Merge branch 'dev/10/fp2/security-aosp-qt-release' into int/10/fp2

* dev/10/fp2/security-aosp-qt-release:
  Fix integer overflow when parsing avrc response
  Add length check when copy AVDT and AVCT packet
  Add missing increment in bnep_api.cc
  RESTRICT AUTOMERGE Added max buffer length check
  Add length check when copy AVDTP packet
  Add buffer in pin_reply in bluetooth.cc
  Add negative length check in process_service_search_rsp

Change-Id: Ifa3582358d1082182b8bf681285a04d5be63311c
diff --git a/TEST_MAPPING b/TEST_MAPPING
index d29c2f7..dc17051 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -78,6 +78,10 @@
       "host" : true
     },
     {
+      "name" : "net_test_btif_rc",
+      "host" : true
+    },
+    {
       "name" : "net_test_stack_a2dp_native",
       "host" : true
     }
diff --git a/binder/android/bluetooth/IBluetoothManager.aidl b/binder/android/bluetooth/IBluetoothManager.aidl
index 2e12700..8a80d49 100644
--- a/binder/android/bluetooth/IBluetoothManager.aidl
+++ b/binder/android/bluetooth/IBluetoothManager.aidl
@@ -46,6 +46,8 @@
     String getAddress();
     String getName();
 
+    boolean onFactoryReset();
+
     boolean isBleScanAlwaysAvailable();
     int updateBleAppCount(IBinder b, boolean enable, String packageName);
     boolean isBleAppPresent();
diff --git a/binder/android/bluetooth/IBluetoothPan.aidl b/binder/android/bluetooth/IBluetoothPan.aidl
index 16b6ddf..4052aa4 100644
--- a/binder/android/bluetooth/IBluetoothPan.aidl
+++ b/binder/android/bluetooth/IBluetoothPan.aidl
@@ -26,7 +26,7 @@
 interface IBluetoothPan {
     // Public API
     boolean isTetheringOn();
-    void setBluetoothTethering(boolean value);
+    void setBluetoothTethering(boolean value, String pkgName);
     boolean connect(in BluetoothDevice device);
     boolean disconnect(in BluetoothDevice device);
     List<BluetoothDevice> getConnectedDevices();
diff --git a/bta/av/bta_av_aact.cc b/bta/av/bta_av_aact.cc
index b022b43..7cd7056 100644
--- a/bta/av/bta_av_aact.cc
+++ b/bta/av/bta_av_aact.cc
@@ -1246,7 +1246,6 @@
     open.chnl = p_scb->chnl;
     open.hndl = p_scb->hndl;
     open.status = BTA_AV_SUCCESS;
-    open.starting = bta_av_chk_start(p_scb);
     open.edr = 0;
     p = BTM_ReadRemoteFeatures(p_scb->PeerAddress());
     if (p != NULL) {
@@ -1262,8 +1261,10 @@
     bta_ar_avdt_conn(BTA_ID_AV, open.bd_addr, p_scb->hdi);
 #endif
     if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC) {
+      open.starting = false;
       open.sep = AVDT_TSEP_SNK;
     } else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK) {
+      open.starting = bta_av_chk_start(p_scb);
       open.sep = AVDT_TSEP_SRC;
     }
 
diff --git a/bta/av/bta_av_main.cc b/bta/av/bta_av_main.cc
index 34516fc..bdd8a70 100644
--- a/bta/av/bta_av_main.cc
+++ b/bta/av/bta_av_main.cc
@@ -1108,8 +1108,10 @@
                   "%s: peer %s BTM_SwitchRole(BTM_ROLE_MASTER) error: %d",
                   __func__, p_scb->PeerAddress().ToString().c_str(), status);
       }
-      is_ok = false;
-      p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_START;
+      if (status != BTM_DEV_BLACKLISTED) {
+        is_ok = false;
+        p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_START;
+      }
     }
   }
 
diff --git a/bta/av/bta_av_ssm.cc b/bta/av/bta_av_ssm.cc
index a1a94b0..80effa3 100644
--- a/bta/av/bta_av_ssm.cc
+++ b/bta/av/bta_av_ssm.cc
@@ -329,7 +329,7 @@
     /* STR_RECONFIG_CFM_EVT */
     {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST},
     /* AVRC_TIMER_EVT */
-    {BTA_AV_OPEN_RC, BTA_AV_CHK_2ND_START, BTA_AV_OPEN_SST},
+    {BTA_AV_OPEN_RC, BTA_AV_SIGNORE, BTA_AV_OPEN_SST},
     /* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST},
     /* AVDT_DISCONNECT_EVT */
     {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST},
diff --git a/bta/hearing_aid/hearing_aid.cc b/bta/hearing_aid/hearing_aid.cc
index fb7cab7..867c628 100644
--- a/bta/hearing_aid/hearing_aid.cc
+++ b/bta/hearing_aid/hearing_aid.cc
@@ -390,6 +390,13 @@
       hearingDevice->connection_update_status = AWAITING;
     }
 
+    tACL_CONN* p_acl = btm_bda_to_acl(address, BT_TRANSPORT_LE);
+    if (p_acl != nullptr && controller_get_interface()->supports_ble_2m_phy() &&
+        HCI_LE_2M_PHY_SUPPORTED(p_acl->peer_le_features)) {
+      LOG(INFO) << address << " set preferred PHY to 2M";
+      BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
+    }
+
     // Set data length
     // TODO(jpawlowski: for 16khz only 87 is required, optimize
     BTM_SetBleDataLength(address, 167);
@@ -1005,13 +1012,16 @@
     }
   }
 
-  void OnAudioSuspend() {
+  void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) {
+    CHECK(stop_audio_ticks) << "stop_audio_ticks is empty";
+
     if (!audio_running) {
       LOG(WARNING) << __func__ << ": Unexpected audio suspend";
     } else {
       LOG(INFO) << __func__ << ": audio_running=" << audio_running;
     }
     audio_running = false;
+    stop_audio_ticks();
 
     std::vector<uint8_t> stop({CONTROL_POINT_OP_STOP});
     for (auto& device : hearingDevices.devices) {
@@ -1032,23 +1042,33 @@
     }
   }
 
-  void OnAudioResume() {
+  void OnAudioResume(const std::function<void()>& start_audio_ticks) {
+    CHECK(start_audio_ticks) << "start_audio_ticks is empty";
+
     if (audio_running) {
       LOG(ERROR) << __func__ << ": Unexpected Audio Resume";
     } else {
       LOG(INFO) << __func__ << ": audio_running=" << audio_running;
     }
-    audio_running = true;
+
+    for (auto& device : hearingDevices.devices) {
+      if (!device.accepting_audio) continue;
+      audio_running = true;
+      SendStart(&device);
+    }
+
+    if (!audio_running) {
+      LOG(INFO) << __func__ << ": No device (0/" << GetDeviceCount()
+                << ") ready to start";
+      return;
+    }
 
     // TODO: shall we also reset the encoder ?
     encoder_state_release();
     encoder_state_init();
     seq_counter = 0;
 
-    for (auto& device : hearingDevices.devices) {
-      if (!device.accepting_audio) continue;
-      SendStart(&device);
-    }
+    start_audio_ticks();
   }
 
   uint8_t GetOtherSideStreamStatus(HearingDevice* this_side_device) {
@@ -1140,10 +1160,9 @@
     }
 
     if (left == nullptr && right == nullptr) {
-      HearingAidAudioSource::Stop();
-      audio_running = false;
-      encoder_state_release();
-      current_volume = VOLUME_UNKNOWN;
+      LOG(WARNING) << __func__ << ": No more (0/" << GetDeviceCount()
+                   << ") devices ready";
+      DoDisconnectAudioStop();
       return;
     }
 
@@ -1456,8 +1475,17 @@
 
     hearingDevices.Remove(address);
 
-    if (connected)
-      callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
+    if (!connected) {
+      return;
+    }
+
+    callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
+    for (const auto& device : hearingDevices.devices) {
+      if (device.accepting_audio) return;
+    }
+    LOG(INFO) << __func__ << ": No more (0/" << GetDeviceCount()
+              << ") devices ready";
+    DoDisconnectAudioStop();
   }
 
   void OnGattDisconnected(tGATT_STATUS status, uint16_t conn_id,
@@ -1479,7 +1507,16 @@
 
     DoDisconnectCleanUp(hearingDevice);
 
+    // Keep this hearing aid in the list, and allow to reconnect back.
+
     callbacks->OnConnectionState(ConnectionState::DISCONNECTED, remote_bda);
+
+    for (const auto& device : hearingDevices.devices) {
+      if (device.accepting_audio) return;
+    }
+    LOG(INFO) << __func__ << ": No more (0/" << GetDeviceCount()
+              << ") devices ready";
+    DoDisconnectAudioStop();
   }
 
   void DoDisconnectCleanUp(HearingDevice* hearingDevice) {
@@ -1512,6 +1549,13 @@
     hearingDevice->command_acked = false;
   }
 
+  void DoDisconnectAudioStop() {
+    HearingAidAudioSource::Stop();
+    audio_running = false;
+    encoder_state_release();
+    current_volume = VOLUME_UNKNOWN;
+  }
+
   void SetVolume(int8_t volume) override {
     VLOG(2) << __func__ << ": " << +volume;
     current_volume = volume;
@@ -1723,14 +1767,11 @@
   void OnAudioDataReady(const std::vector<uint8_t>& data) override {
     if (instance) instance->OnAudioDataReady(data);
   }
-  void OnAudioSuspend(std::promise<void> do_suspend_promise) override {
-    if (instance) instance->OnAudioSuspend();
-    do_suspend_promise.set_value();
+  void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) override {
+    if (instance) instance->OnAudioSuspend(stop_audio_ticks);
   }
-
-  void OnAudioResume(std::promise<void> do_resume_promise) override {
-    if (instance) instance->OnAudioResume();
-    do_resume_promise.set_value();
+  void OnAudioResume(const std::function<void()>& start_audio_ticks) override {
+    if (instance) instance->OnAudioResume(start_audio_ticks);
   }
 };
 
diff --git a/bta/hearing_aid/hearing_aid_audio_source.cc b/bta/hearing_aid/hearing_aid_audio_source.cc
index 3b92d41..0896e2b 100644
--- a/bta/hearing_aid/hearing_aid_audio_source.cc
+++ b/bta/hearing_aid/hearing_aid_audio_source.cc
@@ -97,12 +97,20 @@
 }
 
 void start_audio_ticks() {
+  if (data_interval_ms != HA_INTERVAL_10_MS &&
+      data_interval_ms != HA_INTERVAL_20_MS) {
+    LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
+  }
+
   wakelock_acquire();
-  audio_timer.SchedulePeriodic(get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data),
-                               base::TimeDelta::FromMilliseconds(data_interval_ms));
+  audio_timer.SchedulePeriodic(
+      get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data),
+      base::TimeDelta::FromMilliseconds(data_interval_ms));
+  LOG(INFO) << __func__ << ": running with data interval: " << data_interval_ms;
 }
 
 void stop_audio_ticks() {
+  LOG(INFO) << __func__ << ": stopped";
   audio_timer.CancelAndWait();
   wakelock_release();
 }
@@ -121,17 +129,12 @@
       UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
                  reinterpret_cast<void*>(0));
 
-      if (data_interval_ms != HA_INTERVAL_10_MS &&
-          data_interval_ms != HA_INTERVAL_20_MS) {
-        LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
-      }
-
-      start_audio_ticks();
+      do_in_main_thread(FROM_HERE, base::BindOnce(start_audio_ticks));
       break;
     case UIPC_CLOSE_EVT:
       LOG(INFO) << __func__ << ": UIPC_CLOSE_EVT";
       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
-      stop_audio_ticks();
+      do_in_main_thread(FROM_HERE, base::BindOnce(stop_audio_ticks));
       break;
     default:
       LOG(ERROR) << "Hearing Aid audio data event not recognized:" << event;
@@ -306,65 +309,52 @@
 }
 
 bool hearing_aid_on_resume_req(bool start_media_task) {
-  // hearing_aid_recv_ctrl_data(HEARING_AID_CTRL_CMD_START)
-  if (localAudioReceiver != nullptr) {
-    // Call OnAudioResume and block till it returns.
-    std::promise<void> do_resume_promise;
-    std::future<void> do_resume_future = do_resume_promise.get_future();
-    bt_status_t status = do_in_main_thread(
-        FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
-                                  base::Unretained(localAudioReceiver),
-                                  std::move(do_resume_promise)));
-    if (status == BT_STATUS_SUCCESS) {
-      do_resume_future.wait();
-    } else {
-      LOG(ERROR) << __func__
-                 << ": HEARING_AID_CTRL_CMD_START: do_in_main_thread err="
-                 << status;
-      return false;
-    }
-  } else {
+  if (localAudioReceiver == nullptr) {
     LOG(ERROR) << __func__
                << ": HEARING_AID_CTRL_CMD_START: audio receiver not started";
     return false;
   }
-
-  // hearing_aid_data_cb(UIPC_OPEN_EVT): start_media_task
+  bt_status_t status;
   if (start_media_task) {
-    if (data_interval_ms != HA_INTERVAL_10_MS &&
-        data_interval_ms != HA_INTERVAL_20_MS) {
-      LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
-      data_interval_ms = HA_INTERVAL_10_MS;
-    }
-    start_audio_ticks();
+    status = do_in_main_thread(
+        FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
+                                  base::Unretained(localAudioReceiver),
+                                  start_audio_ticks));
+  } else {
+    auto start_dummy_ticks = []() {
+      LOG(INFO) << "start_audio_ticks: waiting for data path opened";
+    };
+    status = do_in_main_thread(
+        FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
+                                  base::Unretained(localAudioReceiver),
+                                  start_dummy_ticks));
+  }
+  if (status != BT_STATUS_SUCCESS) {
+    LOG(ERROR) << __func__
+               << ": HEARING_AID_CTRL_CMD_START: do_in_main_thread err="
+               << status;
+    return false;
   }
   return true;
 }
 
 bool hearing_aid_on_suspend_req() {
-  // hearing_aid_recv_ctrl_data(HEARING_AID_CTRL_CMD_SUSPEND): stop_media_task
-  stop_audio_ticks();
-  if (localAudioReceiver != nullptr) {
-    // Call OnAudioSuspend and block till it returns.
-    std::promise<void> do_suspend_promise;
-    std::future<void> do_suspend_future = do_suspend_promise.get_future();
-    bt_status_t status = do_in_main_thread(
-        FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend,
-                                  base::Unretained(localAudioReceiver),
-                                  std::move(do_suspend_promise)));
-    if (status == BT_STATUS_SUCCESS) {
-      do_suspend_future.wait();
-      return true;
-    } else {
-      LOG(ERROR) << __func__
-                 << ": HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err="
-                 << status;
-    }
-  } else {
+  if (localAudioReceiver == nullptr) {
     LOG(ERROR) << __func__
                << ": HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started";
+    return false;
   }
-  return false;
+  bt_status_t status = do_in_main_thread(
+      FROM_HERE,
+      base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend,
+                     base::Unretained(localAudioReceiver), stop_audio_ticks));
+  if (status != BT_STATUS_SUCCESS) {
+    LOG(ERROR) << __func__
+               << ": HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err="
+               << status;
+    return false;
+  }
+  return true;
 }
 }  // namespace
 
