am a5df8e12: Merge "Accept takes a socklen_t, not an int."

* commit 'a5df8e122f4f322d9d1d4e9c14bf998ff2e3406a':
  Accept takes a socklen_t, not an int.
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c
index 04bd186..f7422f7 100755
--- a/bta/dm/bta_dm_act.c
+++ b/bta/dm/bta_dm_act.c
@@ -673,6 +673,11 @@
     int i;
     tBTA_DM_SEC sec_event;
 
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+    /* need to remove all pending background connection before unpair */
+    BTA_GATTC_CancelOpen(0, p_dev->bd_addr, FALSE);
+#endif
+
     if (BTM_IsAclConnectionUp(p_dev->bd_addr))
     {
         /* Take the link down first, and mark the device for removal when disconnected */
@@ -692,6 +697,11 @@
     else    /* Ok to remove the device in application layer */
     {
         BTM_SecDeleteDevice(p_dev->bd_addr);
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+        /* remove all cached GATT information */
+        BTA_GATTC_Refresh(p_dev->bd_addr);
+#endif
+
         if( bta_dm_cb.p_sec_cback )
         {
             bdcpy(sec_event.link_down.bd_addr, p_dev->bd_addr);
@@ -829,14 +839,14 @@
     if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))
     {
 
-        p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
-        if (!p_name)
-            p_name = "";
-
         memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
         bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);
-        memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1));
-        sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
+        p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
+        if (p_name != NULL)
+        {
+            memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1));
+            sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
+        }
 
 /*      taken care of by memset [above]
         sec_event.auth_cmpl.key_present = FALSE;
@@ -3459,6 +3469,10 @@
             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 (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+                /* remove all cached GATT information */
+                BTA_GATTC_Refresh(p_bda);
+#endif
                 issue_unpair_cb = TRUE;
             }
 
@@ -3768,6 +3782,12 @@
     else
     {
         BTM_SecDeleteDevice (remote_bd_addr);
+#if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
+        /* need to remove all pending background connection */
+        BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
+        /* remove all cached GATT information */
+        BTA_GATTC_Refresh(remote_bd_addr);
+#endif
     }
 }
 
@@ -4997,6 +5017,7 @@
                         p_data->ble_set_adv_params.p_dir_bda,
                         BTA_DM_BLE_ADV_CHNL_MAP);
 }
+
 /*******************************************************************************
 **
 ** Function         bta_dm_ble_set_adv_config
@@ -5012,6 +5033,34 @@
                         (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg);
 }
 
+/*******************************************************************************
+**
+** Function         bta_dm_ble_set_scan_rsp
+**
+** Description      This function set the customized ADV scan resp. configuration
+**
+** Parameters:
+**
+*******************************************************************************/
+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);
+}
+
+/*******************************************************************************
+**
+** Function         bta_dm_ble_broadcast
+**
+** Description      Starts or stops LE broadcasts
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
+{
+    BTM_BleBroadcast(p_data->ble_observe.start);
+}
 
 #if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE))
 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
diff --git a/bta/dm/bta_dm_api.c b/bta/dm/bta_dm_api.c
index 941213a..e37548e 100644
--- a/bta/dm/bta_dm_api.c
+++ b/bta/dm/bta_dm_api.c
@@ -1510,6 +1510,60 @@
         bta_sys_sendmsg(p_msg);
     }
 }
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleSetScanRsp
+**
+** Description      This function is called to override the BTA scan response.
+**
+** Parameters       Pointer to User defined ADV data structure
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg)
+{
+    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)
+    {
+        p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT;
+		p_msg->data_mask = data_mask;
+        p_msg->p_adv_cfg = p_adv_cfg;
+
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleBroadcast
+**
+** Description      This function starts or stops LE broadcasting.
+**
+** Parameters       start: start or stop broadcast.
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleBroadcast (BOOLEAN start)
+{
+    tBTA_DM_API_BLE_OBSERVE   *p_msg;
+
+    APPL_TRACE_API1("BTA_DmBleBroadcast: start = %d ", start);
+
+    if ((p_msg = (tBTA_DM_API_BLE_OBSERVE *) GKI_getbuf(sizeof(tBTA_DM_API_BLE_OBSERVE))) != NULL)
+    {
+        memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_OBSERVE));
+
+        p_msg->hdr.event = BTA_DM_API_BLE_BROADCAST_EVT;
+        p_msg->start = start;
+
+        bta_sys_sendmsg(p_msg);
+    }
+}
+
 #endif
 /*******************************************************************************
 **
diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h
index d87dbf3..dd3e16c 100644
--- a/bta/dm/bta_dm_int.h
+++ b/bta/dm/bta_dm_int.h
@@ -101,6 +101,8 @@
     BTA_DM_API_BLE_OBSERVE_EVT,
     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,
 #endif
 
 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
@@ -996,6 +998,8 @@
 extern void bta_dm_ble_observe (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);
 
 #endif
 extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
diff --git a/bta/dm/bta_dm_main.c b/bta/dm/bta_dm_main.c
index 50f871f..0f6b91a 100644
--- a/bta/dm/bta_dm_main.c
+++ b/bta/dm/bta_dm_main.c
@@ -98,6 +98,8 @@
     bta_dm_ble_observe,
     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 */
 #endif
 
 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
diff --git a/bta/gatt/bta_gattc_act.c b/bta/gatt/bta_gattc_act.c
index f5b60fa..444c357 100644
--- a/bta/gatt/bta_gattc_act.c
+++ b/bta/gatt/bta_gattc_act.c
@@ -52,13 +52,16 @@
 
 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 tGATT_CBACK bta_gattc_cl_cback =
 {
     bta_gattc_conn_cback,
     bta_gattc_cmpl_cback,
     bta_gattc_disc_res_cback,
     bta_gattc_disc_cmpl_cback,
-    NULL
+    NULL,
+    bta_gattc_enc_cmpl_cback
 };
 
 /* opcode(tGATTC_OPTYPE) order has to be comply with internal event order */
@@ -399,6 +402,34 @@
 
     }
 }
+
+/*******************************************************************************
+**
+** Function         bta_gattc_process_enc_cmpl
+**
+** Description      process encryption complete message.
+**
+** Returns          void
+**
+*******************************************************************************/
+void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
+{
+    tBTA_GATTC_RCB *p_clreg;
+    tBTA_GATTC cb_data;
+
+    p_clreg = bta_gattc_cl_get_regcb(p_msg->enc_cmpl.client_if);
+
+    if (p_clreg && p_clreg->p_cback)
+    {
+        memset(&cb_data, 0, sizeof(tBTA_GATTC));
+
+        cb_data.enc_cmpl.client_if = p_msg->enc_cmpl.client_if;
+        bdcpy(cb_data.enc_cmpl.remote_bda, p_msg->enc_cmpl.remote_bda);
+
+        (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
+    }
+}
+
 /*******************************************************************************
 **
 ** Function         bta_gattc_cancel_open_error
@@ -1635,6 +1666,50 @@
 
 /*******************************************************************************
 **
+** Function         bta_gattc_enc_cmpl_cback
+**
+** Description      encryption complete callback function to GATT client stack.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
+{
+    tBTA_GATTC_DATA *p_buf;
+    tBTA_GATTC_CLCB *p_clcb = NULL;
+
+    if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
+    {
+        return;
+    }
+
+#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
+    /* filter this event just for BTA HH LE GATT client,
+       In the future, if we want to enable encryption complete event
+       for all GATT clients, we can remove this code */
+    if (!bta_hh_le_is_hh_gatt_if(gattc_if))
+    {
+        return;
+    }
+#endif
+
+    APPL_TRACE_DEBUG1("bta_gattc_enc_cmpl_cback: cif = %d", gattc_if);
+
+    if ((p_buf = (tBTA_GATTC_DATA *) GKI_getbuf(sizeof(tBTA_GATTC_DATA))) != NULL)
+    {
+        memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
+
+        p_buf->enc_cmpl.hdr.event            = BTA_GATTC_ENC_CMPL_EVT;
+        p_buf->enc_cmpl.hdr.layer_specific   = p_clcb->bta_conn_id;
+        p_buf->enc_cmpl.client_if            = gattc_if;
+        bdcpy(p_buf->enc_cmpl.remote_bda, bda);
+
+        bta_sys_sendmsg(p_buf);
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         bta_gattc_process_api_refresh
 **
 ** Description      process refresh API to delete cache and start a new discovery
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
index c2056d4..1ff8f79 100644
--- a/bta/gatt/bta_gattc_int.h
+++ b/bta/gatt/bta_gattc_int.h
@@ -69,7 +69,8 @@
     BTA_GATTC_API_REG_EVT,
     BTA_GATTC_API_DEREG_EVT,
     BTA_GATTC_API_LISTEN_EVT,
-    BTA_GATTC_API_DISABLE_EVT
+    BTA_GATTC_API_DISABLE_EVT,
+    BTA_GATTC_ENC_CMPL_EVT
 };
 typedef UINT16 tBTA_GATTC_INT_EVT;
 
@@ -195,6 +196,13 @@
     tGATT_DISCONN_REASON    reason;
 }tBTA_GATTC_INT_CONN;
 
+typedef struct
+{
+    BT_HDR                  hdr;
+    BD_ADDR                 remote_bda;
+    tBTA_GATTC_IF           client_if;
+}tBTA_GATTC_ENC_CMPL;
+
 typedef union
 {
     BT_HDR                      hdr;
@@ -213,6 +221,7 @@
     tBTA_GATTC_CI_EVT           ci_save;
     tBTA_GATTC_CI_LOAD          ci_load;
     tBTA_GATTC_INT_CONN         int_conn;
+    tBTA_GATTC_ENC_CMPL         enc_cmpl;
 
     tBTA_GATTC_INT_START_IF     int_start_if;
     tBTA_GATTC_INT_DEREG        int_dereg;
@@ -433,6 +442,7 @@
 extern void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
 extern void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
 extern void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB  *p_clreg);
+extern void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
 
 /* function within state machine */
 extern void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
diff --git a/bta/gatt/bta_gattc_main.c b/bta/gatt/bta_gattc_main.c
index 9427f89..650cf5e 100644
--- a/bta/gatt/bta_gattc_main.c
+++ b/bta/gatt/bta_gattc_main.c
@@ -386,6 +386,11 @@
             bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);
             break;
 #endif
+
+        case BTA_GATTC_ENC_CMPL_EVT:
+            bta_gattc_process_enc_cmpl(p_cb, (tBTA_GATTC_DATA *) p_msg);
+            break;
+
         default:
             if (p_msg->event == BTA_GATTC_INT_CONN_EVT)
                 p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg);
diff --git a/bta/gatt/bta_gatts_act.c b/bta/gatt/bta_gatts_act.c
index f59b593..f1bd88e 100644
--- a/bta/gatt/bta_gatts_act.c
+++ b/bta/gatt/bta_gatts_act.c
@@ -49,7 +49,8 @@
     NULL,
     NULL,
     NULL,
-    bta_gatts_send_request_cback
+    bta_gatts_send_request_cback,
+    NULL
 };
 
 tGATT_APPL_INFO bta_gatts_nv_cback =
diff --git a/bta/hh/bta_hh_act.c b/bta/hh/bta_hh_act.c
index 1c83d07..19f6b0c 100644
--- a/bta/hh/bta_hh_act.c
+++ b/bta/hh/bta_hh_act.c
@@ -222,6 +222,10 @@
                     p_cb->app_id = 0;
                 }
             }
