Merge "Fix the test case HCT  BV-01-C"
am: e28586ea5b

Change-Id: I1289d8c4802f673bfff967fbd38050ae8fbbd9ed
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 7fb1636..380216c 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -4,3 +4,6 @@
 [Builtin Hooks]
 clang_format = true
 
+[Hook Scripts]
+aosp_first = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} ".*$"
+
diff --git a/binder/Android.bp b/binder/Android.bp
index e1f1592..e4beadb 100644
--- a/binder/Android.bp
+++ b/binder/Android.bp
@@ -75,6 +75,9 @@
         "-Wextra",
         "-Wno-unused-parameter",
     ],
+    sanitize: {
+        scs: true,
+    },
 }
 
 // AIDL interface between libbluetooth-binder and framework.jar
diff --git a/bta/ag/bta_ag_cmd.cc b/bta/ag/bta_ag_cmd.cc
index bec5497..87b2a82 100644
--- a/bta/ag/bta_ag_cmd.cc
+++ b/bta/ag/bta_ag_cmd.cc
@@ -782,9 +782,11 @@
  ******************************************************************************/
 static bool bta_ag_parse_biev_response(tBTA_AG_SCB* p_scb, tBTA_AG_VAL* val) {
   char* p_token = strtok(val->str, ",");
+  if (p_token == nullptr) return false;
   uint16_t rcv_ind_id = atoi(p_token);
 
   p_token = strtok(nullptr, ",");
+  if (p_token == nullptr) return false;
   uint16_t rcv_ind_val = atoi(p_token);
 
   APPL_TRACE_DEBUG("%s BIEV indicator id %d, value %d", __func__, rcv_ind_id,
diff --git a/bta/av/bta_av_aact.cc b/bta/av/bta_av_aact.cc
index aa4a1e4..c695c7f 100644
--- a/bta/av/bta_av_aact.cc
+++ b/bta/av/bta_av_aact.cc
@@ -965,7 +965,7 @@
  *
  ******************************************************************************/
 void bta_av_config_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
-  tBTA_AV_CI_SETCONFIG setconfig;
+  tBTA_AV_CI_SETCONFIG setconfig{};
   tAVDT_SEP_INFO* p_info;
   const AvdtpSepConfig* p_evt_cfg = &p_data->str_msg.cfg;
   uint8_t psc_mask = (p_evt_cfg->psc_mask | p_scb->cfg.psc_mask);
diff --git a/bta/gatt/bta_gattc_api.cc b/bta/gatt/bta_gattc_api.cc
index 9b0bd9e..829084c 100644
--- a/bta/gatt/bta_gattc_api.cc
+++ b/bta/gatt/bta_gattc_api.cc
@@ -269,7 +269,7 @@
  * Returns          returns list of gatt::Service or NULL.
  *
  ******************************************************************************/
-const std::vector<gatt::Service>* BTA_GATTC_GetServices(uint16_t conn_id) {
+const std::list<gatt::Service>* BTA_GATTC_GetServices(uint16_t conn_id) {
   return bta_gattc_get_services(conn_id);
 }
 
diff --git a/bta/gatt/bta_gattc_cache.cc b/bta/gatt/bta_gattc_cache.cc
index 25b85ba..eed1d67 100644
--- a/bta/gatt/bta_gattc_cache.cc
+++ b/bta/gatt/bta_gattc_cache.cc
@@ -120,7 +120,7 @@
 }
 
 const Service* bta_gattc_find_matching_service(
-    const std::vector<Service>& services, uint16_t handle) {
+    const std::list<Service>& services, uint16_t handle) {
   for (const Service& service : services) {
     if (handle >= service.handle && handle <= service.end_handle)
       return &service;
@@ -419,14 +419,13 @@
   }
 }
 
-const std::vector<Service>* bta_gattc_get_services_srcb(
-    tBTA_GATTC_SERV* p_srcb) {
+const std::list<Service>* bta_gattc_get_services_srcb(tBTA_GATTC_SERV* p_srcb) {
   if (!p_srcb || p_srcb->gatt_database.IsEmpty()) return NULL;
 
   return &p_srcb->gatt_database.Services();
 }
 
-const std::vector<Service>* bta_gattc_get_services(uint16_t conn_id) {
+const std::list<Service>* bta_gattc_get_services(uint16_t conn_id) {
   tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
 
   if (p_clcb == NULL) return NULL;
@@ -438,14 +437,14 @@
 
 const Service* bta_gattc_get_service_for_handle_srcb(tBTA_GATTC_SERV* p_srcb,
                                                      uint16_t handle) {
-  const std::vector<Service>* services = bta_gattc_get_services_srcb(p_srcb);
+  const std::list<Service>* services = bta_gattc_get_services_srcb(p_srcb);
   if (services == NULL) return NULL;
   return bta_gattc_find_matching_service(*services, handle);
 }
 
 const Service* bta_gattc_get_service_for_handle(uint16_t conn_id,
                                                 uint16_t handle) {
-  const std::vector<Service>* services = bta_gattc_get_services(conn_id);
+  const std::list<Service>* services = bta_gattc_get_services(conn_id);
   if (services == NULL) return NULL;
 
   return bta_gattc_find_matching_service(*services, handle);
@@ -556,7 +555,7 @@
 /*******************************************************************************
  * Returns          number of elements inside db from start_handle to end_handle
  ******************************************************************************/
-static size_t bta_gattc_get_db_size(const std::vector<Service>& services,
+static size_t bta_gattc_get_db_size(const std::list<Service>& services,
                                     uint16_t start_handle,
                                     uint16_t end_handle) {
   if (services.empty()) return 0;
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
index 6ee962d..f0ead49 100644
--- a/bta/gatt/bta_gattc_int.h
+++ b/bta/gatt/bta_gattc_int.h
@@ -426,8 +426,7 @@
                                                    uint8_t disc_type);
 extern void bta_gattc_search_service(tBTA_GATTC_CLCB* p_clcb,
                                      bluetooth::Uuid* p_uuid);
-extern const std::vector<gatt::Service>* bta_gattc_get_services(
-    uint16_t conn_id);
+extern const std::list<gatt::Service>* bta_gattc_get_services(uint16_t conn_id);
 extern const gatt::Service* bta_gattc_get_service_for_handle(uint16_t conn_id,
                                                              uint16_t handle);
 const gatt::Characteristic* bta_gattc_get_characteristic_srcb(
diff --git a/bta/gatt/database.cc b/bta/gatt/database.cc
index 5f99d55..1486b08 100644
--- a/bta/gatt/database.cc
+++ b/bta/gatt/database.cc
@@ -21,6 +21,7 @@
 #include "stack/include/gattdefs.h"
 
 #include <base/logging.h>
+#include <list>
 #include <memory>
 #include <sstream>
 
@@ -39,7 +40,7 @@
 }
 }  // namespace
 
-Service* FindService(std::vector<Service>& services, uint16_t handle) {
+Service* FindService(std::list<Service>& services, uint16_t handle) {
   for (Service& service : services) {
     if (handle >= service.handle && handle <= service.end_handle)
       return &service;
@@ -182,4 +183,4 @@
   return result;
 }
 
-}  // namespace gatt
\ No newline at end of file
+}  // namespace gatt
diff --git a/bta/gatt/database.h b/bta/gatt/database.h
index 1e74809..d1ba836 100644
--- a/bta/gatt/database.h
+++ b/bta/gatt/database.h
@@ -18,6 +18,7 @@
 
 #pragma once
 
+#include <list>
 #include <set>
 #include <string>
 #include <utility>
@@ -101,10 +102,10 @@
 
   /* Clear the GATT database. This method forces relocation to ensure no extra
    * space is used unnecesarly */
-  void Clear() { std::vector<Service>().swap(services); }
+  void Clear() { std::list<Service>().swap(services); }
 
   /* Return list of services available in this database */
-  const std::vector<Service>& Services() const { return services; }
+  const std::list<Service>& Services() const { return services; }
 
   std::string ToString() const;
 
@@ -116,11 +117,11 @@
   friend class DatabaseBuilder;
 
  private:
-  std::vector<Service> services;
+  std::list<Service> services;
 };
 
 /* Find a service that should contain handle. Helper method for internal use
  * inside gatt namespace.*/
-Service* FindService(std::vector<Service>& services, uint16_t handle);
+Service* FindService(std::list<Service>& services, uint16_t handle);
 
 }  // namespace gatt
diff --git a/bta/gatt/database_builder.h b/bta/gatt/database_builder.h
index 0913100..d2cc720 100644
--- a/bta/gatt/database_builder.h
+++ b/bta/gatt/database_builder.h
@@ -21,7 +21,6 @@
 #include "gatt/database.h"
 
 #include <utility>
-#include <vector>
 
 namespace gatt {
 
diff --git a/bta/hearing_aid/hearing_aid.cc b/bta/hearing_aid/hearing_aid.cc
index 7463909..75116f4 100644
--- a/bta/hearing_aid/hearing_aid.cc
+++ b/bta/hearing_aid/hearing_aid.cc
@@ -623,7 +623,7 @@
       return;
     }
 
-    const std::vector<gatt::Service>* services = BTA_GATTC_GetServices(conn_id);
+    const std::list<gatt::Service>* services = BTA_GATTC_GetServices(conn_id);
 
     const gatt::Service* service = nullptr;
     for (const gatt::Service& tmp : *services) {
diff --git a/bta/hh/bta_hh_le.cc b/bta/hh/bta_hh_le.cc
index eb87cdf..510e3a4 100644
--- a/bta/hh/bta_hh_le.cc
+++ b/bta/hh/bta_hh_le.cc
@@ -1490,7 +1490,7 @@
     return;
   }
 
-  const std::vector<gatt::Service>* services =
+  const std::list<gatt::Service>* services =
       BTA_GATTC_GetServices(p_data->conn_id);
 
   bool have_hid = false;
diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h
index 9176501..41151f8 100644
--- a/bta/include/bta_gatt_api.h
+++ b/bta/include/bta_gatt_api.h
@@ -491,8 +491,7 @@
  * Returns          returns list of gatt::Service or NULL.
  *
  ******************************************************************************/
-extern const std::vector<gatt::Service>* BTA_GATTC_GetServices(
-    uint16_t conn_id);
+extern const std::list<gatt::Service>* BTA_GATTC_GetServices(uint16_t conn_id);
 
 /*******************************************************************************
  *
diff --git a/bta/test/gatt/database_builder_sample_device_test.cc b/bta/test/gatt/database_builder_sample_device_test.cc
index bd4dabc..2bfaa04 100644
--- a/bta/test/gatt/database_builder_sample_device_test.cc
+++ b/bta/test/gatt/database_builder_sample_device_test.cc
@@ -19,6 +19,7 @@
 #include <gtest/gtest.h>
 
 #include <base/logging.h>
+#include <iterator>
 #include <utility>
 
 #include "gatt/database_builder.h"
@@ -223,64 +224,51 @@
   EXPECT_FALSE(builder.InProgress());
 
   // verify that the returned database matches what was discovered
-  EXPECT_EQ(result.Services()[0].handle, 0x0001);
-  EXPECT_EQ(result.Services()[0].uuid, SERVICE_1_UUID);
-  EXPECT_EQ(result.Services()[1].uuid, SERVICE_2_UUID);
-  EXPECT_EQ(result.Services()[2].uuid, SERVICE_3_UUID);
-  EXPECT_EQ(result.Services()[3].uuid, SERVICE_4_UUID);
-  EXPECT_EQ(result.Services()[4].uuid, SERVICE_5_UUID);
-  EXPECT_EQ(result.Services()[5].uuid, SERVICE_6_UUID);
+  auto service = result.Services().begin();
+  EXPECT_EQ(service->handle, 0x0001);
+  EXPECT_EQ(service->uuid, SERVICE_1_UUID);
 
-  EXPECT_EQ(result.Services()[0].characteristics[0].uuid,
-            SERVICE_1_CHAR_1_UUID);
-  EXPECT_EQ(result.Services()[0].characteristics[1].uuid,
-            SERVICE_1_CHAR_2_UUID);
-  EXPECT_EQ(result.Services()[0].characteristics[2].uuid,
-            SERVICE_1_CHAR_3_UUID);
+  EXPECT_EQ(service->characteristics[0].uuid, SERVICE_1_CHAR_1_UUID);
+  EXPECT_EQ(service->characteristics[1].uuid, SERVICE_1_CHAR_2_UUID);
+  EXPECT_EQ(service->characteristics[2].uuid, SERVICE_1_CHAR_3_UUID);
 
-  EXPECT_EQ(result.Services()[2].characteristics[0].uuid,
-            SERVICE_3_CHAR_1_UUID);
-  EXPECT_EQ(result.Services()[2].characteristics[0].descriptors[0].uuid,
+  service++;
+  EXPECT_EQ(service->uuid, SERVICE_2_UUID);
+
+  service++;
+  EXPECT_EQ(service->uuid, SERVICE_3_UUID);
+  EXPECT_EQ(service->characteristics[0].uuid, SERVICE_3_CHAR_1_UUID);
+  EXPECT_EQ(service->characteristics[0].descriptors[0].uuid,
             SERVICE_3_CHAR_1_DESC_1_UUID);
 
-  EXPECT_EQ(result.Services()[3].characteristics[0].uuid,
-            SERVICE_4_CHAR_1_UUID);
-  EXPECT_EQ(result.Services()[3].characteristics[1].uuid,
-            SERVICE_4_CHAR_2_UUID);
-  EXPECT_EQ(result.Services()[3].characteristics[2].uuid,
-            SERVICE_4_CHAR_3_UUID);
-  EXPECT_EQ(result.Services()[3].characteristics[3].uuid,
-            SERVICE_4_CHAR_4_UUID);
-  EXPECT_EQ(result.Services()[3].characteristics[4].uuid,
-            SERVICE_4_CHAR_5_UUID);
-  EXPECT_EQ(result.Services()[3].characteristics[5].uuid,
-            SERVICE_4_CHAR_6_UUID);
-  EXPECT_EQ(result.Services()[3].characteristics[5].descriptors[0].uuid,
+  service++;
+  EXPECT_EQ(service->uuid, SERVICE_4_UUID);
+  EXPECT_EQ(service->characteristics[0].uuid, SERVICE_4_CHAR_1_UUID);
+  EXPECT_EQ(service->characteristics[1].uuid, SERVICE_4_CHAR_2_UUID);
+  EXPECT_EQ(service->characteristics[2].uuid, SERVICE_4_CHAR_3_UUID);
+  EXPECT_EQ(service->characteristics[3].uuid, SERVICE_4_CHAR_4_UUID);
+  EXPECT_EQ(service->characteristics[4].uuid, SERVICE_4_CHAR_5_UUID);
+  EXPECT_EQ(service->characteristics[5].uuid, SERVICE_4_CHAR_6_UUID);
+  EXPECT_EQ(service->characteristics[5].descriptors[0].uuid,
             SERVICE_4_CHAR_6_DESC_1_UUID);
 
-  EXPECT_EQ(result.Services()[4].characteristics[0].uuid,
-            SERVICE_5_CHAR_1_UUID);
-  EXPECT_EQ(result.Services()[4].characteristics[1].uuid,
-            SERVICE_5_CHAR_2_UUID);
-  EXPECT_EQ(result.Services()[4].characteristics[2].uuid,
-            SERVICE_5_CHAR_3_UUID);
-  EXPECT_EQ(result.Services()[4].characteristics[3].uuid,
-            SERVICE_5_CHAR_4_UUID);
-  EXPECT_EQ(result.Services()[4].characteristics[4].uuid,
-            SERVICE_5_CHAR_5_UUID);
-  EXPECT_EQ(result.Services()[4].characteristics[5].uuid,
-            SERVICE_5_CHAR_6_UUID);
-  EXPECT_EQ(result.Services()[4].characteristics[6].uuid,
-            SERVICE_5_CHAR_7_UUID);
+  service++;
+  EXPECT_EQ(service->uuid, SERVICE_5_UUID);
+  EXPECT_EQ(service->characteristics[0].uuid, SERVICE_5_CHAR_1_UUID);
+  EXPECT_EQ(service->characteristics[1].uuid, SERVICE_5_CHAR_2_UUID);
+  EXPECT_EQ(service->characteristics[2].uuid, SERVICE_5_CHAR_3_UUID);
+  EXPECT_EQ(service->characteristics[3].uuid, SERVICE_5_CHAR_4_UUID);
+  EXPECT_EQ(service->characteristics[4].uuid, SERVICE_5_CHAR_5_UUID);
+  EXPECT_EQ(service->characteristics[5].uuid, SERVICE_5_CHAR_6_UUID);
+  EXPECT_EQ(service->characteristics[6].uuid, SERVICE_5_CHAR_7_UUID);
 
-  EXPECT_EQ(result.Services()[5].characteristics[0].uuid,
-            SERVICE_6_CHAR_1_UUID);
-  EXPECT_EQ(result.Services()[5].characteristics[0].descriptors[0].uuid,
+  service++;
+  EXPECT_EQ(service->uuid, SERVICE_6_UUID);
+  EXPECT_EQ(service->characteristics[0].uuid, SERVICE_6_CHAR_1_UUID);
+  EXPECT_EQ(service->characteristics[0].descriptors[0].uuid,
             SERVICE_6_CHAR_1_DESC_1_UUID);
-  EXPECT_EQ(result.Services()[5].characteristics[1].uuid,
-            SERVICE_6_CHAR_2_UUID);
-  EXPECT_EQ(result.Services()[5].characteristics[2].uuid,
-            SERVICE_6_CHAR_3_UUID);
+  EXPECT_EQ(service->characteristics[1].uuid, SERVICE_6_CHAR_2_UUID);
+  EXPECT_EQ(service->characteristics[2].uuid, SERVICE_6_CHAR_3_UUID);
 }
 
 }  // namespace gatt
\ No newline at end of file
diff --git a/bta/test/gatt/database_builder_test.cc b/bta/test/gatt/database_builder_test.cc
index fcafb49..0a7e928 100644
--- a/bta/test/gatt/database_builder_test.cc
+++ b/bta/test/gatt/database_builder_test.cc
@@ -19,6 +19,7 @@
 #include <gtest/gtest.h>
 
 #include <base/logging.h>
+#include <iterator>
 #include <utility>
 
 #include "gatt/database_builder.h"
@@ -59,10 +60,11 @@
   Database result = builder.Build();
 
   // verify that the returned database matches what was discovered
-  EXPECT_EQ(result.Services()[0].handle, 0x0001);
-  EXPECT_EQ(result.Services()[0].end_handle, 0x0001);
-  EXPECT_EQ(result.Services()[0].is_primary, true);
-  EXPECT_EQ(result.Services()[0].uuid, SERVICE_1_UUID);
+  auto service = result.Services().begin();
+  EXPECT_EQ(service->handle, 0x0001);
+  EXPECT_EQ(service->end_handle, 0x0001);
+  EXPECT_EQ(service->is_primary, true);
+  EXPECT_EQ(service->uuid, SERVICE_1_UUID);
 }
 
 /* Verify adding service, characteristic and descriptor work */
@@ -79,21 +81,20 @@
   Database result = builder.Build();
 
   // verify that the returned database matches what was discovered
-  EXPECT_EQ(result.Services()[0].handle, 0x0001);
-  EXPECT_EQ(result.Services()[0].end_handle, 0x000f);
-  EXPECT_EQ(result.Services()[0].is_primary, true);
-  EXPECT_EQ(result.Services()[0].uuid, SERVICE_1_UUID);
+  auto service = result.Services().begin();
+  EXPECT_EQ(service->handle, 0x0001);
+  EXPECT_EQ(service->end_handle, 0x000f);
+  EXPECT_EQ(service->is_primary, true);
+  EXPECT_EQ(service->uuid, SERVICE_1_UUID);
 
-  EXPECT_EQ(result.Services()[0].characteristics[0].uuid,
-            SERVICE_1_CHAR_1_UUID);
-  EXPECT_EQ(result.Services()[0].characteristics[0].declaration_handle, 0x0002);
-  EXPECT_EQ(result.Services()[0].characteristics[0].value_handle, 0x0003);
-  EXPECT_EQ(result.Services()[0].characteristics[0].properties, 0x02);
+  EXPECT_EQ(service->characteristics[0].uuid, SERVICE_1_CHAR_1_UUID);
+  EXPECT_EQ(service->characteristics[0].declaration_handle, 0x0002);
+  EXPECT_EQ(service->characteristics[0].value_handle, 0x0003);
+  EXPECT_EQ(service->characteristics[0].properties, 0x02);
 
-  EXPECT_EQ(result.Services()[0].characteristics[0].descriptors[0].uuid,
+  EXPECT_EQ(service->characteristics[0].descriptors[0].uuid,
             SERVICE_1_CHAR_1_DESC_1_UUID);
-  EXPECT_EQ(result.Services()[0].characteristics[0].descriptors[0].handle,
-            0x0004);
+  EXPECT_EQ(service->characteristics[0].descriptors[0].handle, 0x0004);
 }
 
 /* This test verifies that DatabaseBuilder properly handle discovery of
@@ -139,27 +140,35 @@
   Database result = builder.Build();
 
   // verify that the returned database matches what was discovered
-  EXPECT_EQ(result.Services()[0].handle, 0x0001);
-  EXPECT_EQ(result.Services()[0].is_primary, true);
-  EXPECT_EQ(result.Services()[0].uuid, SERVICE_1_UUID);
+  auto service = result.Services().begin();
+  EXPECT_EQ(service->handle, 0x0001);
+  EXPECT_EQ(service->is_primary, true);
+  EXPECT_EQ(service->uuid, SERVICE_1_UUID);
 
-  EXPECT_EQ(result.Services()[1].handle, 0x0020);
-  EXPECT_EQ(result.Services()[1].end_handle, 0x002f);
-  EXPECT_EQ(result.Services()[1].uuid, SERVICE_2_UUID);
-  EXPECT_EQ(result.Services()[1].is_primary, false);
+  service++;
+  EXPECT_EQ(service->handle, 0x0020);
+  EXPECT_EQ(service->end_handle, 0x002f);
+  EXPECT_EQ(service->uuid, SERVICE_2_UUID);
+  EXPECT_EQ(service->is_primary, false);
 
-  EXPECT_EQ(result.Services()[2].handle, 0x0030);
-  EXPECT_EQ(result.Services()[2].end_handle, 0x003f);
-  EXPECT_EQ(result.Services()[2].uuid, SERVICE_3_UUID);
-  EXPECT_EQ(result.Services()[2].is_primary, true);
+  service++;
+  EXPECT_EQ(service->handle, 0x0030);
+  EXPECT_EQ(service->end_handle, 0x003f);
+  EXPECT_EQ(service->uuid, SERVICE_3_UUID);
+  EXPECT_EQ(service->is_primary, true);
 
-  EXPECT_EQ(result.Services()[3].handle, 0x0040);
-  EXPECT_EQ(result.Services()[3].uuid, SERVICE_4_UUID);
-  EXPECT_EQ(result.Services()[3].is_primary, false);
+  service++;
+  EXPECT_EQ(service->handle, 0x0040);
+  EXPECT_EQ(service->uuid, SERVICE_4_UUID);
+  EXPECT_EQ(service->is_primary, false);
 
-  EXPECT_EQ(result.Services()[4].handle, 0x0050);
-  EXPECT_EQ(result.Services()[4].uuid, SERVICE_5_UUID);
-  EXPECT_EQ(result.Services()[4].is_primary, true);
+  service++;
+  EXPECT_EQ(service->handle, 0x0050);
+  EXPECT_EQ(service->uuid, SERVICE_5_UUID);
+  EXPECT_EQ(service->is_primary, true);
+
+  service++;
+  ASSERT_EQ(service, result.Services().end());
 }
 
 }  // namespace gatt
\ No newline at end of file
diff --git a/btif/Android.bp b/btif/Android.bp
index 814cba7..dd05ead 100644
--- a/btif/Android.bp
+++ b/btif/Android.bp
@@ -24,6 +24,8 @@
     "system/bt/utils/include",
     "system/bt/include",
     "system/libhwbinder/include",
+    "system/security/keystore/include",
+    "hardware/interfaces/keymaster/4.0/support/include",
 ]
 
 // libbtif static library for target
@@ -71,6 +73,7 @@
         "src/btif_hf_client.cc",
         "src/btif_hh.cc",
         "src/btif_hd.cc",
+        "src/btif_keystore.cc",
         "src/btif_mce.cc",
         "src/btif_pan.cc",
         "src/btif_profile_queue.cc",
@@ -103,6 +106,12 @@
         "libhwbinder",
         "libutils",
         "libcrypto",
+        "android.hardware.keymaster@4.0",
+        "android.hardware.keymaster@3.0",
+        "libkeymaster4support",
+        "libkeystore_aidl",
+        "libkeystore_binder",
+        "libkeystore_parcelables",
     ],
     whole_static_libs: [
         "avrcp-target-service",
@@ -124,7 +133,10 @@
     defaults: ["fluoride_defaults"],
     test_suites: ["device-tests"],
     include_dirs: btifCommonIncludes,
-    srcs: ["test/btif_storage_test.cc"],
+    srcs: [
+        "test/btif_storage_test.cc",
+        "test/btif_keystore_test.cc"
+    ],
     header_libs: ["libbluetooth_headers"],
     shared_libs: [
         "libaudioclient",
@@ -169,6 +181,9 @@
         "libbluetooth-for-tests",
     ],
     cflags: ["-DBUILDCFG"],
+    sanitize: {
+        integer_overflow: true,
+    },
 }
 
 // btif profile queue unit tests for target
diff --git a/btif/include/btif_api.h b/btif/include/btif_api.h
index 519fc9c..cef1aad 100644
--- a/btif/include/btif_api.h
+++ b/btif/include/btif_api.h
@@ -105,6 +105,19 @@
 
 /*******************************************************************************
  *
+ * Function         is_single_user_mode_
+ *
+ * Description      Checks if BT was enabled in single user mode. In this
+ *                  mode, use of keystore for key attestation of LTK is limitee
+ *                  to this mode defined by UserManager.
+ *
+ * Returns          bool
+ *
+ ******************************************************************************/
+bool is_single_user_mode(void);
+
+/*******************************************************************************
+ *
  * Function         btif_get_adapter_properties
  *
  * Description      Fetches all local adapter properties
diff --git a/btif/include/btif_keystore.h b/btif/include/btif_keystore.h
new file mode 100644
index 0000000..cc06a98
--- /dev/null
+++ b/btif/include/btif_keystore.h
@@ -0,0 +1,78 @@
+/******************************************************************************
+ *
+ *  Copyright 2019 Google, Inc.
+ *
+ *  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 <keystore/keystore_client_impl.h>
+#include <mutex>
+
+#include "osi/include/alarm.h"
+#include "osi/include/allocator.h"
+#include "osi/include/compat.h"
+#include "osi/include/config.h"
+#include "osi/include/log.h"
+#include "osi/include/osi.h"
+#include "osi/include/properties.h"
+
+namespace bluetooth {
+/**
+ * Client wrapper to access AndroidKeystore.
+ *
+ * <p>Use to encrypt/decrypt data and store to disk.
+ */
+class BtifKeystore {
+ public:
+  /**
+   * @param keystore_client injected pre-created client object for keystore
+   */
+  BtifKeystore(keystore::KeystoreClient* keystore_client);
+
+  /**
+   * Encrypts given data
+   *
+   * <p>Returns a string representation of the encrypted data
+   *
+   * @param data to be encrypted
+   * @param flags for keystore
+   */
+  std::string Encrypt(const std::string& data, int32_t flags);
+
+  /**
+   * Returns a decrypted string representation of the encrypted data or empty
+   * string on error.
+   *
+   * @param input encrypted data
+   */
+  std::string Decrypt(const std::string& input_filename);
+
+  /**
+   * Check for existence of keystore key.
+   *
+   * This key can be cleared if a user manually wipes bluetooth storage data
+   * b/133214365
+   */
+  bool DoesKeyExist();
+
+ 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);
+};
+
+}  // namespace bluetooth
diff --git a/btif/src/bluetooth.cc b/btif/src/bluetooth.cc
index 1faca2d..9dd4908 100644
--- a/btif/src/bluetooth.cc
+++ b/btif/src/bluetooth.cc
@@ -81,6 +81,7 @@
 
 bt_callbacks_t* bt_hal_cbacks = NULL;
 bool restricted_mode = false;
+bool single_user_mode = false;
 
 /*******************************************************************************
  *  Externs
@@ -132,8 +133,10 @@
  *
  ****************************************************************************/
 
-static int init(bt_callbacks_t* callbacks) {
-  LOG_INFO(LOG_TAG, "%s", __func__);
+static int init(bt_callbacks_t* callbacks, bool start_restricted,
+                bool is_single_user_mode) {
+  LOG_INFO(LOG_TAG, "%s: start restricted = %d ; single user = %d", __func__,
+           start_restricted, is_single_user_mode);
 
   if (interface_ready()) return BT_STATUS_DONE;
 
@@ -142,16 +145,14 @@
 #endif
 
   bt_hal_cbacks = callbacks;
+  restricted_mode = start_restricted;
+  single_user_mode = is_single_user_mode;
   stack_manager_get_interface()->init_stack();
   btif_debug_init();
   return BT_STATUS_SUCCESS;
 }
 
-static int enable(bool start_restricted) {
-  LOG_INFO(LOG_TAG, "%s: start restricted = %d", __func__, start_restricted);
-
-  restricted_mode = start_restricted;
-
+static int enable() {
   if (!interface_ready()) return BT_STATUS_NOT_READY;
 
   stack_manager_get_interface()->start_up_stack_async();
@@ -168,6 +169,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; }
 
 static int get_adapter_properties(void) {
   /* sanity check */
diff --git a/btif/src/btif_config.cc b/btif/src/btif_config.cc
index c017c0f..ed24d7d 100644
--- a/btif/src/btif_config.cc
+++ b/btif/src/btif_config.cc
@@ -23,19 +23,22 @@
 #include <base/logging.h>
 #include <ctype.h>
 #include <openssl/rand.h>
+#include <openssl/sha.h>
+#include <private/android_filesystem_config.h>
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-#include <string>
-
 #include <mutex>
+#include <sstream>
+#include <string>
 
 #include "bt_types.h"
 #include "btcore/include/module.h"
 #include "btif_api.h"
 #include "btif_common.h"
 #include "btif_config_transcode.h"
+#include "btif_keystore.h"
 #include "btif_util.h"
 #include "common/address_obfuscator.h"
 #include "osi/include/alarm.h"
@@ -52,10 +55,18 @@
 #define FILE_TIMESTAMP "TimeCreated"
 #define FILE_SOURCE "FileSource"
 #define TIME_STRING_LENGTH sizeof("YYYY-MM-DD HH:MM:SS")
+#define DISABLED "disabled"
 static const char* TIME_STRING_FORMAT = "%Y-%m-%d %H:%M:%S";
 
+constexpr int kBufferSize = 400 * 10;  // initial file is ~400B
+
+static bool use_key_attestation() {
+  return getuid() == AID_BLUETOOTH && is_single_user_mode();
+}
+
 #define BT_CONFIG_METRICS_SECTION "Metrics"
 #define BT_CONFIG_METRICS_SALT_256BIT "Salt256Bit"
+using bluetooth::BtifKeystore;
 using bluetooth::common::AddressObfuscator;
 
 // TODO(armansito): Find a better way than searching by a hardcoded path.
@@ -66,6 +77,8 @@
 #else   // !defined(OS_GENERIC)
 static const char* CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf";
 static const char* CONFIG_BACKUP_PATH = "/data/misc/bluedroid/bt_config.bak";
+static const char* CONFIG_FILE_CHECKSUM_PATH = "/data/misc/bluedroid/bt_config.conf.encrypted-checksum";
+static const char* CONFIG_BACKUP_CHECKSUM_PATH = "/data/misc/bluedroid/bt_config.bak.encrypted-checksum";
 static const char* CONFIG_LEGACY_FILE_PATH =
     "/data/misc/bluedroid/bt_config.xml";
 #endif  // defined(OS_GENERIC)
@@ -77,7 +90,12 @@
 static void delete_config_files(void);
 static void btif_config_remove_unpaired(config_t* config);
 static void btif_config_remove_restricted(config_t* config);
-static std::unique_ptr<config_t> btif_config_open(const char* filename);
+static std::unique_ptr<config_t> btif_config_open(const char* filename, const char* checksum_filename);
+
+// Key attestation
+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 enum ConfigSource {
   NOT_LOADED,
@@ -158,21 +176,26 @@
 static std::unique_ptr<config_t> config;
 static alarm_t* config_timer;
 
+static BtifKeystore btif_keystore(new keystore::KeystoreClientImpl);
+
 // Module lifecycle functions
 
 static future_t* init(void) {
   std::unique_lock<std::recursive_mutex> lock(config_lock);
 
-  if (is_factory_reset()) delete_config_files();
+  if (is_factory_reset() ||
+      (use_key_attestation() && !btif_keystore.DoesKeyExist()))
+    delete_config_files();
 
   std::string file_source;
 
-  config = btif_config_open(CONFIG_FILE_PATH);
+  config = btif_config_open(CONFIG_FILE_PATH, CONFIG_FILE_CHECKSUM_PATH);
   btif_config_source = ORIGINAL;
   if (!config) {
     LOG_WARN(LOG_TAG, "%s unable to load config file: %s; using backup.",
              __func__, CONFIG_FILE_PATH);
-    config = btif_config_open(CONFIG_BACKUP_PATH);
+    remove(CONFIG_FILE_CHECKSUM_PATH);
+    config = btif_config_open(CONFIG_BACKUP_PATH, CONFIG_BACKUP_CHECKSUM_PATH);
     btif_config_source = BACKUP;
     file_source = "Backup";
   }
@@ -180,6 +203,7 @@
     LOG_WARN(LOG_TAG,
              "%s unable to load backup; attempting to transcode legacy file.",
              __func__);
+    remove(CONFIG_BACKUP_CHECKSUM_PATH);
     config = btif_config_transcode(CONFIG_LEGACY_FILE_PATH);
     btif_config_source = LEGACY;
     file_source = "Legacy";
@@ -239,7 +263,25 @@
   return future_new_immediate(FUTURE_FAIL);
 }
 
-static std::unique_ptr<config_t> btif_config_open(const char* filename) {
+static std::unique_ptr<config_t> btif_config_open(const char* filename, const char* checksum_filename) {
+  // START KEY ATTESTATION
+  // Get hash of current file
+  std::string current_hash = hash_file(filename);
+  // Get stored hash
+  std::string stored_hash = read_checksum_file(checksum_filename);
+  if (stored_hash.empty()) {
+    LOG(ERROR) << __func__ << ": stored_hash=<empty>";
+    if (!current_hash.empty()) {
+      write_checksum_file(checksum_filename, current_hash);
+      stored_hash = read_checksum_file(checksum_filename);
+    }
+  }
+  // Compare hashes
+  if (current_hash != stored_hash) {
+    return nullptr;
+  }
+  // END KEY ATTESTATION
+
   std::unique_ptr<config_t> config = config_new(filename);
   if (!config) return nullptr;
 
@@ -413,6 +455,12 @@
 
   if (length > 0) CHECK(value != NULL);
 
+  size_t max_value = ((size_t)-1);
+  if (((max_value - 1) / 2) < length) {
+    LOG(ERROR) << __func__ << ": length too long";
+    return false;
+  }
+
   char* str = (char*)osi_calloc(length * 2 + 1);
 
   for (size_t i = 0; i < length; ++i) {
@@ -465,6 +513,13 @@
 
   bool ret = config_save(*config, CONFIG_FILE_PATH);
   btif_config_source = RESET;
+
+  // Save encrypted hash
+  std::string current_hash = hash_file(CONFIG_FILE_PATH);
+  if (!current_hash.empty()) {
+    write_checksum_file(CONFIG_FILE_CHECKSUM_PATH, current_hash);
+  }
+
   return ret;
 }
 
@@ -482,9 +537,15 @@
 
   std::unique_lock<std::recursive_mutex> lock(config_lock);
   rename(CONFIG_FILE_PATH, CONFIG_BACKUP_PATH);
+  rename(CONFIG_FILE_CHECKSUM_PATH, CONFIG_BACKUP_CHECKSUM_PATH);
   std::unique_ptr<config_t> config_paired = config_new_clone(*config);
   btif_config_remove_unpaired(config_paired.get());
   config_save(*config_paired, CONFIG_FILE_PATH);
+  // Save hash
+  std::string current_hash = hash_file(CONFIG_FILE_PATH);
+  if (!current_hash.empty()) {
+    write_checksum_file(CONFIG_FILE_CHECKSUM_PATH, current_hash);
+  }
 }
 
 static void btif_config_remove_unpaired(config_t* conf) {
@@ -576,5 +637,65 @@
 static void delete_config_files(void) {
   remove(CONFIG_FILE_PATH);
   remove(CONFIG_BACKUP_PATH);
+  remove(CONFIG_FILE_CHECKSUM_PATH);
+  remove(CONFIG_BACKUP_CHECKSUM_PATH);
   osi_property_set("persist.bluetooth.factoryreset", "false");
 }
+
+static std::string hash_file(const char* filename) {
+  if (!use_key_attestation()) {
+    LOG(INFO) << __func__ << ": Disabled for multi-user";
+    return DISABLED;
+  }
+  FILE* fp = fopen(filename, "rb");
+  if (!fp) {
+    LOG(ERROR) << __func__ << ": unable to open config file: '" << filename
+               << "': " << strerror(errno);
+    return "";
+  }
+  uint8_t hash[SHA256_DIGEST_LENGTH];
+  SHA256_CTX sha256;
+  SHA256_Init(&sha256);
+  std::array<std::byte, kBufferSize> buffer;
+  int bytes_read = 0;
+  while ((bytes_read = fread(buffer.data(), 1, buffer.size(), fp))) {
+    SHA256_Update(&sha256, buffer.data(), bytes_read);
+  }
+  SHA256_Final(hash, &sha256);
+  std::stringstream ss;
+  for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+    ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
+  }
+  fclose(fp);
+  return ss.str();
+}
+
+static std::string read_checksum_file(const char* checksum_filename) {
+  if (!use_key_attestation()) {
+    LOG(INFO) << __func__ << ": Disabled for multi-user";
+    return DISABLED;
+  }
+  std::string encrypted_hash = checksum_read(checksum_filename);
+  if (encrypted_hash.empty()) {
+    LOG(INFO) << __func__ << ": read empty hash.";
+    return "";
+  }
+  return btif_keystore.Decrypt(encrypted_hash);
+}
+
+static void write_checksum_file(const char* checksum_filename,
+                                const std::string& hash) {
+  if (!use_key_attestation()) {
+    LOG(INFO) << __func__
+              << ": Disabled for multi-user, since config changed removing "
+                 "checksums.";
+    remove(CONFIG_FILE_CHECKSUM_PATH);
+    remove(CONFIG_BACKUP_CHECKSUM_PATH);
+    return;
+  }
+  std::string encrypted_checksum = btif_keystore.Encrypt(hash, 0);
+  CHECK(!encrypted_checksum.empty())
+      << __func__ << ": Failed encrypting checksum";
+  CHECK(checksum_save(encrypted_checksum, checksum_filename))
+      << __func__ << ": Failed to save checksum!";
+}
diff --git a/btif/src/btif_dm.cc b/btif/src/btif_dm.cc
index 683834a..1f5cb82 100644
--- a/btif/src/btif_dm.cc
+++ b/btif/src/btif_dm.cc
@@ -260,6 +260,11 @@
   return !memcmp(zero, data, sizeof(zero));
 }
 
+static bool is_bonding_or_sdp() {
+  return pairing_cb.state == BT_BOND_STATE_BONDING ||
+         (pairing_cb.state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts);
+}
+
 static void btif_dm_data_copy(uint16_t event, char* dst, char* src) {
   tBTA_DM_SEC* dst_dm_sec = (tBTA_DM_SEC*)dst;
   tBTA_DM_SEC* src_dm_sec = (tBTA_DM_SEC*)src;
@@ -486,8 +491,6 @@
                                bt_bond_state_t state) {
   btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_BOND_STATE_CHANGED, state);
 
-  // Send bonding state only once - based on outgoing/incoming we may receive
-  // duplicates
   if ((pairing_cb.state == state) && (state == BT_BOND_STATE_BONDING)) {
     // Cross key pairing so send callback for static address
     if (!pairing_cb.static_bdaddr.IsEmpty()) {
@@ -505,14 +508,18 @@
   auto tmp = bd_addr;
   HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state);
 
-  if (state == BT_BOND_STATE_BONDING) {
+  int dev_type;
+  if (!btif_get_device_type(bd_addr, &dev_type)) {
+    dev_type = BT_DEVICE_TYPE_BREDR;
+  }
+
+  if (state == BT_BOND_STATE_BONDING ||
+      (state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts > 0)) {
+    // Save state for the device is bonding or SDP.
     pairing_cb.state = state;
     pairing_cb.bd_addr = bd_addr;
   } else {
-    if (!pairing_cb.sdp_attempts)
-      memset(&pairing_cb, 0, sizeof(pairing_cb));
-    else
-      BTIF_TRACE_DEBUG("%s: BR-EDR service discovery active", __func__);
+    pairing_cb = {};
   }
 }
 
@@ -1138,6 +1145,17 @@
 
         /* Trigger SDP on the device */
         pairing_cb.sdp_attempts = 1;
+
+        if (is_crosskey) {
+          // If bonding occurred due to cross-key pairing, send bonding callback
+          // for static address now
+          LOG_INFO(LOG_TAG,
+                   "%s: send bonding state update for static address %s",
+                   __func__, bd_addr.ToString().c_str());
+          bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
+        }
+        bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDED);
+
         btif_dm_get_remote_services(bd_addr);
       }
     }
@@ -1395,9 +1413,9 @@
 
       BTIF_TRACE_DEBUG("%s:(result=0x%x, services 0x%x)", __func__,
                        p_data->disc_res.result, p_data->disc_res.services);
-      if ((p_data->disc_res.result != BTA_SUCCESS) &&
-          (pairing_cb.state == BT_BOND_STATE_BONDING) &&
-          (pairing_cb.sdp_attempts < BTIF_DM_MAX_SDP_ATTEMPTS_AFTER_PAIRING)) {
+      if (p_data->disc_res.result != BTA_SUCCESS &&
+          pairing_cb.state == BT_BOND_STATE_BONDED &&
+          pairing_cb.sdp_attempts < BTIF_DM_MAX_SDP_ATTEMPTS_AFTER_PAIRING) {
         if (pairing_cb.sdp_attempts) {
           BTIF_TRACE_WARNING("%s: SDP failed after bonding re-attempting",
                              __func__);
@@ -1424,21 +1442,36 @@
       /* onUuidChanged requires getBondedDevices to be populated.
       ** bond_state_changed needs to be sent prior to remote_device_property
       */
-      if ((pairing_cb.state == BT_BOND_STATE_BONDING) &&
+      if (pairing_cb.state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts &&
           (p_data->disc_res.bd_addr == pairing_cb.bd_addr ||
-           p_data->disc_res.bd_addr == pairing_cb.static_bdaddr) &&
-          pairing_cb.sdp_attempts > 0) {
-        BTIF_TRACE_DEBUG(
-            "%s Remote Service SDP done. Call bond_state_changed_cb BONDED",
-            __func__);
+           p_data->disc_res.bd_addr == pairing_cb.static_bdaddr)) {
+        LOG_INFO(LOG_TAG, "%s: SDP search done for %s", __func__,
+                 bd_addr.ToString().c_str());
         pairing_cb.sdp_attempts = 0;
 
-        // If bonding occured due to cross-key pairing, send bonding callback
-        // for static address now
-        if (p_data->disc_res.bd_addr == pairing_cb.static_bdaddr)
-          bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
+        // Both SDP and bonding are done, clear pairing control block in case
+        // it is not already cleared
+        pairing_cb = {};
 
-        bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDED);
+        // Send one empty UUID to Java to unblock pairing intent when SDP failed
+        // or no UUID is discovered
+        if (p_data->disc_res.result != BTA_SUCCESS ||
+            p_data->disc_res.num_uuids == 0) {
+          LOG_INFO(LOG_TAG,
+                   "%s: SDP failed, send empty UUID to unblock bonding %s",
+                   __func__, bd_addr.ToString().c_str());
+          bt_property_t prop;
+          Uuid uuid = {};
+
+          prop.type = BT_PROPERTY_UUIDS;
+          prop.val = &uuid;
+          prop.len = Uuid::kNumBytes128;
+
+          /* Send the event to the BTIF */
+          HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
+                    BT_STATUS_SUCCESS, &bd_addr, 1, &prop);
+          break;
+        }
       }
 
       if (p_data->disc_res.num_uuids != 0) {
@@ -1634,7 +1667,7 @@
       break;
 
     case BTA_DM_BOND_CANCEL_CMPL_EVT:
-      if (pairing_cb.state == BT_BOND_STATE_BONDING) {
+      if (is_bonding_or_sdp()) {
         bd_addr = pairing_cb.bd_addr;
         btm_set_bond_type_dev(pairing_cb.bd_addr, BOND_TYPE_UNKNOWN);
         bond_state_changed((bt_status_t)p_data->bond_cancel_cmpl.result,
@@ -2274,7 +2307,7 @@
   **  1. Restore scan modes
   **  2. special handling for HID devices
   */
-  if (pairing_cb.state == BT_BOND_STATE_BONDING) {
+  if (is_bonding_or_sdp()) {
     if (pairing_cb.is_ssp) {
       if (pairing_cb.is_le_only) {
         BTA_DmBleSecurityGrant(*bd_addr, BTA_DM_SEC_PAIR_NOT_SPT);
@@ -2486,7 +2519,7 @@
 
 /*******************************************************************************
  *
- * Function         btif_dm_get_remote_services_transport
+ * Function         btif_dm_get_remote_services_by_transport
  *
  * Description      Start SDP to get remote services by transport
  *
@@ -2885,6 +2918,10 @@
         break;
     }
   }
+  if (state == BT_BOND_STATE_BONDED && bd_addr != pairing_cb.static_bdaddr) {
+    // Report RPA bonding state to Java in crosskey paring
+    bond_state_changed(status, bd_addr, BT_BOND_STATE_BONDING);
+  }
   bond_state_changed(status, bd_addr, state);
 }
 
@@ -3191,7 +3228,7 @@
 
 void btif_dm_on_disable() {
   /* cancel any pending pairing requests */
-  if (pairing_cb.state == BT_BOND_STATE_BONDING) {
+  if (is_bonding_or_sdp()) {
     BTIF_TRACE_DEBUG("%s: Cancel pending pairing request", __func__);
     btif_dm_cancel_bond(&pairing_cb.bd_addr);
   }
diff --git a/btif/src/btif_hf.cc b/btif/src/btif_hf.cc
index e0e9515..04ad011 100644
--- a/btif/src/btif_hf.cc
+++ b/btif/src/btif_hf.cc
@@ -412,7 +412,7 @@
     case BTA_AG_AT_BLDN_EVT:
     case BTA_AG_AT_D_EVT:
       bt_hf_callbacks->DialCallCallback(
-          (event == BTA_AG_AT_D_EVT) ? p_data->val.str : nullptr,
+          (event == BTA_AG_AT_D_EVT) ? p_data->val.str : (char*)"",
           &btif_hf_cb[idx].connected_bda);
       break;
 
diff --git a/btif/src/btif_hf_client.cc b/btif/src/btif_hf_client.cc
index e40975e..c999885 100644
--- a/btif/src/btif_hf_client.cc
+++ b/btif/src/btif_hf_client.cc
@@ -949,7 +949,7 @@
                 (bthf_client_call_state_t)p_data->clcc.status,
                 p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI
                                   : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE,
-                p_data->clcc.number_present ? p_data->clcc.number : NULL);
+                p_data->clcc.number_present ? p_data->clcc.number : "");
       break;
 
     case BTA_HF_CLIENT_CNUM_EVT:
diff --git a/btif/src/btif_keystore.cc b/btif/src/btif_keystore.cc
new file mode 100644
index 0000000..0af03e1
--- /dev/null
+++ b/btif/src/btif_keystore.cc
@@ -0,0 +1,105 @@
+/******************************************************************************
+ *
+ *  Copyright 2019 Google, Inc.
+ *
+ *  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 "btif_keystore.h"
+
+#include <base/files/file_util.h>
+#include <base/logging.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_split.h>
+#include <base/strings/string_util.h>
+#include <base/strings/utf_string_conversions.h>
+#include <sys/stat.h>
+
+using namespace keystore;
+using namespace bluetooth;
+
+constexpr char kKeyStore[] = "AndroidKeystore";
+
+namespace bluetooth {
+
+BtifKeystore::BtifKeystore(keystore::KeystoreClient* keystore_client)
+    : keystore_client_(keystore_client) {}
+
+std::string BtifKeystore::Encrypt(const std::string& data, int32_t flags) {
+  std::lock_guard<std::mutex> lock(api_mutex_);
+  std::string output;
+  if (data.empty()) {
+    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.";
+    return output;
+  }
+  return output;
+}
+
+std::string BtifKeystore::Decrypt(const std::string& input) {
+  std::lock_guard<std::mutex> lock(api_mutex_);
+  if (input.empty()) {
+    LOG(ERROR) << __func__ << ": empty input data";
+    return "";
+  }
+  std::string output;
+  if (!keystore_client_->decryptWithAuthentication(kKeyStore, input, &output)) {
+    LOG(FATAL) << "DecryptWithAuthentication failed.\n";
+  }
+  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);
+  }
+  AuthorizationSet hardware_enforced_characteristics;
+  AuthorizationSet software_enforced_characteristics;
+  return keystore_client_->generateKey(name, params, flags,
+                                       &hardware_enforced_characteristics,
+                                       &software_enforced_characteristics);
+}
+
+bool BtifKeystore::DoesKeyExist() {
+  return keystore_client_->doesKeyExist(kKeyStore);
+}
+
+}  // namespace bluetooth
diff --git a/btif/src/btif_storage.cc b/btif/src/btif_storage.cc
index b6ffcda..2427493 100644
--- a/btif/src/btif_storage.cc
+++ b/btif/src/btif_storage.cc
@@ -889,9 +889,8 @@
     tBTA_LE_KEY_VALUE key;
     memset(&key, 0, sizeof(key));
 
-    if (btif_storage_get_ble_bonding_key(
-            &bd_addr, BTIF_DM_LE_KEY_PENC, (uint8_t*)&key,
-            sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) {
+    if (btif_storage_get_ble_bonding_key(&bd_addr, BTIF_DM_LE_KEY_PENC, (uint8_t*)&key, sizeof(tBTM_LE_PENC_KEYS)) ==
+        BT_STATUS_SUCCESS) {
       if (is_sample_ltk(key.penc_key.ltk)) {
         bad_ltk.push_back(bd_addr);
       }
@@ -900,8 +899,7 @@
 
   for (RawAddress address : bad_ltk) {
     android_errorWriteLog(0x534e4554, "128437297");
-    LOG(ERROR) << __func__
-               << ": removing bond to device using test TLK: " << address;
+    LOG(ERROR) << __func__ << ": removing bond to device using test TLK: " << address;
 
     btif_storage_remove_bonded_device(&address);
   }
diff --git a/btif/test/btif_keystore_test.cc b/btif/test/btif_keystore_test.cc
new file mode 100644
index 0000000..4cabbad
--- /dev/null
+++ b/btif/test/btif_keystore_test.cc
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ *  Copyright 2019 Google, Inc.
+ *
+ *  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 <binder/ProcessState.h>
+#include <gtest/gtest.h>
+#include <fstream>
+
+#include "btif/include/btif_keystore.h"
+
+using namespace bluetooth;
+
+class BtifKeystoreTest : public ::testing::Test {
+ protected:
+  std::unique_ptr<BtifKeystore> btif_keystore_;
+  void SetUp() override {
+    android::ProcessState::self()->startThreadPool();
+    btif_keystore_ =
+        std::make_unique<BtifKeystore>(static_cast<keystore::KeystoreClient*>(
+            new keystore::KeystoreClientImpl));
+  };
+  void TearDown() override { btif_keystore_ = nullptr; };
+};
+
+TEST_F(BtifKeystoreTest, test_encrypt_decrypt) {
+  std::string hash = "test";
+
+  std::string encrypted_hash = btif_keystore_->Encrypt(hash, 0);
+  std::string decrypted_hash = btif_keystore_->Decrypt(encrypted_hash);
+
+  EXPECT_FALSE(encrypted_hash.empty());
+  EXPECT_EQ(hash, decrypted_hash);
+}
+
+TEST_F(BtifKeystoreTest, test_encrypt_empty_hash) {
+  std::string hash = "";
+
+  std::string encrypted_hash = btif_keystore_->Encrypt(hash, 0);
+
+  EXPECT_TRUE(encrypted_hash.empty());
+}
+
+TEST_F(BtifKeystoreTest, test_decrypt_empty_hash) {
+  std::string hash = "";
+
+  std::string decrypted_hash = btif_keystore_->Decrypt(hash);
+
+  EXPECT_TRUE(decrypted_hash.empty());
+}
diff --git a/common/scoped_scs_exit.h b/common/scoped_scs_exit.h
deleted file mode 100644
index ad4a8d6..0000000
--- a/common/scoped_scs_exit.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#pragma once
-
-// Prevent x18 (shadow call stack address) from being clobbered by functions
-// called by a function that declares a variable of this type by temporarily
-// storing the value on the stack. This is used only when calling out to certain
-// vendor libraries.
-struct ScopedSCSExit {
-#ifdef __aarch64__
-    void* scs;
-
-    __attribute__((always_inline, no_sanitize("shadow-call-stack"))) ScopedSCSExit() {
-        __asm__ __volatile__("str x18, [%0]" ::"r"(&scs));
-    }
-
-    __attribute__((always_inline, no_sanitize("shadow-call-stack"))) ~ScopedSCSExit() {
-        __asm__ __volatile__("ldr x18, [%0]; str xzr, [%0]" ::"r"(&scs));
-    }
-#else
-    // Silence unused variable warnings in non-SCS builds.
-    __attribute__((no_sanitize("shadow-call-stack"))) ScopedSCSExit() {}
-    __attribute__((no_sanitize("shadow-call-stack"))) ~ScopedSCSExit() {}
-#endif
-};
diff --git a/hci/include/btsnoop.h b/hci/include/btsnoop.h
index e897a96..476c62d 100644
--- a/hci/include/btsnoop.h
+++ b/hci/include/btsnoop.h
@@ -29,6 +29,28 @@
   // true, the packet is marked as incoming. Otherwise, the packet is marked
   // as outgoing.
   void (*capture)(const BT_HDR* packet, bool is_received);
+
+  // Set a L2CAP channel as whitelisted, allowing packets with that L2CAP CID
+  // to show up in the snoop logs.
+  void (*whitelist_l2c_channel)(uint16_t conn_handle, uint16_t local_cid,
+                                uint16_t remote_cid);
+
+  // Set a RFCOMM dlci as whitelisted, allowing packets with that RFCOMM CID
+  // to show up in the snoop logs. The local_cid is used to associate it with
+  // its corrisponding ACL connection. The dlci is the channel with direction
+  // so there is no chance of a collision if two services are using the same
+  // channel but in different directions.
+  void (*whitelist_rfc_dlci)(uint16_t local_cid, uint8_t dlci);
+
+  // Indicate that the provided L2CAP channel is being used for RFCOMM.
+  // If packets with the provided L2CAP CID are encountered, they will be
+  // filtered on RFCOMM based on channels provided to |filter_rfc_channel|.
+  void (*add_rfc_l2c_channel)(uint16_t conn_handle, uint16_t local_cid,
+                              uint16_t remote_cid);
+
+  // Clear an L2CAP channel from being filtered.
+  void (*clear_l2cap_whitelist)(uint16_t conn_handle, uint16_t local_cid,
+                                uint16_t remote_cid);
 } btsnoop_t;
 
 const btsnoop_t* btsnoop_get_interface(void);
diff --git a/hci/src/btsnoop.cc b/hci/src/btsnoop.cc
index 6938725..ad06ac7 100644
--- a/hci/src/btsnoop.cc
+++ b/hci/src/btsnoop.cc
@@ -21,6 +21,7 @@
 #include <mutex>
 
 #include <arpa/inet.h>
+#include <base/logging.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
@@ -34,14 +35,21 @@
 #include <sys/time.h>
 #include <sys/uio.h>
 #include <unistd.h>
+#include <mutex>
+#include <unordered_map>
+#include <unordered_set>
 
 #include "bt_types.h"
 #include "common/time_util.h"
 #include "hci/include/btsnoop.h"
 #include "hci/include/btsnoop_mem.h"
 #include "hci_layer.h"
+#include "internal_include/bt_trace.h"
 #include "osi/include/log.h"
 #include "osi/include/properties.h"
+#include "stack/include/hcimsgs.h"
+#include "stack/include/rfcdefs.h"
+#include "stack/l2cap/l2c_int.h"
 #include "stack_config.h"
 
 // The number of of packets per btsnoop file before we rotate to the next
@@ -50,7 +58,14 @@
 // property
 #define DEFAULT_BTSNOOP_SIZE 0xffff
 
-#define BTSNOOP_ENABLE_PROPERTY "persist.bluetooth.btsnoopenable"
+#define IS_DEBUGGABLE_PROPERTY "ro.debuggable"
+
+#define BTSNOOP_LOG_MODE_PROPERTY "persist.bluetooth.btsnooplogmode"
+#define BTSNOOP_DEFAULT_MODE_PROPERTY "persist.bluetooth.btsnoopdefaultmode"
+#define BTSNOOP_MODE_DISABLED "disabled"
+#define BTSNOOP_MODE_FILTERED "filtered"
+#define BTSNOOP_MODE_FULL "full"
+
 #define BTSNOOP_PATH_PROPERTY "persist.bluetooth.btsnooppath"
 #define DEFAULT_BTSNOOP_PATH "/data/misc/bluetooth/logs/btsnoop_hci.log"
 #define BTSNOOP_MAX_PACKETS_PROPERTY "persist.bluetooth.btsnoopsize"
@@ -65,33 +80,138 @@
 // Epoch in microseconds since 01/01/0000.
 static const uint64_t BTSNOOP_EPOCH_DELTA = 0x00dcddb30f2f8000ULL;
 
+// Number of bytes into a packet where you can find the value for a channel.
+static const size_t ACL_CHANNEL_OFFSET = 0;
+static const size_t L2C_CHANNEL_OFFSET = 6;
+static const size_t RFC_CHANNEL_OFFSET = 8;
+static const size_t RFC_EVENT_OFFSET = 9;
+
+// The size of the L2CAP header. All information past this point is removed from
+// a filtered packet.
+static const uint32_t L2C_HEADER_SIZE = 9;
+
 static int logfile_fd = INVALID_FD;
 static std::mutex btsnoop_mutex;
 
 static int32_t packets_per_file;
 static int32_t packet_counter;
 
+// Channel tracking variables for filtering.
+
+// Keeps track of L2CAP channels that need to be filtered out of the snoop
+// logs.
+class FilterTracker {
+ public:
+  // NOTE: 1 is used as a static CID for L2CAP signaling
+  std::unordered_set<uint16_t> l2c_local_cid = {1};
+  std::unordered_set<uint16_t> l2c_remote_cid = {1};
+  uint16_t rfc_local_cid = 0;
+  uint16_t rfc_remote_cid = 0;
+  std::unordered_set<uint16_t> rfc_channels = {0};
+
+  // Adds L2C channel to whitelist.
+  void addL2cCid(uint16_t local_cid, uint16_t remote_cid) {
+    l2c_local_cid.insert(local_cid);
+    l2c_remote_cid.insert(remote_cid);
+  }
+
+  // Sets L2CAP channel that RFCOMM uses.
+  void setRfcCid(uint16_t local_cid, uint16_t remote_cid) {
+    rfc_local_cid = local_cid;
+    rfc_remote_cid = remote_cid;
+  }
+
+  // Remove L2C channel from whitelist.
+  void removeL2cCid(uint16_t local_cid, uint16_t remote_cid) {
+    if (rfc_local_cid == local_cid) {
+      rfc_channels.clear();
+      rfc_channels.insert(0);
+      rfc_local_cid = 0;
+      rfc_remote_cid = 0;
+    }
+
+    l2c_local_cid.erase(local_cid);
+    l2c_remote_cid.erase(remote_cid);
+  }
+
+  void addRfcDlci(uint8_t channel) { rfc_channels.insert(channel); }
+
+  bool isWhitelistedL2c(bool local, uint16_t cid) {
+    const auto& set = local ? l2c_local_cid : l2c_remote_cid;
+    return (set.find(cid) != set.end());
+  }
+
+  bool isRfcChannel(bool local, uint16_t cid) {
+    const auto& channel = local ? rfc_local_cid : rfc_remote_cid;
+    return cid == channel;
+  }
+
+  bool isWhitelistedDlci(uint8_t dlci) {
+    return rfc_channels.find(dlci) != rfc_channels.end();
+  }
+};
+
+std::mutex filter_list_mutex;
+std::unordered_map<uint16_t, FilterTracker> filter_list;
+std::unordered_map<uint16_t, uint16_t> local_cid_to_acl;
+
+// Cached value for whether full snoop logs are enabled. So the property isn't
+// checked for every packet.
+static bool is_btsnoop_enabled;
+static bool is_btsnoop_filtered;
+
 // TODO(zachoverflow): merge btsnoop and btsnoop_net together
 void btsnoop_net_open();
 void btsnoop_net_close();
 void btsnoop_net_write(const void* data, size_t length);
 
-static void delete_btsnoop_files();
-static bool is_btsnoop_enabled();
-static char* get_btsnoop_log_path(char* log_path);
-static char* get_btsnoop_last_log_path(char* last_log_path, char* log_path);
+static void delete_btsnoop_files(bool filtered);
+static std::string get_btsnoop_log_path(bool filtered);
+static std::string get_btsnoop_last_log_path(std::string log_path);
 static void open_next_snoop_file();
 static void btsnoop_write_packet(packet_type_t type, uint8_t* packet,
                                  bool is_received, uint64_t timestamp_us);
 
 // Module lifecycle functions
 
-static future_t* start_up(void) {
+static future_t* start_up() {
+  std::array<char, PROPERTY_VALUE_MAX> property = {};
   std::lock_guard<std::mutex> lock(btsnoop_mutex);
 
-  if (!is_btsnoop_enabled()) {
-    delete_btsnoop_files();
+  // Default mode is FILTERED on userdebug/eng build, DISABLED on user build.
+  // It can also be overwritten by modifying the global setting.
+  int is_debuggable = osi_property_get_int32(IS_DEBUGGABLE_PROPERTY, 0);
+  std::string default_mode = BTSNOOP_MODE_DISABLED;
+  if (is_debuggable) {
+    int len = osi_property_get(BTSNOOP_DEFAULT_MODE_PROPERTY, property.data(),
+                               BTSNOOP_MODE_DISABLED);
+    default_mode = std::string(property.data(), len);
+  }
+
+  // Get the actual mode
+  int len = osi_property_get(BTSNOOP_LOG_MODE_PROPERTY, property.data(),
+                             default_mode.c_str());
+  std::string btsnoop_mode(property.data(), len);
+
+  if (btsnoop_mode == BTSNOOP_MODE_FILTERED) {
+    LOG(INFO) << __func__ << ": Filtered Snoop Logs enabled";
+    is_btsnoop_enabled = true;
+    is_btsnoop_filtered = true;
+    delete_btsnoop_files(false);
+  } else if (btsnoop_mode == BTSNOOP_MODE_FULL) {
+    LOG(INFO) << __func__ << ": Snoop Logs fully enabled";
+    is_btsnoop_enabled = true;
+    is_btsnoop_filtered = false;
+    delete_btsnoop_files(true);
   } else {
+    LOG(INFO) << __func__ << ": Snoop Logs disabled";
+    is_btsnoop_enabled = false;
+    is_btsnoop_filtered = false;
+    delete_btsnoop_files(true);
+    delete_btsnoop_files(false);
+  }
+
+  if (is_btsnoop_enabled) {
     open_next_snoop_file();
     packets_per_file = osi_property_get_int32(BTSNOOP_MAX_PACKETS_PROPERTY,
                                               DEFAULT_BTSNOOP_SIZE);
@@ -104,14 +224,21 @@
 static future_t* shut_down(void) {
   std::lock_guard<std::mutex> lock(btsnoop_mutex);
 
-  if (!is_btsnoop_enabled()) {
-    delete_btsnoop_files();
+  if (is_btsnoop_enabled) {
+    if (is_btsnoop_filtered) {
+      delete_btsnoop_files(false);
+    } else {
+      delete_btsnoop_files(true);
+    }
+  } else {
+    delete_btsnoop_files(true);
+    delete_btsnoop_files(false);
   }
 
   if (logfile_fd != INVALID_FD) close(logfile_fd);
   logfile_fd = INVALID_FD;
 
-  btsnoop_net_close();
+  if (is_btsnoop_enabled) btsnoop_net_close();
 
   return NULL;
 }
@@ -129,7 +256,12 @@
   uint8_t* p = const_cast<uint8_t*>(buffer->data + buffer->offset);
 
   std::lock_guard<std::mutex> lock(btsnoop_mutex);
-  uint64_t timestamp_us = bluetooth::common::time_gettimeofday_us();
+
+  struct timespec ts_now = {};
+  clock_gettime(CLOCK_REALTIME, &ts_now);
+  uint64_t timestamp_us =
+      ((uint64_t)ts_now.tv_sec * 1000000L) + ((uint64_t)ts_now.tv_nsec / 1000);
+
   btsnoop_mem_capture(buffer, timestamp_us);
 
   if (logfile_fd == INVALID_FD) return;
@@ -152,39 +284,75 @@
   }
 }
 
-static const btsnoop_t interface = {capture};
+static void whitelist_l2c_channel(uint16_t conn_handle, uint16_t local_cid,
+                                  uint16_t remote_cid) {
+  LOG(INFO) << __func__
+            << ": Whitelisting l2cap channel. conn_handle=" << conn_handle
+            << " cid=" << loghex(local_cid) << ":" << loghex(remote_cid);
+  std::lock_guard lock(filter_list_mutex);
 
-const btsnoop_t* btsnoop_get_interface() {
-  return &interface;
+  // This will create the entry if there is no associated filter with the
+  // connection.
+  filter_list[conn_handle].addL2cCid(local_cid, remote_cid);
 }
 
-// Internal functions
-static void delete_btsnoop_files() {
-  LOG_VERBOSE(LOG_TAG, "Deleting snoop log if it exists");
-  char log_path[PROPERTY_VALUE_MAX];
-  char last_log_path[PROPERTY_VALUE_MAX + sizeof(".last")];
-  get_btsnoop_log_path(log_path);
-  get_btsnoop_last_log_path(last_log_path, log_path);
-  remove(log_path);
-  remove(last_log_path);
+static void whitelist_rfc_dlci(uint16_t local_cid, uint8_t dlci) {
+  LOG(INFO) << __func__
+            << ": Whitelisting rfcomm channel. L2CAP CID=" << loghex(local_cid)
+            << " DLCI=" << loghex(dlci);
+  std::lock_guard lock(filter_list_mutex);
+
+  tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(nullptr, local_cid);
+  filter_list[p_ccb->p_lcb->handle].addRfcDlci(dlci);
 }
 
-static bool is_btsnoop_enabled() {
-  char btsnoop_enabled[PROPERTY_VALUE_MAX] = {0};
-  osi_property_get(BTSNOOP_ENABLE_PROPERTY, btsnoop_enabled, "false");
-  return strncmp(btsnoop_enabled, "true", 4) == 0;
+static void add_rfc_l2c_channel(uint16_t conn_handle, uint16_t local_cid,
+                                uint16_t remote_cid) {
+  LOG(INFO) << __func__
+            << ": rfcomm data going over l2cap channel. conn_handle="
+            << conn_handle << " cid=" << loghex(local_cid) << ":"
+            << loghex(remote_cid);
+  std::lock_guard lock(filter_list_mutex);
+
+  filter_list[conn_handle].setRfcCid(local_cid, remote_cid);
+  local_cid_to_acl.insert({local_cid, conn_handle});
 }
 
-static char* get_btsnoop_log_path(char* btsnoop_path) {
+static void clear_l2cap_whitelist(uint16_t conn_handle, uint16_t local_cid,
+                                  uint16_t remote_cid) {
+  LOG(INFO) << __func__
+            << ": Clearing whitelist from l2cap channel. conn_handle="
+            << conn_handle << " cid=" << local_cid << ":" << remote_cid;
+
+  std::lock_guard lock(filter_list_mutex);
+  filter_list[conn_handle].removeL2cCid(local_cid, remote_cid);
+}
+
+static const btsnoop_t interface = {capture, whitelist_l2c_channel,
+                                    whitelist_rfc_dlci, add_rfc_l2c_channel,
+                                    clear_l2cap_whitelist};
+
+const btsnoop_t* btsnoop_get_interface() { return &interface; }
+
+static void delete_btsnoop_files(bool filtered) {
+  LOG(INFO) << __func__
+            << ": Deleting snoop logs if they exist. filtered = " << filtered;
+  auto log_path = get_btsnoop_log_path(filtered);
+  remove(log_path.c_str());
+  remove(get_btsnoop_last_log_path(log_path).c_str());
+}
+
+std::string get_btsnoop_log_path(bool filtered) {
+  char btsnoop_path[PROPERTY_VALUE_MAX];
   osi_property_get(BTSNOOP_PATH_PROPERTY, btsnoop_path, DEFAULT_BTSNOOP_PATH);
-  return btsnoop_path;
+  std::string result(btsnoop_path);
+  if (filtered) result = result.append(".filtered");
+
+  return result;
 }
 
-static char* get_btsnoop_last_log_path(char* last_log_path,
-                                       char* btsnoop_path) {
-  snprintf(last_log_path, PROPERTY_VALUE_MAX + sizeof(".last"), "%s.last",
-           btsnoop_path);
-  return last_log_path;
+std::string get_btsnoop_last_log_path(std::string btsnoop_path) {
+  return btsnoop_path.append(".last");
 }
 
 static void open_next_snoop_file() {
@@ -195,22 +363,20 @@
     logfile_fd = INVALID_FD;
   }
 
-  char log_path[PROPERTY_VALUE_MAX];
-  char last_log_path[PROPERTY_VALUE_MAX + sizeof(".last")];
-  get_btsnoop_log_path(log_path);
-  get_btsnoop_last_log_path(last_log_path, log_path);
+  auto log_path = get_btsnoop_log_path(is_btsnoop_filtered);
+  auto last_log_path = get_btsnoop_last_log_path(log_path);
 
-  if (rename(log_path, last_log_path) != 0 && errno != ENOENT)
-    LOG_ERROR(LOG_TAG, "%s unable to rename '%s' to '%s': %s", __func__,
-              log_path, last_log_path, strerror(errno));
+  if (rename(log_path.c_str(), last_log_path.c_str()) != 0 && errno != ENOENT)
+    LOG(ERROR) << __func__ << ": unable to rename '" << log_path << "' to '"
+               << last_log_path << "' : " << strerror(errno);
 
   mode_t prevmask = umask(0);
-  logfile_fd = open(log_path, O_WRONLY | O_CREAT | O_TRUNC,
+  logfile_fd = open(log_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
                     S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
   umask(prevmask);
   if (logfile_fd == INVALID_FD) {
-    LOG_ERROR(LOG_TAG, "%s unable to open '%s': %s", __func__, log_path,
-              strerror(errno));
+    LOG(ERROR) << __func__ << ": unable to open '" << log_path
+               << "' : " << strerror(errno);
     return;
   }
 
@@ -235,6 +401,32 @@
   return ll;
 }
 
+static bool should_filter_log(bool is_received, uint8_t* packet) {
+  uint16_t acl_handle =
+      HCID_GET_HANDLE((((uint16_t)packet[ACL_CHANNEL_OFFSET + 1]) << 8) +
+                      packet[ACL_CHANNEL_OFFSET]);
+
+  std::lock_guard lock(filter_list_mutex);
+  auto& filters = filter_list[acl_handle];
+  uint16_t l2c_channel =
+      (packet[L2C_CHANNEL_OFFSET + 1] << 8) + packet[L2C_CHANNEL_OFFSET];
+  if (filters.isRfcChannel(is_received, l2c_channel)) {
+    uint8_t rfc_event = packet[RFC_EVENT_OFFSET] & 0b11101111;
+    if (rfc_event == RFCOMM_SABME || rfc_event == RFCOMM_UA) {
+      return false;
+    }
+
+    uint8_t rfc_dlci = packet[RFC_CHANNEL_OFFSET] >> 2;
+    if (!filters.isWhitelistedDlci(rfc_dlci)) {
+      return true;
+    }
+  } else if (!filters.isWhitelistedL2c(is_received, l2c_channel)) {
+    return true;
+  }
+
+  return false;
+}
+
 static void btsnoop_write_packet(packet_type_t type, uint8_t* packet,
                                  bool is_received, uint64_t timestamp_us) {
   uint32_t length_he = 0;
@@ -261,7 +453,15 @@
 
   btsnoop_header_t header;
   header.length_original = htonl(length_he);
-  header.length_captured = header.length_original;
+
+  bool blacklisted = false;
+  if (is_btsnoop_filtered && type == kAclPacket) {
+    blacklisted = should_filter_log(is_received, packet);
+  }
+
+  header.length_captured =
+      blacklisted ? htonl(L2C_HEADER_SIZE) : header.length_original;
+  if (blacklisted) length_he = L2C_HEADER_SIZE;
   header.flags = htonl(flags);
   header.dropped_packets = 0;
   header.timestamp = htonll(timestamp_us + BTSNOOP_EPOCH_DELTA);
diff --git a/hci/src/packet_fragmenter.cc b/hci/src/packet_fragmenter.cc
index c1c61df..f688982 100644
--- a/hci/src/packet_fragmenter.cc
+++ b/hci/src/packet_fragmenter.cc
@@ -123,12 +123,10 @@
   if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ACL) {
     uint8_t* stream = packet->data;
     uint16_t handle;
-    uint16_t l2cap_length;
     uint16_t acl_length;
 
     STREAM_TO_UINT16(handle, stream);
     STREAM_TO_UINT16(acl_length, stream);
-    STREAM_TO_UINT16(l2cap_length, stream);
 
     CHECK(acl_length == packet->len - HCI_ACL_PREAMBLE_SIZE);
 
@@ -136,6 +134,13 @@
     handle = handle & HANDLE_MASK;
 
     if (boundary_flag == START_PACKET_BOUNDARY) {
+      if (acl_length < 2) {
+        LOG_WARN(LOG_TAG, "%s invalid acl_length %d", __func__, acl_length);
+        buffer_allocator->free(packet);
+        return;
+      }
+      uint16_t l2cap_length;
+      STREAM_TO_UINT16(l2cap_length, stream);
       auto map_iter = partial_packets.find(handle);
       if (map_iter != partial_packets.end()) {
         LOG_WARN(LOG_TAG,
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index f97e116..063abf9 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -466,11 +466,16 @@
   /**
    * Opens the interface and provides the callback routines
    * to the implemenation of this interface.
+   * 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.
    */
-  int (*init)(bt_callbacks_t* callbacks);
+  int (*init)(bt_callbacks_t* callbacks, bool guest_mode,
+              bool is_single_user_mode);
 
   /** Enable Bluetooth. */
-  int (*enable)(bool guest_mode);
+  int (*enable)();
 
   /** Disable Bluetooth. */
   int (*disable)(void);
diff --git a/main/Android.bp b/main/Android.bp
index 3efd993..cb300a4 100644
--- a/main/Android.bp
+++ b/main/Android.bp
@@ -34,6 +34,8 @@
         "system/bt/embdrv/sbc/encoder/include",
         "system/bt/embdrv/sbc/decoder/include",
         "system/bt/utils/include",
+        "system/security/keystore/include",
+        "hardware/interfaces/keymaster/4.0/support/include",
     ],
     logtags: ["../EventLogTags.logtags"],
     shared_libs: [
@@ -95,6 +97,9 @@
     cflags: [
         "-DBUILDCFG",
     ],
+    sanitize: {
+        scs: true,
+    },
 }
 
 cc_library_static {
diff --git a/osi/include/config.h b/osi/include/config.h
index 55adecb..47c3a3e 100644
--- a/osi/include/config.h
+++ b/osi/include/config.h
@@ -49,6 +49,9 @@
 // file on the filesystem.
 std::unique_ptr<config_t> config_new(const char* filename);
 
+// Read the checksum from the |filename|
+std::string checksum_read(const char* filename);
+
 // Clones |src|, including all of it's sections, keys, and values.
 // Returns a new config which is a copy and separated from the original;
 // changes to the new config are not reflected in any way in the original.
@@ -133,3 +136,8 @@
 // |config_save|, all comments and special formatting in the original file will
 // be lost. Neither |config| nor |filename| may be NULL.
 bool config_save(const config_t& config, const std::string& filename);
+
+// Saves the encrypted |checksum| of config file to a given |filename| Note
+// that this could be a destructive operation: if |filename| already exists,
+// it will be overwritten.
+bool checksum_save(const std::string& checksum, const std::string& filename);
diff --git a/osi/src/alarm.cc b/osi/src/alarm.cc
index 30e4ed8..bc1eee5 100644
--- a/osi/src/alarm.cc
+++ b/osi/src/alarm.cc
@@ -246,7 +246,7 @@
   CHECK(alarms != NULL);
   if (!alarm) return;
 
-  std::shared_ptr<std::recursive_mutex> local_mutex_ref = alarm->callback_mutex;
+  std::shared_ptr<std::recursive_mutex> local_mutex_ref;
   {
     std::lock_guard<std::mutex> lock(alarms_mutex);
     local_mutex_ref = alarm->callback_mutex;
diff --git a/osi/src/config.cc b/osi/src/config.cc
index e937959..de7e6e6 100644
--- a/osi/src/config.cc
+++ b/osi/src/config.cc
@@ -18,7 +18,7 @@
 
 #include "osi/include/config.h"
 
-#include <base/files/file_path.h>
+#include <base/files/file_util.h>
 #include <base/logging.h>
 #include <ctype.h>
 #include <errno.h>
@@ -84,6 +84,19 @@
   return config;
 }
 
+std::string checksum_read(const char* filename) {
+  base::FilePath path(filename);
+  if (!base::PathExists(path)) {
+    LOG(ERROR) << __func__ << ": unable to locate file '" << filename << "'";
+    return "";
+  }
+  std::string encrypted_hash;
+  if (!base::ReadFileToString(path, &encrypted_hash)) {
+    LOG(ERROR) << __func__ << ": unable to read file '" << filename << "'";
+  }
+  return encrypted_hash;
+}
+
 std::unique_ptr<config_t> config_new_clone(const config_t& src) {
   std::unique_ptr<config_t> ret = config_new_empty();
 
@@ -332,6 +345,107 @@
   return false;
 }
 
+bool checksum_save(const std::string& checksum, const std::string& filename) {
+  CHECK(!checksum.empty()) << __func__ << ": checksum cannot be empty";
+  CHECK(!filename.empty()) << __func__ << ": filename cannot be empty";
+
+  // Steps to ensure content of config checksum file gets to disk:
+  //
+  // 1) Open and write to temp file (e.g.
+  // bt_config.conf.encrypted-checksum.new). 2) Sync the temp file to disk with
+  // fsync(). 3) Rename temp file to actual config checksum file (e.g.
+  // bt_config.conf.encrypted-checksum).
+  //    This ensures atomic update.
+  // 4) Sync directory that has the conf file with fsync().
+  //    This ensures directory entries are up-to-date.
+  FILE* fp = nullptr;
+  int dir_fd = -1;
+
+  // Build temp config checksum file based on config checksum file (e.g.
+  // bt_config.conf.encrypted-checksum.new).
+  const std::string temp_filename = filename + ".new";
+  base::FilePath path(temp_filename);
+
+  // Extract directory from file path (e.g. /data/misc/bluedroid).
+  const std::string directoryname = base::FilePath(filename).DirName().value();
+  if (directoryname.empty()) {
+    LOG(ERROR) << __func__ << ": error extracting directory from '" << filename
+               << "': " << strerror(errno);
+    goto error2;
+  }
+
+  dir_fd = open(directoryname.c_str(), O_RDONLY);
+  if (dir_fd < 0) {
+    LOG(ERROR) << __func__ << ": unable to open dir '" << directoryname
+               << "': " << strerror(errno);
+    goto error2;
+  }
+
+  if (base::WriteFile(path, checksum.data(), checksum.size()) !=
+      (int)checksum.size()) {
+    LOG(ERROR) << __func__ << ": unable to write file '" << filename.c_str();
+    goto error2;
+  }
+
+  fp = fopen(temp_filename.c_str(), "rb");
+  if (!fp) {
+    LOG(ERROR) << __func__ << ": unable to write to file '" << temp_filename
+               << "': " << strerror(errno);
+    goto error2;
+  }
+
+  // Sync written temp file out to disk. fsync() is blocking until data makes it
+  // to disk.
+  if (fsync(fileno(fp)) < 0) {
+    LOG(WARNING) << __func__ << ": unable to fsync file '" << temp_filename
+                 << "': " << strerror(errno);
+  }
+
+  if (fclose(fp) == EOF) {
+    LOG(ERROR) << __func__ << ": unable to close file '" << temp_filename
+               << "': " << strerror(errno);
+    goto error2;
+  }
+  fp = nullptr;
+
+  // Change the file's permissions to Read/Write by User and Group
+  if (chmod(temp_filename.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) ==
+      -1) {
+    LOG(ERROR) << __func__ << ": unable to change file permissions '"
+               << filename << "': " << strerror(errno);
+    goto error2;
+  }
+
+  // Rename written temp file to the actual config file.
+  if (rename(temp_filename.c_str(), filename.c_str()) == -1) {
+    LOG(ERROR) << __func__ << ": unable to commit file '" << filename
+               << "': " << strerror(errno);
+    goto error2;
+  }
+
+  // This should ensure the directory is updated as well.
+  if (fsync(dir_fd) < 0) {
+    LOG(WARNING) << __func__ << ": unable to fsync dir '" << directoryname
+                 << "': " << strerror(errno);
+  }
+
+  if (close(dir_fd) < 0) {
+    LOG(ERROR) << __func__ << ": unable to close dir '" << directoryname
+               << "': " << strerror(errno);
+    goto error2;
+  }
+
+  return true;
+
+error2:
+  // This indicates there is a write issue.  Unlink as partial data is not
+  // acceptable.
+  unlink(temp_filename.c_str());
+  if (fp) fclose(fp);
+  if (dir_fd != -1) close(dir_fd);
+  return false;
+}
+
 static char* trim(char* str) {
   while (isspace(*str)) ++str;
 
diff --git a/osi/test/config_test.cc b/osi/test/config_test.cc
index 7c689c9..32858fd 100644
--- a/osi/test/config_test.cc
+++ b/osi/test/config_test.cc
@@ -1,3 +1,4 @@
+#include <base/files/file_util.h>
 #include <gtest/gtest.h>
 
 #include "AllocationTestHarness.h"
@@ -173,3 +174,24 @@
   std::unique_ptr<config_t> config = config_new(CONFIG_FILE);
   EXPECT_TRUE(config_save(*config, CONFIG_FILE));
 }
+
+TEST_F(ConfigTest, checksum_read) {
+  std::string filename = "/data/misc/bluedroid/test.checksum";
+  std::string checksum = "0x1234";
+  base::FilePath file_path(filename);
+
+  EXPECT_EQ(base::WriteFile(file_path, checksum.data(), checksum.size()),
+            (int)checksum.size());
+
+  EXPECT_EQ(checksum_read(filename.c_str()), checksum.c_str());
+}
+
+TEST_F(ConfigTest, checksum_save) {
+  std::string filename = "/data/misc/bluedroid/test.checksum";
+  std::string checksum = "0x1234";
+  base::FilePath file_path(filename);
+
+  EXPECT_TRUE(checksum_save(checksum, filename));
+
+  EXPECT_TRUE(base::PathExists(file_path));
+}
diff --git a/packet/avrcp/general_reject_packet.cc b/packet/avrcp/general_reject_packet.cc
index cde0031..db3d31a 100644
--- a/packet/avrcp/general_reject_packet.cc
+++ b/packet/avrcp/general_reject_packet.cc
@@ -19,11 +19,9 @@
 namespace bluetooth {
 namespace avrcp {
 
-std::unique_ptr<GeneralRejectBuilder> GeneralRejectBuilder::MakeBuilder(
-    BrowsePdu pdu, Status reason) {
+std::unique_ptr<GeneralRejectBuilder> GeneralRejectBuilder::MakeBuilder(Status reason) {
   std::unique_ptr<GeneralRejectBuilder> builder =
-      std::unique_ptr<GeneralRejectBuilder>(
-          new GeneralRejectBuilder(pdu, reason));
+      std::unique_ptr<GeneralRejectBuilder>(new GeneralRejectBuilder(reason));
 
   return builder;
 }
diff --git a/packet/avrcp/general_reject_packet.h b/packet/avrcp/general_reject_packet.h
index 4058fd4..b3fb2fe 100644
--- a/packet/avrcp/general_reject_packet.h
+++ b/packet/avrcp/general_reject_packet.h
@@ -25,8 +25,7 @@
  public:
   virtual ~GeneralRejectBuilder() = default;
 
-  static std::unique_ptr<GeneralRejectBuilder> MakeBuilder(BrowsePdu pdu,
-                                                           Status reason);
+  static std::unique_ptr<GeneralRejectBuilder> MakeBuilder(Status reason);
 
   virtual size_t size() const override;
   virtual bool Serialize(
@@ -35,8 +34,7 @@
  protected:
   Status reason_;
 
-  GeneralRejectBuilder(BrowsePdu pdu, Status reason)
-      : BrowsePacketBuilder(pdu), reason_(reason){};
+  GeneralRejectBuilder(Status reason) : BrowsePacketBuilder(BrowsePdu::GENERAL_REJECT), reason_(reason){};
 };
 
 }  // namespace avrcp
diff --git a/packet/avrcp/register_notification_packet.cc b/packet/avrcp/register_notification_packet.cc
index adb5e59..6bbd16a 100644
--- a/packet/avrcp/register_notification_packet.cc
+++ b/packet/avrcp/register_notification_packet.cc
@@ -39,8 +39,9 @@
 bool RegisterNotificationResponse::IsValid() const {
   if (!VendorPacket::IsValid()) return false;
   if (size() < kMinSize()) return false;
-  if (GetCType() != CType::INTERIM && GetCType() != CType::CHANGED)
+  if (GetCType() != CType::INTERIM && GetCType() != CType::CHANGED && GetCType() != CType::REJECTED) {
     return false;
+  }
 
   switch (GetEvent()) {
     case Event::VOLUME_CHANGED:
diff --git a/packet/tests/avrcp/avrcp_test_packets.h b/packet/tests/avrcp/avrcp_test_packets.h
index 13994d0..14e30e7 100644
--- a/packet/tests/avrcp/avrcp_test_packets.h
+++ b/packet/tests/avrcp/avrcp_test_packets.h
@@ -106,8 +106,8 @@
     0x00, 0x05, 0x0d, 0x00, 0x00, 0x00, 0x00};
 
 // AVRCP Register Notification without any parameter
-std::vector<uint8_t> register_notification_invalid = {
-    0x03, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31, 0x00, 0x00, 0x05};
+std::vector<uint8_t> register_notification_invalid = {0x03, 0x48, 0x00, 0x00, 0x19, 0x58, 0x31,
+                                                      0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};
 
 // AVRCP Interim Playback Status Notification
 std::vector<uint8_t> interim_play_status_notification = {
@@ -208,9 +208,8 @@
 //    start_item = 0x00
 //    end_item = 0x05
 //    attributes_requested: All Items
-std::vector<uint8_t> get_folder_items_request_now_playing = {
-    0x71, 0x00, 0x0e, 0x03, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x05, 0x00};
+std::vector<uint8_t> get_folder_items_request_now_playing = {0x71, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x00,
+                                                             0x00, 0x00, 0x00, 0x00, 0x05, 0x00};
 
 // AVRCP Browse Get Folder Items Response packet with range out of bounds error
 std::vector<uint8_t> get_folder_items_error_response = {0x71, 0x00, 0x01, 0x0b};
@@ -356,4 +355,36 @@
 std::vector<uint8_t> set_absolute_volume_response = {
     0x09, 0x48, 0x00, 0x00, 0x19, 0x58, 0x50, 0x00, 0x00, 0x01, 0x43};
 
+// Invalid Packets
+// Short Vendor Packet
+std::vector<uint8_t> short_vendor_packet = {0x01, 0x48, 0x00, 0x00, 0x19, 0x58, 0x10, 0x00, 0x00, 0x01};
+
+// Short Get Capabilities Request Packet
+std::vector<uint8_t> short_get_capabilities_request = {0x01, 0x48, 0x00, 0x00, 0x19, 0x58, 0x10, 0x00, 0x00, 0x00};
+
+// Short Get Element Attributes Request Packet
+std::vector<uint8_t> short_get_element_attributes_request = {0x01, 0x48, 0x00, 0x00, 0x19,
+                                                             0x58, 0x20, 0x00, 0x00, 0x00};
+
+// Short Play Item Request Packet
+std::vector<uint8_t> short_play_item_request = {0x00, 0x48, 0x00, 0x00, 0x19, 0x58, 0x74, 0x00, 0x00, 0x00};
+
+// Short Set Addressed Player Request Packet
+std::vector<uint8_t> short_set_addressed_player_request = {0x00, 0x48, 0x00, 0x00, 0x19, 0x58, 0x60, 0x00, 0x00, 0x00};
+
+// Short Browse Packet
+std::vector<uint8_t> short_browse_packet = {0x71, 0x00, 0x0a};
+
+// Short Get Folder Items Request Packet
+std::vector<uint8_t> short_get_folder_items_request = {0x71, 0x00, 0x00};
+
+// Short Get Total Number of Items Request Packet
+std::vector<uint8_t> short_get_total_number_of_items_request = {0x75, 0x00, 0x00};
+
+// Short Change Path Request Packet
+std::vector<uint8_t> short_change_path_request = {0x72, 0x00, 0x00};
+
+// Short Get Item Attributes Request Packet
+std::vector<uint8_t> short_get_item_attributes_request = {0x73, 0x00, 0x00};
+
 }  // namespace
diff --git a/packet/tests/avrcp/general_reject_packet_test.cc b/packet/tests/avrcp/general_reject_packet_test.cc
index e27d0b7..4d73dba 100644
--- a/packet/tests/avrcp/general_reject_packet_test.cc
+++ b/packet/tests/avrcp/general_reject_packet_test.cc
@@ -26,8 +26,7 @@
 using TestGeneralRejectPacket = TestPacketType<BrowsePacket>;
 
 TEST(GeneralRejectPacketBuilderTest, buildPacketTest) {
-  auto builder = GeneralRejectBuilder::MakeBuilder(BrowsePdu::GENERAL_REJECT,
-                                                   Status::INVALID_COMMAND);
+  auto builder = GeneralRejectBuilder::MakeBuilder(Status::INVALID_COMMAND);
 
   ASSERT_EQ(builder->size(), general_reject_invalid_command_packet.size());
 
diff --git a/profile/avrcp/device.cc b/profile/avrcp/device.cc
index cf94cfc..4ca624b 100644
--- a/profile/avrcp/device.cc
+++ b/profile/avrcp/device.cc
@@ -80,6 +80,13 @@
   CHECK(media_interface_);
   DEVICE_VLOG(3) << __func__ << ": pdu=" << pkt->GetCommandPdu();
 
+  if (!pkt->IsValid()) {
+    DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+    auto response = RejectBuilder::MakeBuilder(static_cast<CommandPdu>(0), Status::INVALID_COMMAND);
+    send_message(label, false, std::move(response));
+    return;
+  }
+
   // All CTypes at and above NOT_IMPLEMENTED are all response types.
   if (pkt->GetCType() == CType::NOT_IMPLEMENTED) {
     return;
@@ -125,9 +132,15 @@
     } break;
 
     case CommandPdu::GET_ELEMENT_ATTRIBUTES: {
-      media_interface_->GetSongInfo(base::Bind(
-          &Device::GetElementAttributesResponse, weak_ptr_factory_.GetWeakPtr(),
-          label, Packet::Specialize<GetElementAttributesRequest>(pkt)));
+      auto get_element_attributes_request_pkt = Packet::Specialize<GetElementAttributesRequest>(pkt);
+
+      if (!get_element_attributes_request_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));
+      }
+      media_interface_->GetSongInfo(base::Bind(&Device::GetElementAttributesResponse, weak_ptr_factory_.GetWeakPtr(),
+                                               label, get_element_attributes_request_pkt));
     } break;
 
     case CommandPdu::GET_PLAY_STATUS: {
@@ -145,9 +158,17 @@
       // this currently since the current implementation only has one
       // player and the player will never change, but we need it for a
       // more complete implementation.
-      media_interface_->GetMediaPlayerList(base::Bind(
-          &Device::HandleSetAddressedPlayer, weak_ptr_factory_.GetWeakPtr(),
-          label, Packet::Specialize<SetAddressedPlayerRequest>(pkt)));
+      auto set_addressed_player_request = Packet::Specialize<SetAddressedPlayerRequest>(pkt);
+
+      if (!set_addressed_player_request->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));
+        return;
+      }
+
+      media_interface_->GetMediaPlayerList(base::Bind(&Device::HandleSetAddressedPlayer, weak_ptr_factory_.GetWeakPtr(),
+                                                      label, set_addressed_player_request));
     } break;
 
     default: {
@@ -164,6 +185,13 @@
   DEVICE_VLOG(4) << __func__
                  << ": capability=" << pkt->GetCapabilityRequested();
 
+  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));
+    return;
+  }
+
   switch (pkt->GetCapabilityRequested()) {
     case Capability::COMPANY_ID: {
       auto response =
@@ -202,7 +230,7 @@
 void Device::HandleNotification(
     uint8_t label, const std::shared_ptr<RegisterNotificationRequest>& pkt) {
   if (!pkt->IsValid()) {
-    DEVICE_LOG(ERROR) << __func__ << ": Request packet is not valid";
+    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));
@@ -307,6 +335,17 @@
 void Device::HandleVolumeChanged(
     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) {
@@ -546,6 +585,7 @@
     uint8_t label, std::shared_ptr<GetElementAttributesRequest> pkt,
     SongInfo info) {
   DEVICE_VLOG(2) << __func__;
+
   auto get_element_attributes_pkt = pkt;
   auto attributes_requested =
       get_element_attributes_pkt->GetAttributesRequested();
@@ -570,10 +610,15 @@
 }
 
 void Device::MessageReceived(uint8_t label, std::shared_ptr<Packet> pkt) {
+  if (!pkt->IsValid()) {
+    DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+    auto response = RejectBuilder::MakeBuilder(static_cast<CommandPdu>(0), Status::INVALID_COMMAND);
+    send_message(label, false, std::move(response));
+    return;
+  }
+
   DEVICE_VLOG(4) << __func__ << ": opcode=" << pkt->GetOpcode();
-
   active_labels_.insert(label);
-
   switch (pkt->GetOpcode()) {
     // TODO (apanicke): Remove handling of UNIT_INFO and SUBUNIT_INFO from
     // the AVRC_API and instead handle it here to reduce fragmentation.
@@ -583,6 +628,14 @@
     } break;
     case Opcode::PASS_THROUGH: {
       auto pass_through_packet = Packet::Specialize<PassThroughPacket>(pkt);
+
+      if (!pass_through_packet->IsValid()) {
+        DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+        auto response = RejectBuilder::MakeBuilder(static_cast<CommandPdu>(0), Status::INVALID_COMMAND);
+        send_message(label, false, std::move(response));
+        return;
+      }
+
       auto response = PassThroughPacketBuilder::MakeBuilder(
           true, pass_through_packet->GetKeyState() == KeyState::PUSHED,
           pass_through_packet->GetOperationId());
@@ -633,6 +686,13 @@
   DEVICE_VLOG(2) << __func__ << ": scope=" << pkt->GetScope()
                  << " uid=" << pkt->GetUid();
 
+  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));
+    return;
+  }
+
   std::string media_id = "";
   switch (pkt->GetScope()) {
     case Scope::NOW_PLAYING:
@@ -680,6 +740,13 @@
 
 void Device::BrowseMessageReceived(uint8_t label,
                                    std::shared_ptr<BrowsePacket> pkt) {
+  if (!pkt->IsValid()) {
+    DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+    auto response = GeneralRejectBuilder::MakeBuilder(Status::INVALID_COMMAND);
+    send_message(label, false, std::move(response));
+    return;
+  }
+
   DEVICE_VLOG(1) << __func__ << ": pdu=" << pkt->GetPdu();
 
   switch (pkt->GetPdu()) {
@@ -704,8 +771,7 @@
       break;
     default:
       DEVICE_LOG(WARNING) << __func__ << ": " << pkt->GetPdu();
-      auto response = GeneralRejectBuilder::MakeBuilder(
-          BrowsePdu::GENERAL_REJECT, Status::INVALID_COMMAND);
+      auto response = GeneralRejectBuilder::MakeBuilder(Status::INVALID_COMMAND);
       send_message(label, true, std::move(response));
 
       break;
@@ -714,6 +780,15 @@
 
 void Device::HandleGetFolderItems(uint8_t label,
                                   std::shared_ptr<GetFolderItemsRequest> pkt) {
+  if (!pkt->IsValid()) {
+    // The specific get folder items builder is unimportant on failure.
+    DEVICE_LOG(WARNING) << __func__ << ": Get folder items request packet is not valid";
+    auto response =
+        GetFolderItemsResponseBuilder::MakePlayerListBuilder(Status::INVALID_PARAMETER, 0x0000, browse_mtu_);
+    send_message(label, true, std::move(response));
+    return;
+  }
+
   DEVICE_VLOG(2) << __func__ << ": scope=" << pkt->GetScope();
 
   switch (pkt->GetScope()) {
@@ -735,12 +810,21 @@
       break;
     default:
       DEVICE_LOG(ERROR) << __func__ << ": " << pkt->GetScope();
+      auto response = GetFolderItemsResponseBuilder::MakePlayerListBuilder(Status::INVALID_PARAMETER, 0, browse_mtu_);
+      send_message(label, true, std::move(response));
       break;
   }
 }
 
 void Device::HandleGetTotalNumberOfItems(
     uint8_t label, std::shared_ptr<GetTotalNumberOfItemsRequest> pkt) {
+  if (!pkt->IsValid()) {
+    DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+    auto response = GetTotalNumberOfItemsResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0x0000, 0);
+    send_message(label, true, std::move(response));
+    return;
+  }
+
   DEVICE_VLOG(2) << __func__ << ": scope=" << pkt->GetScope();
 
   switch (pkt->GetScope()) {
@@ -796,6 +880,13 @@
 
 void Device::HandleChangePath(uint8_t label,
                               std::shared_ptr<ChangePathRequest> pkt) {
+  if (!pkt->IsValid()) {
+    DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+    auto response = ChangePathResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0);
+    send_message(label, true, std::move(response));
+    return;
+  }
+
   DEVICE_VLOG(2) << __func__ << ": direction=" << pkt->GetDirection()
                  << " uid=" << loghex(pkt->GetUid());
 
@@ -846,6 +937,13 @@
 
 void Device::HandleGetItemAttributes(
     uint8_t label, std::shared_ptr<GetItemAttributesRequest> pkt) {
+  if (!pkt->IsValid()) {
+    DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+    auto builder = GetItemAttributesResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, browse_mtu_);
+    send_message(label, true, std::move(builder));
+    return;
+  }
+
   DEVICE_VLOG(2) << __func__ << ": scope=" << pkt->GetScope()
                  << " uid=" << loghex(pkt->GetUid())
                  << " uid counter=" << loghex(pkt->GetUidCounter());
@@ -856,6 +954,7 @@
     send_message(label, true, std::move(builder));
     return;
   }
+
   switch (pkt->GetScope()) {
     case Scope::NOW_PLAYING: {
       media_interface_->GetNowPlayingList(
@@ -1121,6 +1220,13 @@
 
 void Device::HandleSetBrowsedPlayer(
     uint8_t label, std::shared_ptr<SetBrowsedPlayerRequest> pkt) {
+  if (!pkt->IsValid()) {
+    DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid";
+    auto response = SetBrowsedPlayerResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0x0000, 0, 0, "");
+    send_message(label, true, std::move(response));
+    return;
+  }
+
   DEVICE_VLOG(2) << __func__ << ": player_id=" << pkt->GetPlayerId();
   media_interface_->SetBrowsedPlayer(
       pkt->GetPlayerId(),
diff --git a/profile/avrcp/tests/avrcp_device_test.cc b/profile/avrcp/tests/avrcp_device_test.cc
index 206e7e2..d221e1b 100644
--- a/profile/avrcp/tests/avrcp_device_test.cc
+++ b/profile/avrcp/tests/avrcp_device_test.cc
@@ -1358,6 +1358,126 @@
   SendMessage(1, reg_notif_request);
 }
 
+TEST_F(AvrcpDeviceTest, invalidVendorPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = RejectBuilder::MakeBuilder(static_cast<CommandPdu>(0), Status::INVALID_COMMAND);
+  EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestAvrcpPacket::Make(short_vendor_packet);
+  SendMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidCapabilitiesPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = RejectBuilder::MakeBuilder(CommandPdu::GET_CAPABILITIES, Status::INVALID_PARAMETER);
+  EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestAvrcpPacket::Make(short_get_capabilities_request);
+  SendMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidGetElementAttributesPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = RejectBuilder::MakeBuilder(CommandPdu::GET_ELEMENT_ATTRIBUTES, Status::INVALID_PARAMETER);
+  EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestAvrcpPacket::Make(short_get_element_attributes_request);
+  SendMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidPlayItemPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = RejectBuilder::MakeBuilder(CommandPdu::PLAY_ITEM, Status::INVALID_PARAMETER);
+  EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestAvrcpPacket::Make(short_play_item_request);
+  SendMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidSetAddressedPlayerPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = RejectBuilder::MakeBuilder(CommandPdu::SET_ADDRESSED_PLAYER, Status::INVALID_PARAMETER);
+  EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestAvrcpPacket::Make(short_set_addressed_player_request);
+  SendMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidBrowsePacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = GeneralRejectBuilder::MakeBuilder(Status::INVALID_COMMAND);
+  EXPECT_CALL(response_cb, Call(1, false, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestBrowsePacket::Make(short_browse_packet);
+  SendBrowseMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidGetFolderItemsPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = GetFolderItemsResponseBuilder::MakePlayerListBuilder(Status::INVALID_PARAMETER, 0x0000, 0xFFFF);
+  EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestBrowsePacket::Make(short_get_folder_items_request);
+  SendBrowseMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidGetTotalNumberOfItemsPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = GetTotalNumberOfItemsResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0x0000, 0xFFFF);
+  EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestBrowsePacket::Make(short_get_total_number_of_items_request);
+  SendBrowseMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidChangePathPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = ChangePathResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0);
+  EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestBrowsePacket::Make(short_change_path_request);
+  SendBrowseMessage(1, short_packet);
+}
+
+TEST_F(AvrcpDeviceTest, invalidGetItemAttributesPacketTest) {
+  MockMediaInterface interface;
+  NiceMock<MockA2dpInterface> a2dp_interface;
+
+  test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+  auto rsp = GetItemAttributesResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0xFFFF);
+  EXPECT_CALL(response_cb, Call(1, true, matchPacket(std::move(rsp)))).Times(1);
+  auto short_packet = TestBrowsePacket::Make(short_get_item_attributes_request);
+  SendBrowseMessage(1, short_packet);
+}
+
 }  // namespace avrcp
 }  // namespace bluetooth
 
diff --git a/service/adapter.cc b/service/adapter.cc
index 669aeff..4d414dd 100644
--- a/service/adapter.cc
+++ b/service/adapter.cc
@@ -230,7 +230,7 @@
 
   bool IsEnabled() const override { return state_.load() == ADAPTER_STATE_ON; }
 
-  bool Enable(bool start_restricted) override {
+  bool Enable() override {
     AdapterState current_state = GetState();
     if (current_state != ADAPTER_STATE_OFF) {
       LOG(INFO) << "Adapter not disabled - state: "
@@ -243,8 +243,7 @@
     state_ = ADAPTER_STATE_TURNING_ON;
     NotifyAdapterStateChanged(current_state, state_);
 
-    int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable(
-        start_restricted);
+    int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable();
     if (status != BT_STATUS_SUCCESS) {
       LOG(ERROR) << "Failed to enable Bluetooth - status: "
                  << BtStatusText((const bt_status_t)status);
diff --git a/service/adapter.h b/service/adapter.h
index edb8afe..a4e517c 100644
--- a/service/adapter.h
+++ b/service/adapter.h
@@ -119,10 +119,7 @@
   // to the controller, otherwise returns false. A successful call to this
   // method only means that the enable request has been sent to the Bluetooth
   // controller and does not imply that the operation itself succeeded.
-  // The |start_restricted| flag enables 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.
-  virtual bool Enable(bool start_restricted) = 0;
+  virtual bool Enable() = 0;
 
   // Powers off the Bluetooth radio. Returns true, if the disable request was
   // successfully sent to the Bluetooth controller.
diff --git a/service/client/main.cc b/service/client/main.cc
index 43228a4..6458b2d 100644
--- a/service/client/main.cc
+++ b/service/client/main.cc
@@ -389,25 +389,8 @@
 }
 
 void HandleEnable(IBluetooth* bt_iface, const vector<string>& args) {
-  bool is_restricted_mode = false;
-
-  for (const auto& iter : args) {
-    const std::string& arg = iter;
-    if (arg == "-h") {
-      static const char kUsage[] =
-          "Usage: start-adv [flags]\n"
-          "\n"
-          "Flags:\n"
-          "\t--restricted|-r\tStart in restricted mode\n";
-      cout << kUsage << endl;
-      return;
-    } else if (arg == "--restricted" || arg == "-r") {
-      is_restricted_mode = true;
-    }
-  }
-
   bool status;
-  bt_iface->Enable(is_restricted_mode, &status);
+  bt_iface->Enable(&status);
   PrintCommandStatus(status);
 }
 
diff --git a/service/common/android/bluetooth/IBluetooth.aidl b/service/common/android/bluetooth/IBluetooth.aidl
index 3986ad7..46c7654 100644
--- a/service/common/android/bluetooth/IBluetooth.aidl
+++ b/service/common/android/bluetooth/IBluetooth.aidl
@@ -32,7 +32,7 @@
 interface IBluetooth {
   boolean IsEnabled();
   int GetState();
-  boolean Enable(boolean startRestricted);
+  boolean Enable();
   boolean EnableNoAutoConnect();
   boolean Disable();
 
diff --git a/service/daemon.cc b/service/daemon.cc
index a64c2d8..439c2c2 100644
--- a/service/daemon.cc
+++ b/service/daemon.cc
@@ -59,7 +59,7 @@
   // ipc::IPCManager::Delegate implementation:
   void OnIPCHandlerStarted(ipc::IPCManager::Type /* type */) override {
     if (!settings_->EnableOnStart()) return;
-    adapter_->Enable(false /* start_restricted */);
+    adapter_->Enable();
   }
 
   void OnIPCHandlerStopped(ipc::IPCManager::Type /* type */) override {
diff --git a/service/hal/bluetooth_interface.cc b/service/hal/bluetooth_interface.cc
index a08fb7b..5ca220c 100644
--- a/service/hal/bluetooth_interface.cc
+++ b/service/hal/bluetooth_interface.cc
@@ -254,7 +254,7 @@
 
     // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API
     // callbacks.
-    status = hal_iface_->init(&bt_callbacks);
+    status = hal_iface_->init(&bt_callbacks, false, false);
     if (status != BT_STATUS_SUCCESS) {
       LOG(ERROR) << "Failed to initialize Bluetooth stack";
       return false;
diff --git a/service/hal/fake_bluetooth_interface.cc b/service/hal/fake_bluetooth_interface.cc
index 7979155..f1d03ad 100644
--- a/service/hal/fake_bluetooth_interface.cc
+++ b/service/hal/fake_bluetooth_interface.cc
@@ -23,7 +23,7 @@
 
 FakeBluetoothInterface::Manager g_hal_manager;
 
-int FakeHALEnable(bool start_restricted) {
+int FakeHALEnable() {
   return g_hal_manager.enable_succeed ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
diff --git a/service/ipc/binder/bluetooth_binder_server.cc b/service/ipc/binder/bluetooth_binder_server.cc
index ca36019..097abb7 100644
--- a/service/ipc/binder/bluetooth_binder_server.cc
+++ b/service/ipc/binder/bluetooth_binder_server.cc
@@ -64,10 +64,9 @@
   return Status::ok();
 }
 
-Status BluetoothBinderServer::Enable(bool start_restricted,
-                                     bool* _aidl_return) {
+Status BluetoothBinderServer::Enable(bool* _aidl_return) {
   VLOG(2) << __func__;
-  *_aidl_return = adapter_->Enable(start_restricted);
+  *_aidl_return = adapter_->Enable();
   return Status::ok();
 }
 
diff --git a/service/ipc/binder/bluetooth_binder_server.h b/service/ipc/binder/bluetooth_binder_server.h
index bfeb589..7131e8b 100644
--- a/service/ipc/binder/bluetooth_binder_server.h
+++ b/service/ipc/binder/bluetooth_binder_server.h
@@ -71,7 +71,7 @@
   // IBluetooth overrides:
   Status IsEnabled(bool* _aidl_return) override;
   Status GetState(int32_t* _aidl_return) override;
-  Status Enable(bool start_restricted, bool* _aidl_return) override;
+  Status Enable(bool* _aidl_return) override;
   Status EnableNoAutoConnect(bool* _aidl_return) override;
   Status Disable(bool* _aidl_return) override;
 
diff --git a/service/test/adapter_unittest.cc b/service/test/adapter_unittest.cc
index e6f5d10..b1cedc1 100644
--- a/service/test/adapter_unittest.cc
+++ b/service/test/adapter_unittest.cc
@@ -124,12 +124,12 @@
   EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState());
 
   // Enable fails at HAL level
-  EXPECT_FALSE(adapter_->Enable(false));
+  EXPECT_FALSE(adapter_->Enable());
   EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState());
 
   // Enable success
   fake_hal_manager_->enable_succeed = true;
-  EXPECT_TRUE(adapter_->Enable(false));
+  EXPECT_TRUE(adapter_->Enable());
 
   // Should have received a state update.
   EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, observer.prev_state());
@@ -137,7 +137,7 @@
 
   // Enable fails because not disabled
   EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_ON, adapter_->GetState());
-  EXPECT_FALSE(adapter_->Enable(false));
+  EXPECT_FALSE(adapter_->Enable());
 
   // Adapter state updates properly
   fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON);
@@ -148,7 +148,7 @@
   EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state());
 
   // Enable fails because already enabled
-  EXPECT_FALSE(adapter_->Enable(false));
+  EXPECT_FALSE(adapter_->Enable());
 }
 
 TEST_F(AdapterTest, Disable) {
diff --git a/service/test/mock_adapter.h b/service/test/mock_adapter.h
index 2c496b1..b652026 100644
--- a/service/test/mock_adapter.h
+++ b/service/test/mock_adapter.h
@@ -32,7 +32,7 @@
   MOCK_METHOD1(RemoveObserver, void(Observer*));
   MOCK_CONST_METHOD0(GetState, AdapterState());
   MOCK_CONST_METHOD0(IsEnabled, bool());
-  MOCK_METHOD1(Enable, bool(bool));
+  MOCK_METHOD0(Enable, bool());
   MOCK_METHOD0(Disable, bool());
   MOCK_CONST_METHOD0(GetName, std::string());
   MOCK_METHOD1(SetName, bool(const std::string&));
diff --git a/stack/Android.bp b/stack/Android.bp
index 03f93a5..d90d6b8 100644
--- a/stack/Android.bp
+++ b/stack/Android.bp
@@ -178,7 +178,6 @@
     shared_libs: [
         "libcutils",
         "liblog",
-        "libstatslog",
     ],
     required: [
         "libldacBT_enc",
@@ -281,6 +280,7 @@
         "rfcomm/rfc_ts_frames.cc",
         "rfcomm/rfc_utils.cc",
         "test/common/mock_btm_layer.cc",
+        "test/common/mock_btsnoop_module.cc",
         "test/common/mock_btu_layer.cc",
         "test/common/mock_l2cap_layer.cc",
         "test/common/stack_test_packet_utils.cc",
diff --git a/stack/a2dp/a2dp_vendor_aptx_encoder.cc b/stack/a2dp/a2dp_vendor_aptx_encoder.cc
index e7d0145..0d605c0 100644
--- a/stack/a2dp/a2dp_vendor_aptx_encoder.cc
+++ b/stack/a2dp/a2dp_vendor_aptx_encoder.cc
@@ -26,7 +26,6 @@
 #include "a2dp_vendor.h"
 #include "a2dp_vendor_aptx.h"
 #include "bt_common.h"
-#include "common/scoped_scs_exit.h"
 #include "common/time_util.h"
 #include "osi/include/log.h"
 #include "osi/include/osi.h"
@@ -55,25 +54,6 @@
 static tAPTX_ENCODER_ENCODE_STEREO aptx_encoder_encode_stereo_func;
 static tAPTX_ENCODER_SIZEOF_PARAMS aptx_encoder_sizeof_params_func;
 
-__attribute__((no_sanitize("shadow-call-stack")))
-static int aptx_encoder_init(void* state, short endian) {
-  ScopedSCSExit x;
-  return aptx_encoder_init_func(state, endian);
-}
-
-__attribute__((no_sanitize("shadow-call-stack")))
-static int aptx_encoder_encode_stereo(void* state, void* pcmL, void* pcmR,
-                                      void* buffer) {
-  ScopedSCSExit x;
-  return aptx_encoder_encode_stereo_func(state, pcmL, pcmR, buffer);
-}
-
-__attribute__((no_sanitize("shadow-call-stack")))
-static int aptx_encoder_sizeof_params() {
-  ScopedSCSExit x;
-  return aptx_encoder_sizeof_params_func();
-}
-
 // offset
 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
 #define A2DP_APTX_OFFSET (AVDT_MEDIA_OFFSET + 1)
@@ -212,9 +192,9 @@
 #endif
 
   a2dp_aptx_encoder_cb.aptx_encoder_state =
-      osi_malloc(aptx_encoder_sizeof_params());
+      osi_malloc(aptx_encoder_sizeof_params_func());
   if (a2dp_aptx_encoder_cb.aptx_encoder_state != NULL) {
-    aptx_encoder_init(a2dp_aptx_encoder_cb.aptx_encoder_state, 0);
+    aptx_encoder_init_func(a2dp_aptx_encoder_cb.aptx_encoder_state, 0);
   } else {
     LOG_ERROR(LOG_TAG, "%s: Cannot allocate aptX encoder state", __func__);
     // TODO: Return an error?
@@ -486,8 +466,8 @@
       pcmR[i] = (uint16_t) * (data16_in + ((2 * j) + 1));
     }
 
-    aptx_encoder_encode_stereo(a2dp_aptx_encoder_cb.aptx_encoder_state, &pcmL,
-                               &pcmR, &encoded_sample);
+    aptx_encoder_encode_stereo_func(a2dp_aptx_encoder_cb.aptx_encoder_state,
+                                    &pcmL, &pcmR, &encoded_sample);
 
     data_out[*data_out_index + 0] = (uint8_t)((encoded_sample[0] >> 8) & 0xff);
     data_out[*data_out_index + 1] = (uint8_t)((encoded_sample[0] >> 0) & 0xff);
diff --git a/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc b/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc
index d271e0d..fb782dd 100644
--- a/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc
+++ b/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc
@@ -26,7 +26,6 @@
 #include "a2dp_vendor.h"
 #include "a2dp_vendor_aptx_hd.h"
 #include "bt_common.h"
-#include "common/scoped_scs_exit.h"
 #include "common/time_util.h"
 #include "osi/include/log.h"
 #include "osi/include/osi.h"
@@ -56,25 +55,6 @@
 static tAPTX_HD_ENCODER_ENCODE_STEREO aptx_hd_encoder_encode_stereo_func;
 static tAPTX_HD_ENCODER_SIZEOF_PARAMS aptx_hd_encoder_sizeof_params_func;
 
-__attribute__((no_sanitize("shadow-call-stack")))
-static int aptx_hd_encoder_init(void* state, short endian) {
-  ScopedSCSExit x;
-  return aptx_hd_encoder_init_func(state, endian);
-}
-
-__attribute__((no_sanitize("shadow-call-stack")))
-static int aptx_hd_encoder_encode_stereo(void* state, void* pcmL, void* pcmR,
-                                         void* buffer) {
-  ScopedSCSExit x;
-  return aptx_hd_encoder_encode_stereo_func(state, pcmL, pcmR, buffer);
-}
-
-__attribute__((no_sanitize("shadow-call-stack")))
-static int aptx_hd_encoder_sizeof_params() {
-  ScopedSCSExit x;
-  return aptx_hd_encoder_sizeof_params_func();
-}
-
 // offset
 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
 #define A2DP_APTX_HD_OFFSET (AVDT_MEDIA_OFFSET + 1)
@@ -213,9 +193,9 @@
 #endif
 
   a2dp_aptx_hd_encoder_cb.aptx_hd_encoder_state =
-      osi_malloc(aptx_hd_encoder_sizeof_params());
+      osi_malloc(aptx_hd_encoder_sizeof_params_func());
   if (a2dp_aptx_hd_encoder_cb.aptx_hd_encoder_state != NULL) {
-    aptx_hd_encoder_init(a2dp_aptx_hd_encoder_cb.aptx_hd_encoder_state, 0);
+    aptx_hd_encoder_init_func(a2dp_aptx_hd_encoder_cb.aptx_hd_encoder_state, 0);
   } else {
     LOG_ERROR(LOG_TAG, "%s: Cannot allocate aptX-HD encoder state", __func__);
     // TODO: Return an error?
@@ -480,7 +460,7 @@
       p += 3;
     }
 
-    aptx_hd_encoder_encode_stereo(
+    aptx_hd_encoder_encode_stereo_func(
         a2dp_aptx_hd_encoder_cb.aptx_hd_encoder_state, &pcmL, &pcmR,
         &encoded_sample);
 
diff --git a/stack/avct/avct_api.cc b/stack/avct/avct_api.cc
index 5ced71f..51e2daf 100644
--- a/stack/avct/avct_api.cc
+++ b/stack/avct/avct_api.cc
@@ -56,7 +56,8 @@
   AVCT_TRACE_API("AVCT_Register");
 
   /* register PSM with L2CAP */
-  L2CA_Register(AVCT_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_appl);
+  L2CA_Register(AVCT_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_appl,
+                true /* enable_snoop */);
 
   /* set security level */
   BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVCTP, sec_mask, AVCT_PSM, 0,
@@ -68,7 +69,8 @@
   memset(&avct_cb, 0, sizeof(tAVCT_CB));
 
   /* Include the browsing channel which uses eFCR */
-  L2CA_Register(AVCT_BR_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_br_appl);
+  L2CA_Register(AVCT_BR_PSM, (tL2CAP_APPL_INFO*)&avct_l2c_br_appl,
+                true /*enable_snoop*/);
 
   /* AVCTP browsing channel uses the same security service as AVCTP control
    * channel */
diff --git a/stack/avct/avct_lcb_act.cc b/stack/avct/avct_lcb_act.cc
index faa098b..eec049d 100644
--- a/stack/avct/avct_lcb_act.cc
+++ b/stack/avct/avct_lcb_act.cc
@@ -53,6 +53,12 @@
   uint8_t pkt_type;
   BT_HDR* p_ret;
 
+  if (p_buf->len < 1) {
+    osi_free(p_buf);
+    p_ret = NULL;
+    return p_ret;
+  }
+
   /* parse the message header */
   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   pkt_type = AVCT_PKT_TYPE(p);
diff --git a/stack/avdt/avdt_api.cc b/stack/avdt/avdt_api.cc
index 903862e..9350c31 100644
--- a/stack/avdt/avdt_api.cc
+++ b/stack/avdt/avdt_api.cc
@@ -90,7 +90,8 @@
  ******************************************************************************/
 void AVDT_Register(AvdtpRcb* p_reg, tAVDT_CTRL_CBACK* p_cback) {
   /* register PSM with L2CAP */
-  L2CA_Register(AVDT_PSM, (tL2CAP_APPL_INFO*)&avdt_l2c_appl);
+  L2CA_Register(AVDT_PSM, (tL2CAP_APPL_INFO*)&avdt_l2c_appl,
+                true /* enable_snoop */);
 
   /* set security level */
   BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
diff --git a/stack/avdt/avdt_msg.cc b/stack/avdt/avdt_msg.cc
index 0ac9b64..853f369 100644
--- a/stack/avdt/avdt_msg.cc
+++ b/stack/avdt/avdt_msg.cc
@@ -586,6 +586,10 @@
     /* parse individual information elements with additional parameters */
     switch (elem) {
       case AVDT_CAT_RECOV:
+        if ((p_end - p) < 3) {
+          err = AVDT_ERR_PAYLOAD;
+          break;
+        }
         p_cfg->recov_type = *p++;
         p_cfg->recov_mrws = *p++;
         p_cfg->recov_mnmp = *p++;
@@ -617,6 +621,10 @@
         break;
 
       case AVDT_CAT_HDRCMP:
+        if ((p_end - p) < 1) {
+          err = AVDT_ERR_PAYLOAD;
+          break;
+        }
         p_cfg->hdrcmp_mask = *p++;
         break;
 
@@ -1191,6 +1199,14 @@
 
   /* parse the message header */
   p = (uint8_t*)(p_buf + 1) + p_buf->offset;
+
+  /* Check if is valid length */
+  if (p_buf->len < 1) {
+    android_errorWriteLog(0x534e4554, "78287084");
+    osi_free(p_buf);
+    p_ret = NULL;
+    return p_ret;
+  }
   AVDT_MSG_PRS_PKT_TYPE(p, pkt_type);
 
   /* quick sanity check on length */
@@ -1499,8 +1515,8 @@
   uint8_t pkt_type;
   uint8_t msg_type;
   uint8_t sig = 0;
-  tAVDT_MSG msg;
-  AvdtpSepConfig cfg;
+  tAVDT_MSG msg{};
+  AvdtpSepConfig cfg{};
   uint8_t err;
   uint8_t evt = 0;
   uint8_t scb_hdl;
diff --git a/stack/avrc/avrc_pars_tg.cc b/stack/avrc/avrc_pars_tg.cc
index c0504ee..22471bd 100644
--- a/stack/avrc/avrc_pars_tg.cc
+++ b/stack/avrc/avrc_pars_tg.cc
@@ -135,15 +135,16 @@
       if (!AVRC_IS_VALID_CAP_ID(p_result->get_caps.capability_id))
         status = AVRC_STS_BAD_PARAM;
       else if (len != 1)
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       break;
 
     case AVRC_PDU_LIST_PLAYER_APP_ATTR: /* 0x11 */
       /* no additional parameters */
-      if (len != 0) status = AVRC_STS_INTERNAL_ERR;
+      if (len != 0) return AVRC_STS_INTERNAL_ERR;
       break;
 
     case AVRC_PDU_LIST_PLAYER_APP_VALUES: /* 0x12 */
+      if (len == 0) return AVRC_STS_INTERNAL_ERR;
       p_result->list_app_values.attr_id = *p++;
       if (!AVRC_IS_VALID_ATTRIBUTE(p_result->list_app_values.attr_id))
         status = AVRC_STS_BAD_PARAM;
@@ -153,6 +154,7 @@
 
     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: /* 0x13 */
     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: /* 0x15 */
+      if (len == 0) return AVRC_STS_INTERNAL_ERR;
       BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_attr, p);
       if (len != (p_result->get_cur_app_val.num_attr + 1)) {
         status = AVRC_STS_INTERNAL_ERR;
@@ -177,6 +179,7 @@
       break;
 
     case AVRC_PDU_SET_PLAYER_APP_VALUE: /* 0x14 */
+      if (len == 0) return AVRC_STS_INTERNAL_ERR;
       BE_STREAM_TO_UINT8(p_result->set_app_val.num_val, p);
       size_needed = sizeof(tAVRC_APP_SETTING);
       if (p_buf && (len == ((p_result->set_app_val.num_val << 1) + 1))) {
@@ -208,7 +211,7 @@
 
     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: /* 0x16 */
       if (len < 3)
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       else {
         BE_STREAM_TO_UINT8(p_result->get_app_val_txt.attr_id, p);
         if (!AVRC_IS_VALID_ATTRIBUTE(p_result->get_app_val_txt.attr_id))
@@ -240,7 +243,7 @@
 
     case AVRC_PDU_INFORM_DISPLAY_CHARSET: /* 0x17 */
       if (len < 3)
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       else {
         BE_STREAM_TO_UINT8(p_result->inform_charset.num_id, p);
         if ((len - 1 /* num_id */) != p_result->inform_charset.num_id * 2)
@@ -258,7 +261,7 @@
 
     case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT: /* 0x18 */
       if (len != 1)
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       else {
         p_result->inform_battery_status.battery_status = *p++;
         if (!AVRC_IS_VALID_BATTERY_STATUS(
@@ -269,7 +272,7 @@
 
     case AVRC_PDU_GET_ELEMENT_ATTR: /* 0x20 */
       if (len < 9)                  /* UID/8 and num_attr/1 */
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       else {
         BE_STREAM_TO_UINT32(u32, p);
         BE_STREAM_TO_UINT32(u32_2, p);
@@ -293,12 +296,12 @@
 
     case AVRC_PDU_GET_PLAY_STATUS: /* 0x30 */
       /* no additional parameters */
-      if (len != 0) status = AVRC_STS_INTERNAL_ERR;
+      if (len != 0) return AVRC_STS_INTERNAL_ERR;
       break;
 
     case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
       if (len != 5)
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       else {
         BE_STREAM_TO_UINT8(p_result->reg_notif.event_id, p);
         BE_STREAM_TO_UINT32(p_result->reg_notif.param, p);
@@ -307,21 +310,21 @@
 
     case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
       if (len != 1)
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       else
         p_result->volume.volume = *p++;
       break;
 
     case AVRC_PDU_REQUEST_CONTINUATION_RSP: /* 0x40 */
       if (len != 1) {
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       }
       BE_STREAM_TO_UINT8(p_result->continu.target_pdu, p);
       break;
 
     case AVRC_PDU_ABORT_CONTINUATION_RSP: /* 0x41 */
       if (len != 1) {
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       }
       BE_STREAM_TO_UINT8(p_result->abort.target_pdu, p);
       break;
@@ -330,14 +333,14 @@
       if (len != 2) {
         AVRC_TRACE_ERROR("AVRC_PDU_SET_ADDRESSED_PLAYER length is incorrect:%d",
                          len);
-        status = AVRC_STS_INTERNAL_ERR;
+        return AVRC_STS_INTERNAL_ERR;
       }
       BE_STREAM_TO_UINT16(p_result->addr_player.player_id, p);
       break;
 
     case AVRC_PDU_PLAY_ITEM:          /* 0x74 */
     case AVRC_PDU_ADD_TO_NOW_PLAYING: /* 0x90 */
-      if (len != (AVRC_UID_SIZE + 3)) status = AVRC_STS_INTERNAL_ERR;
+      if (len != (AVRC_UID_SIZE + 3)) return AVRC_STS_INTERNAL_ERR;
       BE_STREAM_TO_UINT8(p_result->play_item.scope, p);
       if (p_result->play_item.scope > AVRC_SCOPE_NOW_PLAYING) {
         status = AVRC_STS_BAD_SCOPE;
diff --git a/stack/bnep/bnep_api.cc b/stack/bnep/bnep_api.cc
index 0e7b692..809d0b2 100644
--- a/stack/bnep/bnep_api.cc
+++ b/stack/bnep/bnep_api.cc
@@ -340,7 +340,7 @@
   p_bcb = &(bnep_cb.bcb[handle - 1]);
   /* Check MTU size */
   if (p_buf->len > BNEP_MTU_SIZE) {
-    BNEP_TRACE_ERROR("BNEP_Write() length %d exceeded MTU %d", p_buf->len,
+    BNEP_TRACE_ERROR("%s length %d exceeded MTU %d", __func__, p_buf->len,
                      BNEP_MTU_SIZE);
     osi_free(p_buf);
     return (BNEP_MTU_EXCEDED);
@@ -349,7 +349,7 @@
   /* Check if the packet should be filtered out */
   p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
   if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present,
-                             p_data) != BNEP_SUCCESS) {
+                             p_data, p_buf->len) != BNEP_SUCCESS) {
     /*
     ** If packet is filtered and ext headers are present
     ** drop the data and forward the ext headers
@@ -361,6 +361,11 @@
       org_len = p_buf->len;
       new_len = 0;
       do {
+        if ((new_len + 2) > org_len) {
+          osi_free(p_buf);
+          return BNEP_IGNORE_CMD;
+        }
+
         ext = *p_data++;
         length = *p_data++;
         p_data += length;
@@ -437,7 +442,7 @@
 
   /* Check MTU size. Consider the possibility of having extension headers */
   if (len > BNEP_MTU_SIZE) {
-    BNEP_TRACE_ERROR("BNEP_Write() length %d exceeded MTU %d", len,
+    BNEP_TRACE_ERROR("%s length %d exceeded MTU %d", __func__, len,
                      BNEP_MTU_SIZE);
     return (BNEP_MTU_EXCEDED);
   }
@@ -448,7 +453,7 @@
 
   /* Check if the packet should be filtered out */
   if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present,
-                             p_data) != BNEP_SUCCESS) {
+                             p_data, len) != BNEP_SUCCESS) {
     /*
     ** If packet is filtered and ext headers are present
     ** drop the data and forward the ext headers
@@ -461,6 +466,10 @@
       new_len = 0;
       p = p_data;
       do {
+        if ((new_len + 2) > org_len) {
+          return BNEP_IGNORE_CMD;
+        }
+
         ext = *p_data++;
         length = *p_data++;
         p_data += length;
diff --git a/stack/bnep/bnep_int.h b/stack/bnep/bnep_int.h
index 2587147..5bba15d 100644
--- a/stack/bnep/bnep_int.h
+++ b/stack/bnep/bnep_int.h
@@ -229,7 +229,7 @@
 extern tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb,
                                            const RawAddress& p_dest_addr,
                                            uint16_t protocol,
-                                           bool fw_ext_present,
-                                           uint8_t* p_data);
+                                           bool fw_ext_present, uint8_t* p_data,
+                                           uint16_t org_len);
 
 #endif
diff --git a/stack/bnep/bnep_main.cc b/stack/bnep/bnep_main.cc
index ae6c51b..265ec79 100644
--- a/stack/bnep/bnep_main.cc
+++ b/stack/bnep/bnep_main.cc
@@ -94,7 +94,8 @@
   bnep_cb.reg_info.pL2CA_CongestionStatus_Cb = bnep_congestion_ind;
 
   /* Now, register with L2CAP */
-  if (!L2CA_Register(BT_PSM_BNEP, &bnep_cb.reg_info)) {
+  if (!L2CA_Register(BT_PSM_BNEP, &bnep_cb.reg_info,
+                     false /* enable_snoop */)) {
     BNEP_TRACE_ERROR("BNEP - Registration failed");
     return BNEP_SECURITY_FAIL;
   }
diff --git a/stack/bnep/bnep_utils.cc b/stack/bnep/bnep_utils.cc
index 6d6d709..ac74ce0 100644
--- a/stack/bnep/bnep_utils.cc
+++ b/stack/bnep/bnep_utils.cc
@@ -1259,23 +1259,33 @@
 tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb,
                                     const RawAddress& p_dest_addr,
                                     uint16_t protocol, bool fw_ext_present,
-                                    uint8_t* p_data) {
+                                    uint8_t* p_data, uint16_t org_len) {
   if (p_bcb->rcvd_num_filters) {
     uint16_t i, proto;
 
     /* Findout the actual protocol to check for the filtering */
     proto = protocol;
     if (proto == BNEP_802_1_P_PROTOCOL) {
+      uint16_t new_len = 0;
       if (fw_ext_present) {
         uint8_t len, ext;
         /* parse the extension headers and findout actual protocol */
         do {
+          if ((new_len + 2) > org_len) {
+            return BNEP_IGNORE_CMD;
+          }
+
           ext = *p_data++;
           len = *p_data++;
           p_data += len;
 
+          new_len += (len + 2);
+
         } while (ext & 0x80);
       }
+      if ((new_len + 4) > org_len) {
+        return BNEP_IGNORE_CMD;
+      }
       p_data += 2;
       BE_STREAM_TO_UINT16(proto, p_data);
     }
diff --git a/stack/btm/btm_ble_gap.cc b/stack/btm/btm_ble_gap.cc
index ca40a2b..c46acf0 100644
--- a/stack/btm/btm_ble_gap.cc
+++ b/stack/btm/btm_ble_gap.cc
@@ -58,7 +58,10 @@
 
 #define BTM_EXT_BLE_RMT_NAME_TIMEOUT_MS (30 * 1000)
 #define MIN_ADV_LENGTH 2
-#define BTM_VSC_CHIP_CAPABILITY_RSP_LEN_L_RELEASE 9
+#define BTM_VSC_CHIP_CAPABILITY_RSP_LEN 9
+#define BTM_VSC_CHIP_CAPABILITY_RSP_LEN_L_RELEASE \
+  BTM_VSC_CHIP_CAPABILITY_RSP_LEN
+#define BTM_VSC_CHIP_CAPABILITY_RSP_LEN_M_RELEASE 15
 
 namespace {
 
@@ -495,6 +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);
   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);
@@ -512,6 +516,7 @@
 
   if (btm_cb.cmn_ble_vsc_cb.version_supported >=
       BTM_VSC_CHIP_CAPABILITY_M_VERSION) {
+    CHECK(p_vcs_cplt_params->param_len >= BTM_VSC_CHIP_CAPABILITY_RSP_LEN_M_RELEASE);
     STREAM_TO_UINT16(btm_cb.cmn_ble_vsc_cb.total_trackable_advertisers, p);
     STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.extended_scan_support, p);
     STREAM_TO_UINT8(btm_cb.cmn_ble_vsc_cb.debug_logging_supported, p);
@@ -1473,7 +1478,7 @@
   if (!adv_data.empty()) {
     const uint8_t* p_flag = AdvertiseDataParser::GetFieldByType(
         adv_data, BTM_BLE_AD_TYPE_FLAG, &data_len);
-    if (p_flag != NULL) {
+    if (p_flag != NULL && data_len != 0) {
       flag = *p_flag;
 
       if ((btm_cb.btm_inq_vars.inq_active & BTM_BLE_GENERAL_INQUIRY) &&
@@ -1659,7 +1664,7 @@
   if (!data.empty()) {
     const uint8_t* p_flag =
         AdvertiseDataParser::GetFieldByType(data, BTM_BLE_AD_TYPE_FLAG, &len);
-    if (p_flag != NULL) p_cur->flag = *p_flag;
+    if (p_flag != NULL && len != 0) p_cur->flag = *p_flag;
   }
 
   if (!data.empty()) {
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 4db757e..4df0974 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -4552,8 +4552,7 @@
    */
   if (is_sample_ltk(p_dev_rec->ble.keys.pltk)) {
     android_errorWriteLog(0x534e4554, "128437297");
-    LOG(INFO) << __func__ << " removing bond to device that used sample LTK: "
-              << p_dev_rec->bd_addr;
+    LOG(INFO) << __func__ << " removing bond to device that used sample LTK: " << p_dev_rec->bd_addr;
 
     bta_dm_remove_device(p_dev_rec->bd_addr);
   }
diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc
index b9543fd..4612422 100644
--- a/stack/btu/btu_hcif.cc
+++ b/stack/btu/btu_hcif.cc
@@ -1129,8 +1129,16 @@
 
 constexpr uint8_t MIN_KEY_SIZE = 7;
 
-static void read_encryption_key_size_complete_after_encryption_change(
-    uint8_t status, uint16_t handle, uint8_t key_size) {
+static void read_encryption_key_size_complete_after_encryption_change(uint8_t status, uint16_t handle,
+                                                                      uint8_t key_size) {
+  if (status == HCI_ERR_INSUFFCIENT_SECURITY) {
+    /* If remote device stop the encryption before we call "Read Encryption Key
+     * Size", we might receive Insufficient Security, which means that link is
+     * no longer encrypted. */
+    LOG(INFO) << __func__ << ": encryption stopped on link: " << loghex(handle);
+    return;
+  }
+
   if (status != HCI_SUCCESS) {
     LOG(INFO) << __func__ << ": disconnecting, status: " << loghex(status);
     btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
@@ -1139,9 +1147,8 @@
 
   if (key_size < MIN_KEY_SIZE) {
     android_errorWriteLog(0x534e4554, "124301137");
-    LOG(ERROR) << __func__
-               << " encryption key too short, disconnecting. handle: "
-               << loghex(handle) << " key_size: " << +key_size;
+    LOG(ERROR) << __func__ << " encryption key too short, disconnecting. handle: " << loghex(handle)
+               << " key_size: " << +key_size;
 
     btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
     return;
@@ -1169,14 +1176,16 @@
   STREAM_TO_UINT16(handle, p);
   STREAM_TO_UINT8(encr_enable, p);
 
-  if (status != HCI_SUCCESS || encr_enable == 0 ||
-      BTM_IsBleConnection(handle)) {
+  if (status != HCI_SUCCESS || encr_enable == 0 || BTM_IsBleConnection(handle)) {
+    if (status == HCI_ERR_CONNECTION_TOUT) {
+      smp_cancel_start_encryption_attempt();
+      return;
+    }
+
     btm_acl_encrypt_change(handle, status, encr_enable);
     btm_sec_encrypt_change(handle, status, encr_enable);
   } else {
-    btsnd_hcic_read_encryption_key_size(
-        handle,
-        base::Bind(&read_encryption_key_size_complete_after_encryption_change));
+    btsnd_hcic_read_encryption_key_size(handle, base::Bind(&read_encryption_key_size_complete_after_encryption_change));
   }
 }
 
@@ -2049,8 +2058,15 @@
  * End of Simple Pairing Events
  **********************************************/
 
-static void read_encryption_key_size_complete_after_key_refresh(
-    uint8_t status, uint16_t handle, uint8_t key_size) {
+static void read_encryption_key_size_complete_after_key_refresh(uint8_t status, uint16_t handle, uint8_t key_size) {
+  if (status == HCI_ERR_INSUFFCIENT_SECURITY) {
+    /* If remote device stop the encryption before we call "Read Encryption Key
+     * Size", we might receive Insufficient Security, which means that link is
+     * no longer encrypted. */
+    LOG(INFO) << __func__ << ": encryption stopped on link: " << loghex(handle);
+    return;
+  }
+
   if (status != HCI_SUCCESS) {
     LOG(INFO) << __func__ << ": disconnecting, status: " << loghex(status);
     btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
@@ -2059,9 +2075,8 @@
 
   if (key_size < MIN_KEY_SIZE) {
     android_errorWriteLog(0x534e4554, "124301137");
-    LOG(ERROR) << __func__
-               << " encryption key too short, disconnecting. handle: "
-               << loghex(handle) << " key_size: " << +key_size;
+    LOG(ERROR) << __func__ << " encryption key too short, disconnecting. handle: " << loghex(handle)
+               << " key_size: " << +key_size;
 
     btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
     return;
@@ -2080,9 +2095,7 @@
   if (status != HCI_SUCCESS || BTM_IsBleConnection(handle)) {
     btm_sec_encrypt_change(handle, status, (status == HCI_SUCCESS) ? 1 : 0);
   } else {
-    btsnd_hcic_read_encryption_key_size(
-        handle,
-        base::Bind(&read_encryption_key_size_complete_after_key_refresh));
+    btsnd_hcic_read_encryption_key_size(handle, base::Bind(&read_encryption_key_size_complete_after_key_refresh));
   }
 }
 
diff --git a/stack/gap/gap_conn.cc b/stack/gap/gap_conn.cc
index 72183bb..15d3ddb 100644
--- a/stack/gap/gap_conn.cc
+++ b/stack/gap/gap_conn.cc
@@ -235,8 +235,7 @@
 
   /* Register the PSM with L2CAP */
   if (transport == BT_TRANSPORT_BR_EDR) {
-    p_ccb->psm = L2CA_REGISTER(
-        psm, &conn.reg_info, AMP_AUTOSWITCH_ALLOWED | AMP_USE_AMP_IF_POSSIBLE);
+    p_ccb->psm = L2CA_REGISTER(psm, &conn.reg_info, false /* enable_snoop */);
     if (p_ccb->psm == 0) {
       LOG(ERROR) << StringPrintf("%s: Failure registering PSM 0x%04x", __func__,
                                  psm);
diff --git a/stack/gatt/gatt_api.cc b/stack/gatt/gatt_api.cc
index 4195548..37bc614 100644
--- a/stack/gatt/gatt_api.cc
+++ b/stack/gatt/gatt_api.cc
@@ -382,6 +382,7 @@
   if (it == gatt_cb.srv_list_info->end()) {
     LOG(ERROR) << __func__ << ": service_handle=" << loghex(service_handle)
                << " is not in use";
+    return;
   }
 
   if (it->sdp_handle) {
diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc
index 2650a30..27a4f4f 100644
--- a/stack/gatt/gatt_cl.cc
+++ b/stack/gatt/gatt_cl.cc
@@ -627,6 +627,10 @@
   memset(&value, 0, sizeof(value));
   STREAM_TO_UINT16(value.handle, p);
   value.len = len - 2;
+  if (value.len > GATT_MAX_ATTR_LEN) {
+    LOG(ERROR) << "value.len larger than GATT_MAX_ATTR_LEN, discard";
+    return;
+  }
   memcpy(value.value, p, value.len);
 
   if (!GATT_HANDLE_IS_VALID(value.handle)) {
diff --git a/stack/gatt/gatt_main.cc b/stack/gatt/gatt_main.cc
index b332496..87f9c87 100644
--- a/stack/gatt/gatt_main.cc
+++ b/stack/gatt/gatt_main.cc
@@ -124,7 +124,8 @@
   L2CA_RegisterFixedChannel(L2CAP_ATT_CID, &fixed_reg);
 
   /* Now, register with L2CAP for ATT PSM over BR/EDR */
-  if (!L2CA_Register(BT_PSM_ATT, (tL2CAP_APPL_INFO*)&dyn_info)) {
+  if (!L2CA_Register(BT_PSM_ATT, (tL2CAP_APPL_INFO*)&dyn_info,
+                     false /* enable_snoop */)) {
     LOG(ERROR) << "ATT Dynamic Registration failed";
   }
 
diff --git a/stack/hcic/hcicmds.cc b/stack/hcic/hcicmds.cc
index 2e849a4..23a8648 100644
--- a/stack/hcic/hcicmds.cc
+++ b/stack/hcic/hcicmds.cc
@@ -1309,9 +1309,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-static void read_encryption_key_size_complete(
-    ReadEncKeySizeCb cb, uint8_t* return_parameters,
-    uint16_t return_parameters_length) {
+static void read_encryption_key_size_complete(ReadEncKeySizeCb cb, uint8_t* return_parameters,
+                                              uint16_t return_parameters_length) {
   uint8_t status;
   uint16_t handle;
   uint8_t key_size;
@@ -1330,9 +1329,8 @@
   uint8_t* p = param;
   UINT16_TO_STREAM(p, handle);
 
-  btu_hcif_send_cmd_with_cb(
-      FROM_HERE, HCI_READ_ENCR_KEY_SIZE, param, len,
-      base::Bind(&read_encryption_key_size_complete, base::Passed(&cb)));
+  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_READ_ENCR_KEY_SIZE, param, len,
+                            base::Bind(&read_encryption_key_size_complete, base::Passed(&cb)));
 }
 
 void btsnd_hcic_read_failed_contact_counter(uint16_t handle) {
diff --git a/stack/hid/hidd_api.cc b/stack/hid/hidd_api.cc
index f93511e..cd40c2c 100644
--- a/stack/hid/hidd_api.cc
+++ b/stack/hid/hidd_api.cc
@@ -33,7 +33,6 @@
 #include "hidd_api.h"
 #include "hidd_int.h"
 #include "hiddefs.h"
-#include "log/log.h"
 
 tHID_DEV_CTB hd_cb;
 
@@ -321,10 +320,6 @@
       UINT8_TO_BE_STREAM(p, desc_len);
       ARRAY_TO_BE_STREAM(p, p_desc_data, (int)desc_len);
 
-      if (desc_len > HIDD_APP_DESCRIPTOR_LEN - 6) {
-        android_errorWriteLog(0x534e4554, "113572366");
-      }
-
       result &= SDP_AddAttribute(handle, ATTR_ID_HID_DESCRIPTOR_LIST,
                                  DATA_ELE_SEQ_DESC_TYPE, p - p_buf, p_buf);
 
diff --git a/stack/hid/hidd_conn.cc b/stack/hid/hidd_conn.cc
index e4525f9..55ec3b2 100644
--- a/stack/hid/hidd_conn.cc
+++ b/stack/hid/hidd_conn.cc
@@ -614,6 +614,12 @@
 
   HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid);
 
+  if (p_msg->len < 1) {
+    HIDD_TRACE_ERROR("Invalid data length, ignore");
+    osi_free(p_msg);
+    return;
+  }
+
   p_hcon = &hd_cb.device.conn;
 
   if (p_hcon->conn_state == HID_CONN_STATE_UNUSED ||
@@ -756,12 +762,14 @@
   hd_cb.l2cap_intr_cfg.flush_to_present = TRUE;
   hd_cb.l2cap_intr_cfg.flush_to = HID_DEV_FLUSH_TO;
 
-  if (!L2CA_Register(HID_PSM_CONTROL, (tL2CAP_APPL_INFO*)&dev_reg_info)) {
+  if (!L2CA_Register(HID_PSM_CONTROL, (tL2CAP_APPL_INFO*)&dev_reg_info,
+                     false /* enable_snoop */)) {
     HIDD_TRACE_ERROR("HID Control (device) registration failed");
     return (HID_ERR_L2CAP_FAILED);
   }
 
-  if (!L2CA_Register(HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO*)&dev_reg_info)) {
+  if (!L2CA_Register(HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO*)&dev_reg_info,
+                     false /* enable_snoop */)) {
     L2CA_Deregister(HID_PSM_CONTROL);
     HIDD_TRACE_ERROR("HID Interrupt (device) registration failed");
     return (HID_ERR_L2CAP_FAILED);
diff --git a/stack/hid/hidh_conn.cc b/stack/hid/hidh_conn.cc
index 6b729e5..3c694f0 100644
--- a/stack/hid/hidh_conn.cc
+++ b/stack/hid/hidh_conn.cc
@@ -97,11 +97,13 @@
   hh_cb.l2cap_cfg.flush_to = HID_HOST_FLUSH_TO;
 
   /* Now, register with L2CAP */
-  if (!L2CA_Register(HID_PSM_CONTROL, (tL2CAP_APPL_INFO*)&hst_reg_info)) {
+  if (!L2CA_Register(HID_PSM_CONTROL, (tL2CAP_APPL_INFO*)&hst_reg_info,
+                     false /* enable_snoop */)) {
     HIDH_TRACE_ERROR("HID-Host Control Registration failed");
     return (HID_ERR_L2CAP_FAILED);
   }
-  if (!L2CA_Register(HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO*)&hst_reg_info)) {
+  if (!L2CA_Register(HID_PSM_INTERRUPT, (tL2CAP_APPL_INFO*)&hst_reg_info,
+                     false /* enable_snoop */)) {
     L2CA_Deregister(HID_PSM_CONTROL);
     HIDH_TRACE_ERROR("HID-Host Interrupt Registration failed");
     return (HID_ERR_L2CAP_FAILED);
diff --git a/stack/include/advertise_data_parser.h b/stack/include/advertise_data_parser.h
index b62dbb3..a1ac17b 100644
--- a/stack/include/advertise_data_parser.h
+++ b/stack/include/advertise_data_parser.h
@@ -34,7 +34,8 @@
     auto data_start = ad.begin() + position;
 
     // Traxxas - bad name length
-    if (std::equal(data_start, data_start + 3, trx_quirk.begin()) &&
+    if ((ad.size() - position) >= 18 &&
+        std::equal(data_start, data_start + 3, trx_quirk.begin()) &&
         std::equal(data_start + 5, data_start + 11, trx_quirk.begin() + 5) &&
         std::equal(data_start + 12, data_start + 18, trx_quirk.begin() + 12)) {
       return true;
diff --git a/stack/include/bt_types.h b/stack/include/bt_types.h
index 4121a19..7804328 100644
--- a/stack/include/bt_types.h
+++ b/stack/include/bt_types.h
@@ -21,7 +21,6 @@
 
 #include <stdbool.h>
 #include <stdint.h>
-#include <string.h>
 
 #ifndef FALSE
 #define FALSE false
@@ -581,7 +580,9 @@
  * 0x4C68384139F574D836BCF34E9DFB01BF */
 constexpr Octet16 SAMPLE_LTK = {0xbf, 0x01, 0xfb, 0x9d, 0x4e, 0xf3, 0xbc, 0x36,
                                 0xd8, 0x74, 0xf5, 0x39, 0x41, 0x38, 0x68, 0x4c};
-inline bool is_sample_ltk(const Octet16& ltk) { return ltk == SAMPLE_LTK; }
+inline bool is_sample_ltk(const Octet16& ltk) {
+  return ltk == SAMPLE_LTK;
+}
 
 #endif
 
diff --git a/stack/include/hcimsgs.h b/stack/include/hcimsgs.h
index 5682a5c..285ae41 100644
--- a/stack/include/hcimsgs.h
+++ b/stack/include/hcimsgs.h
@@ -611,8 +611,7 @@
 extern void btsnd_hcic_get_link_quality(uint16_t handle); /* Get Link Quality */
 extern void btsnd_hcic_read_rssi(uint16_t handle);        /* Read RSSI */
 using ReadEncKeySizeCb = base::OnceCallback<void(uint8_t, uint16_t, uint8_t)>;
-extern void btsnd_hcic_read_encryption_key_size(uint16_t handle,
-                                                ReadEncKeySizeCb cb);
+extern void btsnd_hcic_read_encryption_key_size(uint16_t handle, ReadEncKeySizeCb cb);
 extern void btsnd_hcic_read_failed_contact_counter(uint16_t handle);
 extern void btsnd_hcic_read_automatic_flush_timeout(uint16_t handle);
 extern void btsnd_hcic_enable_test_mode(
diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h
index 88121af..8f364e7 100644
--- a/stack/include/l2c_api.h
+++ b/stack/include/l2c_api.h
@@ -328,7 +328,7 @@
 
 } tL2CAP_ERTM_INFO;
 
-#define L2CA_REGISTER(a, b, c) L2CA_Register(a, (tL2CAP_APPL_INFO*)(b))
+#define L2CA_REGISTER(a, b, c) L2CA_Register(a, (tL2CAP_APPL_INFO*)(b), c)
 #define L2CA_DEREGISTER(a) L2CA_Deregister(a)
 #define L2CA_CONNECT_REQ(a, b, c) L2CA_ErtmConnectReq(a, b, c)
 #define L2CA_CONNECT_RSP(a, b, c, d, e, f) L2CA_ErtmConnectRsp(a, b, c, d, e, f)
@@ -362,7 +362,8 @@
  *                  BTM_SetSecurityLevel().
  *
  ******************************************************************************/
-extern uint16_t L2CA_Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info);
+extern uint16_t L2CA_Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info,
+                              bool enable_snoop);
 
 /*******************************************************************************
  *
diff --git a/stack/l2cap/l2c_api.cc b/stack/l2cap/l2c_api.cc
index 6dc41de..b5a9564 100644
--- a/stack/l2cap/l2c_api.cc
+++ b/stack/l2cap/l2c_api.cc
@@ -58,7 +58,8 @@
  *                  L2CA_ErtmConnectReq() and L2CA_Deregister()
  *
  ******************************************************************************/
-uint16_t L2CA_Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info) {
+uint16_t L2CA_Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info,
+                       bool enable_snoop) {
   tL2C_RCB* p_rcb;
   uint16_t vpsm = psm;
 
@@ -104,6 +105,7 @@
     }
   }
 
+  p_rcb->log_packets = enable_snoop;
   p_rcb->api = *p_cb_info;
   p_rcb->real_psm = psm;
 
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index 0b71a19..53b6f32 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -241,6 +241,7 @@
 
 typedef struct {
   bool in_use;
+  bool log_packets;
   uint16_t psm;
   uint16_t real_psm; /* This may be a dummy RCB for an o/b connection but */
                      /* this is the real PSM that we need to connect to */
diff --git a/stack/l2cap/l2c_main.cc b/stack/l2cap/l2c_main.cc
index 74e7135..128f60e 100644
--- a/stack/l2cap/l2c_main.cc
+++ b/stack/l2cap/l2c_main.cc
@@ -33,6 +33,7 @@
 #include "btm_int.h"
 #include "btu.h"
 #include "device/include/controller.h"
+#include "hci/include/btsnoop.h"
 #include "hcimsgs.h"
 #include "l2c_api.h"
 #include "l2c_int.h"
@@ -79,8 +80,8 @@
 
   uint16_t hci_len;
   STREAM_TO_UINT16(hci_len, p);
-  if (hci_len < L2CAP_PKT_OVERHEAD) {
-    /* Must receive at least the L2CAP length and CID */
+  if (hci_len < L2CAP_PKT_OVERHEAD || hci_len != p_msg->len - 4) {
+    /* Remote-declared packet size must match HCI_ACL size - ACL header (4) */
     L2CAP_TRACE_WARNING("L2CAP - got incorrect hci header");
     osi_free(p_msg);
     return;
@@ -396,6 +397,14 @@
         p_ccb->p_rcb = p_rcb;
         p_ccb->remote_cid = rcid;
 
+        if (p_rcb->psm == BT_PSM_RFCOMM) {
+          btsnoop_get_interface()->add_rfc_l2c_channel(
+              p_lcb->handle, p_ccb->local_cid, p_ccb->remote_cid);
+        } else if (p_rcb->log_packets) {
+          btsnoop_get_interface()->whitelist_l2c_channel(
+              p_lcb->handle, p_ccb->local_cid, p_ccb->remote_cid);
+        }
+
         l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info);
         break;
       }
@@ -427,6 +436,15 @@
         else
           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info);
 
+        tL2C_RCB* p_rcb = p_ccb->p_rcb;
+        if (p_rcb->psm == BT_PSM_RFCOMM) {
+          btsnoop_get_interface()->add_rfc_l2c_channel(
+              p_lcb->handle, p_ccb->local_cid, p_ccb->remote_cid);
+        } else if (p_rcb->log_packets) {
+          btsnoop_get_interface()->whitelist_l2c_channel(
+              p_lcb->handle, p_ccb->local_cid, p_ccb->remote_cid);
+        }
+
         break;
       }
 
@@ -763,6 +781,10 @@
 #if (L2CAP_NUM_FIXED_CHNLS > 0)
         if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) {
           if (result == L2CAP_INFO_RESP_RESULT_SUCCESS) {
+            if (p + L2CAP_FIXED_CHNL_ARRAY_SIZE > p_next_cmd) {
+              android_errorWriteLog(0x534e4554, "111215173");
+              return;
+            }
             memcpy(p_lcb->peer_chnl_mask, p, L2CAP_FIXED_CHNL_ARRAY_SIZE);
           }
 
diff --git a/stack/l2cap/l2c_utils.cc b/stack/l2cap/l2c_utils.cc
index 448acaa..593f12f 100644
--- a/stack/l2cap/l2c_utils.cc
+++ b/stack/l2cap/l2c_utils.cc
@@ -33,6 +33,7 @@
 #include "btm_int.h"
 #include "btu.h"
 #include "device/include/controller.h"
+#include "hci/include/btsnoop.h"
 #include "hcidefs.h"
 #include "hcimsgs.h"
 #include "l2c_int.h"
@@ -1569,6 +1570,9 @@
   /* If already released, could be race condition */
   if (!p_ccb->in_use) return;
 
+  btsnoop_get_interface()->clear_l2cap_whitelist(
+      p_lcb->handle, p_ccb->local_cid, p_ccb->remote_cid);
+
   if (p_rcb && (p_rcb->psm != p_rcb->real_psm)) {
     btm_sec_clr_service_by_psm(p_rcb->psm);
   }
diff --git a/stack/rfcomm/rfc_l2cap_if.cc b/stack/rfcomm/rfc_l2cap_if.cc
index 3275d77..3dc4ec2 100644
--- a/stack/rfcomm/rfc_l2cap_if.cc
+++ b/stack/rfcomm/rfc_l2cap_if.cc
@@ -30,6 +30,7 @@
 #include "osi/include/osi.h"
 
 #include "bt_utils.h"
+#include "hci/include/btsnoop.h"
 #include "l2c_api.h"
 #include "l2cdefs.h"
 #include "port_api.h"
@@ -73,7 +74,7 @@
   p_l2c->pL2CA_CongestionStatus_Cb = RFCOMM_CongestionStatusInd;
   p_l2c->pL2CA_TxComplete_Cb = NULL;
 
-  L2CA_Register(BT_PSM_RFCOMM, p_l2c);
+  L2CA_Register(BT_PSM_RFCOMM, p_l2c, true /* enable_snoop */);
 }
 
 /*******************************************************************************
diff --git a/stack/rfcomm/rfc_port_fsm.cc b/stack/rfcomm/rfc_port_fsm.cc
index f486bdd..1b82ddf 100644
--- a/stack/rfcomm/rfc_port_fsm.cc
+++ b/stack/rfcomm/rfc_port_fsm.cc
@@ -34,6 +34,14 @@
 #include "rfc_int.h"
 #include "rfcdefs.h"
 
+#include <set>
+#include "hci/include/btsnoop.h"
+
+static const std::set<uint16_t> uuid_logging_whitelist = {
+    UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY,
+    UUID_SERVCLASS_AG_HANDSFREE,
+};
+
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
@@ -206,6 +214,13 @@
     case RFC_EVENT_UA:
       rfc_port_timer_stop(p_port);
       p_port->rfc.state = RFC_STATE_OPENED;
+
+      if (uuid_logging_whitelist.find(p_port->uuid) !=
+          uuid_logging_whitelist.end()) {
+        btsnoop_get_interface()->whitelist_rfc_dlci(p_port->rfc.p_mcb->lcid,
+                                                    p_port->dlci);
+      }
+
       PORT_DlcEstablishCnf(p_port->rfc.p_mcb, p_port->dlci,
                            p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_SUCCESS);
       return;
@@ -317,6 +332,12 @@
       } else {
         rfc_send_ua(p_port->rfc.p_mcb, p_port->dlci);
         p_port->rfc.state = RFC_STATE_OPENED;
+
+        if (uuid_logging_whitelist.find(p_port->uuid) !=
+            uuid_logging_whitelist.end()) {
+          btsnoop_get_interface()->whitelist_rfc_dlci(p_port->rfc.p_mcb->lcid,
+                                                      p_port->dlci);
+        }
       }
       return;
   }
diff --git a/stack/rfcomm/rfc_ts_frames.cc b/stack/rfcomm/rfc_ts_frames.cc
index d253b40..7bc98a2 100644
--- a/stack/rfcomm/rfc_ts_frames.cc
+++ b/stack/rfcomm/rfc_ts_frames.cc
@@ -533,12 +533,21 @@
     return RFC_EVENT_BAD_FRAME;
   }
 
+  if (p_buf->len < (3 + !ead + !eal + 1)) {
+    android_errorWriteLog(0x534e4554, "120255805");
+    RFCOMM_TRACE_ERROR("Bad Length: %d", p_buf->len);
+    return RFC_EVENT_BAD_FRAME;
+  }
   p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */
   p_buf->offset += (3 + !ead + !eal);
 
   /* handle credit if credit based flow control */
   if ((p_mcb->flow == PORT_FC_CREDIT) && (p_frame->type == RFCOMM_UIH) &&
       (p_frame->dlci != RFCOMM_MX_DLCI) && (p_frame->pf == 1)) {
+    if (p_buf->len < sizeof(uint8_t)) {
+      RFCOMM_TRACE_ERROR("Bad Length in flow control: %d", p_buf->len);
+      return RFC_EVENT_BAD_FRAME;
+    }
     p_frame->credit = *p_data++;
     p_buf->len--;
     p_buf->offset++;
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index e7fe979..55259ca 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -217,6 +217,12 @@
   p = (uint8_t*)(p_msg + 1) + p_msg->offset;
   uint8_t* p_end = p + p_msg->len;
 
+  if (p_msg->len < 1) {
+    android_errorWriteLog(0x534e4554, "79883568");
+    sdp_disconnect(p_ccb, SDP_GENERIC_ERROR);
+    return;
+  }
+
   BE_STREAM_TO_UINT8(rsp_pdu, p);
 
   p_msg->len--;
@@ -368,11 +374,6 @@
       SDP_TRACE_WARNING("rem_len :%d less than cpy_len:%d", rem_len, cpy_len);
       cpy_len = rem_len;
     }
-    SDP_TRACE_WARNING(
-        "%s: list_len:%d cpy_len:%d p:%p p_ccb:%p p_db:%p raw_size:%d "
-        "raw_used:%d raw_data:%p",
-        __func__, list_len, cpy_len, p, p_ccb, p_ccb->p_db,
-        p_ccb->p_db->raw_size, p_ccb->p_db->raw_used, p_ccb->p_db->raw_data);
     memcpy(&p_ccb->p_db->raw_data[p_ccb->p_db->raw_used], p, cpy_len);
     p_ccb->p_db->raw_used += cpy_len;
   }
@@ -397,6 +398,12 @@
 
   /* If p_reply is NULL, we were called after the records handles were read */
   if (p_reply) {
+    if (p_reply + 4 /* transaction ID and length */ + sizeof(list_byte_count) >
+        p_reply_end) {
+      sdp_disconnect(p_ccb, SDP_INVALID_PDU_SIZE);
+      return;
+    }
+
     /* Skip transaction ID and length */
     p_reply += 4;
 
diff --git a/stack/sdp/sdp_main.cc b/stack/sdp/sdp_main.cc
index 3df37c5..2211c39 100644
--- a/stack/sdp/sdp_main.cc
+++ b/stack/sdp/sdp_main.cc
@@ -121,7 +121,7 @@
   sdp_cb.reg_info.pL2CA_TxComplete_Cb = NULL;
 
   /* Now, register with L2CAP */
-  if (!L2CA_Register(SDP_PSM, &sdp_cb.reg_info)) {
+  if (!L2CA_Register(SDP_PSM, &sdp_cb.reg_info, true /* enable_snoop */)) {
     SDP_TRACE_ERROR("SDP Registration failed");
   }
 }
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index db6ed66..21b960b 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -16,6 +16,7 @@
  *
  ******************************************************************************/
 
+#include <cutils/log.h>
 #include <log/log.h>
 #include <string.h>
 #include "btif_common.h"
@@ -488,7 +489,15 @@
  ******************************************************************************/
 void smp_proc_pair_fail(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
   SMP_TRACE_DEBUG("%s", __func__);
-  p_cb->status = p_data->status;
+
+  if (p_cb->rcvd_cmd_len < 2) {
+    android_errorWriteLog(0x534e4554, "111214739");
+    SMP_TRACE_WARNING("%s: rcvd_cmd_len %d too short: must be at least 2",
+                      __func__, p_cb->rcvd_cmd_len);
+    p_cb->status = SMP_INVALID_PARAMETERS;
+  } else {
+    p_cb->status = p_data->status;
+  }
 
   /* Cancel pending auth complete timer if set */
   alarm_cancel(p_cb->delayed_auth_timer_ent);
@@ -511,6 +520,14 @@
 
   p_cb->flags |= SMP_PAIR_FLAG_ENC_AFTER_PAIR;
 
+  if (smp_command_has_invalid_length(p_cb)) {
+    tSMP_INT_DATA smp_int_data;
+    smp_int_data.status = SMP_INVALID_PARAMETERS;
+    android_errorWriteLog(0x534e4554, "111850706");
+    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+    return;
+  }
+
   STREAM_TO_UINT8(p_cb->peer_io_caps, p);
   STREAM_TO_UINT8(p_cb->peer_oob_flag, p);
   STREAM_TO_UINT8(p_cb->peer_auth_req, p);
@@ -779,6 +796,14 @@
 
   p_cb->flags |= SMP_PAIR_FLAG_ENC_AFTER_PAIR;
 
+  if (smp_command_has_invalid_length(p_cb)) {
+    tSMP_INT_DATA smp_int_data;
+    smp_int_data.status = SMP_INVALID_PARAMETERS;
+    android_errorWriteLog(0x534e4554, "111213909");
+    smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
+    return;
+  }
+
   STREAM_TO_UINT8(p_cb->peer_io_caps, p);
   STREAM_TO_UINT8(p_cb->peer_oob_flag, p);
   STREAM_TO_UINT8(p_cb->peer_auth_req, p);
@@ -942,7 +967,7 @@
   STREAM_TO_ARRAY(le_key.penc_key.rand, p, BT_OCTET8_LEN);
 
   /* store the encryption keys from peer device */
-  le_key.lenc_key.ltk = p_cb->ltk;
+  le_key.penc_key.ltk = p_cb->ltk;
   le_key.penc_key.sec_level = p_cb->sec_level;
   le_key.penc_key.key_size = p_cb->loc_enc_size;
 
@@ -977,6 +1002,15 @@
   tBTM_LE_KEY_VALUE pid_key;
 
   SMP_TRACE_DEBUG("%s", __func__);
+
+  if (smp_command_has_invalid_parameters(p_cb)) {
+    tSMP_INT_DATA smp_int_data;
+    smp_int_data.status = SMP_INVALID_PARAMETERS;
+    android_errorWriteLog(0x534e4554, "111214770");
+    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+    return;
+  }
+
   smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ID, true);
 
   STREAM_TO_UINT8(pid_key.pid_key.identity_addr_type, p);
@@ -1000,6 +1034,15 @@
   tBTM_LE_KEY_VALUE le_key;
 
   SMP_TRACE_DEBUG("%s", __func__);
+
+  if (smp_command_has_invalid_parameters(p_cb)) {
+    tSMP_INT_DATA smp_int_data;
+    smp_int_data.status = SMP_INVALID_PARAMETERS;
+    android_errorWriteLog(0x534e4554, "111214470");
+    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+    return;
+  }
+
   smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_CSRK, true);
 
   /* save CSRK to security record */
diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h
index 9886d4f..72fdf55 100644
--- a/stack/smp/smp_int.h
+++ b/stack/smp/smp_int.h
@@ -450,6 +450,7 @@
 extern void smp_mask_enc_key(uint8_t loc_enc_size, Octet16* p_data);
 extern void smp_rsp_timeout(void* data);
 extern void smp_delayed_auth_complete_timeout(void* data);
+extern bool smp_command_has_invalid_length(tSMP_CB* p_cb);
 extern bool smp_command_has_invalid_parameters(tSMP_CB* p_cb);
 extern void smp_reject_unexpected_pairing_command(const RawAddress& bd_addr);
 extern tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB* p_cb);
diff --git a/stack/smp/smp_l2c.cc b/stack/smp/smp_l2c.cc
index b6881e6..2daeb21 100644
--- a/stack/smp/smp_l2c.cc
+++ b/stack/smp/smp_l2c.cc
@@ -22,6 +22,7 @@
  *
  ******************************************************************************/
 
+#include <cutils/log.h>
 #include "bt_target.h"
 
 #include <string.h>
@@ -142,6 +143,14 @@
   uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
   uint8_t cmd;
 
+  if (p_buf->len < 1) {
+    android_errorWriteLog(0x534e4554, "111215315");
+    SMP_TRACE_WARNING("%s: smp packet length %d too short: must be at least 1",
+                      __func__, p_buf->len);
+    osi_free(p_buf);
+    return;
+  }
+
   STREAM_TO_UINT8(cmd, p);
 
   SMP_TRACE_EVENT("%s: SMDBG l2c, cmd=0x%x", __func__, cmd);
@@ -286,6 +295,14 @@
   uint8_t cmd;
   SMP_TRACE_EVENT("SMDBG l2c %s", __func__);
 
+  if (p_buf->len < 1) {
+    android_errorWriteLog(0x534e4554, "111215315");
+    SMP_TRACE_WARNING("%s: smp packet length %d too short: must be at least 1",
+                      __func__, p_buf->len);
+    osi_free(p_buf);
+    return;
+  }
+
   STREAM_TO_UINT8(cmd, p);
 
   /* sanity check */
diff --git a/stack/smp/smp_utils.cc b/stack/smp/smp_utils.cc
index f81e21d..b5da5ba 100644
--- a/stack/smp/smp_utils.cc
+++ b/stack/smp/smp_utils.cc
@@ -955,6 +955,33 @@
 
 /*******************************************************************************
  *
+ * Function         smp_command_has_invalid_length
+ *
+ * Description      Checks if the received SMP command has invalid length
+ *                  It returns true if the command has invalid length.
+ *
+ * Returns          true if the command has invalid length, false otherwise.
+ *
+ ******************************************************************************/
+bool smp_command_has_invalid_length(tSMP_CB* p_cb) {
+  uint8_t cmd_code = p_cb->rcvd_cmd_code;
+
+  if ((cmd_code > (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */)) ||
+      (cmd_code < SMP_OPCODE_MIN)) {
+    SMP_TRACE_WARNING("%s: Received command with RESERVED code 0x%02x",
+                      __func__, cmd_code);
+    return true;
+  }
+
+  if (!smp_command_has_valid_fixed_length(p_cb)) {
+    return true;
+  }
+
+  return false;
+}
+
+/*******************************************************************************
+ *
  * Function         smp_command_has_invalid_parameters
  *
  * Description      Checks if the received SMP command has invalid parameters
diff --git a/stack/test/common/mock_btsnoop_module.cc b/stack/test/common/mock_btsnoop_module.cc
new file mode 100644
index 0000000..7a5c5ae
--- /dev/null
+++ b/stack/test/common/mock_btsnoop_module.cc
@@ -0,0 +1,42 @@
+/******************************************************************************
+ *
+ *  Copyright 2019 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 "hci/include/btsnoop.h"
+
+static void capture(const BT_HDR*, bool) { /* do nothing */
+}
+
+static void whitelist_l2c_channel(uint16_t, uint16_t,
+                                  uint16_t) { /* do nothing */
+}
+
+static void whitelist_rfc_dlci(uint16_t, uint8_t) { /* do nothing */
+}
+
+static void add_rfc_l2c_channel(uint16_t, uint16_t, uint16_t) { /* do nothing */
+}
+
+static void clear_l2cap_whitelist(uint16_t, uint16_t,
+                                  uint16_t) { /* do nothing */
+}
+
+static const btsnoop_t fake_snoop = {capture, whitelist_l2c_channel,
+                                     whitelist_rfc_dlci, add_rfc_l2c_channel,
+                                     clear_l2cap_whitelist};
+
+const btsnoop_t* btsnoop_get_interface() { return &fake_snoop; }
diff --git a/stack/test/common/mock_l2cap_layer.cc b/stack/test/common/mock_l2cap_layer.cc
index 9f08d56..4756f17 100644
--- a/stack/test/common/mock_l2cap_layer.cc
+++ b/stack/test/common/mock_l2cap_layer.cc
@@ -24,9 +24,11 @@
   l2cap_interface = mock_l2cap_interface;
 }
 
-uint16_t L2CA_Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info) {
-  VLOG(1) << __func__ << ": psm=" << psm << ", p_cb_info=" << p_cb_info;
-  return l2cap_interface->Register(psm, p_cb_info);
+uint16_t L2CA_Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info,
+                       bool enable_snoop) {
+  VLOG(1) << __func__ << ": psm=" << psm << ", p_cb_info=" << p_cb_info
+          << ", enable_snoop=" << enable_snoop;
+  return l2cap_interface->Register(psm, p_cb_info, enable_snoop);
 }
 
 uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& bd_addr) {
diff --git a/stack/test/common/mock_l2cap_layer.h b/stack/test/common/mock_l2cap_layer.h
index 78c8a9c..ade7585 100644
--- a/stack/test/common/mock_l2cap_layer.h
+++ b/stack/test/common/mock_l2cap_layer.h
@@ -26,7 +26,8 @@
 
 class L2capInterface {
  public:
-  virtual uint16_t Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info) = 0;
+  virtual uint16_t Register(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info,
+                            bool enable_snoop) = 0;
   virtual uint16_t ConnectRequest(uint16_t psm, const RawAddress& bd_addr) = 0;
   virtual bool ConnectResponse(const RawAddress& bd_addr, uint8_t id,
                                uint16_t lcid, uint16_t result,
@@ -41,7 +42,8 @@
 
 class MockL2capInterface : public L2capInterface {
  public:
-  MOCK_METHOD2(Register, uint16_t(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info));
+  MOCK_METHOD3(Register, uint16_t(uint16_t psm, tL2CAP_APPL_INFO* p_cb_info,
+                                  bool enable_snoop));
   MOCK_METHOD2(ConnectRequest,
                uint16_t(uint16_t psm, const RawAddress& bd_addr));
   MOCK_METHOD5(ConnectResponse,
diff --git a/stack/test/rfcomm/stack_rfcomm_test.cc b/stack/test/rfcomm/stack_rfcomm_test.cc
index 3d9da3f..52e1170 100644
--- a/stack/test/rfcomm/stack_rfcomm_test.cc
+++ b/stack/test/rfcomm/stack_rfcomm_test.cc
@@ -453,7 +453,7 @@
         &btm_security_internal_interface_);
     bluetooth::l2cap::SetMockInterface(&l2cap_interface_);
     rfcomm_callback = &rfcomm_callback_;
-    EXPECT_CALL(l2cap_interface_, Register(BT_PSM_RFCOMM, _))
+    EXPECT_CALL(l2cap_interface_, Register(BT_PSM_RFCOMM, _, _))
         .WillOnce(
             DoAll(SaveArgPointee<1>(&l2cap_appl_info_), Return(BT_PSM_RFCOMM)));
     RFCOMM_Init();
diff --git a/test/suite/Android.bp b/test/suite/Android.bp
index 85b46fa..1d919ed 100644
--- a/test/suite/Android.bp
+++ b/test/suite/Android.bp
@@ -15,6 +15,8 @@
     shared_libs: [
         "liblog",
         "libcutils",
+        "libbinder",
+        "libutils",
     ],
     static_libs: [
         "libbtcore",
@@ -40,6 +42,8 @@
     shared_libs: [
         "liblog",
         "libcutils",
+        "libbinder",
+        "libutils",
     ],
     static_libs: [
         "libbtcore",
diff --git a/test/suite/adapter/adapter_unittest.cc b/test/suite/adapter/adapter_unittest.cc
index 24ca3e5..7a26e28 100644
--- a/test/suite/adapter/adapter_unittest.cc
+++ b/test/suite/adapter/adapter_unittest.cc
@@ -35,7 +35,7 @@
   EXPECT_EQ(GetState(), BT_STATE_OFF)
       << "Test should be run with Adapter disabled";
 
-  EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+  EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_EQ(GetState(), BT_STATE_ON) << "Adapter did not turn on.";
 
@@ -49,7 +49,7 @@
       << "Test should be run with Adapter disabled";
 
   for (int i = 0; i < kTestRepeatCount; ++i) {
-    EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+    EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
     semaphore_wait(adapter_state_changed_callback_sem_);
     EXPECT_EQ(GetState(), BT_STATE_ON) << "Adapter did not turn on.";
 
@@ -62,7 +62,7 @@
 TEST_F(BluetoothTest, AdapterSetGetName) {
   bt_property_t* new_name = property_new_name("BluetoothTestName1");
 
-  EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+  EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_EQ(GetState(), BT_STATE_ON)
       << "Test should be run with Adapter enabled";
@@ -114,7 +114,7 @@
 }
 
 TEST_F(BluetoothTest, AdapterStartDiscovery) {
-  EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+  EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_EQ(GetState(), BT_STATE_ON)
       << "Test should be run with Adapter enabled";
@@ -130,7 +130,7 @@
 }
 
 TEST_F(BluetoothTest, AdapterCancelDiscovery) {
-  EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+  EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_EQ(GetState(), BT_STATE_ON)
       << "Test should be run with Adapter enabled";
@@ -155,7 +155,7 @@
   RawAddress bdaddr = {{0x22, 0x22, 0x22, 0x22, 0x22, 0x22}};
 
   for (int i = 0; i < kTestRepeatCount; ++i) {
-    EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+    EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
     semaphore_wait(adapter_state_changed_callback_sem_);
     EXPECT_EQ(GetState(), BT_STATE_ON) << "Adapter did not turn on.";
 
@@ -179,8 +179,8 @@
   ASSERT_TRUE(bt_callbacks != nullptr);
 
   for (int i = 0; i < kTestRepeatCount; ++i) {
-    bt_interface()->init(bt_callbacks);
-    EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+    bt_interface()->init(bt_callbacks, false, false);
+    EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
     semaphore_wait(adapter_state_changed_callback_sem_);
     EXPECT_EQ(GetState(), BT_STATE_ON) << "Adapter did not turn on.";
 
diff --git a/test/suite/adapter/bluetooth_test.cc b/test/suite/adapter/bluetooth_test.cc
index 02132f1..626ac42 100644
--- a/test/suite/adapter/bluetooth_test.cc
+++ b/test/suite/adapter/bluetooth_test.cc
@@ -17,6 +17,8 @@
  ******************************************************************************/
 
 #include "adapter/bluetooth_test.h"
+#include <binder/ProcessState.h>
+#include <stdio.h>
 #include <mutex>
 #include "btcore/include/property.h"
 
@@ -31,6 +33,7 @@
 namespace bttest {
 
 void BluetoothTest::SetUp() {
+  android::ProcessState::self()->startThreadPool();
   bt_interface_ = nullptr;
   state_ = BT_STATE_OFF;
   properties_changed_count_ = 0;
@@ -46,6 +49,9 @@
   adapter_state_changed_callback_sem_ = semaphore_new(0);
   discovery_state_changed_callback_sem_ = semaphore_new(0);
 
+  remove("/data/misc/bluedroid/bt_config.conf.encrypted-checksum");
+  remove("/data/misc/bluedroid/bt_config.bak.encrypted-checksum");
+
   bluetooth::hal::BluetoothInterface::Initialize();
   ASSERT_TRUE(bluetooth::hal::BluetoothInterface::IsInitialized());
   auto bt_hal_interface = bluetooth::hal::BluetoothInterface::Get();
diff --git a/test/suite/gatt/gatt_test.cc b/test/suite/gatt/gatt_test.cc
index e3546d3..8c8f1ab 100644
--- a/test/suite/gatt/gatt_test.cc
+++ b/test/suite/gatt/gatt_test.cc
@@ -33,7 +33,7 @@
   status_ = 0;
 
   BluetoothTest::SetUp();
-  ASSERT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+  ASSERT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   EXPECT_TRUE(GetState() == BT_STATE_ON);
 
diff --git a/test/suite/rfcomm/rfcomm_test.cc b/test/suite/rfcomm/rfcomm_test.cc
index 01d9fed..d5baf35 100644
--- a/test/suite/rfcomm/rfcomm_test.cc
+++ b/test/suite/rfcomm/rfcomm_test.cc
@@ -28,7 +28,7 @@
 void RFCommTest::SetUp() {
   BluetoothTest::SetUp();
 
-  ASSERT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
+  ASSERT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
   semaphore_wait(adapter_state_changed_callback_sem_);
   ASSERT_TRUE(GetState() == BT_STATE_ON);
   socket_interface_ =
diff --git a/udrv/ulinux/uipc.cc b/udrv/ulinux/uipc.cc
index e2f2950..24fa711 100644
--- a/udrv/ulinux/uipc.cc
+++ b/udrv/ulinux/uipc.cc
@@ -621,15 +621,15 @@
 uint32_t UIPC_Read(tUIPC_STATE& uipc, tUIPC_CH_ID ch_id,
                    UNUSED_ATTR uint16_t* p_msg_evt, uint8_t* p_buf,
                    uint32_t len) {
-  int n_read = 0;
-  int fd = uipc.ch[ch_id].fd;
-  struct pollfd pfd;
-
   if (ch_id >= UIPC_CH_NUM) {
     BTIF_TRACE_ERROR("UIPC_Read : invalid ch id %d", ch_id);
     return 0;
   }
 
+  int n_read = 0;
+  int fd = uipc.ch[ch_id].fd;
+  struct pollfd pfd;
+
   if (fd == UIPC_DISCONNECTED) {
     BTIF_TRACE_ERROR("UIPC_Read : channel %d closed", ch_id);
     return 0;