diff --git a/bta/hf_client/bta_hf_client_rfc.cc b/bta/hf_client/bta_hf_client_rfc.cc
index f3e0947..535371f 100644
--- a/bta/hf_client/bta_hf_client_rfc.cc
+++ b/bta/hf_client/bta_hf_client_rfc.cc
@@ -127,6 +127,7 @@
     } else {
       APPL_TRACE_ERROR("%s: PORT_SUCCESS, ignoring handle = %d", __func__,
                        port_handle);
+      osi_free(p_buf);
       return;
     }
   } else if (client_cb != NULL &&
@@ -136,6 +137,10 @@
 
     RFCOMM_RemoveServer(port_handle);
     p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
+  } else if (client_cb == NULL) {
+    // client_cb is already cleaned due to hfp client disabled.
+    // Assigned a valid event value to header and send this message anyway.
+    p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
   }
 
   p_buf->hdr.layer_specific = client_cb != NULL ? client_cb->handle : 0;
diff --git a/bta/include/bta_hearing_aid_api.h b/bta/include/bta_hearing_aid_api.h
index 9026262..6c4954b 100644
--- a/bta/include/bta_hearing_aid_api.h
+++ b/bta/include/bta_hearing_aid_api.h
@@ -21,7 +21,6 @@
 #include <base/callback_forward.h>
 #include <hardware/bt_hearing_aid.h>
 #include <deque>
-#include <future>
 #include <vector>
 
 constexpr uint16_t HEARINGAID_MAX_NUM_UUIDS = 1;
@@ -39,8 +38,22 @@
  public:
   virtual ~HearingAidAudioReceiver() = default;
   virtual void OnAudioDataReady(const std::vector<uint8_t>& data) = 0;
-  virtual void OnAudioSuspend(std::promise<void> do_suspend_promise) = 0;
-  virtual void OnAudioResume(std::promise<void> do_resume_promise) = 0;
+
+  // API to stop our feeding timer, and notify hearing aid devices that the
+  // streaming would stop, too.
+  //
+  // @param stop_audio_ticks a callable function calls out to stop the media
+  // timer for reading data.
+  virtual void OnAudioSuspend(
+      const std::function<void()>& stop_audio_ticks) = 0;
+
+  // To notify hearing aid devices to be ready for streaming, and start the
+  // media timer to feed the audio data.
+  //
+  // @param start_audio_ticks a callable function calls out to start a periodic
+  // timer for feeding data from the audio HAL.
+  virtual void OnAudioResume(
+      const std::function<void()>& start_audio_ticks) = 0;
 };
 
 // Number of rssi reads to attempt when requested
diff --git a/bta/jv/bta_jv_act.cc b/bta/jv/bta_jv_act.cc
index 462ee9d..2ede5c9 100644
--- a/bta/jv/bta_jv_act.cc
+++ b/bta/jv/bta_jv_act.cc
@@ -362,6 +362,8 @@
   p_cb->cong = false;
   bta_jv_free_sec_id(&p_cb->sec_id);
   p_cb->p_cback = NULL;
+  p_cb->handle = 0;
+  p_cb->l2cap_socket_id = 0;
   return status;
 }
 