+            else
+            {
+                hdl = p_cb->hid_handle;
+            }
             /* else : incoming connection after SDP should update the SDP information as well */
 
             if (p_cb->app_id != 0)
diff --git a/bta/hh/bta_hh_int.h b/bta/hh/bta_hh_int.h
index 99a8b82..1ac40da 100644
--- a/bta/hh/bta_hh_int.h
+++ b/bta/hh/bta_hh_int.h
@@ -67,6 +67,7 @@
     BTA_HH_GATT_READ_DESCR_CMPL_EVT,
     BTA_HH_GATT_WRITE_DESCR_CMPL_EVT,
     BTA_HH_API_SCPP_UPDATE_EVT,
+    BTA_HH_GATT_ENC_CMPL_EVT,
 #endif
 
     /* not handled by execute state machine */
@@ -182,6 +183,7 @@
     tBTA_HH_LE_CLOSE         le_close;
     tBTA_GATTC_OPEN          le_open;
     tBTA_HH_SCPP_UPDATE      le_scpp_update;
+    tBTA_GATTC_ENC_CMPL_CB   le_enc_cmpl;
 #endif
 } tBTA_HH_DATA;
 
@@ -201,7 +203,7 @@
 }tBTA_HH_LE_RPT;
 
 #ifndef BTA_HH_LE_RPT_MAX
-#define BTA_HH_LE_RPT_MAX       10
+#define BTA_HH_LE_RPT_MAX       20
 #endif
 
 typedef struct
@@ -283,6 +285,7 @@
     UINT8               scps_notify;   /* scan refresh supported/notification enabled */
 #endif
 
+    BOOLEAN             security_pending;
 } tBTA_HH_DEV_CB;
 
 /* key board parsing control block */
@@ -404,7 +407,7 @@
 extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
 extern void bta_hh_security_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
 extern void bta_hh_le_update_scpp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
-
+extern void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
 
 #if BTA_HH_DEBUG
 extern void bta_hh_trace_dev_db(void);
diff --git a/bta/hh/bta_hh_le.c b/bta/hh/bta_hh_le.c
index 52de4d6..dbbfb32 100644
--- a/bta/hh/bta_hh_le.c
+++ b/bta/hh/bta_hh_le.c
@@ -28,6 +28,7 @@
 #include "bta_hh_co.h"
 #include "bta_gatt_api.h"
 #include "srvc_api.h"
+#include "btm_int.h"
 
 #ifndef BTA_HH_LE_RECONN
 #define BTA_HH_LE_RECONN    TRUE
@@ -37,7 +38,7 @@
 
 #define BTA_HH_LE_RPT_TYPE_VALID(x)     ((x) <= BTA_LE_HID_RPT_FEATURE && (x)>=BTA_LE_HID_RPT_INPUT)
 
-#define BTA_HH_LE_RPT_INST_ID_MAP(s,c)  (UINT8)(((s)<<4)||(c))
+#define BTA_HH_LE_RPT_INST_ID_MAP(s,c)  (UINT8)(((s)<<4)|(c))
 #define BTA_HH_LE_RPT_GET_SRVC_INST_ID(x)  (UINT8)(x  >> 4)
 #define BTA_HH_LE_RPT_GET_RPT_INST_ID(x)  (UINT8)(x & 0x0f)
 
@@ -638,6 +639,8 @@
 
     while (p_rpt != NULL)
     {
+        if (!p_rpt->in_use) break;
+
         if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT)
         {
             /* is battery report */
@@ -718,9 +721,10 @@
 #endif
     }
 
-    if (p_rpt->index < BTA_HH_LE_RPT_MAX)
+    if (p_rpt->index < BTA_HH_LE_RPT_MAX - 1)
         p_rpt ++;
-
+    else
+        p_rpt = NULL;
     /* read next report reference descriptor  */
     bta_hh_le_read_rpt_ref_descr(p_dev_cb, p_rpt);
 
@@ -1084,7 +1088,7 @@
                                           p_char_id->char_id.inst_id,
                                           prop) == NULL)
         {
-            APPL_TRACE_ERROR0("Add report entry failed !!!")
+            APPL_TRACE_ERROR0("Add report entry failed !!!");
             break;
         }
 
@@ -1125,7 +1129,7 @@
                                       prop) == NULL)
 
     {
-        APPL_TRACE_ERROR0("Add report entry failed !!!")
+        APPL_TRACE_ERROR0("Add report entry failed !!!");
     }
 
     return;
@@ -1257,6 +1261,28 @@
         bta_hh_le_api_disc_act(p_cb);
 
 }
+
+/*******************************************************************************
+**
+** Function         bta_hh_le_notify_enc_cmpl
+**
+** Description      process GATT encryption complete event
+**
+** Returns
+**
+*******************************************************************************/
+void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf)
+{
+    if (p_cb == NULL || p_cb->security_pending == FALSE ||
+        p_buf == NULL || p_buf->le_enc_cmpl.client_if != bta_hh_cb.gatt_if)
+    {
+        return;
+    }
+
+    p_cb->security_pending = FALSE;
+    bta_hh_start_security(p_cb, NULL);
+}
+
 /*******************************************************************************
 **
 ** Function         bta_hh_start_security
@@ -1269,6 +1295,19 @@
 void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf)
 {
     UINT8           sec_flag=0;
+    tBTM_SEC_DEV_REC  *p_dev_rec;
+
+    p_dev_rec = btm_find_dev(p_cb->addr);
+    if (p_dev_rec)
+    {
+        if (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING ||
+            p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)
+        {
+            /* if security collision happened, wait for encryption done */
+            p_cb->security_pending = TRUE;
+            return;
+        }
+    }
 
     /* verify bond */
     BTM_GetSecurityFlags(p_cb->addr, &sec_flag);
@@ -1372,7 +1411,7 @@
         p_buf->reason               = p_data->reason;
 
         p_dev_cb->conn_id           = BTA_GATT_INVALID_CONN_ID;
-
+        p_dev_cb->security_pending  = FALSE;
         bta_sys_sendmsg(p_buf);
     }
 }
@@ -2593,6 +2632,8 @@
 *******************************************************************************/
 UINT8 bta_hh_le_add_device(tBTA_HH_DEV_CB *p_cb, tBTA_HH_MAINT_DEV *p_dev_info)
 {
+    p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index);
+    bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
 
     /* update DI information */
     bta_hh_update_di_info(p_cb,
@@ -2709,7 +2750,9 @@
 
         case BTA_GATTC_OPEN_EVT: /* 2 */
             p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->open.remote_bda);
-            bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT, (tBTA_HH_DATA *)&p_data->open);
+            if (p_dev_cb) {
+                bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT, (tBTA_HH_DATA *)&p_data->open);
+            }
             break;
 
         case BTA_GATTC_READ_CHAR_EVT: /* 3 */
@@ -2751,6 +2794,15 @@
         case BTA_GATTC_NOTIF_EVT: /* 10 */
             bta_hh_le_input_rpt_notify(&p_data->notify);
             break;
+
+        case BTA_GATTC_ENC_CMPL_CB_EVT: /* 17 */
+            p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->enc_cmpl.remote_bda);
+            if (p_dev_cb) {
+                bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_ENC_CMPL_EVT,
+                              (tBTA_HH_DATA *)&p_data->enc_cmpl);
+            }
+            break;
+
         default:
             break;
     }
diff --git a/bta/hh/bta_hh_main.c b/bta/hh/bta_hh_main.c
index bf54e57..c2554c1 100644
--- a/bta/hh/bta_hh_main.c
+++ b/bta/hh/bta_hh_main.c
@@ -66,7 +66,7 @@
     BTA_HH_START_SEC,
     BTA_HH_SEC_CMPL,
     BTA_HH_LE_UPDATE_SCPP,
-
+    BTA_HH_GATT_ENC_CMPL,
 #endif
     BTA_HH_NUM_ACTIONS
 };
@@ -106,6 +106,7 @@
     ,bta_hh_start_security
     ,bta_hh_security_cmpl
     ,bta_hh_le_update_scpp
+    ,bta_hh_le_notify_enc_cmpl
 #endif
 };
 
@@ -140,6 +141,7 @@
 /* READ_DESCR_CMPL_EVT */        ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST  }
 /* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
 /* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
+/* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,           BTA_HH_IDLE_ST   }
 #endif
 
 };
@@ -170,6 +172,7 @@
 /* READ_DESCR_CMPL_EVT */        ,{BTA_HH_W4_LE_READ_DESCR, BTA_HH_W4_CONN_ST  }
 /* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_WRITE_DESCR,   BTA_HH_W4_CONN_ST   }
 /* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,           BTA_HH_W4_CONN_ST   }
+/* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,        BTA_HH_W4_CONN_ST }
 #endif
 };
 
@@ -199,6 +202,7 @@
 /* READ_DESCR_CMPL_EVT */        ,{BTA_HH_LE_READ_DESCR, BTA_HH_CONN_ST     }   /* do not currently read any descr when connection up */
 /* WRITE_DESCR_CMPL_EVT */       ,{BTA_HH_WRITE_DESCR,   BTA_HH_CONN_ST     }   /* do not currently write any descr when connection up */
 /* SCPP_UPDATE_EVT */            ,{BTA_HH_LE_UPDATE_SCPP,  BTA_HH_CONN_ST   }
+/* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_IGNORE,        BTA_HH_CONN_ST     }
 #endif
 };
 #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
@@ -226,6 +230,7 @@
 /* READ_DESCR_CMPL_EVT */         {BTA_HH_IGNORE,        BTA_HH_W4_SEC   },
 /* WRITE_DESCR_CMPL_EVT */        {BTA_HH_IGNORE,        BTA_HH_W4_SEC   }
 /* SCPP_UPDATE_EVT */            ,{BTA_HH_IGNORE,        BTA_HH_W4_SEC   }
+/* BTA_HH_GATT_ENC_CMPL_EVT */   ,{BTA_HH_GATT_ENC_CMPL, BTA_HH_W4_SEC   }
 };
 #endif
 
diff --git a/bta/hh/bta_hh_utils.c b/bta/hh/bta_hh_utils.c
index 0c67513..c7c783c 100644
--- a/bta/hh/bta_hh_utils.c
+++ b/bta/hh/bta_hh_utils.c
@@ -335,7 +335,7 @@
         APPL_TRACE_DEBUG1("found keycode %02x ",  this_report[xx]);
 #endif
         p_data->caps_lock   = p_kb->caps_lock;
-        p_kb->num_lock      = p_kb->num_lock;
+        p_data->num_lock      = p_kb->num_lock;
     }
 
     memset (p_kb->last_report, 0, BTA_HH_MAX_RPT_CHARS);
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index e52e699..4345fbf 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -1884,7 +1884,7 @@
 *******************************************************************************/
 BTA_API extern void BTA_DmSetAfhChannelAssessment (BOOLEAN enable_or_disable);
 
