am 977acabd: (-s ours) am eebc8ab9: DO NOT MERGE Change pairing_cb to assume temporary pairing by default

* commit '977acabd3744a3308057b1485c7ac8658698e96b':
  DO NOT MERGE Change pairing_cb to assume temporary pairing by default
diff --git a/Android.mk b/Android.mk
index 5f2d274..1ddfb47 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,12 +1,20 @@
 LOCAL_PATH := $(call my-dir)
 
+bdroid_CFLAGS := -Wno-unused-parameter
+
 # Setup bdroid local make variables for handling configuration
 ifneq ($(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR),)
   bdroid_C_INCLUDES := $(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR)
-  bdroid_CFLAGS := -DHAS_BDROID_BUILDCFG
+  bdroid_CFLAGS += -DHAS_BDROID_BUILDCFG
 else
   bdroid_C_INCLUDES :=
-  bdroid_CFLAGS := -DHAS_NO_BDROID_BUILDCFG
+  bdroid_CFLAGS += -DHAS_NO_BDROID_BUILDCFG
+endif
+
+bdroid_CFLAGS += -Wall -Werror
+
+ifneq ($(BOARD_BLUETOOTH_BDROID_HCILP_INCLUDED),)
+  bdroid_CFLAGS += -DHCILP_INCLUDED=$(BOARD_BLUETOOTH_BDROID_HCILP_INCLUDED)
 endif
 
 include $(call all-subdir-makefiles)
diff --git a/CleanSpec.mk b/CleanSpec.mk
index b84e1b6..518119b 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -44,6 +44,10 @@
 #$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
 #$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
 
+# Start of Clean Step list:
+$(call add-clean-step, find $(OUT_DIR) -type f -iname "*blue*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, find $(OUT_DIR) -type f -iname "*bdroid*" -print0 | xargs -0 rm -f)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/audio_a2dp_hw/Android.mk b/audio_a2dp_hw/Android.mk
index f9fd0a1..6fb83cb 100644
--- a/audio_a2dp_hw/Android.mk
+++ b/audio_a2dp_hw/Android.mk
@@ -1,21 +1,21 @@
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
+LOCAL_SRC_FILES := \
 	audio_a2dp_hw.c
 
-LOCAL_C_INCLUDES+= . $(LOCAL_PATH)/../utils/include
+LOCAL_C_INCLUDES += \
+	. \
+	$(LOCAL_PATH)/../utils/include
 
-LOCAL_SHARED_LIBRARIES := \
-	libcutils liblog
-
-LOCAL_SHARED_LIBRARIES += \
-	libpower
+LOCAL_CFLAGS += -std=c99
 
 LOCAL_MODULE := audio.a2dp.default
 LOCAL_MODULE_RELATIVE_PATH := hw
 
+LOCAL_SHARED_LIBRARIES := libcutils liblog
+
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/audio_a2dp_hw/audio_a2dp_hw.c b/audio_a2dp_hw/audio_a2dp_hw.c
index cde56c1..5310ba3 100644
--- a/audio_a2dp_hw/audio_a2dp_hw.c
+++ b/audio_a2dp_hw/audio_a2dp_hw.c
@@ -25,6 +25,7 @@
  *****************************************************************************/
 
 #include <errno.h>
+#include <inttypes.h>
 #include <pthread.h>
 #include <stdint.h>
 #include <sys/time.h>
@@ -47,7 +48,7 @@
 
 #define LOG_TAG "audio_a2dp_hw"
 /* #define LOG_NDEBUG 0 */
-#include <cutils/log.h>
+#include <log/log.h>
 
 /*****************************************************************************
 **  Constants & Macros
@@ -78,10 +79,12 @@
     AUDIO_A2DP_STATE_STANDBY    /* allows write to autoresume */
 } a2dp_state_t;
 
+struct a2dp_stream_in;
 struct a2dp_stream_out;
 
 struct a2dp_audio_device {
     struct audio_hw_device device;
+    struct a2dp_stream_in  *input;
     struct a2dp_stream_out *output;
 };
 
@@ -93,18 +96,23 @@
 
 /* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
 
-struct a2dp_stream_out {
-    struct audio_stream_out stream;
+struct a2dp_stream_common {
     pthread_mutex_t         lock;
     int                     ctrl_fd;
     int                     audio_fd;
     size_t                  buffer_sz;
-    a2dp_state_t            state;
     struct a2dp_config      cfg;
+    a2dp_state_t            state;
+};
+
+struct a2dp_stream_out {
+    struct audio_stream_out stream;
+    struct a2dp_stream_common common;
 };
 
 struct a2dp_stream_in {
-    struct audio_stream_in stream;
+    struct audio_stream_in  stream;
+    struct a2dp_stream_common common;
 };
 
 /*****************************************************************************
@@ -188,14 +196,14 @@
 **
 *****************************************************************************/
 
-static int skt_connect(struct a2dp_stream_out *out, char *path)
+static int skt_connect(char *path, size_t buffer_sz)
 {
     int ret;
     int skt_fd;
     struct sockaddr_un remote;
     int len;
 
-    INFO("connect to %s (sz %d)", path, out->buffer_sz);
+    INFO("connect to %s (sz %zu)", path, buffer_sz);
 
     skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
 
@@ -207,18 +215,43 @@
         return -1;
     }
 
-    len = out->buffer_sz;
+    len = buffer_sz;
     ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
 
     /* only issue warning if failed */
     if (ret < 0)
         ERROR("setsockopt failed (%s)", strerror(errno));
 
+    ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
+
+    /* only issue warning if failed */
+    if (ret < 0)
+        ERROR("setsockopt failed (%s)", strerror(errno));
+
     INFO("connected to stack fd = %d", skt_fd);
 
     return skt_fd;
 }
 
+static int skt_read(int fd, void *p, size_t len)
+{
+    int read;
+    struct pollfd pfd;
+    struct timespec ts;
+
+    FNLOG();
+
+    ts_log("skt_read recv", len, NULL);
+
+    if ((read = recv(fd, p, len, MSG_NOSIGNAL)) == -1)
+    {
+        ERROR("write failed with errno=%d\n", errno);
+        return -1;
+    }
+
+    return read;
+}
+
 static int skt_write(int fd, const void *p, size_t len)
 {
     int sent;
@@ -266,29 +299,53 @@
 **
 *****************************************************************************/
 
-static int a2dp_command(struct a2dp_stream_out *out, char cmd)
+static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length)
+{
+    int ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
+    if (ret < 0)
+    {
+        ERROR("ack failed (%s)", strerror(errno));
+        if (errno == EINTR)
+        {
+            /* retry again */
+            ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
+            if (ret < 0)
+            {
+               ERROR("ack failed (%s)", strerror(errno));
+               skt_disconnect(common->ctrl_fd);
+               common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+               return -1;
+            }
+        }
+        else
+        {
+               skt_disconnect(common->ctrl_fd);
+               common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+               return -1;
+
+        }
+    }
+    return ret;
+}
+
+static int a2dp_command(struct a2dp_stream_common *common, char cmd)
 {
     char ack;
 
     DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd));
 
     /* send command */
-    if (send(out->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1)
+    if (send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1)
     {
         ERROR("cmd failed (%s)", strerror(errno));
-        skt_disconnect(out->ctrl_fd);
-        out->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+        skt_disconnect(common->ctrl_fd);
+        common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
         return -1;
     }
 
     /* wait for ack byte */
-    if (recv(out->ctrl_fd, &ack, 1, MSG_NOSIGNAL) < 0)
-    {
-        ERROR("ack failed (%s)", strerror(errno));
-        skt_disconnect(out->ctrl_fd);
-        out->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+    if (a2dp_ctrl_receive(common, &ack, 1) < 0)
         return -1;
-    }
 
     DEBUG("A2DP COMMAND %s DONE STATUS %d", dump_a2dp_ctrl_event(cmd), ack);
 
@@ -298,13 +355,74 @@
     return 0;
 }
 
+static int check_a2dp_ready(struct a2dp_stream_common *common)
+{
+    if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0)
+    {
+        ERROR("check a2dp ready failed");
+        return -1;
+    }
+    return 0;
+}
+
+static int a2dp_read_audio_config(struct a2dp_stream_common *common)
+{
+    char cmd = A2DP_CTRL_GET_AUDIO_CONFIG;
+    uint32_t sample_rate;
+    uint8_t channel_count;
+
+    if (a2dp_command(common, A2DP_CTRL_GET_AUDIO_CONFIG) < 0)
+    {
+        ERROR("check a2dp ready failed");
+        return -1;
+    }
+
+    if (a2dp_ctrl_receive(common, &sample_rate, 4) < 0)
+        return -1;
+    if (a2dp_ctrl_receive(common, &channel_count, 1) < 0)
+        return -1;
+
+    common->cfg.channel_flags = (channel_count == 1 ? AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO);
+    common->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
+    common->cfg.rate = sample_rate;
+
+    INFO("got config %d %d", common->cfg.format, common->cfg.rate);
+
+    return 0;
+}
+
+static void a2dp_open_ctrl_path(struct a2dp_stream_common *common)
+{
+    int i;
+
+    /* retry logic to catch any timing variations on control channel */
+    for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++)
+    {
+        /* connect control channel if not already connected */
+        if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0)
+        {
+            /* success, now check if stack is ready */
+            if (check_a2dp_ready(common) == 0)
+                break;
+
+            ERROR("error : a2dp not ready, wait 250 ms and retry");
+            usleep(250000);
+            skt_disconnect(common->ctrl_fd);
+            common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+        }
+
+        /* ctrl channel not ready, wait a bit */
+        usleep(250000);
+    }
+}
+
 /*****************************************************************************
 **
 ** AUDIO DATA PATH
 **
 *****************************************************************************/
 
-static void a2dp_stream_out_init(struct a2dp_stream_out *out)
+static void a2dp_stream_common_init(struct a2dp_stream_common *common)
 {
     pthread_mutexattr_t lock_attr;
 
@@ -312,124 +430,109 @@
 
     pthread_mutexattr_init(&lock_attr);
     pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init(&out->lock, &lock_attr);
+    pthread_mutex_init(&common->lock, &lock_attr);
 
-    out->ctrl_fd = AUDIO_SKT_DISCONNECTED;
-    out->audio_fd = AUDIO_SKT_DISCONNECTED;
-    out->state = AUDIO_A2DP_STATE_STOPPED;
-
-    out->cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG;
-    out->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
-    out->cfg.rate = AUDIO_STREAM_DEFAULT_RATE;
+    common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+    common->audio_fd = AUDIO_SKT_DISCONNECTED;
+    common->state = AUDIO_A2DP_STATE_STOPPED;
 
     /* manages max capacity of socket pipe */
-    out->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
+    common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
 }
 
-static int start_audio_datapath(struct a2dp_stream_out *out)
+static int start_audio_datapath(struct a2dp_stream_common *common)
 {
-    int oldstate = out->state;
+    int oldstate = common->state;
 
-    INFO("state %d", out->state);
+    INFO("state %d", common->state);
 
-    if (out->ctrl_fd == AUDIO_SKT_DISCONNECTED)
+    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
+        INFO("AUDIO_SKT_DISCONNECTED");
         return -1;
+    }
 
-    out->state = AUDIO_A2DP_STATE_STARTING;
+    common->state = AUDIO_A2DP_STATE_STARTING;
 
-    if (a2dp_command(out, A2DP_CTRL_CMD_START) < 0)
+    if (a2dp_command(common, A2DP_CTRL_CMD_START) < 0)
     {
         ERROR("audiopath start failed");
 
-        out->state = oldstate;
+        common->state = oldstate;
         return -1;
     }
 
     /* connect socket if not yet connected */
-    if (out->audio_fd == AUDIO_SKT_DISCONNECTED)
+    if (common->audio_fd == AUDIO_SKT_DISCONNECTED)
     {
-        out->audio_fd = skt_connect(out, A2DP_DATA_PATH);
-
-        if (out->audio_fd < 0)
+        common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
+        if (common->audio_fd < 0)
         {
-            out->state = oldstate;
+            common->state = oldstate;
             return -1;
         }
 
-        out->state = AUDIO_A2DP_STATE_STARTED;
+        common->state = AUDIO_A2DP_STATE_STARTED;
     }
 
     return 0;
 }
 
 
-static int stop_audio_datapath(struct a2dp_stream_out *out)
+static int stop_audio_datapath(struct a2dp_stream_common *common)
 {
-    int oldstate = out->state;
+    int oldstate = common->state;
 
-    INFO("state %d", out->state);
+    INFO("state %d", common->state);
 
-    if (out->ctrl_fd == AUDIO_SKT_DISCONNECTED)
+    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
          return -1;
 
     /* prevent any stray output writes from autostarting the stream
        while stopping audiopath */
-    out->state = AUDIO_A2DP_STATE_STOPPING;
+    common->state = AUDIO_A2DP_STATE_STOPPING;
 
-    if (a2dp_command(out, A2DP_CTRL_CMD_STOP) < 0)
+    if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0)
     {
         ERROR("audiopath stop failed");
-        out->state = oldstate;
+        common->state = oldstate;
         return -1;
     }
 
-    out->state = AUDIO_A2DP_STATE_STOPPED;
+    common->state = AUDIO_A2DP_STATE_STOPPED;
 
     /* disconnect audio path */
-    skt_disconnect(out->audio_fd);
-    out->audio_fd = AUDIO_SKT_DISCONNECTED;
+    skt_disconnect(common->audio_fd);
+    common->audio_fd = AUDIO_SKT_DISCONNECTED;
 
     return 0;
 }
 
-static int suspend_audio_datapath(struct a2dp_stream_out *out, bool standby)
+static int suspend_audio_datapath(struct a2dp_stream_common *common, bool standby)
 {
-    INFO("state %d", out->state);
+    INFO("state %d", common->state);
 
-    if (out->ctrl_fd == AUDIO_SKT_DISCONNECTED)
+    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
          return -1;
 
-    if (out->state == AUDIO_A2DP_STATE_STOPPING)
+    if (common->state == AUDIO_A2DP_STATE_STOPPING)
         return -1;
 
-    if (a2dp_command(out, A2DP_CTRL_CMD_SUSPEND) < 0)
+    if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0)
         return -1;
 
     if (standby)
-        out->state = AUDIO_A2DP_STATE_STANDBY;
+        common->state = AUDIO_A2DP_STATE_STANDBY;
     else
-        out->state = AUDIO_A2DP_STATE_SUSPENDED;
+        common->state = AUDIO_A2DP_STATE_SUSPENDED;
 
     /* disconnect audio path */
-    skt_disconnect(out->audio_fd);
+    skt_disconnect(common->audio_fd);
 
-    out->audio_fd = AUDIO_SKT_DISCONNECTED;
+    common->audio_fd = AUDIO_SKT_DISCONNECTED;
 
     return 0;
 }
 
-static int check_a2dp_ready(struct a2dp_stream_out *out)
-{
-    INFO("state %d", out->state);
-
-    if (a2dp_command(out, A2DP_CTRL_CMD_CHECK_READY) < 0)
-    {
-        ERROR("check a2dp ready failed");
-        return -1;
-    }
-    return 0;
-}
-
 
 /*****************************************************************************
 **
@@ -443,52 +546,52 @@
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
     int sent;
 
-    DEBUG("write %d bytes (fd %d)", bytes, out->audio_fd);
+    DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
 
-    if (out->state == AUDIO_A2DP_STATE_SUSPENDED)
+    if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
     {
         DEBUG("stream suspended");
         return -1;
     }
 
     /* only allow autostarting if we are in stopped or standby */
-    if ((out->state == AUDIO_A2DP_STATE_STOPPED) ||
-        (out->state == AUDIO_A2DP_STATE_STANDBY))
+    if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) ||
+        (out->common.state == AUDIO_A2DP_STATE_STANDBY))
     {
-        pthread_mutex_lock(&out->lock);
+        pthread_mutex_lock(&out->common.lock);
 
-        if (start_audio_datapath(out) < 0)
+        if (start_audio_datapath(&out->common) < 0)
         {
             /* emulate time this write represents to avoid very fast write
                failures during transition periods or remote suspend */
 
-            int us_delay = calc_audiotime(out->cfg, bytes);
+            int us_delay = calc_audiotime(out->common.cfg, bytes);
 
             DEBUG("emulate a2dp write delay (%d us)", us_delay);
 
             usleep(us_delay);
-            pthread_mutex_unlock(&out->lock);
+            pthread_mutex_unlock(&out->common.lock);
             return -1;
         }
 
-        pthread_mutex_unlock(&out->lock);
+        pthread_mutex_unlock(&out->common.lock);
     }
-    else if (out->state != AUDIO_A2DP_STATE_STARTED)
+    else if (out->common.state != AUDIO_A2DP_STATE_STARTED)
     {
         ERROR("stream not in stopped or standby");
         return -1;
     }
 
-    sent = skt_write(out->audio_fd, buffer,  bytes);
+    sent = skt_write(out->common.audio_fd, buffer,  bytes);
 
     if (sent == -1)
     {
-        skt_disconnect(out->audio_fd);
-        out->audio_fd = AUDIO_SKT_DISCONNECTED;
-        out->state = AUDIO_A2DP_STATE_STOPPED;
+        skt_disconnect(out->common.audio_fd);
+        out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
+        out->common.state = AUDIO_A2DP_STATE_STOPPED;
     }
 
-    DEBUG("wrote %d bytes out of %d bytes", sent, bytes);
+    DEBUG("wrote %d bytes out of %zu bytes", sent, bytes);
     return sent;
 }
 
@@ -497,16 +600,16 @@
 {
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
 
-    DEBUG("rate %d", out->cfg.rate);
+    DEBUG("rate %" PRIu32,out->common.cfg.rate);
 
-    return out->cfg.rate;
+    return out->common.cfg.rate;
 }
 
 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
 {
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
 
-    DEBUG("out_set_sample_rate : %d", rate);
+    DEBUG("out_set_sample_rate : %" PRIu32, rate);
 
     if (rate != AUDIO_STREAM_DEFAULT_RATE)
     {
@@ -514,7 +617,7 @@
         return -1;
     }
 
-    out->cfg.rate = rate;
+    out->common.cfg.rate = rate;
 
     return 0;
 }
@@ -523,25 +626,25 @@
 {
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
 
-    DEBUG("buffer_size : %d", out->buffer_sz);
+    DEBUG("buffer_size : %zu", out->common.buffer_sz);
 
-    return out->buffer_sz;
+    return out->common.buffer_sz;
 }
 
 static uint32_t out_get_channels(const struct audio_stream *stream)
 {
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
 
-    DEBUG("channels 0x%x", out->cfg.channel_flags);
+    DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_flags);
 
-    return out->cfg.channel_flags;
+    return out->common.cfg.channel_flags;
 }
 
 static audio_format_t out_get_format(const struct audio_stream *stream)
 {
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
-    DEBUG("format 0x%x", out->cfg.format);
-    return out->cfg.format;
+    DEBUG("format 0x%x", out->common.cfg.format);
+    return out->common.cfg.format;
 }
 
 static int out_set_format(struct audio_stream *stream, audio_format_t format)
@@ -559,13 +662,13 @@
 
     FNLOG();
 
-    pthread_mutex_lock(&out->lock);
+    pthread_mutex_lock(&out->common.lock);
 
-    if (out->state == AUDIO_A2DP_STATE_STARTED)
-        retVal =  suspend_audio_datapath(out, true);
+    if (out->common.state == AUDIO_A2DP_STATE_STARTED)
+        retVal =  suspend_audio_datapath(&out->common, true);
     else
         retVal = 0;
-    pthread_mutex_unlock (&out->lock);
+    pthread_mutex_unlock(&out->common.lock);
 
     return retVal;
 }
@@ -583,11 +686,12 @@
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
     struct str_parms *parms;
     char keyval[16];
-    int retval = 0;
+    int retval;
+    int status = 0;
 
-    INFO("state %d", out->state);
+    INFO("state %d", out->common.state);
 
-    pthread_mutex_lock(&out->lock);
+    pthread_mutex_lock(&out->common.lock);
 
     parms = str_parms_create_str(kvpairs);
 
@@ -601,7 +705,7 @@
         if (strcmp(keyval, "true") == 0)
         {
             DEBUG("stream closing, disallow any writes");
-            out->state = AUDIO_A2DP_STATE_STOPPING;
+            out->common.state = AUDIO_A2DP_STATE_STOPPING;
         }
     }
 
@@ -611,25 +715,24 @@
     {
         if (strcmp(keyval, "true") == 0)
         {
-            if (out->state == AUDIO_A2DP_STATE_STARTED)
-                retval = suspend_audio_datapath(out, false);
+            if (out->common.state == AUDIO_A2DP_STATE_STARTED)
+                status = suspend_audio_datapath(&out->common, false);
         }
         else
         {
             /* Do not start the streaming automatically. If the phone was streaming
              * prior to being suspended, the next out_write shall trigger the
              * AVDTP start procedure */
-            if (out->state == AUDIO_A2DP_STATE_SUSPENDED)
-                out->state = AUDIO_A2DP_STATE_STANDBY;
+            if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
+                out->common.state = AUDIO_A2DP_STATE_STANDBY;
             /* Irrespective of the state, return 0 */
-            retval = 0;
         }
     }
 
-    pthread_mutex_unlock(&out->lock);
+    pthread_mutex_unlock(&out->common.lock);
     str_parms_destroy(parms);
 
-    return retval;
+    return status;
 }
 
 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
@@ -652,9 +755,9 @@
 
     FNLOG();
 
-    latency_us = ((out->buffer_sz * 1000 ) /
-                    audio_stream_frame_size(&out->stream.common) /
-                    out->cfg.rate) * 1000;
+    latency_us = ((out->common.buffer_sz * 1000 ) /
+                    audio_stream_out_frame_size(&out->stream) /
+                    out->common.cfg.rate) * 1000;
 
 
     return (latency_us / 1000) + 200;
@@ -710,19 +813,22 @@
 
 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
 {
-    UNUSED(stream);
+    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
 
     FNLOG();
-    return 8000;
+    return in->common.cfg.rate;
 }
 
 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
 {
-    UNUSED(stream);
-    UNUSED(rate);
+    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
 
     FNLOG();
-    return 0;
+
+    if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
+        return 0;
+    else
+        return -1;
 }
 
 static size_t in_get_buffer_size(const struct audio_stream *stream)
@@ -735,10 +841,10 @@
 
 static uint32_t in_get_channels(const struct audio_stream *stream)
 {
-    UNUSED(stream);
+    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
 
     FNLOG();
-    return AUDIO_CHANNEL_IN_MONO;
+    return in->common.cfg.channel_flags;
 }
 
 static audio_format_t in_get_format(const struct audio_stream *stream)
@@ -755,7 +861,10 @@
     UNUSED(format);
 
     FNLOG();
-    return 0;
+    if (format == AUDIO_FORMAT_PCM_16_BIT)
+        return 0;
+    else
+        return -1;
 }
 
 static int in_standby(struct audio_stream *stream)
@@ -806,12 +915,60 @@
 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
                        size_t bytes)
 {
-    UNUSED(stream);
-    UNUSED(buffer);
-    UNUSED(bytes);
+    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
+    int read;
 
-    FNLOG();
-    return bytes;
+    DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
+
+    if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED)
+    {
+        DEBUG("stream suspended");
+        return -1;
+    }
+
+    /* only allow autostarting if we are in stopped or standby */
+    if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) ||
+        (in->common.state == AUDIO_A2DP_STATE_STANDBY))
+    {
+        pthread_mutex_lock(&in->common.lock);
+
+        if (start_audio_datapath(&in->common) < 0)
+        {
+            /* emulate time this write represents to avoid very fast write
+               failures during transition periods or remote suspend */
+
+            int us_delay = calc_audiotime(in->common.cfg, bytes);
+
+            DEBUG("emulate a2dp read delay (%d us)", us_delay);
+
+            usleep(us_delay);
+            pthread_mutex_unlock(&in->common.lock);
+            return -1;
+        }
+
+        pthread_mutex_unlock(&in->common.lock);
+    }
+    else if (in->common.state != AUDIO_A2DP_STATE_STARTED)
+    {
+        ERROR("stream not in stopped or standby");
+        return -1;
+    }
+
+    read = skt_read(in->common.audio_fd, buffer, bytes);
+
+    if (read == -1)
+    {
+        skt_disconnect(in->common.audio_fd);
+        in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
+        in->common.state = AUDIO_A2DP_STATE_STOPPED;
+    } else if (read == 0) {
+        DEBUG("read time out - return zeros");
+        memset(buffer, 0, bytes);
+        read = bytes;
+    }
+
+    DEBUG("read %d bytes out of %zu bytes", read, bytes);
+    return read;
 }
 
 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
@@ -846,7 +1003,8 @@
                                    audio_devices_t devices,
                                    audio_output_flags_t flags,
                                    struct audio_config *config,
-                                   struct audio_stream_out **stream_out)
+                                   struct audio_stream_out **stream_out,
+                                   const char *address __unused)
 
 {
     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
@@ -882,7 +1040,11 @@
     out->stream.get_render_position = out_get_render_position;
 
     /* initialize a2dp specifics */
-    a2dp_stream_out_init(out);
+    a2dp_stream_common_init(&out->common);
+
+    out->common.cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG;
+    out->common.cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
+    out->common.cfg.rate = AUDIO_STREAM_DEFAULT_RATE;
 
    /* set output config values */
    if (config)
@@ -894,26 +1056,8 @@
     *stream_out = &out->stream;
     a2dp_dev->output = out;
 
-    /* retry logic to catch any timing variations on control channel */
-    for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++)
-    {
-        /* connect control channel if not already connected */
-        if ((out->ctrl_fd = skt_connect(out, A2DP_CTRL_PATH)) > 0)
-        {
-            /* success, now check if stack is ready */
-            if (check_a2dp_ready(out) == 0)
-                break;
-
-            ERROR("error : a2dp not ready, wait 250 ms and retry");
-            usleep(250000);
-            skt_disconnect(out->ctrl_fd);
-        }
-
-        /* ctrl channel not ready, wait a bit */
-        usleep(250000);
-    }
-
-    if (out->ctrl_fd == AUDIO_SKT_DISCONNECTED)
+    a2dp_open_ctrl_path(&out->common);
+    if (out->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
     {
         ERROR("ctrl socket failed to connect (%s)", strerror(errno));
         ret = -1;
@@ -926,6 +1070,7 @@
 err_open:
     free(out);
     *stream_out = NULL;
+    a2dp_dev->output = NULL;
     ERROR("failed");
     return ret;
 }
@@ -936,12 +1081,12 @@
     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
 
-    INFO("closing output (state %d)", out->state);
+    INFO("closing output (state %d)", out->common.state);
 
-    if ((out->state == AUDIO_A2DP_STATE_STARTED) || (out->state == AUDIO_A2DP_STATE_STOPPING))
-        stop_audio_datapath(out);
+    if ((out->common.state == AUDIO_A2DP_STATE_STARTED) || (out->common.state == AUDIO_A2DP_STATE_STOPPING))
+        stop_audio_datapath(&out->common);
 
-    skt_disconnect(out->ctrl_fd);
+    skt_disconnect(out->common.ctrl_fd);
     free(stream);
     a2dp_dev->output = NULL;
 
@@ -955,9 +1100,11 @@
     int retval = 0;
 
     if (out == NULL)
+    {
+        ERROR("ERROR: set param called even when stream out is null");
         return retval;
-
-    INFO("state %d", out->state);
+    }
+    INFO("state %d", out->common.state);
 
     retval = out->stream.common.set_parameters((struct audio_stream *)out, kvpairs);
 
@@ -1055,9 +1202,12 @@
                                   audio_io_handle_t handle,
                                   audio_devices_t devices,
                                   struct audio_config *config,
-                                  struct audio_stream_in **stream_in)
+                                  struct audio_stream_in **stream_in,
+                                  audio_input_flags_t flags __unused,
+                                  const char *address __unused,
+                                  audio_source_t source __unused)
 {
-    struct a2dp_audio_device *ladev = (struct a2dp_audio_device *)dev;
+    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
     struct a2dp_stream_in *in;
     int ret;
     UNUSED(handle);
@@ -1087,24 +1237,54 @@
     in->stream.read = in_read;
     in->stream.get_input_frames_lost = in_get_input_frames_lost;
 
+    /* initialize a2dp specifics */
+    a2dp_stream_common_init(&in->common);
+
     *stream_in = &in->stream;
+    a2dp_dev->input = in;
+
+    a2dp_open_ctrl_path(&in->common);
+    if (in->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
+    {
+        ERROR("ctrl socket failed to connect (%s)", strerror(errno));
+        ret = -1;
+        goto err_open;
+    }
+
+    if (a2dp_read_audio_config(&in->common) < 0) {
+        ERROR("a2dp_read_audio_config failed (%s)", strerror(errno));
+        ret = -1;
+        goto err_open;
+    }
+
+    DEBUG("success");
     return 0;
 
 err_open:
     free(in);
     *stream_in = NULL;
+    a2dp_dev->input = NULL;
+    ERROR("failed");
     return ret;
 }
 
 static void adev_close_input_stream(struct audio_hw_device *dev,
-                                   struct audio_stream_in *in)
+                                   struct audio_stream_in *stream)
 {
-    UNUSED(dev);
-    UNUSED(in);
+    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
+    struct a2dp_stream_in* in = (struct a2dp_stream_in *)stream;
+    a2dp_state_t state = in->common.state;
 
-    FNLOG();
+    INFO("closing input (state %d)", state);
 
-    return;
+    if ((state == AUDIO_A2DP_STATE_STARTED) || (state == AUDIO_A2DP_STATE_STOPPING))
+        stop_audio_datapath(&in->common);
+
+    skt_disconnect(in->common.ctrl_fd);
+    free(stream);
+    a2dp_dev->input = NULL;
+
+    DEBUG("done");
 }
 
 static int adev_dump(const audio_hw_device_t *device, int fd)
@@ -1146,7 +1326,7 @@
         return -ENOMEM;
 
     adev->device.common.tag = HARDWARE_DEVICE_TAG;
-    adev->device.common.version = AUDIO_DEVICE_API_VERSION_CURRENT;
+    adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
     adev->device.common.module = (struct hw_module_t *) module;
     adev->device.common.close = adev_close;
 
diff --git a/audio_a2dp_hw/audio_a2dp_hw.h b/audio_a2dp_hw/audio_a2dp_hw.h
index 2015591..b4ac85d 100644
--- a/audio_a2dp_hw/audio_a2dp_hw.h
+++ b/audio_a2dp_hw/audio_a2dp_hw.h
@@ -46,7 +46,8 @@
     A2DP_CTRL_CMD_CHECK_READY,
     A2DP_CTRL_CMD_START,
     A2DP_CTRL_CMD_STOP,
-    A2DP_CTRL_CMD_SUSPEND
+    A2DP_CTRL_CMD_SUSPEND,
+    A2DP_CTRL_GET_AUDIO_CONFIG,
 } tA2DP_CTRL_CMD;
 
 typedef enum {
diff --git a/bta/Android.mk b/bta/Android.mk
index bca6c08..c863d10 100644
--- a/bta/Android.mk
+++ b/bta/Android.mk
@@ -1,5 +1,3 @@
-ifneq ($(TARGET_SIMULATOR),true)
-
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
@@ -8,7 +6,7 @@
 LOCAL_CFLAGS += \
 	-DBOARD_HAVE_BLUETOOTH_BCM
 endif
-LOCAL_CFLAGS += -DBUILDCFG $(bdroid_CFLAGS)
+LOCAL_CFLAGS += -DBUILDCFG $(bdroid_CFLAGS) -std=c99
 
 LOCAL_PRELINK_MODULE:=false
 LOCAL_SRC_FILES:= \
@@ -39,6 +37,14 @@
     ./ag/bta_ag_cmd.c \
     ./ag/bta_ag_ci.c \
     ./ag/bta_ag_at.c \
+    ./hf_client/bta_hf_client_act.c \
+    ./hf_client/bta_hf_client_api.c \
+    ./hf_client/bta_hf_client_main.c \
+    ./hf_client/bta_hf_client_rfc.c \
+    ./hf_client/bta_hf_client_at.c \
+    ./hf_client/bta_hf_client_sdp.c \
+    ./hf_client/bta_hf_client_sco.c \
+    ./hf_client/bta_hf_client_cmd.c \
     ./hh/bta_hh_cfg.c \
     ./hh/bta_hh_act.c \
     ./hh/bta_hh_api.c \
@@ -67,6 +73,10 @@
     ./hl/bta_hl_utils.c \
     ./hl/bta_hl_sdp.c \
     ./hl/bta_hl_ci.c \
+    ./mce/bta_mce_api.c \
+    ./mce/bta_mce_main.c \
+    ./mce/bta_mce_act.c \
+    ./mce/bta_mce_cfg.c \
     ./sys/bta_sys_main.c \
     ./sys/bta_sys_ci.c \
     ./sys/bta_sys_conn.c \
@@ -77,12 +87,13 @@
     ./jv/bta_jv_act.c \
     ./jv/bta_jv_cfg.c \
     ./jv/bta_jv_main.c \
-    ./jv/bta_jv_api.c
+    ./jv/bta_jv_api.c \
 
 LOCAL_MODULE := libbt-brcm_bta
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE_TAGS := optional
 LOCAL_SHARED_LIBRARIES := libcutils libc
+LOCAL_MULTILIB := 32
 
 LOCAL_C_INCLUDES+= . \
                    $(LOCAL_PATH)/include \
@@ -97,11 +108,9 @@
                    $(LOCAL_PATH)/../hcis \
                    $(LOCAL_PATH)/../hcis/patchram \
                    $(LOCAL_PATH)/../udrv/include \
-                   $(LOCAL_PATH)/../brcm/include \
+                   $(LOCAL_PATH)/../vnd/include \
                    $(LOCAL_PATH)/../utils/include \
                    $(bdroid_C_INCLUDES) \
 
 
 include $(BUILD_STATIC_LIBRARY)
-
-endif  # TARGET_SIMULATOR != true
diff --git a/bta/ag/bta_ag_act.c b/bta/ag/bta_ag_act.c
index 11fc85c..ca4f8eb 100644
--- a/bta/ag/bta_ag_act.c
+++ b/bta/ag/bta_ag_act.c
@@ -244,7 +244,7 @@
 {
     UINT16 event = BTA_AG_DISC_FAIL_EVT;
 
-    APPL_TRACE_DEBUG1 ("bta_ag_disc_int_res: Status: %d", p_data->disc_result.status);
+    APPL_TRACE_DEBUG ("bta_ag_disc_int_res: Status: %d", p_data->disc_result.status);
 
     /* if found service */
     if (p_data->disc_result.status == SDP_SUCCESS ||
@@ -406,7 +406,7 @@
 *******************************************************************************/
 void bta_ag_rfc_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
 {
-    tBTA_AG_HDR    close;
+    tBTA_AG_CLOSE    close;
     tBTA_SERVICE_MASK services;
     int i, num_active_conn = 0;
     UNUSED(p_data);
@@ -423,6 +423,10 @@
 #if (BTM_WBS_INCLUDED == TRUE )
     p_scb->peer_codecs = BTA_AG_CODEC_NONE;
     p_scb->sco_codec = BTA_AG_CODEC_NONE;
+    /* Clear these flags upon SLC teardown */
+    p_scb->codec_updated = FALSE;
+    p_scb->codec_fallback = FALSE;
+    p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
 #endif
     p_scb->role = 0;
     p_scb->post_sco = BTA_AG_POST_SCO_NONE;
@@ -436,13 +440,14 @@
     bta_sys_stop_timer(&p_scb->cn_timer);
 #endif
 
-    close.handle = bta_ag_scb_to_idx(p_scb);
-    close.app_id = p_scb->app_id;
+    close.hdr.handle = bta_ag_scb_to_idx(p_scb);
+    close.hdr.app_id = p_scb->app_id;
+    bdcpy(close.bd_addr, p_scb->peer_addr);
 
     bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
 
     /* call close call-out */
-    bta_ag_co_data_close(close.handle);
+    bta_ag_co_data_close(close.hdr.handle);
 
     /* call close cback */
     (*bta_ag_cb.p_cback)(BTA_AG_CLOSE_EVT, (tBTA_AG *) &close);
@@ -555,13 +560,13 @@
     /* set role */
     p_scb->role = BTA_AG_ACP;
 
-    APPL_TRACE_DEBUG2 ("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d",
+    APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d",
                        p_scb->serv_handle[0], p_scb->serv_handle[1]);
 
     /* get bd addr of peer */
     if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid)))
     {
-        APPL_TRACE_DEBUG1 ("bta_ag_rfc_acp_open error PORT_CheckConnection returned status %d", status);
+        APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open error PORT_CheckConnection returned status %d", status);
     }
 
     /* Collision Handling */
@@ -601,7 +606,7 @@
     /* determine connected service from port handle */
     for (i = 0; i < BTA_AG_NUM_IDX; i++)
     {
-        APPL_TRACE_DEBUG3 ("bta_ag_rfc_acp_open: i = %d serv_handle = %d port_handle = %d",
+        APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: i = %d serv_handle = %d port_handle = %d",
                            i, p_scb->serv_handle[i], p_data->rfc.port_handle);
 
         if (p_scb->serv_handle[i] == p_data->rfc.port_handle)
@@ -612,7 +617,7 @@
         }
     }
 
-    APPL_TRACE_DEBUG2 ("bta_ag_rfc_acp_open: conn_service = %d conn_handle = %d",
+    APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: conn_service = %d conn_handle = %d",
                        p_scb->conn_service, p_scb->conn_handle);
 
     /* close any unopened server */
@@ -819,6 +824,7 @@
         evt.hdr.handle = bta_ag_scb_to_idx(p_scb);
         evt.hdr.app_id = p_scb->app_id;
         evt.peer_feat = p_scb->peer_features;
+        bdcpy(evt.bd_addr, p_scb->peer_addr);
 #if (BTM_WBS_INCLUDED == TRUE )
         evt.peer_codec  = p_scb->peer_codecs;
 #endif
@@ -865,7 +871,7 @@
 {
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG1("bta_ag_rcvd_slc_ready: handle = %d", bta_ag_scb_to_idx(p_scb));
+    APPL_TRACE_DEBUG("bta_ag_rcvd_slc_ready: handle = %d", bta_ag_scb_to_idx(p_scb));
 
     if (bta_ag_cb.parse_mode == BTA_AG_PASS_THROUGH)
     {
@@ -874,3 +880,51 @@
     }
 }
 
+/*******************************************************************************
+**
+** Function         bta_ag_setcodec
+**
+** Description      Handle API SetCodec
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
+{
+#if (BTM_WBS_INCLUDED == TRUE )
+    tBTA_AG_PEER_CODEC codec_type = p_data->api_setcodec.codec;
+    tBTA_AG_VAL        val;
+
+    /* Check if the requested codec type is valid */
+    if((codec_type != BTA_AG_CODEC_NONE) &&
+       (codec_type != BTA_AG_CODEC_CVSD) &&
+       (codec_type != BTA_AG_CODEC_MSBC))
+    {
+        val.num = codec_type;
+        val.hdr.status = BTA_AG_FAIL_RESOURCES;
+        APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d", codec_type);
+        (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG *) &val);
+        return;
+    }
+
+    if((p_scb->peer_codecs & codec_type) || (codec_type == BTA_AG_CODEC_NONE) ||
+        (codec_type == BTA_AG_CODEC_CVSD))
+    {
+        p_scb->sco_codec = codec_type;
+        p_scb->codec_updated = TRUE;
+        val.num = codec_type;
+        val.hdr.status = BTA_AG_SUCCESS;
+        APPL_TRACE_DEBUG("bta_ag_setcodec: Updated codec type %d", codec_type);
+    }
+    else
+    {
+        val.num = codec_type;
+        val.hdr.status = BTA_AG_FAIL_RESOURCES;
+        APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d", codec_type);
+    }
+
+    (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG *) &val);
+#endif
+}
+
diff --git a/bta/ag/bta_ag_api.c b/bta/ag/bta_ag_api.c
index 07dceb9..5bfa492 100644
--- a/bta/ag/bta_ag_api.c
+++ b/bta/ag/bta_ag_api.c
@@ -65,15 +65,13 @@
     {
         if (bta_ag_cb.scb[idx].in_use)
         {
-            APPL_TRACE_ERROR0 ("BTA_AgEnable: FAILED, AG already enabled.");
+            APPL_TRACE_ERROR ("BTA_AgEnable: FAILED, AG already enabled.");
             return BTA_FAILURE;
         }
     }
 
     /* register with BTA system manager */
-    GKI_sched_lock();
     bta_sys_register(BTA_ID_AG, &bta_ag_reg);
-    GKI_sched_unlock();
 
     if ((p_buf = (tBTA_AG_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AG_API_ENABLE))) != NULL)
     {
diff --git a/bta/ag/bta_ag_ci.c b/bta/ag/bta_ag_ci.c
index fd39e34..c9f0a10 100644
--- a/bta/ag/bta_ag_ci.c
+++ b/bta/ag/bta_ag_ci.c
@@ -65,7 +65,7 @@
 
         bta_sys_sendmsg(p_buf);
         } else {
-        APPL_TRACE_ERROR1("ERROR: Unable to allocate buffer to hold AT response code. len=%i", len);
+        APPL_TRACE_ERROR("ERROR: Unable to allocate buffer to hold AT response code. len=%i", len);
             break;
         }
 
diff --git a/bta/ag/bta_ag_cmd.c b/bta/ag/bta_ag_cmd.c
old mode 100644
new mode 100755
index 54cd4d3..fd30247
--- a/bta/ag/bta_ag_cmd.c
+++ b/bta/ag/bta_ag_cmd.c
@@ -21,7 +21,10 @@
  *  This file contains functions for processing AT commands and results.
  *
  ******************************************************************************/
-
+#include "bt_target.h"
+#include "bt_types.h"
+#include "gki.h"
+#include "bd.h"
 #include "bta_api.h"
 #include "bta_sys.h"
 #include "bta_ag_api.h"
@@ -353,7 +356,7 @@
             if(*(p+COLON_IDX_4_VGSVGM) == ':')
             {
                 #if defined(BTA_AG_RESULT_DEBUG) && (BTA_AG_RESULT_DEBUG == TRUE)
-                APPL_TRACE_DEBUG0("[HSP] ':'symbol is changed as '=' for HSP compatibility");
+                APPL_TRACE_DEBUG("[HSP] ':'symbol is changed as '=' for HSP compatibility");
                 #endif
                 *(p+COLON_IDX_4_VGSVGM) = '=';
             }
@@ -379,7 +382,7 @@
     *p++ = '\n';
 
 #if defined(BTA_AG_RESULT_DEBUG) && (BTA_AG_RESULT_DEBUG == TRUE)
-    APPL_TRACE_DEBUG1("bta_ag_send_result: %s", buf);
+    APPL_TRACE_DEBUG("bta_ag_send_result: %s", buf);
 #endif
 
     /* send to RFCOMM */
@@ -406,7 +409,7 @@
 
     if((!m_res_cb) || (m_res_cb->num_result == 0) || (m_res_cb->num_result > BTA_AG_AT_MULTI_LEN))
     {
-        APPL_TRACE_DEBUG0("m_res_cb is NULL or num_result is out of range.");
+        APPL_TRACE_DEBUG("m_res_cb is NULL or num_result is out of range.");
         return;
     }
 
@@ -443,7 +446,7 @@
     }
 
 #if defined(BTA_AG_RESULT_DEBUG) && (BTA_AG_RESULT_DEBUG == TRUE)
-    APPL_TRACE_DEBUG1("send_result: %s", buf);
+    APPL_TRACE_DEBUG("send_result: %s", buf);
 #endif
 
     /* send to RFCOMM */
@@ -681,7 +684,7 @@
             case UUID_CODEC_CVSD:   retval |= BTA_AG_CODEC_CVSD;     break;
             case UUID_CODEC_MSBC:   retval |= BTA_AG_CODEC_MSBC;     break;
             default:
-                APPL_TRACE_ERROR1("Unknown Codec UUID(%d) received", uuid_codec);
+                APPL_TRACE_ERROR("Unknown Codec UUID(%d) received", uuid_codec);
                 return BTA_AG_CODEC_NONE;
         }
 
@@ -823,7 +826,7 @@
 {
     tBTA_AG_VAL val;
 
-    APPL_TRACE_DEBUG4("AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type,
+    APPL_TRACE_DEBUG("AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type,
                       int_arg, p_arg);
 
     /* send OK */
@@ -861,12 +864,13 @@
     tBTA_AG_PEER_CODEC  codec_type, codec_sent;
 #endif
 
-    APPL_TRACE_DEBUG4("HFP AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type,
+    APPL_TRACE_DEBUG("HFP AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type,
                       int_arg, p_arg);
 
     val.hdr.handle = bta_ag_scb_to_idx(p_scb);
     val.hdr.app_id = p_scb->app_id;
     val.num = int_arg;
+    bdcpy(val.bd_addr, p_scb->peer_addr);
     BCM_STRNCPY_S(val.str, sizeof(val.str), p_arg, BTA_AG_AT_MAX_LEN);
     val.str[BTA_AG_AT_MAX_LEN] = 0;
 
@@ -1192,14 +1196,17 @@
                 if (p_scb->peer_codecs & BTA_AG_CODEC_MSBC)
                 {
                     p_scb->sco_codec = UUID_CODEC_MSBC;
-                    APPL_TRACE_DEBUG0("Received AT+BAC, updating sco codec to MSBC");
+                    APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to MSBC");
                 }
                 else
                 {
                     p_scb->sco_codec = UUID_CODEC_CVSD;
-                    APPL_TRACE_DEBUG0("Received AT+BAC, updating sco codec to CVSD");
+                    APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to CVSD");
                 }
-
+                /* The above logic sets the stack preferred codec based on local and peer codec
+                capabilities. This can be overridden by the application depending on its preference
+                using the bta_ag_setcodec API. We send the peer_codecs to the application. */
+                val.num = p_scb->peer_codecs;
                 /* Received BAC while in codec negotiation. */
                 if ((bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST) && (bta_ag_cb.sco.p_curr_scb == p_scb))
                 {
@@ -1209,11 +1216,13 @@
             else
             {
                 p_scb->peer_codecs = BTA_AG_CODEC_NONE;
-                APPL_TRACE_ERROR0("Unexpected CMD:AT+BAC, Codec Negotiation is not supported");
+                APPL_TRACE_ERROR("Unexpected CMD:AT+BAC, Codec Negotiation is not supported");
             }
             break;
 
         case BTA_AG_HF_CMD_BCS:
+            bta_ag_send_ok(p_scb);
+
             /* stop cn timer */
             bta_sys_stop_timer(&p_scb->cn_timer);
 
@@ -1222,7 +1231,7 @@
                 case UUID_CODEC_CVSD:   codec_type = BTA_AG_CODEC_CVSD;     break;
                 case UUID_CODEC_MSBC:   codec_type = BTA_AG_CODEC_MSBC;     break;
                 default:
-                    APPL_TRACE_ERROR1("Unknown codec_uuid %d", int_arg);
+                    APPL_TRACE_ERROR("Unknown codec_uuid %d", int_arg);
                     codec_type = 0xFFFF;
                     break;
             }
@@ -1237,7 +1246,8 @@
             else
                 bta_ag_sco_codec_nego(p_scb, FALSE);
 
-            bta_ag_send_ok(p_scb);
+            /* send final codec info to callback */
+            val.num = codec_sent;
             break;
 
         case BTA_AG_HF_CMD_BCC:
@@ -1274,7 +1284,7 @@
 
     if(unknown && (!strlen(p_arg)))
     {
-        APPL_TRACE_DEBUG0("Empty AT cmd string received");
+        APPL_TRACE_DEBUG("Empty AT cmd string received");
         bta_ag_send_ok(p_scb);
         return;
     }
@@ -1309,7 +1319,7 @@
 {
     UINT8 code = bta_ag_trans_result[p_result->result];
 
-    APPL_TRACE_DEBUG1("bta_ag_hsp_result : res = %d", p_result->result);
+    APPL_TRACE_DEBUG("bta_ag_hsp_result : res = %d", p_result->result);
 
     switch(p_result->result)
     {
@@ -1382,7 +1392,7 @@
 
         case BTA_AG_INBAND_RING_RES:
             p_scb->inband_enabled = p_result->data.state;
-            APPL_TRACE_DEBUG1("inband_enabled set to %d", p_scb->inband_enabled);
+            APPL_TRACE_DEBUG("inband_enabled set to %d", p_scb->inband_enabled);
             break;
 
         case BTA_AG_UNAT_RES:
@@ -1422,7 +1432,7 @@
 {
     UINT8 code = bta_ag_trans_result[p_result->result];
 
-    APPL_TRACE_DEBUG1("bta_ag_hfp_result : res = %d", p_result->result);
+    APPL_TRACE_DEBUG("bta_ag_hfp_result : res = %d", p_result->result);
 
     switch(p_result->result)
     {
@@ -1445,7 +1455,7 @@
                     p_result->data.num = BTA_AG_CLIP_TYPE_DEFAULT;
             }
 
-            APPL_TRACE_DEBUG1("CLIP type :%d", p_result->data.num);
+            APPL_TRACE_DEBUG("CLIP type :%d", p_result->data.num);
             p_scb->clip[0] = 0;
             if (p_result->data.str[0] != 0)
                 sprintf(p_scb->clip,"%s,%d", p_result->data.str, p_result->data.num);
@@ -1593,7 +1603,7 @@
 
         case BTA_AG_INBAND_RING_RES:
             p_scb->inband_enabled = p_result->data.state;
-            APPL_TRACE_DEBUG1("inband_enabled set to %d", p_scb->inband_enabled);
+            APPL_TRACE_DEBUG("inband_enabled set to %d", p_scb->inband_enabled);
             bta_ag_send_result(p_scb, code, NULL, p_result->data.state);
             break;
 
@@ -1605,7 +1615,7 @@
             p_scb->signal_ind = p_result->data.str[6] - '0';
             p_scb->roam_ind = p_result->data.str[8] - '0';
             p_scb->battchg_ind = p_result->data.str[10] - '0';
-            APPL_TRACE_DEBUG2("cind call:%d callsetup:%d", p_scb->call_ind, p_scb->callsetup_ind);
+            APPL_TRACE_DEBUG("cind call:%d callsetup:%d", p_scb->call_ind, p_scb->callsetup_ind);
 
             bta_ag_send_result(p_scb, code, p_result->data.str, 0);
             bta_ag_send_ok(p_scb);
@@ -1638,7 +1648,7 @@
                 if (p_result->data.str[0] != 0)
                 {
                     bta_ag_process_unat_res(p_result->data.str);
-                    APPL_TRACE_DEBUG1("BTA_AG_RES :%s",p_result->data.str);
+                    APPL_TRACE_DEBUG("BTA_AG_RES :%s",p_result->data.str);
                     bta_ag_send_result(p_scb, code, p_result->data.str, 0);
                 }
 
@@ -1714,47 +1724,6 @@
     }
 }
 
-/*******************************************************************************
-**
-** Function         bta_ag_setcodec
-**
-** Description      Handle API SetCodec
-**
-**
-** Returns          void
-**
-*******************************************************************************/
-void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
-{
-#if (BTM_WBS_INCLUDED == TRUE )
-    tBTA_AG_PEER_CODEC codec_type = p_data->api_setcodec.codec;
-
-    /* Check if the requested codec type is valid */
-    if((codec_type != BTA_AG_CODEC_NONE) &&
-       (codec_type != BTA_AG_CODEC_CVSD) &&
-       (codec_type != BTA_AG_CODEC_MSBC))
-    {
-        APPL_TRACE_ERROR1("bta_ag_setcodec error: unsupported codec type %d", codec_type);
-        return;
-    }
-
-    if((p_scb->peer_codecs & codec_type) || (codec_type == BTA_AG_CODEC_NONE) || (codec_type == BTA_AG_CODEC_CVSD))
-    {
-        p_scb->sco_codec = codec_type;
-        p_scb->codec_updated = TRUE;
-        APPL_TRACE_DEBUG1("bta_ag_setcodec: Updated codec type %d", codec_type);
-    }
-    else
-    {
-        APPL_TRACE_ERROR1("bta_ag_setcodec error: unsupported codec type %d", codec_type);
-    }
-#else
-    UNUSED(p_scb);
-    UNUSED(p_data);
-#endif
-}
-
-
 #if (BTM_WBS_INCLUDED == TRUE )
 /*******************************************************************************
 **
@@ -1781,13 +1750,14 @@
             case BTA_AG_CODEC_CVSD:     codec_uuid = UUID_CODEC_CVSD;   break;
             case BTA_AG_CODEC_MSBC:     codec_uuid = UUID_CODEC_MSBC;   break;
             default:
-                APPL_TRACE_ERROR1("bta_ag_send_bcs: unknown codec %d, use CVSD", p_scb->sco_codec);
+                APPL_TRACE_ERROR("bta_ag_send_bcs: unknown codec %d, use CVSD", p_scb->sco_codec);
                 codec_uuid = UUID_CODEC_CVSD;
                 break;
         }
     }
 
     /* send +BCS */
+    APPL_TRACE_DEBUG("send +BCS codec is %d", codec_uuid);
     bta_ag_send_result(p_scb, BTA_AG_RES_BCS, NULL, codec_uuid);
 
 }
diff --git a/bta/ag/bta_ag_int.h b/bta/ag/bta_ag_int.h
index b0d1b1d..b2d9fb0 100644
--- a/bta/ag/bta_ag_int.h
+++ b/bta/ag/bta_ag_int.h
@@ -237,6 +237,14 @@
     UINT8           scn;
 } tBTA_AG_PROFILE;
 
+#if (BTM_WBS_INCLUDED == TRUE)
+typedef enum
+{
+    BTA_AG_SCO_MSBC_SETTINGS_T2 = 0, /* preferred/default when codec is mSBC */
+    BTA_AG_SCO_MSBC_SETTINGS_T1,
+} tBTA_AG_SCO_MSBC_SETTINGS;
+#endif
+
 /* type for each service control block */
 typedef struct
 {
@@ -261,6 +269,7 @@
     tBTA_AG_PEER_CODEC  inuse_codec;    /* codec being used for the current SCO connection */
     BOOLEAN             codec_updated;  /* set to TRUE whenever the app updates codec type */
     BOOLEAN             codec_fallback; /* If sco nego fails for mSBC, fallback to CVSD */
+    tBTA_AG_SCO_MSBC_SETTINGS codec_msbc_settings; /* settings to be used for the impending eSCO */
     TIMER_LIST_ENT      cn_timer;       /* codec negotiation timer */
 #endif
     UINT16              sco_idx;        /* SCO handle */
diff --git a/bta/ag/bta_ag_main.c b/bta/ag/bta_ag_main.c
index bae992b..3a32a9d 100644
--- a/bta/ag/bta_ag_main.c
+++ b/bta/ag/bta_ag_main.c
@@ -318,12 +318,17 @@
             /* initialize variables */
             p_scb->in_use = TRUE;
             p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
-
+#if (BTM_WBS_INCLUDED == TRUE )
+            p_scb->codec_updated = FALSE;
+#endif
             /* set up timers */
             p_scb->act_timer.param = (UINT32) p_scb;
             p_scb->act_timer.p_cback = bta_ag_timer_cback;
-
-            APPL_TRACE_DEBUG1("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb));
+#if (BTM_WBS_INCLUDED == TRUE)
+            /* set eSCO mSBC setting to T2 as the preferred */
+            p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
+#endif
+            APPL_TRACE_DEBUG("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb));
             break;
         }
     }
@@ -332,7 +337,7 @@
     {
         /* out of scbs */
         p_scb = NULL;
-        APPL_TRACE_WARNING0("Out of ag scbs");
+        APPL_TRACE_WARNING("Out of ag scbs");
     }
     return p_scb;
 }
@@ -352,7 +357,7 @@
     UINT8   idx;
     BOOLEAN allocated = FALSE;
 
-    APPL_TRACE_DEBUG1("bta_ag_scb_dealloc %d", bta_ag_scb_to_idx(p_scb));
+    APPL_TRACE_DEBUG("bta_ag_scb_dealloc %d", bta_ag_scb_to_idx(p_scb));
 
     /* stop timers */
     bta_sys_stop_timer(&p_scb->act_timer);
@@ -421,13 +426,13 @@
         if (!p_scb->in_use)
         {
             p_scb = NULL;
-            APPL_TRACE_WARNING1("ag scb idx %d not allocated", idx);
+            APPL_TRACE_WARNING("ag scb idx %d not allocated", idx);
         }
     }
     else
     {
         p_scb = NULL;
-        APPL_TRACE_DEBUG1("ag scb idx %d out of range", idx);
+        APPL_TRACE_DEBUG("ag scb idx %d out of range", idx);
     }
     return p_scb;
 }
@@ -481,7 +486,7 @@
     }
 
     /* no scb found */
-    APPL_TRACE_WARNING0("No ag scb for peer addr");
+    APPL_TRACE_WARNING("No ag scb for peer addr");
     return 0;
 }
 
@@ -509,7 +514,7 @@
     }
 
     /* no other scb found */
-    APPL_TRACE_DEBUG0("No other ag scb open");
+    APPL_TRACE_DEBUG("No other ag scb open");
     return FALSE;
 }
 
@@ -537,7 +542,7 @@
     }
 
     /* no other scb found */
-    APPL_TRACE_DEBUG0("bta_ag_get_other_idle_scb: No idle AG scb");
+    APPL_TRACE_DEBUG("bta_ag_get_other_idle_scb: No idle AG scb");
     return NULL;
 }
 
@@ -555,7 +560,7 @@
 {
     tBTA_AG_SCB *p_scb;
 
-    APPL_TRACE_DEBUG0 ("bta_ag_colli_timer_cback");
+    APPL_TRACE_DEBUG ("bta_ag_colli_timer_cback");
 
     if (p_tle)
     {
@@ -598,15 +603,15 @@
     {
         if (id == BTA_ID_SYS)   /* ACL collision */
         {
-            APPL_TRACE_WARNING0 ("AG found collision (ACL) ...");
+            APPL_TRACE_WARNING ("AG found collision (ACL) ...");
         }
         else if (id == BTA_ID_AG)   /* RFCOMM collision */
         {
-            APPL_TRACE_WARNING0 ("AG found collision (RFCOMM) ...");
+            APPL_TRACE_WARNING ("AG found collision (RFCOMM) ...");
         }
         else
         {
-            APPL_TRACE_WARNING0 ("AG found collision (\?\?\?) ...");
+            APPL_TRACE_WARNING ("AG found collision (\?\?\?) ...");
         }
 
         p_scb->state = BTA_AG_INIT_ST;
@@ -646,7 +651,7 @@
 {
     if (p_scb)
     {
-        APPL_TRACE_DEBUG1 ("bta_ag_resume_open, Handle(%d)", bta_ag_scb_to_idx(p_scb));
+        APPL_TRACE_DEBUG ("bta_ag_resume_open, Handle(%d)", bta_ag_scb_to_idx(p_scb));
 
         /* resume opening process.  */
         if (p_scb->state == BTA_AG_INIT_ST)
@@ -657,7 +662,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR0 ("bta_ag_resume_open, Null p_scb");
+        APPL_TRACE_ERROR ("bta_ag_resume_open, Null p_scb");
     }
 }
 
@@ -708,14 +713,12 @@
 
     if (!bta_sys_is_register (BTA_ID_AG))
     {
-        APPL_TRACE_ERROR0("BTA AG is already disabled, ignoring ...");
+        APPL_TRACE_ERROR("BTA AG is already disabled, ignoring ...");
         return;
     }
 
     /* De-register with BTA system manager */
-    GKI_sched_lock();
     bta_sys_deregister(BTA_ID_AG);
-    GKI_sched_unlock();
 
     for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++)
     {
@@ -753,6 +756,7 @@
     /* allocate an scb */
     if ((p_scb = bta_ag_scb_alloc()) != NULL)
     {
+        APPL_TRACE_DEBUG("bta_ag_api_register: p_scb 0x%08x ", p_scb);
         bta_ag_sm_execute(p_scb, p_data->hdr.event, p_data);
     }
     else
@@ -781,6 +785,7 @@
     {
         if ((p_scb = bta_ag_scb_by_idx(p_data->hdr.layer_specific)) != NULL)
         {
+            APPL_TRACE_DEBUG("bta_ag_api_result: p_scb 0x%08x ", p_scb);
             bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data);
         }
     }
@@ -788,8 +793,9 @@
     {
         for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, p_scb++)
         {
-            if (p_scb->in_use)
+            if (p_scb->in_use && p_scb->svc_conn)
             {
+                APPL_TRACE_DEBUG("bta_ag_api_result p_scb 0x%08x ", p_scb);
                 bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data);
             }
         }
@@ -819,20 +825,20 @@
     /* Ignore displaying of AT results when not connected (Ignored in state machine) */
     if (in_event != BTA_AG_API_RESULT_EVT || p_scb->state == BTA_AG_OPEN_ST)
     {
-        APPL_TRACE_EVENT5("AG evt (hdl 0x%04x): State %d (%s), Event 0x%04x (%s)",
+        APPL_TRACE_EVENT("AG evt (hdl 0x%04x): State %d (%s), Event 0x%04x (%s)",
                            bta_ag_scb_to_idx(p_scb),
                            p_scb->state, bta_ag_state_str(p_scb->state),
                            event, bta_ag_evt_str(event, p_data->api_result.result));
     }
 #else
-    APPL_TRACE_EVENT3("AG evt (hdl 0x%04x): State %d, Event 0x%04x",
+    APPL_TRACE_EVENT("AG evt (hdl 0x%04x): State %d, Event 0x%04x",
                       bta_ag_scb_to_idx(p_scb), p_scb->state, event);
 #endif
 
     event &= 0x00FF;
     if (event >= (BTA_AG_MAX_EVT & 0x00FF))
     {
-        APPL_TRACE_ERROR0("AG evt out of range, ignoring...");
+        APPL_TRACE_ERROR("AG evt out of range, ignoring...");
         return;
     }
 
@@ -857,7 +863,7 @@
 #if BTA_AG_DEBUG == TRUE
     if (p_scb->state != in_state)
     {
-        APPL_TRACE_EVENT3("BTA AG State Change: [%s] -> [%s] after Event [%s]",
+        APPL_TRACE_EVENT("BTA AG State Change: [%s] -> [%s] after Event [%s]",
                       bta_ag_state_str(in_state),
                       bta_ag_state_str(p_scb->state),
                       bta_ag_evt_str(in_event, p_data->api_result.result));
@@ -879,6 +885,7 @@
 {
     tBTA_AG_SCB *p_scb;
 
+    APPL_TRACE_DEBUG("bta_ag_hdl_event: Event 0x%04x ", p_msg->event);
     switch (p_msg->event)
     {
         /* handle enable event */
@@ -905,6 +912,7 @@
         default:
             if ((p_scb = bta_ag_scb_by_idx(p_msg->layer_specific)) != NULL)
             {
+                APPL_TRACE_DEBUG("bta_ag_hdl_event: p_scb 0x%08x ", p_scb);
                 bta_ag_sm_execute(p_scb, p_msg->event, (tBTA_AG_DATA *) p_msg);
             }
             break;
diff --git a/bta/ag/bta_ag_rfc.c b/bta/ag/bta_ag_rfc.c
index d6b5329..c0a9d3b 100644
--- a/bta/ag/bta_ag_rfc.c
+++ b/bta/ag/bta_ag_rfc.c
@@ -97,7 +97,7 @@
         /* ignore port events for port handles other than connected handle */
         if (port_handle != p_scb->conn_handle)
         {
-            APPL_TRACE_DEBUG3("ag_port_cback ignoring handle:%d conn_handle = %d other handle = %d",
+            APPL_TRACE_DEBUG("ag_port_cback ignoring handle:%d conn_handle = %d other handle = %d",
                               port_handle, p_scb->conn_handle, handle);
             return;
         }
@@ -129,7 +129,7 @@
     UINT8           i;
     BOOLEAN         found_handle = FALSE;
 
-    APPL_TRACE_DEBUG3("ag_mgmt_cback : code = %d, port_handle = %d, handle = %d",
+    APPL_TRACE_DEBUG("ag_mgmt_cback : code = %d, port_handle = %d, handle = %d",
                         code, port_handle, handle);
 
     if ((p_scb = bta_ag_scb_by_idx(handle)) != NULL)
@@ -137,7 +137,7 @@
         /* ignore close event for port handles other than connected handle */
         if ((code != PORT_SUCCESS) && (port_handle != p_scb->conn_handle))
         {
-            APPL_TRACE_DEBUG1("ag_mgmt_cback ignoring handle:%d", port_handle);
+            APPL_TRACE_DEBUG("ag_mgmt_cback ignoring handle:%d", port_handle);
             return;
         }
 
@@ -159,7 +159,7 @@
 
             if (!found_handle)
             {
-                APPL_TRACE_ERROR1 ("bta_ag_mgmt_cback: PORT_SUCCESS, ignoring handle = %d", port_handle);
+                APPL_TRACE_ERROR ("bta_ag_mgmt_cback: PORT_SUCCESS, ignoring handle = %d", port_handle);
                 return;
             }
 
@@ -306,7 +306,7 @@
             else
             {
                 /* TODO: CR#137125 to handle to error properly */
-                APPL_TRACE_DEBUG1("bta_ag_start_servers: RFCOMM_CreateConnection returned error:%d", bta_ag_port_status);
+                APPL_TRACE_DEBUG("bta_ag_start_servers: RFCOMM_CreateConnection returned error:%d", bta_ag_port_status);
             }
         }
     }
@@ -382,7 +382,7 @@
             bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]) == PORT_SUCCESS)
     {
         bta_ag_setup_port(p_scb, p_scb->conn_handle);
-        APPL_TRACE_DEBUG1("bta_ag_rfc_do_open : conn_handle = %d", p_scb->conn_handle);
+        APPL_TRACE_DEBUG("bta_ag_rfc_do_open : conn_handle = %d", p_scb->conn_handle);
     }
     /* RFCOMM create connection failed; send ourselves RFCOMM close event */
     else
diff --git a/bta/ag/bta_ag_sco.c b/bta/ag/bta_ag_sco.c
index 87d9188..ec00514 100644
--- a/bta/ag/bta_ag_sco.c
+++ b/bta/ag/bta_ag_sco.c
@@ -69,7 +69,11 @@
 };
 
 #if (BTM_WBS_INCLUDED == TRUE )
-#define BTA_AG_NUM_CODECS   2
+#define BTA_AG_NUM_CODECS   3
+#define BTA_AG_ESCO_SETTING_IDX_CVSD    0   /* eSCO setting for CVSD */
+#define BTA_AG_ESCO_SETTING_IDX_T1      1   /* eSCO setting for mSBC T1 */
+#define BTA_AG_ESCO_SETTING_IDX_T2      2   /* eSCO setting for mSBC T2 */
+
 static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] =
 {
     /* CVSD */
@@ -88,7 +92,20 @@
         BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
         BTM_ESCO_RETRANS_POWER       /* Retransmission effort                      */
     },
-    /* mSBC */
+    /* mSBC  T1 */
+    {
+        BTM_64KBITS_RATE,                   /* TX Bandwidth (64 kbits/sec), 8000        */
+        BTM_64KBITS_RATE,                   /* RX Bandwidth (64 kbits/sec), 8000        */
+        8,                                  /* 8 ms                                     */
+        BTM_VOICE_SETTING_TRANS,            /* Inp Linear, Transparent, 2s Comp, 16bit  */
+       (BTM_SCO_PKT_TYPES_MASK_EV3      |   /* Packet Types : EV3 + NO_2_EV3            */
+        BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
+        BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
+        BTM_SCO_PKT_TYPES_MASK_NO_3_EV5 |
+        BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 ),
+        BTM_ESCO_RETRANS_QUALITY       /* Retransmission effort                      */
+    },
+    /* mSBC T2*/
     {
         BTM_64KBITS_RATE,                   /* TX Bandwidth (64 kbits/sec), 8000        */
         BTM_64KBITS_RATE,                   /* RX Bandwidth (64 kbits/sec), 8000        */
@@ -102,6 +119,7 @@
     }
 };
 #else
+/* WBS not included, CVSD by default */
 static const tBTM_ESCO_PARAMS bta_ag_esco_params =
 {
     BTM_64KBITS_RATE,                   /* TX Bandwidth (64 kbits/sec)              */
@@ -184,11 +202,11 @@
     BT_HDR  *p_buf;
     UINT16  handle = 0;
 
-    APPL_TRACE_DEBUG3 ("bta_ag_sco_disc_cback(): sco_idx: 0x%x  p_cur_scb: 0x%08x  sco.state: %d", sco_idx, bta_ag_cb.sco.p_curr_scb, bta_ag_cb.sco.state);
+    APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): sco_idx: 0x%x  p_cur_scb: 0x%08x  sco.state: %d", sco_idx, bta_ag_cb.sco.p_curr_scb, bta_ag_cb.sco.state);
 
-    APPL_TRACE_DEBUG4 ("bta_ag_sco_disc_cback(): scb[0] addr: 0x%08x  in_use: %u  sco_idx: 0x%x  sco state: %u",
+    APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): scb[0] addr: 0x%08x  in_use: %u  sco_idx: 0x%x  sco state: %u",
                        &bta_ag_cb.scb[0], bta_ag_cb.scb[0].in_use, bta_ag_cb.scb[0].sco_idx, bta_ag_cb.scb[0].state);
-    APPL_TRACE_DEBUG4 ("bta_ag_sco_disc_cback(): scb[1] addr: 0x%08x  in_use: %u  sco_idx: 0x%x  sco state: %u",
+    APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): scb[1] addr: 0x%08x  in_use: %u  sco_idx: 0x%x  sco state: %u",
                        &bta_ag_cb.scb[1], bta_ag_cb.scb[1].in_use, bta_ag_cb.scb[1].sco_idx, bta_ag_cb.scb[1].state);
 
     /* match callback to scb */
@@ -207,8 +225,8 @@
     {
 #if (BTM_SCO_HCI_INCLUDED == TRUE )
         tBTM_STATUS status = BTM_ConfigScoPath(BTM_SCO_ROUTE_PCM, NULL, NULL, TRUE);
-        APPL_TRACE_DEBUG1("bta_ag_sco_disc_cback sco close config status = %d", status);
-	    /* SCO clean up here */
+        APPL_TRACE_DEBUG("bta_ag_sco_disc_cback sco close config status = %d", status);
+        /* SCO clean up here */
         bta_dm_sco_co_close();
 #endif
 
@@ -216,14 +234,23 @@
         /* Restore settings */
         if(bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_CODEC_MSBC)
         {
-            BTM_SetWBSCodec (BTM_SCO_CODEC_NONE);
+            /* set_sco_codec(BTM_SCO_CODEC_NONE); we should get a close */
             BTM_WriteVoiceSettings (BTM_VOICE_SETTING_CVSD);
 
-            /* If SCO open was initiated by AG and failed for mSBC, try CVSD again. */
+            /* If SCO open was initiated by AG and failed for mSBC, then attempt
+            mSBC with T1 settings i.e. 'Safe Settings'. If this fails, then switch to CVSD */
             if (bta_ag_sco_is_opening (bta_ag_cb.sco.p_curr_scb))
             {
-                bta_ag_cb.sco.p_curr_scb->codec_fallback = TRUE;
-                APPL_TRACE_DEBUG0("Fallback to CVSD");
+                if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2)
+                {
+                     APPL_TRACE_DEBUG("Fallback to mSBC T1 settings");
+                     bta_ag_cb.sco.p_curr_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T1;
+                }
+                else
+                {
+                    APPL_TRACE_DEBUG("Fallback to CVSD settings");
+                    bta_ag_cb.sco.p_curr_scb->codec_fallback = TRUE;
+                }
             }
         }
 
@@ -240,7 +267,7 @@
     /* no match found */
     else
     {
-        APPL_TRACE_DEBUG0("no scb for ag_sco_disc_cback");
+        APPL_TRACE_DEBUG("no scb for ag_sco_disc_cback");
 
         /* sco could be closed after scb dealloc'ed */
         if (bta_ag_cb.sco.p_curr_scb != NULL)
@@ -266,7 +293,7 @@
 {
     if (status != BTM_SCO_DATA_CORRECT)
     {
-        APPL_TRACE_DEBUG1("bta_ag_sco_read_cback: status(%d)", status);
+        APPL_TRACE_DEBUG("bta_ag_sco_read_cback: status(%d)", status);
     }
 
     /* Callout function must free the data. */
@@ -294,7 +321,7 @@
         {
             status = BTM_RemoveSco(p_scb->sco_idx);
 
-            APPL_TRACE_DEBUG2("ag remove sco: inx 0x%04x, status:0x%x", p_scb->sco_idx, status);
+            APPL_TRACE_DEBUG("ag remove sco: inx 0x%04x, status:0x%x", p_scb->sco_idx, status);
 
             if (status == BTM_CMD_STARTED)
             {
@@ -341,7 +368,7 @@
             /* If no other SCO active, allow this one */
             if (!bta_ag_cb.sco.p_curr_scb)
             {
-                APPL_TRACE_EVENT1("bta_ag_esco_connreq_cback: Accept Conn Request (sco_inx 0x%04x)", sco_inx);
+                APPL_TRACE_EVENT("bta_ag_esco_connreq_cback: Accept Conn Request (sco_inx 0x%04x)", sco_inx);
                 bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
 
                 bta_ag_cb.sco.state = BTA_AG_SCO_OPENING_ST;
@@ -350,14 +377,14 @@
             }
             else    /* Begin a transfer: Close current SCO before responding */
             {
-                APPL_TRACE_DEBUG0("bta_ag_esco_connreq_cback: Begin XFER");
+                APPL_TRACE_DEBUG("bta_ag_esco_connreq_cback: Begin XFER");
                 bta_ag_cb.sco.p_xfer_scb = p_scb;
                 bta_ag_cb.sco.conn_data = p_data->conn_evt;
                 bta_ag_cb.sco.state = BTA_AG_SCO_OPEN_XFER_ST;
 
                 if (!bta_ag_remove_sco(bta_ag_cb.sco.p_curr_scb, TRUE))
                 {
-                    APPL_TRACE_ERROR1("bta_ag_esco_connreq_cback: Nothing to remove so accept Conn Request (sco_inx 0x%04x)", sco_inx);
+                    APPL_TRACE_ERROR("bta_ag_esco_connreq_cback: Nothing to remove so accept Conn Request (sco_inx 0x%04x)", sco_inx);
                     bta_ag_cb.sco.p_xfer_scb = NULL;
                     bta_ag_cb.sco.state = BTA_AG_SCO_LISTEN_ST;
 
@@ -368,14 +395,14 @@
         /* If error occurred send reject response immediately */
         else
         {
-            APPL_TRACE_WARNING0("no scb for bta_ag_esco_connreq_cback or no resources");
+            APPL_TRACE_WARNING("no scb for bta_ag_esco_connreq_cback or no resources");
             BTM_EScoConnRsp(p_data->conn_evt.sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, NULL);
         }
     }
     /* Received a change in the esco link */
     else if (event == BTM_ESCO_CHG_EVT)
     {
-        APPL_TRACE_EVENT5("eSCO change event (inx %d): rtrans %d, rxlen %d, txlen %d, txint %d",
+        APPL_TRACE_EVENT("eSCO change event (inx %d): rtrans %d, rxlen %d, txlen %d, txint %d",
             p_data->chg_evt.sco_inx,
             p_data->chg_evt.retrans_window, p_data->chg_evt.rx_pkt_len,
             p_data->chg_evt.tx_pkt_len, p_data->chg_evt.tx_interval);
@@ -431,7 +458,7 @@
     /* Make sure this sco handle is not already in use */
     if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX)
     {
-        APPL_TRACE_WARNING1("bta_ag_create_sco: Index 0x%04x Already In Use!",
+        APPL_TRACE_WARNING("bta_ag_create_sco: Index 0x%04x Already In Use!",
                              p_scb->sco_idx);
         return;
     }
@@ -450,11 +477,23 @@
         p_scb->codec_updated = TRUE;
     }
 
+    /* If WBS included, use CVSD by default, index is 0 for CVSD by initialization */
+    /* If eSCO codec is mSBC, index is T2 or T1 */
     if (esco_codec == BTM_SCO_CODEC_MSBC)
-        codec_index = esco_codec - 1;
+    {
+        if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2)
+        {
+            codec_index = BTA_AG_ESCO_SETTING_IDX_T2;
+        }
+        else
+        {
+            codec_index = BTA_AG_ESCO_SETTING_IDX_T1;
+        }
+    }
 
     params = bta_ag_esco_params[codec_index];
 #else
+    /* When WBS is not included, use CVSD by default */
     params = bta_ag_esco_params;
 #endif
 
@@ -464,7 +503,7 @@
     if(!bta_ag_cb.sco.param_updated)
     {
 #if (BTM_WBS_INCLUDED == TRUE)
-        if (!codec_index)   /* For non-WBS */
+        if (esco_codec == BTM_SCO_CODEC_CVSD)   /* For CVSD */
 #endif
         {
             /* Use the application packet types (5 slot EV packets not allowed) */
@@ -491,23 +530,23 @@
                 if (esco_codec != BTA_AG_CODEC_MSBC)
                 {
                     p_scb->retry_with_sco_only = TRUE;
-                    APPL_TRACE_API0("Setting retry_with_sco_only to TRUE");
+                    APPL_TRACE_API("Setting retry_with_sco_only to TRUE");
                 }
                 else    /* Do not use SCO when using mSBC */
                 {
                     p_scb->retry_with_sco_only = FALSE;
-                    APPL_TRACE_API0("Setting retry_with_sco_only to FALSE");
+                    APPL_TRACE_API("Setting retry_with_sco_only to FALSE");
                 }
 #else
                 p_scb->retry_with_sco_only = TRUE;
-                APPL_TRACE_API0("Setting retry_with_sco_only to TRUE");
+                APPL_TRACE_API("Setting retry_with_sco_only to TRUE");
 #endif
             }
         }
         else
         {
             if(p_scb->retry_with_sco_only)
-                APPL_TRACE_API0("retrying with SCO only");
+                APPL_TRACE_API("retrying with SCO only");
             p_scb->retry_with_sco_only = FALSE;
 
             BTM_SetEScoMode(BTM_LINK_TYPE_SCO, &params);
@@ -518,8 +557,23 @@
         /* tell sys to stop av if any */
         bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
 
+#if (BTM_WBS_INCLUDED == TRUE )
+        /* Allow any platform specific pre-SCO set up to take place */
+        bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP,\
+        esco_codec);
+
+        /* This setting may not be necessary */
+        /* To be verified with stable 2049 boards */
+        if (esco_codec == BTA_AG_CODEC_MSBC)
+            BTM_WriteVoiceSettings (BTM_VOICE_SETTING_TRANS);
+        else
+            BTM_WriteVoiceSettings (BTM_VOICE_SETTING_CVSD);
+        /* save the current codec because sco_codec can be updated while SCO is open. */
+        p_scb->inuse_codec = esco_codec;
+#else
         /* Allow any platform specific pre-SCO set up to take place */
         bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP);
+#endif
 
 #if (BTM_SCO_HCI_INCLUDED == TRUE )
 #if (BTM_WBS_INCLUDED == TRUE)
@@ -532,26 +586,6 @@
         sco_route = bta_dm_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, p_scb->app_id);
 #endif
 
-#if (BTM_WBS_INCLUDED == TRUE )
-        if (esco_codec == BTA_AG_CODEC_MSBC)
-        {
-            /* Enable mSBC codec in fw */
-            BTM_SetWBSCodec (esco_codec);
-        }
-
-        /* Specify PCM input for SBC codec in fw */
-        BTM_ConfigI2SPCM (esco_codec, (UINT8)HCI_BRCM_I2SPCM_IS_DEFAULT_ROLE, (UINT8)HCI_BRCM_I2SPCM_SAMPLE_DEFAULT, (UINT8)HCI_BRCM_I2SPCM_CLOCK_DEFAULT);
-
-        /* This setting may not be necessary */
-        /* To be verified with stable 2049 boards */
-        if (esco_codec == BTA_AG_CODEC_MSBC)
-            BTM_WriteVoiceSettings (BTM_VOICE_SETTING_TRANS);
-        else
-            BTM_WriteVoiceSettings (BTM_VOICE_SETTING_CVSD);
-
-        /* save the current codec because sco_codec can be updated while SCO is open. */
-        p_scb->inuse_codec = esco_codec;
-#endif
 
 #if (BTM_SCO_HCI_INCLUDED == TRUE )
         /* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */
@@ -579,13 +613,32 @@
         }
     }
 
-    APPL_TRACE_API4("ag create sco: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x",
+    APPL_TRACE_API("ag create sco: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x",
                       is_orig, p_scb->sco_idx, status, params.packet_types);
 }
 
 #if (BTM_WBS_INCLUDED == TRUE )
 /*******************************************************************************
 **
+** Function         bta_ag_attempt_msbc_safe_settings
+**
+** Description    Checks if ESCO connection needs to be attempted using mSBC T1(safe) settings
+**
+**
+** Returns          TRUE if T1 settings has to be used, FALSE otherwise
+**
+*******************************************************************************/
+BOOLEAN bta_ag_attempt_msbc_safe_settings(tBTA_AG_SCB *p_scb)
+{
+    if (p_scb->svc_conn && p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
+        p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+/*******************************************************************************
+**
 ** Function         bta_ag_cn_timer_cback
 **
 ** Description
@@ -627,7 +680,9 @@
 {
     bta_ag_cb.sco.p_curr_scb = p_scb;
 
-    if (p_scb->codec_updated || p_scb->codec_fallback)
+    if ((p_scb->codec_updated || p_scb->codec_fallback ||
+        bta_ag_attempt_msbc_safe_settings(p_scb)) &&
+       (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC))
     {
         /* Change the power mode to Active until sco open is completed. */
         bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
@@ -643,10 +698,11 @@
     else
     {
         /* use same codec type as previous SCO connection, skip codec negotiation */
+        APPL_TRACE_DEBUG("use same codec type as previous SCO connection,skip codec negotiation");
         bta_ag_sco_codec_nego(p_scb, TRUE);
     }
 }
-#endif
+#endif /* (BTM_WBS_INCLUDED == TRUE ) */
 
 /*******************************************************************************
 **
@@ -670,12 +726,12 @@
 #if BTA_AG_SCO_DEBUG == TRUE
     UINT8   in_state = p_sco->state;
 
-    APPL_TRACE_EVENT5("BTA ag sco evt (hdl 0x%04x): State %d (%s), Event %d (%s)",
+    APPL_TRACE_EVENT("BTA ag sco evt (hdl 0x%04x): State %d (%s), Event %d (%s)",
                         p_scb->sco_idx,
                         p_sco->state, bta_ag_sco_state_str(p_sco->state),
                         event, bta_ag_sco_evt_str(event));
 #else
-    APPL_TRACE_EVENT3("BTA ag sco evt (hdl 0x%04x): State %d, Event %d",
+    APPL_TRACE_EVENT("BTA ag sco evt (hdl 0x%04x): State %d, Event %d",
                       p_scb->sco_idx, p_sco->state, event);
 #endif
 
@@ -712,7 +768,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -757,7 +813,7 @@
                 case BTA_AG_SCO_CLOSE_E:
                     /* remove listening connection */
                     /* Ignore the event. We need to keep listening SCO for the active SLC */
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event);
                     break;
 
                 case BTA_AG_SCO_CONN_CLOSE_E:
@@ -767,7 +823,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -819,7 +875,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_CODEC_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_CODEC_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -878,7 +934,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_OPENING_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_OPENING_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -923,7 +979,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_OPEN_CL_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_CL_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -959,7 +1015,7 @@
                      break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -1012,7 +1068,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_OPEN_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -1059,7 +1115,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_CLOSING_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_CLOSING_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -1096,7 +1152,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -1145,7 +1201,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -1202,7 +1258,7 @@
                     break;
 
                 default:
-                    APPL_TRACE_WARNING1("BTA_AG_SCO_SHUTTING_ST: Ignoring event %d", event);
+                    APPL_TRACE_WARNING("BTA_AG_SCO_SHUTTING_ST: Ignoring event %d", event);
                     break;
             }
             break;
@@ -1213,7 +1269,7 @@
 #if BTA_AG_SCO_DEBUG == TRUE
     if (p_sco->state != in_state)
     {
-        APPL_TRACE_EVENT3("BTA AG SCO State Change: [%s] -> [%s] after Event [%s]",
+        APPL_TRACE_EVENT("BTA AG SCO State Change: [%s] -> [%s] after Event [%s]",
                       bta_ag_sco_state_str(in_state),
                       bta_ag_sco_state_str(p_sco->state),
                       bta_ag_sco_evt_str(event));
@@ -1333,7 +1389,7 @@
     if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX)
 #endif
     {
-        APPL_TRACE_DEBUG1("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx);
+        APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx);
         bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
     }
 }
@@ -1399,7 +1455,12 @@
 
     bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
 
+#if (BTM_WBS_INCLUDED == TRUE)
+    bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_ON,
+                          p_scb->inuse_codec);
+#else
     bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_ON);
+#endif
 
 #if (BTM_SCO_HCI_INCLUDED == TRUE )
     /* open SCO codec if SCO is routed through transport */
@@ -1410,6 +1471,10 @@
     bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
 
     p_scb->retry_with_sco_only = FALSE;
+#if (BTM_WBS_INCLUDED == TRUE)
+    /* reset to mSBC T2 settings as the preferred */
+    p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
+#endif
 }
 
 /*******************************************************************************
@@ -1433,7 +1498,9 @@
 
 #if (BTM_WBS_INCLUDED == TRUE)
     /* codec_fallback is set when AG is initiator and connection failed for mSBC. */
-    if (p_scb->codec_fallback && p_scb->svc_conn)
+    /* OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
+    if ((p_scb->codec_fallback && p_scb->svc_conn) ||
+         bta_ag_attempt_msbc_safe_settings(p_scb))
     {
         bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
     }
@@ -1452,12 +1519,15 @@
 #endif
     else
     {
+#if (BTM_WBS_INCLUDED == TRUE)
         /* Indicate if the closing of audio is because of transfer */
-        if (bta_ag_cb.sco.p_xfer_scb)
-            bta_ag_co_audio_state(handle, p_scb->app_id, BTA_AG_CO_AUD_STATE_OFF_XFER);
-        else
-            bta_ag_co_audio_state(handle, p_scb->app_id, BTA_AG_CO_AUD_STATE_OFF);
-
+        bta_ag_co_audio_state(handle, p_scb->app_id,(bta_ag_cb.sco.p_xfer_scb)?\
+        BTA_AG_CO_AUD_STATE_OFF_XFER:BTA_AG_CO_AUD_STATE_OFF,p_scb->inuse_codec);
+#else
+        /* Indicate if the closing of audio is because of transfer */
+        bta_ag_co_audio_state(handle, p_scb->app_id,(bta_ag_cb.sco.p_xfer_scb)?\
+        BTA_AG_CO_AUD_STATE_OFF_XFER:BTA_AG_CO_AUD_STATE_OFF);
+#endif
         bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E);
 
         bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
@@ -1472,6 +1542,9 @@
 
         /* call app callback */
         bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
+#if (BTM_WBS_INCLUDED == TRUE)
+        p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
+#endif
     }
     p_scb->retry_with_sco_only = FALSE;
 }
@@ -1531,12 +1604,14 @@
         /* tell sys to stop av if any */
         bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
 
+#if (BTM_WBS_INCLUDED == FALSE )
         /* Allow any platform specific pre-SCO set up to take place */
         bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP);
-
-#if (BTM_WBS_INCLUDED == TRUE )
+#else
         /* When HS initiated SCO, it cannot be WBS. */
-        BTM_ConfigI2SPCM (BTM_SCO_CODEC_CVSD, (UINT8)HCI_BRCM_I2SPCM_IS_DEFAULT_ROLE, (UINT8)HCI_BRCM_I2SPCM_SAMPLE_DEFAULT, (UINT8)HCI_BRCM_I2SPCM_CLOCK_DEFAULT);
+        /* Allow any platform specific pre-SCO set up to take place */
+        bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP,
+                              BTA_AG_CODEC_CVSD);
 #endif
 
 #if (BTM_SCO_HCI_INCLUDED == TRUE )
@@ -1593,13 +1668,13 @@
     if(set_reset == FALSE)    /* reset the parameters to default */
     {
         bta_ag_cb.sco.param_updated = FALSE;
-        APPL_TRACE_DEBUG0("bta_ag_set_esco_param : Resetting ESCO parameters to default");
+        APPL_TRACE_DEBUG("bta_ag_set_esco_param : Resetting ESCO parameters to default");
     }
     else
     {
         bta_ag_cb.sco.param_updated = TRUE;
         bta_ag_cb.sco.params = *param;
-        APPL_TRACE_DEBUG0("bta_ag_set_esco_param : Setting ESCO parameters");
+        APPL_TRACE_DEBUG("bta_ag_set_esco_param : Setting ESCO parameters");
     }
 }
 
diff --git a/bta/ag/bta_ag_sdp.c b/bta/ag/bta_ag_sdp.c
index 333cb1b..8099d5f 100644
--- a/bta/ag/bta_ag_sdp.c
+++ b/bta/ag/bta_ag_sdp.c
@@ -74,7 +74,7 @@
     UINT16              event;
     tBTA_AG_SCB         *p_scb;
 
-    APPL_TRACE_DEBUG1("bta_ag_sdp_cback status:0x%x", status);
+    APPL_TRACE_DEBUG("bta_ag_sdp_cback status:0x%x", status);
 
     if ((p_scb = bta_ag_scb_by_idx(idx)) != NULL)
     {
@@ -140,7 +140,7 @@
     BOOLEAN             codec_supported = FALSE;
     UINT8               buf[2];
 
-    APPL_TRACE_DEBUG1("bta_ag_add_record uuid: %x", service_uuid);
+    APPL_TRACE_DEBUG("bta_ag_add_record uuid: %x", service_uuid);
 
     memset( proto_elem_list, 0 , BTA_AG_NUM_PROTO_ELEMS*sizeof(tSDP_PROTOCOL_ELEM));
 
@@ -280,7 +280,7 @@
         /* if service registered for this scb and not registered for any other scb */
         if (((services & 1) == 1) && ((others & 1) == 0))
         {
-            APPL_TRACE_DEBUG1("bta_ag_del_records %d", i);
+            APPL_TRACE_DEBUG("bta_ag_del_records %d", i);
             if (bta_ag_cb.profile[i].sdp_handle != 0)
             {
                 SDP_DeleteRecord(bta_ag_cb.profile[i].sdp_handle);
diff --git a/bta/ar/bta_ar.c b/bta/ar/bta_ar.c
index 89b732a..25b27d3 100644
--- a/bta/ar/bta_ar.c
+++ b/bta/ar/bta_ar.c
@@ -115,7 +115,7 @@
 #if (BTA_AR_DEBUG == TRUE)
     else
     {
-        APPL_TRACE_ERROR1("bta_ar_reg_avdt: the registration is from wrong sys_id:%d", sys_id);
+        APPL_TRACE_ERROR("bta_ar_reg_avdt: the registration is from wrong sys_id:%d", sys_id);
     }
 #endif
 
diff --git a/bta/av/bta_av_aact.c b/bta/av/bta_av_aact.c
index fed838a..e8e5edc 100644
--- a/bta/av/bta_av_aact.c
+++ b/bta/av/bta_av_aact.c
@@ -193,6 +193,7 @@
     0                               /* AVDT_DELAY_REPORT_CFM_EVT */
 };
 
+void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt);
 static void bta_av_stream0_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
 static void bta_av_stream1_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
 #if BTA_AV_NUM_STRS > 2
@@ -225,6 +226,48 @@
     ,bta_av_stream5_cback
 #endif
 };
+/***********************************************
+**
+** Function         bta_get_scb_handle
+**
+** Description      gives the registered AVDT handle.by checking with sep_type.
+**
+**
+** Returns          void
+***********************************************/
+UINT8  bta_av_get_scb_handle ( tBTA_AV_SCB *p_scb, UINT8 local_sep )
+{
+    UINT8 xx =0;
+    for (xx = 0; xx<BTA_AV_MAX_SEPS; xx++)
+    {
+        if ((p_scb->seps[xx].tsep == local_sep) &&
+            (p_scb->seps[xx].codec_type == p_scb->codec_type))
+            return (p_scb->seps[xx].av_handle);
+    }
+    APPL_TRACE_DEBUG(" bta_av_get_scb_handle appropiate sep_type not found")
+    return 0; /* return invalid handle */
+}
+
+/***********************************************
+**
+** Function         bta_av_get_scb_sep_type
+**
+** Description      gives the sep type by cross-checking with AVDT handle
+**
+**
+** Returns          void
+***********************************************/
+UINT8  bta_av_get_scb_sep_type ( tBTA_AV_SCB *p_scb, UINT8 tavdt_handle)
+{
+    UINT8 xx =0;
+    for (xx = 0; xx<BTA_AV_MAX_SEPS; xx++)
+    {
+        if (p_scb->seps[xx].av_handle == tavdt_handle)
+            return (p_scb->seps[xx].tsep);
+    }
+    APPL_TRACE_DEBUG(" bta_av_get_scb_sep_type appropiate handle not found")
+    return 3; /* return invalid sep type */
+}
 
 /*******************************************************************************
 **
@@ -238,11 +281,11 @@
 *******************************************************************************/
 static void bta_av_save_addr(tBTA_AV_SCB *p_scb, const BD_ADDR b)
 {
-    APPL_TRACE_DEBUG2("bta_av_save_addr r:%d, s:%d",
+    APPL_TRACE_DEBUG("bta_av_save_addr r:%d, s:%d",
         p_scb->recfg_sup, p_scb->suspend_sup);
     if(bdcmp(p_scb->peer_addr, b) != 0)
     {
-        APPL_TRACE_ERROR0("reset flags");
+        APPL_TRACE_ERROR("reset flags");
         /* a new addr, reset the supported flags */
         p_scb->recfg_sup    = TRUE;
         p_scb->suspend_sup  = TRUE;
@@ -290,7 +333,7 @@
 {
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG2("bta_av_st_rc_timer rc_handle:%d, use_rc: %d",
+    APPL_TRACE_DEBUG("bta_av_st_rc_timer rc_handle:%d, use_rc: %d",
         p_scb->rc_handle, p_scb->use_rc);
     /* for outgoing RC connection as INT/CT */
     if( (p_scb->rc_handle == BTA_AV_RC_HANDLE_NONE) &&
@@ -320,12 +363,19 @@
     int     i;
     tAVDT_GETCAP_REQ    *p_req;
     BOOLEAN     sent_cmd = FALSE;
+    UINT16 uuid_int = p_scb->uuid_int;
+    UINT8 sep_requested = 0;
+
+    if(uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
+       sep_requested = AVDT_TSEP_SNK;
+    else if(uuid_int == UUID_SERVCLASS_AUDIO_SINK)
+       sep_requested = AVDT_TSEP_SRC;
 
     for (i = p_scb->sep_info_idx; i < p_scb->num_seps; i++)
     {
         /* steam not in use, is a sink, and is the right media type (audio/video) */
         if ((p_scb->sep_info[i].in_use == FALSE) &&
-            (p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
+            (p_scb->sep_info[i].tsep == sep_requested) &&
             (p_scb->sep_info[i].media_type == p_scb->media_type))
         {
             p_scb->sep_info_idx = i;
@@ -405,7 +455,7 @@
         if (bd_addr != NULL)
         {
             bdcpy(p_msg->bd_addr, bd_addr);
-            APPL_TRACE_DEBUG6("  bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
+            APPL_TRACE_DEBUG("  bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
                           bd_addr[0], bd_addr[1],
                           bd_addr[2], bd_addr[3],
                           bd_addr[4], bd_addr[5]);
@@ -418,7 +468,7 @@
             switch (event)
             {
             case AVDT_RECONFIG_CFM_EVT:
-            APPL_TRACE_DEBUG4("reconfig cfm event codec info = 0x%06x-%06x-%06x-%02x",
+            APPL_TRACE_DEBUG("reconfig cfm event codec info = 0x%06x-%06x-%06x-%02x",
                 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[0]<<16)+(p_msg->msg.reconfig_cfm.p_cfg->codec_info[1]<<8)+p_msg->msg.reconfig_cfm.p_cfg->codec_info[2],
                 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[3]<<16)+(p_msg->msg.reconfig_cfm.p_cfg->codec_info[4]<<8)+p_msg->msg.reconfig_cfm.p_cfg->codec_info[5],
                 (p_msg->msg.reconfig_cfm.p_cfg->codec_info[6]<<16)+(p_msg->msg.reconfig_cfm.p_cfg->codec_info[7]<<8)+p_msg->msg.reconfig_cfm.p_cfg->codec_info[8],
@@ -494,7 +544,7 @@
         if (event == AVDT_SUSPEND_CFM_EVT)
             p_msg->initiator = TRUE;
 
-        APPL_TRACE_VERBOSE1("hndl:x%x", p_scb->hndl);
+        APPL_TRACE_VERBOSE("hndl:x%x", p_scb->hndl);
         p_msg->hdr.layer_specific = p_scb->hndl;
         p_msg->handle   = handle;
         p_msg->avdt_event = event;
@@ -509,6 +559,39 @@
 
 /*******************************************************************************
 **
+** Function         bta_av_stream_data_cback
+**
+** Description      This is the AVDTP callback function for stream events.
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt)
+{
+    int index = 0;
+    tBTA_AV_SCB         *p_scb ;
+    APPL_TRACE_DEBUG("bta_av_stream_data_cback avdt_handle: %d pkt_len=0x%x  ofst = 0x%x", handle,p_pkt->len,p_pkt->offset);
+    APPL_TRACE_DEBUG(" Number of frames 0x%x",*((UINT8*)(p_pkt + 1) + p_pkt->offset));
+    APPL_TRACE_DEBUG("Sequence Number 0x%x",p_pkt->layer_specific);
+    /* Get  SCB  and correct sep type*/
+    for(index = 0; index < BTA_AV_NUM_STRS;index ++ )
+    {
+        p_scb = bta_av_cb.p_scb[index];
+        if((p_scb->avdt_handle == handle)&&(p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK))
+            break;
+    }
+    if(index == BTA_AV_NUM_STRS) /* cannot find correct handler */
+    {
+        GKI_freebuf(p_pkt);
+        return;
+    }
+    p_pkt->event = BTA_AV_MEDIA_DATA_EVT;
+    p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_DATA_EVT, (tBTA_AV_MEDIA*)p_pkt);
+    GKI_freebuf(p_pkt);  /* a copy of packet had been delivered, we free this buffer */
+}
+
+/*******************************************************************************
+**
 ** Function         bta_av_stream0_cback
 **
 ** Description      This is the AVDTP callback function for stream events.
@@ -518,7 +601,7 @@
 *******************************************************************************/
 static void bta_av_stream0_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
 {
-    APPL_TRACE_VERBOSE2("bta_av_stream0_cback avdt_handle: %d event=0x%x", handle, event);
+    APPL_TRACE_VERBOSE("bta_av_stream0_cback avdt_handle: %d event=0x%x", handle, event);
     bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 0);
 }
 
@@ -533,7 +616,7 @@
 *******************************************************************************/
 static void bta_av_stream1_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
 {
-    APPL_TRACE_EVENT2("bta_av_stream1_cback avdt_handle: %d event=0x%x", handle, event);
+    APPL_TRACE_EVENT("bta_av_stream1_cback avdt_handle: %d event=0x%x", handle, event);
     bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 1);
 }
 
@@ -549,7 +632,7 @@
 *******************************************************************************/
 static void bta_av_stream2_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
 {
-    APPL_TRACE_EVENT2("bta_av_stream2_cback avdt_handle: %d event=0x%x", handle, event);
+    APPL_TRACE_EVENT("bta_av_stream2_cback avdt_handle: %d event=0x%x", handle, event);
     bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 2);
 }
 #endif
@@ -566,7 +649,7 @@
 *******************************************************************************/
 static void bta_av_stream3_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
 {
-    APPL_TRACE_EVENT2("bta_av_stream3_cback avdt_handle: %d event=0x%x", handle, event);
+    APPL_TRACE_EVENT("bta_av_stream3_cback avdt_handle: %d event=0x%x", handle, event);
     bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 3);
 }
 #endif
@@ -583,7 +666,7 @@
 #if BTA_AV_NUM_STRS > 4
 static void bta_av_stream4_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
 {
-    APPL_TRACE_EVENT2("bta_av_stream4_cback avdt_handle: %d event=0x%x", handle, event);
+    APPL_TRACE_EVENT("bta_av_stream4_cback avdt_handle: %d event=0x%x", handle, event);
     bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 4);
 }
 #endif
@@ -600,7 +683,7 @@
 #if BTA_AV_NUM_STRS > 5
 static void bta_av_stream5_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
 {
-    APPL_TRACE_EVENT2("bta_av_stream5_cback avdt_handle: %d event=0x%x", handle, event);
+    APPL_TRACE_EVENT("bta_av_stream5_cback avdt_handle: %d event=0x%x", handle, event);
     bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 5);
 }
 #endif
@@ -636,7 +719,7 @@
         }
         else
         {
-            APPL_TRACE_ERROR1 ("bta_av_a2d_sdp_cback, no scb found for handle(0x%x)", bta_av_cb.handle);
+            APPL_TRACE_ERROR ("bta_av_a2d_sdp_cback, no scb found for handle(0x%x)", bta_av_cb.handle);
         }
     }
 }
@@ -650,16 +733,16 @@
 ** Returns
 **
 *******************************************************************************/
-static void bta_av_adjust_seps_idx(tBTA_AV_SCB *p_scb)
+static void bta_av_adjust_seps_idx(tBTA_AV_SCB *p_scb, UINT8 avdt_handle)
 {
-    int             xx;
-
-    APPL_TRACE_DEBUG1("bta_av_adjust_seps_idx codec_type: %d", p_scb->codec_type);
+    int xx;
+    APPL_TRACE_DEBUG("bta_av_adjust_seps_idx codec_type: %d", p_scb->codec_type);
     for(xx=0; xx<BTA_AV_MAX_SEPS; xx++)
     {
-        APPL_TRACE_DEBUG2("av_handle: %d codec_type: %d",
+        APPL_TRACE_DEBUG("av_handle: %d codec_type: %d",
             p_scb->seps[xx].av_handle, p_scb->seps[xx].codec_type);
-        if(p_scb->seps[xx].av_handle && p_scb->codec_type == p_scb->seps[xx].codec_type)
+        if((p_scb->seps[xx].av_handle && p_scb->codec_type == p_scb->seps[xx].codec_type)
+            && (p_scb->seps[xx].av_handle == avdt_handle))
         {
             p_scb->sep_idx      = xx;
             p_scb->avdt_handle  = p_scb->seps[xx].av_handle;
@@ -684,7 +767,7 @@
     tBTA_AV_API_OPEN  *p_buf = &p_scb->q_info.open;
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG1("bta_av_switch_role wait:x%x", p_scb->wait);
+    APPL_TRACE_DEBUG("bta_av_switch_role wait:x%x", p_scb->wait);
     if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_START)
         p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RETRY;
 
@@ -739,7 +822,7 @@
     tBTA_AV_START   start;
     tBTA_AV_OPEN    av_open;
 
-    APPL_TRACE_DEBUG3("bta_av_role_res q_tag:%d, wait:x%x, role:x%x", p_scb->q_tag, p_scb->wait, p_scb->role);
+    APPL_TRACE_DEBUG("bta_av_role_res q_tag:%d, wait:x%x, role:x%x", p_scb->q_tag, p_scb->wait, p_scb->role);
     if (p_scb->role & BTA_AV_ROLE_START_INT)
         initiator = TRUE;
 
@@ -781,6 +864,10 @@
                 av_open.chnl   = p_scb->chnl;
                 av_open.hndl   = p_scb->hndl;
                 start.status = BTA_AV_FAIL_ROLE;
+                if(p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC )
+                    av_open.sep = AVDT_TSEP_SNK;
+                else if(p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK )
+                    av_open.sep = AVDT_TSEP_SRC;
                 (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV *)&av_open);
             }
             else
@@ -792,11 +879,11 @@
         }
         else
         {
-            APPL_TRACE_WARNING2 ("Unexpected role switch event: q_tag = %d wait = %d", p_scb->q_tag, p_scb->wait);
+            APPL_TRACE_WARNING ("Unexpected role switch event: q_tag = %d wait = %d", p_scb->q_tag, p_scb->wait);
         }
     }
 
-    APPL_TRACE_DEBUG2("wait:x%x, role:x%x", p_scb->wait, p_scb->role);
+    APPL_TRACE_DEBUG("wait:x%x, role:x%x", p_scb->wait, p_scb->role);
 }
 
 /*******************************************************************************
@@ -830,8 +917,9 @@
     UINT16              attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
                                        ATTR_ID_PROTOCOL_DESC_LIST,
                                        ATTR_ID_BT_PROFILE_DESC_LIST};
+    UINT16 sdp_uuid = 0; /* UUID for which SDP has to be done */
 
-    APPL_TRACE_DEBUG3("bta_av_do_disc_a2d use_rc: %d rs:%d, oc:%d",
+    APPL_TRACE_DEBUG("bta_av_do_disc_a2d use_rc: %d rs:%d, oc:%d",
         p_data->api_open.use_rc, p_data->api_open.switch_res, bta_av_cb.audio_open_cnt);
 
     memcpy (&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN));
@@ -876,7 +964,7 @@
         break;
     }
 
-    APPL_TRACE_DEBUG3("ok_continue: %d wait:x%x, q_tag: %d", ok_continue, p_scb->wait, p_scb->q_tag);
+    APPL_TRACE_DEBUG("ok_continue: %d wait:x%x, q_tag: %d", ok_continue, p_scb->wait, p_scb->q_tag);
     if (!ok_continue)
         return;
 
@@ -891,13 +979,13 @@
 
     if (bta_av_cb.features & BTA_AV_FEAT_MASTER)
     {
-    L2CA_SetDesireRole(L2CAP_ROLE_DISALLOW_SWITCH);
+        L2CA_SetDesireRole(L2CAP_ROLE_DISALLOW_SWITCH);
 
-    if (bta_av_cb.audio_open_cnt == 1)
-    {
-        /* there's already an A2DP connection. do not allow switch */
-        bta_sys_clear_default_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH);
-    }
+        if (bta_av_cb.audio_open_cnt == 1)
+        {
+            /* there's already an A2DP connection. do not allow switch */
+            bta_sys_clear_default_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH);
+        }
     }
     /* store peer addr other parameters */
     bta_av_save_addr(p_scb, p_data->api_open.bd_addr);
@@ -922,8 +1010,14 @@
         db_params.num_attr = 3;
         db_params.p_db = p_scb->p_disc_db;
         db_params.p_attrs = attr_list;
+        p_scb->uuid_int = p_data->api_open.uuid;
+        if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SINK)
+            sdp_uuid = UUID_SERVCLASS_AUDIO_SOURCE;
+        else if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
+            sdp_uuid = UUID_SERVCLASS_AUDIO_SINK;
 
-        if(A2D_FindService(UUID_SERVCLASS_AUDIO_SINK, p_scb->peer_addr, &db_params,
+        APPL_TRACE_DEBUG("uuid_int 0x%x, Doing SDP For 0x%x", p_scb->uuid_int, sdp_uuid);
+        if(A2D_FindService(sdp_uuid, p_scb->peer_addr, &db_params,
                         bta_av_a2d_sdp_cback) == A2D_SUCCESS)
         {
             return;
@@ -951,7 +1045,7 @@
     UINT8           role = BTA_AV_ROLE_AD_INT;
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG0("bta_av_cleanup");
+    APPL_TRACE_DEBUG("bta_av_cleanup");
 
     /* free any buffers */
     utl_freebuf((void **) &p_scb->p_cap);
@@ -1021,8 +1115,12 @@
     tAVDT_SEP_INFO       *p_info;
     tAVDT_CFG            *p_evt_cfg = &p_data->str_msg.cfg;
     UINT8   psc_mask = (p_evt_cfg->psc_mask | p_scb->cfg.psc_mask);
+    UINT8 local_sep;    /* sep type of local handle on which connection was received */
+    UINT8 count = 0;
+    tBTA_AV_STR_MSG  *p_msg = (tBTA_AV_STR_MSG *)p_data;
     UNUSED(p_data);
 
+    local_sep = bta_av_get_scb_sep_type(p_scb, p_msg->handle);
     p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
     memcpy(p_scb->cfg.codec_info, p_evt_cfg->codec_info, AVDT_CODEC_SIZE);
     p_scb->codec_type = p_evt_cfg->codec_info[BTA_AV_CODEC_TYPE_IDX];
@@ -1048,7 +1146,13 @@
         p_info->in_use = 0;
         p_info->media_type = p_scb->media_type;
         p_info->seid = p_data->str_msg.msg.config_ind.int_seid;
-        p_info->tsep = AVDT_TSEP_SNK;
+
+        /* Sep type of Peer will be oppsite role to our local sep */
+        if (local_sep == AVDT_TSEP_SRC)
+            p_info->tsep = AVDT_TSEP_SNK;
+        else if (local_sep == AVDT_TSEP_SNK)
+            p_info->tsep = AVDT_TSEP_SRC;
+
         p_scb->role      |= BTA_AV_ROLE_AD_ACP;
         p_scb->cur_psc_mask = p_evt_cfg->psc_mask;
         if (bta_av_cb.features & BTA_AV_FEAT_RCTG)
@@ -1058,14 +1162,30 @@
 
         p_scb->num_seps  = 1;
         p_scb->sep_info_idx = 0;
-        APPL_TRACE_DEBUG3("bta_av_config_ind: SEID: %d use_rc: %d cur_psc_mask:0x%x", p_info->seid, p_scb->use_rc, p_scb->cur_psc_mask);
-
-        p_scb->p_cos->setcfg(p_scb->hndl, p_scb->codec_type,
+        APPL_TRACE_DEBUG("bta_av_config_ind: SEID: %d use_rc: %d cur_psc_mask:0x%x", p_info->seid, p_scb->use_rc, p_scb->cur_psc_mask);
+        /*  in case of A2DP SINK this is the first time peer data is being sent to co functions */
+        if (local_sep == AVDT_TSEP_SNK)
+        {
+            p_scb->p_cos->setcfg(p_scb->hndl, p_scb->codec_type,
                              p_evt_cfg->codec_info,
                              p_info->seid,
                              p_scb->peer_addr,
                              p_evt_cfg->num_protect,
-                             p_evt_cfg->protect_info);
+                             p_evt_cfg->protect_info,
+                             AVDT_TSEP_SNK,
+                             p_msg->handle);
+        }
+        else
+        {
+            p_scb->p_cos->setcfg(p_scb->hndl, p_scb->codec_type,
+                             p_evt_cfg->codec_info,
+                             p_info->seid,
+                             p_scb->peer_addr,
+                             p_evt_cfg->num_protect,
+                             p_evt_cfg->protect_info,
+                             AVDT_TSEP_SRC,
+                             p_msg->handle);
+        }
     }
 }
 
@@ -1083,7 +1203,7 @@
     tBTA_AV_RCB *p_rcb;
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG1("bta_av_disconnect_req conn_lcb: 0x%x", bta_av_cb.conn_lcb);
+    APPL_TRACE_DEBUG("bta_av_disconnect_req conn_lcb: 0x%x", bta_av_cb.conn_lcb);
 
     bta_sys_stop_timer(&bta_av_cb.sig_tmr);
     bta_sys_stop_timer(&p_scb->timer);
@@ -1153,12 +1273,22 @@
 void bta_av_setconfig_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
 {
     UINT8   num = p_data->ci_setconfig.num_seid + 1;
+    UINT8   avdt_handle = p_data->ci_setconfig.avdt_handle;
     UINT8   *p_seid = p_data->ci_setconfig.p_seid;
     int     i;
+    UINT8   local_sep;
 
     /* we like this codec_type. find the sep_idx */
-    bta_av_adjust_seps_idx(p_scb);
-    APPL_TRACE_DEBUG2("bta_av_setconfig_rsp: sep_idx: %d cur_psc_mask:0x%x", p_scb->sep_idx, p_scb->cur_psc_mask);
+    local_sep = bta_av_get_scb_sep_type(p_scb,avdt_handle);
+    bta_av_adjust_seps_idx(p_scb, avdt_handle);
+    APPL_TRACE_DEBUG("bta_av_setconfig_rsp: sep_idx: %d cur_psc_mask:0x%x", p_scb->sep_idx, p_scb->cur_psc_mask);
+
+    if ((AVDT_TSEP_SNK == local_sep) && (p_data->ci_setconfig.err_code == AVDT_SUCCESS) &&
+                                     (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL))
+        p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT,
+                                              (tBTA_AV_MEDIA*)p_scb->cfg.codec_info);
+
+
     AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, p_data->ci_setconfig.err_code,
                    p_data->ci_setconfig.category);
 
@@ -1169,7 +1299,7 @@
         p_scb->wait = BTA_AV_WAIT_ACP_CAPS_ON;
         if(p_data->ci_setconfig.recfg_needed)
             p_scb->role |= BTA_AV_ROLE_SUSPEND_OPT;
-        APPL_TRACE_ERROR3("bta_av_setconfig_rsp recfg_needed:%d role:x%x num:%d",
+        APPL_TRACE_DEBUG("bta_av_setconfig_rsp recfg_needed:%d role:x%x num:%d",
             p_data->ci_setconfig.recfg_needed, p_scb->role, num);
         /* callout module tells BTA the number of "good" SEPs and their SEIDs.
          * getcap on these SEID */
@@ -1182,8 +1312,11 @@
         if (p_scb->codec_type == BTA_AV_CODEC_SBC || num > 1)
         {
             /* if SBC is used by the SNK as INT, discover req is not sent in bta_av_config_ind.
-             * call disc_res now */
-            p_scb->p_cos->disc_res(p_scb->hndl, num, num, p_scb->peer_addr);
+                       * call disc_res now */
+           /* this is called in A2DP SRC path only, In case of SINK we don't need it  */
+            if (local_sep == AVDT_TSEP_SRC)
+                p_scb->p_cos->disc_res(p_scb->hndl, num, num, 0, p_scb->peer_addr,
+                                                      UUID_SERVCLASS_AUDIO_SOURCE);
         }
         else
         {
@@ -1195,14 +1328,22 @@
 
         for (i = 1; i < num; i++)
         {
-            APPL_TRACE_DEBUG2("sep_info[%d] SEID: %d", i, p_seid[i-1]);
+            APPL_TRACE_DEBUG("sep_info[%d] SEID: %d", i, p_seid[i-1]);
             /* initialize the sep_info[] to get capabilities */
             p_scb->sep_info[i].in_use = FALSE;
             p_scb->sep_info[i].tsep = AVDT_TSEP_SNK;
             p_scb->sep_info[i].media_type = p_scb->media_type;
             p_scb->sep_info[i].seid = p_seid[i-1];
         }
-        bta_av_next_getcap(p_scb, p_data);
+
+        /* only in case of local sep as SRC we need to look for other SEPs, In case of SINK we don't */
+        if (local_sep == AVDT_TSEP_SRC)
+        {
+            /* Make sure UUID has been initialized... */
+            if (p_scb->uuid_int == 0)
+                p_scb->uuid_int = p_scb->open_api.uuid;
+            bta_av_next_getcap(p_scb, p_data);
+        }
     }
 }
 
@@ -1233,7 +1374,7 @@
 
     p_scb->stream_mtu = p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE;
     mtu = bta_av_chk_mtu(p_scb, p_scb->stream_mtu);
-    APPL_TRACE_DEBUG3("bta_av_str_opened l2c_cid: 0x%x stream_mtu: %d mtu: %d",
+    APPL_TRACE_DEBUG("bta_av_str_opened l2c_cid: 0x%x stream_mtu: %d mtu: %d",
         p_scb->l2c_cid, p_scb->stream_mtu, mtu);
     if(mtu == 0 || mtu > p_scb->stream_mtu)
         mtu = p_scb->stream_mtu;
@@ -1275,6 +1416,11 @@
 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
         bta_ar_avdt_conn(BTA_ID_AV, open.bd_addr);
 #endif
+        if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC )
+            open.sep = AVDT_TSEP_SNK;
+        else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK )
+            open.sep = AVDT_TSEP_SRC;
+
         (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV *) &open);
         if(open.starting)
         {
@@ -1303,7 +1449,7 @@
         protect_req.chnl    = p_scb->chnl;
         protect_req.hndl    = p_scb->hndl;
         /*
-        APPL_TRACE_EVENT1("sec ind handle: x%x", protect_req.hndl);
+        APPL_TRACE_EVENT("sec ind handle: x%x", protect_req.hndl);
         */
         protect_req.p_data  = p_data->str_msg.msg.security_ind.p_data;
         protect_req.len     = p_data->str_msg.msg.security_ind.len;
@@ -1398,7 +1544,7 @@
     {
         /* SNK initiated L2C connection while SRC was doing SDP.    */
         /* Wait until timeout to check if SNK starts signalling.    */
-        APPL_TRACE_EVENT1("bta_av_connect_req: coll_mask = 0x%2X", p_scb->coll_mask);
+        APPL_TRACE_EVENT("bta_av_connect_req: coll_mask = 0x%2X", p_scb->coll_mask);
         return;
     }
 
@@ -1436,8 +1582,11 @@
 *******************************************************************************/
 void bta_av_disc_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
 {
-    UINT8 num_snks = 0, i;
+    UINT8 num_snks = 0, num_srcs =0, i;
+    /* our uuid in case we initiate connection */
+    UINT16 uuid_int = p_scb->uuid_int;
 
+    APPL_TRACE_DEBUG(" initiator UUID 0x%x", uuid_int);
     /* store number of stream endpoints returned */
     p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps;
 
@@ -1445,15 +1594,23 @@
     {
         /* steam not in use, is a sink, and is audio */
         if ((p_scb->sep_info[i].in_use == FALSE) &&
-            (p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
             (p_scb->sep_info[i].media_type == p_scb->media_type))
         {
-            num_snks++;
+            if((p_scb->sep_info[i].tsep == AVDT_TSEP_SNK) &&
+               (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE))
+                num_snks++;
+
+            if((p_scb->sep_info[i].tsep == AVDT_TSEP_SRC) &&
+               (uuid_int == UUID_SERVCLASS_AUDIO_SINK))
+                num_srcs++;
+
         }
     }
 
-    p_scb->p_cos->disc_res(p_scb->hndl, p_scb->num_seps, num_snks, p_scb->peer_addr);
+    p_scb->p_cos->disc_res(p_scb->hndl, p_scb->num_seps, num_snks, num_srcs, p_scb->peer_addr,
+                                                                                    uuid_int);
     p_scb->num_disc_snks = num_snks;
+    p_scb->num_disc_srcs = num_srcs;
 
     /* if we got any */
     if (p_scb->num_seps > 0)
@@ -1501,9 +1658,10 @@
             num_snks++;
         }
     }
-
-    p_scb->p_cos->disc_res(p_scb->hndl, p_scb->num_seps, num_snks, p_scb->peer_addr);
+    p_scb->p_cos->disc_res(p_scb->hndl, p_scb->num_seps, num_snks, 0, p_scb->peer_addr,
+                                                          UUID_SERVCLASS_AUDIO_SOURCE);
     p_scb->num_disc_snks = num_snks;
+    p_scb->num_disc_srcs = 0;
 
     /* if we got any */
     if (p_scb->num_seps > 0)
@@ -1537,7 +1695,7 @@
     UINT8       old_wait = p_scb->wait;
     BOOLEAN     getcap_done = FALSE;
 
-    APPL_TRACE_DEBUG3("bta_av_save_caps num_seps:%d sep_info_idx:%d wait:x%x",
+    APPL_TRACE_DEBUG("bta_av_save_caps num_seps:%d sep_info_idx:%d wait:x%x",
         p_scb->num_seps, p_scb->sep_info_idx, p_scb->wait);
     memcpy(&cfg, p_scb->p_cap, sizeof(tAVDT_CFG));
     /* let application know the capability of the SNK */
@@ -1622,7 +1780,7 @@
     UINT8 idx;
     tBTA_AV_OPEN    open;
 
-    APPL_TRACE_DEBUG0("bta_av_open_failed");
+    APPL_TRACE_DEBUG("bta_av_open_failed");
     p_scb->open_status = BTA_AV_FAIL_STREAM;
     bta_av_cco_close(p_scb, p_data);
 
@@ -1648,6 +1806,11 @@
         /* set the state back to initial state */
         bta_av_set_scb_sst_init(p_scb);
 
+        if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC )
+            open.sep = AVDT_TSEP_SNK;
+        else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK )
+            open.sep = AVDT_TSEP_SRC;
+
         (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV *) &open);
 
     }
@@ -1674,6 +1837,7 @@
     tAVDT_CFG   cfg;
     UINT8       media_type;
     tAVDT_SEP_INFO  *p_info = &p_scb->sep_info[p_scb->sep_info_idx];
+    UINT16 uuid_int; /* UUID for which connection was initiatied */
 
     memcpy(&cfg, &p_scb->cfg, sizeof(tAVDT_CFG));
     cfg.num_codec = 1;
@@ -1682,10 +1846,10 @@
     memcpy(cfg.protect_info, p_scb->p_cap->protect_info, AVDT_PROTECT_SIZE);
     media_type = p_scb->p_cap->codec_info[BTA_AV_MEDIA_TYPE_IDX] >> 4;
 
-    APPL_TRACE_DEBUG1("num_codec %d", p_scb->p_cap->num_codec);
-    APPL_TRACE_DEBUG2("media type x%x, x%x", media_type, p_scb->media_type);
+    APPL_TRACE_DEBUG("num_codec %d", p_scb->p_cap->num_codec);
+    APPL_TRACE_DEBUG("media type x%x, x%x", media_type, p_scb->media_type);
 #if AVDT_MULTIPLEXING == TRUE
-    APPL_TRACE_DEBUG2("mux x%x, x%x", cfg.mux_mask, p_scb->p_cap->mux_mask);
+    APPL_TRACE_DEBUG("mux x%x, x%x", cfg.mux_mask, p_scb->p_cap->mux_mask);
 #endif
 
     /* if codec present and we get a codec configuration */
@@ -1697,16 +1861,31 @@
     {
 #if AVDT_MULTIPLEXING == TRUE
         cfg.mux_mask &= p_scb->p_cap->mux_mask;
-        APPL_TRACE_DEBUG1("mux_mask used x%x", cfg.mux_mask);
+        APPL_TRACE_DEBUG("mux_mask used x%x", cfg.mux_mask);
 #endif
         /* save copy of codec type and configuration */
         p_scb->codec_type = cfg.codec_info[BTA_AV_CODEC_TYPE_IDX];
         memcpy(&p_scb->cfg, &cfg, sizeof(tAVDT_CFG));
-        bta_av_adjust_seps_idx(p_scb);
+
+        uuid_int = p_scb->uuid_int;
+        APPL_TRACE_DEBUG(" initiator UUID = 0x%x ", uuid_int);
+        if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE)
+            bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC));
+        else if (uuid_int == UUID_SERVCLASS_AUDIO_SINK)
+            bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SNK));
+
         /* use only the services peer supports */
         cfg.psc_mask &= p_scb->p_cap->psc_mask;
         p_scb->cur_psc_mask = cfg.psc_mask;
 
+        if ((uuid_int == UUID_SERVCLASS_AUDIO_SINK) &&
+            (p_scb->seps[p_scb->sep_idx].p_app_data_cback != NULL))
+        {
+            APPL_TRACE_DEBUG(" Configure Deoder for Sink Connection ");
+            p_scb->seps[p_scb->sep_idx].p_app_data_cback(BTA_AV_MEDIA_SINK_CFG_EVT,
+                     (tBTA_AV_MEDIA*)p_scb->cfg.codec_info);
+        }
+
         /* open the stream */
         AVDT_OpenReq(p_scb->seps[p_scb->sep_idx].av_handle, p_scb->peer_addr,
                      p_scb->sep_info[p_scb->sep_info_idx].seid, &cfg);
@@ -1738,9 +1917,12 @@
 void bta_av_setconfig_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
 {
     tBTA_AV_REJECT reject;
+    UINT8   avdt_handle = p_data->ci_setconfig.avdt_handle;
 
-    APPL_TRACE_DEBUG0("bta_av_setconfig_rej");
-    AVDT_ConfigRsp(p_data->str_msg.handle, p_data->str_msg.msg.hdr.label, AVDT_ERR_BAD_STATE, 0);
+    bta_av_adjust_seps_idx(p_scb, avdt_handle);
+    APPL_TRACE_DEBUG("bta_av_setconfig_rej: sep_idx: %d",p_scb->sep_idx);
+    AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_UNSUP_CFG, 0);
+
     bdcpy(reject.bd_addr, p_data->str_msg.bd_addr);
     reject.hndl = p_scb->hndl;
     (*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, (tBTA_AV *) &reject);
@@ -1793,7 +1975,7 @@
     UINT8 policy = HCI_ENABLE_SNIFF_MODE;
     UINT8       cur_role;
 
-    APPL_TRACE_DEBUG3("bta_av_do_start sco_occupied:%d, role:x%x, started:%d", bta_av_cb.sco_occupied, p_scb->role, p_scb->started);
+    APPL_TRACE_DEBUG("bta_av_do_start sco_occupied:%d, role:x%x, started:%d", bta_av_cb.sco_occupied, p_scb->role, p_scb->started);
     if (bta_av_cb.sco_occupied)
     {
         bta_av_start_failed(p_scb, p_data);
@@ -1829,7 +2011,7 @@
             }
         }
     }
-    APPL_TRACE_DEBUG2("started %d role:x%x", p_scb->started, p_scb->role);
+    APPL_TRACE_DEBUG("started %d role:x%x", p_scb->started, p_scb->role);
 }
 
 /*******************************************************************************
@@ -1849,7 +2031,7 @@
     BT_HDR  *p_buf;
     UINT8 policy = HCI_ENABLE_SNIFF_MODE;
 
-    APPL_TRACE_ERROR2("bta_av_str_stopped:audio_open_cnt=%d, p_data %x",
+    APPL_TRACE_ERROR("bta_av_str_stopped:audio_open_cnt=%d, p_data %x",
             bta_av_cb.audio_open_cnt, p_data);
 
     bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
@@ -1882,7 +2064,7 @@
 
     if (p_data && p_data->api_stop.suspend)
     {
-        APPL_TRACE_DEBUG2("suspending: %d, sup:%d", start, p_scb->suspend_sup);
+        APPL_TRACE_DEBUG("suspending: %d, sup:%d", start, p_scb->suspend_sup);
         if ((start)  && (p_scb->suspend_sup))
         {
             sus_evt = FALSE;
@@ -1902,7 +2084,7 @@
     {
         suspend_rsp.status = BTA_AV_SUCCESS;
         suspend_rsp.initiator = TRUE;
-        APPL_TRACE_EVENT1("bta_av_str_stopped status %d", suspend_rsp.status);
+        APPL_TRACE_EVENT("bta_av_str_stopped status %d", suspend_rsp.status);
 
         /* send STOP_EVT event only if not in reconfiguring state */
         if (p_scb->state != BTA_AV_RCFG_SST)
@@ -1930,7 +2112,7 @@
     tBTA_AV_RECONFIG    evt;
     tBTA_AV_API_RCFG    *p_rcfg = &p_data->api_reconfig;
 
-    APPL_TRACE_DEBUG4("bta_av_reconfig r:%d, s:%d idx: %d (o:%d)",
+    APPL_TRACE_DEBUG("bta_av_reconfig r:%d, s:%d idx: %d (o:%d)",
         p_scb->recfg_sup, p_scb->suspend_sup,
         p_scb->rcfg_idx, p_scb->sep_info_idx);
 
@@ -1976,7 +2158,7 @@
         }
         else
         {
-            APPL_TRACE_DEBUG0("Reconfig");
+            APPL_TRACE_DEBUG("Reconfig");
             AVDT_ReconfigReq(p_scb->avdt_handle, p_scb->p_cap);
             p_scb->p_cap->psc_mask = p_scb->cur_psc_mask;
         }
@@ -1984,7 +2166,7 @@
     else
     {
         /* close the stream */
-        APPL_TRACE_DEBUG1("close/open num_protect: %d", p_cfg->num_protect);
+        APPL_TRACE_DEBUG("close/open num_protect: %d", p_cfg->num_protect);
         if(p_scb->started)
             bta_av_str_stopped(p_scb, NULL);
             p_scb->started = FALSE;
@@ -2019,7 +2201,7 @@
     if (!p_scb->cong)
     {
         /*
-        APPL_TRACE_ERROR1("q: %d", p_scb->l2c_bufs);
+        APPL_TRACE_ERROR("q: %d", p_scb->l2c_bufs);
         */
         //Always get the current number of bufs que'd up
         p_scb->l2c_bufs = (UINT8)L2CA_FlushChannel (p_scb->l2c_cid, L2CAP_FLUSH_CHANS_GET);
@@ -2055,7 +2237,7 @@
                 /*  There's no need to increment it here, it is always read from L2CAP see above */
                 /* p_scb->l2c_bufs++; */
                 /*
-                APPL_TRACE_ERROR1("qw: %d", p_scb->l2c_bufs);
+                APPL_TRACE_ERROR("qw: %d", p_scb->l2c_bufs);
                 */
 
                 /* opt is a bit mask, it could have several options set */
@@ -2118,7 +2300,7 @@
     UINT8           policy = HCI_ENABLE_SNIFF_MODE;
     UINT8           cur_role;
 
-    APPL_TRACE_DEBUG2("bta_av_start_ok wait:x%x, role:x%x", p_scb->wait, p_scb->role);
+    APPL_TRACE_DEBUG("bta_av_start_ok wait:x%x, role:x%x", p_scb->wait, p_scb->role);
 
     p_scb->started = TRUE;
     if (p_scb->sco_suspend)
@@ -2129,6 +2311,13 @@
     if (new_role & BTA_AV_ROLE_START_INT)
         initiator = TRUE;
 
+    /* for A2DP SINK we do not send get_caps */
+    if ((p_scb->avdt_handle == p_scb->seps[p_scb->sep_idx].av_handle)
+         &&(p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK))
+    {
+        p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON);
+        APPL_TRACE_DEBUG(" Local SEP type is SNK  new wait is 0x%x",p_scb->wait);
+    }
     if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_FAILED)
     {
         /* role switch has failed */
@@ -2136,7 +2325,7 @@
         p_data = (tBTA_AV_DATA *)&hdr;
         hdr.offset = BTA_AV_RS_FAIL;
     }
-    APPL_TRACE_DEBUG1("wait:x%x", p_scb->wait);
+    APPL_TRACE_DEBUG("wait:x%x", p_scb->wait);
 
     if (p_data && (p_data->hdr.offset != BTA_AV_RS_NONE))
     {
@@ -2170,15 +2359,15 @@
         p_scb->q_tag = BTA_AV_Q_TAG_START;
     }
 
-    if (p_scb->wait & BTA_AV_WAIT_ACP_CAPS_ON)
-    {
-        p_scb->wait |= BTA_AV_WAIT_ACP_CAPS_STARTED;
-    }
-
     if (p_scb->wait)
     {
-        APPL_TRACE_DEBUG2("wait:x%x q_tag:%d- not started", p_scb->wait, p_scb->q_tag);
-        return;
+        APPL_TRACE_ERROR("wait:x%x q_tag:%d- not started", p_scb->wait, p_scb->q_tag);
+        /* Clear first bit of p_scb->wait and not to return from this point else
+         * HAL layer gets blocked. And if there is delay in Get Capability response as
+         * first bit of p_scb->wait is cleared hence it ensures bt_av_start_ok is not called
+         * again from bta_av_save_caps.
+        */
+        p_scb->wait &= ~BTA_AV_WAIT_ACP_CAPS_ON;
     }
 
     /* tell role manager to check M/S role */
@@ -2243,7 +2432,7 @@
         p_scb->p_cos->start(p_scb->hndl, p_scb->codec_type, p_scb->cfg.codec_info, &p_scb->no_rtp_hdr);
         p_scb->co_started = TRUE;
 
-        APPL_TRACE_DEBUG3("bta_av_start_ok suspending: %d, role:x%x, init %d",
+        APPL_TRACE_DEBUG("bta_av_start_ok suspending: %d, role:x%x, init %d",
             suspend, p_scb->role, initiator);
 
         start.suspending = suspend;
@@ -2322,6 +2511,12 @@
         data.open.status = p_scb->open_status;
         data.open.chnl   = p_scb->chnl;
         data.open.hndl   = p_scb->hndl;
+
+        if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC )
+            data.open.sep = AVDT_TSEP_SNK;
+        else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK )
+            data.open.sep = AVDT_TSEP_SRC;
+
         event = BTA_AV_OPEN_EVT;
         p_scb->open_status = BTA_AV_SUCCESS;
 
@@ -2385,7 +2580,7 @@
     UINT8           err_code = p_data->str_msg.msg.hdr.err_code;
     UINT8 policy = HCI_ENABLE_SNIFF_MODE;
 
-    APPL_TRACE_DEBUG2 ("bta_av_suspend_cfm:audio_open_cnt = %d, err_code = %d",
+    APPL_TRACE_DEBUG ("bta_av_suspend_cfm:audio_open_cnt = %d, err_code = %d",
         bta_av_cb.audio_open_cnt, err_code);
 
     if (p_scb->started == FALSE)
@@ -2393,7 +2588,7 @@
         /* handle the condition where there is a collision of SUSPEND req from either side
         ** Second SUSPEND req could be rejected. Do not treat this as a failure
         */
-        APPL_TRACE_WARNING1("bta_av_suspend_cfm: already suspended, ignore, err_code %d",
+        APPL_TRACE_WARNING("bta_av_suspend_cfm: already suspended, ignore, err_code %d",
                             err_code);
         return;
     }
@@ -2408,7 +2603,7 @@
         }
         suspend_rsp.status = BTA_AV_FAIL;
 
-        APPL_TRACE_ERROR0 ("bta_av_suspend_cfm: suspend failed, closing connection");
+        APPL_TRACE_ERROR ("bta_av_suspend_cfm: suspend failed, closing connection");
 
         /* SUSPEND failed. Close connection. */
         bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL);
@@ -2465,7 +2660,7 @@
     UNUSED(p_data);
 
     p_scb->l2c_cid      = AVDT_GetL2CapChannel(p_scb->avdt_handle);
-    APPL_TRACE_DEBUG1("bta_av_rcfg_str_ok: l2c_cid: %d", p_scb->l2c_cid);
+    APPL_TRACE_DEBUG("bta_av_rcfg_str_ok: l2c_cid: %d", p_scb->l2c_cid);
 
     /* rc listen */
     bta_av_st_rc_timer(p_scb, NULL);
@@ -2498,7 +2693,7 @@
 {
     tBTA_AV_RECONFIG evt;
 
-    APPL_TRACE_DEBUG2("bta_av_rcfg_failed num_recfg: %d, conn_lcb:0x%x",
+    APPL_TRACE_DEBUG("bta_av_rcfg_failed num_recfg: %d, conn_lcb:0x%x",
         p_scb->num_recfg, bta_av_cb.conn_lcb);
     if(p_scb->num_recfg > BTA_AV_RECONFIG_RETRY)
     {
@@ -2541,7 +2736,7 @@
 
     p_scb->cong    = FALSE;
     p_scb->num_recfg++;
-    APPL_TRACE_DEBUG1("bta_av_rcfg_connect num_recfg: %d", p_scb->num_recfg);
+    APPL_TRACE_DEBUG("bta_av_rcfg_connect num_recfg: %d", p_scb->num_recfg);
     if(p_scb->num_recfg > BTA_AV_RECONFIG_RETRY)
     {
         /* let bta_av_rcfg_failed report fail */
@@ -2565,7 +2760,7 @@
     tBTA_AV_RECONFIG    evt;
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG1("bta_av_rcfg_discntd num_recfg: %d", p_scb->num_recfg);
+    APPL_TRACE_DEBUG("bta_av_rcfg_discntd num_recfg: %d", p_scb->num_recfg);
     p_scb->num_recfg++;
     if(p_scb->num_recfg > BTA_AV_RECONFIG_RETRY)
     {
@@ -2609,7 +2804,7 @@
         }
         else
         {
-            APPL_TRACE_ERROR0("suspend rejected, try close");
+            APPL_TRACE_ERROR("suspend rejected, try close");
              /* Disable suspend feature only with explicit rejection(not with timeout) */
             if (err_code != AVDT_ERR_TIMEOUT)
             {
@@ -2623,7 +2818,7 @@
     }
     else
     {
-        APPL_TRACE_DEBUG0("bta_av_suspend_cont calling AVDT_ReconfigReq");
+        APPL_TRACE_DEBUG("bta_av_suspend_cont calling AVDT_ReconfigReq");
         /* reconfig the stream */
 
         AVDT_ReconfigReq(p_scb->avdt_handle, p_scb->p_cap);
@@ -2646,11 +2841,11 @@
     UINT8   err_code = p_data->str_msg.msg.hdr.err_code;
 
     /*
-    APPL_TRACE_DEBUG0("bta_av_rcfg_cfm");
+    APPL_TRACE_DEBUG("bta_av_rcfg_cfm");
     */
     if (err_code)
     {
-        APPL_TRACE_ERROR0("reconfig rejected, try close");
+        APPL_TRACE_ERROR("reconfig rejected, try close");
          /* Disable reconfiguration feature only with explicit rejection(not with timeout) */
         if (err_code != AVDT_ERR_TIMEOUT)
         {
@@ -2683,7 +2878,7 @@
 {
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG1("bta_av_rcfg_open, num_disc_snks = %d", p_scb->num_disc_snks);
+	APPL_TRACE_DEBUG("bta_av_rcfg_open, num_disc_snks = %d", p_scb->num_disc_snks);
 
     if (p_scb->num_disc_snks == 0)
     {
@@ -2699,7 +2894,7 @@
         memcpy(p_scb->cfg.codec_info, p_scb->p_cap->codec_info, AVDT_CODEC_SIZE);
         /* we may choose to use a different SEP at reconfig.
          * adjust the sep_idx now */
-        bta_av_adjust_seps_idx(p_scb);
+        bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC));
 
         /* open the stream with the new config */
         p_scb->sep_info_idx = p_scb->rcfg_idx;
@@ -2786,13 +2981,13 @@
 {
     tBTA_AV_START   start;
 
-    APPL_TRACE_DEBUG3("bta_av_open_rc use_rc: %d, wait: x%x role:x%x", p_scb->use_rc, p_scb->wait, p_scb->role);
+    APPL_TRACE_DEBUG("bta_av_open_rc use_rc: %d, wait: x%x role:x%x", p_scb->use_rc, p_scb->wait, p_scb->role);
     if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) && (p_scb->q_tag == BTA_AV_Q_TAG_START))
     {
         /* waiting for role switch for some reason & the timer expires */
         if (!bta_av_link_role_ok(p_scb, A2D_SET_ONE_BIT))
         {
-            APPL_TRACE_ERROR0 ("failed to start streaming for role management reasons!!");
+            APPL_TRACE_ERROR ("failed to start streaming for role management reasons!!");
             bta_sys_stop_timer(&p_scb->timer);
             start.chnl   = p_scb->chnl;
             start.status = BTA_AV_FAIL_ROLE;
diff --git a/bta/av/bta_av_act.c b/bta/av/bta_av_act.c
old mode 100755
new mode 100644
index 4408874..dfd3662
--- a/bta/av/bta_av_act.c
+++ b/bta/av/bta_av_act.c
@@ -100,7 +100,7 @@
             p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
             if(p_scb)
             {
-                APPL_TRACE_DEBUG3("bta_av_del_rc shdl:%d, srch:%d rc_handle:%d", p_rcb->shdl,
+                APPL_TRACE_DEBUG("bta_av_del_rc shdl:%d, srch:%d rc_handle:%d", p_rcb->shdl,
                                   p_scb->rc_handle, p_rcb->handle);
                 if(p_scb->rc_handle == p_rcb->handle)
                     p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE;
@@ -110,7 +110,7 @@
             }
         }
 
-        APPL_TRACE_EVENT4("bta_av_del_rc  handle: %d status=0x%x, rc_acp_handle:%d, idx:%d",
+        APPL_TRACE_EVENT("bta_av_del_rc  handle: %d status=0x%x, rc_acp_handle:%d, idx:%d",
             p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, bta_av_cb.rc_acp_idx);
         rc_handle = p_rcb->handle;
         if(!(p_rcb->status & BTA_AV_RC_CONN_MASK) ||
@@ -125,7 +125,7 @@
         AVRC_Close(rc_handle);
         if (rc_handle == bta_av_cb.rc_acp_handle)
             bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE;
-        APPL_TRACE_EVENT4("end del_rc handle: %d status=0x%x, rc_acp_handle:%d, lidx:%d",
+        APPL_TRACE_EVENT("end del_rc handle: %d status=0x%x, rc_acp_handle:%d, lidx:%d",
             p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, p_rcb->lidx);
     }
 }
@@ -206,9 +206,9 @@
     UNUSED(result);
 
 #if (defined(BTA_AV_MIN_DEBUG_TRACES) && BTA_AV_MIN_DEBUG_TRACES == TRUE)
-    APPL_TRACE_EVENT2("rc_ctrl handle: %d event=0x%x", handle, event);
+    APPL_TRACE_EVENT("rc_ctrl handle: %d event=0x%x", handle, event);
 #else
-    APPL_TRACE_EVENT2("bta_av_rc_ctrl_cback handle: %d event=0x%x", handle, event);
+    APPL_TRACE_EVENT("bta_av_rc_ctrl_cback handle: %d event=0x%x", handle, event);
 #endif
     if (event == AVRC_OPEN_IND_EVT)
     {
@@ -252,9 +252,9 @@
     UINT16          data_len = 0;
 
 #if (defined(BTA_AV_MIN_DEBUG_TRACES) && BTA_AV_MIN_DEBUG_TRACES == TRUE)
-    APPL_TRACE_ERROR2("rc_msg handle: %d opcode=0x%x", handle, opcode);
+    APPL_TRACE_ERROR("rc_msg handle: %d opcode=0x%x", handle, opcode);
 #else
-    APPL_TRACE_EVENT2("bta_av_rc_msg_cback handle: %d opcode=0x%x", handle, opcode);
+    APPL_TRACE_EVENT("bta_av_rc_msg_cback handle: %d opcode=0x%x", handle, opcode);
 #endif
     /* determine size of buffer we need */
     if (opcode == AVRC_OP_VENDOR && p_msg->vendor.p_vendor_data != NULL)
@@ -314,7 +314,7 @@
     {
         if ((p_rcb = bta_av_get_rcb_by_shdl(shdl)) != NULL )
         {
-            APPL_TRACE_ERROR1("bta_av_rc_create ACP handle exist for shdl:%d", shdl);
+            APPL_TRACE_ERROR("bta_av_rc_create ACP handle exist for shdl:%d", shdl);
             return p_rcb->handle;
         }
     }
@@ -335,7 +335,7 @@
 
     if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE)
     {
-        APPL_TRACE_ERROR1("bta_av_rc_create found duplicated handle:%d", rc_handle);
+        APPL_TRACE_ERROR("bta_av_rc_create found duplicated handle:%d", rc_handle);
     }
 
     p_rcb->handle = rc_handle;
@@ -348,9 +348,9 @@
         /* this LIDX is reserved for the AVRCP ACP connection */
         p_cb->rc_acp_handle = p_rcb->handle;
         p_cb->rc_acp_idx = (i + 1);
-        APPL_TRACE_DEBUG2("rc_acp_handle:%d idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
+        APPL_TRACE_DEBUG("rc_acp_handle:%d idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
     }
-    APPL_TRACE_DEBUG6("create %d, role: %d, shdl:%d, rc_handle:%d, lidx:%d, status:0x%x",
+    APPL_TRACE_DEBUG("create %d, role: %d, shdl:%d, rc_handle:%d, lidx:%d, status:0x%x",
         i, role, shdl, p_rcb->handle, lidx, p_rcb->status);
 
     return rc_handle;
@@ -463,7 +463,7 @@
             if(op == BTA_AV_LCB_FREE)
             {
                 p_cb->conn_lcb &= ~mask; /* clear the connect mask */
-                APPL_TRACE_DEBUG1("conn_lcb: 0x%x", p_cb->conn_lcb);
+                APPL_TRACE_DEBUG("conn_lcb: 0x%x", p_cb->conn_lcb);
             }
             break;
         }
@@ -498,9 +498,9 @@
         if(p_scb && bdcmp(p_scb->peer_addr, p_data->rc_conn_chg.peer_addr) == 0)
         {
             p_scb->rc_handle = p_data->rc_conn_chg.handle;
-            APPL_TRACE_DEBUG2("bta_av_rc_opened shdl:%d, srch %d", i + 1, p_scb->rc_handle);
+            APPL_TRACE_DEBUG("bta_av_rc_opened shdl:%d, srch %d", i + 1, p_scb->rc_handle);
             shdl = i+1;
-            APPL_TRACE_ERROR1("use_rc:%d", p_scb->use_rc);
+            APPL_TRACE_ERROR("use_rc:%d", p_scb->use_rc);
             bta_sys_stop_timer(&p_scb->timer);
             disc = p_scb->hndl;
             break;
@@ -510,7 +510,7 @@
     i = p_data->rc_conn_chg.handle;
     if (p_cb->rcb[i].handle == BTA_AV_RC_HANDLE_NONE)
     {
-        APPL_TRACE_ERROR1("not a valid handle:%d any more", i);
+        APPL_TRACE_ERROR("not a valid handle:%d any more", i);
         return;
     }
 
@@ -528,14 +528,14 @@
             p_cb->rcb[i].lidx = tmp;
             p_cb->rc_acp_handle = p_rcb->handle;
             p_cb->rc_acp_idx = (p_rcb - p_cb->rcb) + 1;
-            APPL_TRACE_DEBUG2("switching RCB rc_acp_handle:%d idx:%d",
+            APPL_TRACE_DEBUG("switching RCB rc_acp_handle:%d idx:%d",
                                p_cb->rc_acp_handle, p_cb->rc_acp_idx);
         }
     }
 
     p_cb->rcb[i].shdl = shdl;
     rc_open.rc_handle = i;
-    APPL_TRACE_ERROR4("bta_av_rc_opened rcb[%d] shdl:%d lidx:%d/%d",
+    APPL_TRACE_ERROR("bta_av_rc_opened rcb[%d] shdl:%d lidx:%d/%d",
             i, shdl, p_cb->rcb[i].lidx, p_cb->lcb[BTA_AV_NUM_LINKS].lidx);
     p_cb->rcb[i].status |= BTA_AV_RC_CONN_MASK;
 
@@ -545,14 +545,14 @@
          * update the index to the extra LCB */
         p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS];
         bdcpy(p_lcb->addr, p_data->rc_conn_chg.peer_addr);
-        APPL_TRACE_DEBUG6("rc_only bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
+        APPL_TRACE_DEBUG("rc_only bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
                       p_lcb->addr[0], p_lcb->addr[1],
                       p_lcb->addr[2], p_lcb->addr[3],
                       p_lcb->addr[4], p_lcb->addr[5]);
         p_lcb->lidx = BTA_AV_NUM_LINKS + 1;
             p_cb->rcb[i].lidx = p_lcb->lidx;
         p_lcb->conn_msk = 1;
-        APPL_TRACE_ERROR3("rcb[%d].lidx=%d, lcb.conn_msk=x%x",
+        APPL_TRACE_ERROR("rcb[%d].lidx=%d, lcb.conn_msk=x%x",
             i, p_cb->rcb[i].lidx, p_lcb->conn_msk);
         disc = p_data->rc_conn_chg.handle|BTA_AV_CHNL_MSK;
     }
@@ -560,7 +560,7 @@
     bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr);
     rc_open.peer_features = p_cb->rcb[i].peer_features;
     rc_open.status = BTA_AV_SUCCESS;
-    APPL_TRACE_DEBUG2("local features:x%x peer_features:x%x", p_cb->features,
+    APPL_TRACE_DEBUG("local features:x%x peer_features:x%x", p_cb->features,
                       rc_open.peer_features);
     if(rc_open.peer_features == 0)
     {
@@ -777,7 +777,7 @@
     /* Metadata messages only use PANEL sub-unit type */
     if (p_vendor->hdr.subunit_type != AVRC_SUB_PANEL)
     {
-        APPL_TRACE_DEBUG0("SUBUNIT must be PANEL");
+        APPL_TRACE_DEBUG("SUBUNIT must be PANEL");
         /* reject it */
         evt=0;
         p_vendor->hdr.ctype = BTA_AV_RSP_NOT_IMPL;
@@ -785,7 +785,7 @@
     }
     else if (!AVRC_IsValidAvcType(pdu, p_vendor->hdr.ctype) )
     {
-        APPL_TRACE_DEBUG2("Invalid pdu/ctype: 0x%x, %d", pdu, p_vendor->hdr.ctype);
+        APPL_TRACE_DEBUG("Invalid pdu/ctype: 0x%x, %d", pdu, p_vendor->hdr.ctype);
         /* reject invalid message without reporting to app */
         evt = 0;
         p_rc_rsp->rsp.status = AVRC_STS_BAD_CMD;
@@ -824,7 +824,7 @@
                 }
                 else
                 {
-                    APPL_TRACE_DEBUG1("Invalid capability ID: 0x%x", u8);
+                    APPL_TRACE_DEBUG("Invalid capability ID: 0x%x", u8);
                     /* reject - unknown capability ID */
                     p_rc_rsp->get_caps.status = AVRC_STS_BAD_PARAM;
                 }
@@ -842,7 +842,7 @@
         }
     }
 #else
-    APPL_TRACE_DEBUG0("AVRCP 1.3 Metadata not supporteed. Reject command.");
+    APPL_TRACE_DEBUG("AVRCP 1.3 Metadata not supporteed. Reject command.");
     /* reject invalid message without reporting to app */
     evt = 0;
     p_rc_rsp->rsp.status = AVRC_STS_BAD_CMD;
@@ -870,7 +870,7 @@
     BOOLEAN is_inquiry = ((p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_SPEC_INQ) || p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_GEN_INQ);
 #if (AVRC_METADATA_INCLUDED == TRUE)
     tAVRC_STS   res;
-    UINT8       ctype;
+    UINT8       ctype = 0;
     tAVRC_RESPONSE  rc_rsp;
 
     rc_rsp.rsp.status = BTA_AV_STS_NO_RSP;
@@ -900,7 +900,7 @@
                 p_data->rc_msg.msg.hdr.ctype = bta_av_op_supported(p_data->rc_msg.msg.pass.op_id, is_inquiry);
             }
 
-            APPL_TRACE_DEBUG1("ctype %d",p_data->rc_msg.msg.hdr.ctype)
+            APPL_TRACE_DEBUG("ctype %d",p_data->rc_msg.msg.hdr.ctype)
 
             /* send response */
             if (p_data->rc_msg.msg.hdr.ctype != BTA_AV_RSP_INTERIM)
@@ -1031,7 +1031,7 @@
     {
         p_rcb = &p_cb->rcb[handle];
 
-        APPL_TRACE_DEBUG2("bta_av_rc_close handle: %d, status=0x%x", p_rcb->handle, p_rcb->status);
+        APPL_TRACE_DEBUG("bta_av_rc_close handle: %d, status=0x%x", p_rcb->handle, p_rcb->status);
         if(p_rcb->handle != BTA_AV_RC_HANDLE_NONE)
         {
             if(p_rcb->shdl)
@@ -1092,7 +1092,7 @@
     tBTA_AV_SCB *p_scbi;
 
     started_msk = BTA_AV_HNDL_TO_MSK(p_scb->hdi);
-    APPL_TRACE_DEBUG3 ("bta_av_stream_chg started:%d started_msk:x%x chnl:x%x", started,
+    APPL_TRACE_DEBUG ("bta_av_stream_chg started:%d started_msk:x%x chnl:x%x", started,
                                                   started_msk, p_scb->chnl);
     if (BTA_AV_CHNL_AUDIO == p_scb->chnl)
         p_streams = &bta_av_cb.audio_streams;
@@ -1138,7 +1138,7 @@
             }
         }
 
-        APPL_TRACE_DEBUG4 ("no_streams:%d i:%d, audio_streams:x%x, video_streams:x%x", no_streams, i,
+        APPL_TRACE_DEBUG ("no_streams:%d i:%d, audio_streams:x%x, video_streams:x%x", no_streams, i,
                            bta_av_cb.audio_streams, bta_av_cb.video_streams);
         if (no_streams)
         {
@@ -1192,7 +1192,7 @@
                     if (bta_av_cb.rcb[i].lidx == p_lcb->lidx)
                     {
                         bta_av_cb.rcb[i].shdl = index + 1;
-                        APPL_TRACE_DEBUG5("conn_chg up[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i,
+                        APPL_TRACE_DEBUG("conn_chg up[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i,
                                           bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status,
                                           bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
                         break;
@@ -1217,18 +1217,18 @@
             }
 
 
-            APPL_TRACE_DEBUG2("rc_acp_handle:%d rc_acp_idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
+            APPL_TRACE_DEBUG("rc_acp_handle:%d rc_acp_idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
             /* check if the AVRCP ACP channel is already connected */
             if(p_lcb && p_cb->rc_acp_handle != BTA_AV_RC_HANDLE_NONE && p_cb->rc_acp_idx)
             {
                 p_lcb_rc = &p_cb->lcb[BTA_AV_NUM_LINKS];
-                APPL_TRACE_DEBUG1("rc_acp is connected && conn_chg on same addr p_lcb_rc->conn_msk:x%x",
+                APPL_TRACE_DEBUG("rc_acp is connected && conn_chg on same addr p_lcb_rc->conn_msk:x%x",
                                   p_lcb_rc->conn_msk);
                 /* check if the RC is connected to the scb addr */
-                APPL_TRACE_DEBUG6 ("p_lcb_rc->addr: %02x:%02x:%02x:%02x:%02x:%02x",
+                APPL_TRACE_DEBUG ("p_lcb_rc->addr: %02x:%02x:%02x:%02x:%02x:%02x",
                        p_lcb_rc->addr[0], p_lcb_rc->addr[1], p_lcb_rc->addr[2], p_lcb_rc->addr[3],
                        p_lcb_rc->addr[4], p_lcb_rc->addr[5]);
-                APPL_TRACE_DEBUG6 ("conn_chg.peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
+                APPL_TRACE_DEBUG ("conn_chg.peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
                        p_data->conn_chg.peer_addr[0], p_data->conn_chg.peer_addr[1],
                        p_data->conn_chg.peer_addr[2],
                        p_data->conn_chg.peer_addr[3], p_data->conn_chg.peer_addr[4],
@@ -1242,7 +1242,7 @@
                     p_scb->rc_handle = p_cb->rc_acp_handle;
                     p_rcb = &p_cb->rcb[p_cb->rc_acp_idx - 1];
                     p_rcb->shdl = bta_av_get_shdl(p_scb);
-                    APPL_TRACE_DEBUG3("update rc_acp shdl:%d/%d srch:%d", index + 1, p_rcb->shdl,
+                    APPL_TRACE_DEBUG("update rc_acp shdl:%d/%d srch:%d", index + 1, p_rcb->shdl,
                                       p_scb->rc_handle );
 
                     p_rcb2 = bta_av_get_rcb_by_shdl(p_rcb->shdl);
@@ -1251,14 +1251,14 @@
                         /* found the RCB that was created to associated with this SCB */
                         p_cb->rc_acp_handle = p_rcb2->handle;
                         p_cb->rc_acp_idx = (p_rcb2 - p_cb->rcb) + 1;
-                        APPL_TRACE_DEBUG2("new rc_acp_handle:%d, idx:%d", p_cb->rc_acp_handle,
+                        APPL_TRACE_DEBUG("new rc_acp_handle:%d, idx:%d", p_cb->rc_acp_handle,
                                            p_cb->rc_acp_idx);
                         p_rcb2->lidx = (BTA_AV_NUM_LINKS + 1);
-                        APPL_TRACE_DEBUG3("rc2 handle:%d lidx:%d/%d",p_rcb2->handle, p_rcb2->lidx,
+                        APPL_TRACE_DEBUG("rc2 handle:%d lidx:%d/%d",p_rcb2->handle, p_rcb2->lidx,
                                           p_cb->lcb[p_rcb2->lidx-1].lidx);
                     }
                     p_rcb->lidx = p_lcb->lidx;
-                    APPL_TRACE_DEBUG3("rc handle:%d lidx:%d/%d",p_rcb->handle, p_rcb->lidx,
+                    APPL_TRACE_DEBUG("rc handle:%d lidx:%d/%d",p_rcb->handle, p_rcb->lidx,
                                       p_cb->lcb[p_rcb->lidx-1].lidx);
                 }
             }
@@ -1297,10 +1297,10 @@
             }
         }
 
-        APPL_TRACE_DEBUG1("bta_av_conn_chg shdl:%d", index + 1);
+        APPL_TRACE_DEBUG("bta_av_conn_chg shdl:%d", index + 1);
         for (i=0; i<BTA_AV_NUM_RCB; i++)
         {
-            APPL_TRACE_DEBUG5("conn_chg dn[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i,
+            APPL_TRACE_DEBUG("conn_chg dn[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i,
                               bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status,
                               bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
             if(bta_av_cb.rcb[i].shdl == index + 1)
@@ -1322,7 +1322,7 @@
             bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
     }
 
-    APPL_TRACE_DEBUG6("bta_av_conn_chg audio:%x video:%x up:%d conn_msk:0x%x chk_restore:%d audio_open_cnt:%d",
+    APPL_TRACE_DEBUG("bta_av_conn_chg audio:%x video:%x up:%d conn_msk:0x%x chk_restore:%d audio_open_cnt:%d",
         p_cb->conn_audio, p_cb->conn_video, p_data->conn_chg.is_up, conn_msk, chk_restore, p_cb->audio_open_cnt);
 
     if (chk_restore)
@@ -1417,7 +1417,7 @@
     UINT8   mask;
     tBTA_AV_LCB *p_lcb = NULL;
 
-    APPL_TRACE_DEBUG1("bta_av_sig_chg event: %d", event);
+    APPL_TRACE_DEBUG("bta_av_sig_chg event: %d", event);
     if(event == AVDT_CONNECT_IND_EVT)
     {
         p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FIND);
@@ -1427,7 +1427,7 @@
             for(xx=0; xx<BTA_AV_NUM_LINKS; xx++)
             {
                 mask = 1 << xx;
-                APPL_TRACE_DEBUG1("conn_lcb: 0x%x", p_cb->conn_lcb);
+                APPL_TRACE_DEBUG("conn_lcb: 0x%x", p_cb->conn_lcb);
 
                 /* look for a p_lcb with its p_scb registered */
                 if((!(mask & p_cb->conn_lcb)) && (p_cb->p_scb[xx] != NULL))
@@ -1443,10 +1443,10 @@
                     }
                     /* this entry is not used yet. */
                     p_cb->conn_lcb |= mask;     /* mark it as used */
-                    APPL_TRACE_DEBUG1("start sig timer %d", p_data->hdr.offset);
+                    APPL_TRACE_DEBUG("start sig timer %d", p_data->hdr.offset);
                     if (p_data->hdr.offset == AVDT_ACP)
                     {
-                        APPL_TRACE_DEBUG1("Incoming L2CAP acquired, set state as incoming", NULL);
+                        APPL_TRACE_DEBUG("Incoming L2CAP acquired, set state as incoming", NULL);
                         bdcpy(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr);
                         p_cb->p_scb[xx]->use_rc = TRUE;     /* allowing RC for incoming connection */
                         bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_ACP_CONNECT_EVT, p_data);
@@ -1474,7 +1474,7 @@
             {
                 /* We do not have scb for this avdt connection.     */
                 /* Silently close the connection.                   */
-                APPL_TRACE_ERROR0("av scb not available for avdt connection");
+                APPL_TRACE_ERROR("av scb not available for avdt connection");
                 AVDT_DisconnectReq (p_data->str_msg.bd_addr, NULL);
                 return;
             }
@@ -1492,7 +1492,7 @@
         p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FREE);
         if(p_lcb && p_lcb->conn_msk)
         {
-            APPL_TRACE_DEBUG1("conn_msk: 0x%x", p_lcb->conn_msk);
+            APPL_TRACE_DEBUG("conn_msk: 0x%x", p_lcb->conn_msk);
             /* clean up ssm  */
             for(xx=0; xx < BTA_AV_NUM_STRS; xx++)
             {
@@ -1505,7 +1505,7 @@
             }
         }
     }
-    APPL_TRACE_DEBUG1("conn_lcb: 0x%x", p_cb->conn_lcb);
+    APPL_TRACE_DEBUG("conn_lcb: 0x%x", p_cb->conn_lcb);
 }
 
 /*******************************************************************************
@@ -1528,7 +1528,7 @@
     tBTA_AV_PEND pend;
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG0("bta_av_sig_timer");
+    APPL_TRACE_DEBUG("bta_av_sig_timer");
     for(xx=0; xx<BTA_AV_NUM_LINKS; xx++)
     {
         mask = 1 << xx;
@@ -1565,7 +1565,7 @@
 
     if (p_scb)
     {
-        APPL_TRACE_DEBUG1("bta_av_acp_sig_timer_cback, coll_mask = 0x%02X", p_scb->coll_mask);
+        APPL_TRACE_DEBUG("bta_av_acp_sig_timer_cback, coll_mask = 0x%02X", p_scb->coll_mask);
 
         if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR)
         {
@@ -1628,7 +1628,7 @@
     UINT16              peer_rc_version=0;
     UINT16              categories = 0;
 
-    APPL_TRACE_DEBUG1("bta_av_check_peer_features service_uuid:x%x", service_uuid);
+    APPL_TRACE_DEBUG("bta_av_check_peer_features service_uuid:x%x", service_uuid);
     /* loop through all records we found */
     while (TRUE)
     {
@@ -1655,7 +1655,7 @@
         {
             /* get profile version (if failure, version parameter is not updated) */
             SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
-            APPL_TRACE_DEBUG1("peer_rc_version 0x%x", peer_rc_version);
+            APPL_TRACE_DEBUG("peer_rc_version 0x%x", peer_rc_version);
 
             if (peer_rc_version >= AVRC_REV_1_3)
                 peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA);
@@ -1674,7 +1674,7 @@
             }
         }
     }
-    APPL_TRACE_DEBUG1("peer_features:x%x", peer_features);
+    APPL_TRACE_DEBUG("peer_features:x%x", peer_features);
     return peer_features;
 }
 
@@ -1699,7 +1699,7 @@
     tBTA_AV_FEAT        peer_features;  /* peer features mask */
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG1("bta_av_rc_disc_done disc:x%x", p_cb->disc);
+    APPL_TRACE_DEBUG("bta_av_rc_disc_done disc:x%x", p_cb->disc);
     if (!p_cb->disc)
     {
         return;
@@ -1722,7 +1722,7 @@
         }
     }
 
-    APPL_TRACE_DEBUG1("rc_handle %d", rc_handle);
+    APPL_TRACE_DEBUG("rc_handle %d", rc_handle);
     /* check peer version and whether support CT and TG role */
     peer_features = bta_av_check_peer_features (UUID_SERVCLASS_AV_REMOTE_CONTROL);
     if ((p_cb->features & BTA_AV_FEAT_ADV_CTRL) && ((peer_features&BTA_AV_FEAT_ADV_CTRL) == 0))
@@ -1735,7 +1735,7 @@
     p_cb->disc = 0;
     utl_freebuf((void **) &p_cb->p_disc_db);
 
-    APPL_TRACE_DEBUG2("peer_features 0x%x, features 0x%x", peer_features, p_cb->features);
+    APPL_TRACE_DEBUG("peer_features 0x%x, features 0x%x", peer_features, p_cb->features);
 
     /* if we have no rc connection */
     if (rc_handle == BTA_AV_RC_HANDLE_NONE)
@@ -1755,7 +1755,7 @@
 #if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE)
                 else
                 {
-                    APPL_TRACE_ERROR0("can not find LCB!!");
+                    APPL_TRACE_ERROR("can not find LCB!!");
                 }
 #endif
             }
@@ -1800,17 +1800,17 @@
     tBTA_AV_LCB *p_lcb;
 
     rc_close.rc_handle = BTA_AV_RC_HANDLE_NONE;
-    APPL_TRACE_DEBUG1("bta_av_rc_closed rc_handle:%d", p_msg->handle);
+    APPL_TRACE_DEBUG("bta_av_rc_closed rc_handle:%d", p_msg->handle);
     for(i=0; i<BTA_AV_NUM_RCB; i++)
     {
         p_rcb = &p_cb->rcb[i];
-        APPL_TRACE_DEBUG3("bta_av_rc_closed rcb[%d] rc_handle:%d, status=0x%x", i, p_rcb->handle, p_rcb->status);
+        APPL_TRACE_DEBUG("bta_av_rc_closed rcb[%d] rc_handle:%d, status=0x%x", i, p_rcb->handle, p_rcb->status);
         if(p_rcb->handle == p_msg->handle)
         {
             rc_close.rc_handle = i;
             p_rcb->status &= ~BTA_AV_RC_CONN_MASK;
             p_rcb->peer_features = 0;
-            APPL_TRACE_DEBUG2("       shdl:%d, lidx:%d", p_rcb->shdl, p_rcb->lidx);
+            APPL_TRACE_DEBUG("       shdl:%d, lidx:%d", p_rcb->shdl, p_rcb->lidx);
             if(p_rcb->shdl)
             {
                 p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
@@ -1819,7 +1819,7 @@
                     bdcpy(rc_close.peer_addr, p_scb->peer_addr);
                     if(p_scb->rc_handle == p_rcb->handle)
                         p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE;
-                    APPL_TRACE_DEBUG2("shdl:%d, srch:%d", p_rcb->shdl, p_scb->rc_handle);
+                    APPL_TRACE_DEBUG("shdl:%d, srch:%d", p_rcb->shdl, p_scb->rc_handle);
                 }
                 p_rcb->shdl = 0;
             }
@@ -1828,7 +1828,7 @@
                 /* if the RCB uses the extra LCB, use the addr for event and clean it */
                 p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS];
                 bdcpy(rc_close.peer_addr, p_msg->peer_addr);
-                APPL_TRACE_DEBUG6("rc_only closed bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
+                APPL_TRACE_DEBUG("rc_only closed bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
                               p_msg->peer_addr[0], p_msg->peer_addr[1],
                               p_msg->peer_addr[2], p_msg->peer_addr[3],
                               p_msg->peer_addr[4], p_msg->peer_addr[5]);
@@ -1895,7 +1895,7 @@
     UINT8       *p_addr = NULL;
     UINT8       rc_handle;
 
-    APPL_TRACE_DEBUG2("bta_av_rc_disc 0x%x, %d", disc, bta_av_cb.disc);
+    APPL_TRACE_DEBUG("bta_av_rc_disc 0x%x, %d", disc, bta_av_cb.disc);
     if ((bta_av_cb.disc != 0) || (disc == 0))
         return;
 
@@ -1915,7 +1915,7 @@
 
         if (p_scb)
         {
-            APPL_TRACE_DEBUG1("rc_handle %d", p_scb->rc_handle);
+            APPL_TRACE_DEBUG("rc_handle %d", p_scb->rc_handle);
             p_addr = p_scb->peer_addr;
         }
     }
@@ -1941,7 +1941,7 @@
                             bta_av_avrc_sdp_cback) == AVRC_SUCCESS)
             {
                 p_cb->disc = disc;
-                APPL_TRACE_DEBUG1("disc %d", p_cb->disc);
+                APPL_TRACE_DEBUG("disc %d", p_cb->disc);
             }
         }
     }
@@ -1969,7 +1969,7 @@
 
     if(p_scb)
     {
-        APPL_TRACE_DEBUG2("deregistered %d(h%d)", p_scb->chnl, p_scb->hndl);
+        APPL_TRACE_DEBUG("deregistered %d(h%d)", p_scb->chnl, p_scb->hndl);
         mask = BTA_AV_HNDL_TO_MSK(p_scb->hdi);
         if(p_scb->chnl == BTA_AV_CHNL_AUDIO)
         {
@@ -1996,6 +1996,11 @@
 #endif
                 bta_av_del_sdp_rec(&p_cb->sdp_a2d_handle);
                 bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+                bta_av_del_sdp_rec(&p_cb->sdp_a2d_snk_handle);
+                bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SINK);
+#endif
             }
         }
         else
@@ -2013,7 +2018,7 @@
         utl_freebuf((void **)&p_cb->p_scb[p_scb->hdi]);
     }
 
-    APPL_TRACE_DEBUG3("audio 0x%x, video: 0x%x, disable:%d",
+    APPL_TRACE_DEBUG("audio 0x%x, video: 0x%x, disable:%d",
         p_cb->reg_audio, p_cb->reg_video, p_cb->disabling);
     /* if no stream control block is active */
     if((p_cb->reg_audio + p_cb->reg_video) == 0)
diff --git a/bta/av/bta_av_api.c b/bta/av/bta_av_api.c
index 98718fd..5aa401b 100644
--- a/bta/av/bta_av_api.c
+++ b/bta/av/bta_av_api.c
@@ -63,9 +63,7 @@
     tBTA_AV_API_ENABLE  *p_buf;
 
     /* register with BTA system manager */
-    GKI_sched_lock();
     bta_sys_register(BTA_ID_AV, &bta_av_reg);
-    GKI_sched_unlock();
 
     if ((p_buf = (tBTA_AV_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AV_API_ENABLE))) != NULL)
     {
@@ -111,7 +109,7 @@
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id)
+void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, tBTA_AV_DATA_CBACK  *p_data_cback)
 {
     tBTA_AV_API_REG  *p_buf;
 
@@ -130,6 +128,7 @@
             p_buf->p_service_name[0] = 0;
         }
         p_buf->app_id = app_id;
+        p_buf->p_app_data_cback = p_data_cback;
         bta_sys_sendmsg(p_buf);
     }
 }
@@ -166,7 +165,8 @@
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask)
+void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask,
+                                                                             UINT16 uuid)
 {
     tBTA_AV_API_OPEN  *p_buf;
 
@@ -178,6 +178,7 @@
         p_buf->use_rc = use_rc;
         p_buf->sec_mask = sec_mask;
         p_buf->switch_res = BTA_AV_RS_NONE;
+        p_buf->uuid = uuid;
         bta_sys_sendmsg(p_buf);
     }
 }
@@ -246,6 +247,31 @@
 
 /*******************************************************************************
 **
+** Function         BTA_AvEnable_Sink
+**
+** Description      Enable/Disable A2DP Sink..
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_AvEnable_Sink(int enable)
+{
+    BT_HDR  *p_buf;
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+    {
+        p_buf->event = BTA_AV_API_SINK_ENABLE_EVT;
+        p_buf->layer_specific = enable;
+        bta_sys_sendmsg(p_buf);
+    }
+#else
+    return;
+#endif
+}
+
+/*******************************************************************************
+**
 ** Function         BTA_AvStop
 **
 ** Description      Stop audio/video stream data transfer.
diff --git a/bta/av/bta_av_cfg.c b/bta/av/bta_av_cfg.c
old mode 100755
new mode 100644
diff --git a/bta/av/bta_av_ci.c b/bta/av/bta_av_ci.c
index a1c2ac0..2da1d97 100644
--- a/bta/av/bta_av_ci.c
+++ b/bta/av/bta_av_ci.c
@@ -68,7 +68,7 @@
 **
 *******************************************************************************/
 void bta_av_ci_setconfig(tBTA_AV_HNDL hndl, UINT8 err_code, UINT8 category,
-                         UINT8 num_seid, UINT8 *p_seid, BOOLEAN recfg_needed)
+                         UINT8 num_seid, UINT8 *p_seid, BOOLEAN recfg_needed, UINT8 avdt_handle)
 {
     tBTA_AV_CI_SETCONFIG  *p_buf;
 
@@ -81,6 +81,7 @@
         p_buf->category = category;
         p_buf->recfg_needed = recfg_needed;
         p_buf->num_seid = num_seid;
+        p_buf->avdt_handle= avdt_handle;
         if(p_seid && num_seid)
         {
             p_buf->p_seid   = (UINT8 *)(p_buf + 1);
diff --git a/bta/av/bta_av_int.h b/bta/av/bta_av_int.h
index cd22bcb..5deed76 100644
--- a/bta/av/bta_av_int.h
+++ b/bta/av/bta_av_int.h
@@ -96,6 +96,9 @@
     BTA_AV_AVRC_CLOSE_EVT,
     BTA_AV_CONN_CHG_EVT,
     BTA_AV_DEREG_COMP_EVT,
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+    BTA_AV_API_SINK_ENABLE_EVT,
+#endif
 #if (AVDT_REPORTING == TRUE)
     BTA_AV_AVDT_RPT_CONN_EVT,
 #endif
@@ -156,16 +159,15 @@
 /* function types for call-out functions */
 typedef BOOLEAN (*tBTA_AV_CO_INIT) (UINT8 *p_codec_type, UINT8 *p_codec_info,
                                    UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
-
 typedef void (*tBTA_AV_CO_DISC_RES) (tBTA_AV_HNDL hndl, UINT8 num_seps,
-                                     UINT8 num_snk, BD_ADDR addr);
-
+                                     UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local);
 typedef UINT8 (*tBTA_AV_CO_GETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
                                      UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid,
                                      UINT8 *p_num_protect, UINT8 *p_protect_info);
 typedef void (*tBTA_AV_CO_SETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
-                                    UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr,
-                                    UINT8 num_protect, UINT8 *p_protect_info);
+                                     UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr,
+                                     UINT8 num_protect, UINT8 *p_protect_info,
+                                     UINT8 t_local_sep, UINT8 avdt_handle);
 typedef void (*tBTA_AV_CO_OPEN) (tBTA_AV_HNDL hndl,
                                  tBTA_AV_CODEC codec_type, UINT8 *p_codec_info,
                                    UINT16 mtu);
@@ -206,6 +208,7 @@
     BT_HDR              hdr;
     char                p_service_name[BTA_SERVICE_NAME_LEN+1];
     UINT8               app_id;
+    tBTA_AV_DATA_CBACK       *p_app_data_cback;
 } tBTA_AV_API_REG;
 
 
@@ -225,6 +228,7 @@
     BOOLEAN             use_rc;
     tBTA_SEC            sec_mask;
     tBTA_AV_RS_RES      switch_res;
+    UINT16              uuid;  /* uuid of initiator */
 } tBTA_AV_API_OPEN;
 
 /* data type for BTA_AV_API_STOP_EVT */
@@ -319,6 +323,7 @@
     UINT8               num_seid;
     UINT8               *p_seid;
     BOOLEAN             recfg_needed;
+    UINT8               avdt_handle;  /* local sep type for which this stream will be set up */
 } tBTA_AV_CI_SETCONFIG;
 
 /* data type for all stream events from AVDTP */
@@ -376,8 +381,10 @@
 /* type for SEP control block */
 typedef struct
 {
-    UINT8               av_handle;      /* AVDTP handle */
-    tBTA_AV_CODEC       codec_type;     /* codec type */
+    UINT8               av_handle;         /* AVDTP handle */
+    tBTA_AV_CODEC       codec_type;        /* codec type */
+    UINT8               tsep;              /* SEP type of local SEP */
+    tBTA_AV_DATA_CBACK  *p_app_data_cback; /* Application callback for media packets */
 } tBTA_AV_SEP;
 
 
@@ -483,6 +490,7 @@
     UINT8               hdi;            /* the index to SCB[] */
     UINT8               num_seps;       /* number of seps returned by stream discovery */
     UINT8               num_disc_snks;  /* number of discovered snks */
+    UINT8               num_disc_srcs;  /* number of discovered srcs */
     UINT8               sep_info_idx;   /* current index into sep_info */
     UINT8               sep_idx;        /* current index into local seps[] */
     UINT8               rcfg_idx;       /* reconfig requested index into sep_info */
@@ -505,6 +513,7 @@
     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*/
+    UINT16              uuid_int;       /*intended UUID of Initiator to connect to */
 } tBTA_AV_SCB;
 
 #define BTA_AV_RC_ROLE_MASK     0x10
@@ -554,6 +563,9 @@
     TIMER_LIST_ENT      sig_tmr;        /* link timer */
     TIMER_LIST_ENT      acp_sig_tmr;    /* timer to monitor signalling when accepting */
     UINT32              sdp_a2d_handle; /* SDP record handle for audio src */
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+    UINT32              sdp_a2d_snk_handle; /* SDP record handle for audio snk */
+#endif
     UINT32              sdp_vdp_handle; /* SDP record handle for video src */
     tBTA_AV_FEAT        features;       /* features mask */
     tBTA_SEC            sec_mask;       /* security mask */
@@ -601,6 +613,7 @@
 extern const tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
 extern const tBTA_AV_SACT bta_av_vdp_action[];
 extern tAVDT_CTRL_CBACK * const bta_av_dt_cback[];
+extern void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt);
 
 /*****************************************************************************
 **  Function prototypes
diff --git a/bta/av/bta_av_main.c b/bta/av/bta_av_main.c
index 25c40a5..a8544c4 100644
--- a/bta/av/bta_av_main.c
+++ b/bta/av/bta_av_main.c
@@ -41,6 +41,8 @@
 *****************************************************************************/
 
 /* AVDTP protocol timeout values */
+#define BTIF_AVK_SERVICE_NAME "Advanced Audio Sink"
+
 #ifndef BTA_AV_RET_TOUT
 #define BTA_AV_RET_TOUT     4
 #endif
@@ -150,6 +152,9 @@
 typedef void (*tBTA_AV_NSM_ACT)(tBTA_AV_DATA *p_data);
 static void bta_av_api_enable(tBTA_AV_DATA *p_data);
 static void bta_av_api_register(tBTA_AV_DATA *p_data);
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data);
+#endif
 static void bta_av_ci_data(tBTA_AV_DATA *p_data);
 #if (AVDT_REPORTING == TRUE)
 static void bta_av_rpc_conn(tBTA_AV_DATA *p_data);
@@ -175,6 +180,9 @@
     bta_av_rc_closed,       /* BTA_AV_AVRC_CLOSE_EVT */
     bta_av_conn_chg,        /* BTA_AV_CONN_CHG_EVT */
     bta_av_dereg_comp,      /* BTA_AV_DEREG_COMP_EVT */
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+    bta_av_api_sink_enable, /* BTA_AV_API_SINK_ENABLE_EVT */
+#endif
 #if (AVDT_REPORTING == TRUE)
     bta_av_rpc_conn,        /* BTA_AV_AVDT_RPT_CONN_EVT */
 #endif
@@ -342,7 +350,7 @@
     {
         if(p_bta_av_cfg->p_act_tbl == NULL || p_bta_av_cfg->p_reg == NULL)
         {
-            APPL_TRACE_ERROR0("Video streaming not supported");
+            APPL_TRACE_ERROR("Video streaming not supported");
             sts = BTA_AV_FAIL;
         }
         else
@@ -350,14 +358,14 @@
             /* allow only one Video channel */
             if(bta_av_cb.reg_video)
             {
-                APPL_TRACE_ERROR0("Already registered");
+                APPL_TRACE_ERROR("Already registered");
                 sts = BTA_AV_FAIL;
             }
         }
     }
     else if(chnl != BTA_AV_CHNL_AUDIO)
     {
-        APPL_TRACE_ERROR1("bad channel: %d", chnl);
+        APPL_TRACE_ERROR("bad channel: %d", chnl);
         sts = BTA_AV_FAIL;
     }
 
@@ -407,7 +415,7 @@
 #if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
         else if (AVDT_CONNECT_IND_EVT == event)
         {
-            APPL_TRACE_DEBUG1("CONN_IND is ACP:%d", p_data->hdr.err_param);
+            APPL_TRACE_DEBUG("CONN_IND is ACP:%d", p_data->hdr.err_param);
         }
 #endif
 
@@ -425,10 +433,10 @@
 #if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
             if(p_scb)
             {
-                APPL_TRACE_DEBUG2("scb hndl x%x, role x%x", p_scb->hndl, p_scb->role);
+                APPL_TRACE_DEBUG("scb hndl x%x, role x%x", p_scb->hndl, p_scb->role);
             }
 #endif
-            APPL_TRACE_DEBUG6("conn_cback bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
+            APPL_TRACE_DEBUG("conn_cback bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
                           bd_addr[0], bd_addr[1],
                           bd_addr[2], bd_addr[3],
                           bd_addr[4], bd_addr[5]);
@@ -459,6 +467,49 @@
 }
 #endif
 
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function         bta_av_api_sink_enable
+**
+** Description      activate, deactive A2DP Sink,
+**
+** Returns          void
+**
+*******************************************************************************/
+
+static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data)
+{
+    UINT16 activate_sink = 0;
+    activate_sink = p_data->hdr.layer_specific;
+    APPL_TRACE_DEBUG("bta_av_api_sink_enable %d ", activate_sink)
+    char p_service_name[BTA_SERVICE_NAME_LEN+1];
+    BCM_STRNCPY_S(p_service_name, sizeof(p_service_name),
+            BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
+
+    if(activate_sink)
+    {
+        AVDT_SINK_Activate();
+        if (bta_av_cb.sdp_a2d_snk_handle == 0)
+        {
+            bta_av_cb.sdp_a2d_snk_handle = SDP_CreateRecord();
+            A2D_AddRecord(UUID_SERVCLASS_AUDIO_SINK, p_service_name, NULL,
+                          A2D_SUPF_PLAYER, bta_av_cb.sdp_a2d_snk_handle);
+            bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SINK);
+        }
+    }
+    else
+    {
+        AVDT_SINK_Deactivate();
+        if (bta_av_cb.sdp_a2d_snk_handle != 0)
+        {
+            SDP_DeleteRecord(bta_av_cb.sdp_a2d_snk_handle);
+            bta_av_cb.sdp_a2d_snk_handle = 0;
+            bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SINK);
+        }
+    }
+}
+#endif
 /*******************************************************************************
 **
 ** Function         bta_av_api_register
@@ -480,6 +531,8 @@
     tBTA_AV_CODEC   codec_type;
     tBTA_UTL_COD    cod;
     UINT8           index = 0;
+    char p_avk_service_name[BTA_SERVICE_NAME_LEN+1];
+    BCM_STRNCPY_S(p_avk_service_name, sizeof(p_avk_service_name), BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
 
     memset(&cs,0,sizeof(tAVDT_CS));
 
@@ -491,7 +544,7 @@
         p_scb = bta_av_alloc_scb(registr.chnl);
         if(p_scb == NULL)
         {
-            APPL_TRACE_ERROR0("failed to alloc SCB");
+            APPL_TRACE_ERROR("failed to alloc SCB");
             break;
         }
 
@@ -534,7 +587,11 @@
             }
 
             /* Set the Capturing service class bit */
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+            cod.service = BTM_COD_SERVICE_CAPTURING | BTM_COD_SERVICE_RENDERING;
+#else
             cod.service = BTM_COD_SERVICE_CAPTURING;
+#endif
             utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
         } /* if 1st channel */
 
@@ -550,7 +607,7 @@
         */
         cs.nsc_mask = AVDT_NSC_RECONFIG |
               ((bta_av_cb.features & BTA_AV_FEAT_PROTECT) ? 0 : AVDT_NSC_SECURITY);
-        APPL_TRACE_DEBUG1("nsc_mask: 0x%x", cs.nsc_mask);
+        APPL_TRACE_DEBUG("nsc_mask: 0x%x", cs.nsc_mask);
 
         if (p_data->api_reg.p_service_name[0] == 0)
         {
@@ -594,10 +651,28 @@
                 (*bta_av_a2d_cos.init)(&codec_type, cs.cfg.codec_info,
                 &cs.cfg.num_protect, cs.cfg.protect_info, index) == TRUE)
             {
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+            if(index == 1)
+            {
+                cs.tsep = AVDT_TSEP_SNK;
+                cs.p_data_cback = bta_av_stream_data_cback;
+            }
+                APPL_TRACE_DEBUG(" SEP Type = %d",cs.tsep);
+#endif
                 if(AVDT_CreateStream(&p_scb->seps[index].av_handle, &cs) == AVDT_SUCCESS)
                 {
                     p_scb->seps[index].codec_type = codec_type;
-                    APPL_TRACE_DEBUG3("audio[%d] av_handle: %d codec_type: %d",
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+                    p_scb->seps[index].tsep = cs.tsep;
+                    if(cs.tsep == AVDT_TSEP_SNK)
+                        p_scb->seps[index].p_app_data_cback = p_data->api_reg.p_app_data_cback;
+                    else
+                        p_scb->seps[index].p_app_data_cback = NULL; /* In case of A2DP SOURCE we don't need a callback to handle media packets */
+#endif
+
+                    APPL_TRACE_DEBUG("audio[%d] av_handle: %d codec_type: %d",
                         index, p_scb->seps[index].av_handle, p_scb->seps[index].codec_type);
                     index++;
                 }
@@ -613,6 +688,12 @@
                                   A2D_SUPF_PLAYER, bta_av_cb.sdp_a2d_handle);
                 bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
 
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+                bta_av_cb.sdp_a2d_snk_handle = SDP_CreateRecord();
+                A2D_AddRecord(UUID_SERVCLASS_AUDIO_SINK, p_avk_service_name, NULL,
+                                  A2D_SUPF_PLAYER, bta_av_cb.sdp_a2d_snk_handle);
+                bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SINK);
+#endif
                 /* start listening when A2DP is registered */
                 if (bta_av_cb.features & BTA_AV_FEAT_RCTG)
                     bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
@@ -641,7 +722,7 @@
                 }
             }
             bta_av_cb.reg_audio |= BTA_AV_HNDL_TO_MSK(p_scb->hdi);
-            APPL_TRACE_DEBUG1("reg_audio: 0x%x",bta_av_cb.reg_audio);
+            APPL_TRACE_DEBUG("reg_audio: 0x%x",bta_av_cb.reg_audio);
         }
         else
         {
@@ -805,7 +886,7 @@
     int     i;
     UINT8   mask;
 
-    APPL_TRACE_DEBUG1("reg_audio: 0x%x",bta_av_cb.reg_audio);
+    APPL_TRACE_DEBUG("reg_audio: 0x%x",bta_av_cb.reg_audio);
     for(i=0; i<BTA_AV_NUM_STRS; i++)
     {
         mask = BTA_AV_HNDL_TO_MSK(i);
@@ -838,7 +919,7 @@
     UINT8       peer_idx = 0;
     UNUSED(status);
 
-    APPL_TRACE_DEBUG1("bta_av_sys_rs_cback: %d", bta_av_cb.rs_idx);
+    APPL_TRACE_DEBUG("bta_av_sys_rs_cback: %d", bta_av_cb.rs_idx);
     for(i=0; i<BTA_AV_NUM_STRS; i++)
     {
         /* loop through all the SCBs to find matching peer addresses and report the role change event */
@@ -847,7 +928,7 @@
         if (p_scb && (bdcmp (peer_addr, p_scb->peer_addr) == 0) &&
             (p_buf = (tBTA_AV_ROLE_RES *) GKI_getbuf(sizeof(tBTA_AV_ROLE_RES))) != NULL)
         {
-            APPL_TRACE_DEBUG3("new_role:%d, hci_status:x%x hndl: x%x", id, app_id, p_scb->hndl);
+            APPL_TRACE_DEBUG("new_role:%d, hci_status:x%x hndl: x%x", id, app_id, p_scb->hndl);
             /*
             if ((id != BTM_ROLE_MASTER) && (app_id != HCI_SUCCESS))
             {
@@ -879,7 +960,7 @@
         p_scb = bta_av_cb.p_scb[bta_av_cb.rs_idx - 1];
         if (p_scb && p_scb->q_tag == BTA_AV_Q_TAG_OPEN)
         {
-            APPL_TRACE_DEBUG3 ("bta_av_sys_rs_cback: rs_idx(%d), hndl:x%x q_tag: %d",
+            APPL_TRACE_DEBUG ("bta_av_sys_rs_cback: rs_idx(%d), hndl:x%x q_tag: %d",
                 bta_av_cb.rs_idx, p_scb->hndl, p_scb->q_tag);
 
             if(HCI_SUCCESS == app_id || HCI_ERR_NO_CONNECTION == app_id)
@@ -915,7 +996,7 @@
     UNUSED(app_id);
     UNUSED(peer_addr);
 
-    APPL_TRACE_DEBUG2("bta_av_sco_chg_cback:%d status:%d", id, status);
+    APPL_TRACE_DEBUG("bta_av_sco_chg_cback:%d status:%d", id, status);
     if(id)
     {
         bta_av_cb.sco_occupied = TRUE;
@@ -927,7 +1008,7 @@
 
             if( p_scb && p_scb->co_started && (p_scb->sco_suspend == FALSE))
             {
-                APPL_TRACE_DEBUG1("suspending scb:%d", i);
+                APPL_TRACE_DEBUG("suspending scb:%d", i);
                 /* scb is used and started, not suspended automatically */
                 p_scb->sco_suspend = TRUE;
                 stop.flush   = FALSE;
@@ -946,7 +1027,7 @@
 
             if( p_scb && p_scb->sco_suspend ) /* scb is used and suspended for SCO */
             {
-                APPL_TRACE_DEBUG1("starting scb:%d", i);
+                APPL_TRACE_DEBUG("starting scb:%d", i);
                 bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
             }
         }
@@ -1020,7 +1101,7 @@
 
     if (BTM_GetRole(p_scb->peer_addr, &role) == BTM_SUCCESS)
     {
-        APPL_TRACE_ERROR5("bta_av_link_role_ok hndl:x%x role:%d, conn_audio:x%x, bits:%d, features:x%x", p_scb->hndl, role, bta_av_cb.conn_audio, bits, bta_av_cb.features);
+        APPL_TRACE_ERROR("bta_av_link_role_ok hndl:x%x role:%d, conn_audio:x%x, bits:%d, features:x%x", p_scb->hndl, role, bta_av_cb.conn_audio, bits, bta_av_cb.features);
         if (BTM_ROLE_MASTER != role && (A2D_BitsSet(bta_av_cb.conn_audio) > bits || (bta_av_cb.features & BTA_AV_FEAT_MASTER)))
         {
             if (bta_av_cb.features & BTA_AV_FEAT_MASTER)
@@ -1070,7 +1151,7 @@
                 if((p_scb != p_scbi) && p_scbi && (p_scbi->chnl == BTA_AV_CHNL_AUDIO) )
                 {
                     mask = BTA_AV_HNDL_TO_MSK(i);
-                    APPL_TRACE_DEBUG3("[%d] mtu: %d, mask:0x%x",
+                    APPL_TRACE_DEBUG("[%d] mtu: %d, mask:0x%x",
                         i, p_scbi->stream_mtu, mask);
                     if(bta_av_cb.conn_audio & mask)
                     {
@@ -1080,7 +1161,7 @@
                 }
             }
         }
-        APPL_TRACE_DEBUG3("bta_av_chk_mtu audio count:%d, conn_audio:0x%x, ret:%d",
+        APPL_TRACE_DEBUG("bta_av_chk_mtu audio count:%d, conn_audio:0x%x, ret:%d",
             bta_av_cb.audio_open_cnt, bta_av_cb.conn_audio, ret_mtu);
     }
     return ret_mtu;
@@ -1153,10 +1234,10 @@
     UINT8               action;
 
 #if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
-    APPL_TRACE_EVENT4("AV event=0x%x(%s) state=%d(%s)",
+    APPL_TRACE_EVENT("AV event=0x%x(%s) state=%d(%s)",
         event, bta_av_evt_code(event), p_cb->state, bta_av_st_code(p_cb->state));
 #else
-    APPL_TRACE_EVENT2("AV event=0x%x state=%d", event, p_cb->state);
+    APPL_TRACE_EVENT("AV event=0x%x state=%d", event, p_cb->state);
 #endif
 
     /* look up the state table for the current state */
@@ -1166,7 +1247,7 @@
 
     /* set next state */
     p_cb->state = state_table[event][BTA_AV_NEXT_STATE];
-    APPL_TRACE_EVENT1("next state=%d", p_cb->state);
+    APPL_TRACE_EVENT("next state=%d", p_cb->state);
 
     /* execute action functions */
     if ((action = state_table[event][BTA_AV_ACTION_COL]) != BTA_AV_IGNORE)
@@ -1199,9 +1280,9 @@
     if(event >= first_event)
     {
 #if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
-        APPL_TRACE_VERBOSE2("AV nsm event=0x%x(%s)", event, bta_av_evt_code(event));
+        APPL_TRACE_VERBOSE("AV nsm event=0x%x(%s)", event, bta_av_evt_code(event));
 #else
-        APPL_TRACE_VERBOSE1("AV nsm event=0x%x", event);
+        APPL_TRACE_VERBOSE("AV nsm event=0x%x", event);
 #endif
         /* non state machine events */
         (*bta_av_nsm_act[event - BTA_AV_FIRST_NSM_EVT]) ((tBTA_AV_DATA *) p_msg);
@@ -1209,16 +1290,16 @@
     else if (event >= BTA_AV_FIRST_SM_EVT && event <= BTA_AV_LAST_SM_EVT)
     {
 #if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
-        APPL_TRACE_VERBOSE2("AV sm event=0x%x(%s)", event, bta_av_evt_code(event));
+        APPL_TRACE_VERBOSE("AV sm event=0x%x(%s)", event, bta_av_evt_code(event));
 #else
-        APPL_TRACE_VERBOSE1("AV sm event=0x%x", event);
+        APPL_TRACE_VERBOSE("AV sm event=0x%x", event);
 #endif
         /* state machine events */
         bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA *) p_msg);
     }
     else
     {
-        APPL_TRACE_VERBOSE1("handle=0x%x", p_msg->layer_specific);
+        APPL_TRACE_VERBOSE("handle=0x%x", p_msg->layer_specific);
         /* stream state machine events */
         bta_av_ssm_execute( bta_av_hndl_to_scb(p_msg->layer_specific),
                                 p_msg->event, (tBTA_AV_DATA *) p_msg);
@@ -1318,6 +1399,9 @@
     case BTA_AV_AVRC_CLOSE_EVT: return "AVRC_CLOSE";
     case BTA_AV_CONN_CHG_EVT: return "CONN_CHG";
     case BTA_AV_DEREG_COMP_EVT: return "DEREG_COMP";
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+    case BTA_AV_API_SINK_ENABLE_EVT: return "SINK_ENABLE";
+#endif
 #if (AVDT_REPORTING == TRUE)
     case BTA_AV_AVDT_RPT_CONN_EVT: return "RPT_CONN";
 #endif
diff --git a/bta/av/bta_av_sbc.c b/bta/av/bta_av_sbc.c
index a570375..dec24df 100644
--- a/bta/av/bta_av_sbc.c
+++ b/bta/av/bta_av_sbc.c
@@ -441,7 +441,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("bta_av_sbc_cfg_for_cap: ch_mode(0x%02X) not supported", p_pref->ch_mode);
+        APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: ch_mode(0x%02X) not supported", p_pref->ch_mode);
         return A2D_FAIL;
     }
 
@@ -452,7 +452,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("bta_av_sbc_cfg_for_cap: samp_freq(0x%02X) not supported", p_pref->samp_freq);
+        APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: samp_freq(0x%02X) not supported", p_pref->samp_freq);
         return A2D_FAIL;
     }
 
@@ -463,7 +463,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("bta_av_sbc_cfg_for_cap: block_len(0x%02X) not supported", p_pref->block_len);
+        APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: block_len(0x%02X) not supported", p_pref->block_len);
         return A2D_FAIL;
     }
 
@@ -474,7 +474,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("bta_av_sbc_cfg_for_cap: num_subbands(0x%02X) not supported", p_pref->num_subbands);
+        APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: num_subbands(0x%02X) not supported", p_pref->num_subbands);
         return A2D_FAIL;
     }
 
@@ -485,7 +485,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("bta_av_sbc_cfg_for_cap: alloc_mthd(0x%02X) not supported", p_pref->alloc_mthd);
+        APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: alloc_mthd(0x%02X) not supported", p_pref->alloc_mthd);
         return A2D_FAIL;
     }
 
@@ -511,6 +511,78 @@
 
 /*******************************************************************************
 **
+** Function         bta_av_sbc_cfg_matches_cap
+**
+** Description      This function checks whether an SBC codec configuration
+**                  matched with capabilities. Here we check subset.
+**
+** Returns          0 if ok, nonzero if error.
+**
+*******************************************************************************/
+UINT8 bta_av_sbc_cfg_matches_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap)
+{
+    UINT8           status = 0;
+    tA2D_SBC_CIE    cfg_cie;
+
+    /* parse configuration */
+    if ((status = A2D_ParsSbcInfo(&cfg_cie, p_cfg, TRUE)) != 0)
+    {
+        APPL_TRACE_ERROR(" bta_av_sbc_cfg_matches_cap Parsing Failed %d", status);
+        return status;
+    }
+
+    /* verify that each parameter is in range */
+
+    APPL_TRACE_DEBUG(" FREQ peer: 0%x, capability  0%x", cfg_cie.samp_freq, p_cap->samp_freq);
+    APPL_TRACE_DEBUG(" CH_MODE peer: 0%x, capability  0%x", cfg_cie.ch_mode, p_cap->ch_mode);
+    APPL_TRACE_DEBUG(" BLOCK_LEN peer: 0%x, capability  0%x", cfg_cie.block_len, p_cap->block_len);
+    APPL_TRACE_DEBUG(" SUB_BAND peer: 0%x, capability  0%x", cfg_cie.num_subbands, p_cap->num_subbands);
+    APPL_TRACE_DEBUG(" ALLOC_MTHD peer: 0%x, capability  0%x", cfg_cie.alloc_mthd, p_cap->alloc_mthd);
+    APPL_TRACE_DEBUG(" MAX_BitPool peer: 0%x, capability  0%x", cfg_cie.max_bitpool, p_cap->max_bitpool);
+    APPL_TRACE_DEBUG(" Min_bitpool peer: 0%x, capability  0%x", cfg_cie.min_bitpool, p_cap->min_bitpool);
+
+    /* sampling frequency */
+    if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0)
+    {
+        status = A2D_NS_SAMP_FREQ;
+    }
+    /* channel mode */
+    else if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0)
+    {
+        status = A2D_NS_CH_MODE;
+    }
+    /* block length */
+    else if ((cfg_cie.block_len & p_cap->block_len) == 0)
+    {
+        status = A2D_BAD_BLOCK_LEN;
+    }
+    /* subbands */
+    else if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0)
+    {
+        status = A2D_NS_SUBBANDS;
+    }
+    /* allocation method */
+    else if ((cfg_cie.alloc_mthd & p_cap->alloc_mthd) == 0)
+    {
+        status = A2D_NS_ALLOC_MTHD;
+    }
+    /* max bitpool */
+    else if (cfg_cie.max_bitpool > p_cap->max_bitpool)
+    {
+        status = A2D_NS_MAX_BITPOOL;
+    }
+    /* min bitpool */
+    else if (cfg_cie.min_bitpool < p_cap->min_bitpool)
+    {
+        status = A2D_NS_MIN_BITPOOL;
+    }
+
+    return status;
+}
+
+
+/*******************************************************************************
+**
 ** Function         bta_av_sbc_cfg_in_cap
 **
 ** Description      This function checks whether an SBC codec configuration
@@ -532,6 +604,7 @@
 
     /* verify that each parameter is in range */
 
+
     /* sampling frequency */
     if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0)
     {
diff --git a/bta/av/bta_av_ssm.c b/bta/av/bta_av_ssm.c
index 407146e..64ee42a 100644
--- a/bta/av/bta_av_ssm.c
+++ b/bta/av/bta_av_ssm.c
@@ -162,7 +162,7 @@
 /* API_RC_OPEN_EVT  */      {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
 /* SRC_DATA_READY_EVT */    {BTA_AV_SIGNORE,        BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
 /* CI_SETCONFIG_OK_EVT */   {BTA_AV_SETCONFIG_RSP,  BTA_AV_ST_RC_TIMER,    BTA_AV_INCOMING_SST },
-/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SETCONFIG_RSP,  BTA_AV_CLEANUP,        BTA_AV_INIT_SST },
+/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SETCONFIG_REJ,  BTA_AV_CLEANUP,        BTA_AV_INIT_SST },
 /* SDP_DISC_OK_EVT */       {BTA_AV_FREE_SDB,       BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
 /* SDP_DISC_FAIL_EVT */     {BTA_AV_FREE_SDB,       BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
 /* STR_DISC_OK_EVT */       {BTA_AV_DISC_RES_AS_ACP,BTA_AV_SIGNORE,        BTA_AV_INCOMING_SST },
@@ -410,7 +410,7 @@
     if(p_scb == NULL)
     {
         /* this stream is not registered */
-        APPL_TRACE_EVENT0("AV channel not registered");
+        APPL_TRACE_EVENT("AV channel not registered");
         return;
     }
 
@@ -436,10 +436,10 @@
     }
 
 #if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
-    APPL_TRACE_VERBOSE5("AV Sevent(0x%x)=0x%x(%s) state=%d(%s)",
+    APPL_TRACE_VERBOSE("AV Sevent(0x%x)=0x%x(%s) state=%d(%s)",
         p_scb->hndl, event, bta_av_evt_code(event), p_scb->state, bta_av_sst_code(p_scb->state));
 #else
-    APPL_TRACE_VERBOSE2("AV Sevent=0x%x state=%d", event, p_scb->state);
+    APPL_TRACE_VERBOSE("AV Sevent=0x%x state=%d", event, p_scb->state);
 #endif
 
     /* look up the state table for the current state */
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
old mode 100755
new mode 100644
index ee1ba03..2ef728b
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- *  Copyright (C) 2003-2012 Broadcom Corporation
+ *  Copyright (C) 2003-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@
 #include "l2c_api.h"
 #include "wbt_api.h"
 #include "utl.h"
+#include "gap_api.h"    /* For GAP_BleReadPeerPrefConnParams */
 #include <string.h>
 
 #if (GAP_INCLUDED == TRUE)
@@ -89,7 +90,7 @@
 static char *bta_dm_get_remname(void);
 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
 
-static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr);
+static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport);
 static void bta_dm_discover_device(BD_ADDR remote_bd_addr);
 
 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status );
@@ -108,9 +109,11 @@
 static void btm_dm_start_gatt_discovery ( BD_ADDR bd_addr);
 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr);
 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
+extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
     #endif
 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
 static void bta_dm_observe_cmpl_cb (void * p_result);
+static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
 
 #ifndef BTA_DM_BLE_ADV_CHNL_MAP
 #define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37|BTM_BLE_ADV_CHNL_38|BTM_BLE_ADV_CHNL_39)
@@ -240,26 +243,6 @@
 
 /*******************************************************************************
 **
-** Function         bta_dm_app_ready_timer_cback
-**
-** Description      allow sending EIR to controller
-**
-**
-** Returns          void
-**
-*******************************************************************************/
-#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&(BTA_EIR_CANNED_UUID_LIST != TRUE)
-static void bta_dm_app_ready_timer_cback (TIMER_LIST_ENT *p_tle)
-{
-    UNUSED(p_tle);
-    bta_dm_set_eir (NULL);
-}
-#else
-#define bta_dm_app_ready_timer_cback (x)
-#endif
-
-/*******************************************************************************
-**
 ** Function         bta_dm_enable
 **
 ** Description      Initialises the BT device manager
@@ -276,7 +259,7 @@
     /* if already in use, return an error */
     if( bta_dm_cb.is_bta_dm_active == TRUE  )
     {
-        APPL_TRACE_WARNING0("bta_dm_enable - device already started by another application");
+        APPL_TRACE_WARNING("bta_dm_enable - device already started by another application");
         memset(&sec_event.enable, 0, sizeof ( tBTA_DM_ENABLE ));
         sec_event.enable.status = BTA_FAILURE;
         if( p_data->enable.p_sec_cback != NULL  )
@@ -330,7 +313,7 @@
     tBTA_BLE_LOCAL_ID_KEYS  id_key;
     tBT_UUID                app_uuid = {LEN_UUID_128,{0}};
 #endif
-    APPL_TRACE_DEBUG1(" bta_dm_sys_hw_cback with event: %i" , status );
+    APPL_TRACE_DEBUG(" bta_dm_sys_hw_cback with event: %i" , status );
 
     /* On H/W error evt, report to the registered DM application callback */
     if (status == BTA_SYS_HW_ERROR_EVT) {
@@ -401,6 +384,11 @@
 #else
         BTM_AclRegisterForChanges(bta_dm_acl_change_cback);
 #endif
+
+#if BLE_VND_INCLUDED == TRUE
+        BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback);
+#endif
+
         /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the bd_addr
            from the control block and invoking the callback which was sending the DM_ENABLE_EVT.
            But then we have a few HCI commands being invoked above which were still in progress
@@ -415,28 +403,6 @@
 
         bta_sys_policy_register((tBTA_SYS_CONN_CBACK*)bta_dm_policy_cback);
 
-
-        // BLUEDROID REMOVE ??
-#if 0
-#if 1
-        /* Create broadcom primary DI record */
-        if(WBT_ExtCreateRecord())
-        {
-#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )
-            /* while app_ready_timer is running, BTA DM doesn't send EIR to controller */
-            bta_dm_cb.app_ready_timer.p_cback = (TIMER_CBACK*)&bta_dm_app_ready_timer_cback;
-            bta_sys_start_timer(&bta_dm_cb.app_ready_timer, 0, 100);
-
-            bta_sys_add_uuid(UUID_SERVCLASS_PNP_INFORMATION);
-#endif
-            bta_dm_di_cb.di_handle[bta_dm_di_cb.di_num] = 0;    /* primary DI record */
-            bta_dm_di_cb.di_num ++;
-        }
-#else   /* Eventually implement pin code */
-        if (WBT_ExtCreateRecord())
-            WBT_ExtAddPinCode();
-#endif
-#endif
 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
         memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
         bta_dm_gattc_register();
@@ -444,7 +410,7 @@
 
     }
     else
-        APPL_TRACE_DEBUG0(" --- ignored event");
+        APPL_TRACE_DEBUG(" --- ignored event");
 
 }
 
@@ -476,6 +442,9 @@
     bta_dm_disable_search_and_disc();
     bta_dm_cb.disabling = TRUE;
 
+#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
+    BTM_BleClearBgConnDev();
+#endif
 
     if(BTM_GetNumAclLinks()==0)
     {
@@ -483,7 +452,7 @@
         /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the shutdown by
          * BTA_DISABLE_DELAY milliseconds
          */
-        APPL_TRACE_WARNING2("%s BTA_DISABLE_DELAY set to %d ms",
+        APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms",
                             __FUNCTION__, BTA_DISABLE_DELAY);
         bta_sys_stop_timer(&bta_dm_cb.disable_timer);
         bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_conn_down_timer_cback;
@@ -495,6 +464,7 @@
     else
     {
         bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_timer_cback;
+        bta_dm_cb.disable_timer.param = 0;
         bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 5000);
     }
 
@@ -516,17 +486,31 @@
 {
     UNUSED(p_tle);
     UINT8 i;
+    tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+    BOOLEAN trigger_disc = FALSE;
 
-    APPL_TRACE_EVENT0(" bta_dm_disable_timer_cback  ");
 
-    if(BTM_GetNumAclLinks())
+    APPL_TRACE_EVENT(" bta_dm_disable_timer_cback trial %d ", p_tle->param);
+
+    if(BTM_GetNumAclLinks() && p_tle->param == 0)
     {
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
-            btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
-
+#if (BLE_INCLUDED == TRUE)
+            transport = bta_dm_cb.device_list.peer_device[i].transport;
+#endif
+            btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, transport);
+            trigger_disc = TRUE;
         }
 
+        /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still need
+            to be sent out to avoid jave layer disable timeout */
+        if (trigger_disc)
+        {
+            bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK*)&bta_dm_disable_timer_cback;
+            bta_dm_cb.disable_timer.param = 1;
+            bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 1500);
+        }
     }
     else
     {
@@ -665,7 +649,7 @@
 {
     if (BTM_WriteInquiryTxPower (p_data->tx_inq_pwr.tx_power) == BTM_ILLEGAL_VALUE)
     {
-        APPL_TRACE_ERROR1("Invalid Inquiry Tx Power: %d", p_data->tx_inq_pwr.tx_power);
+        APPL_TRACE_ERROR("Invalid Inquiry Tx Power: %d", p_data->tx_inq_pwr.tx_power);
     }
     return;
 }
@@ -688,22 +672,25 @@
     BTA_GATTC_CancelOpen(0, p_dev->bd_addr, FALSE);
 #endif
 
-    if (BTM_IsAclConnectionUp(p_dev->bd_addr))
+    if ( BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
+         BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR))
     {
+           APPL_TRACE_DEBUG("%s: ACL Up count  %d", __FUNCTION__,bta_dm_cb.device_list.count);
         /* Take the link down first, and mark the device for removal when disconnected */
-        btm_remove_acl( p_dev->bd_addr) ;
 
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
             if(!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr))
-            break;
-        }
-
-        if(i < bta_dm_cb.device_list.count)
-        {
-            bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
+            {
+                bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
+                btm_remove_acl( p_dev->bd_addr,bta_dm_cb.device_list.peer_device[i].transport);
+                APPL_TRACE_DEBUG("%s:transport = %d", __FUNCTION__,
+                                   bta_dm_cb.device_list.peer_device[i].transport);
+                break;
+            }
         }
     }
+
     else    /* Ok to remove the device in application layer */
     {
         BTM_SecDeleteDevice(p_dev->bd_addr);
@@ -770,7 +757,7 @@
     if (!BTM_SecAddDevice (p_dev->bd_addr, p_dc, p_dev->bd_name, p_dev->features,
                            trusted_services_mask, p_lc, p_dev->key_type, p_dev->io_cap))
     {
-        APPL_TRACE_ERROR2 ("BTA_DM: Error adding device %08x%04x",
+        APPL_TRACE_ERROR ("BTA_DM: Error adding device %08x%04x",
                 (p_dev->bd_addr[0]<<24)+(p_dev->bd_addr[1]<<16)+(p_dev->bd_addr[2]<<8)+p_dev->bd_addr[3],
                 (p_dev->bd_addr[4]<<8)+p_dev->bd_addr[5]);
     }
@@ -789,15 +776,23 @@
 {
     tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl;
     UINT8   index;
+    tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
 
-    APPL_TRACE_DEBUG0("bta_dm_close_acl");
+    APPL_TRACE_DEBUG("bta_dm_close_acl");
 
-    if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr))
+    if ( BTM_IsAclConnectionUp(p_remove_acl->bd_addr, BT_TRANSPORT_LE) ||
+         BTM_IsAclConnectionUp(p_remove_acl->bd_addr, BT_TRANSPORT_BR_EDR))
+
     {
         for (index = 0; index < bta_dm_cb.device_list.count; index ++)
         {
             if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr))
+            {
+#if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
+                transport = bta_dm_cb.device_list.peer_device[index].transport;
+#endif
                 break;
+            }
         }
         if (index != bta_dm_cb.device_list.count)
         {
@@ -806,17 +801,17 @@
         }
         else
         {
-            APPL_TRACE_ERROR0("unknown device, remove ACL failed");
+            APPL_TRACE_ERROR("unknown device, remove ACL failed");
         }
         /* Disconnect the ACL link */
-        btm_remove_acl(p_remove_acl->bd_addr);
+        btm_remove_acl(p_remove_acl->bd_addr, transport);
     }
     /* if to remove the device from security database ? do it now */
     else if (p_remove_acl->remove_dev)
     {
         if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr))
         {
-            APPL_TRACE_ERROR0("delete device from security database failed.");
+            APPL_TRACE_ERROR("delete device from security database failed.");
         }
 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
         /* need to remove all pending background connection if any */
@@ -844,7 +839,11 @@
     tBTA_DM_SEC sec_event;
     char        *p_name;
 
-    status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
+    if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN)
+        status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
+    else
+        status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 );
+
 
     if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))
     {
@@ -892,7 +891,7 @@
     tBTM_STATUS status;
     tBTA_DM_SEC sec_event;
 
-    APPL_TRACE_EVENT0(" bta_dm_bond_cancel ");
+    APPL_TRACE_EVENT(" bta_dm_bond_cancel ");
     status = BTM_SecBondCancel ( p_data->bond_cancel.bd_addr );
 
     if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED && status != BTM_SUCCESS))
@@ -960,7 +959,7 @@
     if(!p_dev)
         return;
 
-    APPL_TRACE_DEBUG2(" bta_dm_link_policy set:%d, policy:0x%x",
+    APPL_TRACE_DEBUG(" bta_dm_link_policy set:%d, policy:0x%x",
         p_data->link_policy.set, p_data->link_policy.policy_mask);
     if(p_data->link_policy.set)
     {
@@ -1000,7 +999,7 @@
     if(peer_addr)
         p_dev = bta_dm_find_peer_device(peer_addr);
 
-    APPL_TRACE_DEBUG2(" bta_dm_policy_cback cmd:%d, policy:0x%x",
+    APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x",
         status, policy);
     switch(status)
     {
@@ -1204,7 +1203,7 @@
     UINT16 len = (UINT16)(sizeof(tBT_UUID) * p_data->search.num_uuid);
 #endif
 
-    APPL_TRACE_DEBUG1("bta_dm_search_start avoid_scatter=%d", bta_dm_cfg.avoid_scatter);
+    APPL_TRACE_DEBUG("bta_dm_search_start avoid_scatter=%d", bta_dm_cfg.avoid_scatter);
     if (bta_dm_cfg.avoid_scatter &&
         (p_data->search.rs_res == BTA_DM_RS_NONE) && bta_dm_check_av(BTA_DM_API_SEARCH_EVT))
     {
@@ -1225,7 +1224,7 @@
     {
         if ((bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)GKI_getbuf(len)) == NULL)
         {
-            APPL_TRACE_ERROR0("bta_dm_search_start no resources");
+            APPL_TRACE_ERROR("bta_dm_search_start no resources");
 
             result.status = BTA_FAILURE;
             result.num_resp = 0;
@@ -1240,7 +1239,7 @@
                         bta_dm_inq_results_cb,
                         (tBTM_CMPL_CB*) bta_dm_inq_cmpl_cb);
 
-    APPL_TRACE_EVENT1("bta_dm_search_start status=%d", result.status);
+    APPL_TRACE_EVENT("bta_dm_search_start status=%d", result.status);
     if (result.status != BTM_CMD_STARTED)
     {
         result.num_resp = 0;
@@ -1305,7 +1304,7 @@
 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
     UINT16 len = (UINT16)(sizeof(tBT_UUID) * p_data->discover.num_uuid);
 #endif
-    APPL_TRACE_EVENT2("bta_dm_discover services_to_search=0x%04X, sdp_search=%d",
+    APPL_TRACE_EVENT("bta_dm_discover services_to_search=0x%04X, sdp_search=%d",
                       p_data->discover.services, p_data->discover.sdp_search);
 
     /* save the search condition */
@@ -1334,6 +1333,7 @@
     bta_dm_search_cb.peer_name[0] = 0;
     bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
     bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr);
+    bta_dm_search_cb.transport = p_data->discover.transport;
 
     bta_dm_search_cb.name_discover_done = FALSE;
     memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID));
@@ -1479,7 +1479,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR0("No buffer to start DI discovery");
+        APPL_TRACE_ERROR("No buffer to start DI discovery");
     }
 
     if ( result == BTA_FAILURE &&
@@ -1501,27 +1501,28 @@
 ** Returns          TRUE if started to get remote name
 **
 *******************************************************************************/
-static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr)
+static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport)
 {
     tBTM_STATUS  btm_status;
 
-    APPL_TRACE_DEBUG0("bta_dm_read_remote_device_name");
+    APPL_TRACE_DEBUG("bta_dm_read_remote_device_name");
 
     bdcpy(bta_dm_search_cb.peer_bdaddr, bd_addr);
     bta_dm_search_cb.peer_name[0] = 0;
 
     btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
-                                           (tBTM_CMPL_CB *) bta_dm_remname_cback);
+                                           (tBTM_CMPL_CB *) bta_dm_remname_cback,
+                                           transport);
 
     if ( btm_status == BTM_CMD_STARTED )
     {
-        APPL_TRACE_DEBUG0("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is started");
+        APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is started");
 
         return (TRUE);
     }
     else if ( btm_status == BTM_BUSY )
     {
-        APPL_TRACE_DEBUG0("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy");
+        APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy");
 
         /* Remote name discovery is on going now so BTM cannot notify through "bta_dm_remname_cback" */
         /* adding callback to get notified that current reading remore name done */
@@ -1531,7 +1532,7 @@
     }
     else
     {
-        APPL_TRACE_WARNING1("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
+        APPL_TRACE_WARNING("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
 
         return (FALSE);
     }
@@ -1551,7 +1552,7 @@
     tBTA_DM_MSG * p_msg;
     tBTA_DM_SEARCH  data;
 
-    APPL_TRACE_DEBUG0("bta_dm_inq_cmpl");
+    APPL_TRACE_DEBUG("bta_dm_inq_cmpl");
 
     data.inq_cmpl.num_resps = p_data->inq_cmpl.num;
     bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data);
@@ -1588,7 +1589,7 @@
 *******************************************************************************/
 void bta_dm_rmt_name (tBTA_DM_MSG *p_data)
 {
-    APPL_TRACE_DEBUG0("bta_dm_rmt_name");
+    APPL_TRACE_DEBUG("bta_dm_rmt_name");
 
     if( p_data->rem_name.result.disc_res.bd_name[0] && bta_dm_search_cb.p_btm_inq_info)
     {
@@ -1612,7 +1613,7 @@
 {
     tBTM_INQ_INFO *p_btm_inq_info;
 
-    APPL_TRACE_DEBUG0("bta_dm_disc_rmt_name");
+    APPL_TRACE_DEBUG("bta_dm_disc_rmt_name");
 
     p_btm_inq_info = BTM_InqDbRead (p_data->rem_name.result.disc_res.bd_addr);
     if( p_btm_inq_info )
@@ -1658,7 +1659,7 @@
         || (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH)
         || (p_data->sdp_event.sdp_result == SDP_DB_FULL))
     {
-        APPL_TRACE_DEBUG1("sdp_result::0x%x", p_data->sdp_event.sdp_result);
+        APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result);
         do
         {
 
@@ -1775,7 +1776,7 @@
 
 //        GKI_freebuf(bta_dm_search_cb.p_sdp_db);
 //        bta_dm_search_cb.p_sdp_db = NULL;
-        APPL_TRACE_DEBUG1("bta_dm_sdp_result services_found = %04x", bta_dm_search_cb.services_found);
+        APPL_TRACE_DEBUG("bta_dm_sdp_result services_found = %04x", bta_dm_search_cb.services_found);
 
         /* Collect the 128-bit services here and put them into the list */
         if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK)
@@ -1826,12 +1827,12 @@
                                num_uuids*MAX_UUID_SIZE);
                     } else {
                        p_msg->disc_result.result.disc_res.num_uuids = 0;
-                       APPL_TRACE_ERROR1("%s: Unable to allocate memory for uuid_list", __FUNCTION__);
+                       APPL_TRACE_ERROR("%s: Unable to allocate memory for uuid_list", __FUNCTION__);
                     }
                 }
                 //copy the raw_data to the discovery result  structure
                 //
-                APPL_TRACE_DEBUG2("bta_dm_sdp_result (raw_data used = 0x%x raw_data_ptr = 0x%x)\r\n",bta_dm_search_cb.p_sdp_db->raw_used, bta_dm_search_cb.p_sdp_db->raw_data);
+                APPL_TRACE_DEBUG("bta_dm_sdp_result (raw_data used = 0x%x raw_data_ptr = 0x%x)\r\n",bta_dm_search_cb.p_sdp_db->raw_used, bta_dm_search_cb.p_sdp_db->raw_data);
 
                 if (  bta_dm_search_cb.p_sdp_db != NULL && bta_dm_search_cb.p_sdp_db->raw_used != 0   &&
                     bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
@@ -1846,7 +1847,7 @@
                             bta_dm_search_cb.p_sdp_db->raw_used;
 
                     } else {
-                        APPL_TRACE_DEBUG1("bta_dm_sdp_result GKI Alloc failed to allocate %d bytes !!\r\n",bta_dm_search_cb.p_sdp_db->raw_used);
+                        APPL_TRACE_DEBUG("bta_dm_sdp_result GKI Alloc failed to allocate %d bytes !!\r\n",bta_dm_search_cb.p_sdp_db->raw_used);
                     }
 
                     bta_dm_search_cb.p_sdp_db->raw_data = NULL;     //no need to free this - it is a global assigned.
@@ -1854,7 +1855,7 @@
                     bta_dm_search_cb.p_sdp_db->raw_size = 0;
                 }
                 else {
-                    APPL_TRACE_DEBUG0("bta_dm_sdp_result raw data size is 0 or raw_data is null!!\r\n");
+                    APPL_TRACE_DEBUG("bta_dm_sdp_result raw data size is 0 or raw_data is null!!\r\n");
                 }
                 /* Done with p_sdp_db. Free it */
                 bta_dm_free_sdp_db(NULL);
@@ -1866,7 +1867,7 @@
                   p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn);
                   p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
 
-                  APPL_TRACE_EVENT1(" Piggy back the SCN over result field  SCN=%d", bta_dm_search_cb.peer_scn);
+                  APPL_TRACE_EVENT(" Piggy back the SCN over result field  SCN=%d", bta_dm_search_cb.peer_scn);
 
                 }
                 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
@@ -1923,7 +1924,7 @@
 *******************************************************************************/
 void bta_dm_search_cmpl (tBTA_DM_MSG *p_data)
 {
-    APPL_TRACE_DEBUG0("bta_dm_search_cmpl");
+    APPL_TRACE_DEBUG("bta_dm_search_cmpl");
 
 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
     utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
@@ -1948,7 +1949,7 @@
 {
     tBTA_DM_MSG *      p_msg;
 
-    APPL_TRACE_DEBUG0("bta_dm_disc_result");
+    APPL_TRACE_DEBUG("bta_dm_disc_result");
 
 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
     /* if any BR/EDR service discovery has been done, report the event */
@@ -1976,7 +1977,7 @@
 *******************************************************************************/
 void bta_dm_search_result (tBTA_DM_MSG *p_data)
 {
-    APPL_TRACE_DEBUG2("bta_dm_search_result searching:0x%04x, result:0x%04x",
+    APPL_TRACE_DEBUG("bta_dm_search_result searching:0x%04x, result:0x%04x",
                        bta_dm_search_cb.services,
                        p_data->disc_result.result.disc_res.services);
 
@@ -2020,7 +2021,7 @@
 {
     UNUSED(p_tle);
 
-    APPL_TRACE_EVENT0(" bta_dm_search_timer_cback  ");
+    APPL_TRACE_EVENT(" bta_dm_search_timer_cback  ");
     bta_dm_search_cb.wait_disc = FALSE;
 
     /* proceed with next device */
@@ -2210,11 +2211,11 @@
         {
             if((bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)GKI_getbuf(BTA_DM_SDP_DB_SIZE)) != NULL)
             {
-                APPL_TRACE_DEBUG1("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services);
+                APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services);
                 /* try to search all services by search based on L2CAP UUID */
                 if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK )
                 {
-                    APPL_TRACE_ERROR1("services_to_search = %08x",bta_dm_search_cb.services_to_search);
+                    APPL_TRACE_ERROR("services_to_search = %08x",bta_dm_search_cb.services_to_search);
                     if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK)
                     {
                         uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0];
@@ -2276,7 +2277,7 @@
                 }
 
 
-                APPL_TRACE_ERROR1("****************search UUID = %04x***********", uuid.uu.uuid16);
+                APPL_TRACE_ERROR("****************search UUID = %04x***********", uuid.uu.uuid16);
                 //SDP_InitDiscoveryDb (bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, num_attrs, attr_list);
                 SDP_InitDiscoveryDb (bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL);
 
@@ -2308,7 +2309,7 @@
             }
             else
             {
-                APPL_TRACE_ERROR0("#### Failed to allocate SDP DB buffer! ####");
+                APPL_TRACE_ERROR("#### Failed to allocate SDP DB buffer! ####");
             }
         }
 
@@ -2348,7 +2349,7 @@
 
     tBTA_DM_MSG * p_msg;
 
-    APPL_TRACE_DEBUG0("bta_dm_discover_next_device");
+    APPL_TRACE_DEBUG("bta_dm_discover_next_device");
 
     /* searching next device on inquiry result */
     if((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info)) != NULL)
@@ -2383,21 +2384,36 @@
 static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
 {
     tBTA_DM_MSG * p_msg;
+    tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+#if BLE_INCLUDED == TRUE
+        tBT_DEVICE_TYPE dev_type;
+        tBLE_ADDR_TYPE  addr_type;
 
-    APPL_TRACE_DEBUG6("bta_dm_discover_device, BDA:0x%02X%02X%02X%02X%02X%02X",
+    if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN)
+    {
+        BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
+        if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM )
+            transport = BT_TRANSPORT_LE;
+    }
+    else
+        transport = bta_dm_search_cb.transport;
+#endif
+
+
+    APPL_TRACE_DEBUG("bta_dm_discover_device, BDA:0x%02X%02X%02X%02X%02X%02X",
                         remote_bd_addr[0],remote_bd_addr[1],
                         remote_bd_addr[2],remote_bd_addr[3],
                         remote_bd_addr[4],remote_bd_addr[5]);
 
     bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
 
-    APPL_TRACE_DEBUG2("bta_dm_discover_device name_discover_done = %d p_btm_inq_info 0x%x ",
+    APPL_TRACE_DEBUG("bta_dm_discover_device name_discover_done = %d p_btm_inq_info 0x%x ",
                         bta_dm_search_cb.name_discover_done,
                         bta_dm_search_cb.p_btm_inq_info
                         );
     if ( bta_dm_search_cb.p_btm_inq_info ) {
 
-        APPL_TRACE_DEBUG1("bta_dm_discover_device appl_knows_rem_name %d",
+        APPL_TRACE_DEBUG("bta_dm_discover_device appl_knows_rem_name %d",
                             bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name
                             );
     }
@@ -2407,7 +2423,7 @@
        && (( bta_dm_search_cb.p_btm_inq_info == NULL )
             ||(bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name))))
     {
-        if( bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr) == TRUE )
+            if(bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE)
         {
             return;
         }
@@ -2446,7 +2462,7 @@
             /* check whether connection already exists to the device
                if connection exists, we don't have to wait for ACL
                link to go down to start search on next device */
-            if(BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr))
+            if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR))
                 bta_dm_search_cb.wait_disc = FALSE;
             else
                 bta_dm_search_cb.wait_disc = TRUE;
@@ -2454,14 +2470,13 @@
 #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
             if ( bta_dm_search_cb.p_btm_inq_info )
             {
-                APPL_TRACE_DEBUG3("bta_dm_discover_device p_btm_inq_info 0x%x results.device_type 0x%x services_to_search 0x%x",
+                APPL_TRACE_DEBUG("bta_dm_discover_device p_btm_inq_info 0x%x results.device_type 0x%x services_to_search 0x%x",
                                     bta_dm_search_cb.p_btm_inq_info,
                                     bta_dm_search_cb.p_btm_inq_info->results.device_type,
                                     bta_dm_search_cb.services_to_search
                                     );
             }
-            if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr))
-            /*
+            if (transport == BT_TRANSPORT_LE)            /*
             if ( bta_dm_search_cb.p_btm_inq_info != NULL &&
                  bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE &&
                  (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK))*/
@@ -2559,7 +2574,7 @@
     result.inq_res.ble_addr_type    = p_inq->ble_addr_type;
     result.inq_res.inq_result_type  = p_inq->inq_result_type;
     result.inq_res.device_type      = p_inq->device_type;
-
+    result.inq_res.flag             = p_inq->flag;
 #endif
 
     /* application will parse EIR to find out remote device name */
@@ -2602,7 +2617,7 @@
 
     tBTA_DM_MSG * p_msg;
 
-    APPL_TRACE_DEBUG0("bta_dm_inq_cmpl_cb");
+    APPL_TRACE_DEBUG("bta_dm_inq_cmpl_cb");
     if ((p_msg = (tBTA_DM_MSG *) GKI_getbuf(sizeof(tBTA_DM_MSG))) != NULL)
     {
         p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
@@ -2629,7 +2644,7 @@
     tBTM_STATUS             btm_status;
     UNUSED(dc);
 
-    APPL_TRACE_DEBUG1("bta_dm_service_search_remname_cback name=<%s>", bd_name);
+    APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name);
 
     /* if this is what we are looking for */
     if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr))
@@ -2649,16 +2664,17 @@
     {
         /* get name of device */
         btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
-                                                (tBTM_CMPL_CB *) bta_dm_remname_cback);
+                                                (tBTM_CMPL_CB *) bta_dm_remname_cback,
+                                                BT_TRANSPORT_BR_EDR);
         if ( btm_status == BTM_BUSY )
         {
             /* wait for next chance(notification of remote name discovery done) */
-            APPL_TRACE_DEBUG0("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy");
+            APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy");
         }
         else if ( btm_status != BTM_CMD_STARTED )
         {
             /* if failed to start getting remote name then continue */
-            APPL_TRACE_WARNING1("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
+            APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
 
             rem_name.length = 0;
             rem_name.remote_bd_name[0] = 0;
@@ -2682,7 +2698,7 @@
 {
     tBTA_DM_REM_NAME * p_msg;
 
-    APPL_TRACE_DEBUG2("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
+    APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
                       p_remote_name->remote_bd_name);
 
     /* remote name discovery is done but it could be failed */
@@ -2691,9 +2707,12 @@
     bta_dm_search_cb.peer_name[BD_NAME_LEN]=0;
 
     BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
+
 #if BLE_INCLUDED == TRUE
-    if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr))
-        GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
+    if (bta_dm_search_cb.transport == BT_TRANSPORT_LE )
+    {
+       GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
+    }
 #endif
     if ((p_msg = (tBTA_DM_REM_NAME *) GKI_getbuf(sizeof(tBTA_DM_REM_NAME))) != NULL)
     {
@@ -2856,10 +2875,10 @@
         bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
         bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
         BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
-        if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
+        if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
             return BTM_CMD_STARTED;
 
-        APPL_TRACE_WARNING0(" bta_dm_pin_cback() -> Failed to start Remote Name Request  ");
+        APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request  ");
     }
 
     bdcpy(sec_event.pin_req.bd_addr, bd_addr);
@@ -2943,7 +2962,7 @@
     }
     else
     {
-        APPL_TRACE_WARNING0(" bta_dm_new_link_key_cback() Received AMP Key??  ");
+        APPL_TRACE_WARNING(" bta_dm_new_link_key_cback() Received AMP Key??  ");
     }
 
     return BTM_CMD_STARTED;
@@ -3004,7 +3023,7 @@
     tBTA_DM_SEC sec_event;
     tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
 
-    APPL_TRACE_EVENT1("bta_dm_sp_cback: %d", event);
+    APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
     if (!bta_dm_cb.p_sec_cback)
         return BTM_NOT_AUTHORIZED;
 
@@ -3021,7 +3040,7 @@
         status = BTM_SUCCESS;
 #endif
 
-        APPL_TRACE_EVENT2("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
+        APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
         break;
     case BTM_SP_IO_RSP_EVT:
 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
@@ -3044,22 +3063,56 @@
     /*case BTM_SP_KEY_REQ_EVT: */
     case BTM_SP_KEY_NOTIF_EVT:
 #endif
-        bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
-        /* If the device name is not known, save bdaddr and devclass and initiate a name request */
-        if (p_data->key_notif.bd_name[0] == 0)
+        if(BTM_SP_CFM_REQ_EVT == event)
         {
-            bta_dm_cb.pin_evt = pin_evt;
-            bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
-            BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
-            if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
-                return BTM_CMD_STARTED;
-
-            APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
+          /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
+             call remote name request using values from cfm_req */
+          if(p_data->cfm_req.bd_name[0] == 0)
+          {
+              bta_dm_cb.pin_evt = pin_evt;
+              bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
+              BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
+              if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
+                         BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
+                  return BTM_CMD_STARTED;
+              APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
+          }
+          else
+          {
+              /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
+                 copy these values into key_notif from cfm_req */
+              bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
+              BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
+              BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME),
+                   (char*)p_data->cfm_req.bd_name, (BD_NAME_LEN-1));
+              sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
+           }
         }
-        bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
-        BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
-            BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME), (char*)p_data->key_notif.bd_name, (BD_NAME_LEN-1));
-            sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
+
+        bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
+        if (BTM_SP_KEY_NOTIF_EVT == event)
+        {
+            /* If the device name is not known, save bdaddr and devclass
+               and initiate a name request with values from key_notif */
+            if(p_data->key_notif.bd_name[0] == 0)
+            {
+                bta_dm_cb.pin_evt = pin_evt;
+                bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
+                BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
+                if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
+                         BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
+                return BTM_CMD_STARTED;
+                APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
+            }
+            else
+            {
+                bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
+                BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
+                BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME),
+                    (char*)p_data->key_notif.bd_name, (BD_NAME_LEN-1));
+                sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
+            }
+        }
 
         bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
 
@@ -3075,17 +3128,18 @@
         /* If the device name is not known, save bdaddr and devclass and initiate a name request */
         if (p_data->rmt_oob.bd_name[0] == 0)
         {
-            bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
-            bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
-            BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
-            if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
-                return BTM_CMD_STARTED;
+             bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
+             bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
+             BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
+             if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
+                      BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
+             return BTM_CMD_STARTED;
+             APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
+         }
 
-            APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
-        }
-        bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
-        BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
-            BCM_STRNCPY_S((char*)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char*)p_data->rmt_oob.bd_name, (BD_NAME_LEN-1));
+         bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
+         BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
+         BCM_STRNCPY_S((char*)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char*)p_data->rmt_oob.bd_name, (BD_NAME_LEN-1));
             sec_event.rmt_oob.bd_name[BD_NAME_LEN-1] = 0;
 
         bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
@@ -3110,7 +3164,7 @@
         status = BTM_NOT_AUTHORIZED;
         break;
     }
-    APPL_TRACE_EVENT1("dm status: %d", status);
+    APPL_TRACE_EVENT("dm status: %d", status);
     return status;
 }
 
@@ -3134,6 +3188,7 @@
 
     if(bta_dm_cb.p_sec_cback)
         bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
+
 }
 
 /*******************************************************************************
@@ -3227,9 +3282,17 @@
         case BTM_BL_CONN_EVT:
             p_msg->is_new = TRUE;
             bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
+#if BLE_INCLUDED == TRUE
+            p_msg->transport = p_data->conn.transport;
+            p_msg->handle = p_data->conn.handle;
+#endif
             break;
         case BTM_BL_DISCN_EVT:
             bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
+#if BLE_INCLUDED == TRUE
+            p_msg->transport = p_data->discn.transport;
+            p_msg->handle = p_data->discn.handle;
+#endif
             break;
         case BTM_BL_UPDATE_EVT:
             p_msg->busy_level = p_data->update.busy_level;
@@ -3240,9 +3303,9 @@
             p_msg->hci_status = p_data->role_chg.hci_status;
             bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
             break;
-            case BTM_BL_COLLISION_EVT:
-                bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
-                break;;
+        case BTM_BL_COLLISION_EVT:
+            bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
+            break;
         }
 
         p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
@@ -3264,7 +3327,8 @@
 **
 *******************************************************************************/
 static void bta_dm_acl_change_cback (BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bdn,
-                                     UINT8 *features, BOOLEAN is_new)
+                                     UINT8 *features, BOOLEAN is_new,UINT16 handle,
+                                     tBT_TRANSPORT transport)
 {
 
     tBTA_DM_ACL_CHANGE * p_msg;
@@ -3273,7 +3337,10 @@
     {
         bdcpy (p_msg->bd_addr, p_bda);
         p_msg->is_new = is_new;
-
+#if BLE_INCLUDED == TRUE
+        p_msg->handle   = handle;
+        p_msg->transport = transport;
+#endif
         /* This is collision case */
         if (features != NULL)
         {
@@ -3300,7 +3367,7 @@
 static void bta_dm_rs_cback (tBTM_ROLE_SWITCH_CMPL *p1)
 {
     UNUSED(p1);
-    APPL_TRACE_WARNING1("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
+    APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
     if(bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT)
     {
         bta_dm_cb.search_msg.rs_res = BTA_DM_RS_OK; /* do not care about the result for now */
@@ -3336,13 +3403,13 @@
     }
 #endif
 
-    APPL_TRACE_WARNING1("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
+    APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
     if(bta_dm_cb.cur_av_count)
     {
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
             p_dev = &bta_dm_cb.device_list.peer_device[i];
-            APPL_TRACE_WARNING4("[%d]: state:%d, info:x%x, avoid_rs %d",
+            APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d",
                                 i, p_dev->conn_state, p_dev->info, avoid_roleswitch);
             if((p_dev->conn_state == BTA_DM_CONNECTED) && (p_dev->info & BTA_DM_DI_AV_ACTIVE) &&
                (avoid_roleswitch == FALSE))
@@ -3386,6 +3453,7 @@
 
 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
     tBTA_DM_PEER_DEVICE *p_dev;
+    memset(&conn, 0, sizeof(tBTA_DM_SEC));
 
     switch(p_data->acl_change.event)
     {
@@ -3402,7 +3470,7 @@
         p_dev = bta_dm_find_peer_device(p_bda);
         if(p_dev)
         {
-            APPL_TRACE_DEBUG3("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d",
+            APPL_TRACE_DEBUG("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d",
                 p_dev->info, p_data->acl_change.new_role, bta_dm_cb.device_list.count);
             if(p_dev->info & BTA_DM_DI_AV_ACTIVE)
             {
@@ -3437,7 +3505,7 @@
             bdcpy(conn.role_chg.bd_addr, p_bda);
             conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
             if( bta_dm_cb.p_sec_cback )
-                bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, &conn);
+                bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
         }
         return;
     }
@@ -3454,7 +3522,11 @@
     {
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
-            if(!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda))
+            if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
+#if BLE_INCLUDED == TRUE
+                 && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
+#endif
+                 )
                 break;
 
         }
@@ -3464,19 +3536,29 @@
             bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
             bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
             bta_dm_cb.device_list.count++;
+#if BLE_INCLUDED == TRUE
+            bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
+            if (p_data->acl_change.transport == BT_TRANSPORT_LE)
+                bta_dm_cb.device_list.le_count++;
+#endif
         }
 
         bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
         bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
         bdcpy(conn.link_up.bd_addr, p_bda);
         bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
-        if( ((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
-            ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) )
+#if BLE_INCLUDED == TRUE
+        conn.link_up.link_type = p_data->acl_change.transport;
+        bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
+#endif
+
+        if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
+            ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)))
         {
             /* both local and remote devices support SSR */
             bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
         }
-        APPL_TRACE_WARNING1("info:x%x", bta_dm_cb.device_list.peer_device[i].info);
+        APPL_TRACE_WARNING("info:x%x", bta_dm_cb.device_list.peer_device[i].info);
         if( bta_dm_cb.p_sec_cback )
             bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, &conn);
 
@@ -3485,17 +3567,23 @@
     {
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
-            if(bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda))
+            if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
+#if BLE_INCLUDED == TRUE
+                 ||bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
+#endif
+               )
                 continue;
 
             if( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING )
             {
-                BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
+                if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr))
+                {
 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
-                /* remove all cached GATT information */
-                BTA_GATTC_Refresh(p_bda);
+                    /* remove all cached GATT information */
+                    BTA_GATTC_Refresh(p_bda);
 #endif
-                issue_unpair_cb = TRUE;
+                    issue_unpair_cb = TRUE;
+                }
             }
 
             conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
@@ -3508,6 +3596,12 @@
         }
         if(bta_dm_cb.device_list.count)
             bta_dm_cb.device_list.count--;
+#if BLE_INCLUDED == TRUE
+        if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
+             (bta_dm_cb.device_list.le_count))
+            bta_dm_cb.device_list.le_count--;
+        conn.link_down.link_type = p_data->acl_change.transport;
+#endif
 
         if(bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda))
         {
@@ -3515,7 +3609,7 @@
 
             if(bta_dm_search_cb.sdp_results)
             {
-                APPL_TRACE_EVENT0(" timer stopped  ");
+                APPL_TRACE_EVENT(" timer stopped  ");
                 bta_sys_stop_timer(&bta_dm_search_cb.search_timer);
                 bta_dm_discover_next_device();
             }
@@ -3706,7 +3800,7 @@
             if(BTA_ID_AV == id)
                 bta_dm_cb.cur_av_count = app_id;
         }
-        APPL_TRACE_WARNING2("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status);
+        APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status);
     }
     else if ((status == BTA_SYS_CONN_BUSY) || (status == BTA_SYS_CONN_IDLE))
     {
@@ -3746,7 +3840,7 @@
                  ((bta_role_switch_blacklist[i].lmp_sub_version & lmp_sub_version) ==
                      bta_role_switch_blacklist[i].lmp_sub_version))
                 {
-                    APPL_TRACE_EVENT0("Black list F/W version matches.. Delay Role Switch...");
+                    APPL_TRACE_EVENT("Black list F/W version matches.. Delay Role Switch...");
                     return TRUE;
                 }
 
@@ -3767,7 +3861,7 @@
 static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle)
 {
     UNUSED(p_tle);
-    APPL_TRACE_EVENT0("bta_dm_delay_role_switch_cback: initiating Delayed RS");
+    APPL_TRACE_EVENT("bta_dm_delay_role_switch_cback: initiating Delayed RS");
     bta_dm_adjust_roles (FALSE);
 }
 
@@ -3785,9 +3879,10 @@
 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
 {
     UINT16 index = 0;
-    if (BTM_IsAclConnectionUp(remote_bd_addr))
+    if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
+         BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR))
     {
-         APPL_TRACE_DEBUG1("%s ACL is not down. Schedule for  Dev Removal when ACL closes",
+         APPL_TRACE_DEBUG("%s ACL is not down. Schedule for  Dev Removal when ACL closes",
                             __FUNCTION__);
         for (index = 0; index < bta_dm_cb.device_list.count; index ++)
         {
@@ -3800,7 +3895,7 @@
         }
         else
         {
-            APPL_TRACE_ERROR1(" %s Device does not exist in DB", __FUNCTION__);
+            APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
         }
     }
     else
@@ -3831,14 +3926,18 @@
 
     UINT8 i;
     BOOLEAN set_master_role = FALSE;
-
-    if(bta_dm_cb.device_list.count)
+#if BLE_INCLUDED == TRUE
+    UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
+#else
+    UINT8 br_count = bta_dm_cb.device_list.count;
+#endif
+    if (br_count)
     {
 
         /* the configuration is no scatternet
          * or AV connection exists and there are more than one ACL link */
-        if( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
-            (bta_dm_cb.cur_av_count && bta_dm_cb.device_list.count > 1) )
+        if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
+             (bta_dm_cb.cur_av_count && br_count > 1) )
         {
 
             L2CA_SetDesireRole (HCI_ROLE_MASTER);
@@ -3848,7 +3947,11 @@
 
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
-            if(bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+            if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
+#if BLE_INCLUDED == TRUE
+                && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
+#endif
+                )
             {
                 if(!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
                     && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET))
@@ -3858,7 +3961,7 @@
                 }
 
                 if((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
-                    || (bta_dm_cb.device_list.count > 1))
+                    || (br_count > 1))
                 {
 
                 /* Initiating immediate role switch with certain remote devices
@@ -3988,7 +4091,7 @@
         {
             if (empty_slot == BTA_EIR_SERVER_NUM_CUSTOM_UUID)
             {
-                APPL_TRACE_ERROR0("No space to add UUID for EIR");
+                APPL_TRACE_ERROR("No space to add UUID for EIR");
                 return;
             }
             else
@@ -3998,7 +4101,7 @@
         }
         else
         {
-            APPL_TRACE_ERROR0("UUID is already added for EIR");
+            APPL_TRACE_ERROR("UUID is already added for EIR");
             return;
         }
     }
@@ -4006,7 +4109,7 @@
     {
         if (match_slot == BTA_EIR_SERVER_NUM_CUSTOM_UUID)
         {
-            APPL_TRACE_ERROR0("UUID is not found for EIR");
+            APPL_TRACE_ERROR("UUID is not found for EIR");
             return;
         }
         else
@@ -4087,7 +4190,7 @@
     {
         if( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS )
         {
-            APPL_TRACE_ERROR0("Fail to read local device name for EIR");
+            APPL_TRACE_ERROR("Fail to read local device name for EIR");
         }
     }
 #endif
@@ -4095,14 +4198,14 @@
     /* Allocate a buffer to hold HCI command */
     if ((p_buf = (BT_HDR *)GKI_getpoolbuf(BTM_CMD_POOL_ID)) == NULL)
     {
-        APPL_TRACE_ERROR0("bta_dm_set_eir couldn't allocate buffer");
+        APPL_TRACE_ERROR("bta_dm_set_eir couldn't allocate buffer");
         return;
     }
     p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET;
 
     memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN );
 
-    APPL_TRACE_DEBUG0("BTA is generating EIR");
+    APPL_TRACE_DEBUG("BTA is generating EIR");
 
     if( local_name )
         local_name_len = strlen( local_name );
@@ -4127,7 +4230,7 @@
         /* if UUID doesn't fit remaing space, shorten local name */
         if ( local_name_len > (free_eir_length - 4 - num_uuid*LEN_UUID_16))
         {
-            APPL_TRACE_WARNING0("BTA EIR: local name is shortened");
+            APPL_TRACE_WARNING("BTA EIR: local name is shortened");
             local_name_len = p_bta_dm_eir_cfg->bta_dm_eir_min_name_len;
             data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
         }
@@ -4161,7 +4264,7 @@
             }
             else /* not enough room for all UUIDs */
             {
-                APPL_TRACE_WARNING0("BTA EIR: UUID 16-bit list is truncated");
+                APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
                 num_uuid = free_eir_length / LEN_UUID_16;
                 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
             }
@@ -4185,7 +4288,7 @@
 
         if( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE )
         {
-            APPL_TRACE_WARNING0("BTA EIR: UUID 16-bit list is truncated");
+            APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
         }
 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
         else
@@ -4202,7 +4305,7 @@
                     else
                     {
                         data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
-                        APPL_TRACE_WARNING0("BTA EIR: UUID 16-bit list is truncated");
+                        APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
                         break;
                     }
                 }
@@ -4239,7 +4342,7 @@
                 else
                 {
                     data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
-                    APPL_TRACE_WARNING0("BTA EIR: UUID 32-bit list is truncated");
+                    APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
                     break;
                 }
             }
@@ -4272,7 +4375,7 @@
                 else
                 {
                     data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
-                    APPL_TRACE_WARNING0("BTA EIR: UUID 128-bit list is truncated");
+                    APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
                     break;
                 }
             }
@@ -4352,12 +4455,12 @@
     tBTA_SERVICE_MASK       service_index = 0;
     tBTM_EIR_SEARCH_RESULT  result;
 
-    APPL_TRACE_DEBUG6("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
+    APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
                         p_result->remote_bd_addr[0],p_result->remote_bd_addr[1],
                         p_result->remote_bd_addr[2],p_result->remote_bd_addr[3],
                         p_result->remote_bd_addr[4],p_result->remote_bd_addr[5]);
 
-    APPL_TRACE_DEBUG1("    with services_to_search=0x%08X", *p_services_to_search);
+    APPL_TRACE_DEBUG("    with services_to_search=0x%08X", *p_services_to_search);
 
 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
     /* always do GATT based service discovery by SDP instead of from EIR    */
@@ -4406,7 +4509,7 @@
         service_index++;
     }
 
-    APPL_TRACE_ERROR2("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
+    APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
                         *p_services_to_search, *p_services_found);
 }
 #endif
@@ -4429,20 +4532,20 @@
 
     if( adding )
     {
-        APPL_TRACE_EVENT1("Adding UUID=0x%04X into EIR", uuid16);
+        APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
 
         BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 );
     }
     else
     {
-        APPL_TRACE_EVENT1("Removing UUID=0x%04X from EIR", uuid16);
+        APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
 
         BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 );
     }
 
     bta_dm_set_eir (NULL);
 
-    APPL_TRACE_EVENT2("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
+    APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
                        bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] );
 }
 #endif
@@ -4508,13 +4611,26 @@
 ** Returns         None
 **
 *******************************************************************************/
-void bta_dm_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
 {
     tBTA_STATUS   bta_status = BTA_SUCCESS;
-    tBTA_DM_ENCRYPT_CBACK *p_callback = bta_dm_cb.p_encrypt_cback;
+    tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
+    UINT8   i ;
     UNUSED(p_ref_data);
 
-    bta_dm_cb.p_encrypt_cback = NULL;
+    for (i=0; i<bta_dm_cb.device_list.count; i++)
+    {
+        if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
+            bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+            break;
+    }
+
+    if (i < bta_dm_cb.device_list.count)
+    {
+        p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
+        bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
+    }
+
     switch (result)
     {
         case BTM_SUCCESS:
@@ -4533,11 +4649,11 @@
             break;
     }
 
-    APPL_TRACE_DEBUG2("bta_dm_encrypt_cback status =%d p_callback=0x%x", bta_status, p_callback);
+    APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x", bta_status, p_callback);
 
     if (p_callback)
     {
-        (*p_callback)(bd_addr, bta_status);
+        (*p_callback)(bd_addr, transport, bta_status);
     }
 }
 /*******************************************************************************
@@ -4551,24 +4667,44 @@
 *******************************************************************************/
 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
 {
+    UINT8 i ;
 
-    APPL_TRACE_DEBUG0("bta_dm_set_encryption"); //todo
+    APPL_TRACE_DEBUG("bta_dm_set_encryption"); //todo
     if (!p_data->set_encryption.p_callback)
     {
-        APPL_TRACE_ERROR0("bta_dm_set_encryption callback is not provided");
+        APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided");
         return;
     }
 
-    if (bta_dm_cb.p_encrypt_cback)
+    for (i=0; i<bta_dm_cb.device_list.count; i++)
     {
-        (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr, BTA_BUSY);
-        return;
+        if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
+            bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+            break;
     }
+    if (i < bta_dm_cb.device_list.count)
+    {
+        if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback)
+        {
+            APPL_TRACE_ERROR("earlier enc was not done for same device");
+            (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
+                p_data->set_encryption.transport, BTA_BUSY);
+            return;
+        }
 
-
-    bta_dm_cb.p_encrypt_cback = p_data->set_encryption.p_callback;
-    bta_dm_cb.sec_act         = p_data->set_encryption.sec_act;
-    BTM_SetEncryption(p_data->set_encryption.bd_addr, bta_dm_encrypt_cback, &bta_dm_cb.sec_act);
+        if (BTM_SetEncryption(p_data->set_encryption.bd_addr,
+                              p_data->set_encryption.transport,
+                              bta_dm_encrypt_cback,
+                              &p_data->set_encryption.sec_act)
+                              == BTM_CMD_STARTED)
+        {
+            bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
+        }
+    }
+    else
+    {
+        APPL_TRACE_ERROR(" %s Device not found/not connected", __FUNCTION__);
+    }
 }
 
 /*******************************************************************************
@@ -4620,7 +4756,7 @@
     tBTA_DM_SEARCH     result;
     tBTM_INQ_INFO      *p_inq_info;
     UINT16             service_class;
-    APPL_TRACE_DEBUG0("bta_dm_observe_results_cb")
+    APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
 
     bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
     result.inq_res.rssi = p_inq->rssi;
@@ -4663,7 +4799,7 @@
 {
     tBTA_DM_SEARCH  data;
 
-    APPL_TRACE_DEBUG0("bta_dm_observe_cmpl_cb");
+    APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
 
     data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
     if (bta_dm_search_cb.p_scan_cback)
@@ -4690,7 +4826,7 @@
     char* p_name = NULL;
     UINT8 i;
 
-    APPL_TRACE_DEBUG0("bta_dm_ble_smp_cback");
+    APPL_TRACE_DEBUG("bta_dm_ble_smp_cback");
 
     if (!bta_dm_cb.p_sec_cback)
         return BTM_NOT_AUTHORIZED;
@@ -4712,7 +4848,7 @@
 #if BTM_OOB_INCLUDED == FALSE
             status = BTM_SUCCESS;
 #endif
-            APPL_TRACE_EVENT2("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
+            APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
 
             break;
 
@@ -4849,7 +4985,7 @@
             break;
 
         default:
-            APPL_TRACE_DEBUG1("Unknown key type %d", key_type);
+            APPL_TRACE_DEBUG("Unknown key type %d", key_type);
             break;
     }
     return;
@@ -4874,7 +5010,7 @@
                            (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey,
                            p_data->add_ble_key.key_type))
     {
-        APPL_TRACE_ERROR2 ("BTA_DM: Error adding BLE Key for device %08x%04x",
+        APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x",
                            (p_data->add_ble_key.bd_addr[0]<<24)+(p_data->add_ble_key.bd_addr[1]<<16)+\
                            (p_data->add_ble_key.bd_addr[2]<<8)+p_data->add_ble_key.bd_addr[3],
                            (p_data->add_ble_key.bd_addr[4]<<8)+p_data->add_ble_key.bd_addr[5]);
@@ -4898,7 +5034,7 @@
                               p_data->add_ble_device.dev_type  ,
                               p_data->add_ble_device.addr_type))
     {
-        APPL_TRACE_ERROR2 ("BTA_DM: Error adding BLE Device for device %08x%04x",
+        APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
                            (p_data->add_ble_device.bd_addr[0]<<24)+(p_data->add_ble_device.bd_addr[1]<<16)+ \
                            (p_data->add_ble_device.bd_addr[2]<<8)+p_data->add_ble_device.bd_addr[3],
                            (p_data->add_ble_device.bd_addr[4]<<8)+p_data->add_ble_device.bd_addr[5]);
@@ -4920,7 +5056,6 @@
 {
     if (p_data->pin_reply.accept)
     {
-
         BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey);
     }
     else
@@ -4991,8 +5126,42 @@
     BTM_BleSetConnScanParams(p_data->ble_set_scan_params.scan_int,
                              p_data->ble_set_scan_params.scan_window);
 }
+/*******************************************************************************
+**
+** Function         bta_dm_ble_update_conn_params
+**
+** Description      This function update LE connection parameters.
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
+{
+    if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
+                                 p_data->ble_update_conn_params.min_int,
+                                 p_data->ble_update_conn_params.max_int,
+                                 p_data->ble_update_conn_params.latency,
+                                 p_data->ble_update_conn_params.timeout))
+    {
+        APPL_TRACE_ERROR("Update connection parameters failed!");
+    }
+}
 
-
+#if BLE_PRIVACY_SPT == TRUE
+/*******************************************************************************
+**
+** Function         bta_dm_ble_config_local_privacy
+**
+** Description      This function set the local device LE privacy settings.
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
+{
+    BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable);
+}
+#endif
 /*******************************************************************************
 **
 ** Function         bta_dm_ble_observe
@@ -5004,17 +5173,16 @@
 *******************************************************************************/
 void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
 {
-
     tBTM_STATUS status;
     if (p_data->ble_observe.start)
     {
         /*Save the  callback to be called when a scan results are available */
         bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
         if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
-                                bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb))!= BTM_SUCCESS)
+                            bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb))!= BTM_CMD_STARTED)
         {
             tBTA_DM_SEARCH  data;
-            APPL_TRACE_WARNING2(" %s BTM_BleObserve  failed. status %d",__FUNCTION__,status);
+            APPL_TRACE_WARNING(" %s BTM_BleObserve  failed. status %d",__FUNCTION__,status);
             data.inq_cmpl.num_resps = 0;
             if (bta_dm_search_cb.p_scan_cback)
             {
@@ -5056,8 +5224,16 @@
 *******************************************************************************/
 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
 {
-    BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
-                        (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg);
+    tBTA_STATUS status = BTA_FAILURE;
+
+    if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
+                        (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS)
+    {
+        status = BTA_SUCCESS;
+    }
+
+    if (p_data->ble_set_adv_data.p_adv_data_cback)
+        (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
 }
 
 /*******************************************************************************
@@ -5071,8 +5247,16 @@
 *******************************************************************************/
 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
 {
-    BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
-                        (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg);
+    tBTA_STATUS status = BTA_FAILURE;
+
+    if(BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
+                        (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS)
+    {
+        status = BTA_SUCCESS;
+    }
+
+    if (p_data->ble_set_adv_data.p_adv_data_cback)
+        (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
 }
 
 /*******************************************************************************
@@ -5089,6 +5273,509 @@
     BTM_BleBroadcast(p_data->ble_observe.start);
 }
 
+/*******************************************************************************
+**
+** Function         bta_dm_ble_multi_adv_enb
+**
+** Description      This function enables a single advertising instance
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+    void *p_ref = NULL;
+
+    bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback;
+    if(BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref)
+    {
+        btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS*)
+                                            p_data->ble_multi_adv_enb.p_params,
+                                            p_data->ble_multi_adv_enb.p_cback,
+                                            p_data->ble_multi_adv_enb.p_ref);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+    {
+        bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF,
+                                    p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE);
+    }
+}
+/*******************************************************************************
+**
+** Function         bta_dm_ble_multi_adv_param_upd
+**
+** Description      This function updates multiple advertising instance parameters
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+    void *p_ref = NULL;
+
+    if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0
+        && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount())
+    {
+        btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
+                         (tBTM_BLE_ADV_PARAMS*)p_data->ble_multi_adv_param.p_params);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+    {
+       p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id);
+       bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT,
+                                   p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE);
+    }
+}
+/*******************************************************************************
+**
+** Function         bta_dm_ble_multi_adv_data
+**
+** Description      This function write multiple advertising instance adv data
+**                  or scan response data
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+    void *p_ref = NULL;
+
+    if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0
+        && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount())
+    {
+        btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
+                        p_data->ble_multi_adv_data.is_scan_rsp,
+                        p_data->ble_multi_adv_data.data_mask,
+                        (tBTM_BLE_ADV_DATA*)p_data->ble_multi_adv_data.p_data);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+    {
+       p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id);
+       bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT,
+                                   p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE);
+    }
+
+}
+/*******************************************************************************
+**
+** Function         btm_dm_ble_multi_adv_disable
+**
+** Description      This function disable a single adv instance
+**
+** Parameters:
+**
+*******************************************************************************/
+void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+    void *p_ref = NULL;
+
+    if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0
+        && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount())
+    {
+        btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+    {
+       p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id);
+       bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT,
+                                   p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_ble_setup_storage
+**
+** Description      This function configures up the storage parameters for ADV batch scanning
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+    tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+
+    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
+
+    if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
+    {
+        btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max,
+                                             p_data->ble_set_storage.batch_scan_trunc_max,
+                                             p_data->ble_set_storage.batch_scan_notify_threshold,
+                                             p_data->ble_set_storage.p_setup_cback,
+                                             p_data->ble_set_storage.p_thres_cback,
+                                             p_data->ble_set_storage.p_read_rep_cback,
+                                             p_data->ble_set_storage.ref_value);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+       bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
+                             btm_status);
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_ble_enable_batch_scan
+**
+** Description      This function sets up the parameters and enables batch scan
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+    tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+
+    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
+
+    if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
+    {
+        btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode,
+                                            p_data->ble_enable_scan.scan_int,
+                                            p_data->ble_enable_scan.scan_window,
+                                            p_data->ble_enable_scan.discard_rule,
+                                            p_data->ble_enable_scan.addr_type,
+                                            p_data->ble_enable_scan.ref_value);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+       bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
+                             btm_status);
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_ble_disable_batch_scan
+**
+** Description      This function disables the batch scan
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
+{
+    UNUSED(p_data);
+    tBTM_STATUS btm_status = 0;
+    tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+
+    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
+
+    if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
+    {
+        btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+       bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
+                             btm_status);
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_ble_read_scan_reports
+**
+** Description      This function reads the batch scan reports
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+    tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+
+    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
+
+    if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
+    {
+        btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type,
+                                            p_data->ble_read_reports.ref_value);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+       bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
+                             btm_status);
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_ble_track_advertiser
+**
+** Description      This function tracks the specific advertiser
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+    BD_ADDR bda;
+    memset(&bda, 0 , sizeof(BD_ADDR));
+    tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+
+    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
+
+    if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
+    {
+        btm_status = BTM_BleTrackAdvertiser(p_data->ble_track_advert.p_track_adv_cback,
+                                            p_data->ble_track_advert.ref_value);
+    }
+
+    if(BTM_CMD_STARTED != btm_status)
+       p_data->ble_track_advert.p_track_adv_cback(0, 0, bda, 0, p_data->ble_track_advert.ref_value);
+}
+
+/*******************************************************************************
+**
+** Function         bta_ble_scan_setup_cb
+**
+** Description      Handle the setup callback from BTM layer and forward it to app layer
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value,
+                                  tBTM_STATUS status)
+{
+    tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0;
+
+    APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt,
+                      ref_value, status);
+
+    switch(evt)
+    {
+        case BTM_BLE_BATCH_SCAN_ENABLE_EVT:
+           bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT;
+           break;
+        case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT:
+           bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT;
+           break;
+        case BTM_BLE_BATCH_SCAN_DISABLE_EVT:
+            bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT;
+            break;
+        case BTM_BLE_BATCH_SCAN_PARAM_EVT:
+            bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT;
+            break;
+        default:
+            break;
+    }
+
+    if(NULL != bta_dm_cb.p_setup_cback)
+       bta_dm_cb.p_setup_cback(bta_evt, ref_value, status);
+}
+
+
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+/*******************************************************************************
+**
+** Function         bta_ble_scan_pf_cmpl
+**
+** Description      ADV payload filtering operation complete callback
+**
+**
+** Returns         TRUE if handled, otherwise FALSE.
+**
+*******************************************************************************/
+static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op,
+                                 tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status,
+                                 tBTM_BLE_REF_VALUE ref_value)
+{
+    tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
+
+    APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status);
+
+    if(bta_dm_cb.p_scan_filt_cfg_cback)
+       bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value);
+}
+
+/*******************************************************************************
+**
+** Function         bta_ble_status_cmpl
+**
+** Description      ADV payload filtering enable / disable complete callback
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void bta_ble_status_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_REF_VALUE ref_value,
+                                    tBTM_STATUS status)
+{
+    tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
+
+    APPL_TRACE_DEBUG("bta_ble_status_cmpl: %d, %d", action, status);
+
+    if(bta_dm_cb.p_scan_filt_status_cback)
+       bta_dm_cb.p_scan_filt_status_cback(action, ref_value, st);
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_cfg_filter_cond
+**
+** Description      This function configure adv payload filtering condition
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
+    tBTA_STATUS status = BTA_FAILURE;
+
+    tBTM_BLE_VSC_CB cmn_vsc_cb;
+
+    APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond");
+    BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
+    if(0 != cmn_vsc_cb.filter_support)
+    {
+        if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action,
+                            p_data->ble_cfg_filter_cond.cond_type,
+                            (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index,
+                            (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param,
+                            bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value))
+                == BTM_CMD_STARTED)
+        {
+            bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback;
+            return;
+        }
+    }
+
+    if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
+        p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
+                                            p_data->ble_cfg_filter_cond.cond_type, 0, status,
+                                            p_data->ble_cfg_filter_cond.ref_value);
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_enable_scan_filter
+**
+** Description      This function enable/disable adv payload filtering condition
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
+    tBTA_STATUS status = BTA_FAILURE;
+
+    tBTM_BLE_VSC_CB cmn_vsc_cb;
+    APPL_TRACE_DEBUG("bta_dm_enable_scan_filter");
+    BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
+
+    if(0 != cmn_vsc_cb.filter_support)
+    {
+        if((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action,
+                   p_data->ble_enable_scan_filt.p_filt_status_cback,
+                   (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED)
+        bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback;
+        return;
+    }
+
+    if (p_data->ble_enable_scan_filt.p_filt_status_cback)
+        p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
+                                            p_data->ble_enable_scan_filt.ref_value, status);
+
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_scan_filter_param_setup
+**
+** Description      This function sets up scan filter params
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
+    tBTA_STATUS status = BTA_FAILURE;
+
+    tBTM_BLE_VSC_CB cmn_vsc_cb;
+
+    APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup");
+    BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
+    if(0 != cmn_vsc_cb.filter_support)
+    {
+        if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action,
+                   p_data->ble_scan_filt_param_setup.filt_index,
+                  (tBTM_BLE_PF_FILT_PARAMS *)p_data->ble_scan_filt_param_setup.p_filt_params,
+                   p_data->ble_scan_filt_param_setup.p_target,
+                   p_data->ble_scan_filt_param_setup.p_filt_param_cback,
+                   p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED)
+        {
+            bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback;
+            return;
+        }
+    }
+
+    if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
+        p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
+                                        p_data->ble_scan_filt_param_setup.ref_value, status);
+
+    return;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         bta_ble_enable_scan_cmpl
+**
+** Description      ADV payload filtering enable / disable complete callback
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
+                                        tBTM_BLE_RX_TIME_MS rx_time,
+                                        tBTM_BLE_IDLE_TIME_MS idle_time,
+                                        tBTM_BLE_ENERGY_USED  energy_used,
+                                        tBTM_STATUS status)
+{
+    tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
+    tBTA_DM_CONTRL_STATE ctrl_state = 0;
+
+    if (BTA_SUCCESS == st)
+       ctrl_state = bta_dm_pm_obtain_controller_state();
+
+    if (bta_dm_cb.p_energy_info_cback)
+        bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_ble_get_energy_info
+**
+** Description      This function obtains the energy info
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS btm_status = 0;
+
+    bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
+    btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
+    if (BTM_CMD_STARTED != btm_status)
+        bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
+}
+
 #if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE))
 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
 #define BTA_DM_GATT_CLOSE_DELAY_TOUT    1000
@@ -5157,7 +5844,7 @@
 
     if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size )
     {
-        APPL_TRACE_DEBUG3("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x", service_id.uuid.uu.uuid16,bta_dm_search_cb.p_ble_rawdata,bta_dm_search_cb.ble_raw_used);
+        APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x", service_id.uuid.uu.uuid16,bta_dm_search_cb.p_ble_rawdata,bta_dm_search_cb.ble_raw_used);
 
         if(bta_dm_search_cb.p_ble_rawdata)
         {
@@ -5168,16 +5855,16 @@
         }
         else
         {
-            APPL_TRACE_ERROR0("p_ble_rawdata is NULL");
+            APPL_TRACE_ERROR("p_ble_rawdata is NULL");
         }
 
     }
     else
     {
-        APPL_TRACE_ERROR3("%s out of room to accomodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__,bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used );
+        APPL_TRACE_ERROR("%s out of room to accomodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__,bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used );
     }
 
-    APPL_TRACE_ERROR1("bta_dm_gatt_disc_result serivce_id len=%d ", service_id.uuid.len);
+    APPL_TRACE_ERROR("bta_dm_gatt_disc_result serivce_id len=%d ", service_id.uuid.len);
     if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
     {
 
@@ -5204,7 +5891,7 @@
 {
     tBTA_DM_MSG *p_msg;
 
-    APPL_TRACE_DEBUG1("bta_dm_gatt_disc_complete conn_id = %d",conn_id);
+    APPL_TRACE_DEBUG("bta_dm_gatt_disc_complete conn_id = %d",conn_id);
 
     if (bta_dm_search_cb.uuid_to_search > 0) bta_dm_search_cb.uuid_to_search --;
 
@@ -5310,7 +5997,7 @@
         btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
     }
     else
-        BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE);
+        BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
 }
 
 /*******************************************************************************
@@ -5349,14 +6036,14 @@
     p1 = bta_dm_search_cb.peer_bdaddr;
     p2 = p_data->remote_bda;
 
-    APPL_TRACE_DEBUG5("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
+    APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
                       bta_dm_search_cb.state,
                       ((p1[0])<<24)+((p1[1])<<16)+((p1[2])<<8)+(p1[3]),
                       ((p1[4])<<8)+ p1[5],
                       ((p2[0])<<24)+((p2[1])<<16)+((p2[2])<<8)+(p2[3]),
                       ((p2[4])<<8)+ p2[5]);
 
-    APPL_TRACE_DEBUG3("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
+    APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
                       p_data->conn_id,
                       p_data->client_if,
                       p_data->status);
@@ -5384,12 +6071,12 @@
 *******************************************************************************/
 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
 {
-    APPL_TRACE_DEBUG1("bta_dm_gattc_callback event = %d", event);
+    APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
 
     switch (event)
     {
         case BTA_GATTC_REG_EVT:
-            APPL_TRACE_DEBUG1("BTA_GATTC_REG_EVT client_if = %d",  p_data->reg_oper.client_if);
+            APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d",  p_data->reg_oper.client_if);
             if (p_data->reg_oper.status == BTA_GATT_OK)
                 bta_dm_search_cb.client_if = p_data->reg_oper.client_if;
             else
@@ -5410,7 +6097,7 @@
             break;
 
         case BTA_GATTC_CLOSE_EVT:
-            APPL_TRACE_DEBUG1("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
+            APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
             /* in case of disconnect before search is completed */
             if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
                  !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN))
@@ -5425,4 +6112,30 @@
 }
 
 #endif /* BTA_GATT_INCLUDED */
+
+/*******************************************************************************
+**
+** Function         bta_dm_ctrl_features_rd_cmpl_cback
+**
+** Description      callback to handle controller feature read complete
+**
+** Parameters:
+**
+*******************************************************************************/
+static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
+{
+    APPL_TRACE_DEBUG("%s  status = %d ", __FUNCTION__, result);
+    if (result == BTM_SUCCESS)
+    {
+        if(bta_dm_cb.p_sec_cback)
+            bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
+    }
+    else
+    {
+        APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d",__FUNCTION__, result);
+    }
+
+}
+
+
 #endif  /* BLE_INCLUDED */
diff --git a/bta/dm/bta_dm_api.c b/bta/dm/bta_dm_api.c
index 7db7f7b..9000207 100644
--- a/bta/dm/bta_dm_api.c
+++ b/bta/dm/bta_dm_api.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- *  Copyright (C) 2003-2012 Broadcom Corporation
+ *  Copyright (C) 2003-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@
 #include "btm_int.h"
 #include <string.h>
 #include "utl.h"
+#include "vendor_ble.h"
 
 /*****************************************************************************
 **  Constants
@@ -71,15 +72,12 @@
 
     memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
 
-    GKI_sched_lock();
     bta_sys_register (BTA_ID_DM, &bta_dm_reg );
     bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg );
 
     /* if UUID list is not provided as static data */
     bta_sys_eir_register(bta_dm_eir_update_uuid);
 
-    GKI_sched_unlock();
-
     if ((p_msg = (tBTA_DM_API_ENABLE *) GKI_getbuf(sizeof(tBTA_DM_API_ENABLE))) != NULL)
     {
         p_msg->hdr.event = BTA_DM_API_ENABLE_EVT;
@@ -133,7 +131,7 @@
 {
     BT_HDR    *p_msg;
 
-    APPL_TRACE_API0("BTA_EnableTestMode");
+    APPL_TRACE_API("BTA_EnableTestMode");
 
     if ((p_msg = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
     {
@@ -158,7 +156,7 @@
 {
     BT_HDR    *p_msg;
 
-    APPL_TRACE_API0("BTA_DisableTestMode");
+    APPL_TRACE_API("BTA_DisableTestMode");
 
     if ((p_msg = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
     {
@@ -179,14 +177,7 @@
 *******************************************************************************/
 BOOLEAN BTA_DmIsDeviceUp(void)
 {
-
-    BOOLEAN status;
-
-    GKI_sched_lock();
-    status = BTM_IsDeviceUp();
-    GKI_sched_unlock();
-    return status;
-
+    return BTM_IsDeviceUp();
 }
 
 /*******************************************************************************
@@ -262,7 +253,7 @@
 void BTA_DmSetScanParam (UINT16 page_scan_interval, UINT16 page_scan_window,
                                   UINT16 inquiry_scan_interval, UINT16 inquiry_scan_window)
 {
-    APPL_TRACE_API4 ("BTA_DmSetScanParam: %d, %d, %d, %d",
+    APPL_TRACE_API ("BTA_DmSetScanParam: %d, %d, %d, %d",
             page_scan_interval, page_scan_window,
             inquiry_scan_interval, inquiry_scan_window);
 
@@ -505,7 +496,7 @@
     UINT8 link_role;
 
     BTM_GetRole(bd_addr, &link_role);
-    APPL_TRACE_API1("BTA_DmIsMaster role:x%x", link_role);
+    APPL_TRACE_API("BTA_DmIsMaster role:x%x", link_role);
     if(link_role == BTM_ROLE_MASTER)
     {
         is_master = TRUE;
@@ -526,12 +517,29 @@
 *******************************************************************************/
 void BTA_DmBond(BD_ADDR bd_addr)
 {
+    BTA_DmBondByTransport (bd_addr, BTA_TRANSPORT_UNKNOWN);
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBondByTransports
+**
+** Description      This function initiates a bonding procedure with a peer
+**                  device
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport)
+{
     tBTA_DM_API_BOND    *p_msg;
 
     if ((p_msg = (tBTA_DM_API_BOND *) GKI_getbuf(sizeof(tBTA_DM_API_BOND))) != NULL)
     {
         p_msg->hdr.event = BTA_DM_API_BOND_EVT;
         bdcpy(p_msg->bd_addr, bd_addr);
+        p_msg->transport = transport;
         bta_sys_sendmsg(p_msg);
     }
 
@@ -1085,6 +1093,22 @@
 }
 
 /*******************************************************************************
+**
+** Function         BTA_DmGetConnectionState
+**
+** Description      Returns whether the remote device is currently connected.
+**
+** Returns          0 if the device is NOT connected.
+**
+*******************************************************************************/
+UINT16 BTA_DmGetConnectionState( BD_ADDR bd_addr )
+{
+    tBTA_DM_PEER_DEVICE * p_dev = bta_dm_find_peer_device(bd_addr);
+    return (p_dev && p_dev->conn_state == BTA_DM_CONNECTED);
+}
+
+
+/*******************************************************************************
 **                   Device Identification (DI) Server Functions
 *******************************************************************************/
 /*******************************************************************************
@@ -1210,7 +1234,7 @@
 {
     bta_sys_cb.sys_features = sys_features;
 
-    APPL_TRACE_API1("BTA_SysFeatures: sys_features = %d", sys_features);
+    APPL_TRACE_API("BTA_SysFeatures: sys_features = %d", sys_features);
 }
 
 /*******************************************************************************
@@ -1237,8 +1261,6 @@
     }
 }
 
-#if BLE_INCLUDED == TRUE
-
 /*******************************************************************************
 **
 ** Function         BTA_DmAddBleKey
@@ -1466,7 +1488,7 @@
 #if BLE_INCLUDED == TRUE
     tBTA_DM_API_BLE_ADV_PARAMS    *p_msg;
 
-    APPL_TRACE_API2 ("BTA_DmSetBleAdvParam: %d, %d", adv_int_min, adv_int_max);
+    APPL_TRACE_API ("BTA_DmSetBleAdvParam: %d, %d", adv_int_min, adv_int_max);
 
     if ((p_msg = (tBTA_DM_API_BLE_ADV_PARAMS *) GKI_getbuf(sizeof(tBTA_DM_API_BLE_ADV_PARAMS))) != NULL)
     {
@@ -1487,6 +1509,9 @@
     }
 #endif
 }
+/*******************************************************************************
+**                      BLE ADV data management API
+********************************************************************************/
 
 #if BLE_INCLUDED == TRUE
 /*******************************************************************************
@@ -1495,19 +1520,26 @@
 **
 ** Description      This function is called to override the BTA default ADV parameters.
 **
-** Parameters       Pointer to User defined ADV data structure
+** Parameters       data_mask: adv data mask.
+**                  p_adv_cfg: Pointer to User defined ADV data structure. This
+**                             memory space can not be freed until p_adv_data_cback
+**                             is received.
+**                  p_adv_data_cback: set adv data complete callback.
 **
 ** Returns          None
 **
 *******************************************************************************/
-void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg)
+void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg,
+                            tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
 {
     tBTA_DM_API_SET_ADV_CONFIG  *p_msg;
 
-    if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
+    if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *)
+        GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
     {
         p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_EVT;
-		p_msg->data_mask = data_mask;
+        p_msg->data_mask = data_mask;
+        p_msg->p_adv_data_cback = p_adv_data_cback;
         p_msg->p_adv_cfg = p_adv_cfg;
 
         bta_sys_sendmsg(p_msg);
@@ -1525,14 +1557,17 @@
 ** Returns          None
 **
 *******************************************************************************/
-BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg)
+BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg,
+                        tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
 {
     tBTA_DM_API_SET_ADV_CONFIG  *p_msg;
 
-    if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
+    if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *)
+        GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
     {
         p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT;
-		p_msg->data_mask = data_mask;
+        p_msg->data_mask = data_mask;
+        p_msg->p_adv_data_cback = p_adv_data_cback;
         p_msg->p_adv_cfg = p_adv_cfg;
 
         bta_sys_sendmsg(p_msg);
@@ -1541,6 +1576,163 @@
 
 /*******************************************************************************
 **
+** Function         BTA_DmBleSetStorageParams
+**
+** Description      This function is called to override the BTA scan response.
+**
+** Parameters       batch_scan_full_max -Max storage space (in %) allocated to full scanning
+**                  batch_scan_trunc_max -Max storage space (in %) allocated to truncated scanning
+**                  batch_scan_notify_threshold -Setup notification level based on total space
+**                  p_setup_cback - Setup callback pointer
+**                  p_thres_cback - Threshold callback pointer
+**                  p_rep_cback - Reports callback pointer
+**                  ref_value - Ref value
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max,
+                                         UINT8 batch_scan_trunc_max,
+                                         UINT8 batch_scan_notify_threshold,
+                                         tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback,
+                                         tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback,
+                                         tBTA_BLE_SCAN_REP_CBACK* p_rep_cback,
+                                         tBTA_DM_BLE_REF_VALUE ref_value)
+{
+    tBTA_DM_API_SET_STORAGE_CONFIG  *p_msg;
+    bta_dm_cb.p_setup_cback = p_setup_cback;
+    if ((p_msg = (tBTA_DM_API_SET_STORAGE_CONFIG *)
+          GKI_getbuf(sizeof(tBTA_DM_API_SET_STORAGE_CONFIG))) != NULL)
+    {
+        p_msg->hdr.event = BTA_DM_API_BLE_SETUP_STORAGE_EVT;
+        p_msg->p_setup_cback=bta_ble_scan_setup_cb;
+        p_msg->p_thres_cback=p_thres_cback;
+        p_msg->p_read_rep_cback=p_rep_cback;
+        p_msg->ref_value = ref_value;
+        p_msg->batch_scan_full_max = batch_scan_full_max;
+        p_msg->batch_scan_trunc_max = batch_scan_trunc_max;
+        p_msg->batch_scan_notify_threshold = batch_scan_notify_threshold;
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleEnableBatchScan
+**
+** Description      This function is called to enable the batch scan
+**
+** Parameters       scan_mode -Batch scan mode
+**                  scan_interval - Scan interval
+**                  scan_window - Scan window
+**                  discard_rule -Discard rules
+**                  addr_type - Address type
+**                  ref_value - Reference value
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleEnableBatchScan(tBTA_BLE_SCAN_MODE scan_mode,
+                                         UINT32 scan_interval, UINT32 scan_window,
+                                         tBTA_BLE_DISCARD_RULE discard_rule,
+                                         tBLE_ADDR_TYPE        addr_type,
+                                         tBTA_DM_BLE_REF_VALUE ref_value)
+{
+    tBTA_DM_API_ENABLE_SCAN  *p_msg;
+
+    if ((p_msg = (tBTA_DM_API_ENABLE_SCAN *) GKI_getbuf(sizeof(tBTA_DM_API_ENABLE_SCAN))) != NULL)
+    {
+        p_msg->hdr.event = BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT;
+        p_msg->scan_mode = scan_mode;
+        p_msg->scan_int = scan_interval;
+        p_msg->scan_window = scan_window;
+        p_msg->discard_rule = discard_rule;
+        p_msg->addr_type = addr_type;
+        p_msg->ref_value = ref_value;
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleDisableBatchScan
+**
+** Description      This function is called to disable the batch scan
+**
+** Parameters       ref_value - Reference value
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value)
+{
+    tBTA_DM_API_DISABLE_SCAN  *p_msg;
+
+    if ((p_msg = (tBTA_DM_API_DISABLE_SCAN *)
+         GKI_getbuf(sizeof(tBTA_DM_API_DISABLE_SCAN))) != NULL)
+    {
+        p_msg->hdr.event = BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT;
+        p_msg->ref_value = ref_value;
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleReadScanReports
+**
+** Description      This function is called to read scan reports
+**
+** Parameters       scan_type -Batch scan mode
+**                  ref_value - Reference value
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleReadScanReports(tBTA_BLE_SCAN_MODE scan_type,
+                                             tBTA_DM_BLE_REF_VALUE ref_value)
+{
+    tBTA_DM_API_READ_SCAN_REPORTS  *p_msg;
+
+    if ((p_msg = (tBTA_DM_API_READ_SCAN_REPORTS *)
+          GKI_getbuf(sizeof(tBTA_DM_API_READ_SCAN_REPORTS))) != NULL)
+    {
+        p_msg->hdr.event = BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT;
+        p_msg->scan_type = scan_type;
+        p_msg->ref_value = ref_value;
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleTrackAdvertiser
+**
+** Description      This function is called to track advertiser
+**
+** Parameters       ref_value - Reference value
+**                  p_track_adv_cback - Track ADV callback
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleTrackAdvertiser(tBTA_DM_BLE_REF_VALUE ref_value,
+                            tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback)
+{
+    tBTA_DM_API_TRACK_ADVERTISER  *p_msg;
+
+    if ((p_msg = (tBTA_DM_API_TRACK_ADVERTISER *)
+         GKI_getbuf(sizeof(tBTA_DM_API_TRACK_ADVERTISER))) != NULL)
+    {
+        p_msg->hdr.event = BTA_DM_API_BLE_TRACK_ADVERTISER_EVT;
+        p_msg->p_track_adv_cback = p_track_adv_cback;
+        p_msg->ref_value = ref_value;
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         BTA_DmBleBroadcast
 **
 ** Description      This function starts or stops LE broadcasting.
@@ -1554,7 +1746,7 @@
 {
     tBTA_DM_API_BLE_OBSERVE   *p_msg;
 
-    APPL_TRACE_API1("BTA_DmBleBroadcast: start = %d ", start);
+    APPL_TRACE_API("BTA_DmBleBroadcast: start = %d ", start);
 
     if ((p_msg = (tBTA_DM_API_BLE_OBSERVE *) GKI_getbuf(sizeof(tBTA_DM_API_BLE_OBSERVE))) != NULL)
     {
@@ -1599,6 +1791,81 @@
     }
 #endif
 }
+
+/*******************************************************************************
+**
+** Function         bta_dm_discover_send_msg
+**
+** Description      This function send discover message to BTA task.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_dm_discover_send_msg(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+                    tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search,
+                    tBTA_TRANSPORT transport)
+{
+    tBTA_DM_API_DISCOVER    *p_msg;
+    UINT16  len = p_services ? (sizeof(tBTA_DM_API_DISCOVER) +
+                                sizeof(tBT_UUID) * p_services->num_uuid) :
+                                sizeof(tBTA_DM_API_DISCOVER);
+
+    if ((p_msg = (tBTA_DM_API_DISCOVER *) GKI_getbuf(len)) != NULL)
+    {
+        memset(p_msg, 0, len);
+
+        p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT;
+        bdcpy(p_msg->bd_addr, bd_addr);
+        p_msg->p_cback = p_cback;
+        p_msg->sdp_search = sdp_search;
+        p_msg->transport    = transport;
+
+        if (p_services != NULL)
+        {
+#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
+            p_msg->services = p_services->srvc_mask;
+            p_msg->num_uuid = p_services->num_uuid;
+            if (p_services->num_uuid != 0)
+            {
+                p_msg->p_uuid = (tBT_UUID *)(p_msg + 1);
+                memcpy(p_msg->p_uuid, p_services->p_uuid, sizeof(tBT_UUID) * p_services->num_uuid);
+            }
+#endif
+        }
+
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmDiscoverByTransport
+**
+** Description      This function does service discovery on particular transport
+**                  for services of a
+**                  peer device. When services.num_uuid is 0, it indicates all
+**                  GATT based services are to be searched; otherwise a list of
+**                  UUID of interested services should be provided through
+**                  p_services->p_uuid.
+**
+** Parameters       bd_addr: Bluetooth address of remote device
+**                  p_services :bit mask of the list of services to be discovered
+**                  p_cback : Callback on which result will be received
+**                  sdp_search: if TRUE SDP search will be initiated, else services present in
+**                                     EIR structure of remote device will be returned.
+**                  transport : Physical transport BR/EDR or LE
+** Returns          void
+**
+*******************************************************************************/
+
+void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+                    tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search,
+                    tBTA_TRANSPORT transport)
+{
+    bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search, transport);
+}
+
+
 /*******************************************************************************
 **
 ** Function         BTA_DmDiscoverExt
@@ -1609,7 +1876,11 @@
 **                  UUID of interested services should be provided through
 **                  p_services->p_uuid.
 **
-**
+** Parameters       bd_addr: Bluetooth address of remote device
+**                  p_services :bit mask of the list of services to be discovered
+**                  p_cback : Callback on which result will be received
+**                  sdp_search: if TRUE SDP search will be initiated, else services present in
+**                                     EIR structure of remote device will be returned.
 **
 ** Returns          void
 **
@@ -1617,40 +1888,7 @@
 void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
                     tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search)
 {
-#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
-    tBTA_DM_API_DISCOVER    *p_msg;
-    UINT16  len = p_services ? (sizeof(tBTA_DM_API_DISCOVER) + sizeof(tBT_UUID) * p_services->num_uuid) :
-                    sizeof(tBTA_DM_API_DISCOVER);
-
-    if ((p_msg = (tBTA_DM_API_DISCOVER *) GKI_getbuf(len)) != NULL)
-    {
-        memset(p_msg, 0, len);
-
-        p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT;
-        bdcpy(p_msg->bd_addr, bd_addr);
-        p_msg->p_cback = p_cback;
-        p_msg->sdp_search = sdp_search;
-
-        if (p_services != NULL)
-        {
-            p_msg->services = p_services->srvc_mask;
-            p_msg->num_uuid = p_services->num_uuid;
-
-            if (p_services->num_uuid != 0)
-            {
-                p_msg->p_uuid = (tBT_UUID *)(p_msg + 1);
-                memcpy(p_msg->p_uuid, p_services->p_uuid, sizeof(tBT_UUID) * p_services->num_uuid);
-            }
-        }
-
-        bta_sys_sendmsg(p_msg);
-    }
-#else
-    UNUSED(bd_addr);
-    UNUSED(p_services);
-    UNUSED(p_cback);
-    UNUSED(sdp_search);
-#endif
+    bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search, BTA_TRANSPORT_UNKNOWN);
 
 }
 
@@ -1745,7 +1983,454 @@
 *******************************************************************************/
 void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable)
 {
-    UNUSED(privacy_enable);
+#if BLE_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE
+    tBTA_DM_API_LOCAL_PRIVACY *p_msg;
+
+    if ((p_msg = (tBTA_DM_API_LOCAL_PRIVACY *) GKI_getbuf(sizeof(tBTA_DM_API_ENABLE_PRIVACY))) != NULL)
+    {
+        memset (p_msg, 0, sizeof(tBTA_DM_API_LOCAL_PRIVACY));
+
+        p_msg->hdr.event = BTA_DM_API_LOCAL_PRIVACY_EVT;
+        p_msg->privacy_enable   = privacy_enable;
+
+        bta_sys_sendmsg(p_msg);
+    }
+#else
+    UNUSED (privacy_enable);
+#endif
+}
+
+#if BLE_INCLUDED == TRUE
+/*******************************************************************************
+**
+** Function         BTA_BleEnableAdvInstance
+**
+** Description      This function enable a Multi-ADV instance with the specififed
+**                  adv parameters
+**
+** Parameters       p_params: pointer to the adv parameter structure.
+**                  p_cback: callback function associated to this adv instance.
+**                  p_ref: reference data pointer to this adv instance.
+**
+** Returns          BTA_SUCCESS if command started sucessfully; otherwise failure.
+**
+*******************************************************************************/
+void BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params,
+                                tBTA_BLE_MULTI_ADV_CBACK *p_cback,
+                                void *p_ref)
+{
+    tBTA_DM_API_BLE_MULTI_ADV_ENB    *p_msg;
+    UINT16 len = sizeof(tBTA_BLE_ADV_PARAMS) + sizeof(tBTA_DM_API_BLE_MULTI_ADV_ENB);
+
+    APPL_TRACE_API ("BTA_BleEnableAdvInstance");
+
+    if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_ENB *) GKI_getbuf(len)) != NULL)
+    {
+        memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_ENB));
+
+        p_msg->hdr.event     = BTA_DM_API_BLE_MULTI_ADV_ENB_EVT;
+        p_msg->p_cback      = (void *)p_cback;
+        if (p_params != NULL)
+        {
+            p_msg->p_params =  (void *)(p_msg + 1);
+            memcpy(p_msg->p_params, p_params, sizeof(tBTA_BLE_ADV_PARAMS));
+        }
+        p_msg->p_ref        = p_ref;
+
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_BleUpdateAdvInstParam
+**
+** Description      This function update a Multi-ADV instance with the specififed
+**                  adv parameters.
+**
+** Parameters       inst_id: Adv instance to update the parameter.
+**                  p_params: pointer to the adv parameter structure.
+**
+** Returns          BTA_SUCCESS if command started sucessfully; otherwise failure.
+**
+*******************************************************************************/
+void BTA_BleUpdateAdvInstParam (UINT8 inst_id, tBTA_BLE_ADV_PARAMS *p_params)
+{
+    tBTA_DM_API_BLE_MULTI_ADV_PARAM    *p_msg;
+    UINT16      len = sizeof(tBTA_BLE_ADV_PARAMS) + sizeof(tBTA_DM_API_BLE_MULTI_ADV_PARAM);
+
+    APPL_TRACE_API ("BTA_BleUpdateAdvInstParam");
+     if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_PARAM *) GKI_getbuf(len)) != NULL)
+     {
+          memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_PARAM));
+          p_msg->hdr.event     = BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT;
+          p_msg->inst_id        = inst_id;
+          p_msg->p_params =  (void *)(p_msg + 1);
+          memcpy(p_msg->p_params, p_params, sizeof(tBTA_BLE_ADV_PARAMS));
+
+          bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_BleCfgAdvInstData
+**
+** Description      This function configure a Multi-ADV instance with the specififed
+**                  adv data or scan response data.
+**
+** Parameter        inst_id: Adv instance to configure the adv data or scan response.
+**                  is_scan_rsp: is the data scan response or adv data.
+**                  data_mask: adv data type as bit mask.
+**                  p_data: pointer to the ADV data structure tBTA_BLE_ADV_DATA. This
+**                  memory space can not be freed until BTA_BLE_MULTI_ADV_DATA_EVT
+**                  is sent to application.
+**
+** Returns          BTA_SUCCESS if command started sucessfully; otherwise failure.
+**
+*******************************************************************************/
+void BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
+                            tBTA_BLE_AD_MASK data_mask,
+                            tBTA_BLE_ADV_DATA *p_data)
+{
+    tBTA_DM_API_BLE_MULTI_ADV_DATA    *p_msg;
+    UINT16      len =  sizeof(tBTA_DM_API_BLE_MULTI_ADV_DATA) ;
+
+    APPL_TRACE_API ("BTA_BleCfgAdvInstData");
+
+    if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_DATA *) GKI_getbuf(len)) != NULL)
+    {
+          memset(p_msg, 0, len);
+          p_msg->hdr.event     = BTA_DM_API_BLE_MULTI_ADV_DATA_EVT;
+          p_msg->inst_id      = inst_id;
+          p_msg->is_scan_rsp  = is_scan_rsp;
+          p_msg->data_mask     = data_mask;
+          p_msg->p_data        = p_data;
+
+          bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_BleDisableAdvInstance
+**
+** Description      This function disable a Multi-ADV instance.
+**
+** Parameter        inst_id: instance ID to disable.
+**
+** Returns          BTA_SUCCESS if command started sucessfully; otherwise failure.
+**
+*******************************************************************************/
+void BTA_BleDisableAdvInstance (UINT8  inst_id)
+{
+    tBTA_DM_API_BLE_MULTI_ADV_DISABLE    *p_msg;
+
+    APPL_TRACE_API ("BTA_BleDisableAdvInstance: %d", inst_id);
+    if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_DISABLE *)
+          GKI_getbuf(sizeof(tBTA_DM_API_BLE_MULTI_ADV_DISABLE))) != NULL)
+    {
+         memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_DISABLE));
+         p_msg->hdr.event    = BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT;
+         p_msg->inst_id      = inst_id;
+         bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleCfgFilterCondition
+**
+** Description      This function is called to configure the adv data payload filter
+**                  condition.
+**
+** Parameters       action: to read/write/clear
+**                  cond_type: filter condition type
+**                  filt_index - Filter index
+**                  p_cond: filter condition parameter
+**                  p_cmpl_back - Command completed callback
+**                  ref_value - Reference value
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action,
+                                 tBTA_DM_BLE_PF_COND_TYPE cond_type,
+                                 tBTA_DM_BLE_PF_FILT_INDEX filt_index,
+                                 tBTA_DM_BLE_PF_COND_PARAM *p_cond,
+                                 tBTA_DM_BLE_PF_CFG_CBACK *p_cmpl_cback,
+                                 tBTA_DM_BLE_REF_VALUE ref_value)
+{
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+    tBTA_DM_API_CFG_FILTER_COND *p_msg;
+    APPL_TRACE_API ("BTA_DmBleCfgFilterCondition: %d, %d", action, cond_type);
+
+    UINT16  len = sizeof(tBTA_DM_API_CFG_FILTER_COND) +
+                  sizeof(tBTA_DM_BLE_PF_COND_PARAM);
+    UINT8 *p;
+
+    if (NULL != p_cond)
+    {
+        switch(cond_type)
+        {
+            case BTA_DM_BLE_PF_SRVC_DATA_PATTERN:
+            case BTA_DM_BLE_PF_MANU_DATA:
+                /* Length of pattern and pattern mask and other elements in */
+                /* tBTA_DM_BLE_PF_MANU_COND */
+                len += ((p_cond->manu_data.data_len) * 2) +
+                        sizeof(UINT16) + sizeof(UINT16) + sizeof(UINT8);
+                break;
+
+            case BTA_DM_BLE_PF_LOCAL_NAME:
+                len += ((p_cond->local_name.data_len) + sizeof(UINT8));
+                break;
+
+            case BTM_BLE_PF_SRVC_UUID:
+            case BTM_BLE_PF_SRVC_SOL_UUID:
+                len += sizeof(tBLE_BD_ADDR) + sizeof(tBTA_DM_BLE_PF_COND_MASK);
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    if ((p_msg = (tBTA_DM_API_CFG_FILTER_COND *) GKI_getbuf(len)) != NULL)
+    {
+        memset (p_msg, 0, len);
+        p_msg->hdr.event        = BTA_DM_API_CFG_FILTER_COND_EVT;
+        p_msg->action           = action;
+        p_msg->cond_type        = cond_type;
+        p_msg->filt_index       = filt_index;
+        p_msg->p_filt_cfg_cback = p_cmpl_cback;
+        p_msg->ref_value        = ref_value;
+
+        if (p_cond)
+        {
+            p_msg->p_cond_param = (tBTA_DM_BLE_PF_COND_PARAM *)(p_msg + 1);
+            memcpy(p_msg->p_cond_param, p_cond, sizeof(tBTA_DM_BLE_PF_COND_PARAM));
+
+            p = (UINT8 *)(p_msg->p_cond_param + 1);
+
+            if (cond_type == BTA_DM_BLE_PF_SRVC_DATA_PATTERN ||
+                cond_type == BTA_DM_BLE_PF_MANU_DATA)
+            {
+                p_msg->p_cond_param->manu_data.p_pattern = p;
+                p_msg->p_cond_param->manu_data.data_len = p_cond->manu_data.data_len;
+                memcpy(p_msg->p_cond_param->manu_data.p_pattern, p_cond->manu_data.p_pattern,
+                    p_cond->manu_data.data_len);
+                p += p_cond->manu_data.data_len;
+
+                if (cond_type == BTA_DM_BLE_PF_MANU_DATA)
+                {
+                    p_msg->p_cond_param->manu_data.company_id_mask =
+                        p_cond->manu_data.company_id_mask;
+                    if ( p_cond->manu_data.p_pattern_mask != NULL)
+                    {
+                        p_msg->p_cond_param->manu_data.p_pattern_mask = p;
+                        memcpy(p_msg->p_cond_param->manu_data.p_pattern_mask,
+                            p_cond->manu_data.p_pattern_mask, p_cond->manu_data.data_len);
+                    }
+                }
+            }
+            else if (cond_type == BTA_DM_BLE_PF_LOCAL_NAME)
+            {
+                p_msg->p_cond_param->local_name.p_data = p;
+                p_msg->p_cond_param->local_name.data_len =
+                    p_cond->local_name.data_len;
+                memcpy(p_msg->p_cond_param->local_name.p_data,
+                    p_cond->local_name.p_data, p_cond->local_name.data_len);
+            }
+            else if ((cond_type == BTM_BLE_PF_SRVC_UUID
+                || cond_type == BTM_BLE_PF_SRVC_SOL_UUID))
+            {
+                if (p_cond->srvc_uuid.p_target_addr != NULL)
+                {
+                    p_msg->p_cond_param->srvc_uuid.p_target_addr = (tBLE_BD_ADDR *)(p);
+                    p_msg->p_cond_param->srvc_uuid.p_target_addr->type =
+                        p_cond->srvc_uuid.p_target_addr->type;
+                    memcpy(p_msg->p_cond_param->srvc_uuid.p_target_addr->bda,
+                        p_cond->srvc_uuid.p_target_addr->bda, BD_ADDR_LEN);
+                    p = (UINT8*)( p_msg->p_cond_param->srvc_uuid.p_target_addr + 1);
+                }
+                if (p_cond->srvc_uuid.p_uuid_mask)
+                {
+                    p_msg->p_cond_param->srvc_uuid.p_uuid_mask = (tBTA_DM_BLE_PF_COND_MASK *)p;
+                    memcpy(p_msg->p_cond_param->srvc_uuid.p_uuid_mask,
+                        p_cond->srvc_uuid.p_uuid_mask, sizeof(tBTA_DM_BLE_PF_COND_MASK));
+                }
+            }
+        }
+
+        bta_sys_sendmsg(p_msg);
+    }
+#else
+    UNUSED(action);
+    UNUSED(cond_type);
+    UNUSED(filt_index);
+    UNUSED(p_cond);
+    UNUSED(p_cmpl_cback);
+    UNUSED(ref_value);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleScanFilterSetup
+**
+** Description      This function is called to setup the adv data payload filter param
+**
+** Parameters       p_target: enable the filter condition on a target device; if NULL
+**                  filt_index - Filter index
+**                  p_filt_params -Filter parameters
+**                  ref_value - Reference value
+**                  action - Add, delete or clear
+**                  p_cmpl_back - Command completed callback
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmBleScanFilterSetup(UINT8 action, tBTA_DM_BLE_PF_FILT_INDEX filt_index,
+                                    tBTA_DM_BLE_PF_FILT_PARAMS *p_filt_params,
+                                    tBLE_BD_ADDR *p_target,
+                                    tBTA_DM_BLE_PF_PARAM_CBACK *p_cmpl_cback,
+                                    tBTA_DM_BLE_REF_VALUE ref_value)
+{
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+    tBTA_DM_API_SCAN_FILTER_PARAM_SETUP *p_msg;
+    APPL_TRACE_API ("BTA_DmBleScanFilterSetup: %d", action);
+
+    UINT16  len = sizeof(tBTA_DM_API_SCAN_FILTER_PARAM_SETUP) + sizeof(tBLE_BD_ADDR);
+
+    if ((p_msg = (tBTA_DM_API_SCAN_FILTER_PARAM_SETUP *) GKI_getbuf(len)) != NULL)
+    {
+        memset (p_msg, 0, len);
+
+        p_msg->hdr.event        = BTA_DM_API_SCAN_FILTER_SETUP_EVT;
+        p_msg->action       = action;
+        p_msg->filt_index = filt_index;
+        p_msg->p_filt_params = p_filt_params;
+        p_msg->p_filt_param_cback = p_cmpl_cback;
+        p_msg->ref_value        = ref_value;
+
+        if (p_target)
+        {
+            p_msg->p_target = (tBLE_BD_ADDR *)(p_msg + 1);
+            memcpy(p_msg->p_target, p_target, sizeof(tBLE_BD_ADDR));
+        }
+
+        bta_sys_sendmsg(p_msg);
+    }
+#else
+    UNUSED(action);
+    UNUSED(filt_index);
+    UNUSED(p_filt_params);
+    UNUSED(p_target);
+    UNUSED(p_cmpl_cback);
+    UNUSED(ref_value);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleGetEnergyInfo
+**
+** Description      This function is called to obtain the energy info
+**
+** Parameters       p_cmpl_cback - Command complete callback
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmBleGetEnergyInfo(tBTA_BLE_ENERGY_INFO_CBACK *p_cmpl_cback)
+{
+    tBTA_DM_API_ENERGY_INFO *p_msg;
+    APPL_TRACE_API ("BTA_DmBleGetEnergyInfo");
+
+    UINT16  len = sizeof(tBTA_DM_API_ENERGY_INFO) + sizeof(tBLE_BD_ADDR);
+
+    if ((p_msg = (tBTA_DM_API_ENERGY_INFO *) GKI_getbuf(len)) != NULL)
+    {
+        memset (p_msg, 0, len);
+        p_msg->hdr.event        = BTA_DM_API_BLE_ENERGY_INFO_EVT;
+        p_msg->p_energy_info_cback = p_cmpl_cback;
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmEnableScanFilter
+**
+** Description      This function is called to enable the adv data payload filter
+**
+** Parameters       action - enable or disable the APCF feature
+**                  p_cmpl_cback - Command completed callback
+**                  ref_value - Reference value
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmEnableScanFilter(UINT8 action, tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cback,
+                                    tBTA_DM_BLE_REF_VALUE ref_value)
+{
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+    tBTA_DM_API_ENABLE_SCAN_FILTER *p_msg;
+    APPL_TRACE_API ("BTA_DmEnableScanFilter: %d", action);
+
+    UINT16  len = sizeof(tBTA_DM_API_ENABLE_SCAN_FILTER) + sizeof(tBLE_BD_ADDR);
+
+    if ((p_msg = (tBTA_DM_API_ENABLE_SCAN_FILTER *) GKI_getbuf(len)) != NULL)
+    {
+        memset (p_msg, 0, len);
+
+        p_msg->hdr.event        = BTA_DM_API_SCAN_FILTER_ENABLE_EVT;
+        p_msg->action       = action;
+        p_msg->ref_value    = ref_value;
+        p_msg->p_filt_status_cback = p_cmpl_cback;
+
+        bta_sys_sendmsg(p_msg);
+    }
+#else
+    UNUSED(action);
+    UNUSED(p_cmpl_cback);
+    UNUSED(ref_value);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleUpdateConnectionParams
+**
+** Description      Update connection parameters, can only be used when connection is up.
+**
+** Parameters:      bd_addr   - BD address of the peer
+**                  min_int   -     minimum connection interval, [0x0004~ 0x4000]
+**                  max_int   -     maximum connection interval, [0x0004~ 0x4000]
+**                  latency   -     slave latency [0 ~ 500]
+**                  timeout   -     supervision timeout [0x000a ~ 0xc80]
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int,
+                                    UINT16 latency, UINT16 timeout)
+{
+    tBTA_DM_API_UPDATE_CONN_PARAM *p_msg;
+
+    if ((p_msg = (tBTA_DM_API_UPDATE_CONN_PARAM *) GKI_getbuf(sizeof(tBTA_DM_API_UPDATE_CONN_PARAM))) != NULL)
+    {
+        memset (p_msg, 0, sizeof(tBTA_DM_API_UPDATE_CONN_PARAM));
+
+        p_msg->hdr.event = BTA_DM_API_UPDATE_CONN_PARAM_EVT;
+        bdcpy(p_msg->bd_addr, bd_addr);
+        p_msg->min_int   = min_int;
+        p_msg->max_int   = max_int;
+        p_msg->latency   = latency;
+        p_msg->timeout   = timeout;
+
+        bta_sys_sendmsg(p_msg);
+    }
 }
 #endif
 
@@ -1759,6 +2444,7 @@
 **                  bring up unencrypted links, then later encrypt them.
 **
 ** Parameters:      bd_addr       - Address of the peer device
+**                  transport     - transport of the link to be encruypted
 **                  p_callback    - Pointer to callback function to indicat the
 **                                  link encryption status
 **                  sec_act       - This is the security action to indicate
@@ -1770,12 +2456,12 @@
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback,
+void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_DM_ENCRYPT_CBACK *p_callback,
                             tBTA_DM_BLE_SEC_ACT sec_act)
 {
     tBTA_DM_API_SET_ENCRYPTION   *p_msg;
 
-    APPL_TRACE_API0("BTA_DmSetEncryption"); //todo
+    APPL_TRACE_API("BTA_DmSetEncryption"); //todo
     if ((p_msg = (tBTA_DM_API_SET_ENCRYPTION *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ENCRYPTION))) != NULL)
     {
         memset(p_msg, 0, sizeof(tBTA_DM_API_SET_ENCRYPTION));
@@ -1783,6 +2469,7 @@
         p_msg->hdr.event = BTA_DM_API_SET_ENCRYPTION_EVT;
 
         memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
+        p_msg->transport    = transport;
         p_msg->p_callback      = p_callback;
         p_msg->sec_act         = sec_act;
 
@@ -1803,11 +2490,11 @@
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev)
+void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport)
 {
     tBTA_DM_API_REMOVE_ACL   *p_msg;
 
-    APPL_TRACE_API0("BTA_DmCloseACL");
+    APPL_TRACE_API("BTA_DmCloseACL");
 
     if ((p_msg = (tBTA_DM_API_REMOVE_ACL *) GKI_getbuf(sizeof(tBTA_DM_API_REMOVE_ACL))) != NULL)
     {
@@ -1817,6 +2504,7 @@
 
         memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
         p_msg->remove_dev      = remove_dev;
+        p_msg->transport       = transport;
 
         bta_sys_sendmsg(p_msg);
     }
@@ -1841,11 +2529,9 @@
 BTA_API extern void BTA_DmBleObserve(BOOLEAN start, UINT8 duration,
                                      tBTA_DM_SEARCH_CBACK *p_results_cb)
 {
-#if BLE_INCLUDED == TRUE
-
     tBTA_DM_API_BLE_OBSERVE   *p_msg;
 
-    APPL_TRACE_API1("BTA_DmBleObserve:start = %d ", start);
+    APPL_TRACE_API("BTA_DmBleObserve:start = %d ", start);
 
     if ((p_msg = (tBTA_DM_API_BLE_OBSERVE *) GKI_getbuf(sizeof(tBTA_DM_API_BLE_OBSERVE))) != NULL)
     {
@@ -1858,6 +2544,49 @@
 
         bta_sys_sendmsg(p_msg);
     }
-#endif
 }
+
+/*******************************************************************************
+**
+** Function         BTA_VendorInit
+**
+** Description      This function initializes vendor specific
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_VendorInit (void)
+{
+    APPL_TRACE_API("BTA_VendorInit");
+}
+
+/*******************************************************************************
+**
+** Function         BTA_VendorCleanup
+**
+** Description      This function frees up Broadcom specific VS specific dynamic memory
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_VendorCleanup (void)
+{
+    tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
+
+#if (BLE_INCLUDED == TRUE && BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE)
+    if (cmn_ble_vsc_cb.max_filter > 0)
+    {
+        btm_ble_adv_filter_cleanup();
+        btm_ble_vendor_cleanup();
+    }
+
+    if (cmn_ble_vsc_cb.tot_scan_results_strg > 0)
+        btm_ble_batchscan_cleanup();
+#endif
+
+   if(cmn_ble_vsc_cb.adv_inst_max > 0)
+      btm_ble_multi_adv_cleanup();
+}
+
 #endif
diff --git a/bta/dm/bta_dm_cfg.c b/bta/dm/bta_dm_cfg.c
index e4a1681..62ce9c6 100644
--- a/bta/dm/bta_dm_cfg.c
+++ b/bta/dm/bta_dm_cfg.c
@@ -111,14 +111,16 @@
 tBTA_DM_RM *p_bta_dm_rm_cfg = (tBTA_DM_RM *)&bta_dm_rm_cfg;
 
 #if BLE_INCLUDED == TRUE
-#define BTA_DM_NUM_PM_ENTRY         (17+BTA_DM_NUM_JV_ID)  /* number of entries in bta_dm_pm_cfg except the first */
+#  define BTA_DM_NUM_PM_ENTRY         22  /* number of entries in bta_dm_pm_cfg except the first */
+#  define BTA_DM_NUM_PM_SPEC          14  /* number of entries in bta_dm_pm_spec */
 #else
-#define BTA_DM_NUM_PM_ENTRY         (15+BTA_DM_NUM_JV_ID)  /* number of entries in bta_dm_pm_cfg except the first */
+#  define BTA_DM_NUM_PM_ENTRY         20  /* number of entries in bta_dm_pm_cfg except the first */
+#  define BTA_DM_NUM_PM_SPEC          12  /* number of entries in bta_dm_pm_spec */
 #endif
 
-tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG bta_dm_pm_cfg[] =
+tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG bta_dm_pm_cfg[BTA_DM_NUM_PM_ENTRY + 1] =
 {
-  {BTA_ID_SYS, BTA_DM_NUM_PM_ENTRY, 0},
+  {BTA_ID_SYS, BTA_DM_NUM_PM_ENTRY, 0},  /* reserved: specifies length of this table. */
   {BTA_ID_AG,  BTA_ALL_APP_ID,      0},  /* ag uses first spec table for app id 0 */
   {BTA_ID_CT,  1,                   1},  /* ct (BTA_ID_CT,APP ID=1) spec table */
   {BTA_ID_CG,  BTA_ALL_APP_ID,      1},  /* cg resue ct spec table */
@@ -135,28 +137,16 @@
   {BTA_ID_MSE, BTA_ALL_APP_ID,      7},  /* reuse fts spec table */
   {BTA_ID_JV,  BTA_JV_PM_ID_1,      6},  /* app BTA_JV_PM_ID_1, reuse ftc spec table */
   {BTA_ID_JV,  BTA_ALL_APP_ID,      7},  /* reuse fts spec table */
-  {BTA_ID_HL,  BTA_ALL_APP_ID,      8}   /* reuse fts spec table */
+  {BTA_ID_HL,  BTA_ALL_APP_ID,      8},  /* reuse fts spec table */
+  {BTA_ID_HS,  BTA_ALL_APP_ID,      9},  /* HS spec table */
+  {BTA_ID_PAN, BTUI_PAN_ID_PANU,   10},  /* PANU spec table */
+  {BTA_ID_PAN, BTUI_PAN_ID_NAP,    11}   /* NAP spec table */
 #if BLE_INCLUDED == TRUE
-  ,{BTA_ID_GATTC,  BTA_ALL_APP_ID,   9}   /* gattc spec table */
-  ,{BTA_ID_GATTS,  BTA_ALL_APP_ID,   10}  /* gatts spec table */
+  ,{BTA_ID_GATTC,  BTA_ALL_APP_ID,  12}   /* gattc spec table */
+  ,{BTA_ID_GATTS,  BTA_ALL_APP_ID,  13}  /* gatts spec table */
 #endif
 };
 
-#if BLE_INCLUDED == TRUE /* add GATT PM entry for GATT over BR/EDR  */
-#ifdef BTE_SIM_APP      /* For Insight builds only, see the detail below */
-#define BTA_DM_NUM_PM_SPEC      (11 + 2)  /* additional two */
-#else
-#define BTA_DM_NUM_PM_SPEC      11 /* additional JV*/
-#endif
-#else
-#ifdef BTE_SIM_APP      /* For Insight builds only, see the detail below */
-#define BTA_DM_NUM_PM_SPEC      (9 + 2)  /* additional two */
-#else
-#define BTA_DM_NUM_PM_SPEC      9  /* additional JV*/
-#endif
-#endif
-
-
 tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] =
 {
   /* AG */
@@ -166,12 +156,12 @@
   (BTA_DM_PM_SSR2),                                              /* the SSR entry */
 #endif
   {
-      {{BTA_DM_PM_SNIFF,  5000},   {BTA_DM_PM_NO_ACTION, 0}},   /* conn open sniff  */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff  */
       {{BTA_DM_PM_NO_PREF,   0},   {BTA_DM_PM_NO_ACTION, 0}},   /* conn close  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},   /* app open */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},   /* app close */
-      {{BTA_DM_PM_SNIFF3, 5000},   {BTA_DM_PM_NO_ACTION, 0}},   /* sco open, active */
-      {{BTA_DM_PM_SNIFF,  5000},   {BTA_DM_PM_NO_ACTION, 0}},   /* sco close sniff  */
+      {{BTA_DM_PM_SNIFF_SCO_OPEN_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},   /* idle */
       {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},   /* busy */
       {{BTA_DM_PM_RETRY,  5000},   {BTA_DM_PM_NO_ACTION, 0}}    /* mode change retry */
@@ -189,7 +179,7 @@
       {{BTA_DM_PM_NO_PREF,   0},  {BTA_DM_PM_NO_ACTION, 0}},    /* conn close  */
       {{BTA_DM_PM_NO_ACTION, 0},  {BTA_DM_PM_NO_ACTION, 0}},    /* app open */
       {{BTA_DM_PM_NO_ACTION, 0},  {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
-      {{BTA_DM_PM_SNIFF,  5000},  {BTA_DM_PM_NO_ACTION, 0}},    /* sco open sniff */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open sniff */
       {{BTA_DM_PM_PARK,   5000},  {BTA_DM_PM_NO_ACTION, 0}},    /* sco close  park */
       {{BTA_DM_PM_NO_ACTION, 0},  {BTA_DM_PM_NO_ACTION, 0}},    /* idle */
       {{BTA_DM_PM_NO_ACTION, 0},  {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
@@ -223,14 +213,14 @@
   (BTA_DM_PM_SSR3),                                              /* the SSR entry */
 #endif
   {
-      {{BTA_DM_PM_SNIFF4, 5000},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn open  sniff */
+      {{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open  sniff */
       {{BTA_DM_PM_NO_PREF,   0},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn close  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app open */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco open  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco close   */
-      {{BTA_DM_PM_SNIFF2, 5000},   {BTA_DM_PM_NO_ACTION, 0}},    /* idle */
-      {{BTA_DM_PM_SNIFF4,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
+      {{BTA_DM_PM_SNIFF_HD_IDLE_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
+      {{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}}     /* mode change retry */
   }
  },
@@ -242,13 +232,13 @@
   (BTA_DM_PM_SSR2),                                              /* the SSR entry */
 #endif
   {
-      {{BTA_DM_PM_SNIFF,  5000},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn open  sniff */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open  sniff */
       {{BTA_DM_PM_NO_PREF,   0},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn close  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app open */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco open  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco close   */
-      {{BTA_DM_PM_SNIFF,  5000},   {BTA_DM_PM_NO_ACTION, 0}},    /* idle */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
       {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}}     /* mode change retry */
   }
@@ -261,14 +251,14 @@
   (BTA_DM_PM_SSR1),                                              /* the SSR entry */
 #endif
   {
-      {{BTA_DM_PM_SNIFF2, 30000},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn open  sniff */
+      {{BTA_DM_PM_SNIFF_HH_OPEN_IDX, BTA_DM_PM_HH_OPEN_DELAY},{BTA_DM_PM_NO_ACTION, 0}}, /* conn open  sniff */
       {{BTA_DM_PM_NO_PREF,   0},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn close  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app open */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco open  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco close, used for HH suspend   */
-      {{BTA_DM_PM_SNIFF2, 30000},   {BTA_DM_PM_NO_ACTION, 0}},    /* idle */
-      {{BTA_DM_PM_SNIFF2, 30000},   {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
+      {{BTA_DM_PM_SNIFF_HH_IDLE_IDX, BTA_DM_PM_HH_IDLE_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
+      {{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}}     /* mode change retry */
   }
  },
@@ -286,7 +276,7 @@
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco open  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco close   */
-      {{BTA_DM_PM_SNIFF,  5000},   {BTA_DM_PM_NO_ACTION, 0}},    /* idle */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
       {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}}     /* mode change retry */
   }
@@ -305,7 +295,7 @@
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco open  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco close   */
-      {{BTA_DM_PM_SNIFF,  7000},   {BTA_DM_PM_NO_ACTION, 0}},    /* idle */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
       {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}}     /* mode change retry */
   }
@@ -318,7 +308,7 @@
   (BTA_DM_PM_SSR2),                                              /* the SSR entry */
 #endif
   {
-      {{BTA_DM_PM_SNIFF,  5000},   {BTA_DM_PM_NO_ACTION, 0}},   /* conn open sniff  */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff  */
       {{BTA_DM_PM_NO_PREF,   0},   {BTA_DM_PM_NO_ACTION, 0}},   /* conn close  */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},   /* app open */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},   /* app close */
@@ -328,8 +318,64 @@
       {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},   /* busy */
       {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}}    /* mode change retry */
   }
- }
+ },
 
+  /* PANU */
+ {
+  (BTA_DM_PM_SNIFF),                                             /* allow sniff */
+#if (BTM_SSR_INCLUDED == TRUE)
+  (BTA_DM_PM_SSR2),                                              /* the SSR entry */
+#endif
+  {
+      {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn open  active */
+      {{BTA_DM_PM_NO_PREF,   0},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn close  */
+      {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app open */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco open  */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco close   */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
+      {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}}     /* mode change retry */
+  }
+ },
+
+  /* NAP */
+ {
+  (BTA_DM_PM_SNIFF),                                             /* allow sniff */
+#if (BTM_SSR_INCLUDED == TRUE)
+  (BTA_DM_PM_SSR2),                                              /* the SSR entry */
+#endif
+  {
+      {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn open  active */
+      {{BTA_DM_PM_NO_PREF,   0},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn close  */
+      {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app open */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco open  */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco close   */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
+      {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}}     /* mode change retry */
+  }
+ },
+
+  /* HS */
+ {
+  (BTA_DM_PM_SNIFF | BTA_DM_PM_PARK),                           /* allow park & sniff */
+#if (BTM_SSR_INCLUDED == TRUE)
+  (BTA_DM_PM_SSR2),                                              /* the SSR entry */
+#endif
+  {
+      {{BTA_DM_PM_SNIFF,  7000},   {BTA_DM_PM_NO_ACTION, 0}},   /* conn open sniff  */
+      {{BTA_DM_PM_NO_PREF,   0},   {BTA_DM_PM_NO_ACTION, 0}},   /* conn close  */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},   /* app open */
+      {{BTA_DM_PM_NO_ACTION, 0},   {BTA_DM_PM_NO_ACTION, 0}},   /* app close */
+      {{BTA_DM_PM_SNIFF3, 7000},   {BTA_DM_PM_NO_ACTION, 0}},   /* sco open, active */
+      {{BTA_DM_PM_SNIFF,  7000},   {BTA_DM_PM_NO_ACTION, 0}},   /* sco close sniff  */
+      {{BTA_DM_PM_SNIFF,  7000},   {BTA_DM_PM_NO_ACTION, 0}},   /* idle */
+      {{BTA_DM_PM_ACTIVE,    0},   {BTA_DM_PM_NO_ACTION, 0}},   /* busy */
+      {{BTA_DM_PM_RETRY,  7000},   {BTA_DM_PM_NO_ACTION, 0}}    /* mode change retry */
+  }
+ }
 #if BLE_INCLUDED == TRUE
     /* GATTC */
  ,{
@@ -338,13 +384,13 @@
   (BTA_DM_PM_SSR2),                                              /* the SSR entry */
 #endif
   {
-      {{BTA_DM_PM_SNIFF,  10000},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn open  active */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 10000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open  active */
       {{BTA_DM_PM_NO_PREF,    0},   {BTA_DM_PM_NO_ACTION, 0}},    /* conn close  */
       {{BTA_DM_PM_ACTIVE,     0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app open */
       {{BTA_DM_PM_NO_ACTION,  0},   {BTA_DM_PM_NO_ACTION, 0}},    /* app close */
       {{BTA_DM_PM_NO_ACTION,  0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco open  */
       {{BTA_DM_PM_NO_ACTION,  0},   {BTA_DM_PM_NO_ACTION, 0}},    /* sco close   */
-      {{BTA_DM_PM_SNIFF,  10000},   {BTA_DM_PM_NO_ACTION, 0}},    /* idle */
+      {{BTA_DM_PM_SNIFF_A2DP_IDX, 10000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
       {{BTA_DM_PM_ACTIVE,     0},   {BTA_DM_PM_NO_ACTION, 0}},    /* busy */
 #if (AMP_INCLUDED == TRUE)
       {{BTA_DM_PM_NO_ACTION,  0},   {BTA_DM_PM_NO_ACTION, 0}},   /* amp */
@@ -387,21 +433,29 @@
 #endif  /* BTE_SIM_APP */
 };
 
+/* Please refer to the SNIFF table definitions in bta_api.h.
+ *
+ * Adding to or Modifying the Table
+ * Additional sniff parameter entries can be added for BTA_DM_PM_SNIFF5 - BTA_DM_PM_SNIFF7.
+ * Overrides of additional table entries can be specified in bdroid_buildcfg.h.  If additional
+ * sniff parameter entries are added or an override of an existing entry is specified in
+ * bdroid_buildcfg.h then the BTA_DM_PM_*_IDX defines in bta_api.h will need to be match the new
+ * ordering.
+ *
+ * Table Ordering
+ * Sniff Table entries must be ordered from highest latency (biggest interval) to lowest latency.
+ * If there is a conflict among the connected services the setting with the lowest latency will
+ * be selected.
+ */
 tBTA_DM_PM_TYPE_QUALIFIER tBTM_PM_PWR_MD bta_dm_pm_md[] =
 {
-/* more sniff parameter entries can be added for BTA_DM_PM_SNIFF3 - BTA_DM_PM_SNIFF7, if needed
-When entries are added or removed, BTA_DM_PM_PARK_IDX needs to be updated to reflect the actual index
-BTA_DM_PM_PARK_IDX is defined in bta_api.h and can be override by the bdroid_buildcfg.h settings.
-The SNIFF table entries must be in the order from highest latency (biggest interval) to lowest latency.
-If there's a conflict among the connected services, the setting with lowest latency wins.
-*/
 /* sniff modes: max interval, min interval, attempt, timeout */
-  {800, 400, 4, 1, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF - A2DP */
-  {400, 200, 4, 1, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF1 */
-  {180, 150, 4, 1, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF2- HD idle */
-  {150,  50, 4, 1, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF3- SCO open */
-  { 54,  30, 4, 1, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF4- HD active*/
-  {800, 400, 0, 0, BTM_PM_MD_PARK}
+  {BTA_DM_PM_SNIFF_MAX,  BTA_DM_PM_SNIFF_MIN,  BTA_DM_PM_SNIFF_ATTEMPT,  BTA_DM_PM_SNIFF_TIMEOUT,  BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF - A2DP */
+  {BTA_DM_PM_SNIFF1_MAX, BTA_DM_PM_SNIFF1_MIN, BTA_DM_PM_SNIFF1_ATTEMPT, BTA_DM_PM_SNIFF1_TIMEOUT, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF1 */
+  {BTA_DM_PM_SNIFF2_MAX, BTA_DM_PM_SNIFF2_MIN, BTA_DM_PM_SNIFF2_ATTEMPT, BTA_DM_PM_SNIFF2_TIMEOUT, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF2- HD idle */
+  {BTA_DM_PM_SNIFF3_MAX, BTA_DM_PM_SNIFF3_MIN, BTA_DM_PM_SNIFF3_ATTEMPT, BTA_DM_PM_SNIFF3_TIMEOUT, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF3- SCO open */
+  {BTA_DM_PM_SNIFF4_MAX, BTA_DM_PM_SNIFF4_MIN, BTA_DM_PM_SNIFF4_ATTEMPT, BTA_DM_PM_SNIFF4_TIMEOUT, BTM_PM_MD_SNIFF}, /*for BTA_DM_PM_SNIFF4- HD active*/
+  {BTA_DM_PM_PARK_MAX,   BTA_DM_PM_PARK_MIN,   BTA_DM_PM_PARK_ATTEMPT,   BTA_DM_PM_PARK_TIMEOUT,   BTM_PM_MD_PARK}
 
 #ifdef BTE_SIM_APP      /* For Insight builds only */
   /* Entries at the end of the bta_dm_pm_md table are user-defined (runtime configurable),
diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h
index dd3e16c..e54dcff 100644
--- a/bta/dm/bta_dm_int.h
+++ b/bta/dm/bta_dm_int.h
@@ -99,10 +99,30 @@
     BTA_DM_API_BLE_CONN_PARAM_EVT,
     BTA_DM_API_BLE_SCAN_PARAM_EVT,
     BTA_DM_API_BLE_OBSERVE_EVT,
+    BTA_DM_API_UPDATE_CONN_PARAM_EVT,
+#if BLE_PRIVACY_SPT == TRUE
+    BTA_DM_API_LOCAL_PRIVACY_EVT,
+#endif
     BTA_DM_API_BLE_ADV_PARAM_EVT,
     BTA_DM_API_BLE_SET_ADV_CONFIG_EVT,
     BTA_DM_API_BLE_SET_SCAN_RSP_EVT,
     BTA_DM_API_BLE_BROADCAST_EVT,
+
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+    BTA_DM_API_CFG_FILTER_COND_EVT,
+    BTA_DM_API_SCAN_FILTER_SETUP_EVT,
+    BTA_DM_API_SCAN_FILTER_ENABLE_EVT,
+#endif
+    BTA_DM_API_BLE_MULTI_ADV_ENB_EVT,
+    BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT,
+    BTA_DM_API_BLE_MULTI_ADV_DATA_EVT,
+    BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT,
+    BTA_DM_API_BLE_SETUP_STORAGE_EVT,
+    BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT,
+    BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT,
+    BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT,
+    BTA_DM_API_BLE_TRACK_ADVERTISER_EVT,
+    BTA_DM_API_BLE_ENERGY_INFO_EVT,
 #endif
 
 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
@@ -209,6 +229,7 @@
     tBTA_SERVICE_MASK services;
     tBTA_DM_SEARCH_CBACK * p_cback;
     BOOLEAN         sdp_search;
+    tBTA_TRANSPORT  transport;
 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
     UINT8           num_uuid;
     tBT_UUID        *p_uuid;
@@ -231,6 +252,7 @@
 {
     BT_HDR      hdr;
     BD_ADDR bd_addr;
+    tBTA_TRANSPORT transport;
 } tBTA_DM_API_BOND;
 
 /* data type for BTA_DM_API_BOND_CANCEL_EVT */
@@ -238,6 +260,7 @@
 {
     BT_HDR          hdr;
     BD_ADDR         bd_addr;
+    tBTA_TRANSPORT  transport;
 } tBTA_DM_API_BOND_CANCEL;
 
 /* data type for BTA_DM_API_PIN_REPLY_EVT */
@@ -365,6 +388,10 @@
     UINT8           new_role;
     BD_ADDR         bd_addr;
     UINT8           hci_status;
+#if BLE_INCLUDED == TRUE
+    UINT16          handle;
+    tBT_TRANSPORT   transport;
+#endif
 } tBTA_DM_ACL_CHANGE;
 
 /* data type for BTA_DM_PM_BTM_STATUS_EVT */
@@ -424,6 +451,7 @@
 typedef struct
 {
     BT_HDR                    hdr;
+    tBTA_TRANSPORT            transport;
     tBTA_DM_ENCRYPT_CBACK     *p_callback;
     tBTA_DM_BLE_SEC_ACT       sec_act;
     BD_ADDR                   bd_addr;
@@ -526,11 +554,99 @@
 typedef struct
 {
     BT_HDR                  hdr;
+    BOOLEAN                 enable;
+
+}tBTA_DM_API_BLE_FEATURE;
+
+/* multi adv data structure */
+typedef struct
+{
+    BT_HDR                      hdr;
+    tBTA_BLE_MULTI_ADV_CBACK    *p_cback;
+    void                        *p_ref;
+    tBTA_BLE_ADV_PARAMS         *p_params;
+}tBTA_DM_API_BLE_MULTI_ADV_ENB;
+
+typedef struct
+{
+    BT_HDR                      hdr;
+    UINT8                        inst_id;
+    tBTA_BLE_ADV_PARAMS         *p_params;
+}tBTA_DM_API_BLE_MULTI_ADV_PARAM;
+
+typedef struct
+{
+    BT_HDR                  hdr;
+    UINT8                   inst_id;
+    BOOLEAN                 is_scan_rsp;
+    tBTA_BLE_AD_MASK        data_mask;
+    tBTA_BLE_ADV_DATA      *p_data;
+}tBTA_DM_API_BLE_MULTI_ADV_DATA;
+
+typedef struct
+{
+    BT_HDR                  hdr;
+    UINT8                   inst_id;
+}tBTA_DM_API_BLE_MULTI_ADV_DISABLE;
+
+typedef struct
+{
+    BT_HDR                  hdr;
     UINT16                  data_mask;
     tBTA_BLE_ADV_DATA       *p_adv_cfg;
+    tBTA_SET_ADV_DATA_CMPL_CBACK    *p_adv_data_cback;
 }tBTA_DM_API_SET_ADV_CONFIG;
 
-#endif
+typedef struct
+{
+    BT_HDR                  hdr;
+    UINT8                   batch_scan_full_max;
+    UINT8                   batch_scan_trunc_max;
+    UINT8                   batch_scan_notify_threshold;
+    tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback;
+    tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback;
+    tBTA_BLE_SCAN_REP_CBACK *p_read_rep_cback;
+    tBTA_DM_BLE_REF_VALUE    ref_value;
+} tBTA_DM_API_SET_STORAGE_CONFIG;
+
+typedef struct
+{
+    BT_HDR                  hdr;
+    tBTA_BLE_SCAN_MODE      scan_mode;
+    UINT32                  scan_int;
+    UINT32                  scan_window;
+    tBTA_BLE_DISCARD_RULE   discard_rule;
+    tBLE_ADDR_TYPE          addr_type;
+    tBTA_DM_BLE_REF_VALUE   ref_value;
+} tBTA_DM_API_ENABLE_SCAN;
+
+typedef struct
+{
+    BT_HDR                  hdr;
+    tBTA_DM_BLE_REF_VALUE    ref_value;
+} tBTA_DM_API_DISABLE_SCAN;
+
+typedef struct
+{
+    BT_HDR                  hdr;
+    tBTA_BLE_SCAN_MODE scan_type;
+    tBTA_DM_BLE_REF_VALUE    ref_value;
+} tBTA_DM_API_READ_SCAN_REPORTS;
+
+typedef struct
+{
+    BT_HDR                  hdr;
+    tBTA_DM_BLE_REF_VALUE ref_value;
+    tBTA_BLE_TRACK_ADV_CBACK *p_track_adv_cback;
+} tBTA_DM_API_TRACK_ADVERTISER;
+
+typedef struct
+{
+    BT_HDR                  hdr;
+    tBTA_BLE_ENERGY_INFO_CBACK *p_energy_info_cback;
+} tBTA_DM_API_ENERGY_INFO;
+
+#endif /* BLE_INCLUDED */
 
 typedef struct
 {
@@ -563,7 +679,50 @@
     BT_HDR      hdr;
     BD_ADDR     bd_addr;
     BOOLEAN     remove_dev;
+    tBTA_TRANSPORT transport;
+
 }tBTA_DM_API_REMOVE_ACL;
+typedef struct
+{
+    BT_HDR      hdr;
+    BD_ADDR     bd_addr;
+    UINT16      min_int;
+    UINT16      max_int;
+    UINT16      latency;
+    UINT16      timeout;
+}tBTA_DM_API_UPDATE_CONN_PARAM;
+
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+typedef struct
+{
+    BT_HDR                          hdr;
+    tBTA_DM_BLE_SCAN_COND_OP        action;
+    tBTA_DM_BLE_PF_COND_TYPE        cond_type;
+    tBTA_DM_BLE_PF_FILT_INDEX       filt_index;
+    tBTA_DM_BLE_PF_COND_PARAM       *p_cond_param;
+    tBTA_DM_BLE_PF_CFG_CBACK      *p_filt_cfg_cback;
+    tBTA_DM_BLE_REF_VALUE            ref_value;
+}tBTA_DM_API_CFG_FILTER_COND;
+
+typedef struct
+{
+    BT_HDR                          hdr;
+    UINT8                           action;
+    tBTA_DM_BLE_PF_STATUS_CBACK    *p_filt_status_cback;
+    tBTA_DM_BLE_REF_VALUE            ref_value;
+}tBTA_DM_API_ENABLE_SCAN_FILTER;
+
+typedef struct
+{
+    BT_HDR                          hdr;
+    UINT8                           action;
+    tBTA_DM_BLE_PF_FILT_INDEX       filt_index;
+    tBTA_DM_BLE_PF_FILT_PARAMS      *p_filt_params;
+    tBLE_BD_ADDR                    *p_target;
+    tBTA_DM_BLE_PF_PARAM_CBACK      *p_filt_param_cback;
+    tBTA_DM_BLE_REF_VALUE            ref_value;
+}tBTA_DM_API_SCAN_FILTER_PARAM_SETUP;
+#endif
 
 /* union of all data types */
 typedef union
@@ -640,6 +799,23 @@
     tBTA_DM_API_LOCAL_PRIVACY           ble_local_privacy;
     tBTA_DM_API_BLE_ADV_PARAMS          ble_set_adv_params;
     tBTA_DM_API_SET_ADV_CONFIG          ble_set_adv_data;
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+    tBTA_DM_API_SCAN_FILTER_PARAM_SETUP ble_scan_filt_param_setup;
+    tBTA_DM_API_CFG_FILTER_COND         ble_cfg_filter_cond;
+    tBTA_DM_API_ENABLE_SCAN_FILTER      ble_enable_scan_filt;
+#endif
+    tBTA_DM_API_UPDATE_CONN_PARAM       ble_update_conn_params;
+    tBTA_DM_API_BLE_MULTI_ADV_ENB       ble_multi_adv_enb;
+    tBTA_DM_API_BLE_MULTI_ADV_PARAM     ble_multi_adv_param;
+    tBTA_DM_API_BLE_MULTI_ADV_DATA      ble_multi_adv_data;
+    tBTA_DM_API_BLE_MULTI_ADV_DISABLE   ble_multi_adv_disable;
+
+    tBTA_DM_API_SET_STORAGE_CONFIG      ble_set_storage;
+    tBTA_DM_API_ENABLE_SCAN             ble_enable_scan;
+    tBTA_DM_API_READ_SCAN_REPORTS       ble_read_reports;
+    tBTA_DM_API_DISABLE_SCAN            ble_disable_scan;
+    tBTA_DM_API_TRACK_ADVERTISER        ble_track_advert;
+    tBTA_DM_API_ENERGY_INFO             ble_energy_info;
 #endif
 
     tBTA_DM_API_SET_AFH_CHANNEL_ASSESSMENT set_afh_channel_assessment;
@@ -679,13 +855,15 @@
     tBTA_PREF_ROLES             pref_role;
     BOOLEAN                     in_use;
     tBTA_DM_DEV_INFO            info;
+    tBTA_DM_ENCRYPT_CBACK      *p_encrypt_cback;
 #if (BTM_SSR_INCLUDED == TRUE)
     tBTM_PM_STATUS              prev_low;   /* previous low power mode used */
 #endif
     tBTA_DM_PM_ACTTION          pm_mode_attempted;
     tBTA_DM_PM_ACTTION          pm_mode_failed;
     BOOLEAN                     remove_dev_pending;
-
+    UINT16                      conn_handle;
+    tBT_TRANSPORT               transport;
 } tBTA_DM_PEER_DEVICE;
 
 
@@ -696,7 +874,9 @@
 {
     tBTA_DM_PEER_DEVICE    peer_device[BTA_DM_NUM_PEER_DEVICE];
     UINT8                  count;
-
+#if BLE_INCLUDED == TRUE
+    UINT8                  le_count;
+#endif
 } tBTA_DM_ACTIVE_LINK;
 
 
@@ -738,6 +918,14 @@
     BOOLEAN                     is_bta_dm_active;
     tBTA_DM_ACTIVE_LINK         device_list;
     tBTA_DM_SEC_CBACK           *p_sec_cback;
+#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
+    tBTA_BLE_SCAN_SETUP_CBACK   *p_setup_cback;
+    tBTA_DM_BLE_PF_CFG_CBACK     *p_scan_filt_cfg_cback;
+    tBTA_DM_BLE_PF_STATUS_CBACK  *p_scan_filt_status_cback;
+    tBTA_DM_BLE_PF_PARAM_CBACK   *p_scan_filt_param_cback;
+    tBTA_BLE_MULTI_ADV_CBACK     *p_multi_adv_cback;
+    tBTA_BLE_ENERGY_INFO_CBACK   *p_energy_info_cback;
+#endif
     TIMER_LIST_ENT              signal_strength_timer;
     tBTA_SIG_STRENGTH_MASK      signal_strength_mask;
     UINT16                      state;
@@ -777,8 +965,6 @@
 
 #endif
 
-    tBTA_DM_ENCRYPT_CBACK      *p_encrypt_cback;
-    tBTA_DM_BLE_SEC_ACT         sec_act;
     TIMER_LIST_ENT              switch_delay_timer;
 
 } tBTA_DM_CB;
@@ -809,7 +995,7 @@
     tSDP_UUID              uuid;
     UINT8                  peer_scn;
     BOOLEAN                sdp_search;
-
+    tBTA_TRANSPORT         transport;
 #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
     tBTA_DM_SEARCH_CBACK * p_scan_cback;
 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
@@ -996,11 +1182,30 @@
 extern void bta_dm_ble_set_scan_params (tBTA_DM_MSG *p_data);
 extern void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_observe (tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data);
 
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data);
+extern void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data);
+extern void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data);
+#endif
+extern void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data);
+
+extern void bta_dm_ble_setup_storage(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_enable_batch_scan(tBTA_DM_MSG * p_data);
+extern void bta_dm_ble_disable_batch_scan(tBTA_DM_MSG * p_data);
+extern void bta_dm_ble_read_scan_reports(tBTA_DM_MSG * p_data);
+extern void bta_dm_ble_track_advertiser(tBTA_DM_MSG * p_data);
+extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data);
+
 #endif
 extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
 extern void bta_dm_confirm(tBTA_DM_MSG *p_data);
@@ -1035,6 +1240,8 @@
 extern void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data);
 extern tBTA_DM_PEER_DEVICE * bta_dm_find_peer_device(BD_ADDR peer_addr);
 
+extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data);
+
 extern void bta_dm_pm_active(BD_ADDR peer_addr);
 
 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )
diff --git a/bta/dm/bta_dm_main.c b/bta/dm/bta_dm_main.c
index 0f6b91a..35835c7 100644
--- a/bta/dm/bta_dm_main.c
+++ b/bta/dm/bta_dm_main.c
@@ -96,10 +96,29 @@
     bta_dm_ble_set_conn_params,      /* BTA_DM_API_BLE_CONN_PARAM_EVT */
     bta_dm_ble_set_scan_params,      /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
     bta_dm_ble_observe,
+    bta_dm_ble_update_conn_params,   /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */
+#if BLE_PRIVACY_SPT == TRUE
+    bta_dm_ble_config_local_privacy,   /* BTA_DM_API_LOCAL_PRIVACY_EVT */
+#endif
     bta_dm_ble_set_adv_params,     /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
     bta_dm_ble_set_adv_config,     /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */
     bta_dm_ble_set_scan_rsp,       /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */
     bta_dm_ble_broadcast,          /* BTA_DM_API_BLE_BROADCAST_EVT */
+#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
+    bta_dm_cfg_filter_cond,         /* BTA_DM_API_CFG_FILTER_COND_EVT */
+    bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */
+    bta_dm_enable_scan_filter,      /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */
+#endif
+    bta_dm_ble_multi_adv_enb,           /*  BTA_DM_API_BLE_MULTI_ADV_ENB_EVT*/
+    bta_dm_ble_multi_adv_upd_param,     /*  BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */
+    bta_dm_ble_multi_adv_data,          /*  BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */
+    btm_dm_ble_multi_adv_disable,       /*  BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */
+    bta_dm_ble_setup_storage,      /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */
+    bta_dm_ble_enable_batch_scan,  /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */
+    bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */
+    bta_dm_ble_read_scan_reports,  /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */
+    bta_dm_ble_track_advertiser,   /* BTA_DM_API_BLE_TRACK_ADVERTISER_EVT */
+    bta_dm_ble_get_energy_info,    /* BTA_DM_API_BLE_ENERGY_INFO_EVT */
 #endif
 
 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
@@ -300,7 +319,7 @@
 {
     UINT16  event = p_msg->event & 0x00ff;
 
-    APPL_TRACE_EVENT1("bta_dm_sm_execute event:0x%x", event);
+    APPL_TRACE_EVENT("bta_dm_sm_execute event:0x%x", event);
 
     /* execute action functions */
     if(event < BTA_DM_NUM_ACTIONS)
@@ -344,7 +363,7 @@
     UINT8               action;
     int                 i;
 
-    APPL_TRACE_EVENT2("bta_dm_search_sm_execute state:%d, event:0x%x",
+    APPL_TRACE_EVENT("bta_dm_search_sm_execute state:%d, event:0x%x",
         bta_dm_search_cb.state, p_msg->event);
 
     /* look up the state table for the current state */
diff --git a/bta/dm/bta_dm_pm.c b/bta/dm/bta_dm_pm.c
index 7008498..6bf1697 100644
--- a/bta/dm/bta_dm_pm.c
+++ b/bta/dm/bta_dm_pm.c
@@ -31,8 +31,6 @@
 #include "btm_api.h"
 
 #include <string.h>
-#include <cutils/properties.h>
-#include <utils/Log.h>
 
 
 static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
@@ -107,7 +105,7 @@
     {
         if(bta_dm_cb.pm_timer[i].in_use)
         {
-            APPL_TRACE_DEBUG1("stop dm_pm_timer:%d", i);
+            APPL_TRACE_DEBUG("stop dm_pm_timer:%d", i);
             bta_sys_stop_timer(&bta_dm_cb.pm_timer[i].timer);
             bta_dm_cb.pm_timer[i].in_use = FALSE;
         }
@@ -133,7 +131,7 @@
 
         if(bta_dm_cb.pm_timer[i].in_use && !bdcmp(bta_dm_cb.pm_timer[i].peer_bdaddr, peer_addr))
         {
-            APPL_TRACE_DEBUG1("stop dm_pm_timer:%d", i);
+            APPL_TRACE_DEBUG("stop dm_pm_timer:%d", i);
             bta_sys_stop_timer(&bta_dm_cb.pm_timer[i].timer);
             bta_dm_cb.pm_timer[i].in_use = FALSE;
             break;
@@ -164,7 +162,7 @@
 #endif
     tBTA_DM_PEER_DEVICE *p_dev;
 
-    APPL_TRACE_DEBUG3("bta_dm_pm_cback: st(%d), id(%d), app(%d)", status, id, app_id);
+    APPL_TRACE_DEBUG("bta_dm_pm_cback: st(%d), id(%d), app(%d)", status, id, app_id);
 
     btm_status = BTM_ReadLocalVersion (&vers);
     p_dev = bta_dm_find_peer_device(peer_addr);
@@ -243,7 +241,7 @@
         }
         else
         {
-            APPL_TRACE_WARNING0("bta_dm_act no entry for connected service cbs");
+            APPL_TRACE_WARNING("bta_dm_act no entry for connected service cbs");
             return;
         }
     }
@@ -252,7 +250,7 @@
         /* check if we have more connected service that cbs */
         if(bta_dm_conn_srvcs.count == BTA_DM_NUM_CONN_SRVS)
         {
-            APPL_TRACE_WARNING0("bta_dm_act no more connected service cbs");
+            APPL_TRACE_WARNING("bta_dm_act no more connected service cbs");
             return;
         }
 
@@ -261,7 +259,7 @@
         bta_dm_conn_srvcs.conn_srvc[j].app_id = app_id;
         bdcpy(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, peer_addr);
 
-        APPL_TRACE_WARNING2("new conn_srvc id:%d, app_id:%d", id, app_id);
+        APPL_TRACE_WARNING("new conn_srvc id:%d, app_id:%d", id, app_id);
 
         bta_dm_conn_srvcs.count++;
         bta_dm_conn_srvcs.conn_srvc[j].state = status;
@@ -336,8 +334,6 @@
     tBTA_DM_PM_SPEC     *p_pm_spec;
     tBTA_DM_PM_ACTN     *p_act0, *p_act1;
     tBTA_DM_SRVCS       *p_srvcs;
-    char buf[PROPERTY_VALUE_MAX];
-    int len = 0, temp = 0;
 
 
     if(!bta_dm_cb.device_list.count)
@@ -372,7 +368,7 @@
             p_act0 = &p_pm_spec->actn_tbl[p_srvcs->state][0];
             p_act1 = &p_pm_spec->actn_tbl[p_srvcs->state][1];
 
-            APPL_TRACE_DEBUG3("bta_dm_pm_set_mode: srvcsid: %d, state: %d, j: %d", p_srvcs->id, p_srvcs->state, j);
+            APPL_TRACE_DEBUG("bta_dm_pm_set_mode: srvcsid: %d, state: %d, j: %d", p_srvcs->id, p_srvcs->state, j);
             allowed_modes |= p_pm_spec->allow_mask;
 
             /* PM actions are in the order of strictness */
@@ -436,14 +432,8 @@
                 bta_dm_cb.pm_timer[i].in_use = TRUE;
                 bdcpy(bta_dm_cb.pm_timer[i].peer_bdaddr, peer_addr);
                 bta_dm_cb.pm_timer[i].timer.p_cback = bta_dm_pm_timer_cback;
-                len = property_get("bluetooth.force_pm_timer", buf, NULL);
-                if(len > 0)
-                {
-                    sscanf(buf, "%d", &temp);
-                    timeout = temp;
-                }
                 bta_sys_start_timer(&bta_dm_cb.pm_timer[i].timer, 0, timeout);
-                APPL_TRACE_DEBUG2("start dm_pm_timer:%d, %d", i, timeout);
+                APPL_TRACE_DEBUG("start dm_pm_timer:%d, %d", i, timeout);
                 return;
 
             }
@@ -453,7 +443,7 @@
         /* no more timers */
         if(i==BTA_DM_NUM_PM_TIMER)
         {
-            APPL_TRACE_WARNING0("bta_dm_act dm_pm_timer no more");
+            APPL_TRACE_WARNING("bta_dm_act dm_pm_timer no more");
             return;
         }
     }
@@ -479,7 +469,7 @@
         }
         else
         {
-            APPL_TRACE_DEBUG0("bta_dm_pm_set_mode: Link policy disallows SNIFF, ignore request");
+            APPL_TRACE_DEBUG("bta_dm_pm_set_mode: Link policy disallows SNIFF, ignore request");
         }
     }
     else if(pm_action == BTA_DM_PM_ACTIVE)
@@ -539,13 +529,13 @@
     BTM_ReadPowerMode(p_peer_dev->peer_bdaddr, &mode);
 
 #if (BTM_SSR_INCLUDED == TRUE)
-    APPL_TRACE_DEBUG3("bta_dm_pm_sniff cur:%d, idx:%d, info:x%x", mode, index, p_peer_dev->info);
+    APPL_TRACE_DEBUG("bta_dm_pm_sniff cur:%d, idx:%d, info:x%x", mode, index, p_peer_dev->info);
     if (mode != BTM_PM_MD_SNIFF ||
         (HCI_SNIFF_SUB_RATE_SUPPORTED(BTM_ReadLocalFeatures ()) &&
          HCI_SNIFF_SUB_RATE_SUPPORTED(BTM_ReadRemoteFeatures (p_peer_dev->peer_bdaddr)) &&
          !(p_peer_dev->info & BTA_DM_DI_USE_SSR)))
 #else
-    APPL_TRACE_DEBUG2("bta_dm_pm_sniff cur:%d, idx:%d", mode, index);
+    APPL_TRACE_DEBUG("bta_dm_pm_sniff cur:%d, idx:%d", mode, index);
     if(mode != BTM_PM_MD_SNIFF)
 #endif
     {
@@ -564,12 +554,12 @@
         }
         else if (status == BTM_SUCCESS)
         {
-            APPL_TRACE_DEBUG0("bta_dm_pm_sniff BTM_SetPowerMode() returns BTM_SUCCESS");
+            APPL_TRACE_DEBUG("bta_dm_pm_sniff BTM_SetPowerMode() returns BTM_SUCCESS");
             p_peer_dev->info &= ~(BTA_DM_DI_INT_SNIFF|BTA_DM_DI_ACP_SNIFF|BTA_DM_DI_SET_SNIFF);
         }
         else /* error */
         {
-            APPL_TRACE_ERROR1("bta_dm_pm_sniff BTM_SetPowerMode() returns ERROR status=%d", status);
+            APPL_TRACE_ERROR("bta_dm_pm_sniff BTM_SetPowerMode() returns ERROR status=%d", status);
             p_peer_dev->info &= ~(BTA_DM_DI_INT_SNIFF|BTA_DM_DI_ACP_SNIFF|BTA_DM_DI_SET_SNIFF);
         }
     }
@@ -607,7 +597,7 @@
                     && ((p_bta_dm_pm_cfg[j].app_id == BTA_ALL_APP_ID )
                     || (p_bta_dm_pm_cfg[j].app_id == bta_dm_conn_srvcs.conn_srvc[i].app_id)))
                 {
-                    APPL_TRACE_WARNING2("bta_dm_pm_ssr conn_srvc id:%d, app_id:%d",
+                    APPL_TRACE_WARNING("bta_dm_pm_ssr conn_srvc id:%d, app_id:%d",
                         bta_dm_conn_srvcs.conn_srvc[i].id, bta_dm_conn_srvcs.conn_srvc[i].app_id);
                     break;
                 }
@@ -635,7 +625,7 @@
     }
 
     p_spec = &p_bta_dm_ssr_spec[ssr];
-    APPL_TRACE_WARNING2("bta_dm_pm_ssr:%d, lat:%d", ssr, p_spec->max_lat);
+    APPL_TRACE_WARNING("bta_dm_pm_ssr:%d, lat:%d", ssr, p_spec->max_lat);
     if(p_spec->max_lat)
     {
         /* set the SSR parameters. */
@@ -708,7 +698,7 @@
     tBTA_DM_PM_TIMER  *p_buf;
     UINT8 i;
 
-    APPL_TRACE_WARNING0("dm_pm_timer expires");
+    APPL_TRACE_WARNING("dm_pm_timer expires");
 
     for(i=0; i<BTA_DM_NUM_PM_TIMER; i++)
     {
@@ -718,7 +708,7 @@
 
             if(&bta_dm_cb.pm_timer[i].timer == (TIMER_LIST_ENT*) p_tle)
             {
-                APPL_TRACE_WARNING1("dm_pm_timer expires %d", i);
+                APPL_TRACE_WARNING("dm_pm_timer expires %d", i);
                 bta_dm_cb.pm_timer[i].in_use = FALSE;
                 break;
             }
@@ -758,7 +748,7 @@
     tBTA_DM_PEER_DEVICE *p_dev;
     tBTA_DM_DEV_INFO    info;
 
-    APPL_TRACE_DEBUG1("bta_dm_pm_btm_status:%d", p_data->pm_status.status);
+    APPL_TRACE_DEBUG("bta_dm_pm_btm_status:%d", p_data->pm_status.status);
     p_dev = bta_dm_find_peer_device(p_data->pm_status.bd_addr);
     if(NULL == p_dev)
         return;
@@ -772,7 +762,7 @@
             we should not try it again*/
             if (p_data->pm_status.hci_status != 0)
             {
-                APPL_TRACE_ERROR1("bta_dm_pm_btm_status  hci_status=%d", p_data->pm_status.hci_status);
+                APPL_TRACE_ERROR("bta_dm_pm_btm_status  hci_status=%d", p_data->pm_status.hci_status);
                 p_dev->info &= ~(BTA_DM_DI_INT_SNIFF|BTA_DM_DI_ACP_SNIFF|BTA_DM_DI_SET_SNIFF);
 
                 if(p_dev->pm_mode_attempted &(BTA_DM_PM_PARK | BTA_DM_PM_SNIFF))
@@ -816,6 +806,16 @@
             break;
 #endif
         case BTM_PM_STS_SNIFF:
+            if (p_data->pm_status.hci_status == 0)
+            {
+                /* Stop PM timer now if already active for
+                 * particular device since link is already
+                 * put in sniff mode by remote device, and
+                 * PM timer sole purpose is to put the link
+                 * in sniff mode from host side.
+                 */
+                bta_dm_pm_stop_timer(p_data->pm_status.bd_addr);
+            }
             p_dev->info &= ~(BTA_DM_DI_SET_SNIFF|BTA_DM_DI_INT_SNIFF|BTA_DM_DI_ACP_SNIFF);
             if (info & BTA_DM_DI_SET_SNIFF)
                 p_dev->info |= BTA_DM_DI_INT_SNIFF;
@@ -848,7 +848,7 @@
 void bta_dm_pm_timer(tBTA_DM_MSG *p_data)
 {
 
-    APPL_TRACE_WARNING0("proc dm_pm_timer expires");
+    APPL_TRACE_WARNING("proc dm_pm_timer expires");
     bta_dm_pm_set_mode(p_data->pm_status.bd_addr, TRUE);
 
 
@@ -904,7 +904,7 @@
         }
     }
 
-    APPL_TRACE_DEBUG1("bta_dm_is_sco_active: SCO active: %d", bScoActive);
+    APPL_TRACE_DEBUG("bta_dm_is_sco_active: SCO active: %d", bScoActive);
     return bScoActive;
 }
 
@@ -929,7 +929,7 @@
         /* check if an entry already present */
         if(bta_dm_conn_srvcs.conn_srvc[j].id == BTA_ID_HH )
         {
-            APPL_TRACE_DEBUG2 ("SCO status change(Active: %d), modify HID link policy. state: %d",
+            APPL_TRACE_DEBUG ("SCO status change(Active: %d), modify HID link policy. state: %d",
                 bScoActive, bta_dm_conn_srvcs.conn_srvc[j].state);
             bta_dm_pm_set_sniff_policy( bta_dm_find_peer_device(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr), bScoActive);
 
@@ -980,3 +980,26 @@
     BTM_SetLinkPolicy(p_dev->peer_bdaddr, &policy_setting);
 
 }
+
+#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** Function         bta_dm_pm_obtain_controller_state
+**
+** Description      This function obtains the consolidated controller power state
+**
+** Parameters:
+**
+*******************************************************************************/
+tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void)
+{
+    /*   Did not use counts as it is not sure, how accurate the count values are in
+     **  bta_dm_cb.device_list.count > 0 || bta_dm_cb.device_list.le_count > 0 */
+
+    tBTA_DM_CONTRL_STATE cur_state = BTA_DM_CONTRL_UNKNOWN;
+    cur_state = BTM_PM_ReadControllerState();
+
+    APPL_TRACE_DEBUG("bta_dm_pm_obtain_controller_state: %d", cur_state);
+    return cur_state;
+}
+#endif
diff --git a/bta/dm/bta_dm_sco.c b/bta/dm/bta_dm_sco.c
index 803242b..109140a 100644
--- a/bta/dm/bta_dm_sco.c
+++ b/bta/dm/bta_dm_sco.c
@@ -247,7 +247,7 @@
     SRC_TYPE        *pOv, *pOvEnd;
     INT16           *psBtOut = (INT16 *)pDst;
 #if BTA_DM_SCO_DEBUG
-    APPL_TRACE_DEBUG1("Convert_8M_ToBT_Filtered,  CurrentPos %d\n", CurrentPos);
+    APPL_TRACE_DEBUG("Convert_8M_ToBT_Filtered,  CurrentPos %d\n", CurrentPos);
 #endif
     memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
 
@@ -411,7 +411,7 @@
     INT16           *psBtOut = (INT16 *)pDst;
 
 #if BTA_DM_SCO_DEBUG
-    APPL_TRACE_DEBUG5("Convert_8S_ToBT_Filtered CurrentPos %d, SRC_TYPE %d, SRC_CHANNELS %d, \
+    APPL_TRACE_DEBUG("Convert_8S_ToBT_Filtered CurrentPos %d, SRC_TYPE %d, SRC_CHANNELS %d, \
         dwSrcSamples %d,  dwSrcSps %d",  	CurrentPos, sizeof (SRC_TYPE), SRC_CHANNELS, \
         dwSrcSamples, dwSrcSps);
 #endif
@@ -608,7 +608,7 @@
          p_cb->can_be_filtered = 0;
 
 #if BTA_DM_SCO_DEBUG
-    APPL_TRACE_DEBUG2("bta_dm_pcm_init_samples: n_channels = %d bits = %d", n_channels, bits);
+    APPL_TRACE_DEBUG("bta_dm_pcm_init_samples: n_channels = %d bits = %d", n_channels, bits);
 #endif
     if(n_channels == 1)
     {
@@ -642,11 +642,11 @@
     }
 
 #if BTA_DM_SCO_DEBUG
-    APPL_TRACE_DEBUG2("bta_pcm_init_dwn_sample: cur_pos %d, src_sps %d", \
+    APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: cur_pos %d, src_sps %d", \
 		p_cb->cur_pos, p_cb->src_sps);
-    APPL_TRACE_DEBUG3("bta_pcm_init_dwn_sample: bits %d, n_channels %d, sample_size %d, ", \
+    APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: bits %d, n_channels %d, sample_size %d, ", \
 		p_cb->bits, p_cb->n_channels, p_cb->sample_size);
-    APPL_TRACE_DEBUG3("bta_pcm_init_dwn_sample: can_be_filtered %d, n_channels: %d, \
+    APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: can_be_filtered %d, n_channels: %d, \
         divisor %d", p_cb->can_be_filtered, p_cb->n_channels, p_cb->divisor);
 #endif
 
@@ -673,7 +673,7 @@
     UINT32 out_sample;
 
 #if BTA_DM_SCO_DEBUG
-    APPL_TRACE_DEBUG1("bta_pcm_resample : insamples  %d",  (in_bytes  / bta_dm_pcm_cb.divisor));
+    APPL_TRACE_DEBUG("bta_pcm_resample : insamples  %d",  (in_bytes  / bta_dm_pcm_cb.divisor));
 #endif
     if(bta_dm_pcm_cb.can_be_filtered)
     {
@@ -687,7 +687,7 @@
     }
 
 #if BTA_DM_SCO_DEBUG
-    APPL_TRACE_DEBUG1("bta_pcm_resample : outsamples  %d",  out_sample);
+    APPL_TRACE_DEBUG("bta_pcm_resample : outsamples  %d",  out_sample);
 #endif
 
     return (out_sample * bta_dm_pcm_cb.sample_size);
diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c
old mode 100644
new mode 100755
index 44f88e4..546a56f
--- a/bta/gatt/bta_gattc_act.c
+++ b/bta/gatt/bta_gattc_act.c
@@ -45,14 +45,15 @@
 **  Constants
 *****************************************************************************/
 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
-                                 BOOLEAN connected, tGATT_DISCONN_REASON reason);
+                                 BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                 tBT_TRANSPORT transport);
 
 static void  bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
                                   tGATT_CL_COMPLETE *p_data);
 
 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg);
-
 static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
+static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested);
 
 static tGATT_CBACK bta_gattc_cl_cback =
 {
@@ -61,7 +62,8 @@
     bta_gattc_disc_res_cback,
     bta_gattc_disc_cmpl_cback,
     NULL,
-    bta_gattc_enc_cmpl_cback
+    bta_gattc_enc_cmpl_cback,
+    bta_gattc_cong_cback
 };
 
 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
@@ -102,7 +104,7 @@
 *******************************************************************************/
 static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
 {
-    APPL_TRACE_DEBUG0("bta_gattc_enable");
+    APPL_TRACE_DEBUG("bta_gattc_enable");
 
     if (p_cb->state == BTA_GATTC_STATE_DISABLED)
     {
@@ -112,7 +114,7 @@
     }
     else
     {
-        APPL_TRACE_DEBUG0("GATTC is arelady enabled");
+        APPL_TRACE_DEBUG("GATTC is arelady enabled");
     }
 }
 
@@ -131,11 +133,11 @@
 {
     UINT8           i;
 
-    APPL_TRACE_DEBUG0("bta_gattc_disable");
+    APPL_TRACE_DEBUG("bta_gattc_disable");
 
     if (p_cb->state != BTA_GATTC_STATE_ENABLED)
     {
-        APPL_TRACE_ERROR0("not enabled or disable in pogress");
+        APPL_TRACE_ERROR("not enabled or disable in pogress");
         return;
     }
 
@@ -182,7 +184,7 @@
     tBTA_GATT_STATUS         status = BTA_GATT_NO_RESOURCES;
 
 
-    APPL_TRACE_DEBUG1("bta_gattc_register state %d",p_cb->state);
+    APPL_TRACE_DEBUG("bta_gattc_register state %d",p_cb->state);
     memset(&cb_data, 0, sizeof(cb_data));
     cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES;
 
@@ -198,7 +200,7 @@
         {
             if ((p_app_uuid == NULL) || (p_cb->cl_rcb[i].client_if = GATT_Register(p_app_uuid, &bta_gattc_cl_cback)) == 0)
             {
-                APPL_TRACE_ERROR0("Register with GATT stack failed.");
+                APPL_TRACE_ERROR("Register with GATT stack failed.");
                 status = BTA_GATT_ERROR;
             }
             else
@@ -259,7 +261,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.client_if );
+        APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.client_if );
     }
 }
 /*******************************************************************************
@@ -315,7 +317,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR0("bta_gattc_deregister Deregister Failedm unknown client cif");
+        APPL_TRACE_ERROR("bta_gattc_deregister Deregister Failedm unknown client cif");
     }
 }
 /*******************************************************************************
@@ -339,19 +341,20 @@
         if (p_msg->api_conn.is_direct)
         {
             if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
-                                                    p_msg->api_conn.remote_bda)) != NULL)
+                                                    p_msg->api_conn.remote_bda,
+                                                    p_msg->api_conn.transport)) != NULL)
             {
                 bta_gattc_sm_execute(p_clcb, event, p_msg);
             }
             else
             {
-                APPL_TRACE_ERROR0("No resources to open a new connection.");
+                APPL_TRACE_ERROR("No resources to open a new connection.");
 
                 bta_gattc_send_open_cback(p_clreg,
                                           BTA_GATT_NO_RESOURCES,
                                           p_msg->api_conn.remote_bda,
                                           BTA_GATT_INVALID_CONN_ID,
-                                          0);
+                                          p_msg->api_conn.transport, 0);
             }
         }
         else
@@ -361,7 +364,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("bta_gattc_process_api_open Failed, unknown client_if: %d",
+        APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
                         p_msg->api_conn.client_if);
     }
 }
@@ -385,13 +388,14 @@
     if (p_msg->api_cancel_conn.is_direct)
     {
         if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
-                                                 p_msg->api_cancel_conn.remote_bda)) != NULL)
+                                                 p_msg->api_cancel_conn.remote_bda,
+                                                 BTA_GATT_TRANSPORT_LE)) != NULL)
         {
             bta_gattc_sm_execute(p_clcb, event, p_msg);
         }
         else
         {
-            APPL_TRACE_ERROR0("No such connection need to be cancelled");
+            APPL_TRACE_ERROR("No such connection need to be cancelled");
 
             p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if);
 
@@ -470,12 +474,13 @@
 {
     UNUSED(p_data);
 
-    APPL_TRACE_ERROR0("Connection already opened. wrong state");
+    APPL_TRACE_ERROR("Connection already opened. wrong state");
 
     bta_gattc_send_open_cback(p_clcb->p_rcb,
                               BTA_GATT_OK,
                               p_clcb->bda,
                               p_clcb->bta_conn_id,
+                              p_clcb->transport,
                               0);
 }
 /*******************************************************************************
@@ -495,8 +500,8 @@
                               BTA_GATT_ERROR,
                               p_clcb->bda,
                               p_clcb->bta_conn_id,
+                              p_clcb->transport,
                               0);
-
     /* open failure, remove clcb */
     bta_gattc_clcb_dealloc(p_clcb);
 }
@@ -515,9 +520,10 @@
     tBTA_GATTC_DATA gattc_data;
 
     /* open/hold a connection */
-    if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, TRUE))
+    if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
+                      TRUE, p_data->api_conn.transport))
     {
-        APPL_TRACE_ERROR0("Connection open failure");
+        APPL_TRACE_ERROR("Connection open failure");
 
         bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data);
     }
@@ -526,7 +532,8 @@
         /* a connected remote device */
         if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
                                       p_data->api_conn.remote_bda,
-                                      &p_clcb->bta_conn_id))
+                                      &p_clcb->bta_conn_id,
+                                      p_data->api_conn.transport))
         {
             gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
 
@@ -553,11 +560,11 @@
 
     if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE))
     {
-        /* alwaya call open to hold a connection */
-        if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE))
+        /* always call open to hold a connection */
+        if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport))
         {
             status = BTA_GATT_ERROR;
-            APPL_TRACE_ERROR0("bta_gattc_init_bk_conn failed");
+            APPL_TRACE_ERROR("bta_gattc_init_bk_conn failed");
         }
         else
         {
@@ -566,9 +573,11 @@
             /* if is a connected remote device */
             if (GATT_GetConnIdIfConnected(p_data->client_if,
                                           p_data->remote_bda,
-                                          &conn_id))
+                                          &conn_id,
+                                          p_data->transport))
             {
-                if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda)) != NULL)
+                if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda,
+                    BTA_GATT_TRANSPORT_LE)) != NULL)
                 {
                     gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
 
@@ -583,7 +592,8 @@
     /* open failure, report OPEN_EVT */
     if (status != BTA_GATT_OK)
     {
-        bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda, BTA_GATT_INVALID_CONN_ID, 0);
+        bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
+        BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
     }
 }
 /*******************************************************************************
@@ -610,7 +620,7 @@
         }
         else
         {
-            APPL_TRACE_ERROR0("bta_gattc_cancel_bk_conn failed");
+            APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
         }
     }
     p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
@@ -681,13 +691,15 @@
 void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 {
     tBTA_GATTC_IF   gatt_if;
-    APPL_TRACE_DEBUG1("bta_gattc_conn server cache state=%d",p_clcb->p_srcb->state);
+    APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d",p_clcb->p_srcb->state);
 
     if (p_data != NULL)
     {
-        APPL_TRACE_DEBUG1("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific);
+        APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific);
         p_clcb->bta_conn_id  = p_data->int_conn.hdr.layer_specific;
-        GATT_GetConnectionInfor(p_data->int_conn.hdr.layer_specific, &gatt_if, p_clcb->bda);
+
+        GATT_GetConnectionInfor(p_data->hdr.layer_specific,
+                                &gatt_if, p_clcb->bda, &p_clcb->transport);
     }
 
         p_clcb->p_srcb->connected = TRUE;
@@ -721,14 +733,16 @@
 
         if (p_clcb->p_rcb)
         {
-            /* there is no RM for GATT */
-            if (!BTM_IsBleLink(p_clcb->bda))
-                bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
-            bta_gattc_send_open_cback(p_clcb->p_rcb,
-                                      BTA_GATT_OK,
-                                      p_clcb->bda,
-                                      p_clcb->bta_conn_id,
-                                      p_clcb->p_srcb->mtu);
+        /* there is no RM for GATT */
+        if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
+            bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+
+        bta_gattc_send_open_cback(p_clcb->p_rcb,
+                                  BTA_GATT_OK,
+                                  p_clcb->bda,
+                                  p_clcb->bta_conn_id,
+                                  p_clcb->transport,
+                                  p_clcb->p_srcb->mtu);
         }
     }
 /*******************************************************************************
@@ -772,7 +786,7 @@
     tBTA_GATTC_RCB      *p_clreg = p_clcb->p_rcb;
     tBTA_GATTC           cb_data;
 
-    APPL_TRACE_DEBUG1("bta_gattc_close conn_id=%d",p_clcb->bta_conn_id);
+    APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d",p_clcb->bta_conn_id);
 
     cb_data.close.client_if = p_clcb->p_rcb->client_if;
     cb_data.close.conn_id   = p_clcb->bta_conn_id;
@@ -780,13 +794,19 @@
     cb_data.close.status    = p_clcb->status;
     bdcpy(cb_data.close.remote_bda, p_clcb->bda);
 
-    if (!BTM_IsBleLink(p_clcb->bda))
+    if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
         bta_sys_conn_close( BTA_ID_GATTC ,BTA_ALL_APP_ID, p_clcb->bda);
 
     bta_gattc_clcb_dealloc(p_clcb);
 
     if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT)
+    {
         cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific);
+    }
+    else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT)
+    {
+        cb_data.close.status = p_data->int_conn.reason;
+    }
 
     if(p_cback)
         (* p_cback)(BTA_GATTC_CLOSE_EVT,   (tBTA_GATTC *)&cb_data);
@@ -830,10 +850,11 @@
 *******************************************************************************/
 void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 {
-    APPL_TRACE_DEBUG1("Discovery cancel conn_id=%d",p_clcb->bta_conn_id);
-
-    bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
-    bta_gattc_sm_execute(p_clcb, BTA_GATTC_API_CLOSE_EVT, p_data);
+    APPL_TRACE_DEBUG("Discovery cancel conn_id=%d",p_clcb->bta_conn_id);
+    if (p_clcb->disc_active)
+        bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_ERROR);
+    else
+        p_clcb->state = BTA_GATTC_CONN_ST;
 }
 /*******************************************************************************
 **
@@ -925,7 +946,7 @@
 {
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG2("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
+    APPL_TRACE_DEBUG("bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
         p_clcb->bta_conn_id, p_clcb->p_srcb->state);
 
     if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
@@ -942,22 +963,28 @@
             p_clcb->p_srcb->update_count = 0;
             p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
 
+            if (p_clcb->transport == BTA_TRANSPORT_LE)
+                L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
+
             /* set all srcb related clcb into discovery ST */
             bta_gattc_set_discover_st(p_clcb->p_srcb);
 
             if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK)
             {
-                p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
+                p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
+                                                               p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
             }
             if (p_clcb->status != BTA_GATT_OK)
             {
-                APPL_TRACE_ERROR0("discovery on server failed");
+                APPL_TRACE_ERROR("discovery on server failed");
                 bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
             }
+            else
+                p_clcb->disc_active = TRUE;
         }
         else
         {
-            APPL_TRACE_ERROR0("unknown device, can not start discovery");
+            APPL_TRACE_ERROR("unknown device, can not start discovery");
         }
     }
     /* pending operation, wait until it finishes */
@@ -984,12 +1011,14 @@
     tBTA_GATTC_DATA *p_q_cmd = p_clcb->p_q_cmd;
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG1("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id);
+    APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id);
 
 #if BLE_INCLUDED == TRUE
-    L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
+    if(p_clcb->transport == BTA_TRANSPORT_LE)
+        L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
 #endif
     p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
+    p_clcb->disc_active = FALSE;
 
     if (p_clcb->status != GATT_SUCCESS)
     {
@@ -1020,9 +1049,13 @@
         p_clcb->p_q_cmd = NULL;
 
         bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
-
-        utl_freebuf((void **)&p_q_cmd);
-
+        /* if the command executed requeued the cmd, we don't
+         * want to free the underlying buffer that's being
+         * referenced by p_clcb->p_q_cmd
+         */
+        if (p_q_cmd != p_clcb->p_q_cmd) {
+            utl_freebuf((void **)&p_q_cmd);
+        }
     }
 }
 /*******************************************************************************
@@ -1112,7 +1145,7 @@
             }
             else
             {
-                APPL_TRACE_ERROR1("invalud ID type: %d", p_id->id_type);
+                APPL_TRACE_ERROR("invalud ID type: %d", p_id->id_type);
             }
 
             if (handle == 0)
@@ -1240,20 +1273,23 @@
                                       &p_data->api_confirm.char_id,
                                       NULL)) == 0)
     {
-        APPL_TRACE_ERROR0("Can not map service/char ID into valid handle");
+        APPL_TRACE_ERROR("Can not map service/char ID into valid handle");
     }
     else
     {
         if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, handle)
             != GATT_SUCCESS)
         {
-            APPL_TRACE_ERROR1("bta_gattc_confirm to handle [0x%04x] failed", handle);
+            APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
         }
-        /* if over BR_EDR, inform PM for mode change */
-        else if (!BTM_IsBleLink(p_clcb->bda))
+        else
         {
-            bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
-            bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+            /* if over BR_EDR, inform PM for mode change */
+            if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
+            {
+                bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+                bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+            }
         }
     }
 }
@@ -1286,7 +1322,8 @@
                                 &cb_data.read.descr_type) == FALSE)
         {
             cb_data.read.status = BTA_GATT_INTERNAL_ERROR;
-            APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", p_data->p_cmpl->att_value.handle);
+            APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x",
+                                p_data->p_cmpl->att_value.handle);
         }
         else
         {
@@ -1302,10 +1339,12 @@
         cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id;
         cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id;
         if (p_clcb->p_q_cmd->api_read.p_descr_type)
-            memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type, sizeof(tBTA_GATT_ID));
+            memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type,
+                   sizeof(tBTA_GATT_ID));
     }
 
-    event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ? BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
+    event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ?
+                    BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
     cb_data.read.conn_id = p_clcb->bta_conn_id;
 
     utl_freebuf((void **)&p_clcb->p_q_cmd);
@@ -1339,10 +1378,13 @@
     }
     else
     {
-        memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
-        memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id, sizeof(tBTA_GATT_ID));
+        memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id,
+                sizeof(tBTA_GATT_SRVC_ID));
+        memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id,
+                sizeof(tBTA_GATT_ID));
         if (p_clcb->p_q_cmd->api_write.p_descr_type)
-            memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type, sizeof(tBTA_GATT_ID));
+            memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type,
+                   sizeof(tBTA_GATT_ID));
     }
 
     if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
@@ -1430,17 +1472,17 @@
     UINT8           op = (UINT8)p_data->op_cmpl.op_code;
     UINT8           mapped_op = 0;
 
-    APPL_TRACE_DEBUG1("bta_gattc_op_cmpl op = %d", op);
+    APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
 
     if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION)
     {
-        APPL_TRACE_ERROR0("unexpected operation, ignored");
+        APPL_TRACE_ERROR("unexpected operation, ignored");
     }
     else if (op >= GATTC_OPTYPE_READ)
     {
         if (p_clcb->p_q_cmd == NULL)
         {
-            APPL_TRACE_ERROR0("No pending command");
+            APPL_TRACE_ERROR("No pending command");
             return;
         }
         if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ])
@@ -1449,23 +1491,25 @@
             if ( mapped_op > GATTC_OPTYPE_INDICATION)   mapped_op = 0;
 
 #if (BT_TRACE_VERBOSE == TRUE)
-            APPL_TRACE_ERROR3("expect op:(%s :0x%04x), receive unexpected operation (%s).",
+            APPL_TRACE_ERROR("expect op:(%s :0x%04x), receive unexpected operation (%s).",
                                 bta_gattc_op_code_name[mapped_op] , p_clcb->p_q_cmd->hdr.event,
                                 bta_gattc_op_code_name[op]);
 #else
-            APPL_TRACE_ERROR3("expect op:(%u :0x%04x), receive unexpected operation (%u).",
+            APPL_TRACE_ERROR("expect op:(%u :0x%04x), receive unexpected operation (%u).",
                                 mapped_op , p_clcb->p_q_cmd->hdr.event, op);
 #endif
             return;
         }
 
-        /* service handle change void the response, discard it */
-        if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING)
+        /* discard responses if service change indication is received before operation completed */
+        if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg)
         {
-            p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
-            bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
+            APPL_TRACE_DEBUG("Discard all responses when service change indication is received.");
+            p_data->op_cmpl.status = GATT_ERROR;
         }
-        else if (op == GATTC_OPTYPE_READ)
+
+        /* service handle change void the response, discard it */
+        if (op == GATTC_OPTYPE_READ)
             bta_gattc_read_cmpl(p_clcb, &p_data->op_cmpl);
 
         else if (op == GATTC_OPTYPE_WRITE)
@@ -1476,6 +1520,12 @@
 
         else if (op == GATTC_OPTYPE_CONFIG)
             bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);
+
+        if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING)
+        {
+            p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
+            bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
+        }
     }
 }
 /*******************************************************************************
@@ -1493,7 +1543,7 @@
 
     /* receive op complete when discovery is started, ignore the response,
         and wait for discovery finish and resent */
-    APPL_TRACE_DEBUG1("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
+    APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d", p_data->hdr.layer_specific);
 
 }
 /*******************************************************************************
@@ -1509,7 +1559,7 @@
 {
     tBTA_GATT_STATUS    status = GATT_INTERNAL_ERROR;
     tBTA_GATTC cb_data;
-    APPL_TRACE_DEBUG1("bta_gattc_search conn_id=%d",p_clcb->bta_conn_id);
+    APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d",p_clcb->bta_conn_id);
     if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache)
     {
         status = BTA_GATT_OK;
@@ -1551,7 +1601,7 @@
 
     bta_gattc_set_discover_st(p_clcb->p_srcb);
 
-    APPL_TRACE_DEBUG1("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id);
+    APPL_TRACE_DEBUG("bta_gattc_cache_open conn_id=%d",p_clcb->bta_conn_id);
     bta_gattc_co_cache_open(p_clcb->p_srcb->server_bda, BTA_GATTC_CI_CACHE_OPEN_EVT,
                             p_clcb->bta_conn_id, FALSE);
 }
@@ -1566,7 +1616,7 @@
 *******************************************************************************/
 void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 {
-    APPL_TRACE_DEBUG2("bta_gattc_ci_open conn_id=%d server state=%d" ,
+    APPL_TRACE_DEBUG("bta_gattc_ci_open conn_id=%d server state=%d" ,
                       p_clcb->bta_conn_id, p_clcb->p_srcb->state);
     if (p_clcb->p_srcb->state == BTA_GATTC_SERV_LOAD)
     {
@@ -1615,21 +1665,21 @@
 void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 {
 
-    APPL_TRACE_DEBUG2("bta_gattc_ci_load conn_id=%d load status=%d" ,
-                      p_clcb->bta_conn_id, p_data->ci_load.status );
-    bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
+    APPL_TRACE_DEBUG("bta_gattc_ci_load conn_id=%d load status=%d",
+                      p_clcb->bta_conn_id, p_data->ci_load.status);
 
-    if ((p_data->ci_load.status == BTA_GATT_OK ||
-         p_data->ci_load.status == BTA_GATT_MORE) &&
-        p_data->ci_load.num_attr > 0)
+    if (p_data->ci_load.status == BTA_GATT_OK ||
+         p_data->ci_load.status == BTA_GATT_MORE)
     {
-        bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
+        if (p_data->ci_load.num_attr != 0)
+            bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr,
+                                p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
 
         if (p_data->ci_load.status == BTA_GATT_OK)
         {
             p_clcb->p_srcb->attr_index = 0;
             bta_gattc_reset_discover_st(p_clcb->p_srcb, BTA_GATT_OK);
-
+            bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
         }
         else /* load more */
         {
@@ -1643,6 +1693,7 @@
     }
     else
     {
+        bta_gattc_co_cache_close(p_clcb->p_srcb->server_bda, 0);
         p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC;
         p_clcb->p_srcb->attr_index = 0;
         /* cache load failure, start discovery */
@@ -1651,7 +1702,7 @@
 }
 /*******************************************************************************
 **
-** Function         bta_gattc_ci_load
+** Function         bta_gattc_ci_save
 **
 ** Description      cache loading received.
 **
@@ -1662,7 +1713,7 @@
 {
     UNUSED(p_data);
 
-    APPL_TRACE_DEBUG1("bta_gattc_ci_save conn_id=%d  " ,
+    APPL_TRACE_DEBUG("bta_gattc_ci_save conn_id=%d  " ,
                       p_clcb->bta_conn_id   );
 
     if (!bta_gattc_cache_save(p_clcb->p_srcb, p_clcb->bta_conn_id))
@@ -1687,7 +1738,7 @@
 
     if (p_clcb->status == BTA_GATT_OK)
     {
-        APPL_TRACE_ERROR1("operation not supported at current state [%d]", p_clcb->state);
+        APPL_TRACE_ERROR("operation not supported at current state [%d]", p_clcb->state);
     }
 }
 
@@ -1735,27 +1786,33 @@
 **
 *******************************************************************************/
 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
-                                 BOOLEAN connected, tGATT_DISCONN_REASON reason)
+                                 BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                 tBT_TRANSPORT transport)
 {
     tBTA_GATTC_DATA *p_buf;
 
-    APPL_TRACE_DEBUG4("bta_gattc_conn_cback: cif = %d connected = %d conn_id = %d reaosn = 0x%04x",
-                      gattc_if, connected, conn_id, reason);
+    if (reason != 0)
+    {
+        APPL_TRACE_WARNING("%s() - cif=%d connected=%d conn_id=%d reason=0x%04x",
+                      __FUNCTION__, gattc_if, connected, conn_id, reason);
+    }
 
     if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
     {
         memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
 
-        p_buf->int_conn.hdr.event            = connected ? BTA_GATTC_INT_CONN_EVT: BTA_GATTC_INT_DISCONN_EVT;
+        p_buf->int_conn.hdr.event            = connected ? BTA_GATTC_INT_CONN_EVT:
+                                                           BTA_GATTC_INT_DISCONN_EVT;
         p_buf->int_conn.hdr.layer_specific   = conn_id;
         p_buf->int_conn.client_if            = gattc_if;
         p_buf->int_conn.role                 = L2CA_GetBleConnRole(bda);
         p_buf->int_conn.reason               = reason;
+        p_buf->int_conn.transport            = transport;
         bdcpy(p_buf->int_conn.remote_bda, bda);
 
-                bta_sys_sendmsg(p_buf);
-            }
-        }
+        bta_sys_sendmsg(p_buf);
+    }
+}
 
 /*******************************************************************************
 **
@@ -1771,7 +1828,7 @@
     tBTA_GATTC_DATA *p_buf;
     tBTA_GATTC_CLCB *p_clcb = NULL;
 
-    if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
+    if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL)
     {
         return;
     }
@@ -1786,7 +1843,7 @@
     }
 #endif
 
-    APPL_TRACE_DEBUG1("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
+    APPL_TRACE_DEBUG("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
 
     if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
     {
@@ -1934,10 +1991,10 @@
                                      tGATT_CL_COMPLETE *p_data,
                                      tBTA_GATTC_NOTIFY *p_notify)
 {
-    APPL_TRACE_DEBUG2("bta_gattc_proc_other_indication check \
+    APPL_TRACE_DEBUG("bta_gattc_proc_other_indication check \
                        p_data->att_value.handle=%d p_data->handle=%d",
                        p_data->att_value.handle, p_data->handle);
-    APPL_TRACE_DEBUG1("is_notify", p_notify->is_notify);
+    APPL_TRACE_DEBUG("is_notify", p_notify->is_notify);
 
     p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? FALSE : TRUE;
     p_notify->len = p_data->att_value.len;
@@ -1967,22 +2024,23 @@
     tBTA_GATTC_NOTIFY   notify;
     BD_ADDR             remote_bda;
     tBTA_GATTC_IF       gatt_if;
+    tBTA_TRANSPORT transport;
 
-    if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda))
+    if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
     {
-        APPL_TRACE_ERROR0("indication/notif for unknown app");
+        APPL_TRACE_ERROR("indication/notif for unknown app");
         return;
     }
 
     if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) == NULL)
     {
-        APPL_TRACE_ERROR0("indication/notif for unregistered app");
+        APPL_TRACE_ERROR("indication/notif for unregistered app");
         return;
     }
 
     if ((p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL)
     {
-        APPL_TRACE_ERROR0("indication/notif for unknown device, ignore");
+        APPL_TRACE_ERROR("indication/notif for unknown device, ignore");
         return;
     }
 
@@ -2002,15 +2060,16 @@
                 /* connection not open yet */
                 if (p_clcb == NULL)
                 {
-                    if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda)) != NULL)
+                    if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport)) != NULL)
                     {
                         p_clcb->bta_conn_id = conn_id;
+                        p_clcb->transport   = transport;
 
                         bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
                     }
                     else
                     {
-                        APPL_TRACE_ERROR0("No resources");
+                        APPL_TRACE_ERROR("No resources");
                     }
                 }
 
@@ -2020,14 +2079,15 @@
             /* no one intersted and need ack? */
             else if (op == GATTC_OPTYPE_INDICATION)
             {
-                APPL_TRACE_DEBUG0("no one interested, ack now");
+                APPL_TRACE_DEBUG("no one interested, ack now");
                 GATTC_SendHandleValueConfirm(conn_id, handle);
             }
         }
     }
     else
     {
-        APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.", handle);
+        APPL_TRACE_ERROR("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.",
+                          handle);
     }
 }
 /*******************************************************************************
@@ -2046,7 +2106,7 @@
     tBTA_GATTC_OP_CMPL  *p_buf;
     UINT16              len = sizeof(tBTA_GATTC_OP_CMPL) + sizeof(tGATT_CL_COMPLETE);
 
-    APPL_TRACE_DEBUG3("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
+    APPL_TRACE_DEBUG("bta_gattc_cmpl_cback: conn_id = %d op = %d status = %d",
                       conn_id, op, status);
 
     /* notification and indication processed right away */
@@ -2058,13 +2118,12 @@
     /* for all other operation, not expected if w/o connection */
     else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) == NULL)
     {
-        APPL_TRACE_ERROR1("bta_gattc_cmpl_cback unknown conn_id =  %d, ignore data", conn_id);
+        APPL_TRACE_ERROR("bta_gattc_cmpl_cback unknown conn_id =  %d, ignore data", conn_id);
         return;
     }
 
-
-/* if over BR_EDR, inform PM for mode change */
-    if (!BTM_IsBleLink(p_clcb->bda))
+    /* if over BR_EDR, inform PM for mode change */
+    if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
     {
         bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
         bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
@@ -2089,6 +2148,33 @@
 
     return;
 }
+
+/*******************************************************************************
+**
+** Function         bta_gattc_cong_cback
+**
+** Description      congestion callback for BTA GATT client.
+**
+** Returns          void
+**
+********************************************************************************/
+static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested)
+{
+    tBTA_GATTC_CLCB *p_clcb;
+    tBTA_GATTC cb_data;
+
+    if ((p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id)) != NULL)
+    {
+        if (p_clcb->p_rcb->p_cback)
+        {
+            cb_data.congest.conn_id = conn_id;
+            cb_data.congest.congested = congested;
+
+            (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CONGEST_EVT, &cb_data);
+        }
+    }
+}
+
 #if BLE_INCLUDED == TRUE
 /*******************************************************************************
 **
@@ -2106,14 +2192,14 @@
     UINT16              conn_id;
 
     /* should always get the connection ID */
-    if (GATT_GetConnIdIfConnected(cif, remote_bda,&conn_id) == FALSE)
+    if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE)
     {
-        APPL_TRACE_ERROR0("bta_gattc_init_clcb_conn ERROR: not a connected device");
+        APPL_TRACE_ERROR("bta_gattc_init_clcb_conn ERROR: not a connected device");
         return;
     }
 
     /* initaite a new connection here */
-    if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda)) != NULL)
+    if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL)
     {
         gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
 
@@ -2125,7 +2211,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR0("No resources");
+        APPL_TRACE_ERROR("No resources");
     }
 }
 /*******************************************************************************
@@ -2147,7 +2233,7 @@
     {
         if (p_conn->in_use )
         {
-            if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda) == NULL)
+            if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL)
             {
                 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
             }
@@ -2175,7 +2261,7 @@
 
     if (p_clreg == NULL)
     {
-        APPL_TRACE_ERROR1("bta_gattc_listen failed, unknown client_if: %d",
+        APPL_TRACE_ERROR("bta_gattc_listen failed, unknown client_if: %d",
                             p_msg->api_listen.client_if);
         return;
     }
@@ -2189,7 +2275,7 @@
                          p_msg->api_listen.start,
                          p_msg->api_listen.remote_bda))
         {
-            APPL_TRACE_ERROR0("Listen failure");
+            APPL_TRACE_ERROR("Listen failure");
             (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
         }
         else
@@ -2206,7 +2292,9 @@
 
                     /* if is a connected remote device */
                     if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
-                        bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if, p_msg->api_listen.remote_bda) == NULL)
+                        bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
+                                                   p_msg->api_listen.remote_bda,
+                                                   BTA_GATT_TRANSPORT_LE) == NULL)
                     {
 
                         bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
@@ -2216,8 +2304,9 @@
                 /* if listen to all */
                 else
                 {
-                    APPL_TRACE_ERROR0("Listen For All now");
-                    /* go through all connected device and send callback for all connected slave connection */
+                    APPL_TRACE_ERROR("Listen For All now");
+                    /* go through all connected device and send
+                    callback for all connected slave connection */
                     bta_gattc_process_listen_all(p_msg->api_listen.client_if);
                 }
             }
@@ -2238,7 +2327,7 @@
 {
     tBTA_GATTC_RCB      *p_clreg = bta_gattc_cl_get_regcb(p_msg->api_listen.client_if);
     tBTA_GATTC          cb_data;
-    (void)(p_cb);
+    UNUSED(p_cb);
 
     cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
     cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start);
diff --git a/bta/gatt/bta_gattc_api.c b/bta/gatt/bta_gattc_api.c
index 0bc87ec..a91b20e 100644
--- a/bta/gatt/bta_gattc_api.c
+++ b/bta/gatt/bta_gattc_api.c
@@ -60,7 +60,7 @@
 
     if (bta_sys_is_register(BTA_ID_GATTC) == FALSE)
     {
-        APPL_TRACE_WARNING0("GATTC Module not enabled/already disabled");
+        APPL_TRACE_WARNING("GATTC Module not enabled/already disabled");
         return;
     }
     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
@@ -91,9 +91,7 @@
 
     if (bta_sys_is_register(BTA_ID_GATTC) == FALSE)
     {
-        GKI_sched_lock();
         bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg);
-        GKI_sched_unlock();
     }
 
     if ((p_buf = (tBTA_GATTC_API_REG *) GKI_getbuf(sizeof(tBTA_GATTC_API_REG))) != NULL)
@@ -143,11 +141,13 @@
 ** Parameters       client_if: server interface.
 **                  remote_bda: remote device BD address.
 **                  is_direct: direct connection or background auto connection
+**                  transport: Transport to be used for GATT connection (BREDR/LE)
 **
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct)
+void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+                    BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport)
 {
     tBTA_GATTC_API_OPEN  *p_buf;
 
@@ -157,6 +157,7 @@
 
         p_buf->client_if = client_if;
         p_buf->is_direct = is_direct;
+        p_buf->transport = transport;
         memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
 
 
@@ -414,7 +415,6 @@
         memcpy(&p_descr_result->descr_id, &p_descr_result->char_id.char_id, sizeof(tBTA_GATT_ID));
         memcpy(&p_descr_result->char_id, p_char_id, sizeof(tBTA_GATTC_CHAR_ID));
     }
-
     return status;
 
 }
@@ -426,7 +426,7 @@
 **                  of the characterisctic.
 **
 ** Parameters       conn_id: connection ID which identify the server.
-**                  p_start_descr_id: start the characteristic search from the next record
+**                  p_start_descr_id: start the descriptor search from the next record
 **                           after the one identified by p_start_descr_id.
 **                  p_descr_uuid_cond: Characteristic descriptor UUID, if NULL find
 **                               the first available characteristic descriptor.
@@ -860,7 +860,7 @@
 {
     tBTA_GATTC_API_CONFIRM  *p_buf;
 
-    APPL_TRACE_API3("BTA_GATTC_SendIndConfirm conn_id=%d service uuid1=0x%x char uuid=0x%x",
+    APPL_TRACE_API("BTA_GATTC_SendIndConfirm conn_id=%d service uuid1=0x%x char uuid=0x%x",
                     conn_id, p_char_id->srvc_id.id.uuid.uu.uuid16, p_char_id->char_id.uuid.uu.uuid16);
 
     if ((p_buf = (tBTA_GATTC_API_CONFIRM *) GKI_getbuf(sizeof(tBTA_GATTC_API_CONFIRM))) != NULL)
@@ -902,13 +902,10 @@
 
     if (!p_char_id)
     {
-        APPL_TRACE_ERROR0("deregistration failed, unknow char id");
+        APPL_TRACE_ERROR("deregistration failed, unknow char id");
         return status;
     }
 
-    /* lock other GKI task */
-    GKI_sched_lock();
-
     if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
     {
         for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
@@ -917,7 +914,7 @@
                  !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
                   bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id))
             {
-                APPL_TRACE_WARNING0("notification already registered");
+                APPL_TRACE_WARNING("notification already registered");
                 status = BTA_GATT_OK;
                 break;
             }
@@ -944,17 +941,15 @@
             if (i == BTA_GATTC_NOTIF_REG_MAX)
             {
                 status = BTA_GATT_NO_RESOURCES;
-                APPL_TRACE_ERROR0("Max Notification Reached, registration failed.");
+                APPL_TRACE_ERROR("Max Notification Reached, registration failed.");
             }
         }
     }
     else
     {
-        APPL_TRACE_ERROR1("Client_if: %d Not Registered", client_if);
+        APPL_TRACE_ERROR("Client_if: %d Not Registered", client_if);
     }
 
-    GKI_sched_unlock();
-
     return status;
 }
 
@@ -981,13 +976,10 @@
 
     if (!p_char_id)
     {
-        APPL_TRACE_ERROR0("deregistration failed, unknow char id");
+        APPL_TRACE_ERROR("deregistration failed, unknow char id");
         return status;
     }
 
-    /* lock other GKI task */
-    GKI_sched_lock();
-
     if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
     {
         for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
@@ -996,7 +988,7 @@
                 !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
                 bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id))
             {
-                APPL_TRACE_DEBUG0("Deregistered.");
+                APPL_TRACE_DEBUG("Deregistered.");
                 memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
                 status = BTA_GATT_OK;
                 break;
@@ -1006,16 +998,14 @@
         {
             status = BTA_GATT_ERROR;
 
-            APPL_TRACE_ERROR0("registration not found");
+            APPL_TRACE_ERROR("registration not found");
         }
     }
     else
     {
-        APPL_TRACE_ERROR1("Client_if: %d Not Registered", client_if);
+        APPL_TRACE_ERROR("Client_if: %d Not Registered", client_if);
     }
 
-    GKI_sched_unlock();
-
     return status;
 }
 
diff --git a/bta/gatt/bta_gattc_cache.c b/bta/gatt/bta_gattc_cache.c
index 3d603c3..65026ba 100644
--- a/bta/gatt/bta_gattc_cache.c
+++ b/bta/gatt/bta_gattc_cache.c
@@ -70,11 +70,11 @@
     tBTA_GATTC_CACHE    *p_cur_srvc = p_cache;
     tBTA_GATTC_CACHE_ATTR   *p_attr;
 
-    APPL_TRACE_ERROR0("<================Start Server Cache =============>");
+    APPL_TRACE_ERROR("<================Start Server Cache =============>");
 
     while (p_cur_srvc)
     {
-        APPL_TRACE_ERROR6("Service[%d]: handle[%d ~ %d] %s[0x%04x] inst[%d]",
+        APPL_TRACE_ERROR("Service[%d]: handle[%d ~ %d] %s[0x%04x] inst[%d]",
                           i, p_cur_srvc->s_handle, p_cur_srvc->e_handle,
                           ((p_cur_srvc->service_uuid.id.uuid.len == 2) ? "uuid16" : "uuid128"),
                           p_cur_srvc->service_uuid.id.uuid.uu.uuid16,
@@ -85,7 +85,7 @@
 
         for (j = 0; p_attr; j ++ )
         {
-            APPL_TRACE_ERROR6("\t Attr[0x%04x] handle[%d] uuid[0x%04x] inst[%d] type[%s] prop[0x%1x]",
+            APPL_TRACE_ERROR("\t Attr[0x%04x] handle[%d] uuid[0x%04x] inst[%d] type[%s] prop[0x%1x]",
                               j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id,
                               bta_gattc_attr_type[p_attr->attr_type], p_attr->property);
 
@@ -94,8 +94,8 @@
         p_cur_srvc = p_cur_srvc->p_next;
     }
 
-    APPL_TRACE_ERROR0("<================End Server Cache =============>");
-    APPL_TRACE_ERROR0(" ");
+    APPL_TRACE_ERROR("<================End Server Cache =============>");
+    APPL_TRACE_ERROR(" ");
 }
 
 /*******************************************************************************
@@ -112,14 +112,14 @@
     UINT8 i;
     tBTA_GATTC_ATTR_REC *pp = p_rec;
 
-    APPL_TRACE_ERROR0("<================Start Explore Queue =============>");
+    APPL_TRACE_ERROR("<================Start Explore Queue =============>");
     for (i = 0; i < num_rec; i ++, pp ++)
     {
-        APPL_TRACE_ERROR5("\t rec[%d] uuid[0x%04x] s_handle[%d] e_handle[%d] is_primary[%d]",
+        APPL_TRACE_ERROR("\t rec[%d] uuid[0x%04x] s_handle[%d] e_handle[%d] is_primary[%d]",
                           i + 1, pp->uuid.uu.uuid16, pp->s_handle, pp->e_handle, pp->is_primary);
     }
-    APPL_TRACE_ERROR0("<================ End Explore Queue =============>");
-    APPL_TRACE_ERROR0(" ");
+    APPL_TRACE_ERROR("<================ End Explore Queue =============>");
+    APPL_TRACE_ERROR(" ");
 
 }
 #endif  /* BTA_GATT_DEBUG == TRUE */
@@ -140,7 +140,7 @@
 
     if ((p_buf = (BT_HDR *)GKI_getpoolbuf(GATT_DB_POOL_ID)) == NULL)
     {
-        APPL_TRACE_DEBUG0("No resources: GKI buffer allocation failed.");
+        APPL_TRACE_DEBUG("No resources: GKI buffer allocation failed.");
         utl_freebuf((void **)&p_srvc_cb->p_srvc_list);
         p_srvc_cb->free_byte = 0;
     }
@@ -154,7 +154,7 @@
         GKI_enqueue(&p_srvc_cb->cache_buffer, p_buf);
     }
 #if BTA_GATT_DEBUG== TRUE
-    APPL_TRACE_DEBUG1("allocating new buffer: free byte = %d", p_srvc_cb->free_byte);
+    APPL_TRACE_DEBUG("allocating new buffer: free byte = %d", p_srvc_cb->free_byte);
 #endif
     return p_buf;
 }
@@ -178,7 +178,7 @@
 
     if ((p_srvc_cb->p_srvc_list = (tBTA_GATTC_ATTR_REC*)GKI_getbuf(BTA_GATTC_ATTR_LIST_SIZE)) == NULL)
     {
-        APPL_TRACE_DEBUG0("No resources: GKI buffer allocation failed.");
+        APPL_TRACE_DEBUG("No resources: GKI buffer allocation failed.");
         status = GATT_NO_RESOURCES;
     }
     else
@@ -301,8 +301,8 @@
     tBTA_GATT_STATUS    status = BTA_GATT_OK;
 
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-    APPL_TRACE_DEBUG0("Add a service into Service");
-    APPL_TRACE_DEBUG2("free byte = %d,  req %d bytes.", p_srvc_cb->free_byte, sizeof(tBTA_GATTC_CACHE))
+    APPL_TRACE_DEBUG("Add a service into Service");
+    APPL_TRACE_DEBUG("free byte = %d,  req %d bytes.", p_srvc_cb->free_byte, sizeof(tBTA_GATTC_CACHE))
 #endif
 
     if (p_srvc_cb->free_byte < sizeof(tBTA_GATTC_CACHE))
@@ -357,14 +357,14 @@
     UINT8   *pp;
 
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-    APPL_TRACE_DEBUG1("bta_gattc_add_attr_to_cache: Add a [%s] into Service", bta_gattc_attr_type[type]);
-    APPL_TRACE_DEBUG4("handle=%d uuid16=0x%x property=0x%x type=%d", handle, p_uuid->uu.uuid16, property, type);
-    APPL_TRACE_DEBUG2("free byte = %d,  req %d bytes.", p_srvc_cb->free_byte, len);
+    APPL_TRACE_DEBUG("bta_gattc_add_attr_to_cache: Add a [%s] into Service", bta_gattc_attr_type[type]);
+    APPL_TRACE_DEBUG("handle=%d uuid16=0x%x property=0x%x type=%d", handle, p_uuid->uu.uuid16, property, type);
+    APPL_TRACE_DEBUG("free byte = %d,  req %d bytes.", p_srvc_cb->free_byte, len);
 #endif
 
     if (p_srvc_cb->p_cur_srvc == NULL)
     {
-        APPL_TRACE_ERROR0("Illegal action to add char/descr/incl srvc before adding a service!");
+        APPL_TRACE_ERROR("Illegal action to add char/descr/incl srvc before adding a service!");
         return GATT_WRONG_STATE;
     }
 
@@ -447,7 +447,7 @@
 
     *p_e_hdl = p_rec->e_handle;
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-    APPL_TRACE_DEBUG2("discover range [%d ~ %d]",p_rec->s_handle, p_rec->e_handle);
+    APPL_TRACE_DEBUG("discover range [%d ~ %d]",p_rec->s_handle, p_rec->e_handle);
 #endif
     return;
 }
@@ -460,12 +460,21 @@
 ** Returns          status of the operation.
 **
 *******************************************************************************/
-tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type)
+tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb,
+                                                    UINT8 disc_type)
 {
-    if (BTM_IsBleLink(p_server_cb->server_bda))
-        return bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type);
-    else
-        return bta_gattc_sdp_service_disc(conn_id, p_server_cb);
+    tBTA_GATTC_CLCB     *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
+    tBTA_GATT_STATUS    status =  BTA_GATT_ERROR;
+
+    if (p_clcb)
+    {
+        if (p_clcb->transport == BTA_TRANSPORT_LE)
+            status = bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type);
+        else
+            status = bta_gattc_sdp_service_disc(conn_id, p_server_cb);
+    }
+
+    return status;
 }
 /*******************************************************************************
 **
@@ -476,7 +485,8 @@
 ** Returns          status of the operation.
 **
 *******************************************************************************/
-tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type)
+tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb,
+                                                   UINT8 disc_type)
 {
     tGATT_DISC_PARAM param;
     BOOLEAN is_service = TRUE;
@@ -542,7 +552,7 @@
 *******************************************************************************/
 void bta_gattc_start_disc_char_dscp(UINT16 conn_id, tBTA_GATTC_SERV *p_srvc_cb)
 {
-    APPL_TRACE_DEBUG0("starting discover characteristics descriptor");
+    APPL_TRACE_DEBUG("starting discover characteristics descriptor");
 
     if (bta_gattc_discover_procedure(conn_id, p_srvc_cb, GATT_DISC_CHAR_DSCPT) != 0)
         bta_gattc_char_dscpt_disc_cmpl(conn_id, p_srvc_cb);
@@ -562,13 +572,13 @@
     tBTA_GATTC_ATTR_REC *p_rec = p_srvc_cb->p_srvc_list + p_srvc_cb->cur_srvc_idx;
     tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
 
-    APPL_TRACE_DEBUG1("Start service discovery: srvc_idx = %d", p_srvc_cb->cur_srvc_idx);
+    APPL_TRACE_DEBUG("Start service discovery: srvc_idx = %d", p_srvc_cb->cur_srvc_idx);
 
     p_srvc_cb->cur_char_idx = p_srvc_cb->next_avail_idx = p_srvc_cb->total_srvc;
 
     if (p_clcb == NULL)
     {
-        APPL_TRACE_ERROR0("unknown connection ID");
+        APPL_TRACE_ERROR("unknown connection ID");
         return;
     }
     /* start expore a service if there is service not been explored */
@@ -588,7 +598,7 @@
         }
     }
     /* no service found at all, the end of server discovery*/
-    APPL_TRACE_ERROR0("No More Service found");
+    APPL_TRACE_ERROR("No More Service found");
 
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
     bta_gattc_display_cache_server(p_srvc_cb->p_srvc_cache);
@@ -677,7 +687,7 @@
     /* all characteristic has been explored, start with next service if any */
     {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-        APPL_TRACE_ERROR0("all char has been explored");
+        APPL_TRACE_ERROR("all char has been explored");
 #endif
         p_srvc_cb->cur_srvc_idx ++;
         bta_gattc_explore_srvc (conn_id, p_srvc_cb);
@@ -694,7 +704,7 @@
 
     if (!GATT_HANDLE_IS_VALID(s_handle) || !GATT_HANDLE_IS_VALID(e_handle))
     {
-        APPL_TRACE_ERROR2("invalid included service handle: [0x%04x ~ 0x%04x]", s_handle, e_handle);
+        APPL_TRACE_ERROR("invalid included service handle: [0x%04x ~ 0x%04x]", s_handle, e_handle);
         exist_srvc = TRUE;
     }
     else
@@ -735,7 +745,7 @@
 
         p_srvc_cb->total_srvc ++;
 
-        APPL_TRACE_DEBUG2("bta_gattc_add_srvc_to_list handle = %d, service type = 0x%04x",
+        APPL_TRACE_DEBUG("bta_gattc_add_srvc_to_list handle = %d, service type = 0x%04x",
             s_handle, uuid.uu.uuid16);
 
         p_rec->s_handle     = s_handle;
@@ -751,7 +761,7 @@
     {   /* allocate bigger buffer ?? */
         status = GATT_DB_FULL;
 
-        APPL_TRACE_ERROR0("service not added, no resources or wrong state");
+        APPL_TRACE_ERROR("service not added, no resources or wrong state");
     }
     return status;
 }
@@ -773,7 +783,7 @@
 
     if (p_srvc_cb->p_srvc_list == NULL)
     {
-        APPL_TRACE_ERROR0("No service available, unexpected char discovery result");
+        APPL_TRACE_ERROR("No service available, unexpected char discovery result");
         status = BTA_GATT_INTERNAL_ERROR;
     }
     else if (p_srvc_cb->next_avail_idx < BTA_GATTC_MAX_CACHE_CHAR)
@@ -798,7 +808,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR0("char not added, no resources");
+        APPL_TRACE_ERROR("char not added, no resources");
         /* allocate bigger buffer ?? */
         status = BTA_GATT_DB_FULL;
     }
@@ -840,11 +850,11 @@
                         end_handle      = (UINT16) pe.params[1];
 
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                        APPL_TRACE_EVENT3("Found ATT service [0x%04x] handle[0x%04x ~ 0x%04x]",
+                        APPL_TRACE_EVENT("Found ATT service [0x%04x] handle[0x%04x ~ 0x%04x]",
                                         service_uuid.uu.uuid16, start_handle, end_handle);
 #endif
 
-                        if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle) &&
+                        if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle)&&
                             p_srvc_cb != NULL)
                         {
                             /* discover services result, add services into a service list */
@@ -856,7 +866,8 @@
                         }
                         else
                         {
-                            APPL_TRACE_ERROR2("invalid start_handle = %d end_handle = %d", start_handle, end_handle);
+                            APPL_TRACE_ERROR("invalid start_handle = %d end_handle = %d",
+                                                start_handle, end_handle);
                         }
                 }
 
@@ -871,7 +882,7 @@
         bta_gattc_explore_srvc(bta_gattc_cb.sdp_conn_id, p_srvc_cb);
     else
     {
-        APPL_TRACE_ERROR0("GATT service discovery is done on unknown connection");
+        APPL_TRACE_ERROR("GATT service discovery is done on unknown connection");
     }
 
     GKI_freebuf(bta_gattc_cb.p_sdp_db);
@@ -904,9 +915,11 @@
         attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
         attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
 
-        SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1, &uuid, num_attrs, attr_list);
+        SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1,
+                             &uuid, num_attrs, attr_list);
 
-        if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda, bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback))
+        if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda,
+                                              bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback))
         {
             GKI_freebuf(bta_gattc_cb.p_sdp_db);
             bta_gattc_cb.p_sdp_db = NULL;
@@ -990,7 +1003,8 @@
                 break;
 
             case GATT_DISC_CHAR_DSCPT:
-                bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0, BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
+                bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0,
+                                            BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
                 break;
         }
     }
@@ -1061,7 +1075,7 @@
     while (p_service_id && p_cache && !done)
     {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-        APPL_TRACE_DEBUG3("Service: handle[%d] uuid[0x%04x] inst[%d]",
+        APPL_TRACE_DEBUG("Service: handle[%d] uuid[0x%04x] inst[%d]",
                           p_cache->s_handle, p_cache->service_uuid.id.uuid.uu.uuid16,
                           p_cache->service_uuid.id.inst_id);
 #endif
@@ -1072,8 +1086,9 @@
             for (j = 0; p_attr; j ++)
             {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                APPL_TRACE_DEBUG5("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
-                                  j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id, p_attr->attr_type);
+                APPL_TRACE_DEBUG("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
+                                  j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16,
+                                    p_attr->inst_id, p_attr->attr_type);
 #endif
                 bta_gattc_pack_attr_uuid(p_attr, &attr_uuid);
 
@@ -1089,7 +1104,7 @@
                     else
                     {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                        APPL_TRACE_DEBUG0("found matching characteristic for the descriptor");
+                        APPL_TRACE_DEBUG("found matching characteristic for the descriptor");
 #endif
                         char_map = TRUE;
                     }
@@ -1104,7 +1119,7 @@
                             p_descr_uuid->inst_id == p_attr->inst_id)
                         {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                            APPL_TRACE_DEBUG0("found descriptor!!");
+                            APPL_TRACE_DEBUG("found descriptor!!");
 #endif
                             handle = p_attr->attr_handle;
                             done = TRUE;
@@ -1113,14 +1128,14 @@
                         else
                         {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                            APPL_TRACE_DEBUG0("descriptor UUID not matching");
+                            APPL_TRACE_DEBUG("descriptor UUID not matching");
 #endif
                         }
                     }
                     else /* another char */
                     {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                        APPL_TRACE_DEBUG0("no matching descriptor found!! start of next characteristic");
+                       APPL_TRACE_DEBUG("no matching descptr found!!start of next characteristic");
 #endif
                         char_map = FALSE;
                         done = TRUE;
@@ -1159,7 +1174,7 @@
     while (p_cache)
     {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-        APPL_TRACE_DEBUG3("Service: handle[%d] uuid[0x%04x] inst[%d]",
+        APPL_TRACE_DEBUG("Service: handle[%d] uuid[0x%04x] inst[%d]",
                           p_cache->s_handle, p_cache->service_uuid.id.uuid.uu.uuid16,
                           p_cache->service_uuid.id.inst_id);
 #endif
@@ -1177,8 +1192,9 @@
             for (j = 0; p_attr; j ++)
             {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                APPL_TRACE_DEBUG5("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
-                                  j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id, p_attr->attr_type);
+                APPL_TRACE_DEBUG("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
+                                  j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16,
+                                  p_attr->inst_id, p_attr->attr_type);
 #endif
                 if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR)
                     p_char = p_attr;
@@ -1199,7 +1215,7 @@
                         }
                         else
                         {
-                            APPL_TRACE_ERROR0("descriptor does not belong to any chracteristic, error");
+                            APPL_TRACE_ERROR("descptr does not belong to any chracteristic");
                         }
                     }
                     else
@@ -1239,7 +1255,7 @@
         if (bta_gattc_uuid_compare(p_uuid, &p_cache->service_uuid.id.uuid, FALSE))
         {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-            APPL_TRACE_DEBUG3("found service [0x%04x], inst[%d] handle [%d]",
+            APPL_TRACE_DEBUG("found service [0x%04x], inst[%d] handle [%d]",
                               p_cache->service_uuid.id.uuid.uu.uuid16,
                               p_cache->service_uuid.id.inst_id,
                               p_cache->s_handle);
@@ -1249,7 +1265,8 @@
                 memset(&cb_data, 0, sizeof(tBTA_GATTC));
 
                 cb_data.srvc_res.conn_id = p_clcb->bta_conn_id;
-                memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid ,sizeof(tBTA_GATT_SRVC_ID));
+                memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid,
+                        sizeof(tBTA_GATT_SRVC_ID));
 
                 (* p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_RES_EVT, &cb_data);
             }
@@ -1289,7 +1306,7 @@
         if (bta_gattc_srvcid_compare(p_service_id, &p_cache->service_uuid))
         {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-            APPL_TRACE_DEBUG2("found matching service [0x%04x], inst[%d]",
+            APPL_TRACE_DEBUG("found matching service [0x%04x], inst[%d]",
                               p_cache->service_uuid.id.uuid.uu.uuid16,
                               p_cache->service_uuid.id.inst_id);
 #endif
@@ -1298,7 +1315,7 @@
             for (j = 0; p_attr; j ++)
             {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                APPL_TRACE_DEBUG5("\t Attr[%d] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
+                APPL_TRACE_DEBUG("\t Attr[%d] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
                                   j + 1, p_attr->attr_handle,
                                   p_attr->p_uuid->uuid16,
                                   p_attr->inst_id,
@@ -1359,7 +1376,7 @@
                         {
 
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                            APPL_TRACE_DEBUG0("found char handle mapping characteristic");
+                            APPL_TRACE_DEBUG("found char handle mapping characteristic");
 #endif
                             p_result->inst_id = p_attr->inst_id;
 
@@ -1382,7 +1399,7 @@
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
             if (status)
             {
-                APPL_TRACE_ERROR0("In the given service, can not find matching record");
+                APPL_TRACE_ERROR("In the given service, can not find matching record");
             }
 #endif
             break;
@@ -1423,9 +1440,6 @@
     tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
     tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
 
-    /* lock other GKI task */
-    GKI_sched_lock();
-
     if (p_clcb != NULL )
     {
         if (p_clcb->state == BTA_GATTC_CONN_ST)
@@ -1445,21 +1459,20 @@
             else
             {
                 status = BTA_GATT_ERROR;
-                APPL_TRACE_ERROR0("No server cache available");
+                APPL_TRACE_ERROR("No server cache available");
             }
         }
         else
         {
-            APPL_TRACE_ERROR1("server cache not available, CLCB state = %d", p_clcb->state);
+            APPL_TRACE_ERROR("server cache not available, CLCB state = %d", p_clcb->state);
 
             status = (p_clcb->state == BTA_GATTC_DISCOVER_ST) ? BTA_GATT_BUSY : BTA_GATT_ERROR;
         }
     }
     else
     {
-        APPL_TRACE_ERROR1("Unknown conn ID: %d", conn_id);
+        APPL_TRACE_ERROR("Unknown conn ID: %d", conn_id);
     }
-    GKI_sched_unlock();
 
     return status;
 }
@@ -1479,7 +1492,7 @@
                              tBTA_GATTC_NV_ATTR *p_attr, UINT16 attr_index)
 {
     /* first attribute loading, initialize buffer */
-    APPL_TRACE_ERROR0("bta_gattc_rebuild_cache");
+    APPL_TRACE_ERROR("bta_gattc_rebuild_cache");
     if (attr_index == 0)
     {
         while (p_srvc_cb->cache_buffer.p_first)
@@ -1487,7 +1500,7 @@
 
         if (bta_gattc_alloc_cache_buf(p_srvc_cb) == NULL)
         {
-            APPL_TRACE_ERROR0("allocate cache buffer failed, no resources");
+            APPL_TRACE_ERROR("allocate cache buffer failed, no resources");
         }
         else
         {
@@ -1533,7 +1546,8 @@
 **
 *******************************************************************************/
 void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_handle,
-                            UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop, BOOLEAN is_primary)
+                            UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop,
+                            BOOLEAN is_primary)
 {
     p_attr->s_handle    = s_handle;
     p_attr->e_handle    = e_handle;
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
index 4f192cb..3b8430f 100644
--- a/bta/gatt/bta_gattc_int.h
+++ b/bta/gatt/bta_gattc_int.h
@@ -118,6 +118,7 @@
     BD_ADDR                 remote_bda;
     tBTA_GATTC_IF           client_if;
     BOOLEAN                 is_direct;
+    tBTA_TRANSPORT          transport;
 } tBTA_GATTC_API_OPEN;
 
 typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
@@ -202,6 +203,7 @@
     BD_ADDR                 remote_bda;
     tBTA_GATTC_IF           client_if;
     UINT8                   role;
+    tBT_TRANSPORT           transport;
     tGATT_DISCONN_REASON    reason;
 }tBTA_GATTC_INT_CONN;
 
@@ -340,7 +342,7 @@
 } tBTA_GATTC_SERV;
 
 #ifndef BTA_GATTC_NOTIF_REG_MAX
-#define BTA_GATTC_NOTIF_REG_MAX     7
+#define BTA_GATTC_NOTIF_REG_MAX     15
 #endif
 
 typedef struct
@@ -366,6 +368,7 @@
 {
     UINT16              bta_conn_id;    /* client channel ID, unique for clcb */
     BD_ADDR             bda;
+    tBTA_TRANSPORT      transport;      /* channel transport */
     tBTA_GATTC_RCB      *p_rcb;         /* pointer to the registration CB */
     tBTA_GATTC_SERV     *p_srcb;    /* server cache CB */
     tBTA_GATTC_DATA     *p_q_cmd;   /* command in queue waiting for execution */
@@ -375,6 +378,7 @@
 #define BTA_GATTC_REQ_WAITING       0x10
 
     UINT8               auto_update; /* auto update is waiting */
+    BOOLEAN             disc_active;
     BOOLEAN             in_use;
     tBTA_GATTC_STATE    state;
     tBTA_GATT_STATUS    status;
@@ -444,7 +448,7 @@
 **  Function prototypes
 *****************************************************************************/
 extern BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg);
-extern void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
+extern BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
 
 /* function processed outside SM */
 extern void bta_gattc_disable(tBTA_GATTC_CB *p_cb);
@@ -491,7 +495,7 @@
 extern void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg);
 extern void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data);
 extern void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
-                                       BD_ADDR remote_bda, UINT16 conn_id, UINT16 mtu);
+                                       BD_ADDR remote_bda, UINT16 conn_id, tBTA_TRANSPORT transport,  UINT16 mtu);
 extern void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
 extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
 #if BLE_INCLUDED == TRUE
@@ -499,11 +503,11 @@
 extern void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
 #endif
 /* utility functions */
-extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
 extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_conn_id (UINT16 conn_id);
-extern tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
 extern void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb);
-extern tBTA_GATTC_CLCB * bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
 extern tBTA_GATTC_RCB * bta_gattc_cl_get_regcb(UINT8 client_if);
 extern tBTA_GATTC_SERV * bta_gattc_find_srcb(BD_ADDR bda);
 extern tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda);
diff --git a/bta/gatt/bta_gattc_main.c b/bta/gatt/bta_gattc_main.c
index 932a1d7..7885fa6 100644
--- a/bta/gatt/bta_gattc_main.c
+++ b/bta/gatt/bta_gattc_main.c
@@ -288,18 +288,20 @@
 ** Description      State machine event handling function for GATTC
 **
 **
-** Returns          void
+** Returns          BOOLEAN  : TRUE if queued client request buffer can be immediately released
+**                                        else FALSE
 **
 *******************************************************************************/
-void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
+BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
 {
     tBTA_GATTC_ST_TBL     state_table;
     UINT8               action;
     int                 i;
+    BOOLEAN             rt = TRUE;
 #if BTA_GATT_DEBUG == TRUE
     tBTA_GATTC_STATE in_state = p_clcb->state;
     UINT16         in_event = event;
-    APPL_TRACE_DEBUG4("bta_gattc_sm_execute: State 0x%02x [%s], Event 0x%x[%s]", in_state,
+    APPL_TRACE_DEBUG("bta_gattc_sm_execute: State 0x%02x [%s], Event 0x%x[%s]", in_state,
                       gattc_state_code(in_state),
                       in_event,
                       gattc_evt_code(in_event));
@@ -320,6 +322,12 @@
         if ((action = state_table[event][i]) != BTA_GATTC_IGNORE)
         {
             (*bta_gattc_action[action])(p_clcb, p_data);
+            if (p_clcb->p_q_cmd == p_data) {
+                /* buffer is queued, don't free in the bta dispatcher.
+                 * we free it ourselves when a completion event is received.
+                 */
+                rt = FALSE;
+            }
         }
         else
         {
@@ -330,12 +338,13 @@
 #if BTA_GATT_DEBUG == TRUE
     if (in_state != p_clcb->state)
     {
-        APPL_TRACE_DEBUG3("GATTC State Change: [%s] -> [%s] after Event [%s]",
+        APPL_TRACE_DEBUG("GATTC State Change: [%s] -> [%s] after Event [%s]",
                           gattc_state_code(in_state),
                           gattc_state_code(p_clcb->state),
                           gattc_evt_code(in_event));
     }
 #endif
+    return rt;
 }
 
 /*******************************************************************************
@@ -345,7 +354,7 @@
 ** Description      GATT client main event handling function.
 **
 **
-** Returns          void
+** Returns          BOOLEAN
 **
 *******************************************************************************/
 BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
@@ -353,8 +362,9 @@
     tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
     tBTA_GATTC_CLCB *p_clcb = NULL;
     tBTA_GATTC_RCB      *p_clreg;
+    BOOLEAN             rt = TRUE;
 #if BTA_GATT_DEBUG == TRUE
-    APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event));
+    APPL_TRACE_DEBUG("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event));
 #endif
     switch (p_msg->event)
     {
@@ -410,18 +420,18 @@
 
             if (p_clcb != NULL)
             {
-                bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
+                rt = bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
             }
             else
             {
-                APPL_TRACE_DEBUG1("Ignore unknown conn ID: %d", p_msg->layer_specific);
+                APPL_TRACE_DEBUG("Ignore unknown conn ID: %d", p_msg->layer_specific);
             }
 
             break;
     }
 
 
-    return(TRUE);
+    return rt;
 }
 
 
diff --git a/bta/gatt/bta_gattc_utils.c b/bta/gatt/bta_gattc_utils.c
index b52e52c..a7a9557 100644
--- a/bta/gatt/bta_gattc_utils.c
+++ b/bta/gatt/bta_gattc_utils.c
@@ -163,7 +163,8 @@
 ** Returns          pointer to the clcb
 **
 *******************************************************************************/
-tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda,
+                                              tBTA_TRANSPORT transport)
 {
     tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
     UINT8   i;
@@ -172,6 +173,7 @@
     {
         if (p_clcb->in_use &&
             p_clcb->p_rcb->client_if == client_if &&
+            p_clcb->transport == transport &&
             bdcmp(p_clcb->bda, remote_bda) == 0)
             return p_clcb;
     }
@@ -209,7 +211,8 @@
 ** Returns          pointer to the clcb
 **
 *******************************************************************************/
-tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+                                       tBTA_TRANSPORT transport)
 {
     UINT8               i_clcb = 0;
     tBTA_GATTC_CLCB     *p_clcb = NULL;
@@ -219,11 +222,12 @@
         if (!bta_gattc_cb.clcb[i_clcb].in_use)
         {
 #if BTA_GATT_DEBUG == TRUE
-            APPL_TRACE_DEBUG1("bta_gattc_clcb_alloc: found clcb[%d] available",i_clcb);
+            APPL_TRACE_DEBUG("bta_gattc_clcb_alloc: found clcb[%d] available",i_clcb);
 #endif
             p_clcb                  = &bta_gattc_cb.clcb[i_clcb];
             p_clcb->in_use          = TRUE;
             p_clcb->status          = BTA_GATT_OK;
+            p_clcb->transport       = transport;
             bdcpy(p_clcb->bda, remote_bda);
 
             p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
@@ -256,13 +260,14 @@
 ** Returns          pointer to the clcb
 **
 *******************************************************************************/
-tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+                                           tBTA_TRANSPORT transport)
 {
     tBTA_GATTC_CLCB *p_clcb ;
 
-    if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda)) == NULL)
+    if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport)) == NULL)
     {
-        p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda);
+        p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
     }
     return p_clcb;
 }
@@ -303,7 +308,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR0("bta_gattc_clcb_dealloc p_clcb=NULL");
+        APPL_TRACE_ERROR("bta_gattc_clcb_dealloc p_clcb=NULL");
     }
 }
 
@@ -427,168 +432,20 @@
 *******************************************************************************/
 BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 {
-    BOOLEAN in_q = FALSE;
 
-    if (p_clcb->p_q_cmd == NULL && p_data)
-    {
-        UINT16 len;
-        switch (p_data->hdr.event)
-        {
-            case BTA_GATTC_API_SEARCH_EVT:
-            {
-                if (p_data->api_search.p_srvc_uuid)
-                {
-                    len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(tBT_UUID);
-                }
-                else
-                {
-                    len = sizeof(tBTA_GATTC_API_SEARCH);
-                }
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_SEARCH));
-                if (p_data->api_search.p_srvc_uuid)
-                {
-                    tBTA_GATTC_API_SEARCH *p_buf;
-                    p_buf = &(p_clcb->p_q_cmd->api_search);
-                    p_buf->p_srvc_uuid = (tBT_UUID *)(p_buf + 1);
-                    memcpy(p_buf->p_srvc_uuid, p_data->api_search.p_srvc_uuid,
-                           sizeof(tBT_UUID));
-                }
-                break;
-            }
-            case BTA_GATTC_API_READ_EVT:
-            {
-                if (p_data->api_read.p_descr_type)
-                {
-                    len = sizeof(tBTA_GATT_ID) + sizeof(tBTA_GATTC_API_READ);
-                }
-                else
-                {
-                    len = sizeof(tBTA_GATTC_API_READ);
-                }
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_READ));
-                if (p_data->api_read.p_descr_type)
-                {
-                    tBTA_GATTC_API_READ *p_buf;
-                    p_buf = &(p_clcb->p_q_cmd->api_read);
-                    p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
-                    memcpy(p_buf->p_descr_type, p_data->api_read.p_descr_type,
-                           sizeof(tBTA_GATT_ID));
-                }
-                break;
-            }
-            case BTA_GATTC_API_WRITE_EVT:
-            {
-                tBTA_GATTC_API_WRITE  *p_buf;
-                len = sizeof(tBTA_GATTC_API_WRITE) + p_data->api_write.len;
-                if (p_data->api_write.p_descr_type)
-                {
-                    len += sizeof(tBTA_GATT_ID);
-                }
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_WRITE));
-                p_buf = &(p_clcb->p_q_cmd->api_write);
-                if (p_data->api_write.p_descr_type)
-                {
-                    p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
-                    memcpy(p_buf->p_descr_type, p_data->api_write.p_descr_type,
-                           sizeof(tBTA_GATT_ID));
-                    if (p_buf->len && p_buf->p_value)
-                    {
-                        p_buf->p_value  = (UINT8 *)(p_buf->p_descr_type + 1);
-                        memcpy(p_buf->p_value, p_data->api_write.p_value,
-                               p_data->api_write.len);
-                    }
-                }
-                else if (p_buf->len && p_buf->p_value)
-                {
-                    p_buf->p_value = (UINT8 *)(p_buf + 1);
-                    memcpy(p_buf->p_value, p_data->api_write.p_value,
-                           p_data->api_write.len);
-                }
-                break;
-            }
-            case BTA_GATTC_API_EXEC_EVT:
-            {
-                len = sizeof(tBTA_GATTC_API_EXEC);
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, len);
-                break;
-            }
-            case BTA_GATTC_API_READ_MULTI_EVT:
-            {
-                len = sizeof(tBTA_GATTC_API_READ_MULTI) +
-                      p_data->api_read_multi.num_attr * sizeof(tBTA_GATTC_ATTR_ID);
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_READ_MULTI));
-                if (p_data->api_read_multi.num_attr &&
-                    p_data->api_read_multi.p_id_list)
-                {
-                    tBTA_GATTC_API_READ_MULTI *p_buf;
-                    p_buf = &(p_clcb->p_q_cmd->api_read_multi);
-                    p_buf->p_id_list = (tBTA_GATTC_ATTR_ID *)(p_buf + 1);
-                    memcpy(p_buf->p_id_list, p_data->api_read_multi.p_id_list,
-                        p_data->api_read_multi.num_attr * sizeof(tBTA_GATTC_ATTR_ID));
-                }
-                break;
-            }
-            case BTA_GATTC_API_CFG_MTU_EVT:
-            {
-                len = sizeof(tBTA_GATTC_API_CFG_MTU);
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, len);
-                break;
-            }
-            default:
-                APPL_TRACE_ERROR1("queue unsupported command %d", p_data->hdr.event);
-                return FALSE;
-        }
+ if (p_clcb->p_q_cmd == NULL)
+ {
+     p_clcb->p_q_cmd = p_data;
+ }
+ else
+ {
+     APPL_TRACE_ERROR("already has a pending command!!");
+     /* skip the callback now. ----- need to send callback ? */
+ }
+ return (p_clcb->p_q_cmd != NULL) ? TRUE : FALSE;
 
-        in_q = TRUE;
-    }
-    else if (p_clcb->p_q_cmd)
-    {
-        APPL_TRACE_ERROR0("already has a pending command!!");
-        /* skip the callback now. ----- need to send callback ? */
-    }
-    else
-    {
-        APPL_TRACE_ERROR0("queue a null command");
-    }
-
-    return in_q;
 }
+
 /*******************************************************************************
 **
 ** Function         bta_gattc_pack_attr_uuid
@@ -716,7 +573,7 @@
             bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
             bta_gattc_charid_compare (&p_clreg->notif_reg[i].char_id, &p_notify->char_id))
         {
-            APPL_TRACE_DEBUG0("Notification registered!");
+            APPL_TRACE_DEBUG("Notification registered!");
             return TRUE;
         }
     }
@@ -738,21 +595,23 @@
     tBTA_GATTC_IF       gatt_if;
     tBTA_GATTC_RCB      *p_clrcb ;
     UINT8       i;
+    tGATT_TRANSPORT     transport;
 
-    if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda))
+    if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
     {
         if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL)
         {
             for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
             {
-                if (p_clrcb->notif_reg[i].in_use && !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
+                if (p_clrcb->notif_reg[i].in_use &&
+                    !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
                     memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
             }
         }
     }
     else
     {
-        APPL_TRACE_ERROR0("can not clear indication/notif registration for unknown app");
+        APPL_TRACE_ERROR("can not clear indication/notif registration for unknown app");
     }
     return;
 }
@@ -790,7 +649,7 @@
                                     &p_value->aggre_value.pre_format[i].descr_id) == FALSE)
             {
                 status = BTA_GATT_INTERNAL_ERROR;
-                APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", handle);
+                APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x", handle);
                 break;
             }
             i ++;
@@ -851,7 +710,7 @@
     }
     if (!add)
     {
-        APPL_TRACE_ERROR0("Do not find the bg connection mask for the remote device");
+        APPL_TRACE_ERROR("Do not find the bg connection mask for the remote device");
         return FALSE;
     }
     else /* adding a new device mask */
@@ -873,7 +732,7 @@
                 return TRUE;
             }
         }
-        APPL_TRACE_ERROR0("no available space to mark the bg connection status");
+        APPL_TRACE_ERROR("no available space to mark the bg connection status");
         return FALSE;
     }
 }
@@ -919,7 +778,8 @@
 **
 *******************************************************************************/
 void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
-                                BD_ADDR remote_bda, UINT16 conn_id, UINT16 mtu)
+                                BD_ADDR remote_bda, UINT16 conn_id,
+                                tBTA_TRANSPORT transport, UINT16 mtu)
 {
     tBTA_GATTC      cb_data;
 
@@ -931,6 +791,7 @@
         cb_data.open.client_if = p_clreg->client_if;
         cb_data.open.conn_id = conn_id;
         cb_data.open.mtu = mtu;
+        cb_data.open.transport = transport;
         bdcpy(cb_data.open.remote_bda, remote_bda);
 
         (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
@@ -955,7 +816,7 @@
         if (!p_conn->in_use)
         {
 #if BTA_GATT_DEBUG == TRUE
-            APPL_TRACE_DEBUG1("bta_gattc_conn_alloc: found conn_track[%d] available",i_conn);
+            APPL_TRACE_DEBUG("bta_gattc_conn_alloc: found conn_track[%d] available",i_conn);
 #endif
             p_conn->in_use          = TRUE;
             bdcpy(p_conn->remote_bda, remote_bda);
@@ -984,7 +845,7 @@
         if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0)
         {
 #if BTA_GATT_DEBUG == TRUE
-            APPL_TRACE_DEBUG1("bta_gattc_conn_find: found conn_track[%d] matched",i_conn);
+            APPL_TRACE_DEBUG("bta_gattc_conn_find: found conn_track[%d] matched",i_conn);
 #endif
             return p_conn;
         }
@@ -1053,16 +914,19 @@
 
     /* try to locate a logic channel */
     if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
-                                             p_msg->int_conn.remote_bda)) == NULL)
+                                             p_msg->int_conn.remote_bda,
+                                             p_msg->int_conn.transport)) == NULL)
     {
         /* for a background connection or listening connection */
-        if (p_msg->int_conn.role == HCI_ROLE_SLAVE ||
+        if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE ||  */
             bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
                                     p_msg->int_conn.remote_bda,
                                     p_msg->int_conn.role))
         {
             /* allocate a new channel */
-            p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if, p_msg->int_conn.remote_bda);
+            p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
+                                          p_msg->int_conn.remote_bda,
+                                          p_msg->int_conn.transport);
         }
     }
     return p_clcb;
@@ -1083,16 +947,17 @@
     tGATT_DISCONN_REASON    reason = p_msg->int_conn.reason;
 
     bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
-    /* connection attempt timeout, send connection callback event */
-    if (reason == GATT_CONN_CANCEL || reason == GATT_CONN_L2C_FAILURE)
+    if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
     {
+        /* connection attempt failed, send connection callback event */
         p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
-                                            p_msg->int_conn.remote_bda);
+                                            p_msg->int_conn.remote_bda,
+                                            p_msg->int_conn.transport);
     }
-    else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
+    if (p_clcb == NULL)
     {
-        APPL_TRACE_DEBUG1("disconnection ID: [%d] not used by BTA",
-                           p_msg->int_conn.hdr.layer_specific);
+        APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
+            p_msg->int_conn.hdr.layer_specific);
     }
     return p_clcb;
 }
diff --git a/bta/gatt/bta_gatts_act.c b/bta/gatt/bta_gatts_act.c
index be03655..20faa62 100644
--- a/bta/gatt/bta_gatts_act.c
+++ b/bta/gatt/bta_gatts_act.c
@@ -37,12 +37,17 @@
 #include <string.h>
 
 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
-static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp);
+static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
+                                                tGATTS_SRV_CHG_RSP *p_rsp);
 
-static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
+                                      BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                      tGATT_TRANSPORT transport);
 static void bta_gatts_send_request_cback (UINT16 conn_id,
                                           UINT32 trans_id,
                                           tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
+static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);
+
 static tGATT_CBACK bta_gatts_cback =
 {
     bta_gatts_conn_cback,
@@ -50,7 +55,8 @@
     NULL,
     NULL,
     bta_gatts_send_request_cback,
-    NULL
+    NULL,
+    bta_gatts_cong_cback
 };
 
 tGATT_APPL_INFO bta_gatts_nv_cback =
@@ -85,7 +91,8 @@
 ** Returns          none.
 **
 *******************************************************************************/
-static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
+static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
+                                              tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
 {
     return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
                                 (tBTA_GATTS_SRV_CHG_REQ *) p_req,
@@ -110,7 +117,7 @@
 
     if (p_cb->enabled)
     {
-        APPL_TRACE_DEBUG0("GATTS already enabled.");
+        APPL_TRACE_DEBUG("GATTS already enabled.");
     }
     else
     {
@@ -125,11 +132,11 @@
             index++;
         }
 
-        APPL_TRACE_DEBUG1("bta_gatts_enable: num of handle range added=%d", index);
+        APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);
 
         if (!GATTS_NVRegister(&bta_gatts_nv_cback))
         {
-            APPL_TRACE_ERROR0("BTA GATTS NV register failed.");
+            APPL_TRACE_ERROR("BTA GATTS NV register failed.");
             status = BTA_GATT_ERROR;
         }
     }
@@ -162,7 +169,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR0("GATTS not enabled");
+        APPL_TRACE_ERROR("GATTS not enabled");
     }
 }
 
@@ -193,7 +200,7 @@
         {
             if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid))
             {
-                APPL_TRACE_ERROR0("application already registered.");
+                APPL_TRACE_ERROR("application already registered.");
                 status = BTA_GATT_DUP_REG;
                 break;
             }
@@ -217,20 +224,22 @@
 // btla-specific --
         if (first_unuse != 0xff)
         {
-            APPL_TRACE_ERROR1("register application first_unuse rcb_idx = %d", first_unuse);
+            APPL_TRACE_ERROR("register application first_unuse rcb_idx = %d", first_unuse);
 
             p_cb->rcb[first_unuse].in_use = TRUE;
             p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
             memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
             cb_data.reg_oper.server_if      =
-            p_cb->rcb[first_unuse].gatt_if  = GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
+            p_cb->rcb[first_unuse].gatt_if  =
+            GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
             if ( !p_cb->rcb[first_unuse].gatt_if)
             {
                 status = BTA_GATT_NO_RESOURCES;
             }
             else
             {
-                if ((p_buf = (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
+                if ((p_buf =
+                  (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
                 {
                     p_buf->hdr.event    = BTA_GATTS_INT_START_IF_EVT;
                     p_buf->server_if    = p_cb->rcb[first_unuse].gatt_if;
@@ -275,7 +284,8 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.server_if );
+        APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
+            p_msg->int_start_if.server_if );
     }
 }
 /*******************************************************************************
@@ -320,7 +330,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR0("application not registered.");
+        APPL_TRACE_ERROR("application not registered.");
     }
 }
 /*******************************************************************************
@@ -343,7 +353,7 @@
 
     rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);
 
-    APPL_TRACE_ERROR1("create service rcb_idx = %d", rcb_idx);
+    APPL_TRACE_ERROR("create service rcb_idx = %d", rcb_idx);
 
     if (rcb_idx != BTA_GATTS_INVALID_APP)
     {
@@ -358,7 +368,8 @@
 
             if (service_id != 0)
             {
-                memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
+                memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
+                    &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
                 p_cb->srvc_cb[srvc_idx].service_id   = service_id;
                 p_cb->srvc_cb[srvc_idx].inst_num     = p_msg->api_create_svc.inst;
                 p_cb->srvc_cb[srvc_idx].idx          = srvc_idx;
@@ -374,7 +385,7 @@
             {
                 cb_data.status  = BTA_GATT_ERROR;
                 memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
-                APPL_TRACE_ERROR0("service creation failed.");
+                APPL_TRACE_ERROR("service creation failed.");
             }
 // btla-specific ++
             memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
@@ -386,7 +397,7 @@
     }
     else /* application not registered */
     {
-        APPL_TRACE_ERROR0("Application not registered");
+        APPL_TRACE_ERROR("Application not registered");
     }
 }
 /*******************************************************************************
@@ -554,7 +565,7 @@
                            p_srvc_cb->service_id,
                            p_msg->api_start.transport) ==  GATT_SUCCESS)
     {
-        APPL_TRACE_DEBUG1("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
+        APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
         cb_data.srvc_oper.status = BTA_GATT_OK;
     }
     else
@@ -585,7 +596,7 @@
     cb_data.srvc_oper.server_if = p_rcb->gatt_if;
     cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
     cb_data.srvc_oper.status = BTA_GATT_OK;
-    APPL_TRACE_ERROR1("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
+    APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
 
     if (p_rcb->p_cback)
         (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
@@ -609,7 +620,7 @@
                         p_msg->api_rsp.status,
                         (tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS)
     {
-        APPL_TRACE_ERROR0("Sending response failed");
+        APPL_TRACE_ERROR("Sending response failed");
     }
 
 }
@@ -617,11 +628,7 @@
 **
 ** Function         bta_gatts_indicate_handle
 **
-<<<<<<< HEAD
-** Description      GATTS indicate handel value
-=======
 ** Description      GATTS send handle value indication or notification.
->>>>>>> 6ea30bf... LE: UPF 45 bug fixes
 **
 ** Returns          none.
 **
@@ -629,17 +636,22 @@
 void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
 {
     tBTA_GATTS_SRVC_CB  *p_srvc_cb;
+    tBTA_GATTS_RCB      *p_rcb = NULL;
     tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
     tGATT_IF            gatt_if;
     BD_ADDR             remote_bda;
-
+    tBTA_TRANSPORT transport;
+    tBTA_GATTS          cb_data;
 
     p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
 
     if (p_srvc_cb )
     {
-        if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific, &gatt_if, remote_bda))
+        if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
+            &gatt_if, remote_bda, &transport))
         {
+            p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
+
             if (p_msg->api_indicate.need_confirm)
 
                 status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
@@ -653,7 +665,7 @@
                                                         p_msg->api_indicate.value);
 
             /* if over BR_EDR, inform PM for mode change */
-            if (!BTM_IsBleLink(remote_bda))
+            if (transport == BTA_TRANSPORT_BR_EDR)
             {
                 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
                 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
@@ -661,19 +673,22 @@
         }
         else
         {
-            APPL_TRACE_ERROR1("Unknown connection ID: %d fail sending notification",
+            APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
                               p_msg->api_indicate.hdr.layer_specific);
         }
 
-        if (status != GATT_SUCCESS && p_msg->api_indicate.need_confirm &&
-            p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
+        if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
+            p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
         {
-            (*p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)(BTA_GATTS_CONF_EVT, (tBTA_GATTS *)&status);
+            cb_data.req_data.status = status;
+            cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
+
+            (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
         }
     }
     else
     {
-        APPL_TRACE_ERROR1("Not an registered servce attribute ID: 0x%04x",
+        APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
                           p_msg->api_indicate.attr_id);
     }
 }
@@ -692,18 +707,27 @@
 {
     tBTA_GATTS_RCB      *p_rcb=NULL;
     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
+    UINT16              conn_id;
     UNUSED(p_cb);
 
     if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
     {
-        if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, p_msg->api_open.is_direct))
+        /* should always get the connection ID */
+        if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
+                        p_msg->api_open.is_direct, p_msg->api_open.transport))
         {
             status = BTA_GATT_OK;
+
+            if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
+                                            &conn_id, p_msg->api_open.transport))
+            {
+                status = BTA_GATT_ALREADY_OPEN;
+            }
         }
     }
     else
     {
-        APPL_TRACE_ERROR1("Inavlide server_if=%d", p_msg->api_open.server_if);
+        APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
     }
 
     if (p_rcb && p_rcb->p_cback)
@@ -727,9 +751,10 @@
 
     if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
     {
-        if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, p_msg->api_cancel_open.is_direct))
+        if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
+                                p_msg->api_cancel_open.is_direct))
         {
-            APPL_TRACE_ERROR0("bta_gatts_cancel_open failed for open request");
+            APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
         }
         else
         {
@@ -738,7 +763,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
+        APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
     }
 
     if (p_rcb && p_rcb->p_cback)
@@ -759,13 +784,15 @@
     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
     tGATT_IF            gatt_if;
     BD_ADDR             remote_bda;
+    tBTA_GATT_TRANSPORT transport;
+
     UNUSED(p_cb);
 
-    if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda))
+    if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
     {
         if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
         {
-            APPL_TRACE_ERROR1("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
+            APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
         }
         else
         {
@@ -776,7 +803,7 @@
 
         if (p_rcb && p_rcb->p_cback)
         {
-            if (!BTM_IsBleLink(remote_bda))
+            if (transport == BTA_TRANSPORT_BR_EDR)
                 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);
 
             (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT,  (tBTA_GATTS *)&status);
@@ -784,7 +811,7 @@
     }
     else
     {
-        APPL_TRACE_ERROR1("Unknown connection ID: %d", p_msg->hdr.layer_specific);
+        APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
     }
 
 }
@@ -808,7 +835,7 @@
 
     if (p_rcb == NULL)
     {
-        APPL_TRACE_ERROR0("Unknown GATTS application");
+        APPL_TRACE_ERROR("Unknown GATTS application");
         return;
     }
 
@@ -817,7 +844,7 @@
                      p_msg->api_listen.remote_bda))
     {
         cb_data.status = BTA_GATT_ERROR;
-        APPL_TRACE_ERROR0("bta_gatts_listen Listen failed");
+        APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
     }
 
     if (p_rcb->p_cback)
@@ -840,19 +867,21 @@
     tBTA_GATTS          cb_data;
     tBTA_GATTS_RCB     *p_rcb;
     tGATT_IF            gatt_if;
+    tBTA_GATT_TRANSPORT transport;
 
     memset(&cb_data, 0 , sizeof(tBTA_GATTS));
 
-    if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda))
+    if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
     {
         p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
 
-        APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d", conn_id, trans_id, req_type);
+        APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
+                            conn_id, trans_id, req_type);
 
         if (p_rcb && p_rcb->p_cback)
         {
             /* if over BR_EDR, inform PM for mode change */
-            if (!BTM_IsBleLink(cb_data.req_data.remote_bda))
+            if (transport == BTA_TRANSPORT_BR_EDR)
             {
                 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
                 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
@@ -866,12 +895,12 @@
         }
         else
         {
-            APPL_TRACE_ERROR1("connection request on gatt_if[%d] is not interested", gatt_if);
+            APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
         }
     }
     else
     {
-        APPL_TRACE_ERROR1("request received on unknown connectino ID: %d", conn_id);
+        APPL_TRACE_ERROR("request received on unknown connectino ID: %d", conn_id);
     }
 }
 
@@ -885,15 +914,16 @@
 **
 *******************************************************************************/
 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
-                                  BOOLEAN connected, tGATT_DISCONN_REASON reason)
+                                  BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                  tGATT_TRANSPORT transport)
 {
     tBTA_GATTS      cb_data;
     UINT8           evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
     tBTA_GATTS_RCB  *p_reg;
 
-    APPL_TRACE_DEBUG4 ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
+    APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
                         gatt_if, conn_id, connected, reason);
-    APPL_TRACE_DEBUG6("bta_gatts_conn_cback  bda :%02x-%02x-%02x-%02x-%02x-%02x ",
+    APPL_TRACE_DEBUG("bta_gatts_conn_cback  bda :%02x-%02x-%02x-%02x-%02x-%02x ",
                       bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);
 
     p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
@@ -901,7 +931,7 @@
     if (p_reg && p_reg->p_cback)
     {
         /* there is no RM for GATT */
-        if (!BTM_IsBleLink(bda))
+        if (transport == BTA_TRANSPORT_BR_EDR)
         {
             if (connected)
                 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
@@ -912,12 +942,43 @@
         cb_data.conn.conn_id = conn_id;
         cb_data.conn.server_if = gatt_if;
         cb_data.conn.reason = reason;
+        cb_data.conn.transport = transport;
         memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
         (*p_reg->p_cback)(evt, &cb_data);
     }
     else
     {
-        APPL_TRACE_ERROR1("bta_gatts_conn_cback server_if=%d not found",gatt_if);
+        APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found",gatt_if);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_gatts_cong_cback
+**
+** Description      congestion callback.
+**
+** Returns          none.
+**
+*******************************************************************************/
+static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
+{
+    tBTA_GATTS_RCB *p_rcb;
+    tGATT_IF gatt_if;
+    tBTA_GATT_TRANSPORT transport;
+    tBTA_GATTS cb_data;
+
+    if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
+    {
+        p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
+
+        if (p_rcb && p_rcb->p_cback)
+        {
+            cb_data.congest.conn_id = conn_id;
+            cb_data.congest.congested = congested;
+
+            (*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
+        }
     }
 }
 #endif /* BTA_GATT_INCLUDED */
diff --git a/bta/gatt/bta_gatts_api.c b/bta/gatt/bta_gatts_api.c
index ad30d73..e2f1874 100644
--- a/bta/gatt/bta_gatts_api.c
+++ b/bta/gatt/bta_gatts_api.c
@@ -59,7 +59,7 @@
 
     if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
     {
-        APPL_TRACE_WARNING0("GATTS Module not enabled/already disabled");
+        APPL_TRACE_WARNING("GATTS Module not enabled/already disabled");
         return;
     }
 
@@ -90,11 +90,9 @@
     tBTA_GATTS_API_REG  *p_buf;
 
     /* register with BTA system manager */
-   if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
-   {
-        GKI_sched_lock();
+    if (bta_sys_is_register(BTA_ID_GATTS) == FALSE)
+    {
         bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg);
-        GKI_sched_unlock();
     }
 
     if ((p_buf = (tBTA_GATTS_API_REG *) GKI_getbuf(sizeof(tBTA_GATTS_API_REG))) != NULL)
@@ -464,11 +462,13 @@
 ** Parameters       server_if: server interface.
 **                  remote_bda: remote device BD address.
 **                  is_direct: direct connection or background auto connection
+**                  transport : Transport on which GATT connection to be opened (BR/EDR or LE)
 **
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct)
+void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct,
+                    tBTA_GATT_TRANSPORT transport)
 {
     tBTA_GATTS_API_OPEN  *p_buf;
 
@@ -477,6 +477,7 @@
         p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
         p_buf->server_if = server_if;
         p_buf->is_direct = is_direct;
+        p_buf->transport = transport;
         memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
 
         bta_sys_sendmsg(p_buf);
diff --git a/bta/gatt/bta_gatts_int.h b/bta/gatt/bta_gatts_int.h
index ce9553a..9a12dfd 100644
--- a/bta/gatt/bta_gatts_int.h
+++ b/bta/gatt/bta_gatts_int.h
@@ -139,10 +139,12 @@
 
 typedef struct
 {
-    BT_HDR              hdr;
-    BD_ADDR             remote_bda;
-    tBTA_GATTS_IF       server_if;
-    BOOLEAN             is_direct;
+    BT_HDR                  hdr;
+    BD_ADDR                 remote_bda;
+    tBTA_GATTS_IF           server_if;
+    BOOLEAN                 is_direct;
+    tBTA_GATT_TRANSPORT     transport;
+
 }tBTA_GATTS_API_OPEN;
 
 typedef tBTA_GATTS_API_OPEN tBTA_GATTS_API_CANCEL_OPEN;
diff --git a/bta/gatt/bta_gatts_main.c b/bta/gatt/bta_gatts_main.c
index 02810fc..9bcb471 100644
--- a/bta/gatt/bta_gatts_main.c
+++ b/bta/gatt/bta_gatts_main.c
@@ -128,7 +128,7 @@
             }
             else
             {
-                APPL_TRACE_ERROR0("service not created");
+                APPL_TRACE_ERROR("service not created");
             }
             break;
 
diff --git a/bta/gatt/bta_gatts_utils.c b/bta/gatt/bta_gatts_utils.c
index 5145c95..e7ac1e3 100644
--- a/bta/gatt/bta_gatts_utils.c
+++ b/bta/gatt/bta_gatts_utils.c
@@ -133,13 +133,13 @@
 tBTA_GATTS_SRVC_CB * bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB *p_cb, UINT16 service_id)
 {
     UINT8 i;
-    APPL_TRACE_DEBUG1("bta_gatts_find_srvc_cb_by_srvc_id  service_id=%d", service_id);
+    APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id  service_id=%d", service_id);
     for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++)
     {
         if (p_cb->srvc_cb[i].in_use &&
             p_cb->srvc_cb[i].service_id == service_id)
         {
-            APPL_TRACE_DEBUG1("bta_gatts_find_srvc_cb_by_srvc_id  found service cb index =%d", i);
+            APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id  found service cb index =%d", i);
             return &p_cb->srvc_cb[i];
         }
     }
diff --git a/bta/hf_client/bta_hf_client_act.c b/bta/hf_client/bta_hf_client_act.c
new file mode 100644
index 0000000..8e37909
--- /dev/null
+++ b/bta/hf_client/bta_hf_client_act.c
@@ -0,0 +1,768 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2014 The Android Open Source Project
+ *  Copyright (C) 2003-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 action functions for the handsfree client.
+ *
+ ******************************************************************************/
+
+#include "bta_api.h"
+#include "bd.h"
+#include "bta_hf_client_api.h"
+#include "bta_hf_client_int.h"
+#include "bta_dm_int.h"
+#include "l2c_api.h"
+#include "port_api.h"
+#include "bta_sys.h"
+#include "utl.h"
+#include "bt_utils.h"
+#include <string.h>
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/* maximum length of data to read from RFCOMM */
+#define BTA_HF_CLIENT_RFC_READ_MAX     512
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_register
+**
+** Description      This function initializes values of the scb and sets up
+**                  the SDP record for the services.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_register(tBTA_HF_CLIENT_DATA *p_data)
+{
+    tBTA_HF_CLIENT evt;
+    tBTA_UTL_COD   cod;
+
+    memset(&evt, 0, sizeof(evt));
+
+    /* initialize control block */
+    bta_hf_client_scb_init();
+
+    bta_hf_client_cb.scb.serv_sec_mask = p_data->api_register.sec_mask;
+    bta_hf_client_cb.scb.features = p_data->api_register.features;
+
+    /* initialize AT control block */
+    bta_hf_client_at_init();
+
+    /* create SDP records */
+    bta_hf_client_create_record(p_data);
+
+    /* Set the Audio service class bit */
+    cod.service = BTM_COD_SERVICE_AUDIO;
+    utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
+
+    /* start RFCOMM server */
+    bta_hf_client_start_server();
+
+    /* call app callback with register event */
+    evt.reg.status = BTA_HF_CLIENT_SUCCESS;
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_REGISTER_EVT, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_deregister
+**
+** Description      This function removes the sdp records, closes the RFCOMM
+**                  servers, and deallocates the service control block.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_deregister(tBTA_HF_CLIENT_DATA *p_data)
+{
+    bta_hf_client_cb.scb.deregister = TRUE;
+
+    /* remove sdp record */
+    bta_hf_client_del_record(p_data);
+
+    /* remove rfcomm server */
+    bta_hf_client_close_server();
+
+    /* disable */
+    bta_hf_client_scb_disable();
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_start_dereg
+**
+** Description      Start a deregister event.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_start_dereg(tBTA_HF_CLIENT_DATA *p_data)
+{
+    bta_hf_client_cb.scb.deregister = TRUE;
+
+    /* remove sdp record */
+    bta_hf_client_del_record(p_data);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_start_close
+**
+** Description      Start the process of closing SCO and RFCOMM connection.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA *p_data)
+{
+    /* Take the link out of sniff and set L2C idle time to 0 */
+    bta_dm_pm_active(bta_hf_client_cb.scb.peer_addr);
+    L2CA_SetIdleTimeoutByBdAddr(bta_hf_client_cb.scb.peer_addr, 0);
+
+    /* if SCO is open close SCO and wait on RFCOMM close */
+    if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST)
+    {
+        bta_hf_client_cb.scb.sco_close_rfc = TRUE;
+    }
+    else
+    {
+        bta_hf_client_rfc_do_close(p_data);
+    }
+
+    /* always do SCO shutdown to handle all SCO corner cases */
+    bta_hf_client_sco_shutdown(NULL);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_start_open
+**
+** Description      This starts an HF Client open.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA *p_data)
+{
+    BD_ADDR pending_bd_addr;
+
+    /* store parameters */
+    if (p_data)
+    {
+        bdcpy(bta_hf_client_cb.scb.peer_addr, p_data->api_open.bd_addr);
+        bta_hf_client_cb.scb.cli_sec_mask = p_data->api_open.sec_mask;
+    }
+
+    /* Check if RFCOMM has any incoming connection to avoid collision. */
+    if (PORT_IsOpening (pending_bd_addr))
+    {
+        /* Let the incoming connection goes through.                        */
+        /* Issue collision for now.                                         */
+        /* We will decide what to do when we find incoming connection later.*/
+        bta_hf_client_collision_cback (0, BTA_ID_HS, 0, bta_hf_client_cb.scb.peer_addr);
+        return;
+    }
+
+    /* close server */
+    bta_hf_client_close_server();
+
+    /* set role */
+    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_INT;
+
+    /* do service search */
+    bta_hf_client_do_disc();
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_cback_open
+**
+** Description      Send open callback event to application.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_hf_client_cback_open(tBTA_HF_CLIENT_DATA *p_data, tBTA_HF_CLIENT_STATUS status)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    /* call app callback with open event */
+    evt.open.status = status;
+    if(p_data)
+    {
+        /* if p_data is provided then we need to pick the bd address from the open api structure */
+        bdcpy(evt.open.bd_addr, p_data->api_open.bd_addr);
+    }
+    else
+    {
+        bdcpy(evt.open.bd_addr, bta_hf_client_cb.scb.peer_addr);
+    }
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPEN_EVT, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_rfc_open
+**
+** Description      Handle RFCOMM channel open.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA *p_data)
+{
+    UNUSED(p_data);
+
+    bta_sys_conn_open(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
+
+    bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_SUCCESS);
+
+    /* start SLC procedure */
+    bta_hf_client_slc_seq(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_rfc_acp_open
+**
+** Description      Handle RFCOMM channel open when accepting connection.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data)
+{
+    UINT16          lcid;
+    int             i;
+    BD_ADDR         dev_addr;
+    int             status;
+
+    /* set role */
+    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
+
+    APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open: serv_handle = %d rfc.port_handle = %d",
+            bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle);
+
+    /* get bd addr of peer */
+    if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid)))
+    {
+        APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status);
+    }
+
+    /* Collision Handling */
+    if (bta_hf_client_cb.scb.colli_tmr_on)
+    {
+        /* stop collision timer */
+        bta_hf_client_cb.scb.colli_tmr_on = FALSE;
+        bta_sys_stop_timer (&bta_hf_client_cb.scb.colli_timer);
+
+        if (bdcmp (dev_addr, bta_hf_client_cb.scb.peer_addr) == 0)
+        {
+            /* If incoming and outgoing device are same, nothing more to do.            */
+            /* Outgoing conn will be aborted because we have successful incoming conn.  */
+        }
+        else
+        {
+            /* Resume outgoing connection. */
+            bta_hf_client_resume_open ();
+        }
+    }
+
+    bdcpy (bta_hf_client_cb.scb.peer_addr, dev_addr);
+    bta_hf_client_cb.scb.conn_handle = p_data->rfc.port_handle;
+
+    /* do service discovery to get features */
+    bta_hf_client_do_disc();
+
+    /* continue with open processing */
+    bta_hf_client_rfc_open(p_data);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_rfc_fail
+**
+** Description      RFCOMM connection failed.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA *p_data)
+{
+    UNUSED(p_data);
+
+    /* reinitialize stuff */
+    bta_hf_client_cb.scb.conn_handle = 0;
+    bta_hf_client_cb.scb.peer_features = 0;
+    bta_hf_client_cb.scb.chld_features = 0;
+    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
+    bta_hf_client_cb.scb.svc_conn = FALSE;
+    bta_hf_client_cb.scb.send_at_reply = FALSE;
+    bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
+
+    bta_hf_client_at_reset();
+
+    /* reopen server */
+    bta_hf_client_start_server();
+
+    /* call open cback w. failure */
+    bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_RFCOMM);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_disc_fail
+**
+** Description      This function handles a discovery failure.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA *p_data)
+{
+    UNUSED(p_data);
+
+    /* reopen server */
+    bta_hf_client_start_server();
+
+    /* reinitialize stuff */
+
+    /* call open cback w. failure */
+    bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_SDP);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_open_fail
+**
+** Description      open connection failed.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA *p_data)
+{
+    /* call open cback w. failure */
+    bta_hf_client_cback_open(p_data, BTA_HF_CLIENT_FAIL_RESOURCES);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_rfc_close
+**
+** Description      RFCOMM connection closed.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data)
+{
+    int i, num_active_conn = 0;
+    UNUSED(p_data);
+
+    /* reinitialize stuff */
+    bta_hf_client_cb.scb.peer_features = 0;
+    bta_hf_client_cb.scb.chld_features = 0;
+    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
+    bta_hf_client_cb.scb.svc_conn = FALSE;
+    bta_hf_client_cb.scb.send_at_reply = FALSE;
+    bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
+
+    bta_hf_client_at_reset();
+
+    bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
+
+    /* call close cback */
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL);
+
+    /* if not deregistering reopen server */
+    if (bta_hf_client_cb.scb.deregister == FALSE)
+    {
+        /* Clear peer bd_addr so instance can be reused */
+        bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null);
+
+        /* start server as it might got closed on open*/
+        bta_hf_client_start_server();
+
+        bta_hf_client_cb.scb.conn_handle = 0;
+
+        /* Make sure SCO is shutdown */
+        bta_hf_client_sco_shutdown(NULL);
+
+        bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
+    }
+    /* else close port and deallocate scb */
+    else
+    {
+        bta_hf_client_close_server();
+        bta_hf_client_scb_disable();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_disc_int_res
+**
+** Description      This function handles a discovery result when initiator.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA *p_data)
+{
+    UINT16 event = BTA_HF_CLIENT_DISC_FAIL_EVT;
+
+    APPL_TRACE_DEBUG ("bta_hf_client_disc_int_res: Status: %d", p_data->disc_result.status);
+
+    /* if found service */
+    if (p_data->disc_result.status == SDP_SUCCESS ||
+        p_data->disc_result.status == SDP_DB_FULL)
+    {
+        /* get attributes */
+        if (bta_hf_client_sdp_find_attr())
+        {
+            event = BTA_HF_CLIENT_DISC_OK_EVT;
+        }
+    }
+
+    /* free discovery db */
+    bta_hf_client_free_db(p_data);
+
+    /* send ourselves sdp ok/fail event */
+    bta_hf_client_sm_execute(event, p_data);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_disc_acp_res
+**
+** Description      This function handles a discovery result when acceptor.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA *p_data)
+{
+    /* if found service */
+    if (p_data->disc_result.status == SDP_SUCCESS ||
+        p_data->disc_result.status == SDP_DB_FULL)
+    {
+        /* get attributes */
+        bta_hf_client_sdp_find_attr();
+    }
+
+    /* free discovery db */
+    bta_hf_client_free_db(p_data);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_rfc_data
+**
+** Description      Read and process data from RFCOMM.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA *p_data)
+{
+    UINT16  len;
+    char    buf[BTA_HF_CLIENT_RFC_READ_MAX];
+    UNUSED(p_data);
+
+    memset(buf, 0, sizeof(buf));
+
+    /* read data from rfcomm; if bad status, we're done */
+    while (PORT_ReadData(bta_hf_client_cb.scb.conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX, &len) == PORT_SUCCESS)
+    {
+        /* if no data, we're done */
+        if (len == 0)
+        {
+            break;
+        }
+
+        bta_hf_client_at_parse(buf, len);
+
+        /* no more data to read, we're done */
+        if (len < BTA_HF_CLIENT_RFC_READ_MAX)
+        {
+            break;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_svc_conn_open
+**
+** Description      Service level connection opened
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA *p_data)
+{
+    tBTA_HF_CLIENT evt;
+    UNUSED(p_data);
+
+    memset(&evt, 0, sizeof(evt));
+
+    if (!bta_hf_client_cb.scb.svc_conn)
+    {
+        /* set state variable */
+        bta_hf_client_cb.scb.svc_conn = TRUE;
+
+        /* call callback */
+        evt.conn.peer_feat = bta_hf_client_cb.scb.peer_features;
+        evt.conn.chld_feat = bta_hf_client_cb.scb.chld_features;
+
+        (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CONN_EVT, &evt);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_cback_ind
+**
+** Description      Send indicator callback event to application.
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type, UINT16 value)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    evt.ind.type = type;
+    evt.ind.value = value;
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_IND_EVT, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_evt_val
+**
+** Description      Send event to application.
+**                  This is a generic helper for events with common data.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type, UINT16 value)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    evt.val.value = value;
+
+    (*bta_hf_client_cb.p_cback)(type, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_operator_name
+**
+** Description      Send operator name event to application.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_operator_name(char *name)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    strlcpy(evt.operator.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
+    evt.operator.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
+}
+
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_clip
+**
+** Description      Send CLIP event to application.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_clip(char *number)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
+    evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLIP_EVT, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_ccwa
+**
+** Description      Send CLIP event to application.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_ccwa(char *number)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
+    evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CCWA_EVT, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_at_result
+**
+** Description      Send AT result event to application.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    evt.result.type = type;
+    evt.result.cme = cme;
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_clcc
+**
+** Description      Send clcc event to application.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_clcc(UINT32 idx, BOOLEAN incoming, UINT8 status, BOOLEAN mpty, char *number)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    evt.clcc.idx = idx;
+    evt.clcc.inc = incoming;
+    evt.clcc.status = status;
+    evt.clcc.mpty = mpty;
+
+    if (number)
+    {
+        evt.clcc.number_present = TRUE;
+        strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
+        evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
+    }
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLCC_EVT, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_cnum
+**
+** Description      Send cnum event to application.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_cnum(char *number, UINT16 service)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    evt.cnum.service = service;
+    strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
+    evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CNUM_EVT, &evt);
+}
+
+/*******************************************************************************
+**
+** Function         bta_hf_client_binp
+**
+** Description      Send BINP event to application.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_hf_client_binp(char *number)
+{
+    tBTA_HF_CLIENT evt;
+
+    memset(&evt, 0, sizeof(evt));
+
+    strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
+    evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
+
+    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_BINP_EVT, &evt);
+}
diff --git a/bta/hf_client/bta_hf_client_api.c b/bta/hf_client/bta_hf_client_api.c
new file mode 100644
index 0000000..6fdad9a
--- /dev/null
+++ b/bta/hf_client/bta_hf_client_api.c
@@ -0,0 +1,289 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2014 The Android Open Source Project
+ *  Copyright (C) 2003-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 is the implementation of the API for the handsfree (HF role)
+ *  subsystem of BTA
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "bta_hf_client_api.h"
+#include "bta_hf_client_int.h"
+#include "bd.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+static const tBTA_SYS_REG bta_hf_client_reg =
+{
+    bta_hf_client_hdl_event,
+    BTA_HfClientDisable
+};
+
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         BTA_HfClientEnable
+**
+** Description      Enable the HF CLient service. When the enable
+**                  operation is complete the callback function will be
+**                  called with a BTA_HF_CLIENT_ENABLE_EVT. This function must
+**                  be called before other function in the HF CLient API are
+**                  called.
+**
+** Returns          BTA_SUCCESS if OK, BTA_FAILURE otherwise.
+**
+*******************************************************************************/
+BTA_API tBTA_STATUS BTA_HfClientEnable(tBTA_HF_CLIENT_CBACK *p_cback)
+{
+    tBTA_HF_CLIENT_API_ENABLE  *p_buf;
+    UINT8       idx;
+
+    if (bta_sys_is_register (BTA_ID_HS))
+    {
+        APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ...");
+        return BTA_FAILURE;
+    }
+
+    /* register with BTA system manager */
+    bta_sys_register(BTA_ID_HS, &bta_hf_client_reg);
+
+    if ((p_buf = (tBTA_HF_CLIENT_API_ENABLE *) GKI_getbuf(sizeof(tBTA_HF_CLIENT_API_ENABLE))) != NULL)
+    {
+        p_buf->hdr.event = BTA_HF_CLIENT_API_ENABLE_EVT;
+        p_buf->p_cback = p_cback;
+        bta_sys_sendmsg(p_buf);
+    }
+
+    return BTA_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         BTA_HfClientDisable
+**
+** Description      Disable the HF Client service
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API void BTA_HfClientDisable(void)
+{
+    BT_HDR  *p_buf;
+
+    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+    {
+        p_buf->event = BTA_HF_CLIENT_API_DISABLE_EVT;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_HfClientRegister
+**
+** Description      Register an HF Client service.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API void BTA_HfClientRegister(tBTA_SEC sec_mask, tBTA_HF_CLIENT_FEAT features,
+                                                        char *p_service_name)
+{
+    tBTA_HF_CLIENT_API_REGISTER    *p_buf;
+
+    if ((p_buf = (tBTA_HF_CLIENT_API_REGISTER *) GKI_getbuf(sizeof(tBTA_HF_CLIENT_API_REGISTER))) != NULL)
+    {
+        p_buf->hdr.event = BTA_HF_CLIENT_API_REGISTER_EVT;
+        p_buf->features = features;
+        p_buf->sec_mask = sec_mask;
+        if(p_service_name)
+        {
+            BCM_STRNCPY_S(p_buf->name, BTA_SERVICE_NAME_LEN+1, p_service_name, BTA_SERVICE_NAME_LEN);
+            p_buf->name[BTA_SERVICE_NAME_LEN] = 0;
+        }
+        else
+        {
+            p_buf->name[0] = '\0';
+        }
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_HfClientDeregister
+**
+** Description      Deregister an HF Client service.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API void BTA_HfClientDeregister(UINT16 handle)
+{
+    BT_HDR  *p_buf;
+
+     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+     {
+         p_buf->event = BTA_HF_CLIENT_API_DEREGISTER_EVT;
+         p_buf->layer_specific = handle;
+         bta_sys_sendmsg(p_buf);
+     }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_HfClientOpen
+**
+** Description      Opens a connection to an audio gateway.
+**                  When connection is open callback function is called
+**                  with a BTA_AG_OPEN_EVT. Only the data connection is
+**                  opened. The audio connection is not opened.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API void BTA_HfClientOpen(UINT16 handle, BD_ADDR bd_addr, tBTA_SEC sec_mask)
+{
+    tBTA_HF_CLIENT_API_OPEN  *p_buf;
+
+    if ((p_buf = (tBTA_HF_CLIENT_API_OPEN *) GKI_getbuf(sizeof(tBTA_HF_CLIENT_API_OPEN))) != NULL)
+    {
+        p_buf->hdr.event = BTA_HF_CLIENT_API_OPEN_EVT;
+        p_buf->hdr.layer_specific = handle;
+        bdcpy(p_buf->bd_addr, bd_addr);
+        p_buf->sec_mask = sec_mask;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_HfClientClose
+**
+** Description      Close the current connection to an audio gateway.
+**                  Any current audio connection will also be closed
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API void BTA_HfClientClose(UINT16 handle)
+{
+    BT_HDR  *p_buf;
+
+    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+    {
+        p_buf->event = BTA_HF_CLIENT_API_CLOSE_EVT;
+        p_buf->layer_specific = handle;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_HfCllientAudioOpen
+**
+** Description      Opens an audio connection to the currently connected
+**                 audio gateway
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API void BTA_HfClientAudioOpen(UINT16 handle)
+{
+    BT_HDR  *p_buf;
+
+    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+    {
+        p_buf->event = BTA_HF_CLIENT_API_AUDIO_OPEN_EVT;
+        p_buf->layer_specific = handle;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_HfClientAudioClose
+**
+** Description      Close the currently active audio connection to an audio
+**                  gateway. The data connection remains open
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API void BTA_HfClientAudioClose(UINT16 handle)
+{
+    BT_HDR  *p_buf;
+
+    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+    {
+        p_buf->event = BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT;
+        p_buf->layer_specific = handle;
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_HfClientSendAT
+**
+** Description      send AT command
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API void BTA_HfClientSendAT(UINT16 handle, tBTA_HF_CLIENT_AT_CMD_TYPE at, UINT32 val1, UINT32 val2, const char *str)
+{
+    tBTA_HF_CLIENT_DATA_VAL  *p_buf;
+
+    if ((p_buf = (tBTA_HF_CLIENT_DATA_VAL *) GKI_getbuf(sizeof(tBTA_HF_CLIENT_DATA_VAL))) != NULL)
+    {
+        p_buf->hdr.event = BTA_HF_CLIENT_SEND_AT_CMD_EVT;
+        p_buf->uint8_val = at;
+        p_buf->uint32_val1 = val1;
+        p_buf->uint32_val2 = val2;
+
+        if (str)
+        {
+            strlcpy(p_buf->str, str, BTA_HF_CLIENT_NUMBER_LEN + 1);
+            p_buf->str[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
+        }
+        else
+        {
+            p_buf->str[0] = '\0';
+        }
+
+        p_buf->hdr.layer_specific = handle;
+        bta_sys_sendmsg(p_buf);
+    }
+}
diff --git a/bta/hf_client/bta_hf_client_at.c b/bta/hf_client/bta_hf_client_at.c
new file mode 100644
index 0000000..462b287
--- /dev/null
+++ b/bta/hf_client/bta_hf_client_at.c
@@ -0,0 +1,1816 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2014 The Android Open Source Project
+ *  Copyright (C) 2003-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.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include "bta_hf_client_api.h"
+#include "bta_hf_client_int.h"
+#include "port_api.h"
+
+/* Uncomment to enable AT traffic dumping */
+/* #define BTA_HF_CLIENT_AT_DUMP 1 */
+
+/* minimum length of AT event */
+#define BTA_HF_CLIENT_AT_EVENT_MIN_LEN 3
+
+/* timeout for AT response  */
+#define BTA_HF_CLIENT_AT_TIMEOUT 29989
+
+/* timeout for AT hold timer  */
+#define BTA_HF_CLIENT_AT_HOLD_TIMEOUT 41
+
+/******************************************************************************
+**
+**          DATA TYPES AND CONTAINERS
+**
+*******************************************************************************/
+/* BRSF: store received values here */
+extern tBTA_HF_CLIENT_CB  bta_hf_client_cb;
+
+/******************************************************************************
+**       SUPPORTED EVENT MESSAGES
+*******************************************************************************/
+
+/* CIND: supported indicator names                        */
+#define BTA_HF_CLIENT_INDICATOR_BATTERYCHG  "battchg"
+#define BTA_HF_CLIENT_INDICATOR_SIGNAL      "signal"
+#define BTA_HF_CLIENT_INDICATOR_SERVICE     "service"
+#define BTA_HF_CLIENT_INDICATOR_CALL        "call"
+#define BTA_HF_CLIENT_INDICATOR_ROAM        "roam"
+#define BTA_HF_CLIENT_INDICATOR_CALLSETUP   "callsetup"
+#define BTA_HF_CLIENT_INDICATOR_CALLHELD    "callheld"
+
+/* CIND: represents each indicators boundaries */
+typedef struct
+{
+    char* name;
+    UINT8 min;
+    UINT8 max;
+    UINT8 namelen;
+} tBTA_HF_CLIENT_INDICATOR;
+
+#define BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT 7
+
+/* CIND: storage room for indicators value range and their statuses */
+static const tBTA_HF_CLIENT_INDICATOR bta_hf_client_indicators[BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT] =
+{
+    /* name                                | min | max | name length - used by parser */
+     {BTA_HF_CLIENT_INDICATOR_BATTERYCHG,     0,   5,    sizeof(BTA_HF_CLIENT_INDICATOR_BATTERYCHG)},
+     {BTA_HF_CLIENT_INDICATOR_SIGNAL,         0,   5,    sizeof(BTA_HF_CLIENT_INDICATOR_SIGNAL)},
+     {BTA_HF_CLIENT_INDICATOR_SERVICE,        0,   1,    sizeof(BTA_HF_CLIENT_INDICATOR_SERVICE)},
+     {BTA_HF_CLIENT_INDICATOR_CALL,           0,   1,    sizeof(BTA_HF_CLIENT_INDICATOR_CALL)},
+     {BTA_HF_CLIENT_INDICATOR_ROAM,           0,   1,    sizeof(BTA_HF_CLIENT_INDICATOR_ROAM)},
+     {BTA_HF_CLIENT_INDICATOR_CALLSETUP,      0,   3,    sizeof(BTA_HF_CLIENT_INDICATOR_CALLSETUP)},
+     {BTA_HF_CLIENT_INDICATOR_CALLHELD,       0,   2,    sizeof(BTA_HF_CLIENT_INDICATOR_CALLHELD)}
+};
+
+/* +VGM/+VGS - gain min/max values  */
+#define BTA_HF_CLIENT_VGS_MIN   0
+#define BTA_HF_CLIENT_VGS_MAX  15
+#define BTA_HF_CLIENT_VGM_MIN   0
+#define BTA_HF_CLIENT_VGM_MAX  15
+
+UINT32 service_index = 0;
+BOOLEAN service_availability = TRUE;
+/* helper functions for handling AT commands queueing */
+
+static void bta_hf_client_clear_queued_at(void)
+{
+    tBTA_HF_CLIENT_AT_QCMD *cur = bta_hf_client_cb.scb.at_cb.queued_cmd;
+    tBTA_HF_CLIENT_AT_QCMD *next;
+
+    while (cur != NULL) {
+        next = cur->next;
+        GKI_freebuf(cur);
+        cur = next;
+    }
+
+    bta_hf_client_cb.scb.at_cb.queued_cmd = NULL;
+}
+
+static void bta_hf_client_queue_at(tBTA_HF_CLIENT_AT_CMD cmd, const char *buf, UINT16 buf_len)
+{
+    tBTA_HF_CLIENT_AT_QCMD *new_cmd;
+
+    APPL_TRACE_DEBUG("%s", __FUNCTION__);
+
+    if ((new_cmd = (tBTA_HF_CLIENT_AT_QCMD *) GKI_getbuf(sizeof(tBTA_HF_CLIENT_AT_QCMD))) != NULL)
+    {
+        new_cmd->cmd = cmd;
+        new_cmd->buf_len = buf_len;
+        new_cmd->next = NULL;
+        memcpy(new_cmd->buf, buf, buf_len);
+
+        if (bta_hf_client_cb.scb.at_cb.queued_cmd != NULL)
+        {
+            tBTA_HF_CLIENT_AT_QCMD *qcmd = bta_hf_client_cb.scb.at_cb.queued_cmd;
+
+            while (qcmd->next != NULL)
+                qcmd = qcmd->next;
+
+            qcmd->next = new_cmd;
+        }
+        else
+        {
+            bta_hf_client_cb.scb.at_cb.queued_cmd = new_cmd;
+        }
+    }
+}
+
+static void bta_hf_client_at_resp_timer_cback (TIMER_LIST_ENT *p_tle)
+{
+    if (p_tle)
+    {
+        bta_hf_client_cb.scb.at_cb.resp_timer_on = FALSE;
+
+        APPL_TRACE_ERROR("HFPClient: AT response timeout, disconnecting");
+
+        bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
+    }
+}
+
+static void bta_hf_client_stop_at_resp_timer(void)
+{
+    if (bta_hf_client_cb.scb.at_cb.resp_timer_on)
+    {
+        bta_hf_client_cb.scb.at_cb.resp_timer_on = FALSE;
+        bta_sys_stop_timer (&bta_hf_client_cb.scb.at_cb.resp_timer);
+    }
+}
+
+static void bta_hf_client_start_at_resp_timer(void)
+{
+    if (bta_hf_client_cb.scb.at_cb.resp_timer_on)
+    {
+        bta_sys_stop_timer (&bta_hf_client_cb.scb.at_cb.resp_timer);
+    }
+
+    bta_hf_client_cb.scb.at_cb.resp_timer.p_cback = (TIMER_CBACK*)&bta_hf_client_at_resp_timer_cback;
+    bta_sys_start_timer(&bta_hf_client_cb.scb.at_cb.resp_timer, 0, BTA_HF_CLIENT_AT_TIMEOUT);
+    bta_hf_client_cb.scb.at_cb.resp_timer_on = TRUE;
+}
+
+static void bta_hf_client_send_at(tBTA_HF_CLIENT_AT_CMD cmd, char *buf, UINT16 buf_len)
+{
+    if ((bta_hf_client_cb.scb.at_cb.current_cmd == BTA_HF_CLIENT_AT_NONE ||
+            bta_hf_client_cb.scb.svc_conn == FALSE) &&
+            bta_hf_client_cb.scb.at_cb.hold_timer_on == FALSE)
+    {
+        UINT16  len;
+
+#ifdef BTA_HF_CLIENT_AT_DUMP
+        APPL_TRACE_DEBUG("%s %.*s", __FUNCTION__, buf_len - 1, buf);
+#endif
+
+        bta_hf_client_cb.scb.at_cb.current_cmd = cmd;
+        PORT_WriteData(bta_hf_client_cb.scb.conn_handle, buf, buf_len, &len);
+
+        bta_hf_client_start_at_resp_timer();
+
+        return;
+    }
+
+    bta_hf_client_queue_at(cmd, buf, buf_len);
+}
+
+static void bta_hf_client_send_queued_at(void)
+{
+    tBTA_HF_CLIENT_AT_QCMD *cur = bta_hf_client_cb.scb.at_cb.queued_cmd;
+    tBTA_HF_CLIENT_AT_QCMD *next;
+
+    APPL_TRACE_DEBUG("%s", __FUNCTION__);
+
+    if (cur != NULL)
+    {
+        next = cur->next;
+
+        bta_hf_client_send_at(cur->cmd, cur->buf, cur->buf_len);
+
+        GKI_freebuf(cur);
+
+        bta_hf_client_cb.scb.at_cb.queued_cmd = next;
+    }
+}
+
+static void bta_hf_client_at_hold_timer_cback(TIMER_LIST_ENT *p_tle)
+{
+    APPL_TRACE_DEBUG("%s", __FUNCTION__);
+
+    if (p_tle)
+    {
+        bta_hf_client_cb.scb.at_cb.hold_timer_on = FALSE;
+        bta_hf_client_send_queued_at();
+    }
+}
+
+static void bta_hf_client_stop_at_hold_timer(void)
+{
+    APPL_TRACE_DEBUG("%s", __FUNCTION__);
+
+    if (bta_hf_client_cb.scb.at_cb.hold_timer_on)
+    {
+        bta_hf_client_cb.scb.at_cb.hold_timer_on = FALSE;
+        bta_sys_stop_timer (&bta_hf_client_cb.scb.at_cb.hold_timer);
+    }
+}
+
+static void bta_hf_client_start_at_hold_timer(void)
+{
+    TIMER_LIST_ENT *timer = &bta_hf_client_cb.scb.at_cb.hold_timer;
+
+    APPL_TRACE_DEBUG("%s", __FUNCTION__);
+
+    if (bta_hf_client_cb.scb.at_cb.hold_timer_on)
+    {
+        bta_sys_stop_timer (timer);
+    }
+
+    timer->p_cback = (TIMER_CBACK*)&bta_hf_client_at_hold_timer_cback;
+    bta_sys_start_timer(timer, 0, BTA_HF_CLIENT_AT_HOLD_TIMEOUT);
+    bta_hf_client_cb.scb.at_cb.hold_timer_on = TRUE;
+}
+
+/******************************************************************************
+**
+**          COMMON AT EVENT HANDLING FUNCTIONS
+**
+**   Receives data (strings, ints, etc.) from the parser and processes this data.
+**   No buffer parsing is being done here.
+*******************************************************************************/
+
+static void bta_hf_client_handle_ok()
+{
+    APPL_TRACE_DEBUG("%s", __FUNCTION__);
+
+    bta_hf_client_stop_at_resp_timer();
+
+    if (!bta_hf_client_cb.scb.svc_conn)
+    {
+        bta_hf_client_slc_seq(FALSE);
+        return;
+    }
+
+    switch(bta_hf_client_cb.scb.at_cb.current_cmd)
+    {
+        case BTA_HF_CLIENT_AT_BIA:
+        case BTA_HF_CLIENT_AT_BCC:
+            break;
+        case BTA_HF_CLIENT_AT_BCS:
+            bta_hf_client_start_at_hold_timer();
+            bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
+            return;
+        case BTA_HF_CLIENT_AT_CLIP: //last cmd is post slc seq
+            if (bta_hf_client_cb.scb.send_at_reply == FALSE)
+            {
+                bta_hf_client_cb.scb.send_at_reply = TRUE;
+            }
+            break;
+        case BTA_HF_CLIENT_AT_NONE:
+            bta_hf_client_stop_at_hold_timer();
+            break;
+        default:
+            if (bta_hf_client_cb.scb.send_at_reply)
+            {
+                bta_hf_client_at_result(BTA_HF_CLIENT_AT_RESULT_OK, 0);
+            }
+            break;
+    }
+
+    bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
+
+    bta_hf_client_send_queued_at();
+}
+
+static void bta_hf_client_handle_error(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme)
+{
+    APPL_TRACE_DEBUG("%s %u %u", __FUNCTION__, type, cme);
+
+    bta_hf_client_stop_at_resp_timer();
+
+    if (!bta_hf_client_cb.scb.svc_conn)
+    {
+        bta_hf_client_slc_seq(TRUE);
+        return;
+    }
+
+    switch(bta_hf_client_cb.scb.at_cb.current_cmd)
+    {
+        case BTA_HF_CLIENT_AT_BIA:
+            break;
+        case BTA_HF_CLIENT_AT_BCC:
+        case BTA_HF_CLIENT_AT_BCS:
+            bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
+            break;
+        case BTA_HF_CLIENT_AT_CLIP: //last cmd is post slc seq
+            if (bta_hf_client_cb.scb.send_at_reply == FALSE)
+            {
+                bta_hf_client_cb.scb.send_at_reply = TRUE;
+            }
+            break;
+        default:
+            if (bta_hf_client_cb.scb.send_at_reply)
+            {
+                bta_hf_client_at_result(type, cme);
+            }
+            break;
+    }
+
+    bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
+
+    bta_hf_client_send_queued_at();
+}
+
+static void bta_hf_client_handle_ring()
+{
+    APPL_TRACE_DEBUG("%s", __FUNCTION__);
+    bta_hf_client_evt_val(BTA_HF_CLIENT_RING_INDICATION,0);
+}
+
+static void bta_hf_client_handle_brsf(UINT32 value)
+{
+    APPL_TRACE_DEBUG("%s 0x%x", __FUNCTION__, value);
+    bta_hf_client_cb.scb.peer_features = value;
+}
+
+/* handles a single indicator descriptor - registers it for value changing events */
+static void bta_hf_client_handle_cind_list_item(char *name, UINT32 min, UINT32 max, UINT32 index)
+{
+
+    UINT8 i = 0;
+
+    APPL_TRACE_DEBUG("%s %lu.%s <%lu:%lu>", __FUNCTION__, index, name, min, max);
+
+    /* look for a matching indicator on list of supported ones */
+    for(i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++)
+    {
+        if (strcmp(name,BTA_HF_CLIENT_INDICATOR_SERVICE) == 0)
+        {
+            service_index = index;
+        }
+        /* look for a match - search one sign further than indicators name to check for string end */
+        /* It will distinguish 'callheld' which could be matched by strncmp as 'call'.               */
+        if (strncmp(name, bta_hf_client_indicators[i].name, bta_hf_client_indicators[i].namelen) != 0)
+            continue;
+
+        /* index - enumerates value position in the incoming sequence                      */
+        /* if name matches one of the known indicators, add its incoming position          */
+        /* to lookup table for easy value->indicator matching later, when only values come  */
+        bta_hf_client_cb.scb.at_cb.indicator_lookup[index] = i;
+
+        return;
+    }
+}
+
+static void bta_hf_client_handle_cind_value(UINT32 index, UINT32 value)
+{
+    APPL_TRACE_DEBUG("%s index: %u value: %u", __FUNCTION__, index, value);
+
+    if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT)
+    {
+        return;
+    }
+
+    if (service_index == index)
+    {
+        if (value == 0)
+        {
+            service_availability = FALSE;
+        }
+        else
+        {
+            service_availability = TRUE;
+        }
+    }
+    if (bta_hf_client_cb.scb.at_cb.indicator_lookup[index] == -1)
+    {
+        return;
+    }
+
+    /* get the real array index from lookup table */
+    index = bta_hf_client_cb.scb.at_cb.indicator_lookup[index];
+
+    /* Ignore out of range values */
+    if(value > bta_hf_client_indicators[index].max ||
+       value < bta_hf_client_indicators[index].min)
+    {
+        return;
+    }
+
+    /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
+    bta_hf_client_ind(index, value);
+}
+
+static void bta_hf_client_handle_chld(UINT32 mask)
+{
+    APPL_TRACE_DEBUG("%s 0x%x", __FUNCTION__, mask);
+
+    bta_hf_client_cb.scb.chld_features |= mask;
+}
+
+static void bta_hf_client_handle_ciev(UINT32 index, UINT32 value)
+{
+    INT8 realind = -1;
+
+    APPL_TRACE_DEBUG("%s index: %u value: %u", __FUNCTION__, index, value);
+
+    if(index == 0 || index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT)
+    {
+        return;
+    }
+
+    realind = bta_hf_client_cb.scb.at_cb.indicator_lookup[index - 1];
+
+    if(realind >= 0 && realind < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT)
+    {
+        /* get the real in-array index from lookup table by index it comes at */
+        /* if there is no bug it should automatically be correctly calculated    */
+        if(value > bta_hf_client_indicators[realind].max || value < bta_hf_client_indicators[realind].min)
+        {
+            return;
+        }
+
+        /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
+        bta_hf_client_ind(realind, value);
+    }
+}
+
+static void bta_hf_client_handle_bcs(UINT32 codec)
+{
+    APPL_TRACE_DEBUG("%s %u", __FUNCTION__, codec);
+
+    if (codec == BTM_SCO_CODEC_CVSD ||
+            (codec == BTM_SCO_CODEC_MSBC && bta_hf_client_cb.msbc_enabled == TRUE))
+    {
+        bta_hf_client_cb.scb.negotiated_codec = codec;
+        bta_hf_client_send_at_bcs(codec);
+    }
+    else
+    {
+        bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
+        bta_hf_client_send_at_bac();
+    }
+}
+
+static void bta_hf_client_handle_bsir(UINT32 provided)
+{
+    APPL_TRACE_DEBUG("%s %u", __FUNCTION__, provided);
+
+    bta_hf_client_evt_val(BTA_HF_CLIENT_BSIR_EVT, provided);
+}
+
+static void bta_hf_client_handle_cmeerror(UINT32 code)
+{
+    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_CME, code);
+}
+
+static void bta_hf_client_handle_vgm(UINT32 value)
+{
+    APPL_TRACE_DEBUG("%s %lu", __FUNCTION__, value);
+
+    if(value <= BTA_HF_CLIENT_VGM_MAX)
+    {
+        bta_hf_client_evt_val(BTA_HF_CLIENT_MIC_EVT, value);
+    }
+}
+
+static void bta_hf_client_handle_vgs(UINT32 value)
+{
+    APPL_TRACE_DEBUG("%s %lu", __FUNCTION__, value);
+
+    if(value <= BTA_HF_CLIENT_VGS_MAX)
+    {
+        bta_hf_client_evt_val(BTA_HF_CLIENT_SPK_EVT, value);
+    }
+}
+
+static void bta_hf_client_handle_bvra(UINT32 value)
+{
+    APPL_TRACE_DEBUG("%s %lu", __FUNCTION__, value);
+
+    if (value > 1)
+    {
+        return;
+    }
+
+    bta_hf_client_evt_val(BTA_HF_CLIENT_VOICE_REC_EVT, value);
+}
+
+static void bta_hf_client_handle_clip(char *numstr, UINT32 type)
+{
+    APPL_TRACE_DEBUG("%s %u %s", __FUNCTION__, type, numstr);
+
+    bta_hf_client_clip(numstr);
+}
+
+static void bta_hf_client_handle_ccwa(char *numstr, UINT32 type)
+{
+    APPL_TRACE_DEBUG("%s %u %s", __FUNCTION__, type, numstr);
+
+    bta_hf_client_ccwa(numstr);
+}
+
+static void bta_hf_client_handle_cops(char *opstr, UINT32 mode)
+{
+    APPL_TRACE_DEBUG("%s %u %s", __FUNCTION__, mode, opstr);
+
+    bta_hf_client_operator_name(opstr);
+}
+
+static void bta_hf_client_handle_binp(char *numstr)
+{
+    APPL_TRACE_DEBUG("%s %s", __FUNCTION__, numstr);
+
+    bta_hf_client_binp(numstr);
+}
+
+static void bta_hf_client_handle_clcc(UINT16 idx, UINT16 dir, UINT16 status, UINT16 mode, UINT16 mpty, char *numstr, UINT16 type)
+{
+    APPL_TRACE_DEBUG("%s idx: %u dir: %u status: %u mode: %u mpty: %u",
+                        __FUNCTION__, idx, dir, status, mode, mpty);
+
+    if (numstr)
+    {
+        APPL_TRACE_DEBUG("%s number: %s  type: %u", __FUNCTION__, numstr, type);
+    }
+
+    bta_hf_client_clcc(idx, dir, status, mpty, numstr);
+}
+
+static void bta_hf_client_handle_cnum( char *numstr, UINT16 type, UINT16 service)
+{
+    APPL_TRACE_DEBUG("%s number: %s type: %u service: %u", __FUNCTION__, numstr, type, service);
+
+    /* TODO: should number be modified according to type? */
+    bta_hf_client_cnum(numstr, service);
+}
+
+static void bta_hf_client_handle_btrh( UINT16 code)
+{
+    APPL_TRACE_DEBUG("%s %lu", __FUNCTION__, code);
+
+    bta_hf_client_evt_val(BTA_HF_CLIENT_BTRH_EVT, code);
+}
+
+/******************************************************************************
+**
+**          COMMON AT EVENTS PARSING FUNCTIONS
+**
+*******************************************************************************/
+
+/* Check if prefix match and skip spaces if any */
+#define AT_CHECK_EVENT(buf, event) \
+    if (strncmp("\r\n"event, buf,sizeof("\r\n"event) - 1) != 0) return buf; \
+    buf += sizeof("\r\n"event) - 1; \
+    while (*buf == ' ') buf++;
+
+/* check for <cr><lf> and forward buffer if match */
+#define AT_CHECK_RN(buf) \
+    if (strncmp("\r\n", buf, sizeof("\r\n") - 1) != 0) { \
+        APPL_TRACE_DEBUG("%s missing end <cr><lf>", __FUNCTION__); \
+        return NULL;} \
+    buf += sizeof("\r\n") - 1;
+
+/* skip rest of AT string up to <cr> */
+#define AT_SKIP_REST(buf) while(*buf != '\r') buf++;
+
+static char *bta_hf_client_parse_ok(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "OK");
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_ok();
+
+    return buffer;
+}
+
+static char *bta_hf_client_parse_error(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "ERROR");
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_ERROR, 0);
+
+    return buffer;
+}
+
+static char *bta_hf_client_parse_ring(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "RING");
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_ring();
+
+    return buffer;
+}
+
+/* generic uint32 parser */
+static char *bta_hf_client_parse_uint32(char *buffer, void (*handler_callback)(UINT32))
+{
+    UINT32 value;
+    int res;
+    int offset;
+
+    res = sscanf(buffer, "%u%n", &value, &offset);
+    if (res < 1)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    AT_CHECK_RN(buffer);
+
+    handler_callback(value);
+    return buffer;
+}
+
+static char *bta_hf_client_parse_brsf(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+BRSF:");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_brsf);
+}
+
+static char *bta_hf_client_parse_cind_values(char *buffer)
+{
+    /* value and its position */
+    UINT16 index = 0;
+    UINT32 value = 0;
+
+    int offset;
+    int res;
+
+    while((res = sscanf(buffer, "%u%n", &value, &offset)) > 0)
+    {
+        /* decides if its valid index and value, if yes stores it */
+        bta_hf_client_handle_cind_value(index, value);
+
+        buffer += offset;
+
+        /* check if more values are present */
+        if (*buffer != ',')
+        {
+            break;
+        }
+
+        index++;
+        buffer++;
+    }
+
+    if (res > 0)
+    {
+        AT_CHECK_RN(buffer);
+        return buffer;
+    }
+
+    return NULL;
+}
+
+static char *bta_hf_client_parse_cind_list(char *buffer)
+{
+    int offset;
+    char name[129];
+    UINT32 min, max;
+    UINT32 index = 0;
+    int res;
+
+    while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min, &max, &offset)) > 2)
+    {
+        bta_hf_client_handle_cind_list_item(name, min, max, index);
+        buffer += offset;
+        index++;
+
+        if (*buffer != ',')
+        {
+            break;
+        }
+
+        buffer++;
+    }
+
+    if (res > 2)
+    {
+        AT_CHECK_RN(buffer);
+        return buffer;
+    }
+
+    return NULL;
+}
+
+static char *bta_hf_client_parse_cind(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+CIND:");
+
+    if(*buffer == '(')
+        return bta_hf_client_parse_cind_list(buffer);
+
+    return bta_hf_client_parse_cind_values(buffer);
+}
+
+static char *bta_hf_client_parse_chld(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+CHLD:");
+
+    if (*buffer != '(')
+    {
+        return NULL;
+    }
+
+    buffer++;
+
+    while(*buffer != '\0')
+    {
+        if(strncmp("0",buffer, 1) == 0)
+        {
+            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_REL);
+            buffer++;
+        }
+        else if(strncmp("1x",buffer, 2) == 0)
+        {
+            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_REL_X);
+            buffer += 2;
+        }
+        else if(strncmp("1",buffer, 1) == 0)
+        {
+            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_REL_ACC);
+            buffer++;
+        }
+        else if(strncmp("2x",buffer, 2) == 0)
+        {
+            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_PRIV_X);
+            buffer += 2;
+        }
+        else if(strncmp("2",buffer, 1) == 0)
+        {
+            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_HOLD_ACC);
+            buffer++;
+        }
+        else if(strncmp("3",buffer, 1) == 0)
+        {
+            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_MERGE);
+            buffer++;
+        }
+        else if(strncmp("4",buffer, 1) == 0)
+        {
+            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_MERGE_DETACH);
+            buffer++;
+        }
+        else
+        {
+            return NULL;
+        }
+
+        if (*buffer == ',')
+        {
+            buffer++;
+            continue;
+        }
+
+        if (*buffer == ')')
+        {
+            buffer++;
+            break;
+        }
+
+        return NULL;
+    }
+
+    AT_CHECK_RN(buffer);
+
+    return buffer;
+}
+
+static char *bta_hf_client_parse_ciev(char *buffer)
+{
+    UINT32 index, value;
+    int res;
+    int offset;
+
+    AT_CHECK_EVENT(buffer, "+CIEV:");
+
+    res = sscanf(buffer, "%u,%u%n", &index, &value, &offset);
+    if(res < 2)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_ciev(index, value);
+    return buffer;
+}
+
+static char *bta_hf_client_parse_bcs(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+BCS:");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_bcs);
+}
+
+static char *bta_hf_client_parse_bsir(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+BSIR:");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_bsir);
+}
+
+static char *bta_hf_client_parse_cmeerror(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+CME ERROR:");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_cmeerror);
+}
+
+static char *bta_hf_client_parse_vgm(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+VGM:");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_vgm);
+}
+
+static char *bta_hf_client_parse_vgme(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+VGM=");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_vgm);
+}
+
+static char *bta_hf_client_parse_vgs(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+VGS:");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_vgs);
+}
+
+static char *bta_hf_client_parse_vgse(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+VGS=");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_vgs);
+}
+
+static char *bta_hf_client_parse_bvra(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "+BVRA:");
+
+    return bta_hf_client_parse_uint32(buffer, bta_hf_client_handle_bvra);
+}
+
+static char *bta_hf_client_parse_clip(char *buffer)
+{
+    /* spec forces 32 chars, plus \0 here */
+    char number[33];
+    UINT32 type = 0;
+    int res;
+    int offset;
+
+    AT_CHECK_EVENT(buffer, "+CLIP:");
+
+    /* there might be something more after %lu but HFP doesn't care */
+    res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
+    if(res < 2)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    AT_SKIP_REST(buffer);
+
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_clip(number, type);
+    return buffer;
+}
+
+/* in HFP context there is no difference between ccwa and clip */
+static char *bta_hf_client_parse_ccwa(char *buffer)
+{
+    /* ac to spec 32 chars max, plus \0 here */
+    char number[33];
+    UINT32 type = 0;
+    int res ;
+    int offset;
+
+    AT_CHECK_EVENT(buffer, "+CCWA:");
+
+    /* there might be something more after %lu but HFP doesn't care */
+    res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
+    if(res < 2)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    AT_SKIP_REST(buffer);
+
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_ccwa(number, type);
+    return buffer;
+}
+
+static char *bta_hf_client_parse_cops(char *buffer)
+{
+    UINT8 mode;
+    /* spec forces 16 chars max, plus \0 here */
+    char opstr[17];
+    int res;
+    int offset;
+
+    AT_CHECK_EVENT(buffer, "+COPS:");
+
+    /* TODO: Not sure if operator string actually can contain escaped " char inside */
+    res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
+    if(res < 2)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    AT_SKIP_REST(buffer);
+
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_cops(opstr, mode);
+    return buffer;
+}
+
+static char *bta_hf_client_parse_binp(char *buffer)
+{
+    /* HFP only supports phone number as BINP data */
+    /* phone number is 32 chars plus one for \0*/
+    char numstr[33];
+    int res;
+    int offset;
+
+    AT_CHECK_EVENT(buffer, "+BINP:");
+
+    res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
+    if(res < 1)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    /* some phones might sent type as well, just skip it */
+    AT_SKIP_REST(buffer);
+
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_binp(numstr);
+    return buffer;
+}
+
+static char *bta_hf_client_parse_clcc(char *buffer)
+{
+    UINT16 idx, dir, status, mode, mpty;
+    char numstr[33];     /* spec forces 32 chars, plus one for \0*/
+    UINT16 type;
+    int res;
+    int offset;
+
+    AT_CHECK_EVENT(buffer, "+CLCC:");
+
+    res = sscanf(buffer, "%hu,%hu,%hu,%hu,%hu%n",
+                    &idx, &dir, &status, &mode, &mpty, &offset);
+    if (res < 5)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    /* check optional part */
+    if (*buffer == ',')
+    {
+        int res2;
+
+        res2 = sscanf(buffer, ",\"%32[^\"]\",%hu%n", numstr, &type, &offset);
+        if (res2 < 0)
+        {
+            return NULL;
+        }
+
+        if (res2 == 0)
+        {
+            res2 = sscanf(buffer, ",\"\",%hu%n", &type, &offset);
+            if (res < 0)
+            {
+                return NULL;
+            }
+
+            /* numstr is not matched in second attempt, correct this */
+            res2++;
+            numstr[0] = '\0';
+        }
+
+        if (res2 < 2)
+        {
+            return NULL;
+        }
+
+        res += res2;
+        buffer += offset;
+    }
+
+    AT_CHECK_RN(buffer);
+
+    if(res > 6)
+    {
+        /* we also have last two optional parameters */
+        bta_hf_client_handle_clcc(idx, dir, status, mode, mpty, numstr, type);
+    }
+    else
+    {
+        /* we didn't get the last two parameters */
+        bta_hf_client_handle_clcc(idx, dir, status, mode, mpty, NULL, 0);
+    }
+
+    return buffer;
+}
+
+static char *bta_hf_client_parse_cnum(char *buffer)
+{
+    char numstr[33];     /* spec forces 32 chars, plus one for \0*/
+    UINT16 type;
+    UINT16 service = 0; /* 0 in case this optional parameter is not being sent */
+    int res;
+    int offset;
+
+    AT_CHECK_EVENT(buffer, "+CNUM:");
+
+    res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service, &offset);
+    if(res < 0)
+    {
+        return NULL;
+    }
+
+    if (res == 0)
+    {
+        res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
+        if (res < 0)
+        {
+            return NULL;
+        }
+
+        /* numstr is not matched in second attempt, correct this */
+        res++;
+        numstr[0] = '\0';
+    }
+
+    if (res < 3)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    AT_CHECK_RN(buffer);
+
+    /* service is optional */
+    if(res == 2)
+    {
+        bta_hf_client_handle_cnum(numstr, type, service);
+        return buffer;
+    }
+
+    if (service != 4 && service != 5)
+    {
+        return NULL;
+    }
+
+    bta_hf_client_handle_cnum(numstr, type, service);
+    return buffer;
+}
+
+static char *bta_hf_client_parse_btrh(char *buffer)
+{
+    UINT16 code = 0;
+    int res;
+    int offset;
+
+    AT_CHECK_EVENT(buffer, "+BTRH:");
+
+    res = sscanf(buffer, "%hu%n", &code, &offset);
+    if(res < 1)
+    {
+        return NULL;
+    }
+
+    buffer += offset;
+
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_btrh(code);
+    return buffer;
+}
+
+static char *bta_hf_client_parse_busy(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "BUSY");
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_BUSY, 0);
+
+    return buffer;
+}
+
+static char *bta_hf_client_parse_delayed(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "DELAYED");
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_DELAY, 0);
+
+    return buffer;
+}
+
+static char *bta_hf_client_parse_no_carrier(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "NO CARRIER");
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_NO_CARRIER, 0);
+
+    return buffer;
+}
+
+static char *bta_hf_client_parse_no_answer(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "NO ANSWER");
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_NO_ANSWER, 0);
+
+    return buffer;
+}
+
+static char *bta_hf_client_parse_blacklisted(char *buffer)
+{
+    AT_CHECK_EVENT(buffer, "BLACKLISTED");
+    AT_CHECK_RN(buffer);
+
+    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_BLACKLISTED, 0);
+
+    return buffer;
+}
+
+static char *bta_hf_client_skip_unknown(char *buffer)
+{
+    char *start;
+    char *tmp;
+
+    tmp = strstr(buffer, "\r\n");
+    if (tmp == NULL)
+    {
+        return NULL;
+    }
+
+    buffer += 2;
+    start = buffer;
+
+    tmp = strstr(buffer, "\r\n");
+    if (tmp == NULL)
+    {
+        return NULL;
+    }
+
+    buffer = tmp + 2;
+
+    APPL_TRACE_DEBUG("%s %.*s", __FUNCTION__, buffer - start - 2, start);
+
+    return buffer;
+}
+
+
+/******************************************************************************
+**       SUPPORTED EVENT MESSAGES
+*******************************************************************************/
+
+/* returned values are as follow:
+ * != NULL && != buf  : match and parsed ok
+ * == NULL            : match but parse failed
+ * != NULL && == buf  : no match
+ */
+typedef char* (*tBTA_HF_CLIENT_PARSER_CALLBACK)(char*);
+
+static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] =
+{
+    bta_hf_client_parse_ok,
+    bta_hf_client_parse_error,
+    bta_hf_client_parse_ring,
+    bta_hf_client_parse_brsf,
+    bta_hf_client_parse_cind,
+    bta_hf_client_parse_ciev,
+    bta_hf_client_parse_chld,
+    bta_hf_client_parse_bcs,
+    bta_hf_client_parse_bsir,
+    bta_hf_client_parse_cmeerror,
+    bta_hf_client_parse_vgm,
+    bta_hf_client_parse_vgme,
+    bta_hf_client_parse_vgs,
+    bta_hf_client_parse_vgse,
+    bta_hf_client_parse_bvra,
+    bta_hf_client_parse_clip,
+    bta_hf_client_parse_ccwa,
+    bta_hf_client_parse_cops,
+    bta_hf_client_parse_binp,
+    bta_hf_client_parse_clcc,
+    bta_hf_client_parse_cnum,
+    bta_hf_client_parse_btrh,
+    bta_hf_client_parse_busy,
+    bta_hf_client_parse_delayed,
+    bta_hf_client_parse_no_carrier,
+    bta_hf_client_parse_no_answer,
+    bta_hf_client_parse_blacklisted,
+    bta_hf_client_skip_unknown
+};
+
+/* calculate supported event list length */
+static const UINT16 bta_hf_client_psraser_cb_count =
+        sizeof(bta_hf_client_parser_cb) / sizeof(bta_hf_client_parser_cb[0]);
+
+#ifdef BTA_HF_CLIENT_AT_DUMP
+static void bta_hf_client_dump_at(void)
+{
+    char dump[(4 * BTA_HF_CLIENT_AT_PARSER_MAX_LEN) + 1];
+    char *p1, *p2;
+
+    p1 = bta_hf_client_cb.scb.at_cb.buf;
+    p