@@ -1121,7 +1123,7 @@
 /* stops an L2CAP server */
 void bta_jv_l2cap_stop_server(uint16_t local_psm, uint32_t l2cap_socket_id) {
   for (int i = 0; i < BTA_JV_MAX_L2C_CONN; i++) {
-    if (bta_jv_cb.l2c_cb[i].psm == local_psm) {
+    if (bta_jv_cb.l2c_cb[i].l2cap_socket_id == l2cap_socket_id) {
       tBTA_JV_L2C_CB* p_cb = &bta_jv_cb.l2c_cb[i];
       tBTA_JV_L2CAP_CBACK* p_cback = p_cb->p_cback;
       tBTA_JV_L2CAP_CLOSE evt_data;
diff --git a/btif/Android.bp b/btif/Android.bp
index f33d174..0ecf207 100644
--- a/btif/Android.bp
+++ b/btif/Android.bp
@@ -208,3 +208,36 @@
     ],
     cflags: ["-DBUILDCFG"],
 }
+
+// btif rc unit tests for target
+// ========================================================
+cc_test {
+    name: "net_test_btif_rc",
+    defaults: ["fluoride_defaults"],
+    test_suites: ["device-tests"],
+    host_supported: true,
+    include_dirs: btifCommonIncludes,
+    srcs: [
+        "test/btif_rc_test.cc",
+    ],
+    header_libs: ["libbluetooth_headers"],
+    shared_libs: [
+        "libcrypto",
+        "libcutils",
+        "liblog",
+        "libprotobuf-cpp-lite",
+    ],
+    static_libs: [
+        "libbluetooth-types",
+        "libbt-common",
+        "libbt-protos-lite",
+        "libosi",
+        "libosi-AllocationTestHarness",
+    ],
+    cflags: ["-DBUILDCFG"],
+    sanitize: {
+        address: true,
+        cfi: true,
+        misc_undefined: ["bounds"],
+    },
+}
diff --git a/btif/include/btif_api.h b/btif/include/btif_api.h
index 71acd28..50d833f 100644
--- a/btif/include/btif_api.h
+++ b/btif/include/btif_api.h
@@ -105,7 +105,7 @@
 
 /*******************************************************************************
  *
- * Function         is_single_user_mode_
+ * Function         is_niap_mode
  *
  * Description      Checks if BT was enabled in single user mode. In this
  *                  mode, use of keystore for key attestation of LTK is limitee
@@ -114,7 +114,7 @@
  * Returns          bool
  *
  ******************************************************************************/
-bool is_single_user_mode(void);
+bool is_niap_mode(void);
 
 /*******************************************************************************
  *
diff --git a/btif/include/btif_bqr.h b/btif/include/btif_bqr.h
index 4407b0d..ecf69f1 100644
--- a/btif/include/btif_bqr.h
+++ b/btif/include/btif_bqr.h
@@ -67,6 +67,11 @@
 static constexpr uint8_t kCriWarnUnusedCh = 55;
 // The queue size of recording the BQR events.
 static constexpr uint8_t kBqrEventQueueSize = 25;
+// The minimum size of the ROOT_INFLAMMATION event
+// HCI_VENDOR_SPECIFIC_EVT(1) + BQR sub event(1) + BQR report ID(1) +
+// error code(1) + vendor error code(1) = 5
+static constexpr uint8_t kRootInflammationPacketMinSize = 5;
+
 // The Property of BQR event mask configuration.
 static constexpr const char* kpPropertyEventMask =
     "persist.bluetooth.bqr.event_mask";
@@ -90,7 +95,8 @@
   QUALITY_REPORT_ID_MONITOR_MODE = 0x01,
   QUALITY_REPORT_ID_APPROACH_LSTO = 0x02,
   QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY = 0x03,
-  QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04
+  QUALITY_REPORT_ID_SCO_VOICE_CHOPPY = 0x04,
+  QUALITY_REPORT_ID_ROOT_INFLAMMATION = 0x05
 };
 
 // Packet Type definition
diff --git a/btif/include/btif_keystore.h b/btif/include/btif_keystore.h
index cc06a98..1b3663d 100644
--- a/btif/include/btif_keystore.h
+++ b/btif/include/btif_keystore.h
@@ -70,9 +70,7 @@
  private:
   std::unique_ptr<keystore::KeystoreClient> keystore_client_;
   std::mutex api_mutex_;
-  keystore::KeyStoreNativeReturnCode GenerateKey(const std::string& name,
-                                                 int32_t flags,
-                                                 bool auth_bound);
+  bool GenerateKey(const std::string& name, int32_t flags);
 };
 
 }  // namespace bluetooth
diff --git a/btif/src/bluetooth.cc b/btif/src/bluetooth.cc
index 9c71422..b1d0c9a 100644
--- a/btif/src/bluetooth.cc
+++ b/btif/src/bluetooth.cc
@@ -81,7 +81,7 @@
 
 bt_callbacks_t* bt_hal_cbacks = NULL;
 bool restricted_mode = false;
-bool single_user_mode = false;
+bool niap_mode = false;
 bool is_local_device_atv = false;
 
 /*******************************************************************************
@@ -135,9 +135,9 @@
  ****************************************************************************/
 
 static int init(bt_callbacks_t* callbacks, bool start_restricted,
-                bool is_single_user_mode, bool is_atv) {
-  LOG_INFO(LOG_TAG, "%s: start restricted = %d ; single user = %d", __func__,
-           start_restricted, is_single_user_mode);
+                bool is_niap_mode, bool is_atv) {
+  LOG_INFO(LOG_TAG, "%s: start restricted = %d ; niap = %d", __func__,
+           start_restricted, is_niap_mode);
 
   if (interface_ready()) return BT_STATUS_DONE;
 
@@ -147,7 +147,7 @@
 
   bt_hal_cbacks = callbacks;
   restricted_mode = start_restricted;
-  single_user_mode = is_single_user_mode;
+  niap_mode = is_niap_mode;
   is_local_device_atv = is_atv;
   stack_manager_get_interface()->init_stack();
   btif_debug_init();
@@ -171,7 +171,7 @@
 static void cleanup(void) { stack_manager_get_interface()->clean_up_stack(); }
 
 bool is_restricted_mode() { return restricted_mode; }
-bool is_single_user_mode() { return single_user_mode; }
+bool is_niap_mode() { return niap_mode; }
 
 bool is_atv_device() { return is_local_device_atv; }
 
diff --git a/btif/src/btif_a2dp_sink.cc b/btif/src/btif_a2dp_sink.cc
index bb1bc49..aa75d21 100644
--- a/btif/src/btif_a2dp_sink.cc
+++ b/btif/src/btif_a2dp_sink.cc
@@ -667,7 +667,6 @@
   LOG_INFO(LOG_TAG, "%s: state=%d", __func__, state);
   LockGuard lock(g_mutex);
 
-  if (!btif_av_is_connected()) return;
   APPL_TRACE_DEBUG("%s: setting focus state to %d", __func__, state);
   btif_a2dp_sink_cb.rx_focus_state = state;
   if (btif_a2dp_sink_cb.rx_focus_state == BTIF_A2DP_SINK_FOCUS_NOT_GRANTED) {
diff --git a/btif/src/btif_config.cc b/btif/src/btif_config.cc
index ed24d7d..277671c 100644
--- a/btif/src/btif_config.cc
+++ b/btif/src/btif_config.cc
@@ -20,6 +20,7 @@
 
 #include "btif_config.h"
 
+#include <base/base64.h>
 #include <base/logging.h>
 #include <ctype.h>
 #include <openssl/rand.h>
@@ -60,8 +61,8 @@
 
 constexpr int kBufferSize = 400 * 10;  // initial file is ~400B
 
-static bool use_key_attestation() {
-  return getuid() == AID_BLUETOOTH && is_single_user_mode();
+static bool btif_is_niap_mode() {
+  return getuid() == AID_BLUETOOTH && is_niap_mode();
 }
 
 #define BT_CONFIG_METRICS_SECTION "Metrics"
@@ -93,10 +94,22 @@
 static std::unique_ptr<config_t> btif_config_open(const char* filename, const char* checksum_filename);
 
 // Key attestation
+static std::string btif_convert_to_encrypt_key(
+    const std::string& unencrypt_str);
+static std::string btif_convert_to_unencrypt_key(
+    const std::string& encrypt_str);
+static bool btif_in_encrypt_key_name_list(std::string key);
+static bool btif_is_key_encrypted(int key_from_config_size,
+                                  std::string key_type_string);
 static std::string hash_file(const char* filename);
 static std::string read_checksum_file(const char* filename);
 static void write_checksum_file(const char* filename, const std::string& hash);
 
+static const int ENCRYPT_KEY_NAME_LIST_SIZE = 7;
+static const std::string encrypt_key_name_list[] = {
+    "LinkKey",      "LE_KEY_PENC", "LE_KEY_PID",  "LE_KEY_LID",
+    "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK"};
+
 static enum ConfigSource {
   NOT_LOADED,
   ORIGINAL,
@@ -183,9 +196,7 @@
 static future_t* init(void) {
   std::unique_lock<std::recursive_mutex> lock(config_lock);
 
-  if (is_factory_reset() ||
-      (use_key_attestation() && !btif_keystore.DoesKeyExist()))
-    delete_config_files();
+  if (is_factory_reset()) delete_config_files();
 
   std::string file_source;
 
@@ -271,7 +282,8 @@
   std::string stored_hash = read_checksum_file(checksum_filename);
   if (stored_hash.empty()) {
     LOG(ERROR) << __func__ << ": stored_hash=<empty>";
-    if (!current_hash.empty()) {
+    // Will encrypt once since the bt_config never encrypt.
+    if (!btif_keystore.DoesKeyExist() && !current_hash.empty()) {
       write_checksum_file(checksum_filename, current_hash);
       stored_hash = read_checksum_file(checksum_filename);
     }
@@ -408,14 +420,29 @@
   CHECK(length != NULL);
 
   std::unique_lock<std::recursive_mutex> lock(config_lock);
-  const std::string* value_str = config_get_string(*config, section, key, NULL);
+  const std::string* value_str;
+  const std::string* value_str_from_config =
+      config_get_string(*config, section, key, NULL);
 
-  if (!value_str) {
+  if (!value_str_from_config) {
     VLOG(1) << __func__ << ": cannot find string for section " << section
             << ", key " << key;
     return false;
   }
 
+  bool in_encrypt_key_name_list = btif_in_encrypt_key_name_list(key);
+  bool is_key_encrypted =
+      btif_is_key_encrypted(value_str_from_config->size(), key);
+
+  if (in_encrypt_key_name_list && is_key_encrypted) {
+    VLOG(2) << __func__ << " decrypt section: " << section << " key:" << key;
+    std::string tmp_value_str =
+        btif_convert_to_unencrypt_key(*value_str_from_config);
+    value_str = &tmp_value_str;
+  } else {
+    value_str = value_str_from_config;
+  }
+
   size_t value_len = value_str->length();
   if ((value_len % 2) != 0 || *length < (value_len / 2)) {
     LOG(WARNING) << ": value size not divisible by 2, size is " << value_len;
@@ -429,12 +456,72 @@
     }
 
   const char* ptr = value_str->c_str();
-  for (*length = 0; *ptr; ptr += 2, *length += 1)
+  for (*length = 0; *ptr; ptr += 2, *length += 1) {
     sscanf(ptr, "%02hhx", &value[*length]);
+  }
+
+  if (btif_is_niap_mode()) {
+    if (in_encrypt_key_name_list && !is_key_encrypted) {
+      VLOG(2) << __func__ << " encrypt section: " << section << " key:" << key;
+      std::string encrypt_str =
+          btif_convert_to_encrypt_key(*value_str_from_config);
+      config_set_string(config.get(), section, key, encrypt_str);
+    }
+  } else {
+    if (in_encrypt_key_name_list && is_key_encrypted) {
+      config_set_string(config.get(), section, key, value_str->c_str());
+    }
+  }
 
   return true;
 }
 
+static bool btif_in_encrypt_key_name_list(std::string key) {
+  return std::find(encrypt_key_name_list,
+                   encrypt_key_name_list + ENCRYPT_KEY_NAME_LIST_SIZE,
+                   key) != (encrypt_key_name_list + ENCRYPT_KEY_NAME_LIST_SIZE);
+}
+
+static bool btif_is_key_encrypted(int key_from_config_size,
+                                  std::string key_type_string) {
+  if (key_type_string.compare("LinkKey") == 0) {
+    return sizeof(LinkKey) * 2 != key_from_config_size;
+  } else if (key_type_string.compare("LE_KEY_PENC") == 0) {
+    return sizeof(tBTM_LE_PENC_KEYS) * 2 != key_from_config_size;
+  } else if (key_type_string.compare("LE_KEY_PID") == 0) {
+    return sizeof(tBTM_LE_PID_KEYS) * 2 != key_from_config_size;
+  } else if (key_type_string.compare("LE_KEY_LID") == 0) {
+    return sizeof(tBTM_LE_PID_KEYS) * 2 != key_from_config_size;
+  } else if (key_type_string.compare("LE_KEY_PCSRK") == 0) {
+    return sizeof(tBTM_LE_PCSRK_KEYS) * 2 != key_from_config_size;
+  } else if (key_type_string.compare("LE_KEY_LENC") == 0) {
+    return sizeof(tBTM_LE_LENC_KEYS) * 2 != key_from_config_size;
+  } else if (key_type_string.compare("LE_KEY_LCSRK") == 0) {
+    return sizeof(tBTM_LE_LCSRK_KEYS) * 2 != key_from_config_size;
+  } else {
+    VLOG(2) << __func__ << ": " << key_type_string
+            << " Key type is unknown, return false first";
+    return false;
+  }
+}
+
+static std::string btif_convert_to_unencrypt_key(
+    const std::string& encrypt_str) {
+  if (!encrypt_str.empty()) {
+    std::string tmp_encrypt_str("");
+    if (base::Base64Decode(encrypt_str, &tmp_encrypt_str)) {
+      std::string unencrypt_str = btif_keystore.Decrypt(tmp_encrypt_str);
+      if (!unencrypt_str.empty()) {
+        return unencrypt_str;
+      }
+    } else {
+      LOG(WARNING) << __func__
+                   << ": base64string decode fail, will return empty string";
+    }
+  }
+  return "";
+}
+
 size_t btif_config_get_bin_length(const std::string& section,
                                   const std::string& key) {
   CHECK(config != NULL);
@@ -468,15 +555,37 @@
     str[(i * 2) + 1] = lookup[value[i] & 0x0F];
   }
 
+  std::string value_str;
+  if (btif_is_niap_mode() && btif_in_encrypt_key_name_list(key)) {
+    VLOG(2) << __func__ << " encrypt section: " << section << " key:" << key;
+    value_str = btif_convert_to_encrypt_key(str);
+  } else {
+    value_str = str;
+  }
+
   {
     std::unique_lock<std::recursive_mutex> lock(config_lock);
-    config_set_string(config.get(), section, key, str);
+    config_set_string(config.get(), section, key, value_str);
   }
 
   osi_free(str);
   return true;
 }
 
+static std::string btif_convert_to_encrypt_key(
+    const std::string& unencrypt_str) {
+  if (!unencrypt_str.empty()) {
+    std::string encrypt_str = btif_keystore.Encrypt(unencrypt_str, 0);
+    if (!encrypt_str.empty()) {
+      base::Base64Encode(encrypt_str, &encrypt_str);
+      return encrypt_str;
+    } else {
+      LOG(ERROR) << __func__ << ": Encrypt fail, will return empty str.";
+    }
+  }
+  return "";
+}
+
 std::list<section_t>& btif_config_sections() { return config->sections; }
 
 bool btif_config_remove(const std::string& section, const std::string& key) {
@@ -643,7 +752,7 @@
 }
 
 static std::string hash_file(const char* filename) {
-  if (!use_key_attestation()) {
+  if (!btif_is_niap_mode()) {
     LOG(INFO) << __func__ << ": Disabled for multi-user";
     return DISABLED;
   }
@@ -671,7 +780,7 @@
 }
 
 static std::string read_checksum_file(const char* checksum_filename) {
-  if (!use_key_attestation()) {
+  if (!btif_is_niap_mode()) {
     LOG(INFO) << __func__ << ": Disabled for multi-user";
     return DISABLED;
   }
@@ -685,7 +794,7 @@
 
 static void write_checksum_file(const char* checksum_filename,
                                 const std::string& hash) {
-  if (!use_key_attestation()) {
+  if (!btif_is_niap_mode()) {
     LOG(INFO) << __func__
               << ": Disabled for multi-user, since config changed removing "
                  "checksums.";
diff --git a/btif/src/btif_keystore.cc b/btif/src/btif_keystore.cc
index 0af03e1..1bf2c0f 100644
--- a/btif/src/btif_keystore.cc
+++ b/btif/src/btif_keystore.cc
@@ -17,6 +17,8 @@
  ******************************************************************************/
 
 #include "btif_keystore.h"
+#include "keystore_client.pb.h"
+#include "string.h"
 
 #include <base/files/file_util.h>
 #include <base/logging.h>
@@ -29,7 +31,9 @@
 using namespace keystore;
 using namespace bluetooth;
 
-constexpr char kKeyStore[] = "AndroidKeystore";
+const std::string kKeyStore = "bluetooth-key-encrypted";
+constexpr uint32_t kAESKeySize = 256;     // bits
+constexpr uint32_t kMACOutputSize = 128;  // bits
 
 namespace bluetooth {
 
@@ -43,19 +47,45 @@
     LOG(ERROR) << __func__ << ": empty data";
     return output;
   }
-  if (!keystore_client_->doesKeyExist(kKeyStore)) {
-    auto gen_result = GenerateKey(kKeyStore, 0, false);
-    if (!gen_result.isOk()) {
-      LOG(FATAL) << "EncryptWithAuthentication Failed: generateKey response="
-                 << gen_result;
-      return output;
-    }
-  }
-  if (!keystore_client_->encryptWithAuthentication(kKeyStore, data, flags,
-                                                   &output)) {
-    LOG(FATAL) << "EncryptWithAuthentication failed.";
+  if (!GenerateKey(kKeyStore, flags)) {
     return output;
   }
+
+  AuthorizationSetBuilder encrypt_params;
+  encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+      .Authorization(TAG_MAC_LENGTH, kMACOutputSize)
+      .Padding(PaddingMode::NONE);
+  AuthorizationSet output_params;
+  std::string raw_encrypted_data;
+  if (!keystore_client_->oneShotOperation(
+          KeyPurpose::ENCRYPT, kKeyStore, encrypt_params, data,
+          std::string() /* signature_to_verify */, &output_params,
+          &raw_encrypted_data)) {
+    LOG(ERROR) << __func__ << ": AES operation failed.";
+    return output;
+  }
+  auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
+  if (!init_vector_blob.isOk()) {
+    LOG(ERROR) << __func__ << ": Missing initialization vector.";
+    return output;
+  }
+
+  const hidl_vec<uint8_t>& value = init_vector_blob.value();
+  std::string init_vector =
+      std::string(reinterpret_cast<const std::string::value_type*>(&value[0]),
+                  value.size());
+
+  if (memcmp(&init_vector_blob, &init_vector, init_vector.length()) == 0) {
+    LOG(ERROR) << __func__
+               << ": Protobuf nonce data doesn't match the actual nonce.";
+  }
+
+  EncryptedData protobuf;
+  protobuf.set_init_vector(init_vector);
+  protobuf.set_encrypted_data(raw_encrypted_data);
+  if (!protobuf.SerializeToString(&output)) {
+    LOG(ERROR) << __func__ << ": Failed to serialize EncryptedData protobuf.";
+  }
   return output;
 }
 
@@ -66,36 +96,49 @@
     return "";
   }
   std::string output;
-  if (!keystore_client_->decryptWithAuthentication(kKeyStore, input, &output)) {
-    LOG(FATAL) << "DecryptWithAuthentication failed.\n";
+  EncryptedData protobuf;
+  if (!protobuf.ParseFromString(input)) {
+    LOG(ERROR) << __func__ << ": Failed to parse EncryptedData protobuf.";
+    return output;
+  }
+  AuthorizationSetBuilder encrypt_params;
+  encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+      .Authorization(TAG_MAC_LENGTH, kMACOutputSize)
+      .Authorization(TAG_NONCE, protobuf.init_vector().data(),
+                     protobuf.init_vector().size())
+      .Padding(PaddingMode::NONE);
+  AuthorizationSet output_params;
+  if (!keystore_client_->oneShotOperation(
+          KeyPurpose::DECRYPT, kKeyStore, encrypt_params,
+          protobuf.encrypted_data(), std::string() /* signature_to_verify */,
+          &output_params, &output)) {
+    LOG(ERROR) << __func__ << ": AES operation failed.";
   }
   return output;
 }
 
-// Note: auth_bound keys created with this tool will not be usable.
-KeyStoreNativeReturnCode BtifKeystore::GenerateKey(const std::string& name,
-                                                   int32_t flags,
-                                                   bool auth_bound) {
-  AuthorizationSetBuilder params;
-  params.RsaSigningKey(2048, 65537)
-      .Digest(Digest::SHA_2_224)
-      .Digest(Digest::SHA_2_256)
-      .Digest(Digest::SHA_2_384)
-      .Digest(Digest::SHA_2_512)
-      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
-      .Padding(PaddingMode::RSA_PSS);
-  if (auth_bound) {
-    // Gatekeeper normally generates the secure user id.
-    // Using zero allows the key to be created, but it will not be usuable.
-    params.Authorization(TAG_USER_SECURE_ID, 0);
-  } else {
-    params.Authorization(TAG_NO_AUTH_REQUIRED);
+bool BtifKeystore::GenerateKey(const std::string& name, int32_t flags) {
+  if (!DoesKeyExist()) {
+    AuthorizationSetBuilder params;
+    params.AesEncryptionKey(kAESKeySize)
+        .Authorization(TAG_NO_AUTH_REQUIRED)
+        .Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+        .Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT)
+        .Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT)
+        .Padding(PaddingMode::NONE)
+        .Authorization(TAG_MIN_MAC_LENGTH, kMACOutputSize);
+    AuthorizationSet hardware_enforced_characteristics;
+    AuthorizationSet software_enforced_characteristics;
+    auto result = keystore_client_->generateKey(
+        name, params, flags, &hardware_enforced_characteristics,
+        &software_enforced_characteristics);
+    if (!result.isOk()) {
+      LOG(FATAL) << __func__ << "Failed to generate key: name: " << name
+                 << ", error code: " << result.getErrorCode();
+      return false;
+    }
   }
-  AuthorizationSet hardware_enforced_characteristics;
-  AuthorizationSet software_enforced_characteristics;
-  return keystore_client_->generateKey(name, params, flags,
-                                       &hardware_enforced_characteristics,
-                                       &software_enforced_characteristics);
+  return true;
 }
 
 bool BtifKeystore::DoesKeyExist() {
diff --git a/btif/src/btif_profile_queue.cc b/btif/src/btif_profile_queue.cc
index 41275f1..900a6af 100644
--- a/btif/src/btif_profile_queue.cc
+++ b/btif/src/btif_profile_queue.cc
@@ -195,7 +195,14 @@
 
   LOG_INFO(LOG_TAG, "%s: executing connection request: %s", __func__,
            head.ToString().c_str());
-  return head.connect();
+  bt_status_t b_status = head.connect();
+  if (b_status != BT_STATUS_SUCCESS) {
+    LOG_INFO(LOG_TAG,
+             "%s: connect %s failed, advance to next scheduled connection.",
+             __func__, head.ToString().c_str());
+    btif_queue_advance();
+  }
+  return b_status;
 }
 
 /*******************************************************************************
diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc
index 9919a7b..575d83e 100644
--- a/btif/src/btif_rc.cc
+++ b/btif/src/btif_rc.cc
@@ -1836,6 +1836,12 @@
   BTIF_TRACE_DEBUG("%s", __func__);
   CHECK_RC_CONNECTED(p_dev);
 
+  if (num_attr > BTRC_MAX_ELEM_ATTR_SIZE) {
+    LOG(WARNING) << __func__
+                 << " Exceeded number attributes:" << static_cast<int>(num_attr)
+                 << " max:" << BTRC_MAX_ELEM_ATTR_SIZE;
+    num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
+  }
   memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
 
   if (num_attr == 0) {
@@ -1844,7 +1850,8 @@
     for (i = 0; i < num_attr; i++) {
       element_attrs[i].attr_id = p_attrs[i].attr_id;
       element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
-      element_attrs[i].name.str_len = (uint16_t)strlen((char*)p_attrs[i].text);
+      element_attrs[i].name.str_len =
+          (uint16_t)strnlen((char*)p_attrs[i].text, BTRC_MAX_ATTR_STR_LEN);
       element_attrs[i].name.p_str = p_attrs[i].text;
       BTIF_TRACE_DEBUG(
           "%s: attr_id: 0x%x, charset_id: 0x%x, str_len: %d, str: %s", __func__,
@@ -2939,11 +2946,12 @@
     return;
   }
   // interval is only valid for AVRC_EVT_PLAY_POS_CHANGED
-  uint32_t interval = 0;
+  uint32_t interval_in_seconds = 0;
   if (p_event->event_id == AVRC_EVT_PLAY_POS_CHANGED) {
-    interval = 2000;
+    interval_in_seconds = 2;
   }
-  status = register_notification_cmd(p_transaction->lbl, p_event->event_id, interval, p_dev);
+  status = register_notification_cmd(p_transaction->lbl, p_event->event_id,
+                                     interval_in_seconds, p_dev);
   if (status != BT_STATUS_SUCCESS) {
     BTIF_TRACE_ERROR("%s: Error in Notification registration: %d", __func__,
                      status);
@@ -3152,11 +3160,10 @@
           break;
         } else {
           uint8_t* p_data = p_rsp->param.track;
-          /* Update the UID for current track
-           * Attributes will be fetched after the AVRCP procedure
-           */
           BE_STREAM_TO_UINT64(p_dev->rc_playing_uid, p_data);
           get_play_status_cmd(p_dev);
+          get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list,
+                                    p_dev);
         }
         break;
 
@@ -3336,6 +3343,8 @@
     rc_ctrl_procedure_complete(p_dev);
     return;
   }
+  p_dev->rc_app_settings.num_attrs = 0;
+  p_dev->rc_app_settings.num_ext_attrs = 0;
 
   for (xx = 0; xx < p_rsp->num_attr; xx++) {
     uint8_t st_index;
@@ -3809,6 +3818,10 @@
   if (p_rsp->status == AVRC_STS_NO_ERROR) {
     do_in_jni_thread(
         FROM_HERE,
+        base::Bind(bt_rc_ctrl_callbacks->play_status_changed_cb, p_dev->rc_addr,
+                   (btrc_play_status_t)p_rsp->play_status));
+    do_in_jni_thread(
+        FROM_HERE,
         base::Bind(bt_rc_ctrl_callbacks->play_position_changed_cb,
                    p_dev->rc_addr, p_rsp->song_len, p_rsp->song_pos));
   } else {
@@ -3907,6 +3920,12 @@
                    /* We want to make the ownership explicit in native */
                    btrc_items, item_count));
 
+    if (item_count > 0) {
+      if (btrc_items[0].item_type == AVRC_ITEM_PLAYER &&
+          (p_dev->rc_features & BTA_AV_FEAT_APP_SETTING)) {
+        list_player_app_setting_attrib_cmd(p_dev);
+      }
+    }
     /* Release the memory block for items and attributes allocated here.
      * Since the executor for do_in_jni_thread is a Single Thread Task Runner it
      * is okay to queue up the cleanup of btrc_items */
diff --git a/btif/src/btif_sock_l2cap.cc b/btif/src/btif_sock_l2cap.cc
index 5d333d1..fa59d87 100644
--- a/btif/src/btif_sock_l2cap.cc
+++ b/btif/src/btif_sock_l2cap.cc
@@ -97,6 +97,7 @@
 static std::mutex state_lock;
 
 l2cap_socket* socks = NULL;
+static uint32_t last_sock_id = 0;
 static uid_set_t* uid_set = NULL;
 static int pth = -1;
 
@@ -254,6 +255,11 @@
     }
     if ((sock->channel >= 0) && (sock->server)) {
       BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP_LE);
+      if (!sock->fixed_chan) {
+        VLOG(2) << __func__ << ": stopping L2CAP LE COC server channel "
+                << sock->channel;
+        BTA_JvL2capStopServer(sock->channel, sock->id);
+      }
     }
   } else {
     // Only call if we are non server connections
@@ -322,7 +328,7 @@
   sock->next = socks;
   sock->prev = NULL;
   if (socks) socks->prev = sock;
-  sock->id = (socks ? socks->id : 0) + 1;
+  sock->id = last_sock_id + 1;
   sock->tx_bytes = 0;
   sock->rx_bytes = 0;
   socks = sock;
@@ -340,6 +346,7 @@
     if (!++sock->id) /* no zero IDs allowed */
       sock->id++;
   }
+  last_sock_id = sock->id;
   DVLOG(2) << __func__ << " SOCK_LIST: alloc id:" << sock->id;
   return sock;
 
diff --git a/btif/test/btif_profile_queue_test.cc b/btif/test/btif_profile_queue_test.cc
index 486959b..af0255b 100644
--- a/btif/test/btif_profile_queue_test.cc
+++ b/btif/test/btif_profile_queue_test.cc
@@ -97,6 +97,49 @@
   EXPECT_EQ(sResult, UUID1_ADDR1);
 }
 
+static bt_status_t test_connect_cb_fail(RawAddress* bda, uint16_t uuid) {
+  sResult = UNKNOWN;
+  if (*bda == BtifProfileQueueTest::kTestAddr1) {
+    if (uuid == BtifProfileQueueTest::kTestUuid1) {
+      sResult = UUID1_ADDR1;
+    } else if (uuid == BtifProfileQueueTest::kTestUuid2) {
+      sResult = UUID2_ADDR1;
+    }
+  } else if (*bda == BtifProfileQueueTest::kTestAddr2) {
+    if (uuid == BtifProfileQueueTest::kTestUuid1) {
+      sResult = UUID1_ADDR2;
+    } else if (uuid == BtifProfileQueueTest::kTestUuid2) {
+      sResult = UUID2_ADDR2;
+    }
+  }
+  return BT_STATUS_BUSY;
+}
+
+TEST_F(BtifProfileQueueTest, test_connect_fail_still_can_advance_the_queue) {
+  sResult = NOT_SET;
+  // First connect-message for UUID1-ADDR1 is executed, but does not be removed
+  // from connect-queue yet.
+  btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
+  EXPECT_EQ(sResult, UUID1_ADDR1);
+  sResult = NOT_SET;
+  // Second connect-message for UUID2-ADDR1 be pushed into connect-queue, but is
+  // not executed
+  btif_queue_connect(kTestUuid2, &kTestAddr1, test_connect_cb_fail);
+  EXPECT_EQ(sResult, NOT_SET);
+  // Third connect-message for UUID1-ADDR2 be pushed into connect-queue, but is
+  // not executed
+  btif_queue_connect(kTestUuid1, &kTestAddr2, test_connect_cb_fail);
+  EXPECT_EQ(sResult, NOT_SET);
+  // Fourth connect-message for UUID2-ADDR2 be pushed into connect-queue, but is
+  // not executed
+  btif_queue_connect(kTestUuid2, &kTestAddr2, test_connect_cb_fail);
+  EXPECT_EQ(sResult, NOT_SET);
+  // removed First connect-message from connect-queue, check it can advance to
+  // subsequent connect-message.
+  btif_queue_advance();
+  EXPECT_EQ(sResult, UUID2_ADDR2);
+}
+
 TEST_F(BtifProfileQueueTest, test_connect_same_uuid_do_not_repeat) {
   sResult = NOT_SET;
   btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
diff --git a/btif/test/btif_rc_test.cc b/btif/test/btif_rc_test.cc
new file mode 100644
index 0000000..6271881
--- /dev/null
+++ b/btif/test/btif_rc_test.cc
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * 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 <base/logging.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <cstdint>
+
+#include "bta/include/bta_av_api.h"
+#include "btif/include/btif_common.h"
+#include "device/include/interop.h"
+#include "include/hardware/bt_rc.h"
+#include "osi/test/AllocationTestHarness.h"
+#include "stack/include/btm_api_types.h"
+#include "types/raw_address.h"
+#undef LOG_TAG
+#include "btif/src/btif_rc.cc"
+
+extern void allocation_tracker_uninit(void);
+
+namespace {
+int AVRC_BldResponse_ = 0;
+}  // namespace
+
+uint8_t appl_trace_level = BT_TRACE_LEVEL_WARNING;
+uint8_t btif_trace_level = BT_TRACE_LEVEL_WARNING;
+
+tAVRC_STS AVRC_BldCommand(tAVRC_COMMAND* p_cmd, BT_HDR** pp_pkt) { return 0; }
+tAVRC_STS AVRC_BldResponse(uint8_t handle, tAVRC_RESPONSE* p_rsp,
+                           BT_HDR** pp_pkt) {
+  AVRC_BldResponse_++;
+  return 0;
+}
+tAVRC_STS AVRC_Ctrl_ParsCommand(tAVRC_MSG* p_msg, tAVRC_COMMAND* p_result) {
+  return 0;
+}
+tAVRC_STS AVRC_Ctrl_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
+                                 uint8_t* p_buf, uint16_t* buf_len) {
+  return 0;
+}
+tAVRC_STS AVRC_ParsCommand(tAVRC_MSG* p_msg, tAVRC_COMMAND* p_result,
+                           uint8_t* p_buf, uint16_t buf_len) {
+  return 0;
+}
+tAVRC_STS AVRC_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
+                            UNUSED_ATTR uint8_t* p_buf,
+                            UNUSED_ATTR uint16_t buf_len) {
+  return 0;
+}
+void BTA_AvCloseRc(uint8_t rc_handle) {}
+void BTA_AvMetaCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_CMD cmd_code,
+                   BT_HDR* p_pkt) {}
+void BTA_AvMetaRsp(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE rsp_code,
+                   BT_HDR* p_pkt) {}
+void BTA_AvRemoteCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_RC rc_id,
+                     tBTA_AV_STATE key_state) {}
+void BTA_AvRemoteVendorUniqueCmd(uint8_t rc_handle, uint8_t label,
+                                 tBTA_AV_STATE key_state, uint8_t* p_msg,
+                                 uint8_t buf_len) {}
+void BTA_AvVendorCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE cmd_code,
+                     uint8_t* p_data, uint16_t len) {}
+void BTA_AvVendorRsp(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE rsp_code,
+                     uint8_t* p_data, uint16_t len, uint32_t company_id) {}
+void btif_av_clear_remote_suspend_flag(void) {}
+bool btif_av_is_connected(void) { return false; }
+bool btif_av_is_sink_enabled(void) { return false; }
+RawAddress btif_av_sink_active_peer(void) { return RawAddress(); }
+RawAddress btif_av_source_active_peer(void) { return RawAddress(); }
+bool btif_av_stream_started_ready(void) { return false; }
+bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event,
+                                  char* p_params, int param_len,
+                                  tBTIF_COPY_CBACK* p_copy_cback) {
+  return BT_STATUS_SUCCESS;
+}
+const char* dump_rc_event(uint8_t event) { return nullptr; }
+const char* dump_rc_notification_event_id(uint8_t event_id) { return nullptr; }
+const char* dump_rc_pdu(uint8_t pdu) { return nullptr; }
+bt_status_t do_in_jni_thread(const base::Location& from_here,
+                             base::OnceClosure task) {
+  return BT_STATUS_SUCCESS;
+}
+base::MessageLoop* get_main_message_loop() { return nullptr; }
+bool interop_match_addr(const interop_feature_t feature,
+                        const RawAddress* addr) {
+  return false;
+}
+void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}
+
+/**
+ * Test class to test selected functionality in hci/src/hci_layer.cc
+ */
+class BtifRcTest : public AllocationTestHarness {
+ protected:
+  void SetUp() override {
+    AllocationTestHarness::SetUp();
+    // Disable our allocation tracker to allow ASAN full range
+    allocation_tracker_uninit();
+  }
+
+  void TearDown() override { AllocationTestHarness::TearDown(); }
+};
+
+TEST_F(BtifRcTest, get_element_attr_rsp) {
+  RawAddress bd_addr;
+
+  btif_rc_cb.rc_multi_cb[0].rc_addr = bd_addr;
+  btif_rc_cb.rc_multi_cb[0].rc_connected = true;
+  btif_rc_cb.rc_multi_cb[0]
+      .rc_pdu_info[IDX_GET_ELEMENT_ATTR_RSP]
+      .is_rsp_pending = true;
+  btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
+
+  btrc_element_attr_val_t p_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
+  uint8_t num_attr = BTRC_MAX_ELEM_ATTR_SIZE + 1;
+
+  CHECK(get_element_attr_rsp(bd_addr, num_attr, p_attrs) == BT_STATUS_SUCCESS);
+  CHECK(AVRC_BldResponse_ == 1);
+}
diff --git a/device/include/controller.h b/device/include/controller.h
index c1fe337..f1c85aa 100644
--- a/device/include/controller.h
+++ b/device/include/controller.h
@@ -85,6 +85,7 @@
   uint8_t (*get_ble_resolving_list_max_size)(void);
   void (*set_ble_resolving_list_max_size)(int resolving_list_max_size);
   uint8_t* (*get_local_supported_codecs)(uint8_t* number_of_codecs);