-#if BLE_INCLUDE == TRUE
+#if BLE_INCLUDED == TRUE
 // btla-specific --
 /*******************************************************************************
 **
@@ -1927,6 +1927,34 @@
 *******************************************************************************/
 BTA_API extern void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask,
                                            tBTA_BLE_ADV_DATA *p_adv_cfg);
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleSetScanRsp
+**
+** Description      This function is called to override the BTA scan response.
+**
+** Parameters       Pointer to User defined ADV data structure
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask,
+                                         tBTA_BLE_ADV_DATA *p_adv_cfg);
+
+/*******************************************************************************
+**
+** Function         BTA_DmBleBroadcast
+**
+** Description      This function starts or stops LE broadcasting.
+**
+** Parameters       start: start or stop broadcast.
+**
+** Returns          None
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleBroadcast (BOOLEAN start);
+
 #endif
 
 #ifdef __cplusplus
diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h
index 93eadd5..bf0d98c 100644
--- a/bta/include/bta_gatt_api.h
+++ b/bta/include/bta_gatt_api.h
@@ -115,6 +115,7 @@
 #define BTA_GATTC_CANCEL_OPEN_EVT   14  /* cancel open event */
 #define BTA_GATTC_SRVC_CHG_EVT      15  /* service change event */
 #define BTA_GATTC_LISTEN_EVT        16  /* listen event */
+#define BTA_GATTC_ENC_CMPL_CB_EVT   17  /* encryption complete callback event */
 
 typedef UINT8 tBTA_GATTC_EVT;
 
@@ -349,6 +350,12 @@
 }tBTA_GATTC_OPEN_CLOSE;
 // btla-specific --
 
+typedef struct
+{
+    tBTA_GATTC_IF       client_if;
+    BD_ADDR             remote_bda;
+}tBTA_GATTC_ENC_CMPL_CB;
+
 typedef union
 {
     tBTA_GATT_STATUS        status;
@@ -362,6 +369,7 @@
     tBTA_GATTC_WRITE        write;            /* write complete data */
     tBTA_GATTC_EXEC_CMPL    exec_cmpl;       /*  execute complete */
     tBTA_GATTC_NOTIFY       notify;           /* notification/indication event data */
+    tBTA_GATTC_ENC_CMPL_CB  enc_cmpl;
     BD_ADDR                 remote_bda;     /* service change event */
 } tBTA_GATTC;
 
diff --git a/btif/co/bta_hh_co.c b/btif/co/bta_hh_co.c
index 51edcd4..9db3370 100644
--- a/btif/co/bta_hh_co.c
+++ b/btif/co/bta_hh_co.c
@@ -419,6 +419,11 @@
     memset(&ev, 0, sizeof(ev));
     ev.type = UHID_CREATE;
     strncpy((char*)ev.u.create.name, dev_name, sizeof(ev.u.create.name) - 1);
+    snprintf((char*)ev.u.create.uniq, sizeof(ev.u.create.uniq),
+             "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+             p_dev->bd_addr.address[5], p_dev->bd_addr.address[4],
+             p_dev->bd_addr.address[3], p_dev->bd_addr.address[2],
+             p_dev->bd_addr.address[1], p_dev->bd_addr.address[0]);
     ev.u.create.rd_size = dscp_len;
     ev.u.create.rd_data = p_dscp;
     ev.u.create.bus = BUS_BLUETOOTH;
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c
index 476aaba..aa42dbc 100755
--- a/btif/src/bluetooth.c
+++ b/btif/src/bluetooth.c
@@ -155,7 +155,6 @@
         return;
 
     btif_shutdown_bluetooth();
-    bt_utils_cleanup();
 
     /* hal callbacks reset upon shutdown complete callback */
 
diff --git a/btif/src/btif_config_util.cpp b/btif/src/btif_config_util.cpp
index 885f5c2..0cc2b36 100644
--- a/btif/src/btif_config_util.cpp
+++ b/btif/src/btif_config_util.cpp
@@ -470,6 +470,8 @@
     {
         error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
         //debug("out");
+        if (fd >= 0)
+            close(fd);
         return FALSE;
     }
     //get local bt device name from bluez config
@@ -539,6 +541,8 @@
     {
         error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
         //debug("out");
+        if (fd >= 0)
+            close(fd);
         return FALSE;
     }
     int line_size = 0;
@@ -597,6 +601,8 @@
     {
         error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
         //debug("out");
+        if (fd >= 0)
+            close(fd);
         return FALSE;
     }
     int pos = 0;
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 40f19d0..9504c3c 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -37,6 +37,7 @@
 
 #define LOG_TAG "BTIF_CORE"
 #include "btif_api.h"
+#include "bt_utils.h"
 #include "bta_api.h"
 #include "gki.h"
 #include "btu.h"
@@ -737,6 +738,14 @@
 {
     BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
 
+    if (btif_core_state == BTIF_CORE_STATE_DISABLING)
+    {
+        BTIF_TRACE_WARNING0("shutdown during disabling");
+        /* shutdown called before disabling is done */
+        btif_shutdown_pending = 1;
+        return BT_STATUS_NOT_READY;
+    }
+
     if (btif_is_enabled())
     {
         BTIF_TRACE_WARNING0("shutdown while still enabled, initiate disable");
@@ -765,6 +774,8 @@
 
     btif_dut_mode = 0;
 
+    bt_utils_cleanup();
+
     BTIF_TRACE_DEBUG1("%s done", __FUNCTION__);
 
     return BT_STATUS_SUCCESS;
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index b2e80d3..3baee2b 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -1936,6 +1936,25 @@
 
 /*******************************************************************************
 **
+** Function         btif_dm_hh_open_failed
+**
+** Description      informs the upper layers if the HH have failed during bonding
+**
+** Returns          none
+**
+*******************************************************************************/
+
+void btif_dm_hh_open_failed(bt_bdaddr_t *bdaddr)
+{
+    if (pairing_cb.state == BT_BOND_STATE_BONDING &&
+            bdcmp(bdaddr->address, pairing_cb.bd_addr) == 0)
+    {
+        bond_state_changed(BT_STATUS_FAIL, bdaddr, BT_BOND_STATE_NONE);
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         btif_dm_remove_bond
 **
 ** Description      Removes bonding with the specified device
diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c
index ce51ce2..64cd976 100644
--- a/btif/src/btif_gatt_client.c
+++ b/btif/src/btif_gatt_client.c
@@ -104,8 +104,8 @@
 
 typedef struct
 {
-    tBTM_BLE_AD_MASK mask;
-    tBTM_BLE_ADV_DATA data;
+    tBTA_BLE_AD_MASK mask;
+    tBTA_BLE_ADV_DATA data;
 } btgatt_adv_data;
 
 typedef struct
@@ -819,17 +819,46 @@
             break;
 
         case BTIF_GATTC_LISTEN:
+#ifdef BLE_PERIPHERAL_MODE_SUPPORT
             BTA_GATTC_Listen(p_cb->client_if, p_cb->start, NULL);
+#else
+            BTA_DmBleBroadcast(p_cb->start);
+#endif
             break;
 
         case BTIF_GATTC_SET_ADV_DATA:
         {
             if (p_cb->start == 0)
-                BTM_BleWriteAdvData(p_cb->adv_data.mask, &p_cb->adv_data.data);
+                BTA_DmBleSetAdvConfig(p_cb->adv_data.mask, &p_cb->adv_data.data);
             else
-                BTM_BleWriteScanRsp(p_cb->adv_data.mask, &p_cb->adv_data.data);
+                BTA_DmBleSetScanRsp(p_cb->adv_data.mask, &p_cb->adv_data.data);
+
+            // Cleanup ...
+
+            // ... manufacturer data
             if (p_cb->adv_data.data.manu.p_val != NULL)
                 GKI_freebuf(p_cb->adv_data.data.manu.p_val);
+
+            // ... service data
+            if (p_cb->adv_data.data.p_proprietary != NULL)
+            {
+                int i = 0;
+                tBTA_BLE_PROP_ELEM *p_elem = p_cb->adv_data.data.p_proprietary->p_elem;
+                while (i++ != p_cb->adv_data.data.p_proprietary->num_elem && p_elem)
+                {
+                    if (p_elem->p_val != NULL)
+                        GKI_freebuf(p_elem->p_val);
+                    ++p_elem;
+                }
+                if (p_cb->adv_data.data.p_proprietary->p_elem != NULL)
+                    GKI_freebuf(p_cb->adv_data.data.p_proprietary->p_elem);
+                GKI_freebuf(p_cb->adv_data.data.p_proprietary);
+            }
+
+            // ... service list
+            if (p_cb->adv_data.data.services.p_uuid != NULL)
+                GKI_freebuf(p_cb->adv_data.data.services.p_uuid);
+
             break;
         }
 
@@ -904,7 +933,9 @@
 
 static bt_status_t btif_gattc_set_adv_data(int client_if, bool set_scan_rsp, bool include_name,
                 bool include_txpower, int min_interval, int max_interval, int appearance,
-                uint16_t manufacturer_len, char* manufacturer_data)
+                uint16_t manufacturer_len, char* manufacturer_data,
+                uint16_t service_data_len, char* service_data,
+                uint16_t service_uuid_len, char* service_uuid)
 {
     CHECK_BTGATT_INIT();
     btif_gattc_cb_t btif_cb;
@@ -950,6 +981,112 @@
         }
     }
 
+    tBTA_BLE_PROP_ELEM *p_elem_service_data = NULL;
+    tBTA_BLE_PROP_ELEM *p_elem_service_128 = NULL;
+
+    if (service_data_len > 0 && service_data != NULL)
+    {
+        p_elem_service_data = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
+        if (p_elem_service_data != NULL)
+        {
+            p_elem_service_data->p_val = GKI_getbuf(service_data_len);
+            if (p_elem_service_data->p_val != NULL)
+            {
+                p_elem_service_data->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
+                p_elem_service_data->len = service_data_len;
+                memcpy(p_elem_service_data->p_val, service_data, service_data_len);
+
+            } else {
+                GKI_freebuf(p_elem_service_data);
+                p_elem_service_data = NULL;
+            }
+        }
+    }
+
+    if (service_uuid_len > 0 && service_uuid != NULL)
+    {
+        btif_cb.adv_data.data.services.list_cmpl = FALSE;
+        btif_cb.adv_data.data.services.num_service = 0;
+
+        btif_cb.adv_data.data.services.p_uuid =
+            GKI_getbuf(service_uuid_len / LEN_UUID_128 * LEN_UUID_16);
+        if (btif_cb.adv_data.data.services.p_uuid != NULL)
+        {
+            UINT16 *p_uuid_out = btif_cb.adv_data.data.services.p_uuid;
+            while (service_uuid_len >= LEN_UUID_128)
+            {
+                bt_uuid_t uuid;
+                memset(&uuid, 0, sizeof(bt_uuid_t));
+                memcpy(&uuid.uu, service_uuid, LEN_UUID_128);
+
+                tBT_UUID bt_uuid;
+                memset(&bt_uuid, 0, sizeof(tBT_UUID));
+                btif_to_bta_uuid(&bt_uuid, &uuid);
+
+                if (bt_uuid.len == LEN_UUID_16)
+                {
+                    btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_SERVICE;
+                    ++btif_cb.adv_data.data.services.num_service;
+                    *p_uuid_out++ = bt_uuid.uu.uuid16;
+
+                } else if (bt_uuid.len == LEN_UUID_128 && p_elem_service_128 == NULL) {
+                    /* Currently, only one 128-bit UUID is supported */
+                    p_elem_service_128 = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
+                    if (p_elem_service_128 != NULL)
+                    {
+                        p_elem_service_128->p_val = GKI_getbuf(LEN_UUID_128);
+                        if (p_elem_service_128->p_val != NULL)
+                        {
+                            p_elem_service_128->adv_type = BTM_BLE_AD_TYPE_128SRV_PART;
+                            p_elem_service_128->len = LEN_UUID_128;
+                            memcpy(p_elem_service_128->p_val, bt_uuid.uu.uuid128, LEN_UUID_128);
+
+                        } else {
+                            GKI_freebuf(p_elem_service_128);
+                            p_elem_service_128 = NULL;
+                        }
+                    }
+                }
+
+                service_uuid += LEN_UUID_128;
+                service_uuid_len -= LEN_UUID_128;
+            }
+        }
+    }
+
+    if (p_elem_service_data != NULL || p_elem_service_128 != NULL)
+    {
+        btif_cb.adv_data.data.p_proprietary = GKI_getbuf(sizeof(tBTA_BLE_PROPRIETARY));
+        if (btif_cb.adv_data.data.p_proprietary != NULL)
+        {
+            tBTA_BLE_PROPRIETARY *p_prop = btif_cb.adv_data.data.p_proprietary;
+            tBTA_BLE_PROP_ELEM *p_elem = NULL;
+            p_prop->num_elem = 0;
+            btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_PROPRIETARY;
+
+            if (p_elem_service_128 != NULL)
+                ++p_prop->num_elem;
+
+            if (p_elem_service_data != NULL)
+                ++p_prop->num_elem;
+
+            p_prop->p_elem = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM) * p_prop->num_elem);
+            p_elem = p_prop->p_elem;
+
+            if (p_elem_service_128 != NULL)
+            {
+                memcpy(p_elem++, p_elem_service_128, sizeof(tBTA_BLE_PROP_ELEM));
+                GKI_freebuf(p_elem_service_128);
+            }
+
+            if (p_elem_service_data != NULL)
+            {
+                memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM));
+                GKI_freebuf(p_elem_service_data);
+            }
+        }
+    }
+
     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SET_ADV_DATA,
                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
 }
diff --git a/btif/src/btif_gatt_test.c b/btif/src/btif_gatt_test.c
index 8c23d56..2a316fe 100644
--- a/btif/src/btif_gatt_test.c
+++ b/btif/src/btif_gatt_test.c
@@ -197,6 +197,7 @@
     btif_test_command_complete_cback,
     btif_test_discovery_result_cback,
     btif_test_discovery_complete_cback,
+    NULL,
     NULL
 };
 
diff --git a/btif/src/btif_hh.c b/btif/src/btif_hh.c
index 1c64e3e..1aca7df 100644
--- a/btif/src/btif_hh.c
+++ b/btif/src/btif_hh.c
@@ -159,6 +159,7 @@
 extern void btif_dm_cb_remove_bond(bt_bdaddr_t *bd_addr);
 extern BOOLEAN check_cod_hid(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
 extern int  scru_ascii_2_hex(char *p_ascii, int len, UINT8 *p_hex);
+extern void btif_dm_hh_open_failed(bt_bdaddr_t *bdaddr);
 
 /*****************************************************************************
 **  Local Function prototypes
@@ -533,6 +534,9 @@
         return;
     }
 
+    /* need to notify up-layer device is disconnected to avoid state out of sync with up-layer */
+    HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr), BTHH_CONN_STATE_DISCONNECTED);
+
     p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN;
     p_dev->dev_handle = BTA_HH_INVALID_HANDLE;
     if (btif_hh_cb.device_num > 0) {
@@ -842,6 +846,7 @@
             }
             else {
                 bt_bdaddr_t *bdaddr = (bt_bdaddr_t*)p_data->conn.bda;
+                btif_dm_hh_open_failed(bdaddr);
                 HAL_CBACK(bt_hh_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,BTHH_CONN_STATE_DISCONNECTED);
                 btif_hh_cb.status = BTIF_HH_DEV_DISCONNECTED;
             }
@@ -873,14 +878,28 @@
                 BTIF_TRACE_WARNING1("Error: cannot find device with handle %d", p_data->dev_status.handle);
             }
             break;
-        case BTA_HH_GET_RPT_EVT:
+        case BTA_HH_GET_RPT_EVT: {
+            BT_HDR *hdr = p_data->hs_data.rsp_data.p_rpt_data;
+            UINT8 *data = NULL;
+            UINT16 len = 0;
+
             BTIF_TRACE_DEBUG2("BTA_HH_GET_RPT_EVT: status = %d, handle = %d",
                  p_data->hs_data.status, p_data->hs_data.handle);
-            p_dev = btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
-            HAL_CBACK(bt_hh_callbacks, get_report_cb,(bt_bdaddr_t*) &(p_dev->bd_addr), (bthh_status_t) p_data->hs_data.status,
-                (uint8_t*) p_data->hs_data.rsp_data.p_rpt_data, BT_HDR_SIZE);
+            /* p_rpt_data in HANDSHAKE response case */
+            if (hdr) {
+                data = (UINT8 *)(hdr + 1) + hdr->offset;
+                len = hdr->len;
+            }
+            p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
+            if (p_dev) {
+                HAL_CBACK(bt_hh_callbacks, get_report_cb,
+                          (bt_bdaddr_t*) &(p_dev->bd_addr),
+                          (bthh_status_t) p_data->hs_data.status, data, len);
+            } else {
+                BTIF_TRACE_WARNING1("Error: cannot find device with handle %d", p_data->hs_data.handle);
+            }
             break;
-
+        }
         case BTA_HH_SET_RPT_EVT:
             BTIF_TRACE_DEBUG2("BTA_HH_SET_RPT_EVT: status = %d, handle = %d",
             p_data->dev_status.status, p_data->dev_status.handle);
@@ -935,9 +954,18 @@
             }
             {
                 char *cached_name = NULL;
-                char name[] = "Broadcom Bluetooth HID";
-                if (cached_name == NULL) {
-                    cached_name = name;
+                bt_bdname_t bdname;
+                bt_property_t prop_name;
+                BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
+                                           sizeof(bt_bdname_t), &bdname);
+                if (btif_storage_get_remote_device_property(
+                    &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS)
+                {
+                    cached_name = (char *)bdname.name;
+                }
+                else
+                {
+                    cached_name = "Bluetooth HID";
                 }
 
                 BTIF_TRACE_WARNING2("%s: name = %s", __FUNCTION__, cached_name);
@@ -1463,6 +1491,7 @@
 
     p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
     if (p_dev != NULL) {
+
         BTA_HhGetProtoMode(p_dev->dev_handle);
     }
     else {
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index ff9f92c..d4d85f2 100755
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -88,6 +88,7 @@
 #define BTIF_MEDIA_TASK_CMD_MBOX        TASK_MBOX_0     /* cmd mailbox  */
 #define BTIF_MEDIA_TASK_DATA_MBOX       TASK_MBOX_1     /* data mailbox  */
 
+
 /* BTIF media cmd event definition : BTIF_MEDIA_TASK_CMD */
 enum
 {
@@ -120,6 +121,7 @@
    (1000/TICKS_PER_SEC) (10) */
 
 #define BTIF_MEDIA_TIME_TICK                     (20 * BTIF_MEDIA_NUM_TICK)
+#define A2DP_DATA_READ_POLL_MS    (BTIF_MEDIA_TIME_TICK / 2)
 
 /* buffer pool */
 #define BTIF_MEDIA_AA_POOL_ID GKI_POOL_ID_3
@@ -175,8 +177,11 @@
    but due to link flow control or thread preemption in lower
    layers we might need to temporarily buffer up data */
 
-/* 24 frames is equivalent to 6.89*24*2.9 ~= 480 ms @ 44.1 khz, 20 ms mediatick */
-#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 24
+/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
+#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 18
+#define A2DP_PACKET_COUNT_LOW_WATERMARK 5
+#define MAX_PCM_FRAME_NUM_PER_TICK     40
+#define RESET_RATE_COUNTER_THRESHOLD_MS    2000
 
 //#define BTIF_MEDIA_VERBOSE_ENABLED
 
@@ -199,6 +204,10 @@
     INT32  aa_feed_residue;
     UINT32 counter;
     UINT32 bytes_per_tick;  /* pcm bytes read each media task tick */
+    UINT32 max_counter_exit;
+    UINT32 max_counter_enter;
+    UINT32 overflow_count;
+    BOOLEAN overflow;
 } tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;
 
 
@@ -553,7 +562,8 @@
             /*  read directly from media task from here on (keep callback for
                 connection events */
             UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
-
+            UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
+                       (void *)A2DP_DATA_READ_POLL_MS);
             /* Start the media task to encode SBC */
             btif_media_task_start_aa_req();
 
@@ -1772,6 +1782,11 @@
  *******************************************************************************/
 static void btif_media_task_feeding_state_reset(void)
 {
+    APPL_TRACE_WARNING3("overflow %d, enter %d, exit %d",
+        btif_media_cb.media_feeding_state.pcm.overflow_count,
+        btif_media_cb.media_feeding_state.pcm.max_counter_enter,
+        btif_media_cb.media_feeding_state.pcm.max_counter_exit);
+
     /* By default, just clear the entire state */
     memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state));
 
@@ -1852,7 +1867,7 @@
  *******************************************************************************/
 static UINT8 btif_get_num_aa_frame(void)
 {
-    UINT8 result=0;
+    UINT32 result=0;
 
     switch (btif_media_cb.TxTranscoding)
     {
@@ -1865,11 +1880,24 @@
 
             btif_media_cb.media_feeding_state.pcm.counter +=
                                 btif_media_cb.media_feeding_state.pcm.bytes_per_tick;
+            if ((!btif_media_cb.media_feeding_state.pcm.overflow) ||
+                (btif_media_cb.TxAaQ.count < A2DP_PACKET_COUNT_LOW_WATERMARK)) {
+                if (btif_media_cb.media_feeding_state.pcm.overflow) {
+                    btif_media_cb.media_feeding_state.pcm.overflow = FALSE;
 
-            /* calculate nbr of frames pending for this media tick */
-            result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
-            btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
-
+                    if (btif_media_cb.media_feeding_state.pcm.counter >
+                        btif_media_cb.media_feeding_state.pcm.max_counter_exit) {
+                        btif_media_cb.media_feeding_state.pcm.max_counter_exit =
+                            btif_media_cb.media_feeding_state.pcm.counter;
+                    }
+                }
+                /* calculate nbr of frames pending for this media tick */
+                result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
+                if (result > MAX_PCM_FRAME_NUM_PER_TICK) result = MAX_PCM_FRAME_NUM_PER_TICK;
+                btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
+            } else {
+                result = 0;
+            }
             VERBOSE("WRITE %d FRAMES", result);
         }
         break;
@@ -1885,7 +1913,7 @@
     APPL_TRACE_DEBUG1("btif_get_num_aa_frame returns %d", result);
 #endif
 
-    return result;
+    return (UINT8)result;
 }
 
 /*******************************************************************************
@@ -2182,6 +2210,32 @@
         {
             GKI_freebuf(p_buf);
         }
+
+        if (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ) {
+            UINT32 reset_rate_bytes = btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
+                                (RESET_RATE_COUNTER_THRESHOLD_MS / BTIF_MEDIA_TIME_TICK);
+            btif_media_cb.media_feeding_state.pcm.overflow = TRUE;
+            btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
+                     btif_media_cb.encoder.s16NumOfSubBands *
+                     btif_media_cb.encoder.s16NumOfBlocks *
+                     btif_media_cb.media_feeding.cfg.pcm.num_channel *
+                     btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
+
+            btif_media_cb.media_feeding_state.pcm.overflow_count++;
+            if (btif_media_cb.media_feeding_state.pcm.counter >
+                btif_media_cb.media_feeding_state.pcm.max_counter_enter) {
+                btif_media_cb.media_feeding_state.pcm.max_counter_enter =
+                    btif_media_cb.media_feeding_state.pcm.counter;
+            }
+
+            if (btif_media_cb.media_feeding_state.pcm.counter > reset_rate_bytes) {
+                btif_media_cb.media_feeding_state.pcm.counter = 0;
+                APPL_TRACE_WARNING0("btif_media_aa_prep_sbc_2_send:reset rate counter");
+            }
+
+            /* no more pcm to read */
+            nb_frame = 0;
+        }
     }
 }
 