+  bool (*supports_ble_offload_features)(void);
   uint8_t (*get_le_all_initiating_phys)(void);
 
 } controller_t;
diff --git a/device/src/controller.cc b/device/src/controller.cc
index 34c8afd..6525c14 100644
--- a/device/src/controller.cc
+++ b/device/src/controller.cc
@@ -22,6 +22,7 @@
 
 #include <base/logging.h>
 
+#include "bt_target.h"
 #include "bt_types.h"
 #include "btcore/include/event_mask.h"
 #include "btcore/include/module.h"
@@ -84,6 +85,7 @@
 
 static bool readable;
 static bool ble_supported;
+static bool ble_offload_features_supported;
 static bool simple_pairing_supported;
 static bool secure_connections_supported;
 
@@ -126,6 +128,9 @@
       AWAIT_COMMAND(packet_factory->make_read_local_supported_commands());
   packet_parser->parse_read_local_supported_commands_response(
       response, supported_commands, HCI_SUPPORTED_COMMANDS_ARRAY_SIZE);
+#if (BTM_SCO_ENHANCED_SYNC_ENABLED == FALSE)
+  supported_commands[29] &= ~0x08;
+#endif
 
   // Read page 0 of the controller features next
   uint8_t page_number = 0;
@@ -178,14 +183,19 @@
     page_number++;
   }
 
+  // read BLE offload features support from controller
+  response = AWAIT_COMMAND(packet_factory->make_ble_read_offload_features_support());
+  packet_parser->parse_ble_read_offload_features_response(response, &ble_offload_features_supported);
 #if (SC_MODE_INCLUDED == TRUE)
-  secure_connections_supported =
-      HCI_SC_CTRLR_SUPPORTED(features_classic[2].as_array);
-  if (secure_connections_supported) {
-    response = AWAIT_COMMAND(
-        packet_factory->make_write_secure_connections_host_support(
-            HCI_SC_MODE_ENABLED));
-    packet_parser->parse_generic_command_complete(response);
+  if(ble_offload_features_supported) {
+    secure_connections_supported =
+        HCI_SC_CTRLR_SUPPORTED(features_classic[2].as_array);
+    if (secure_connections_supported) {
+      response = AWAIT_COMMAND(
+          packet_factory->make_write_secure_connections_host_support(
+              HCI_SC_MODE_ENABLED));
+      packet_parser->parse_generic_command_complete(response);
+    }
   }
 #endif
 
@@ -443,6 +453,12 @@
   return HCI_LE_PERIODIC_ADVERTISING_SUPPORTED(features_ble.as_array);
 }
 
+static bool supports_ble_offload_features(void) {
+  assert(readable);
+  assert(ble_supported);
+  return ble_offload_features_supported;
+}
+
 static uint16_t get_acl_data_size_classic(void) {
   CHECK(readable);
   return acl_data_size_classic;
@@ -580,6 +596,7 @@
     get_ble_resolving_list_max_size,
     set_ble_resolving_list_max_size,
     get_local_supported_codecs,
+    supports_ble_offload_features,
     get_le_all_initiating_phys};
 
 const controller_t* controller_get_interface() {
diff --git a/hci/Android.bp b/hci/Android.bp
index 635d939..5702177 100644
--- a/hci/Android.bp
+++ b/hci/Android.bp
@@ -36,6 +36,7 @@
         "system/bt/stack/include",
         "system/bt/utils/include",
         "system/bt/bta/include",
+        "system/bt/btif/include",
         "system/libhwbinder/include",
     ],
 }
diff --git a/hci/include/hci_packet_factory.h b/hci/include/hci_packet_factory.h
index e7cb47b..91caa7a 100644
--- a/hci/include/hci_packet_factory.h
+++ b/hci/include/hci_packet_factory.h
@@ -46,6 +46,7 @@
   BT_HDR* (*make_ble_read_number_of_supported_advertising_sets)(void);
   BT_HDR* (*make_ble_set_event_mask)(const bt_event_mask_t* event_mask);
   BT_HDR* (*make_read_local_supported_codecs)(void);
+  BT_HDR *(*make_ble_read_offload_features_support)(void);
 } hci_packet_factory_t;
 
 const hci_packet_factory_t* hci_packet_factory_get_interface();
diff --git a/hci/include/hci_packet_parser.h b/hci/include/hci_packet_parser.h
index 8878cb9..06af557 100644
--- a/hci/include/hci_packet_parser.h
+++ b/hci/include/hci_packet_parser.h
@@ -83,6 +83,9 @@
       BT_HDR* response, uint8_t* number_of_local_supported_codecs,
       uint8_t* local_supported_codecs);
 
+  void (*parse_ble_read_offload_features_response)(
+    BT_HDR *response,
+    bool *ble_offload_features_supported);
 } hci_packet_parser_t;
 
 const hci_packet_parser_t* hci_packet_parser_get_interface();
diff --git a/hci/src/hci_layer.cc b/hci/src/hci_layer.cc
index ed2908c..79c44e0 100644
--- a/hci/src/hci_layer.cc
+++ b/hci/src/hci_layer.cc
@@ -36,10 +36,12 @@
 #include <mutex>
 
 #include "btcore/include/module.h"