@@ -2201,13 +2255,6 @@
     VERBOSE("btif_media_aa_prep_2_send : %d frames (queue %d)", nb_frame,
                        btif_media_cb.TxAaQ.count);
 
-    while (btif_media_cb.TxAaQ.count >= MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
-    {
-        APPL_TRACE_WARNING1("btif_media_aa_prep_2_send congestion buf count %d",
-                             btif_media_cb.TxAaQ.count);
-        GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ)));
-    }
-
     switch (btif_media_cb.TxTranscoding)
     {
     case BTIF_MEDIA_TRSCD_PCM_2_SBC:
@@ -2237,8 +2284,10 @@
     /* get the number of frame to send */
     nb_frame_2_send = btif_get_num_aa_frame();
 
-    /* format and Q buffer to send */
-    btif_media_aa_prep_2_send(nb_frame_2_send);
+    if (nb_frame_2_send != 0) {
+        /* format and Q buffer to send */
+        btif_media_aa_prep_2_send(nb_frame_2_send);
+    }
 
     /* send it */
     VERBOSE("btif_media_send_aa_frame : send %d frames", nb_frame_2_send);
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
index 86b1521..644fd1c 100644
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -1499,7 +1499,7 @@
 
     if (!btif_config_exist("Local", BTIF_STORAGE_HL_APP, BTIF_STORAGE_HL_APP_CB))
     {
-        memset(value, value_size, 0);
+        memset(value, 0, value_size);
         if (!btif_config_set("Local", BTIF_STORAGE_HL_APP,BTIF_STORAGE_HL_APP_CB,
                              value, value_size, BTIF_CFG_TYPE_BIN))
         {
@@ -1684,8 +1684,9 @@
     char input_value [20];
 
     bd2str(remote_bd_addr, &bdstr);
-    strncpy(input_value, (char*)bdstr, 20);
-    strncat(input_value,BTIF_AUTO_PAIR_CONF_VALUE_SEPARATOR, 20);
+    strlcpy(input_value, (char*)bdstr, sizeof(input_value));
+    strlcat(input_value,BTIF_AUTO_PAIR_CONF_VALUE_SEPARATOR, sizeof(input_value));
+
     int line_size = sizeof(linebuf);
     if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
                             BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR, linebuf, &line_size))
diff --git a/hci/src/btsnoop.c b/hci/src/btsnoop.c
index 4807df8..5b0f26d 100755
--- a/hci/src/btsnoop.c
+++ b/hci/src/btsnoop.c
@@ -66,6 +66,11 @@
 #define SNOOPDBG(param, ...) {}
 #endif
 
+#define HCIT_TYPE_COMMAND   1
+#define HCIT_TYPE_ACL_DATA  2
+#define HCIT_TYPE_SCO_DATA  3
+#define HCIT_TYPE_EVENT     4
+
 /* file descriptor of the BT snoop file (by default, -1 means disabled) */
 int hci_btsnoop_fd = -1;
 
@@ -117,6 +122,7 @@
 #define BTSNOOP_EPOCH_HI 0x00dcddb3U
 #define BTSNOOP_EPOCH_LO 0x0f2f8000U
 
+
 /*******************************************************************************
  **
  ** Function         tv_to_btsnoop_ts
@@ -252,6 +258,46 @@
 }
 
 /*******************************************************************************
+ ** Function          btsnoop_write
+ **
+ ** Description       Function used to write the actual data to the log
+ **
+ ** Returns           none
+*******************************************************************************/
+
+void btsnoop_write(uint8_t *p, uint32_t flags, const uint8_t *ptype, uint32_t len)
+{
+    uint32_t value, value_hi;
+    struct timeval tv;
+    struct iovec io[3];
+    uint32_t header[6];
+
+    /* store the length in both original and included fields */
+    header[0] = l_to_be(len + 1);
+    header[1] = header[0];
+    /* flags: data can be sent or received */
+    header[2] = l_to_be(flags);
+    /* drops: none */
+    header[3] = 0;
+    /* time */
+    gettimeofday(&tv, NULL);
+    tv_to_btsnoop_ts(&header[5], &header[4], &tv);
+    header[4] = l_to_be(header[4]);
+    header[5] = l_to_be(header[5]);
+
+    io[0].iov_base = header;
+    io[0].iov_len = sizeof(header);
+
+    io[1].iov_base = (void*)ptype;
+    io[1].iov_len = 1;
+
+    io[2].iov_base = p;
+    io[2].iov_len = len;
+
+    (void) writev(hci_btsnoop_fd, io, 3);
+}
+
+/*******************************************************************************
  **
  ** Function         btsnoop_hci_cmd
  **
@@ -261,42 +307,14 @@
 *******************************************************************************/
 void btsnoop_hci_cmd(uint8_t *p)
 {
+    const uint8_t cmd = HCIT_TYPE_COMMAND;
+    int plen;
     SNOOPDBG("btsnoop_hci_cmd: fd = %d", hci_btsnoop_fd);
-
-    if (hci_btsnoop_fd != -1)
-    {
-        uint32_t value, value_hi;
-        struct timeval tv;
-
-        /* since these display functions are called from different contexts */
-        utils_lock();
-
-        /* store the length in both original and included fields */
-        value = l_to_be(p[2] + 4);
-        write(hci_btsnoop_fd, &value, 4);
-        write(hci_btsnoop_fd, &value, 4);
-        /* flags: command sent from the host */
-        value = l_to_be(2);
-        write(hci_btsnoop_fd, &value, 4);
-        /* drops: none */
-        value = 0;
-        write(hci_btsnoop_fd, &value, 4);
-        /* time */
-        gettimeofday(&tv, NULL);
-        tv_to_btsnoop_ts(&value, &value_hi, &tv);
-        value_hi = l_to_be(value_hi);
-        value = l_to_be(value);
-        write(hci_btsnoop_fd, &value_hi, 4);
-        write(hci_btsnoop_fd, &value, 4);
-        /* data */
-        write(hci_btsnoop_fd, "\x1", 1);
-        write(hci_btsnoop_fd, p, p[2] + 3);
-
-        /* since these display functions are called from different contexts */
-        utils_unlock();
-    }
+    plen = (int) p[2] + 3;
+    btsnoop_write(p, 2, &cmd, plen);
 }
 
+
 /*******************************************************************************
  **
  ** Function         btsnoop_hci_evt
@@ -307,40 +325,12 @@
 *******************************************************************************/
 void btsnoop_hci_evt(uint8_t *p)
 {
+    const uint8_t evt = HCIT_TYPE_EVENT;
+    int plen;
     SNOOPDBG("btsnoop_hci_evt: fd = %d", hci_btsnoop_fd);
+    plen = (int) p[1] + 2;
 
-    if (hci_btsnoop_fd != -1)
-    {
-        uint32_t value, value_hi;
-        struct timeval tv;
-
-        /* since these display functions are called from different contexts */
-        utils_lock();
-
-        /* store the length in both original and included fields */
-        value = l_to_be(p[1] + 3);
-        write(hci_btsnoop_fd, &value, 4);
-        write(hci_btsnoop_fd, &value, 4);
-        /* flags: event received in the host */
-        value = l_to_be(3);
-        write(hci_btsnoop_fd, &value, 4);
-        /* drops: none */
-        value = 0;
-        write(hci_btsnoop_fd, &value, 4);
-        /* time */
-        gettimeofday(&tv, NULL);
-        tv_to_btsnoop_ts(&value, &value_hi, &tv);
-        value_hi = l_to_be(value_hi);
-        value = l_to_be(value);
-        write(hci_btsnoop_fd, &value_hi, 4);
-        write(hci_btsnoop_fd, &value, 4);
-        /* data */
-        write(hci_btsnoop_fd, "\x4", 1);
-        write(hci_btsnoop_fd, p, p[1] + 2);
-
-        /* since these display functions are called from different contexts */
-        utils_unlock();
-    }
+    btsnoop_write(p, 3, &evt, plen);
 }
 
 /*******************************************************************************
@@ -353,40 +343,12 @@
 *******************************************************************************/
 void btsnoop_sco_data(uint8_t *p, uint8_t is_rcvd)
 {
+    const uint8_t sco = HCIT_TYPE_SCO_DATA;
+    int plen;
     SNOOPDBG("btsnoop_sco_data: fd = %d", hci_btsnoop_fd);
+    plen = (int) p[2] + 3;
 
-    if (hci_btsnoop_fd != -1)
-    {
-        uint32_t value, value_hi;
-        struct timeval tv;
-
-        /* since these display functions are called from different contexts */
-        utils_lock();
-
-        /* store the length in both original and included fields */
-        value = l_to_be(p[2] + 4);
-        write(hci_btsnoop_fd, &value, 4);
-        write(hci_btsnoop_fd, &value, 4);
-        /* flags: data can be sent or received */
-        value = l_to_be(is_rcvd?1:0);
-        write(hci_btsnoop_fd, &value, 4);
-        /* drops: none */
-        value = 0;
-        write(hci_btsnoop_fd, &value, 4);
-        /* time */
-        gettimeofday(&tv, NULL);
-        tv_to_btsnoop_ts(&value, &value_hi, &tv);
-        value_hi = l_to_be(value_hi);
-        value = l_to_be(value);
-        write(hci_btsnoop_fd, &value_hi, 4);
-        write(hci_btsnoop_fd, &value, 4);
-        /* data */
-        write(hci_btsnoop_fd, "\x3", 1);
-        write(hci_btsnoop_fd, p, p[2] + 3);
-
-        /* since these display functions are called from different contexts */
-        utils_unlock();
-    }
+    btsnoop_write(p, is_rcvd, &sco, plen);
 }
 
 /*******************************************************************************
@@ -399,42 +361,16 @@
 *******************************************************************************/
 void btsnoop_acl_data(uint8_t *p, uint8_t is_rcvd)
 {
+    const uint8_t acl = HCIT_TYPE_ACL_DATA;
+    int plen;
+
     SNOOPDBG("btsnoop_acl_data: fd = %d", hci_btsnoop_fd);
-    if (hci_btsnoop_fd != -1)
-    {
-        uint32_t value, value_hi;
-        struct timeval tv;
 
-        /* since these display functions are called from different contexts */
-        utils_lock();
+    plen = (((int) p[3]) << 8) + ((int) p[2]) +4;
 
-        /* store the length in both original and included fields */
-        value = l_to_be((p[3]<<8) + p[2] + 5);
-        write(hci_btsnoop_fd, &value, 4);
-        write(hci_btsnoop_fd, &value, 4);
-        /* flags: data can be sent or received */
-        value = l_to_be(is_rcvd?1:0);
-        write(hci_btsnoop_fd, &value, 4);
-        /* drops: none */
-        value = 0;
-        write(hci_btsnoop_fd, &value, 4);
-        /* time */
-        gettimeofday(&tv, NULL);
-        tv_to_btsnoop_ts(&value, &value_hi, &tv);
-        value_hi = l_to_be(value_hi);
-        value = l_to_be(value);
-        write(hci_btsnoop_fd, &value_hi, 4);
-        write(hci_btsnoop_fd, &value, 4);
-        /* data */
-        write(hci_btsnoop_fd, "\x2", 1);
-        write(hci_btsnoop_fd, p, (p[3]<<8) + p[2] + 4);
-
-        /* since these display functions are called from different contexts */
-        utils_unlock();
-    }
+    btsnoop_write(p, is_rcvd, &acl, plen);
 }
 
-
 /********************************************************************************
  ** API allow external realtime parsing of output using e.g hcidump
  *********************************************************************************/
@@ -619,11 +555,6 @@
 }
 
 
-#define HCIT_TYPE_COMMAND   1
-#define HCIT_TYPE_ACL_DATA  2
-#define HCIT_TYPE_SCO_DATA  3
-#define HCIT_TYPE_EVENT     4
-
 void btsnoop_capture(HC_BT_HDR *p_buf, uint8_t is_rcvd)
 {
     uint8_t *p = (uint8_t *)(p_buf + 1) + p_buf->offset;
diff --git a/stack/avdt/avdt_msg.c b/stack/avdt/avdt_msg.c
index 5d9c2fb..e3e4c98 100644
--- a/stack/avdt/avdt_msg.c
+++ b/stack/avdt/avdt_msg.c
@@ -688,8 +688,12 @@
                 /* verify length */
                 AVDT_TRACE_WARNING2("psc_mask=0x%x elem_len=%d", p_cfg->psc_mask, elem_len);
                 if( ((0 == (p_cfg->psc_mask & (AVDT_PSC_RECOV|AVDT_PSC_REPORT))) && (elem_len != 3))
-                    || ((p_cfg->psc_mask & AVDT_PSC_RECOV) && (elem_len != 7))
-                    || ((p_cfg->psc_mask & AVDT_PSC_REPORT) && (elem_len != 5)) )
+                    || (((p_cfg->psc_mask & AVDT_PSC_REPORT) && !(p_cfg->psc_mask & AVDT_PSC_RECOV))
+                    && (elem_len != 5))
+                    || ((!(p_cfg->psc_mask & AVDT_PSC_REPORT) && (p_cfg->psc_mask & AVDT_PSC_RECOV))
+                    && (elem_len != 5))
+                    || (((p_cfg->psc_mask & AVDT_PSC_REPORT) && (p_cfg->psc_mask & AVDT_PSC_RECOV))
+                    && (elem_len != 7)) )
                 {
                     err = AVDT_ERR_MUX_FMT;
                     break;
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index 47ee8cf..bfe5fda 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -1518,6 +1518,7 @@
     UINT8                data_len, rssi;
     tBTM_BLE_INQ_CB     *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
     UINT8 *p1;
+    UINT8               *p_uuid16;
 
     STREAM_TO_UINT8    (data_len, p);
 
@@ -1562,6 +1563,26 @@
             p_cur->flag = * p_flag;
     }
 
+    if (p_le_inq_cb->adv_len != 0)
+    {
+        if ((p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache,
+                                         BTM_BLE_AD_TYPE_16SRV_CMPL, &len)) != NULL)
+        {
+            UINT8 i;
+            for (i = 0; i + 2 <= len; i = i + 2)
+            {
+                /* if this BLE device support HID over LE, set HID Major in class of device */
+                if ((p_uuid16[i] | (p_uuid16[i+1] << 8)) == UUID_SERVCLASS_LE_HID)
+                {
+                    p_cur->dev_class[0] = 0;
+                    p_cur->dev_class[1] = BTM_COD_MAJOR_PERIPHERAL;
+                    p_cur->dev_class[2] = 0;
+                    break;
+                }
+            }
+        }
+    }
+
     /* if BR/EDR not supported is not set, assume is a DUMO device */
     if ((p_cur->flag & BTM_BLE_BREDR_NOT_SPT) == 0 &&
          evt_type != BTM_BLE_CONNECT_DIR_EVT)
diff --git a/stack/btm/btm_pm.c b/stack/btm/btm_pm.c
index 19b90d3..925e69f 100644
--- a/stack/btm/btm_pm.c
+++ b/stack/btm/btm_pm.c
@@ -369,8 +369,6 @@
         cb = btm_cb.pm_reg_db[btm_cb.pm_pend_id].cback;
     }
 
-    /* no command pending */
-    btm_cb.pm_pend_link = MAX_L2CAP_LINKS;
 
     /* clear the register record */
     for(xx=0; xx<BTM_MAX_PM_RECORDS; xx++)
@@ -378,8 +376,11 @@
         btm_cb.pm_reg_db[xx].mask = BTM_PM_REC_NOT_USED;
     }
 
-    if(cb != NULL)
+    if(cb != NULL && btm_cb.pm_pend_link < MAX_L2CAP_LINKS)
         (*cb)(btm_cb.acl_db[btm_cb.pm_pend_link].remote_addr, BTM_PM_STS_ERROR, BTM_DEV_RESET, 0);
+
+    /* no command pending */
+    btm_cb.pm_pend_link = MAX_L2CAP_LINKS;
 }
 
 /*******************************************************************************
diff --git a/stack/btu/btu_hcif.c b/stack/btu/btu_hcif.c
index 69b3882..bd7c9ff 100644
--- a/stack/btu/btu_hcif.c
+++ b/stack/btu/btu_hcif.c
@@ -2266,7 +2266,16 @@
 
 static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len)
 {
-/* This is empty until an upper layer cares about returning event */
+    /* LE connection update has completed successfully as a master. */
+    /* We can enable the update request if the result is a success. */
+    /* extract the HCI handle first */
+    UINT8   status;
+    UINT16  handle;
+    BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, "btu_ble_ll_conn_param_upd_evt");
+
+    STREAM_TO_UINT8  (status, p);
+    STREAM_TO_UINT16 (handle, p);
+    L2CA_HandleConnUpdateEvent(handle, status);
 }
 
 static void btu_ble_read_remote_feat_evt (UINT8 *p, UINT16 evt_len)
diff --git a/stack/gap/gap_ble.c b/stack/gap/gap_ble.c
index 6e3afeb..48f4723 100644
--- a/stack/gap/gap_ble.c
+++ b/stack/gap/gap_ble.c
@@ -65,7 +65,8 @@
     gap_ble_c_cmpl_cback,
     NULL,
     NULL,
-    gap_ble_s_attr_request_cback
+    gap_ble_s_attr_request_cback,
+    NULL
 };
 
 
diff --git a/stack/gatt/att_protocol.c b/stack/gatt/att_protocol.c
index 9c715af..3348599 100644
--- a/stack/gatt/att_protocol.c
+++ b/stack/gatt/att_protocol.c
@@ -495,7 +495,7 @@
                 /* do not enq cmd if handle value confirmation or set request */
                 if (cmd_code != GATT_HANDLE_VALUE_CONF && cmd_code != GATT_CMD_WRITE)
                 {
-                    gatt_start_rsp_timer (p_tcb);
+                    gatt_start_rsp_timer (clcb_idx);
                     gatt_cmd_enq(p_tcb, clcb_idx, FALSE, cmd_code, NULL);
                 }
             }
diff --git a/stack/gatt/gatt_api.c b/stack/gatt/gatt_api.c
index a96c58a..232b191 100644
--- a/stack/gatt/gatt_api.c
+++ b/stack/gatt/gatt_api.c
@@ -1285,6 +1285,7 @@
                     (p_clcb->p_reg->gatt_if == gatt_if) &&
                     (p_clcb->p_tcb->tcb_idx == p_tcb->tcb_idx))
                 {
+                    btu_stop_timer(&p_clcb->rsp_timer_ent);
                     gatt_clcb_dealloc (p_clcb);
                     break;
                 }
@@ -1294,7 +1295,9 @@
 
     gatt_deregister_bgdev_list(gatt_if);
     /* update the listen mode */
+#ifdef BLE_PERIPHERAL_MODE_SUPPORT
     GATT_Listen(gatt_if, FALSE, NULL);
+#endif
 
     memset (p_reg, 0, sizeof(tGATT_REG));
 }
diff --git a/stack/gatt/gatt_attr.c b/stack/gatt/gatt_attr.c
index 459580e..9af6a60 100644
--- a/stack/gatt/gatt_attr.c
+++ b/stack/gatt/gatt_attr.c
@@ -48,7 +48,8 @@
     NULL,
     NULL,
     NULL,
-    gatt_profile_request_cback
+    gatt_profile_request_cback,
+    NULL
 } ;
 
 /*******************************************************************************
diff --git a/stack/gatt/gatt_auth.c b/stack/gatt/gatt_auth.c
index 504b7d8..e945c90 100644
--- a/stack/gatt/gatt_auth.c
+++ b/stack/gatt/gatt_auth.c
@@ -228,9 +228,18 @@
     tGATT_TCB   *p_tcb;
     tGATT_PENDING_ENC_CLCB  *p_buf;
     UINT16       count;
+    UINT8        i = 0;
 
     if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL)
     {
+        for (i = 0; i < GATT_MAX_APPS; i++)
+        {
+            if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)
+            {
+                (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if, bd_addr);
+            }
+        }
+
         if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING)
         {
             gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
diff --git a/stack/gatt/gatt_cl.c b/stack/gatt/gatt_cl.c
index b173be9..7457dcb 100644
--- a/stack/gatt/gatt_cl.c
+++ b/stack/gatt/gatt_cl.c
@@ -1096,7 +1096,7 @@
             /* dequeue the request if is write command or sign write */
             if (p_cmd->op_code != GATT_CMD_WRITE && p_cmd->op_code != GATT_SIGN_CMD_WRITE)
             {
-                gatt_start_rsp_timer (p_tcb);
+                gatt_start_rsp_timer (p_cmd->clcb_idx);
             }
             else
             {
@@ -1153,7 +1153,10 @@
             return;
         }
         else
-            btu_stop_timer (&p_tcb->rsp_timer_ent);
+        {
+            btu_stop_timer (&p_clcb->rsp_timer_ent);
+            p_clcb->retry_count = 0;
+        }
     }
     /* the size of the message may not be bigger than the local max PDU size*/
     /* The message has to be smaller than the agreed MTU, len does not count op_code */
diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h
index 48278c2..1f81d63 100644
--- a/stack/gatt/gatt_int.h
+++ b/stack/gatt/gatt_int.h
@@ -78,6 +78,8 @@
 
 /* wait for ATT cmd response timeout value */
 #define GATT_WAIT_FOR_RSP_TOUT       30
+#define GATT_WAIT_FOR_DISC_RSP_TOUT  5
+#define GATT_REQ_RETRY_LIMIT         2
 
 /* characteristic descriptor type */
 #define GATT_DESCR_EXT_DSCPTOR   1    /* Characteristic Extended Properties */
@@ -360,7 +362,6 @@
     UINT8            ind_count;
 
     tGATT_CMD_Q       cl_cmd_q[GATT_CL_MAX_LCB];
-    TIMER_LIST_ENT    rsp_timer_ent;        /* peer response timer */
     TIMER_LIST_ENT    ind_ack_timer_ent;    /* local app confirm to indication timer */
     UINT8             pending_cl_req;
     UINT8             next_slot_inq;    /* index of next available slot in queue */