+#include "btif/include/btif_bqr.h"
 #include "btsnoop.h"
 #include "buffer_allocator.h"
 #include "common/message_loop_thread.h"
 #include "common/metrics.h"
+#include "common/once_timer.h"
 #include "hci_inject.h"
 #include "hci_internals.h"
 #include "hcidefs.h"
@@ -54,6 +56,7 @@
 #define BT_HCI_TIMEOUT_TAG_NUM 1010000
 
 using bluetooth::common::MessageLoopThread;
+using bluetooth::common::OnceTimer;
 
 extern void hci_initialize();
 extern void hci_transmit(BT_HDR* packet);
@@ -110,7 +113,7 @@
 static alarm_t* command_response_timer;
 static list_t* commands_pending_response;
 static std::recursive_timed_mutex commands_pending_response_mutex;
-static alarm_t* hci_timeout_abort_timer;
+static OnceTimer abort_timer;
 
 // The hand-off point for data going to a higher layer, set by the higher layer
 static base::Callback<void(const base::Location&, BT_HDR*)> send_data_upwards;
@@ -160,6 +163,14 @@
   packet_fragmenter->reassemble_and_dispatch(packet);
 }
 
+void hal_service_died() {
+  if (abort_timer.IsScheduled()) {
+    LOG(ERROR) << "abort_timer is scheduled, wait for timeout";
+    return;
+  }
+  abort();
+}
+
 // Module lifecycle functions
 
 static future_t* hci_module_shut_down();
@@ -258,12 +269,6 @@
 
   packet_fragmenter->cleanup();
 
-  // Clean up abort timer, if it exists.
-  if (hci_timeout_abort_timer != NULL) {
-    alarm_free(hci_timeout_abort_timer);
-    hci_timeout_abort_timer = NULL;
-  }
-
   if (hci_firmware_log_fd != INVALID_FD) {
     hci_close_firmware_log_file(hci_firmware_log_fd);
     hci_firmware_log_fd = INVALID_FD;
@@ -436,13 +441,19 @@
 }
 
 // Abort.  The chip has had time to write any debugging information.
-static void hci_timeout_abort(void* unused_data) {
+static void hci_timeout_abort(void) {
   LOG_ERROR(LOG_TAG, "%s restarting the Bluetooth process.", __func__);
   hci_close_firmware_log_file(hci_firmware_log_fd);
 
   // We shouldn't try to recover the stack from this command timeout.
   // If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
-  abort();
+  exit(0);
+}
+
+static void hci_root_inflamed_abort(uint8_t error_code,
+                                    uint8_t vendor_error_code) {
+  LOG(FATAL) << __func__ << ": error_code = " << std::to_string(error_code)
+             << ", vendor_error_code = " << std::to_string(vendor_error_code);
 }
 
 static void command_timed_out_log_info(void* original_wait_entry) {
@@ -494,7 +505,7 @@
   }
 
   // Don't request a firmware dump for multiple hci timeouts
-  if (hci_timeout_abort_timer != NULL || hci_firmware_log_fd != INVALID_FD) {
+  if (hci_firmware_log_fd != INVALID_FD) {
     return;
   }
 
@@ -521,13 +532,13 @@
   osi_free(bt_hdr);
   LOG_ERROR(LOG_TAG, "%s: Setting a timer to restart.", __func__);
 
-  hci_timeout_abort_timer = alarm_new("hci.hci_timeout_aborter");
-  if (!hci_timeout_abort_timer) {
+  // alarm_default_callbacks thread post to hci_thread.
+  if (!abort_timer.Schedule(
+          hci_thread.GetWeakPtr(), FROM_HERE, base::Bind(hci_timeout_abort),
+          base::TimeDelta::FromMilliseconds(COMMAND_TIMEOUT_RESTART_MS))) {
     LOG_ERROR(LOG_TAG, "%s unable to create an abort timer.", __func__);
     abort();
   }
-  alarm_set(hci_timeout_abort_timer, COMMAND_TIMEOUT_RESTART_MS,
-            hci_timeout_abort, nullptr);
 }
 
 // Event/packet receiving functions
@@ -614,15 +625,62 @@
     }
 
     goto intercepted;
-  } else if (event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) {
-    if (hci_firmware_log_fd == INVALID_FD)
-      hci_firmware_log_fd = hci_open_firmware_log_file();
+  } else if (event_code == HCI_VENDOR_SPECIFIC_EVT) {
+    uint8_t sub_event_code;
+    STREAM_TO_UINT8(sub_event_code, stream);
 
-    if (hci_firmware_log_fd != INVALID_FD)
-      hci_log_firmware_debug_packet(hci_firmware_log_fd, packet);
+    if (sub_event_code == HCI_VSE_SUBCODE_DEBUG_INFO_SUB_EVT) {
+      if (hci_firmware_log_fd == INVALID_FD)
+        hci_firmware_log_fd = hci_open_firmware_log_file();
 
-    buffer_allocator->free(packet);
-    return true;
+      if (hci_firmware_log_fd != INVALID_FD)
+        hci_log_firmware_debug_packet(hci_firmware_log_fd, packet);
+
+      buffer_allocator->free(packet);
+      return true;
+    } else if (sub_event_code == HCI_VSE_SUBCODE_BQR_SUB_EVT) {
+      uint8_t bqr_report_id;
+      STREAM_TO_UINT8(bqr_report_id, stream);
+
+      if (bqr_report_id ==
+              bluetooth::bqr::QUALITY_REPORT_ID_ROOT_INFLAMMATION &&
+          packet->len >= bluetooth::bqr::kRootInflammationPacketMinSize) {
+        uint8_t error_code;
+        uint8_t vendor_error_code;
+        STREAM_TO_UINT8(error_code, stream);
+        STREAM_TO_UINT8(vendor_error_code, stream);
+        // TODO(ugoyu) Report to bluetooth metrics here
+
+        LOG(ERROR) << __func__
+                   << ": Root inflammation event! setting timer to restart.";
+        {
+          // Try to stop hci command and startup timers
+          std::unique_lock<std::recursive_timed_mutex> lock(
+              commands_pending_response_mutex, std::defer_lock);
+          if (lock.try_lock_for(std::chrono::milliseconds(
+                  COMMAND_PENDING_MUTEX_ACQUIRE_TIMEOUT_MS))) {
+            if (alarm_is_scheduled(startup_timer)) {
+              alarm_cancel(startup_timer);
+            }
+            if (alarm_is_scheduled(command_response_timer)) {
+              alarm_cancel(command_response_timer);
+            }
+          } else {
+            LOG(ERROR) << __func__ << ": Failed to obtain mutex";
+          }
+        }
+
+        // HwBinder thread post to hci_thread
+        if (!abort_timer.Schedule(hci_thread.GetWeakPtr(), FROM_HERE,
+                                  base::Bind(hci_root_inflamed_abort,
+                                             error_code, vendor_error_code),
+                                  base::TimeDelta::FromMilliseconds(
+                                      COMMAND_TIMEOUT_RESTART_MS))) {
+          LOG(ERROR) << "Failed to schedule abort_timer!";
+          hci_root_inflamed_abort(error_code, vendor_error_code);
+        }
+      }
+    }
   }
 
   return false;
@@ -672,7 +730,26 @@
 
     return wait_entry;
   }
+  // look for any command complete with improper VS Opcode
+  for (const list_node_t *node = list_begin(commands_pending_response);
+      node != list_end(commands_pending_response);
+      node = list_next(node)) {
+    waiting_command_t *wait_entry =
+        reinterpret_cast<waiting_command_t*> (list_node(node));
 
+    if (wait_entry && (wait_entry->opcode != opcode) &&
+        (((wait_entry->opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC) &&
+        ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC))) {
+        LOG_DEBUG(LOG_TAG,"%s VS event found treat it as valid 0x%x", __func__, opcode);
+    }
+    else {
+        continue;
+    }
+
+    list_remove(commands_pending_response, wait_entry);
+
+    return wait_entry;
+  }
   return NULL;
 }
 
diff --git a/hci/src/hci_layer_android.cc b/hci/src/hci_layer_android.cc
index 92be0df..a9fde50 100644
--- a/hci/src/hci_layer_android.cc
+++ b/hci/src/hci_layer_android.cc
@@ -51,6 +51,7 @@
 extern void hci_event_received(const base::Location& from_here, BT_HDR* packet);
 extern void acl_event_received(BT_HDR* packet);
 extern void sco_data_received(BT_HDR* packet);
+extern void hal_service_died();
 
 android::sp<IBluetoothHci> btHci;
 
@@ -58,7 +59,7 @@
  public:
   virtual void serviceDied(uint64_t /*cookie*/, const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
     LOG_ERROR(LOG_TAG, "Bluetooth HAL service died!");
-    abort();
+    hal_service_died();
   }
 };
 android::sp<BluetoothHciDeathRecipient> bluetoothHciDeathRecipient = new BluetoothHciDeathRecipient();
diff --git a/hci/src/hci_packet_factory.cc b/hci/src/hci_packet_factory.cc
index ca0fb5f..1cff9f6 100644
--- a/hci/src/hci_packet_factory.cc
+++ b/hci/src/hci_packet_factory.cc
@@ -159,6 +159,10 @@
   return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CODECS);
 }
 
+static BT_HDR* make_ble_read_offload_features_support(void) {
+    return make_command_no_params(HCI_BLE_VENDOR_CAP_OCF);
+}
+
 static BT_HDR* make_ble_set_event_mask(const bt_event_mask_t* event_mask) {
   uint8_t* stream;
   uint8_t parameter_size = sizeof(bt_event_mask_t);
@@ -220,7 +224,8 @@
     make_ble_read_maximum_advertising_data_length,
     make_ble_read_number_of_supported_advertising_sets,
     make_ble_set_event_mask,
-    make_read_local_supported_codecs};
+    make_read_local_supported_codecs,
+    make_ble_read_offload_features_support};
 
 const hci_packet_factory_t* hci_packet_factory_get_interface() {
   buffer_allocator = buffer_allocator_get_interface();
diff --git a/hci/src/hci_packet_parser.cc b/hci/src/hci_packet_parser.cc
index b1efd44..3f4e46c 100644
--- a/hci/src/hci_packet_parser.cc
+++ b/hci/src/hci_packet_parser.cc
@@ -85,6 +85,20 @@
   buffer_allocator->free(response);
 }
 