@@ -397,6 +398,8 @@
     BOOLEAN                 first_read_blob_after_read;
     tGATT_READ_INC_UUID128  read_uuid128;
     BOOLEAN                 in_use;
+    TIMER_LIST_ENT          rsp_timer_ent;  /* peer response timer */
+    UINT8                   retry_count;
 } tGATT_CLCB;
 
 typedef struct
@@ -556,7 +559,7 @@
 extern UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid);
 extern BOOLEAN gatt_uuid_compare(tBT_UUID src, tBT_UUID tar);
 extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size);
-extern void gatt_start_rsp_timer(tGATT_TCB    *p_tcb);
+extern void gatt_start_rsp_timer(UINT16 clcb_idx);
 extern void gatt_start_conf_timer(tGATT_TCB    *p_tcb);
 extern void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle);
 extern void gatt_ind_ack_timeout(TIMER_LIST_ENT *p_tle);
diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c
index e15918c..36f80a4 100644
--- a/stack/gatt/gatt_utils.c
+++ b/stack/gatt/gatt_utils.c
@@ -1116,11 +1116,18 @@
 ** Returns          TRUE if command sent, otherwise FALSE.
 **
 *******************************************************************************/
-void gatt_start_rsp_timer(tGATT_TCB    *p_tcb)
+void gatt_start_rsp_timer(UINT16 clcb_idx)
 {
-    p_tcb->rsp_timer_ent.param  = (TIMER_PARAM_TYPE)p_tcb;
-    btu_start_timer (&p_tcb->rsp_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP,
-                     GATT_WAIT_FOR_RSP_TOUT);
+    tGATT_CLCB *p_clcb = &gatt_cb.clcb[clcb_idx];
+    UINT32 timeout = GATT_WAIT_FOR_RSP_TOUT;
+    p_clcb->rsp_timer_ent.param  = (TIMER_PARAM_TYPE)p_clcb;
+    if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
+        p_clcb->op_subtype == GATT_DISC_SRVC_ALL)
+    {
+        timeout = GATT_WAIT_FOR_DISC_RSP_TOUT;
+    }
+    btu_start_timer (&p_clcb->rsp_timer_ent, BTU_TTYPE_ATT_WAIT_FOR_RSP,
+                     timeout);
 }
 /*******************************************************************************
 **
@@ -1165,8 +1172,32 @@
 *******************************************************************************/
 void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle)
 {
+    tGATT_CLCB *p_clcb = (tGATT_CLCB *)p_tle->param;
+    if (p_clcb == NULL || p_clcb->p_tcb == NULL)
+    {
+        GATT_TRACE_WARNING0("gatt_rsp_timeout clcb is already deleted");
+        return;
+    }
+    if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
+        p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
+        p_clcb->retry_count < GATT_REQ_RETRY_LIMIT)
+    {
+        UINT8 rsp_code;
+        GATT_TRACE_WARNING0("gatt_rsp_timeout retry discovery primary service");
+        if (p_clcb != gatt_cmd_dequeue(p_clcb->p_tcb, &rsp_code))
+        {
+            GATT_TRACE_ERROR0("gatt_rsp_timeout command queue out of sync, disconnect");
+        }
+        else
+        {
+            p_clcb->retry_count++;
+            gatt_act_discovery(p_clcb);
+            return;
+        }
+    }
+
     GATT_TRACE_WARNING0("gatt_rsp_timeout disconnecting...");
-    gatt_disconnect (((tGATT_TCB *)p_tle->param)->peer_bda);
+    gatt_disconnect (p_clcb->p_tcb->peer_bda);
 }
 
 /*******************************************************************************
@@ -2073,6 +2104,7 @@
 
     operation =  p_clcb->operation;
     conn_id = p_clcb->conn_id;
+    btu_stop_timer(&p_clcb->rsp_timer_ent);
 
     gatt_clcb_dealloc(p_clcb);
 
@@ -2114,6 +2146,7 @@
             p_clcb = &gatt_cb.clcb[i];
             if (p_clcb->in_use && p_clcb->p_tcb == p_tcb)
             {
+                btu_stop_timer(&p_clcb->rsp_timer_ent);
                 GATT_TRACE_DEBUG2 ("found p_clcb conn_id=%d clcb_idx=%d", p_clcb->conn_id, p_clcb->clcb_idx);
                 if (p_clcb->operation != GATTC_OPTYPE_NONE)
                     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
@@ -2123,7 +2156,6 @@
             }
         }
 
-        btu_stop_timer (&p_tcb->rsp_timer_ent);
         btu_stop_timer (&p_tcb->ind_ack_timer_ent);
         btu_stop_timer (&p_tcb->conf_timer_ent);
         gatt_free_pending_ind(p_tcb);
diff --git a/stack/include/gatt_api.h b/stack/include/gatt_api.h
index 01afb71..d9704b7 100644
--- a/stack/include/gatt_api.h
+++ b/stack/include/gatt_api.h
@@ -573,7 +573,8 @@
 /* attribute request callback for ATT server */
 typedef void  (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
 
-
+/* Define a callback function when encryption is established. */
+typedef void (tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, BD_ADDR bda);
 
 
 /* Define the structure that applications use to register with
@@ -587,6 +588,7 @@
     tGATT_DISC_RES_CB               *p_disc_res_cb;
     tGATT_DISC_CMPL_CB              *p_disc_cmpl_cb;
     tGATT_REQ_CBACK                 *p_req_cb;
+    tGATT_ENC_CMPL_CB               *p_enc_cmpl_cb;
 } tGATT_CBACK;
 
 /***********************  Start Handle Management Definitions   **********************
diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h
index 95c44e0..7679d26 100644
--- a/stack/include/l2c_api.h
+++ b/stack/include/l2c_api.h
@@ -1146,6 +1146,18 @@
 
 /*******************************************************************************
 **
+** Function         L2CA_HandleConnUpdateEvent
+**
+** Description      This function enables the connection update request from remote
+**                  after a successful connection update response is received.
+**
+** Returns          void
+**
+*******************************************************************************/
+L2C_API void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status);
+
+/*******************************************************************************
+**
 ** Function         L2CA_GetBleConnRole
 **
 ** Description      This function returns the connection role.
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index b8cddd7..a440492 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -81,6 +81,56 @@
         return(FALSE);
 }
 
+/*******************************************************************************
+**
+**  Function        L2CA_InternalBleConnUpdate
+**
+**  Description     update BLE connection based on status
+**
+**  Parameters:     lcb
+**
+**  Return value:   none
+**
+*******************************************************************************/
+static void L2CA_InternalBleConnUpdate (tL2C_LCB *p_lcb)
+{
+    if (p_lcb->upd_status & L2C_BLE_UPDATE_PENDING) return;
+
+    if (p_lcb->upd_status & L2C_BLE_CONN_UPDATE_DISABLE)
+    {
+        /* application requests to disable parameters update.
+           If parameters are already updated, lets set them
+           up to what has been requested during connection establishement */
+        if (p_lcb->upd_status & L2C_BLE_NOT_DEFAULT_PARAM)
+        {
+            tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
+
+            btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle,
+                (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
+                         p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
+                (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
+                         p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
+                (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
+                         p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
+                (UINT16)((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
+                         p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
+                0, 0);
+            p_lcb->upd_status &= ~L2C_BLE_NOT_DEFAULT_PARAM;
+            p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NEW_CONN_PARAM);
+        }
+    }
+    else
+    {
+        /* application allows to do update, if we were delaying one do it now */
+        if (p_lcb->upd_status & L2C_BLE_NEW_CONN_PARAM)
+        {
+            btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval,
+                p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0);
+            p_lcb->upd_status &= ~L2C_BLE_NEW_CONN_PARAM;
+            p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NOT_DEFAULT_PARAM);
+        }
+    }
+}
 
 /*******************************************************************************
 **
@@ -116,7 +166,14 @@
     }
 
     if (p_lcb->link_role == HCI_ROLE_MASTER)
-        btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int, latency, timeout, 0, 0);
+    {
+        p_lcb->min_interval = min_int;
+        p_lcb->max_interval = max_int;
+        p_lcb->latency = latency;
+        p_lcb->timeout = timeout;
+        p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
+        L2CA_InternalBleConnUpdate(p_lcb);
+    }
     else
         l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
 
@@ -150,8 +207,9 @@
         return (FALSE);
     }
 
-    L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d current upd state %d",
-        (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->upd_disabled);
+    L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d upd state %d",
+        (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5],
+        enable, p_lcb->upd_status);
 
     if (!p_lcb->is_ble_link || (p_lcb->link_role != HCI_ROLE_MASTER))
     {
@@ -162,42 +220,56 @@
 
     if (enable)
     {
-        /* application allows to do update, if we were delaying one do it now, otherwise
-        just mark lcb that updates are enabled */
-        if (p_lcb->upd_disabled == UPD_PENDING)
-        {
-            btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval,
-                                               p_lcb->latency, p_lcb->timeout, 0, 0);
-            p_lcb->upd_disabled = UPD_UPDATED;
-        }
-        else
-        {
-            p_lcb->upd_disabled = UPD_ENABLED;
-        }
+        p_lcb->upd_status &= ~L2C_BLE_CONN_UPDATE_DISABLE;
     }
     else
     {
-        /* application requests to disable parameters update.  If parameters are already updated, lets set them
-        up to what has been requested during connection establishement */
-        if (p_lcb->upd_disabled == UPD_UPDATED)
-        {
-            tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (rem_bda);
-
-            btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
-                (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
-                (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
-                (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
-                (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
-                0, 0);
-        }
-        p_lcb->upd_disabled = UPD_DISABLED;
+        p_lcb->upd_status |= L2C_BLE_CONN_UPDATE_DISABLE;
     }
 
+    L2CA_InternalBleConnUpdate(p_lcb);
+
     return (TRUE);
 }
 
 /*******************************************************************************
 **
+** Function         L2CA_HandleConnUpdateEvent
+**
+** Description      This function enables the connection update request from remote
+**                  after a successful connection update response is received.
+**
+** Returns          void
+**
+*******************************************************************************/
+void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status)
+{
+    tL2C_LCB *p_lcb;
+
+    L2CAP_TRACE_DEBUG0("L2CA_HandleConnUpdateEvent");
+
+    /* See if we have a link control block for the remote device */
+    p_lcb = l2cu_find_lcb_by_handle(handle);
+    if (!p_lcb)
+    {
+        L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Invalid handle: %d", handle);
+        return;
+    }
+
+    p_lcb->upd_status &= ~L2C_BLE_UPDATE_PENDING;
+
+    if (status != HCI_SUCCESS)
+    {
+        L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Error status: %d", status);
+    }
+
+    L2CA_InternalBleConnUpdate(p_lcb);
+
+    L2CAP_TRACE_DEBUG1("L2CA_HandleConnUpdateEvent: upd_status=%d", p_lcb->upd_status);
+}
+
+/*******************************************************************************
+**
 ** Function         L2CA_GetBleConnRole
 **
 ** Description      This function returns the connection role.
@@ -321,6 +393,7 @@
                                            p_dev_rec->conn_params.slave_latency,
                                            p_dev_rec->conn_params.supervision_tout,
                                            0, 0);
+        p_lcb->upd_status |= L2C_BLE_UPDATE_PENDING;
     }
 
     /* Tell BTM Acl management about the link */
@@ -487,18 +560,8 @@
                     p_lcb->max_interval = max_interval;
                     p_lcb->latency = latency;
                     p_lcb->timeout = timeout;
-
-                    if (p_lcb->upd_disabled == UPD_ENABLED)
-                    {
-                        btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval,
-                                                            latency, timeout, 0, 0);
-                        p_lcb->upd_disabled = UPD_UPDATED;
-                    }
-                    else
-                    {
-                        L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
-                        p_lcb->upd_disabled = UPD_PENDING;
-                    }
+                    p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
+                    L2CA_InternalBleConnUpdate(p_lcb);
                 }
             }
             else
diff --git a/stack/l2cap/l2c_csm.c b/stack/l2cap/l2c_csm.c
index 0d04d8a..4e24c23 100644
--- a/stack/l2cap/l2c_csm.c
+++ b/stack/l2cap/l2c_csm.c
@@ -892,14 +892,17 @@
     case L2CEVT_L2CAP_DATA:                        /* Peer data packet rcvd    */
         L2CAP_TRACE_API1 ("L2CAP - Calling DataInd_Cb(), CID: 0x%04x", p_ccb->local_cid);
 #if (L2CAP_NUM_FIXED_CHNLS > 0)
-        if (p_ccb->local_cid < L2CAP_BASE_APPL_CID)
+        if (p_ccb->local_cid >= L2CAP_FIRST_FIXED_CHNL &&
+                p_ccb->local_cid <= L2CAP_LAST_FIXED_CHNL)
         {
-            if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)
-                (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(p_ccb->p_lcb->remote_bd_addr,(BT_HDR *)p_data);
-            else
-                GKI_freebuf (p_data);
-
+            if (p_ccb->local_cid < L2CAP_BASE_APPL_CID)
+            {
+                if (l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)
+                    (*l2cb.fixed_reg[p_ccb->local_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb)(p_ccb->p_lcb->remote_bd_addr,(BT_HDR *)p_data);
+                else
+                    GKI_freebuf (p_data);
             break;
+            }
         }
 #endif
         (*p_ccb->p_rcb->api.pL2CA_DataInd_Cb)(p_ccb->local_cid, (BT_HDR *)p_data);
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index a17c583..72d5544 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -435,11 +435,11 @@
     BOOLEAN             is_ble_link;
     tBLE_ADDR_TYPE      ble_addr_type;
 
-#define UPD_ENABLED     0  /* If peer requests update, we will change params */
-#define UPD_DISABLED    1  /* application requested not to update */
-#define UPD_PENDING     2  /* while updates are disabled, peer requested new parameters */
-#define UPD_UPDATED     3  /* peer updated connection parameters */
-    UINT8               upd_disabled;
+#define L2C_BLE_CONN_UPDATE_DISABLE 0x1  /* disable update connection parameters */
+#define L2C_BLE_NEW_CONN_PARAM      0x2  /* new connection parameter to be set */
+#define L2C_BLE_UPDATE_PENDING      0x4  /* waiting for connection update finished */
+#define L2C_BLE_NOT_DEFAULT_PARAM   0x8  /* not using default connection parameters */
+    UINT8               upd_status;
 
     UINT16              min_interval; /* parameters as requested by peripheral */
     UINT16              max_interval;
diff --git a/stack/rfcomm/rfc_mx_fsm.c b/stack/rfcomm/rfc_mx_fsm.c
index 842f8ee..d6bc506 100644
--- a/stack/rfcomm/rfc_mx_fsm.c
+++ b/stack/rfcomm/rfc_mx_fsm.c
@@ -614,7 +614,9 @@
         else
         {
             p_mcb->state = RFC_MX_STATE_WAIT_SABME;
-            rfc_timer_start (p_mcb, RFC_T2_TIMEOUT);
+            rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT); /* - increased from T2=20 to CONN=120
+                                                to allow the user more than 10 sec to type in the
+                                                pin which can be e.g. 16 digits */
         }
     }
 }
@@ -657,7 +659,9 @@
         else
         {
             p_mcb->state = RFC_MX_STATE_WAIT_SABME;
-            rfc_timer_start (p_mcb, RFC_T2_TIMEOUT);
+            rfc_timer_start (p_mcb, RFCOMM_CONN_TIMEOUT); /* - increased from T2=20 to CONN=120
+                                                to allow the user more than 10 sec to type in the
+                                                pin which can be e.g. 16 digits */
         }
     }
 }
diff --git a/stack/sdp/sdp_api.c b/stack/sdp/sdp_api.c
index cb632bd..7af690b 100644
--- a/stack/sdp/sdp_api.c
+++ b/stack/sdp/sdp_api.c
@@ -513,7 +513,7 @@
                         printf("SDP_FindServiceInDb - p_sattr value = 0x%x serviceuuid = 0x%x\r\n", p_sattr->attr_value.v.u16, service_uuid);
                         if(service_uuid == UUID_SERVCLASS_HDP_PROFILE)
                         {
-                            if( (p_sattr->attr_value.v.u16==UUID_SERVCLASS_HDP_SOURCE) || ( p_sattr->attr_value.v.u16==UUID_SERVCLASS_HDP_SOURCE))
+                            if( (p_sattr->attr_value.v.u16==UUID_SERVCLASS_HDP_SOURCE) || ( p_sattr->attr_value.v.u16==UUID_SERVCLASS_HDP_SINK))
                             {
                                 printf("SDP_FindServiceInDb found HDP source or sink\n" );
                                 return (p_rec);
@@ -989,6 +989,34 @@
 
 /*******************************************************************************
 **
+** Function         SDP_AttrStringCopy
+**
+** Description      This function copy given attribute to specified buffer as a string
+**
+** Returns          none
+**
+*******************************************************************************/
+static void SDP_AttrStringCopy(char *dst, tSDP_DISC_ATTR *p_attr, UINT16 dst_size)
+{
+    if ( dst == NULL ) return;
+    if ( p_attr )
+    {
+        UINT16 len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
+        if ( len > dst_size - 1 )
+        {
+            len = dst_size - 1;
+        }
+        memcpy(dst, (char *)p_attr->attr_value.v.array, len);
+        dst[len] = '\0';
+    }
+    else
+    {
+        dst[0] = '\0';
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         SDP_GetDiRecord
 **
 ** Description      This function retrieves a remote device's DI record from
@@ -1028,27 +1056,16 @@
 
         /* ClientExecutableURL is optional */
         p_curr_attr = SDP_FindAttributeInRec( p_curr_record, ATTR_ID_CLIENT_EXE_URL );
-        if ( p_curr_attr )
-            BCM_STRNCPY_S( p_device_info->rec.client_executable_url, sizeof(p_device_info->rec.client_executable_url),
-                           (char *)p_curr_attr->attr_value.v.array, SDP_MAX_ATTR_LEN );
-        else
-            p_device_info->rec.client_executable_url[0] = '\0';
+        SDP_AttrStringCopy( p_device_info->rec.client_executable_url, p_curr_attr,
+                            SDP_MAX_ATTR_LEN );
 
         /* Service Description is optional */
         p_curr_attr = SDP_FindAttributeInRec( p_curr_record, ATTR_ID_SERVICE_DESCRIPTION );
-        if ( p_curr_attr )
-            BCM_STRNCPY_S( p_device_info->rec.service_description, sizeof(p_device_info->rec.service_description),
-                           (char *)p_curr_attr->attr_value.v.array, SDP_MAX_ATTR_LEN );
-        else
-            p_device_info->rec.service_description[0] = '\0';
+        SDP_AttrStringCopy( p_device_info->rec.service_description, p_curr_attr, SDP_MAX_ATTR_LEN );
 
         /* DocumentationURL is optional */
         p_curr_attr = SDP_FindAttributeInRec( p_curr_record, ATTR_ID_DOCUMENTATION_URL );
-        if ( p_curr_attr )
-            BCM_STRNCPY_S( p_device_info->rec.documentation_url, sizeof(p_device_info->rec.documentation_url),
-                           (char *)p_curr_attr->attr_value.v.array, SDP_MAX_ATTR_LEN );
-        else
-            p_device_info->rec.documentation_url[0] = '\0';
+        SDP_AttrStringCopy( p_device_info->rec.documentation_url, p_curr_attr, SDP_MAX_ATTR_LEN );
 
         p_curr_attr = SDP_FindAttributeInRec( p_curr_record, ATTR_ID_SPECIFICATION_ID );
         if ( p_curr_attr )
diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c
index 032f3ed..babd300 100644
--- a/stack/smp/smp_act.c
+++ b/stack/smp/smp_act.c
@@ -905,10 +905,9 @@
 
     btu_stop_timer (&p_cb->rsp_timer_ent);
 
-    /* if remote user terminate connection, finish SMP pairing as normal */
-    if (p_data->reason == HCI_ERR_PEER_USER)
-        p_cb->status = SMP_SUCCESS;
-    else
+    /* if remote user terminate connection, keep the previous status */
+    /* this is to avoid reporting reverse status to uplayer */
+    if (p_data->reason != HCI_ERR_PEER_USER)
         p_cb->status = SMP_CONN_TOUT;
 
     smp_proc_pairing_cmpl(p_cb);
diff --git a/stack/smp/smp_api.c b/stack/smp/smp_api.c
index cfde2d4..b802376 100644
--- a/stack/smp/smp_api.c
+++ b/stack/smp/smp_api.c
@@ -204,6 +204,9 @@
         memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
         return;
 
+    /* clear the SMP_SEC_REQUEST_EVT event after get grant */
+    /* avoid generate duplicate pair request */
+    smp_cb.cb_evt = 0;
     smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res);
 }
 
diff --git a/stack/srvc/srvc_eng.c b/stack/srvc/srvc_eng.c
index a9b466e..d8db1b0 100644
--- a/stack/srvc/srvc_eng.c
+++ b/stack/srvc/srvc_eng.c
@@ -39,7 +39,8 @@
     srvc_eng_c_cmpl_cback,
     NULL,
     NULL,
-    srvc_eng_s_request_cback
+    srvc_eng_s_request_cback,
+    NULL
 } ;
 /* type for action functions */
 typedef void (*tSRVC_ENG_C_CMPL_ACTION)(tSRVC_CLCB *p_clcb, tGATTC_OPTYPE op,
diff --git a/udrv/ulinux/uipc.c b/udrv/ulinux/uipc.c
index 28706de..67ccd4f 100644
--- a/udrv/ulinux/uipc.c
+++ b/udrv/ulinux/uipc.c
@@ -194,6 +194,7 @@
     if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) < 0)
     {
         BTIF_TRACE_EVENT1("socket failed to create (%s)", strerror(errno));
+        close(s);
         return -1;
     }
 
@@ -429,7 +430,7 @@
         ret = poll(&pfd, 1, 1);
         BTIF_TRACE_EVENT3("uipc_flush_ch_locked polling : fd %d, rxev %x, ret %d", pfd.fd, pfd.revents, ret);
 
-        if (pfd.revents | (POLLERR|POLLHUP))
+        if (pfd.revents & (POLLERR|POLLHUP))
             return;
 
         if (ret <= 0)
@@ -799,7 +800,7 @@
         if (poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms) == 0)
         {
             BTIF_TRACE_EVENT1("poll timeout (%d ms)", uipc_main.ch[ch_id].read_poll_tmo_ms);
-            return 0;
+            break;
         }
 
         //BTIF_TRACE_EVENT1("poll revents %x", pfd.revents);