+static void parse_ble_read_offload_features_response(
+    BT_HDR *response,
+    bool *ble_offload_features_supported) {
+
+  uint8_t *stream = read_command_complete_header(response, NO_OPCODE_CHECKING, 0 /* bytes after */);
+  if(stream) {
+    *ble_offload_features_supported  = true;
+  } else {
+    *ble_offload_features_supported  = false;
+  }
+
+  buffer_allocator->free(response);
+}
+
 static void parse_read_bd_addr_response(BT_HDR* response,
                                         RawAddress* address_ptr) {
   uint8_t* stream = read_command_complete_header(
@@ -281,7 +295,8 @@
     parse_ble_read_maximum_data_length_response,
     parse_ble_read_maximum_advertising_data_length,
     parse_ble_read_number_of_supported_advertising_sets,
-    parse_read_local_supported_codecs_response};
+    parse_read_local_supported_codecs_response,
+    parse_ble_read_offload_features_response};
 
 const hci_packet_parser_t* hci_packet_parser_get_interface() {
   buffer_allocator = buffer_allocator_get_interface();
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index 4c88de8..3097c1a 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -469,11 +469,11 @@
    * The |start_restricted| flag inits the adapter in restricted mode. In
    * restricted mode, bonds that are created are marked as restricted in the
    * config file. These devices are deleted upon leaving restricted mode.
-   * The |is_single_user_mode| flag inits the adapter in NIAP mode.
+   * The |is_niap_mode| flag inits the adapter in NIAP mode.
    * The |is_atv| flag indicates whether the local device is an Android TV
    */
-  int (*init)(bt_callbacks_t* callbacks, bool guest_mode,
-              bool is_single_user_mode, bool is_atv);
+  int (*init)(bt_callbacks_t* callbacks, bool guest_mode, bool is_niap_mode,
+              bool is_atv);
 
   /** Enable Bluetooth. */
   int (*enable)();
diff --git a/internal_include/bt_target.h b/internal_include/bt_target.h
index 67a67c5..e33f0b5 100644
--- a/internal_include/bt_target.h
+++ b/internal_include/bt_target.h
@@ -108,7 +108,7 @@
 #endif
 
 #ifndef BTA_DM_SDP_DB_SIZE
-#define BTA_DM_SDP_DB_SIZE 8000
+#define BTA_DM_SDP_DB_SIZE 20000
 #endif
 
 #ifndef HL_INCLUDED
@@ -286,6 +286,12 @@
 #define BTM_DISC_DURING_RS TRUE
 #endif
 
+/*  This is used to work around a controller bug that report supporting
+ *  enhanced synchronous commands */
+#ifndef BTM_SCO_ENHANCED_SYNC_ENABLED
+#define BTM_SCO_ENHANCED_SYNC_ENABLED TRUE
+#endif
+
 /**************************
  * Initial SCO TX credit
  ************************/
diff --git a/profile/avrcp/connection_handler.cc b/profile/avrcp/connection_handler.cc
index 51ebfea..e9a4c72 100644
--- a/profile/avrcp/connection_handler.cc
+++ b/profile/avrcp/connection_handler.cc
@@ -138,9 +138,7 @@
 bool ConnectionHandler::DisconnectDevice(const RawAddress& bdaddr) {
   for (auto it = device_map_.begin(); it != device_map_.end(); it++) {
     if (bdaddr == it->second->GetAddress()) {
-      it->second->DeviceDisconnected();
       uint8_t handle = it->first;
-      device_map_.erase(handle);
       return avrc_->Close(handle) == AVRC_SUCCESS;
     }
   }
diff --git a/profile/avrcp/device.cc b/profile/avrcp/device.cc
index 4ca624b..264eaf0 100644
--- a/profile/avrcp/device.cc
+++ b/profile/avrcp/device.cc
@@ -98,6 +98,19 @@
       case CommandPdu::REGISTER_NOTIFICATION: {
         auto register_notification =
             Packet::Specialize<RegisterNotificationResponse>(pkt);
+
+        if (!register_notification->IsValid()) {
+          DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+          auto response =
+              RejectBuilder::MakeBuilder(pkt->GetCommandPdu(),
+                                         Status::INVALID_PARAMETER);
+          send_message(label, false, std::move(response));
+          active_labels_.erase(label);
+          volume_interface_ = nullptr;
+          volume_ = VOL_REGISTRATION_FAILED;
+          return;
+        }
+
         if (register_notification->GetEvent() != Event::VOLUME_CHANGED) {
           DEVICE_LOG(WARNING)
               << __func__ << ": Unhandled register notification received: "
@@ -336,16 +349,6 @@
     uint8_t label, const std::shared_ptr<RegisterNotificationResponse>& pkt) {
   DEVICE_VLOG(1) << __func__ << ": interim=" << pkt->IsInterim();
 
-  if (!pkt->IsValid()) {
-    DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
-    auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER);
-    send_message(label, false, std::move(response));
-    active_labels_.erase(label);
-    volume_interface_ = nullptr;
-    volume_ = VOL_REGISTRATION_FAILED;
-    return;
-  }
-
   if (volume_interface_ == nullptr) return;
 
   if (pkt->GetCType() == CType::REJECTED) {
diff --git a/stack/Android.bp b/stack/Android.bp
index 4863afb..c468423 100644
--- a/stack/Android.bp
+++ b/stack/Android.bp
@@ -200,6 +200,7 @@
     ],
     srcs: [
         "test/stack_a2dp_test.cc",
+        "test/stack_avrcp_test.cc",
     ],
     shared_libs: [
         "libcrypto",
diff --git a/stack/BUILD.gn b/stack/BUILD.gn
index 00680c8..87dc726 100644
--- a/stack/BUILD.gn
+++ b/stack/BUILD.gn
@@ -202,6 +202,7 @@
   testonly = true
   sources = [
     "test/stack_a2dp_test.cc",
+    "test/stack_avrcp_test.cc",
   ]
 
   include_dirs = [
diff --git a/stack/avdt/avdt_msg.cc b/stack/avdt/avdt_msg.cc
index ae17c11..bf83d19 100644
--- a/stack/avdt/avdt_msg.cc
+++ b/stack/avdt/avdt_msg.cc
@@ -985,18 +985,30 @@
  * Returns          Error code or zero if no error.
  *
  ******************************************************************************/
-static uint8_t avdt_msg_prs_rej(tAVDT_MSG* p_msg, uint8_t* p, uint8_t sig) {
-  if ((sig == AVDT_SIG_SETCONFIG) || (sig == AVDT_SIG_RECONFIG)) {
-    p_msg->hdr.err_param = *p++;
-    p_msg->hdr.err_code = *p;
-  } else if ((sig == AVDT_SIG_START) || (sig == AVDT_SIG_SUSPEND)) {
-    AVDT_MSG_PRS_SEID(p, p_msg->hdr.err_param);
-    p_msg->hdr.err_code = *p;
+static uint8_t avdt_msg_prs_rej(tAVDT_MSG* p_msg, uint8_t* p, uint16_t len,
+                                uint8_t sig) {
+  uint8_t error = 0;
+
+  if (len > 0) {
+    if ((sig == AVDT_SIG_SETCONFIG) || (sig == AVDT_SIG_RECONFIG)) {
+      p_msg->hdr.err_param = *p++;
+      len--;
+    } else if ((sig == AVDT_SIG_START) || (sig == AVDT_SIG_SUSPEND)) {
+      AVDT_MSG_PRS_SEID(p, p_msg->hdr.err_param);
+      len--;
+    }
+  }
+
+  if (len < 1) {
+    char error_info[] = "AVDT rejected response length mismatch";
+    android_errorWriteWithInfoLog(0x534e4554, "79702484", -1, error_info,
+                                  strlen(error_info));
+    error = AVDT_ERR_LENGTH;
   } else {
     p_msg->hdr.err_code = *p;
   }
 
-  return 0;
+  return error;
 }
 
 /*******************************************************************************
@@ -1610,7 +1622,7 @@
       evt = avdt_msg_rsp_2_evt[sig - 1];
     } else /* msg_type == AVDT_MSG_TYPE_REJ */
     {
-      err = avdt_msg_prs_rej(&msg, p, sig);
+      err = avdt_msg_prs_rej(&msg, p, p_buf->len, sig);
       evt = avdt_msg_rej_2_evt[sig - 1];
     }
 
diff --git a/stack/avrc/avrc_pars_ct.cc b/stack/avrc/avrc_pars_ct.cc
index 74b56e7..83f2293 100644
--- a/stack/avrc/avrc_pars_ct.cc
+++ b/stack/avrc/avrc_pars_ct.cc
@@ -814,7 +814,7 @@
       if (len < min_len) goto length_error;
       BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
       BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
-      BE_STREAM_TO_UINT8(p_result->get_play_status.status, p);
+      BE_STREAM_TO_UINT8(p_result->get_play_status.play_status, p);
       break;
 
     case AVRC_PDU_SET_ADDRESSED_PLAYER:
diff --git a/stack/avrc/avrc_pars_tg.cc b/stack/avrc/avrc_pars_tg.cc
index 00e85e7..99e6671 100644
--- a/stack/avrc/avrc_pars_tg.cc
+++ b/stack/avrc/avrc_pars_tg.cc
@@ -382,7 +382,7 @@
  *
  * Description      This function is used to parse cmds received for CTRL
  *                  Currently it is for SetAbsVolume and Volume Change
- *                  Notification..
+ *                  Notification.
  *
  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
  *                  successfully.
@@ -409,6 +409,12 @@
   return status;
 }
 
+#define RETURN_STATUS_IF_FALSE(_status_, _b_, _msg_, ...) \
+  if (!(_b_)) {                                           \
+    AVRC_TRACE_DEBUG(_msg_, ##__VA_ARGS__);               \
+    return _status_;                                      \
+  }
+
 /*******************************************************************************
  *
  * Function         avrc_pars_browsing_cmd
@@ -428,6 +434,10 @@
   uint8_t* p = p_msg->p_browse_data;
   int count;
 
+  uint16_t min_len = 3;
+  RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, (p_msg->browse_len >= min_len),
+                         "msg too short");
+
   p_result->pdu = *p++;
   AVRC_TRACE_DEBUG("avrc_pars_browsing_cmd() pdu:0x%x", p_result->pdu);
   /* skip over len */
@@ -435,11 +445,20 @@
 
   switch (p_result->pdu) {
     case AVRC_PDU_SET_BROWSED_PLAYER: /* 0x70 */
+      min_len += 2;
+      RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, (p_msg->browse_len >= min_len),
+                             "msg too short");
+
       // For current implementation all players are browsable.
       BE_STREAM_TO_UINT16(p_result->br_player.player_id, p);
       break;
 
     case AVRC_PDU_GET_FOLDER_ITEMS: /* 0x71 */
+
+      min_len += 10;
+      RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, (p_msg->browse_len >= min_len),
+                             "msg too short");
+
       STREAM_TO_UINT8(p_result->get_items.scope, p);
       // To be modified later here (Scope) when all browsing commands are
       // supported
@@ -460,12 +479,21 @@
         if (buf_len < (count << 2))
           p_result->get_items.attr_count = count = (buf_len >> 2);
         for (int idx = 0; idx < count; idx++) {
+          min_len += 4;
+          RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD,
+                                 (p_msg->browse_len >= min_len),
+                                 "msg too short");
+
           BE_STREAM_TO_UINT32(p_result->get_items.p_attr_list[idx], p);
         }
       }
       break;
 
     case AVRC_PDU_CHANGE_PATH: /* 0x72 */
+      min_len += 11;
+      RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, (p_msg->browse_len >= min_len),
+                             "msg too short");
+
       BE_STREAM_TO_UINT16(p_result->chg_path.uid_counter, p);
       BE_STREAM_TO_UINT8(p_result->chg_path.direction, p);
       if (p_result->chg_path.direction != AVRC_DIR_UP &&
@@ -476,7 +504,12 @@
       break;
 
     case AVRC_PDU_GET_ITEM_ATTRIBUTES: /* 0x73 */
+      min_len += 12;
+      RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, (p_msg->browse_len >= min_len),
+                             "msg too short");
+
       BE_STREAM_TO_UINT8(p_result->get_attrs.scope, p);
+
       if (p_result->get_attrs.scope > AVRC_SCOPE_NOW_PLAYING) {
         status = AVRC_STS_BAD_SCOPE;
         break;
@@ -492,6 +525,11 @@
           p_result->get_attrs.attr_count = count = (buf_len >> 2);
         for (int idx = 0, count = 0; idx < p_result->get_attrs.attr_count;
              idx++) {
+          min_len += 4;
+          RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD,
+                                 (p_msg->browse_len >= min_len),
+                                 "msg too short");
+
           BE_STREAM_TO_UINT32(p_result->get_attrs.p_attr_list[count], p);
           if (AVRC_IS_VALID_MEDIA_ATTRIBUTE(
                   p_result->get_attrs.p_attr_list[count])) {
@@ -507,6 +545,10 @@
       break;
 
     case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS: /* 0x75 */
+      ++min_len;
+      RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, (p_msg->browse_len >= min_len),
+                             "msg too short");
+
       BE_STREAM_TO_UINT8(p_result->get_num_of_items.scope, p);
       if (p_result->get_num_of_items.scope > AVRC_SCOPE_NOW_PLAYING) {
         status = AVRC_STS_BAD_SCOPE;
@@ -514,6 +556,10 @@
       break;
 
     case AVRC_PDU_SEARCH: /* 0x80 */
+      min_len += 4;
+      RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, (p_msg->browse_len >= min_len),
+                             "msg too short");
+
       BE_STREAM_TO_UINT16(p_result->search.string.charset_id, p);
       BE_STREAM_TO_UINT16(p_result->search.string.str_len, p);
       p_result->search.string.p_str = p_buf;
@@ -523,6 +569,10 @@
         } else {
           android_errorWriteLog(0x534e4554, "63146237");
         }
+        min_len += p_result->search.string.str_len;
+        RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, (p_msg->browse_len >= min_len),
+                               "msg too short");
+
         BE_STREAM_TO_ARRAY(p, p_buf, p_result->search.string.str_len);
       } else {
         status = AVRC_STS_INTERNAL_ERR;
diff --git a/stack/btm/btm_acl.cc b/stack/btm/btm_acl.cc
index 090a0aa..55772e6 100644
--- a/stack/btm/btm_acl.cc
+++ b/stack/btm/btm_acl.cc
@@ -825,7 +825,8 @@
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda);
 
   /* If there are any preferred connection parameters, set them now */
-  if ((p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN) &&
+  if ((p_lcb != NULL) && (p_dev_rec != NULL) &&
+      (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN) &&
       (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX) &&
       (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN) &&
       (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX) &&
diff --git a/stack/btm/btm_ble_batchscan.cc b/stack/btm/btm_ble_batchscan.cc
index 89b3e6c..db82829 100644
--- a/stack/btm/btm_ble_batchscan.cc
+++ b/stack/btm/btm_ble_batchscan.cc
@@ -63,6 +63,7 @@
 
   uint8_t sub_event = 0;
   tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
+  if (len == 0) return;
   STREAM_TO_UINT8(sub_event, p);
 
   BTM_TRACE_EVENT(
@@ -90,6 +91,7 @@
 
       /* Extract the adv info details */
       if (ADV_INFO_PRESENT == adv_data.advertiser_info_present) {
+        if (len < 15) return;
         STREAM_TO_UINT8(adv_data.tx_power, p);
         STREAM_TO_UINT8(adv_data.rssi_value, p);
         STREAM_TO_UINT16(adv_data.time_stamp, p);
diff --git a/stack/btm/btm_ble_bgconn.cc b/stack/btm/btm_ble_bgconn.cc
index 73256c8..209f49f 100644
--- a/stack/btm/btm_ble_bgconn.cc
+++ b/stack/btm/btm_ble_bgconn.cc
@@ -39,6 +39,7 @@
     uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
     uint8_t phy);
 extern void btm_ble_create_conn_cancel();
+void wl_remove_complete(uint8_t* p_data, uint16_t /* evt_len */);
 
 // Unfortunately (for now?) we have to maintain a copy of the device whitelist
 // on the host to determine if a device is pending to be connected or not. This
@@ -72,7 +73,14 @@
         BackgroundConnection{address, addr_type, false, 0, false};
   } else {
     BackgroundConnection* connection = &map_iter->second;
-    connection->addr_type = addr_type;
+    if (addr_type != connection->addr_type) {
+      LOG(INFO) << __func__ << " Addr type mismatch " << address;
+      btsnd_hcic_ble_remove_from_white_list(
+        connection->addr_type_in_wl, connection->address,
+        base::Bind(&wl_remove_complete));
+      connection->addr_type = addr_type;
+      connection->in_controller_wl = false;
+    }
     connection->pending_removal = false;
   }
 }
@@ -170,8 +178,7 @@
     return true;
 
   // bonded device with identity address known
-  if (p_dev_rec->ble.identity_addr != address &&
-      !p_dev_rec->ble.identity_addr.IsEmpty()) {
+  if (!p_dev_rec->ble.identity_addr.IsEmpty()) {
     return true;
   }
 
@@ -197,8 +204,7 @@
 
   if (p_dev_rec != NULL && p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) {
     if (to_add) {
-      if (p_dev_rec->ble.identity_addr != bd_addr &&
-          !p_dev_rec->ble.identity_addr.IsEmpty()) {
+      if (!p_dev_rec->ble.identity_addr.IsEmpty()) {
         background_connection_add(p_dev_rec->ble.identity_addr_type,
                                   p_dev_rec->ble.identity_addr);
       } else {
@@ -212,8 +218,7 @@
 
       p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT;
     } else {
-      if (!p_dev_rec->ble.identity_addr.IsEmpty() &&
-          p_dev_rec->ble.identity_addr != bd_addr) {
+      if (!p_dev_rec->ble.identity_addr.IsEmpty()) {
         background_connection_remove(p_dev_rec->ble.identity_addr);
       } else {
         background_connection_remove(bd_addr);
diff --git a/stack/btm/btm_ble_connection_establishment.cc b/stack/btm/btm_ble_connection_establishment.cc
index c0d7791..77bc00f 100644
--- a/stack/btm/btm_ble_connection_establishment.cc
+++ b/stack/btm/btm_ble_connection_establishment.cc
@@ -159,6 +159,7 @@
         if (!btm_ble_init_pseudo_addr(match_rec, bda)) {
           /* assign the original address to be the current report address */
           bda = match_rec->ble.pseudo_addr;
+          bda_type = match_rec->ble.ble_addr_type;
         } else {
           bda = match_rec->bd_addr;
         }
diff --git a/stack/btm/btm_ble_gap.cc b/stack/btm/btm_ble_gap.cc
index c46acf0..7f94bb8 100644
--- a/stack/btm/btm_ble_gap.cc
+++ b/stack/btm/btm_ble_gap.cc
@@ -498,7 +498,7 @@
     BTM_TRACE_DEBUG("%s: Status = 0x%02x (0 is success)", __func__, status);
     return;
   }
-  CHECK(p_vcs_cplt_params->param_len > BTM_VSC_CHIP_CAPABILITY_RSP_LEN);
+  CHECK(p_vcs_cplt_params->param_len >= BTM_VSC_CHIP_CAPABILITY_RSP_LEN);
   STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.adv_inst_max, p);
   STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.rpa_offloading, p);
   STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg, p);
@@ -1755,6 +1755,7 @@
       } else {
         // Assign the original address to be the current report address
         bda = match_rec->ble.pseudo_addr;
+        *addr_type = match_rec->ble.ble_addr_type;
       }
     }
   }
diff --git a/stack/btm/btm_ble_multi_adv.cc b/stack/btm/btm_ble_multi_adv.cc
index 22d2e17..b425c09 100644
--- a/stack/btm/btm_ble_multi_adv.cc
+++ b/stack/btm/btm_ble_multi_adv.cc
@@ -728,16 +728,13 @@
       data.insert(data.begin(), flags.begin(), flags.end());
     }
 
-    // Find and fill TX Power with the correct value
-    if (data.size()) {
-      size_t i = 0;
-      while (i < data.size()) {
-        uint8_t type = data[i + 1];
-        if (type == HCI_EIR_TX_POWER_LEVEL_TYPE) {
-          data[i + 2] = adv_inst[inst_id].tx_power;
-        }
-        i += data[i] + 1;
+    // Find and fill TX Power with the correct value.
+    // The TX Power section is a 3 byte section.
+    for (size_t i = 0; (i + 2) < data.size();) {
+      if (data[i + 1] == HCI_EIR_TX_POWER_LEVEL_TYPE) {
+        data[i + 2] = adv_inst[inst_id].tx_power;
       }
+      i += data[i] + 1;
     }
 
     VLOG(1) << "data is: " << base::HexEncode(data.data(), data.size());
diff --git a/stack/btm/btm_inq.cc b/stack/btm/btm_inq.cc
index 1a5d7f5..f56369b 100644
--- a/stack/btm/btm_inq.cc
+++ b/stack/btm/btm_inq.cc
@@ -25,6 +25,7 @@
  *
  ******************************************************************************/
 
+#include <log/log.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -914,10 +915,9 @@
   /* Make sure there is not already one in progress */
   if (p_inq->remname_active) {
     if (BTM_UseLeLink(p_inq->remname_bda)) {
-      if (btm_ble_cancel_remote_name(p_inq->remname_bda))
-        return (BTM_CMD_STARTED);
-      else
-        return (BTM_UNKNOWN_ADDR);
+      /* Cancel remote name request for LE device, and process remote name
+       * callback. */
+      btm_inq_rmt_name_failed_cancelled();
     } else
       btsnd_hcic_rmt_name_req_cancel(p_inq->remname_bda);
     return (BTM_CMD_STARTED);
@@ -1602,7 +1602,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_process_inq_results(uint8_t* p, uint8_t inq_res_mode) {
+void btm_process_inq_results(uint8_t* p, uint8_t hci_evt_len,
+                             uint8_t inq_res_mode) {
   uint8_t num_resp, xx;
   RawAddress bda;
   tINQ_DB_ENT* p_i;
@@ -1631,10 +1632,29 @@
 
   STREAM_TO_UINT8(num_resp, p);
 
-  if (inq_res_mode == BTM_INQ_RESULT_EXTENDED && (num_resp > 1)) {
-    BTM_TRACE_ERROR("btm_process_inq_results() extended results (%d) > 1",
-                    num_resp);
-    return;
+  if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
+    if (num_resp > 1) {
+      BTM_TRACE_ERROR("btm_process_inq_results() extended results (%d) > 1",
+                      num_resp);
+      return;
+    }
+
+    constexpr uint16_t extended_inquiry_result_size = 254;
+    if (hci_evt_len - 1 != extended_inquiry_result_size) {
+      android_errorWriteLog(0x534e4554, "141620271");
+      BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
+                      num_resp, hci_evt_len);
+      return;
+    }
+  } else if (inq_res_mode == BTM_INQ_RESULT_STANDARD ||
+             inq_res_mode == BTM_INQ_RESULT_WITH_RSSI) {
+    constexpr uint16_t inquiry_result_size = 14;
+    if (hci_evt_len < num_resp * inquiry_result_size) {
+      android_errorWriteLog(0x534e4554, "141620271");
+      BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
+                      num_resp, hci_evt_len);
+      return;
+    }
   }
 
   for (xx = 0; xx < num_resp; xx++) {
@@ -2070,22 +2090,22 @@
 }
 
 void btm_inq_remote_name_timer_timeout(UNUSED_ATTR void* data) {
-  btm_inq_rmt_name_failed();
+  btm_inq_rmt_name_failed_cancelled();
 }
 
 /*******************************************************************************
  *
- * Function         btm_inq_rmt_name_failed
+ * Function         btm_inq_rmt_name_failed_cancelled
  *
- * Description      This function is if timeout expires while getting remote
- *                  name.  This is done for devices that incorrectly do not
- *                  report operation failure
+ * Description      This function is if timeout expires or request is cancelled
+ *                  while getting remote name.  This is done for devices that
+ *                  incorrectly do not report operation failure
  *
  * Returns          void
  *
  ******************************************************************************/
-void btm_inq_rmt_name_failed(void) {
-  BTM_TRACE_ERROR("btm_inq_rmt_name_failed()  remname_active=%d",
+void btm_inq_rmt_name_failed_cancelled(void) {
+  BTM_TRACE_ERROR("btm_inq_rmt_name_failed_cancelled()  remname_active=%d",
                   btm_cb.btm_inq_vars.remname_active);
 
   if (btm_cb.btm_inq_vars.remname_active)
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index ee1d655..05180db 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -59,13 +59,14 @@
 
 extern void btm_process_remote_name(const RawAddress* bda, BD_NAME name,
                                     uint16_t evt_len, uint8_t hci_status);
-extern void btm_inq_rmt_name_failed(void);
+extern void btm_inq_rmt_name_failed_cancelled(void);
 extern void btm_inq_remote_name_timer_timeout(void* data);
 
 /* Inquiry related functions */
 extern void btm_clr_inq_db(const RawAddress* p_bda);
 extern void btm_inq_db_init(void);
-extern void btm_process_inq_results(uint8_t* p, uint8_t inq_res_mode);
+extern void btm_process_inq_results(uint8_t* p, uint8_t hci_evt_len,
+                                    uint8_t inq_res_mode);
 extern void btm_process_inq_complete(uint8_t status, uint8_t mode);
 extern void btm_process_cancel_complete(uint8_t status, uint8_t mode);
 extern void btm_event_filter_complete(uint8_t* p);
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 1c1cead..277e01d 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -4313,12 +4313,15 @@
       }
     }
 
-    if (!addr_matched) {
-      /* Don't callback unless this Connection-Complete-failure event has the
-       * same mac address as the bonding device */
+    /* p_auth_complete_callback might have freed the p_dev_rec, ensure it exists
+     * before accessing */
+    p_dev_rec = btm_find_dev(bda);
+    if (!p_dev_rec) {
+      /* Don't callback when device security record was removed */
       VLOG(1) << __func__
-              << ": Different mac addresses: pairing_bda=" << btm_cb.pairing_bda
-              << ", bda=" << bda << ", do not callback";
+              << ": device security record associated with this bda has been "
+                 "removed! bda="
+              << bda << ", do not callback!";
       return;
     }
 
diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc
index c70448e..52d5d60 100644
--- a/stack/btu/btu_hcif.cc
+++ b/stack/btu/btu_hcif.cc
@@ -48,6 +48,7 @@
 #include "btu.h"
 #include "common/metrics.h"
 #include "device/include/controller.h"
+#include "hci_evt_length.h"
 #include "hci_layer.h"
 #include "hcimsgs.h"
 #include "l2c_int.h"
@@ -64,11 +65,12 @@
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
 static void btu_hcif_inquiry_comp_evt(uint8_t* p);
-static void btu_hcif_inquiry_result_evt(uint8_t* p);
-static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p);
-static void btu_hcif_extended_inquiry_result_evt(uint8_t* p);
+static void btu_hcif_inquiry_result_evt(uint8_t* p, uint8_t hci_evt_len);
+static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p, uint8_t hci_evt_len);
+static void btu_hcif_extended_inquiry_result_evt(uint8_t* p,
+                                                 uint8_t hci_evt_len);
 
-static void btu_hcif_connection_comp_evt(uint8_t* p);
+static void btu_hcif_connection_comp_evt(uint8_t* p, uint8_t evt_len);
 static void btu_hcif_connection_request_evt(uint8_t* p);
 static void btu_hcif_disconnection_comp_evt(uint8_t* p);
 static void btu_hcif_authentication_comp_evt(uint8_t* p);
@@ -85,7 +87,7 @@
 static void btu_hcif_hardware_error_evt(uint8_t* p);
 static void btu_hcif_flush_occured_evt(void);
 static void btu_hcif_role_change_evt(uint8_t* p);
-static void btu_hcif_num_compl_data_pkts_evt(uint8_t* p);
+static void btu_hcif_num_compl_data_pkts_evt(uint8_t* p, uint8_t evt_len);
 static void btu_hcif_mode_change_evt(uint8_t* p);
 static void btu_hcif_pin_code_request_evt(uint8_t* p);
 static void btu_hcif_link_key_request_evt(uint8_t* p);
@@ -256,6 +258,13 @@
   STREAM_TO_UINT8(hci_evt_code, p);
   STREAM_TO_UINT8(hci_evt_len, p);
 
+  // validate event size
+  if (hci_evt_len < hci_event_parameters_minimum_length[hci_evt_code]) {
+    HCI_TRACE_WARNING("%s: evt:0x%2X, malformed event of size %hhd", __func__,
+                      hci_evt_code, hci_evt_len);
+    return;
+  }
+
   btu_hcif_log_event_metrics(hci_evt_code, p);
 
   switch (hci_evt_code) {
@@ -263,16 +272,16 @@
       btu_hcif_inquiry_comp_evt(p);
       break;
     case HCI_INQUIRY_RESULT_EVT:
-      btu_hcif_inquiry_result_evt(p);
+      btu_hcif_inquiry_result_evt(p, hci_evt_len);
       break;
     case HCI_INQUIRY_RSSI_RESULT_EVT:
-      btu_hcif_inquiry_rssi_result_evt(p);
+      btu_hcif_inquiry_rssi_result_evt(p, hci_evt_len);
       break;
     case HCI_EXTENDED_INQUIRY_RESULT_EVT:
-      btu_hcif_extended_inquiry_result_evt(p);
+      btu_hcif_extended_inquiry_result_evt(p, hci_evt_len);
       break;
     case HCI_CONNECTION_COMP_EVT:
-      btu_hcif_connection_comp_evt(p);
+      btu_hcif_connection_comp_evt(p, hci_evt_len);
       break;
     case HCI_CONNECTION_REQUEST_EVT:
       btu_hcif_connection_request_evt(p);
@@ -326,7 +335,7 @@
       btu_hcif_role_change_evt(p);
       break;
     case HCI_NUM_COMPL_DATA_PKTS_EVT:
-      btu_hcif_num_compl_data_pkts_evt(p);
+      btu_hcif_num_compl_data_pkts_evt(p, hci_evt_len);
       break;
     case HCI_MODE_CHANGE_EVT:
       btu_hcif_mode_change_evt(p);
@@ -948,9 +957,9 @@
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_inquiry_result_evt(uint8_t* p) {
+static void btu_hcif_inquiry_result_evt(uint8_t* p, uint8_t hci_evt_len) {
   /* Store results in the cache */
-  btm_process_inq_results(p, BTM_INQ_RESULT_STANDARD);
+  btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_STANDARD);
 }
 
 /*******************************************************************************
@@ -962,9 +971,9 @@
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p) {
+static void btu_hcif_inquiry_rssi_result_evt(uint8_t* p, uint8_t hci_evt_len) {
   /* Store results in the cache */
-  btm_process_inq_results(p, BTM_INQ_RESULT_WITH_RSSI);
+  btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_WITH_RSSI);
 }
 
 /*******************************************************************************
@@ -976,9 +985,10 @@
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_extended_inquiry_result_evt(uint8_t* p) {
+static void btu_hcif_extended_inquiry_result_evt(uint8_t* p,
+                                                 uint8_t hci_evt_len) {
   /* Store results in the cache */
-  btm_process_inq_results(p, BTM_INQ_RESULT_EXTENDED);
+  btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_EXTENDED);
 }
 
 /*******************************************************************************
@@ -990,7 +1000,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_connection_comp_evt(uint8_t* p) {
+static void btu_hcif_connection_comp_evt(uint8_t* p, uint8_t evt_len) {
   uint8_t status;
   uint16_t handle;
   RawAddress bda;
@@ -998,6 +1008,12 @@
   uint8_t enc_mode;
   tBTM_ESCO_DATA esco_data;
 
+  if (evt_len < 11) {
+    android_errorWriteLog(0x534e4554, "141619686");
+    HCI_TRACE_WARNING("%s: malformed event of size %hhd", __func__, evt_len);
+    return;
+  }
+
   STREAM_TO_UINT8(status, p);
   STREAM_TO_UINT16(handle, p);
   STREAM_TO_BDADDR(bda, p);
@@ -1699,9 +1715,9 @@
  * Returns          void
  *
  ******************************************************************************/
-static void btu_hcif_num_compl_data_pkts_evt(uint8_t* p) {
+static void btu_hcif_num_compl_data_pkts_evt(uint8_t* p, uint8_t evt_len) {
   /* Process for L2CAP and SCO */
-  l2c_link_process_num_completed_pkts(p);
+  l2c_link_process_num_completed_pkts(p, evt_len);
 
   /* Send on to SCO */
   /*?? No SCO for now */
diff --git a/stack/gatt/gatt_main.cc b/stack/gatt/gatt_main.cc
index 87f9c87..ed8d3fd 100644
--- a/stack/gatt/gatt_main.cc
+++ b/stack/gatt/gatt_main.cc
@@ -823,6 +823,9 @@
     }
   }
 
+  /* Remove the direct connection */
+  connection_manager::on_connection_complete(p_tcb->peer_bda);
+
   if (!p_tcb->app_hold_link.empty() && p_tcb->att_lcid == L2CAP_ATT_CID) {
     /* disable idle timeout if one or more clients are holding the link disable
      * the idle timer */
diff --git a/stack/include/hci_evt_length.h b/stack/include/hci_evt_length.h
new file mode 100644
index 0000000..ea8dfdf
--- /dev/null
+++ b/stack/include/hci_evt_length.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * 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.
+ */
+
+/*
+ *  Definitions for HCI Event Parameter Minimum Length
+ */
+static const uint8_t hci_event_parameters_minimum_length[] = {
+    0,    //  0x00 - N/A
+    1,    //  0x01 - HCI_Inquiry_Complete Event
+    15,   //  0x02 - HCI_Inquiry_Result Event (Num_Responses = 1)
+    11,   //  0x03 - HCI_Connection_Complete Event
+    10,   //  0x04 - HCI_Connection_Request Event
+    4,    //  0x05 - HCI_Disconnection_Complete Event
+    3,    //  0x06 - HCI_Authentication_Complete Event
+    255,  //  0x07 - HCI_Remote_Name_Request_Complete Event
+    4,    //  0x08 - HCI_Encryption_Change Event
+    3,    //  0x09 - HCI_Change_Connection_Link_Key_Complete Event
+    4,    //  0x0A - HCI_Master_Link_Key_Complete Event
+    11,   //  0x0B - HCI_Read_Remote_Supported_Features_Complete Event
+    8,    //  0x0C - HCI_Read_Remote_Version_Information_Complete Event
+    21,   //  0x0D - HCI_QoS_Setup_Complete Event
+    3,    //  0x0E - HCI_Command_Complete Event (Depends on command)
+    4,    //  0x0F - HCI_Command_Status Event
+    1,    //  0x10 - HCI_Hardware_Error Event
+    2,    //  0x11 - HCI_Flush_Occurred Event
+    8,    //  0x12 - HCI_Role_Change Event
+    5,    //  0x13 - HCI_Number_Of_Completed_Packets Event (Num_Handles = 1)
+    6,    //  0x14 - HCI_Mode_Change Event
+    23,   //  0x15 - HCI_Return_Link_Keys Event (Num_Keys = 1)
+    6,    //  0x16 - HCI_PIN_Code_Request Event
+    6,    //  0x17 - HCI_Link_Key_Request Event
+    23,   //  0x18 - HCI_Link_Key_Notification Event
+    3,    //  0x19 - HCI_Loopback_Command Event (Depends on command)
+    1,    //  0x1A - HCI_Data_Buffer_Overflow Event
+    3,    //  0x1B - HCI_Max_Slots_Change Event
+    5,    //  0x1C - HCI_Read_Clock_Offset_Complete Event
+    5,    //  0x1D - HCI_Connection_Packet_Type_Changed Event
+    2,    //  0x1E - HCI_QoS_Violation Event
+    7,    //  0x1F - HCI_Page_Scan_Mode_Change Event (Deprecated)
+    7,    //  0x20 - HCI_Page_Scan_Repetition_Mode_Change Event
+    22,   //  0x21 - HCI_Flow_Specification_Complet Event
+    15,   //  0x22 - HCI_Inquiry_Result_with_RSSI Event (Num_Responses = 1)
+    13,   //  0x23 - HCI_Read_Remote_Extended_Features_Complete Event
+    0,    //  0x24 - N/A
+    0,    //  0x25 - N/A
+    0,    //  0x26 - N/A
+    0,    //  0x27 - N/A
+    0,    //  0x28 - N/A
+    0,    //  0x29 - N/A
+    0,    //  0x2A - N/A
+    0,    //  0x2B - N/A
+    17,   //  0x2C - HCI_Synchronous_Connection_Complete Event
+    9,    //  0x2D - HCI_Synchronous_Connection_Changed Event
+    11,   //  0x2E - HCI_Sniff_Subrating Event
+    255,  //  0x2F - HCI_Extended_Inquiry_Result Event
+    3,    //  0x30 - HCI_Encryption_Key_Refresh_Complete Event
+    6,    //  0x31 - HCI_IO_Capability_Request Event
+    9,    //  0x32 - HCI_IO_Capability_Response Event
+    10,   //  0x33 - HCI_User_Confirmation_Request Event
+    6,    //  0x34 - HCI_User_Passkey_Request Event
+    6,    //  0x35 - HCI_Remote_OOB_Data_Request Event
+    7,    //  0x36 - HCI_Simple_Pairing_Complete Event
+    0,    //  0x37 - N/A
+    4,    //  0x38 - HCI_Link_Supervision_Timeout_Changed Event
+    2,    //  0x39 - HCI_Enhanced_Flush_Complete Event
+    0,    //  0x3A - N/A
+    10,   //  0x3B - HCI_User_Passkey_Notification Event
+    7,    //  0x3C - HCI_Keypress_Notification Event
+    14,   //  0x3D - HCI_Remote_Host_Supported_Features_Notification Event
+    0,    //  0x3E - LE Meta event
+    0,    //  0x3F - N/A
+    2,    //  0x40 - HCI_Physical_Link_Complete Event
+    1,    //  0x41 - HCI_Channel_Selected Event
+    3,    //  0x42 - HCI_Disconnection_Physical_Link_Complete Event
+    2,    //  0x43 - HCI_Physical_Link_Loss_Early_Warning Event
+    1,    //  0x44 - HCI_Physical_Link_Recovery Event
+    5,    //  0x45 - HCI_Logical_Link_Complete Event
+    4,    //  0x46 - HCI_Disconnection_Logical_Link_Complete Event
+    3,    //  0x47 - HCI_Flow_Spec_Modify_Complete Event
+    9,    //  0x48 - HCI_Number_Of_Completed_Data_Blocks Event (Num_Handles = 1)
+    2,    //  0x49 - HCI_AMP_Start_Test Event
+    2,    //  0x4A - HCI_AMP_Test_End Event
+    18,   //  0x4B - HCI_AMP_Receiver_Report Event
+    3,    //  0x4C - HCI_Short_Range_Mode_Change_Complete Event
+    2,    //  0x4D - HCI_AMP_Status_Change Event
+    9,    //  0x4E - HCI_Triggered_Clock_Capture Event
+    1,    //  0x4F - HCI_Synchronization_Train_Complete Event
+    29,   //  0x50 - HCI_Synchronization_Train_Received Event
+    18,   //  0x51 - HCI_Connectionless_Slave_Broadcast_Receive Event
+          //  (Data_Length = 0)
+    7,    //  0x52 - HCI_Connectionless_Slave_Broadcast_Timeout Event
+    7,    //  0x53 - HCI_Truncated_Page_Complete Event
+    0,    //  0x54 - HCI_Slave_Page_Response_Timeout Event
+    10,   //  0x55 - HCI_Connectionless_Slave_Broadcast_Channel_Map_Change Event
+    4,    //  0x56 - HCI_Inquiry_Response_Notification Event
+    2,    //  0x57 - HCI_Authenticated_Payload_Timeout_Expired Event
+    8,    //  0x58 - HCI_SAM_Status_Change Event
+    0,    //  0x59 - N/A
+    0,    //  0x5A - N/A
+    0,    //  0x5B - N/A
+    0,    //  0x5C - N/A
+    0,    //  0x5D - N/A
+    0,    //  0x5E - N/A
+    0,    //  0x5F - N/A
+    0,    //  0x60 - N/A
+    0,    //  0x61 - N/A
+    0,    //  0x62 - N/A
+    0,    //  0x63 - N/A
+    0,    //  0x64 - N/A
+    0,    //  0x65 - N/A
+    0,    //  0x66 - N/A
+    0,    //  0x67 - N/A
+    0,    //  0x68 - N/A
+    0,    //  0x69 - N/A
+    0,    //  0x6A - N/A
+    0,    //  0x6B - N/A
+    0,    //  0x6C - N/A
+    0,    //  0x6D - N/A
+    0,    //  0x6E - N/A
+    0,    //  0x6F - N/A
+    0,    //  0x70 - N/A
+    0,    //  0x71 - N/A
+    0,    //  0x72 - N/A
+    0,    //  0x73 - N/A
+    0,    //  0x74 - N/A
+    0,    //  0x75 - N/A
+    0,    //  0x76 - N/A
+    0,    //  0x77 - N/A
+    0,    //  0x78 - N/A
+    0,    //  0x79 - N/A
+    0,    //  0x7A - N/A
+    0,    //  0x7B - N/A
+    0,    //  0x7C - N/A
+    0,    //  0x7D - N/A
+    0,    //  0x7E - N/A
+    0,    //  0x7F - N/A
+    0,    //  0x80 - N/A
+    0,    //  0x81 - N/A
+    0,    //  0x82 - N/A
+    0,    //  0x83 - N/A
+    0,    //  0x84 - N/A
+    0,    //  0x85 - N/A
+    0,    //  0x86 - N/A
+    0,    //  0x87 - N/A
+    0,    //  0x88 - N/A
+    0,    //  0x89 - N/A
+    0,    //  0x8A - N/A
+    0,    //  0x8B - N/A
+    0,    //  0x8C - N/A
+    0,    //  0x8D - N/A
+    0,    //  0x8E - N/A
+    0,    //  0x8F - N/A
+    0,    //  0x90 - N/A
+    0,    //  0x91 - N/A
+    0,    //  0x92 - N/A
+    0,    //  0x93 - N/A
+    0,    //  0x94 - N/A
+    0,    //  0x95 - N/A
+    0,    //  0x96 - N/A
+    0,    //  0x97 - N/A
+    0,    //  0x98 - N/A
+    0,    //  0x99 - N/A
+    0,    //  0x9A - N/A
+    0,    //  0x9B - N/A
+    0,    //  0x9C - N/A
+    0,    //  0x9D - N/A
+    0,    //  0x9E - N/A
+    0,    //  0x9F - N/A
+    0,    //  0xA0 - N/A
+    0,    //  0xA1 - N/A
+    0,    //  0xA2 - N/A
+    0,    //  0xA3 - N/A
+    0,    //  0xA4 - N/A
+    0,    //  0xA5 - N/A
+    0,    //  0xA6 - N/A
+    0,    //  0xA7 - N/A
+    0,    //  0xA8 - N/A
+    0,    //  0xA9 - N/A
+    0,    //  0xAA - N/A
+    0,    //  0xAB - N/A
+    0,    //  0xAC - N/A
+    0,    //  0xAD - N/A
+    0,    //  0xAE - N/A
+    0,    //  0xAF - N/A
+    0,    //  0xB0 - N/A
+    0,    //  0xB1 - N/A
+    0,    //  0xB2 - N/A
+    0,    //  0xB3 - N/A
+    0,    //  0xB4 - N/A
+    0,    //  0xB5 - N/A
+    0,    //  0xB6 - N/A
+    0,    //  0xB7 - N/A
+    0,    //  0xB8 - N/A
+    0,    //  0xB9 - N/A
+    0,    //  0xBA - N/A
+    0,    //  0xBB - N/A
+    0,    //  0xBC - N/A
+    0,    //  0xBD - N/A
+    0,    //  0xBE - N/A
+    0,    //  0xBF - N/A
+    0,    //  0xC0 - N/A
+    0,    //  0xC1 - N/A
+    0,    //  0xC2 - N/A
+    0,    //  0xC3 - N/A
+    0,    //  0xC4 - N/A
+    0,    //  0xC5 - N/A
+    0,    //  0xC6 - N/A
+    0,    //  0xC7 - N/A
+    0,    //  0xC8 - N/A
+    0,    //  0xC9 - N/A
+    0,    //  0xCA - N/A
+    0,    //  0xCB - N/A
+    0,    //  0xCC - N/A
+    0,    //  0xCD - N/A
+    0,    //  0xCE - N/A
+    0,    //  0xCF - N/A
+    0,    //  0xD0 - N/A
+    0,    //  0xD1 - N/A
+    0,    //  0xD2 - N/A
+    0,    //  0xD3 - N/A
+    0,    //  0xD4 - N/A
+    0,    //  0xD5 - N/A
+    0,    //  0xD6 - N/A
+    0,    //  0xD7 - N/A
+    0,    //  0xD8 - N/A
+    0,    //  0xD9 - N/A
+    0,    //  0xDA - N/A
+    0,    //  0xDB - N/A
+    0,    //  0xDC - N/A
+    0,    //  0xDD - N/A
+    0,    //  0xDE - N/A
+    0,    //  0xDF - N/A
+    0,    //  0xE0 - N/A
+    0,    //  0xE1 - N/A
+    0,    //  0xE2 - N/A
+    0,    //  0xE3 - N/A
+    0,    //  0xE4 - N/A
+    0,    //  0xE5 - N/A
+    0,    //  0xE6 - N/A
+    0,    //  0xE7 - N/A
+    0,    //  0xE8 - N/A
+    0,    //  0xE9 - N/A
+    0,    //  0xEA - N/A
+    0,    //  0xEB - N/A
+    0,    //  0xEC - N/A
+    0,    //  0xED - N/A
+    0,    //  0xEE - N/A
+    0,    //  0xEF - N/A
+    0,    //  0xF0 - N/A
+    0,    //  0xF1 - N/A
+    0,    //  0xF2 - N/A
+    0,    //  0xF3 - N/A
+    0,    //  0xF4 - N/A
+    0,    //  0xF5 - N/A
+    0,    //  0xF6 - N/A
+    0,    //  0xF7 - N/A
+    0,    //  0xF8 - N/A
+    0,    //  0xF9 - N/A
+    0,    //  0xFA - N/A
+    0,    //  0xFB - N/A
+    0,    //  0xFC - N/A
+    0,    //  0xFD - N/A
+    0,    //  0xFE - N/A
+    0,    //  0xFF - HCI_Vendor_Specific Event
+};
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index 53b6f32..e58efaf 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -713,7 +713,7 @@
 extern void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb,
                                      BT_HDR* p_buf);
 extern void l2c_link_adjust_allocation(void);
-extern void l2c_link_process_num_completed_pkts(uint8_t* p);
+extern void l2c_link_process_num_completed_pkts(uint8_t* p, uint8_t evt_len);
 extern void l2c_link_process_num_completed_blocks(uint8_t controller_id,
                                                   uint8_t* p, uint16_t evt_len);
 extern void l2c_link_processs_num_bufs(uint16_t num_lm_acl_bufs);
diff --git a/stack/l2cap/l2c_link.cc b/stack/l2cap/l2c_link.cc
index 8e04c6e..958425d 100644
--- a/stack/l2cap/l2c_link.cc
+++ b/stack/l2cap/l2c_link.cc
@@ -40,6 +40,7 @@
 #include "l2c_api.h"
 #include "l2c_int.h"
 #include "l2cdefs.h"
+#include "log/log.h"
 #include "osi/include/osi.h"
 
 static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
@@ -675,6 +676,8 @@
   uint16_t num_hipri_links = 0;
   uint16_t controller_xmit_quota = l2cb.num_lm_acl_bufs;
   uint16_t high_pri_link_quota = L2CAP_HIGH_PRI_MIN_XMIT_QUOTA_A;
+  bool is_share_buffer =
+      (l2cb.num_lm_ble_bufs == L2C_DEF_NUM_BLE_BUF_SHARED) ? true : false;
 
   /* If no links active, reset buffer quotas and controller buffers */
   if (l2cb.num_links_active == 0) {
@@ -685,7 +688,8 @@
 
   /* First, count the links */
   for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
-    if (p_lcb->in_use) {
+    if (p_lcb->in_use &&
+        (is_share_buffer || p_lcb->transport != BT_TRANSPORT_LE)) {
       if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)
         num_hipri_links++;
       else
@@ -732,7 +736,8 @@
 
   /* Now, assign the quotas to each link */
   for (yy = 0, p_lcb = &l2cb.lcb_pool[0]; yy < MAX_L2CAP_LINKS; yy++, p_lcb++) {
-    if (p_lcb->in_use) {
+    if (p_lcb->in_use &&
+        (is_share_buffer || p_lcb->transport != BT_TRANSPORT_LE)) {
       if (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH) {
         p_lcb->link_xmit_quota = high_pri_link_quota;
       } else {
@@ -1210,13 +1215,22 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2c_link_process_num_completed_pkts(uint8_t* p) {
+void l2c_link_process_num_completed_pkts(uint8_t* p, uint8_t evt_len) {
   uint8_t num_handles, xx;
   uint16_t handle;
   uint16_t num_sent;
   tL2C_LCB* p_lcb;
 
-  STREAM_TO_UINT8(num_handles, p);
+  if (evt_len > 0) {
+    STREAM_TO_UINT8(num_handles, p);
+  } else {
+    num_handles = 0;
+  }
+
+  if (num_handles > evt_len / (2 * sizeof(uint16_t))) {
+    android_errorWriteLog(0x534e4554, "141617601");
+    num_handles = evt_len / (2 * sizeof(uint16_t));
+  }
 
   for (xx = 0; xx < num_handles; xx++) {
     STREAM_TO_UINT16(handle, p);
diff --git a/stack/l2cap/l2c_main.cc b/stack/l2cap/l2c_main.cc
index 128f60e..52d77c5 100644
--- a/stack/l2cap/l2c_main.cc
+++ b/stack/l2cap/l2c_main.cc
@@ -97,6 +97,11 @@
     /* There is a slight possibility (specifically with USB) that we get an */
     /* L2CAP connection request before we get the HCI connection complete.  */
     /* So for these types of messages, hold them for up to 2 seconds.       */
+    if (l2cap_len == 0) {
+      L2CAP_TRACE_WARNING("received empty L2CAP packet");
+      osi_free(p_msg);
+      return;
+    }
     uint8_t cmd_code;
     STREAM_TO_UINT8(cmd_code, p);