[automerger skipped] DO NOT MERGE: Remove pairing on incoming bond request am: 85b5df1d0d am: ab50a6b284 -s ours

am skip reason: Change-Id I048b7b142e3fe2096cf1a9aa2931c175fa52cd45 with SHA-1 e29c52cfda is in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/system/bt/+/11934228

Change-Id: I01231f49767b1f5e54f43bf119e410a147198033
diff --git a/Android.bp b/Android.bp
index dae6460..462b8be 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,6 +14,7 @@
     "bta",
     "vendor_libs",
     "test",
+    "types",
     "udrv",
     "tools",
 ]
diff --git a/bta/Android.bp b/bta/Android.bp
index 08ce3b1..a69e174 100644
--- a/bta/Android.bp
+++ b/bta/Android.bp
@@ -7,7 +7,6 @@
         "dm",
         "hd",
         "hh",
-        "closure",
     ],
     include_dirs: [
         "system/bt",
@@ -51,7 +50,6 @@
         "av/bta_av_ci.cc",
         "av/bta_av_main.cc",
         "av/bta_av_ssm.cc",
-        "closure/bta_closure.cc",
         "dm/bta_dm_act.cc",
         "dm/bta_dm_api.cc",
         "dm/bta_dm_cfg.cc",
@@ -118,7 +116,6 @@
     name: "net_test_bta",
     defaults: ["fluoride_bta_defaults"],
     srcs: [
-        "test/bta_closure_test.cc",
         "test/bta_hf_client_test.cc",
     ],
     shared_libs: [
@@ -129,6 +126,7 @@
     static_libs: [
         "libbtcore",
         "libbt-bta",
+        "libbluetooth-types",
         "libosi",
         "libbt-protos",
     ],
diff --git a/bta/BUILD.gn b/bta/BUILD.gn
index 56a7597..07779d0 100644
--- a/bta/BUILD.gn
+++ b/bta/BUILD.gn
@@ -34,7 +34,6 @@
     "av/bta_av_ci.cc",
     "av/bta_av_main.cc",
     "av/bta_av_ssm.cc",
-    "closure/bta_closure.cc",
     "dm/bta_dm_act.cc",
     "dm/bta_dm_api.cc",
     "dm/bta_dm_cfg.cc",
diff --git a/bta/ag/bta_ag_act.cc b/bta/ag/bta_ag_act.cc
index af697bc..c583054 100644
--- a/bta/ag/bta_ag_act.cc
+++ b/bta/ag/bta_ag_act.cc
@@ -86,9 +86,9 @@
   if (p_data) {
     /* if p_data is provided then we need to pick the bd address from the open
      * api structure */
-    bdcpy(open.bd_addr, p_data->api_open.bd_addr);
+    open.bd_addr = p_data->api_open.bd_addr;
   } else {
-    bdcpy(open.bd_addr, p_scb->peer_addr);
+    open.bd_addr = p_scb->peer_addr;
   }
 
   (*bta_ag_cb.p_cback)(BTA_AG_OPEN_EVT, (tBTA_AG*)&open);
@@ -181,11 +181,11 @@
  *
  ******************************************************************************/
 void bta_ag_start_open(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) {
-  BD_ADDR pending_bd_addr;
+  RawAddress pending_bd_addr;
 
   /* store parameters */
   if (p_data) {
-    bdcpy(p_scb->peer_addr, p_data->api_open.bd_addr);
+    p_scb->peer_addr = p_data->api_open.bd_addr;
     p_scb->open_services = p_data->api_open.services;
     p_scb->cli_sec_mask = p_data->api_open.sec_mask;
   }
@@ -195,7 +195,7 @@
     /* Let the incoming connection goes through.                        */
     /* Issue collision for this scb for now.                            */
     /* We will decide what to do when we find incoming connetion later. */
-    bta_ag_collision_cback(0, BTA_ID_AG, 0, p_scb->peer_addr);
+    bta_ag_collision_cback(0, BTA_ID_AG, 0, &p_scb->peer_addr);
     return;
   }
 
@@ -305,7 +305,7 @@
   /* reinitialize stuff */
 
   /* clear the remote BD address */
-  bdcpy(p_scb->peer_addr, bd_addr_null);
+  p_scb->peer_addr = RawAddress::kEmpty;
 
   /* call open cback w. failure */
   bta_ag_cback_open(p_scb, NULL, BTA_AG_FAIL_SDP);
@@ -347,7 +347,7 @@
   p_scb->svc_conn = false;
   p_scb->hsp_version = HSP_VERSION_1_2;
   /*Clear the BD address*/
-  bdcpy(p_scb->peer_addr, bd_addr_null);
+  p_scb->peer_addr = RawAddress::kEmpty;
 
   /* reopen registered servers */
   bta_ag_start_servers(p_scb, p_scb->reg_services);
@@ -395,7 +395,7 @@
 
   close.hdr.handle = bta_ag_scb_to_idx(p_scb);
   close.hdr.app_id = p_scb->app_id;
-  bdcpy(close.bd_addr, p_scb->peer_addr);
+  close.bd_addr = p_scb->peer_addr;
 
   bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
 
@@ -408,7 +408,7 @@
   /* if not deregistering (deallocating) reopen registered servers */
   if (p_scb->dealloc == false) {
     /* Clear peer bd_addr so instance can be reused */
-    bdcpy(p_scb->peer_addr, bd_addr_null);
+    p_scb->peer_addr = RawAddress::kEmpty;
 
     /* start only unopened server */
     services = p_scb->reg_services;
@@ -501,7 +501,7 @@
   uint16_t lcid;
   int i;
   tBTA_AG_SCB *ag_scb, *other_scb;
-  BD_ADDR dev_addr;
+  RawAddress dev_addr;
   int status;
 
   /* set role */
@@ -523,7 +523,7 @@
     if (ag_scb->in_use && alarm_is_scheduled(ag_scb->collision_timer)) {
       alarm_cancel(ag_scb->collision_timer);
 
-      if (bdcmp(dev_addr, ag_scb->peer_addr) == 0) {
+      if (dev_addr == ag_scb->peer_addr) {
         /* If incoming and outgoing device are same, nothing more to do. */
         /* Outgoing conn will be aborted because we have successful incoming
          * conn.  */
@@ -531,7 +531,7 @@
         /* Resume outgoing connection. */
         other_scb = bta_ag_get_other_idle_scb(p_scb);
         if (other_scb) {
-          bdcpy(other_scb->peer_addr, ag_scb->peer_addr);
+          other_scb->peer_addr = ag_scb->peer_addr;
           other_scb->open_services = ag_scb->open_services;
           other_scb->cli_sec_mask = ag_scb->cli_sec_mask;
 
@@ -543,7 +543,7 @@
     }
   }
 
-  bdcpy(p_scb->peer_addr, dev_addr);
+  p_scb->peer_addr = dev_addr;
 
   /* determine connected service from port handle */
   for (i = 0; i < BTA_AG_NUM_IDX; i++) {
@@ -755,7 +755,7 @@
     evt.hdr.handle = bta_ag_scb_to_idx(p_scb);
     evt.hdr.app_id = p_scb->app_id;
     evt.peer_feat = p_scb->peer_features;
-    bdcpy(evt.bd_addr, p_scb->peer_addr);
+    evt.bd_addr = p_scb->peer_addr;
     evt.peer_codec = p_scb->peer_codecs;
 
     if ((p_scb->call_ind != BTA_AG_CALL_INACTIVE) ||
diff --git a/bta/ag/bta_ag_api.cc b/bta/ag/bta_ag_api.cc
index 6df3a1e..4c0e285 100644
--- a/bta/ag/bta_ag_api.cc
+++ b/bta/ag/bta_ag_api.cc
@@ -155,14 +155,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_AgOpen(uint16_t handle, BD_ADDR bd_addr, tBTA_SEC sec_mask,
+void BTA_AgOpen(uint16_t handle, const RawAddress& bd_addr, tBTA_SEC sec_mask,
                 tBTA_SERVICE_MASK services) {
   tBTA_AG_API_OPEN* p_buf =
       (tBTA_AG_API_OPEN*)osi_malloc(sizeof(tBTA_AG_API_OPEN));
 
   p_buf->hdr.event = BTA_AG_API_OPEN_EVT;
   p_buf->hdr.layer_specific = handle;
-  bdcpy(p_buf->bd_addr, bd_addr);
+  p_buf->bd_addr = bd_addr;
   p_buf->services = services;
   p_buf->sec_mask = sec_mask;
 
@@ -276,3 +276,13 @@
 
   bta_sys_sendmsg(p_buf);
 }
+
+void BTA_AgSetScoAllowed(bool value) {
+  tBTA_AG_API_SET_SCO_ALLOWED* p_buf = (tBTA_AG_API_SET_SCO_ALLOWED*)osi_malloc(
+      sizeof(tBTA_AG_API_SET_SCO_ALLOWED));
+
+  p_buf->hdr.event = BTA_AG_API_SET_SCO_ALLOWED_EVT;
+  p_buf->value = value;
+
+  bta_sys_sendmsg(p_buf);
+}
diff --git a/bta/ag/bta_ag_cmd.cc b/bta/ag/bta_ag_cmd.cc
index 1264b77..dbd38ed 100644
--- a/bta/ag/bta_ag_cmd.cc
+++ b/bta/ag/bta_ag_cmd.cc
@@ -869,7 +869,7 @@
   val.hdr.app_id = p_scb->app_id;
   val.hdr.status = BTA_AG_SUCCESS;
   val.num = int_arg;
-  bdcpy(val.bd_addr, p_scb->peer_addr);
+  val.bd_addr = p_scb->peer_addr;
 
   if ((p_end - p_arg + 1) >= (long)sizeof(val.str)) {
     APPL_TRACE_ERROR("%s: p_arg is too long, send error and return", __func__);
diff --git a/bta/ag/bta_ag_int.h b/bta/ag/bta_ag_int.h
index a74937b..bb40f22 100644
--- a/bta/ag/bta_ag_int.h
+++ b/bta/ag/bta_ag_int.h
@@ -99,7 +99,8 @@
 
   /* these events are handled outside of the state machine */
   BTA_AG_API_ENABLE_EVT,
-  BTA_AG_API_DISABLE_EVT
+  BTA_AG_API_DISABLE_EVT,
+  BTA_AG_API_SET_SCO_ALLOWED_EVT
 };
 
 /* Actions to perform after a SCO event */
@@ -153,7 +154,7 @@
 /* data type for BTA_AG_API_OPEN_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_SERVICE_MASK services;
   tBTA_SEC sec_mask;
 } tBTA_AG_API_OPEN;
@@ -171,6 +172,12 @@
   tBTA_AG_PEER_CODEC codec;
 } tBTA_AG_API_SETCODEC;
 
+/* data type for BTA_AG_API_SET_SCO_ALLOWED_EVT */
+typedef struct {
+  BT_HDR hdr;
+  bool value;
+} tBTA_AG_API_SET_SCO_ALLOWED;
+
 /* data type for BTA_AG_DISC_RESULT_EVT */
 typedef struct {
   BT_HDR hdr;
@@ -218,7 +225,7 @@
   char clip[BTA_AG_AT_MAX_LEN + 1];     /* number string used for CLIP */
   uint16_t serv_handle[BTA_AG_NUM_IDX]; /* RFCOMM server handles */
   tBTA_AG_AT_CB at_cb;                  /* AT command interpreter */
-  BD_ADDR peer_addr;                    /* peer bd address */
+  RawAddress peer_addr;                 /* peer bd address */
   tSDP_DISCOVERY_DB* p_disc_db;         /* pointer to discovery database */
   tBTA_SERVICE_MASK reg_services;       /* services specified in register API */
   tBTA_SERVICE_MASK open_services;      /* services specified in open API */
@@ -316,7 +323,7 @@
 extern uint16_t bta_ag_scb_to_idx(tBTA_AG_SCB* p_scb);
 extern tBTA_AG_SCB* bta_ag_scb_by_idx(uint16_t idx);
 extern uint8_t bta_ag_service_to_idx(tBTA_SERVICE_MASK services);
-extern uint16_t bta_ag_idx_by_bdaddr(BD_ADDR peer_addr);
+extern uint16_t bta_ag_idx_by_bdaddr(const RawAddress* peer_addr);
 extern bool bta_ag_other_scb_open(tBTA_AG_SCB* p_curr_scb);
 extern bool bta_ag_scb_open(tBTA_AG_SCB* p_curr_scb);
 extern tBTA_AG_SCB* bta_ag_get_other_idle_scb(tBTA_AG_SCB* p_curr_scb);
@@ -324,7 +331,7 @@
                               tBTA_AG_DATA* p_data);
 extern bool bta_ag_hdl_event(BT_HDR* p_msg);
 extern void bta_ag_collision_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                                   uint8_t app_id, BD_ADDR peer_addr);
+                                   uint8_t app_id, const RawAddress* peer_addr);
 extern void bta_ag_resume_open(tBTA_AG_SCB* p_scb);
 
 /* SDP functions */
@@ -396,5 +403,6 @@
 extern void bta_ag_ci_sco_data(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
 extern void bta_ag_ci_rx_data(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
 extern void bta_ag_rcvd_slc_ready(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
+extern void bta_ag_set_sco_allowed(tBTA_AG_DATA* p_data);
 
 #endif /* BTA_AG_INT_H */
diff --git a/bta/ag/bta_ag_main.cc b/bta/ag/bta_ag_main.cc
index 908ccde..d33247e 100644
--- a/bta/ag/bta_ag_main.cc
+++ b/bta/ag/bta_ag_main.cc
@@ -38,8 +38,6 @@
 #define BTA_AG_DEBUG FALSE
 #endif
 
-extern fixed_queue_t* btu_bta_alarm_queue;
-
 #if (BTA_AG_DEBUG == TRUE)
 static char* bta_ag_evt_str(uint16_t event, tBTA_AG_RES result);
 static char* bta_ag_state_str(uint8_t state);
@@ -393,13 +391,13 @@
  * Returns          Index of SCB or zero if none found.
  *
  ******************************************************************************/
-uint16_t bta_ag_idx_by_bdaddr(BD_ADDR peer_addr) {
+uint16_t bta_ag_idx_by_bdaddr(const RawAddress* peer_addr) {
   tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
   uint16_t i;
 
   if (peer_addr != NULL) {
     for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++) {
-      if (p_scb->in_use && !bdcmp(peer_addr, p_scb->peer_addr)) {
+      if (p_scb->in_use && *peer_addr == p_scb->peer_addr) {
         return (i + 1);
       }
     }
@@ -511,7 +509,8 @@
  *
  ******************************************************************************/
 void bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, uint8_t id,
-                            UNUSED_ATTR uint8_t app_id, BD_ADDR peer_addr) {
+                            UNUSED_ATTR uint8_t app_id,
+                            const RawAddress* peer_addr) {
   uint16_t handle;
   tBTA_AG_SCB* p_scb;
 
@@ -544,9 +543,8 @@
       bta_ag_start_servers(p_scb, p_scb->reg_services);
 
     /* Start timer to han */
-    alarm_set_on_queue(p_scb->collision_timer, BTA_AG_COLLISION_TIMEOUT_MS,
-                       bta_ag_collision_timer_cback, p_scb,
-                       btu_bta_alarm_queue);
+    alarm_set_on_mloop(p_scb->collision_timer, BTA_AG_COLLISION_TIMEOUT_MS,
+                       bta_ag_collision_timer_cback, p_scb);
   }
 }
 
@@ -799,6 +797,10 @@
       bta_ag_api_result((tBTA_AG_DATA*)p_msg);
       break;
 
+    case BTA_AG_API_SET_SCO_ALLOWED_EVT:
+      bta_ag_set_sco_allowed((tBTA_AG_DATA*)p_msg);
+      break;
+
     /* all others reference scb by handle */
     default:
       p_scb = bta_ag_scb_by_idx(p_msg->layer_specific);
diff --git a/bta/ag/bta_ag_rfc.cc b/bta/ag/bta_ag_rfc.cc
index fcf61a1..02729d5 100644
--- a/bta/ag/bta_ag_rfc.cc
+++ b/bta/ag/bta_ag_rfc.cc
@@ -274,7 +274,7 @@
 
       bta_ag_port_status = RFCOMM_CreateConnection(
           bta_ag_uuid[i], bta_ag_cb.profile[i].scn, true, BTA_AG_MTU,
-          (uint8_t*)bd_addr_any, &(p_scb->serv_handle[i]),
+          RawAddress::kAny, &(p_scb->serv_handle[i]),
           bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]);
 
       if (bta_ag_port_status == PORT_SUCCESS) {
diff --git a/bta/ag/bta_ag_sco.cc b/bta/ag/bta_ag_sco.cc
index e67c122..f118988 100644
--- a/bta/ag/bta_ag_sco.cc
+++ b/bta/ag/bta_ag_sco.cc
@@ -47,13 +47,13 @@
 #define BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS (3 * 1000) /* 3 seconds */
 #endif
 
-extern fixed_queue_t* btu_bta_alarm_queue;
-
 #if (BTA_AG_SCO_DEBUG == TRUE)
 static char* bta_ag_sco_evt_str(uint8_t event);
 static char* bta_ag_sco_state_str(uint8_t state);
 #endif
 
+static bool sco_allowed = true;
+
 #define BTA_AG_NO_EDR_ESCO                                       \
   (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | \
    ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5)
@@ -425,12 +425,9 @@
     bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
   } else {
     /* Not initiating, go to listen mode */
-    uint8_t* p_bd_addr = NULL;
-    p_bd_addr = p_scb->peer_addr;
-
-    tBTM_STATUS status =
-        BTM_CreateSco(p_bd_addr, false, params.packet_types, &p_scb->sco_idx,
-                      bta_ag_sco_conn_cback, bta_ag_sco_disc_cback);
+    tBTM_STATUS status = BTM_CreateSco(
+        &p_scb->peer_addr, false, params.packet_types, &p_scb->sco_idx,
+        bta_ag_sco_conn_cback, bta_ag_sco_disc_cback);
     if (status == BTM_CMD_STARTED)
       BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback);
 
@@ -496,7 +493,7 @@
 #endif
 
     tBTM_STATUS status = BTM_CreateSco(
-        p_scb->peer_addr, true, params.packet_types, &p_scb->sco_idx,
+        &p_scb->peer_addr, true, params.packet_types, &p_scb->sco_idx,
         bta_ag_sco_conn_cback, bta_ag_sco_disc_cback);
     if (status == BTM_CMD_STARTED) {
       /* Initiating the connection, set the current sco handle */
@@ -559,9 +556,9 @@
     bta_ag_send_bcs(p_scb, NULL);
 
     /* Start timer to handle timeout */
-    alarm_set_on_queue(
-        p_scb->codec_negotiation_timer, BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS,
-        bta_ag_codec_negotiation_timer_cback, p_scb, btu_bta_alarm_queue);
+    alarm_set_on_mloop(p_scb->codec_negotiation_timer,
+                       BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS,
+                       bta_ag_codec_negotiation_timer_cback, p_scb);
   } else {
     /* use same codec type as previous SCO connection, skip codec negotiation */
     APPL_TRACE_DEBUG(
@@ -1162,6 +1159,11 @@
 void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) {
   uint8_t event;
 
+  if (!sco_allowed) {
+    APPL_TRACE_DEBUG("%s not opening sco, by policy", __func__);
+    return;
+  }
+
   /* if another scb using sco, this is a transfer */
   if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb != p_scb) {
     event = BTA_AG_SCO_XFER_E;
@@ -1360,6 +1362,11 @@
 #endif
 }
 
+void bta_ag_set_sco_allowed(tBTA_AG_DATA* p_data) {
+  sco_allowed = ((tBTA_AG_API_SET_SCO_ALLOWED*)p_data)->value;
+  APPL_TRACE_DEBUG(sco_allowed ? "sco now allowed" : "sco now not allowed");
+}
+
 /*******************************************************************************
  *  Debugging functions
  ******************************************************************************/
diff --git a/bta/ar/bta_ar.cc b/bta/ar/bta_ar.cc
index f5aeeca..3b93e97 100644
--- a/bta/ar/bta_ar.cc
+++ b/bta/ar/bta_ar.cc
@@ -73,8 +73,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_ar_avdt_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                              tAVDT_CTRL* p_data) {
+static void bta_ar_avdt_cback(uint8_t handle, const RawAddress* bd_addr,
+                              uint8_t event, tAVDT_CTRL* p_data) {
   /* route the AVDT registration callback to av or avk */
   if (bta_ar_cb.p_av_conn_cback)
     (*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data);
@@ -153,17 +153,17 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, BD_ADDR bd_addr) {
+void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, const RawAddress& bd_addr) {
   uint8_t event = BTA_AR_AVDT_CONN_EVT;
   tAVDT_CTRL data;
 
   if (sys_id == BTA_ID_AV) {
     if (bta_ar_cb.p_avk_conn_cback) {
-      (*bta_ar_cb.p_avk_conn_cback)(0, bd_addr, event, &data);
+      (*bta_ar_cb.p_avk_conn_cback)(0, &bd_addr, event, &data);
     }
   } else if (sys_id == BTA_ID_AVK) {
     if (bta_ar_cb.p_av_conn_cback) {
-      (*bta_ar_cb.p_av_conn_cback)(0, bd_addr, event, &data);
+      (*bta_ar_cb.p_av_conn_cback)(0, &bd_addr, event, &data);
     }
   }
 }
diff --git a/bta/av/bta_av_aact.cc b/bta/av/bta_av_aact.cc
index ed8ee30..12f8b24 100644
--- a/bta/av/bta_av_aact.cc
+++ b/bta/av/bta_av_aact.cc
@@ -201,25 +201,25 @@
     0                          /* AVDT_DELAY_REPORT_CFM_EVT */
 };
 
-static void bta_av_stream0_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data);
-static void bta_av_stream1_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data);
+static void bta_av_stream0_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data);
+static void bta_av_stream1_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data);
 #if BTA_AV_NUM_STRS > 2
-static void bta_av_stream2_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data);
+static void bta_av_stream2_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data);
 #endif
 #if BTA_AV_NUM_STRS > 3
-static void bta_av_stream3_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data);
+static void bta_av_stream3_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data);
 #endif
 #if BTA_AV_NUM_STRS > 4
-static void bta_av_stream4_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data);
+static void bta_av_stream4_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data);
 #endif
 #if BTA_AV_NUM_STRS > 5
-static void bta_av_stream5_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data);
+static void bta_av_stream5_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data);
 #endif
 /* the array of callback functions to receive events from AVDT control channel
  */
@@ -291,10 +291,10 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_av_save_addr(tBTA_AV_SCB* p_scb, const BD_ADDR b) {
+static void bta_av_save_addr(tBTA_AV_SCB* p_scb, const RawAddress& b) {
   APPL_TRACE_DEBUG("%s: r:%d, s:%d", __func__, p_scb->recfg_sup,
                    p_scb->suspend_sup);
-  if (bdcmp(p_scb->peer_addr, b) != 0) {
+  if (p_scb->peer_addr != b) {
     APPL_TRACE_ERROR("%s: reset flags", __func__);
     /* a new addr, reset the supported flags */
     p_scb->recfg_sup = true;
@@ -303,7 +303,7 @@
 
   /* do this copy anyway, just in case the first addr matches
    * the control block one by accident */
-  bdcpy(p_scb->peer_addr, b);
+  p_scb->peer_addr = b;
 }
 
 /*******************************************************************************
@@ -324,7 +324,10 @@
   start.status = BTA_AV_FAIL;
   start.initiator = true;
   start.hndl = p_scb->hndl;
-  (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
+
+  tBTA_AV bta_av_data;
+  bta_av_data.start = start;
+  (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
 }
 
 /*******************************************************************************
@@ -402,6 +405,8 @@
 
   /* if no streams available then stream open fails */
   if (!sent_cmd) {
+    APPL_TRACE_ERROR("%s: BTA_AV_STR_GETCAP_FAIL_EVT: peer_addr=%s", __func__,
+                     p_scb->peer_addr.ToString().c_str());
     bta_av_ssm_execute(p_scb, BTA_AV_STR_GETCAP_FAIL_EVT, p_data);
   }
 
@@ -417,7 +422,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_av_proc_stream_evt(uint8_t handle, BD_ADDR bd_addr,
+static void bta_av_proc_stream_evt(uint8_t handle, const RawAddress* bd_addr,
                                    uint8_t event, tAVDT_CTRL* p_data,
                                    int index) {
   uint16_t sec_len = 0;
@@ -443,10 +448,8 @@
     p_msg->hdr.offset = 0;
 
     if (bd_addr != NULL) {
-      bdcpy(p_msg->bd_addr, bd_addr);
-      APPL_TRACE_DEBUG("%s: bd_addr:%02x-%02x-%02x-%02x-%02x-%02x", __func__,
-                       bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3],
-                       bd_addr[4], bd_addr[5]);
+      p_msg->bd_addr = *bd_addr;
+      VLOG(1) << __func__ << ": bd_addr:" << bd_addr;
     }
 
     if (p_data != NULL) {
@@ -479,7 +482,7 @@
            * SST is at INIT state, change it to INCOMING state to handle the
            * signalling
            * from the 2nd SEP. */
-          if ((bta_av_find_lcb(bd_addr, BTA_AV_LCB_FIND) != NULL) &&
+          if ((bta_av_find_lcb(*bd_addr, BTA_AV_LCB_FIND) != NULL) &&
               (bta_av_is_scb_init(p_scb))) {
             bta_av_set_scb_sst_incoming(p_scb);
 
@@ -604,8 +607,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_av_stream0_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data) {
+static void bta_av_stream0_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data) {
   APPL_TRACE_VERBOSE("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
   bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 0);
 }
@@ -619,8 +622,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_av_stream1_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data) {
+static void bta_av_stream1_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data) {
   APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
   bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 1);
 }
@@ -635,8 +638,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_av_stream2_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data) {
+static void bta_av_stream2_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data) {
   APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
   bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 2);
 }
@@ -652,8 +655,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_av_stream3_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data) {
+static void bta_av_stream3_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data) {
   APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
   bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 3);
 }
@@ -669,8 +672,8 @@
  *
  ******************************************************************************/
 #if BTA_AV_NUM_STRS > 4
-static void bta_av_stream4_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data) {
+static void bta_av_stream4_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data) {
   APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
   bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 4);
 }
@@ -686,8 +689,8 @@
  *
  ******************************************************************************/
 #if BTA_AV_NUM_STRS > 5
-static void bta_av_stream5_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                                 tAVDT_CTRL* p_data) {
+static void bta_av_stream5_cback(uint8_t handle, const RawAddress* bd_addr,
+                                 uint8_t event, tAVDT_CTRL* p_data) {
   APPL_TRACE_EVENT("%s: avdt_handle: %d event=0x%x", __func__, handle, event);
   bta_av_proc_stream_evt(handle, bd_addr, event, p_data, 5);
 }
@@ -809,8 +812,6 @@
  ******************************************************************************/
 void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
   bool initiator = false;
-  tBTA_AV_START start;
-  tBTA_AV_OPEN av_open;
 
   APPL_TRACE_DEBUG("%s: q_tag:%d, wait:x%x, role:x%x", __func__, p_scb->q_tag,
                    p_scb->wait, p_scb->role);
@@ -823,11 +824,14 @@
         p_scb->role &= ~BTA_AV_ROLE_START_INT;
         bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
         /* start failed because of role switch. */
+        tBTA_AV_START start;
         start.chnl = p_scb->chnl;
         start.status = BTA_AV_FAIL_ROLE;
         start.hndl = p_scb->hndl;
         start.initiator = initiator;
-        (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
+        tBTA_AV bta_av_data;
+        bta_av_data.start = start;
+        (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
       } else {
         bta_av_start_ok(p_scb, p_data);
       }
@@ -840,15 +844,19 @@
 
       if (p_data->role_res.hci_status != HCI_SUCCESS) {
         /* Open failed because of role switch. */
-        bdcpy(av_open.bd_addr, p_scb->peer_addr);
+        tBTA_AV_OPEN av_open;
+        av_open.bd_addr = p_scb->peer_addr;
         av_open.chnl = p_scb->chnl;
         av_open.hndl = p_scb->hndl;
-        start.status = BTA_AV_FAIL_ROLE;
-        if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC)
+        av_open.status = BTA_AV_FAIL_ROLE;
+        if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC) {
           av_open.sep = AVDT_TSEP_SNK;
-        else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)
+        } else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK) {
           av_open.sep = AVDT_TSEP_SRC;
-        (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV*)&av_open);
+        }
+        tBTA_AV bta_av_data;
+        bta_av_data.open = av_open;
+        (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, &bta_av_data);
       } else {
         /* Continue av open process */
         p_scb->q_info.open.switch_res = BTA_AV_RS_DONE;
@@ -919,6 +927,8 @@
     case BTA_AV_RS_FAIL:
       /* report a new failure event  */
       p_scb->open_status = BTA_AV_FAIL_ROLE;
+      APPL_TRACE_ERROR("%s: BTA_AV_SDP_DISC_FAIL_EVT: peer_addr=%s", __func__,
+                       p_scb->peer_addr.ToString().c_str());
       bta_av_ssm_execute(p_scb, BTA_AV_SDP_DISC_FAIL_EVT, NULL);
       break;
 
@@ -1041,7 +1051,9 @@
         (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
     if (p_scb->offload_start_pending) {
       tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
-      (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
+      tBTA_AV bta_av_data;
+      bta_av_data.status = status;
+      (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &bta_av_data);
     }
   */
 
@@ -1059,7 +1071,7 @@
   } else {
     /* report stream closed to main SM */
     msg.is_up = false;
-    bdcpy(msg.peer_addr, p_scb->peer_addr);
+    msg.peer_addr = p_scb->peer_addr;
     bta_av_conn_chg((tBTA_AV_DATA*)&msg);
   }
 }
@@ -1169,7 +1181,8 @@
                            UNUSED_ATTR tBTA_AV_DATA* p_data) {
   tBTA_AV_RCB* p_rcb;
 
-  APPL_TRACE_DEBUG("%s: conn_lcb: 0x%x", __func__, bta_av_cb.conn_lcb);
+  APPL_TRACE_WARNING("%s: conn_lcb: 0x%x peer_addr: %s", __func__,
+                     bta_av_cb.conn_lcb, p_scb->peer_addr.ToString().c_str());
 
   alarm_cancel(bta_av_cb.link_signalling_timer);
   alarm_cancel(p_scb->avrc_ct_timer);
@@ -1246,8 +1259,7 @@
       (p_data->ci_setconfig.err_code == AVDT_SUCCESS) &&
       (p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback != NULL)) {
     tBTA_AV_MEDIA av_sink_codec_info;
-    memcpy(av_sink_codec_info.avk_config.bd_addr, p_scb->peer_addr,
-           sizeof(BD_ADDR));
+    av_sink_codec_info.avk_config.bd_addr = p_scb->peer_addr;
     av_sink_codec_info.avk_config.codec_info = p_scb->cfg.codec_info;
     p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(BTA_AV_SINK_MEDIA_CFG_EVT,
                                                       &av_sink_codec_info);
@@ -1275,7 +1287,7 @@
         num > 1) {
       /* if SBC is used by the SNK as INT, discover req is not sent in
        * bta_av_config_ind.
-                 * call disc_res now */
+       * call disc_res now */
       /* this is called in A2DP SRC path only, In case of SINK we don't need it
        */
       if (local_sep == AVDT_TSEP_SRC)
@@ -1318,13 +1330,12 @@
  ******************************************************************************/
 void bta_av_str_opened(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
   tBTA_AV_CONN_CHG msg;
-  tBTA_AV_OPEN open;
   uint8_t* p;
   uint16_t mtu;
 
   msg.hdr.layer_specific = p_scb->hndl;
   msg.is_up = true;
-  bdcpy(msg.peer_addr, p_scb->peer_addr);
+  msg.peer_addr = p_scb->peer_addr;
   p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
   bta_av_conn_chg((tBTA_AV_DATA*)&msg);
   /* set the congestion flag, so AV would not send media packets by accident */
@@ -1359,7 +1370,8 @@
      * the connection will be rejected.
      */
     /* check if other audio channel is started. If yes, start */
-    bdcpy(open.bd_addr, p_scb->peer_addr);
+    tBTA_AV_OPEN open;
+    open.bd_addr = p_scb->peer_addr;
     open.chnl = p_scb->chnl;
     open.hndl = p_scb->hndl;
     open.status = BTA_AV_SUCCESS;
@@ -1369,8 +1381,7 @@
     if (p != NULL) {
       if (HCI_EDR_ACL_2MPS_SUPPORTED(p)) open.edr |= BTA_AV_EDR_2MBPS;
       if (HCI_EDR_ACL_3MPS_SUPPORTED(p)) {
-        if (!interop_match_addr(INTEROP_2MBPS_LINK_ONLY,
-                                (const bt_bdaddr_t*)&p_scb->peer_addr)) {
+        if (!interop_match_addr(INTEROP_2MBPS_LINK_ONLY, &p_scb->peer_addr)) {
           open.edr |= BTA_AV_EDR_3MBPS;
         }
       }
@@ -1378,12 +1389,15 @@
 #if (BTA_AR_INCLUDED == TRUE)
     bta_ar_avdt_conn(BTA_ID_AV, open.bd_addr);
 #endif
-    if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC)
+    if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC) {
       open.sep = AVDT_TSEP_SNK;
-    else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)
+    } else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK) {
       open.sep = AVDT_TSEP_SRC;
+    }
 
-    (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV*)&open);
+    tBTA_AV bta_av_data;
+    bta_av_data.open = open;
+    (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, &bta_av_data);
     if (open.starting) {
       bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL);
     }
@@ -1408,17 +1422,18 @@
  *
  ******************************************************************************/
 void bta_av_security_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
-  tBTA_AV_PROTECT_REQ protect_req;
-
   p_scb->avdt_label = p_data->str_msg.msg.hdr.label;
 
   if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
+    tBTA_AV_PROTECT_REQ protect_req;
     protect_req.chnl = p_scb->chnl;
     protect_req.hndl = p_scb->hndl;
     protect_req.p_data = p_data->str_msg.msg.security_ind.p_data;
     protect_req.len = p_data->str_msg.msg.security_ind.len;
 
-    (*bta_av_cb.p_cback)(BTA_AV_PROTECT_REQ_EVT, (tBTA_AV*)&protect_req);
+    tBTA_AV bta_av_data;
+    bta_av_data.protect_req = protect_req;
+    (*bta_av_cb.p_cback)(BTA_AV_PROTECT_REQ_EVT, &bta_av_data);
   }
   /* app doesn't support security indication; respond with failure */
   else {
@@ -1437,16 +1452,17 @@
  *
  ******************************************************************************/
 void bta_av_security_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
-  tBTA_AV_PROTECT_RSP protect_rsp;
-
   if (bta_av_cb.features & BTA_AV_FEAT_PROTECT) {
+    tBTA_AV_PROTECT_RSP protect_rsp;
     protect_rsp.chnl = p_scb->chnl;
     protect_rsp.hndl = p_scb->hndl;
     protect_rsp.p_data = p_data->str_msg.msg.security_cfm.p_data;
     protect_rsp.len = p_data->str_msg.msg.security_cfm.len;
     protect_rsp.err_code = p_data->str_msg.msg.hdr.err_code;
 
-    (*bta_av_cb.p_cback)(BTA_AV_PROTECT_RSP_EVT, (tBTA_AV*)&protect_rsp);
+    tBTA_AV bta_av_data;
+    bta_av_data.protect_rsp = protect_rsp;
+    (*bta_av_cb.p_cback)(BTA_AV_PROTECT_RSP_EVT, &bta_av_data);
   }
 }
 
@@ -1520,7 +1536,12 @@
  *
  ******************************************************************************/
 void bta_av_sdp_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
-  if (!p_scb->open_status) p_scb->open_status = BTA_AV_FAIL_SDP;
+  APPL_TRACE_ERROR("%s: peer_addr=%s open_status=%d", __func__,
+                   p_scb->peer_addr.ToString().c_str(), p_scb->open_status);
+
+  if (p_scb->open_status == BTA_AV_SUCCESS) {
+    p_scb->open_status = BTA_AV_FAIL_SDP;
+  }
 
   p_scb->sdp_discovery_started = false;
   bta_av_str_closed(p_scb, p_data);
@@ -1575,6 +1596,8 @@
   }
   /* else we got discover response but with no streams; we're done */
   else {
+    APPL_TRACE_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__,
+                     p_scb->peer_addr.ToString().c_str());
     bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data);
   }
 }
@@ -1619,6 +1642,8 @@
   }
   /* else we got discover response but with no streams; we're done */
   else {
+    APPL_TRACE_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__,
+                     p_scb->peer_addr.ToString().c_str());
     bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data);
   }
 }
@@ -1715,9 +1740,9 @@
   bool is_av_opened = false;
   tBTA_AV_SCB* p_opened_scb = NULL;
   uint8_t idx;
-  tBTA_AV_OPEN open;
 
-  APPL_TRACE_DEBUG("%s", __func__);
+  APPL_TRACE_ERROR("%s: peer_addr=%s", __func__,
+                   p_scb->peer_addr.ToString().c_str());
   p_scb->open_status = BTA_AV_FAIL_STREAM;
   bta_av_cco_close(p_scb, p_data);
 
@@ -1726,7 +1751,7 @@
   for (idx = 0; (idx < BTA_AV_NUM_STRS) && (is_av_opened == false); idx++) {
     p_opened_scb = bta_av_cb.p_scb[idx];
     if (p_opened_scb && (p_opened_scb->state == BTA_AV_OPEN_SST) &&
-        (!bdcmp(p_opened_scb->peer_addr, p_scb->peer_addr)))
+        (p_opened_scb->peer_addr == p_scb->peer_addr))
       is_av_opened = true;
   }
 
@@ -1734,7 +1759,8 @@
      don't send disconnect req, just report the open event with
      BTA_AV_FAIL_GET_CAP status */
   if (is_av_opened == true) {
-    bdcpy(open.bd_addr, p_scb->peer_addr);
+    tBTA_AV_OPEN open;
+    open.bd_addr = p_scb->peer_addr;
     open.chnl = p_scb->chnl;
     open.hndl = p_scb->hndl;
     open.status = BTA_AV_FAIL_GET_CAP;
@@ -1743,13 +1769,21 @@
     /* set the state back to initial state */
     bta_av_set_scb_sst_init(p_scb);
 
-    if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC)
+    if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC) {
       open.sep = AVDT_TSEP_SNK;
-    else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK)
+    } else if (p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SNK) {
       open.sep = AVDT_TSEP_SRC;
+    }
 
-    (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, (tBTA_AV*)&open);
+    APPL_TRACE_ERROR(
+        "%s: there is already an active connection: peer_addr=%s chnl=%d "
+        "hndl=%d status=%d starting=%d edr=%d",
+        __func__, open.bd_addr.ToString().c_str(), open.chnl, open.hndl,
+        open.status, open.starting, open.edr);
 
+    tBTA_AV bta_av_data;
+    bta_av_data.open = open;
+    (*bta_av_cb.p_cback)(BTA_AV_OPEN_EVT, &bta_av_data);
   } else {
     AVDT_DisconnectReq(p_scb->peer_addr, bta_av_dt_cback[p_scb->hdi]);
   }
@@ -1813,8 +1847,7 @@
         (p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback != NULL)) {
       APPL_TRACE_DEBUG("%s: configure decoder for Sink connection", __func__);
       tBTA_AV_MEDIA av_sink_codec_info;
-      memcpy(av_sink_codec_info.avk_config.bd_addr, p_scb->peer_addr,
-             sizeof(BD_ADDR));
+      av_sink_codec_info.avk_config.bd_addr = p_scb->peer_addr;
       av_sink_codec_info.avk_config.codec_info = p_scb->cfg.codec_info;
       p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback(
           BTA_AV_SINK_MEDIA_CFG_EVT, &av_sink_codec_info);
@@ -1856,9 +1889,12 @@
   APPL_TRACE_DEBUG("%s: sep_idx: %d", __func__, p_scb->sep_idx);
   AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_UNSUP_CFG, 0);
 
-  bdcpy(reject.bd_addr, p_data->str_msg.bd_addr);
+  reject.bd_addr = p_data->str_msg.bd_addr;
   reject.hndl = p_scb->hndl;
-  (*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, (tBTA_AV*)&reject);
+
+  tBTA_AV bta_av_data;
+  bta_av_data.reject = reject;
+  (*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, &bta_av_data);
 }
 
 /*******************************************************************************
@@ -1887,6 +1923,9 @@
  *
  ******************************************************************************/
 void bta_av_conn_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
+  APPL_TRACE_ERROR("%s: peer_addr=%s open_status=%d", __func__,
+                   p_scb->peer_addr.ToString().c_str(), p_scb->open_status);
+
   p_scb->open_status = BTA_AV_FAIL_STREAM;
   bta_av_str_closed(p_scb, p_data);
 }
@@ -1972,7 +2011,9 @@
         (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
     if (p_scb->offload_start_pending) {
       tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
-      (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
+      tBTA_AV bta_av_data;
+      bta_av_data.status = status;
+      (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &bta_av_data);
     }
     p_scb->offload_start_pending = false;
     */
@@ -2014,7 +2055,9 @@
     if ((sus_evt) && (p_scb->state != BTA_AV_RCFG_SST)) {
       suspend_rsp.status = BTA_AV_SUCCESS;
       suspend_rsp.initiator = true;
-      (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, (tBTA_AV*)&suspend_rsp);
+      tBTA_AV bta_av_data;
+      bta_av_data.suspend = suspend_rsp;
+      (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, &bta_av_data);
     }
   } else {
     suspend_rsp.status = BTA_AV_SUCCESS;
@@ -2026,7 +2069,9 @@
     // the Close->Configure->Open->Start path.
     if (p_scb->state != BTA_AV_RCFG_SST ||
         (p_data && p_data->api_stop.reconfig_stop)) {
-      (*bta_av_cb.p_cback)(BTA_AV_STOP_EVT, (tBTA_AV*)&suspend_rsp);
+      tBTA_AV bta_av_data;
+      bta_av_data.suspend = suspend_rsp;
+      (*bta_av_cb.p_cback)(BTA_AV_STOP_EVT, &bta_av_data);
     }
   }
 }
@@ -2252,7 +2297,6 @@
  *
  ******************************************************************************/
 void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
-  tBTA_AV_START start;
   bool initiator = false;
   bool suspend = false;
   uint16_t flush_to;
@@ -2292,11 +2336,14 @@
     p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
     if (p_data->hdr.offset == BTA_AV_RS_FAIL) {
       bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
+      tBTA_AV_START start;
       start.chnl = p_scb->chnl;
       start.status = BTA_AV_FAIL_ROLE;
       start.hndl = p_scb->hndl;
       start.initiator = initiator;
-      (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
+      tBTA_AV bta_av_data;
+      bta_av_data.start = start;
+      (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
       return;
     }
   }
@@ -2328,7 +2375,7 @@
      * first bit of p_scb->wait is cleared hence it ensures bt_av_start_ok is
      * not called
      * again from bta_av_save_caps.
-    */
+     */
     p_scb->wait &= ~BTA_AV_WAIT_ACP_CAPS_ON;
   }
 
@@ -2370,9 +2417,9 @@
     /* If sink starts stream, disable sniff mode here */
     if (!initiator) {
       /* If souce is the master role, disable role switch during streaming.
-      * Otherwise allow role switch, if source is slave.
-      * Because it would not hurt source, if the peer device wants source to be
-      * master */
+       * Otherwise allow role switch, if source is slave.
+       * Because it would not hurt source, if the peer device wants source to be
+       * master */
       if ((BTM_GetRole(p_scb->peer_addr, &cur_role) == BTM_SUCCESS) &&
           (cur_role == BTM_ROLE_MASTER)) {
         policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
@@ -2392,12 +2439,15 @@
     APPL_TRACE_DEBUG("%s: suspending: %d, role:x%x, init %d", __func__, suspend,
                      p_scb->role, initiator);
 
+    tBTA_AV_START start;
     start.suspending = suspend;
     start.initiator = initiator;
     start.chnl = p_scb->chnl;
     start.status = BTA_AV_SUCCESS;
     start.hndl = p_scb->hndl;
-    (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
+    tBTA_AV bta_av_data;
+    bta_av_data.start = start;
+    (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
 
     if (suspend) {
       tBTA_AV_API_STOP stop;
@@ -2449,6 +2499,11 @@
   tBTA_AV_EVT event;
   uint8_t policy = HCI_ENABLE_SNIFF_MODE;
 
+  APPL_TRACE_WARNING(
+      "%s: peer_addr=%s open_status=%d chnl=%d hndl=%d co_started=%d", __func__,
+      p_scb->peer_addr.ToString().c_str(), p_scb->open_status, p_scb->chnl,
+      p_scb->hndl, p_scb->co_started);
+
   if ((bta_av_cb.features & BTA_AV_FEAT_MASTER) == 0 ||
       bta_av_cb.audio_open_cnt == 1)
     policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
@@ -2458,9 +2513,9 @@
     L2CA_SetDesireRole(L2CAP_ROLE_ALLOW_SWITCH);
   }
 
-  if (p_scb->open_status) {
+  if (p_scb->open_status != BTA_AV_SUCCESS) {
     /* must be failure when opening the stream */
-    bdcpy(data.open.bd_addr, p_scb->peer_addr);
+    data.open.bd_addr = p_scb->peer_addr;
     data.open.status = p_scb->open_status;
     data.open.chnl = p_scb->chnl;
     data.open.hndl = p_scb->hndl;
@@ -2527,9 +2582,9 @@
 
   if (p_scb->started == false) {
     /* handle the condition where there is a collision of SUSPEND req from
-    *either side
-    ** Second SUSPEND req could be rejected. Do not treat this as a failure
-    */
+     *either side
+     ** Second SUSPEND req could be rejected. Do not treat this as a failure
+     */
     APPL_TRACE_WARNING("%s: already suspended, ignore, err_code %d", __func__,
                        err_code);
     return;
@@ -2570,7 +2625,9 @@
         (vendor_opcode_t)BT_VND_OP_A2DP_OFFLOAD_STOP, (void*)&p_scb->l2c_cid);
     if (p_scb->offload_start_pending) {
       tBTA_AV_STATUS status = BTA_AV_FAIL_STREAM;
-      (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
+      tBTA_AV bta_av_data;
+      bta_av_data.status = status;
+      (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &bta_av_data);
     }
     p_scb->offload_start_pending = false;
     */
@@ -2588,7 +2645,9 @@
     suspend_rsp.chnl = p_scb->chnl;
     suspend_rsp.hndl = p_scb->hndl;
     suspend_rsp.initiator = p_data->str_msg.initiator;
-    (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, (tBTA_AV*)&suspend_rsp);
+    tBTA_AV bta_av_data;
+    bta_av_data.suspend = suspend_rsp;
+    (*bta_av_cb.p_cback)(BTA_AV_SUSPEND_EVT, &bta_av_data);
   }
 }
 
@@ -2602,8 +2661,6 @@
  *
  ******************************************************************************/
 void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
-  tBTA_AV_RECONFIG evt;
-
   p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle);
   APPL_TRACE_DEBUG("%s: l2c_cid: %d", __func__, p_scb->l2c_cid);
 
@@ -2629,10 +2686,13 @@
 
   {
     /* reconfigure success  */
-    evt.status = BTA_AV_SUCCESS;
-    evt.chnl = p_scb->chnl;
-    evt.hndl = p_scb->hndl;
-    (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV*)&evt);
+    tBTA_AV_RECONFIG reconfig;
+    reconfig.status = BTA_AV_SUCCESS;
+    reconfig.chnl = p_scb->chnl;
+    reconfig.hndl = p_scb->hndl;
+    tBTA_AV bta_av_data;
+    bta_av_data.reconfig = reconfig;
+    (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data);
   }
 }
 
@@ -2646,17 +2706,20 @@
  *
  ******************************************************************************/
 void bta_av_rcfg_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
-  tBTA_AV_RECONFIG evt;
+  APPL_TRACE_ERROR("%s: num_recfg=%d conn_lcb=0x%x peer_addr=%s", __func__,
+                   p_scb->num_recfg, bta_av_cb.conn_lcb,
+                   p_scb->peer_addr.ToString().c_str());
 
-  APPL_TRACE_DEBUG("%s: num_recfg: %d, conn_lcb:0x%x", __func__,
-                   p_scb->num_recfg, bta_av_cb.conn_lcb);
   if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) {
     bta_av_cco_close(p_scb, p_data);
     /* report failure */
-    evt.status = BTA_AV_FAIL_STREAM;
-    evt.chnl = p_scb->chnl;
-    evt.hndl = p_scb->hndl;
-    (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV*)&evt);
+    tBTA_AV_RECONFIG reconfig;
+    reconfig.status = BTA_AV_FAIL_STREAM;
+    reconfig.chnl = p_scb->chnl;
+    reconfig.hndl = p_scb->hndl;
+    tBTA_AV bta_av_data;
+    bta_av_data.reconfig = reconfig;
+    (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data);
     /* go to closing state */
     bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL);
   } else {
@@ -2701,16 +2764,20 @@
  *
  ******************************************************************************/
 void bta_av_rcfg_discntd(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) {
-  tBTA_AV_RECONFIG evt;
+  APPL_TRACE_ERROR("%s: num_recfg=%d conn_lcb=0x%x peer_addr=%s", __func__,
+                   p_scb->num_recfg, bta_av_cb.conn_lcb,
+                   p_scb->peer_addr.ToString().c_str());
 
-  APPL_TRACE_DEBUG("%s: num_recfg: %d", __func__, p_scb->num_recfg);
   p_scb->num_recfg++;
   if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) {
     /* report failure */
-    evt.status = BTA_AV_FAIL_STREAM;
-    evt.chnl = p_scb->chnl;
-    evt.hndl = p_scb->hndl;
-    (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV*)&evt);
+    tBTA_AV_RECONFIG reconfig;
+    reconfig.status = BTA_AV_FAIL_STREAM;
+    reconfig.chnl = p_scb->chnl;
+    reconfig.hndl = p_scb->hndl;
+    tBTA_AV bta_av_data;
+    bta_av_data.reconfig = reconfig;
+    (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data);
     /* report close event & go to init state */
     bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL);
   } else
@@ -2730,15 +2797,19 @@
  ******************************************************************************/
 void bta_av_suspend_cont(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
   uint8_t err_code = p_data->str_msg.msg.hdr.err_code;
-  tBTA_AV_RECONFIG evt;
 
   p_scb->started = false;
   p_scb->cong = false;
   if (err_code) {
     if (AVDT_ERR_CONNECT == err_code) {
       /* report failure */
-      evt.status = BTA_AV_FAIL;
-      (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, (tBTA_AV*)&evt);
+      tBTA_AV_RECONFIG reconfig;
+      reconfig.status = BTA_AV_FAIL;
+      tBTA_AV bta_av_data;
+      bta_av_data.reconfig = reconfig;
+      (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data);
+      APPL_TRACE_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__,
+                       p_scb->peer_addr.ToString().c_str());
       bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL);
     } else {
       APPL_TRACE_ERROR("%s: suspend rejected, try close", __func__);
@@ -2781,18 +2852,13 @@
   bool disable_avdtp_reconfigure = false;
   {
     char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
-    bt_bdaddr_t bd_addr;
-    for (int i = 0; i < 6; i++) bd_addr.address[i] = p_scb->peer_addr[i];
-    if (btif_storage_get_stored_remote_name(bd_addr, remote_name)) {
+    if (btif_storage_get_stored_remote_name(p_scb->peer_addr, remote_name)) {
       if (interop_match_name(INTEROP_DISABLE_AVDTP_RECONFIGURE, remote_name) ||
           interop_match_addr(INTEROP_DISABLE_AVDTP_RECONFIGURE,
-                             (const bt_bdaddr_t*)&p_scb->peer_addr)) {
-        APPL_TRACE_DEBUG(
-            "%s: disable AVDTP RECONFIGURE: interop matched "
-            "name %s address %02x:%02x:%02x:%02x:%02x:%02x",
-            __func__, remote_name, p_scb->peer_addr[0], p_scb->peer_addr[1],
-            p_scb->peer_addr[2], p_scb->peer_addr[3], p_scb->peer_addr[4],
-            p_scb->peer_addr[5]);
+                             (const RawAddress*)&p_scb->peer_addr)) {
+        VLOG(1) << __func__ << ": disable AVDTP RECONFIGURE: interop matched "
+                               "name "
+                << remote_name << " address " << p_scb->peer_addr;
         disable_avdtp_reconfigure = true;
       }
     }
@@ -2925,8 +2991,6 @@
  *
  ******************************************************************************/
 void bta_av_open_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
-  tBTA_AV_START start;
-
   APPL_TRACE_DEBUG("%s: use_rc: %d, wait: x%x role:x%x", __func__,
                    p_scb->use_rc, p_scb->wait, p_scb->role);
   if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) &&
@@ -2937,13 +3001,17 @@
           "%s: failed to start streaming for role management reasons!!",
           __func__);
       alarm_cancel(p_scb->avrc_ct_timer);
+
+      tBTA_AV_START start;
       start.chnl = p_scb->chnl;
       start.status = BTA_AV_FAIL_ROLE;
       start.initiator = true;
       start.hndl = p_scb->hndl;
       p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS;
       bta_av_cb.rs_idx = 0;
-      (*bta_av_cb.p_cback)(BTA_AV_START_EVT, (tBTA_AV*)&start);
+      tBTA_AV bta_av_data;
+      bta_av_data.start = start;
+      (*bta_av_cb.p_cback)(BTA_AV_START_EVT, &bta_av_data);
     } else {
       /* role switch is done. continue to start streaming */
       bta_av_cb.rs_idx = 0;
@@ -3070,8 +3138,11 @@
      }
    }
    */
-  if (status != BTA_AV_SUCCESS)
-    (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
+  if (status != BTA_AV_SUCCESS) {
+    tBTA_AV bta_av_data;
+    bta_av_data.status = status;
+    (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &bta_av_data);
+  }
 }
 
 /*******************************************************************************
@@ -3097,5 +3168,7 @@
   }
 
   p_scb->offload_start_pending = false;
-  (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, (tBTA_AV*)&status);
+  tBTA_AV bta_av_data;
+  bta_av_data.status = status;
+  (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &bta_av_data);
 }
diff --git a/bta/av/bta_av_act.cc b/bta/av/bta_av_act.cc
index 2b4efb2..541d683 100644
--- a/bta/av/bta_av_act.cc
+++ b/bta/av/bta_av_act.cc
@@ -27,6 +27,7 @@
 
 #include "bt_target.h"
 
+#include <base/logging.h>
 #include <string.h>
 
 #include "avdt_api.h"
@@ -58,8 +59,6 @@
 #define BTA_AV_ACCEPT_SIGNALLING_TIMEOUT_MS (2 * 1000) /* 2 seconds */
 #endif
 
-extern fixed_queue_t* btu_bta_alarm_queue;
-
 static void bta_av_accept_signalling_timer_cback(void* data);
 
 #ifndef AVRC_MIN_META_CMD_LEN
@@ -206,7 +205,7 @@
  ******************************************************************************/
 static void bta_av_rc_ctrl_cback(uint8_t handle, uint8_t event,
                                  UNUSED_ATTR uint16_t result,
-                                 BD_ADDR peer_addr) {
+                                 const RawAddress* peer_addr) {
   uint16_t msg_event = 0;
 
   APPL_TRACE_EVENT("%s handle: %d event=0x%x", __func__, handle, event);
@@ -228,7 +227,7 @@
         (tBTA_AV_RC_CONN_CHG*)osi_malloc(sizeof(tBTA_AV_RC_CONN_CHG));
     p_msg->hdr.event = msg_event;
     p_msg->handle = handle;
-    if (peer_addr) bdcpy(p_msg->peer_addr, peer_addr);
+    if (peer_addr) p_msg->peer_addr = *peer_addr;
     bta_sys_sendmsg(p_msg);
   }
 }
@@ -306,7 +305,7 @@
 uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl,
                          uint8_t lidx) {
   tAVRC_CONN_CB ccb;
-  BD_ADDR_PTR bda = (BD_ADDR_PTR)bd_addr_any;
+  RawAddress bda = RawAddress::kAny;
   uint8_t status = BTA_AV_RC_ROLE_ACP;
   tBTA_AV_SCB* p_scb = p_cb->p_scb[shdl - 1];
   int i;
@@ -437,7 +436,7 @@
  * Returns          NULL, if not found.
  *
  ******************************************************************************/
-tBTA_AV_LCB* bta_av_find_lcb(BD_ADDR addr, uint8_t op) {
+tBTA_AV_LCB* bta_av_find_lcb(const RawAddress& addr, uint8_t op) {
   tBTA_AV_CB* p_cb = &bta_av_cb;
   int xx;
   uint8_t mask;
@@ -445,7 +444,7 @@
 
   for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) {
     mask = 1 << xx; /* the used mask for this lcb */
-    if ((mask & p_cb->conn_lcb) && 0 == (bdcmp(p_cb->lcb[xx].addr, addr))) {
+    if ((mask & p_cb->conn_lcb) && p_cb->lcb[xx].addr == addr) {
       p_lcb = &p_cb->lcb[xx];
       if (op == BTA_AV_LCB_FREE) {
         p_cb->conn_lcb &= ~mask; /* clear the connect mask */
@@ -479,7 +478,7 @@
   /* find the SCB & stop the timer */
   for (i = 0; i < BTA_AV_NUM_STRS; i++) {
     p_scb = p_cb->p_scb[i];
-    if (p_scb && bdcmp(p_scb->peer_addr, p_data->rc_conn_chg.peer_addr) == 0) {
+    if (p_scb && p_scb->peer_addr == p_data->rc_conn_chg.peer_addr) {
       p_scb->rc_handle = p_data->rc_conn_chg.handle;
       APPL_TRACE_DEBUG("bta_av_rc_opened shdl:%d, srch %d", i + 1,
                        p_scb->rc_handle);
@@ -532,10 +531,8 @@
     /* no associated SCB -> connected to an RC only device
      * update the index to the extra LCB */
     p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS];
-    bdcpy(p_lcb->addr, p_data->rc_conn_chg.peer_addr);
-    APPL_TRACE_DEBUG("rc_only bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
-                     p_lcb->addr[0], p_lcb->addr[1], p_lcb->addr[2],
-                     p_lcb->addr[3], p_lcb->addr[4], p_lcb->addr[5]);
+    p_lcb->addr = p_data->rc_conn_chg.peer_addr;
+    VLOG(1) << "rc_only bd_addr:" << p_lcb->addr;
     p_lcb->lidx = BTA_AV_NUM_LINKS + 1;
     p_cb->rcb[i].lidx = p_lcb->lidx;
     p_lcb->conn_msk = 1;
@@ -544,7 +541,7 @@
     disc = p_data->rc_conn_chg.handle | BTA_AV_CHNL_MSK;
   }
 
-  bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr);
+  rc_open.peer_addr = p_data->rc_conn_chg.peer_addr;
   rc_open.peer_features = p_cb->rcb[i].peer_features;
   rc_open.status = BTA_AV_SUCCESS;
   APPL_TRACE_DEBUG("%s local features:x%x peer_features:x%x", __func__,
@@ -559,7 +556,9 @@
 
     bta_av_rc_disc(disc);
   }
-  (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV*)&rc_open);
+  tBTA_AV bta_av_data;
+  bta_av_data.rc_open = rc_open;
+  (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data);
 
   /* if local initiated AVRCP connection and both peer and locals device support
    * browsing channel, open the browsing channel now
@@ -1120,7 +1119,7 @@
           p_scbi = bta_av_cb.p_scb[i];
           /* scb is used and started */
           if (p_scbi && (bta_av_cb.audio_streams & BTA_AV_HNDL_TO_MSK(i)) &&
-              bdcmp(p_scbi->peer_addr, p_scb->peer_addr) == 0) {
+              p_scbi->peer_addr == p_scb->peer_addr) {
             no_streams = false;
             break;
           }
@@ -1209,17 +1208,11 @@
             "p_lcb_rc->conn_msk:x%x",
             p_lcb_rc->conn_msk);
         /* check if the RC is connected to the scb addr */
-        APPL_TRACE_DEBUG("p_lcb_rc->addr: %02x:%02x:%02x:%02x:%02x:%02x",
-                         p_lcb_rc->addr[0], p_lcb_rc->addr[1],
-                         p_lcb_rc->addr[2], p_lcb_rc->addr[3],
-                         p_lcb_rc->addr[4], p_lcb_rc->addr[5]);
-        APPL_TRACE_DEBUG(
-            "conn_chg.peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
-            p_data->conn_chg.peer_addr[0], p_data->conn_chg.peer_addr[1],
-            p_data->conn_chg.peer_addr[2], p_data->conn_chg.peer_addr[3],
-            p_data->conn_chg.peer_addr[4], p_data->conn_chg.peer_addr[5]);
+        VLOG(1) << "p_lcb_rc->addr: " << p_lcb_rc->addr
+                << " conn_chg.peer_addr:" << p_data->conn_chg.peer_addr;
+
         if (p_lcb_rc->conn_msk &&
-            bdcmp(p_lcb_rc->addr, p_data->conn_chg.peer_addr) == 0) {
+            p_lcb_rc->addr == p_data->conn_chg.peer_addr) {
           /* AVRCP is already connected.
            * need to update the association betwen SCB and RCB */
           p_lcb_rc->conn_msk = 0; /* indicate RC ONLY is not connected */
@@ -1260,7 +1253,7 @@
       /* the stream is closed.
        * clear the peer address, so it would not mess up the AVRCP for the next
        * round of operation */
-      bdcpy(p_scb->peer_addr, bd_addr_null);
+      p_scb->peer_addr = RawAddress::kEmpty;
       if (p_scb->chnl == BTA_AV_CHNL_AUDIO) {
         if (p_lcb) {
           p_lcb->conn_msk &= ~conn_msk;
@@ -1410,7 +1403,7 @@
         if ((!(mask & p_cb->conn_lcb)) && (p_cb->p_scb[xx] != NULL)) {
           p_lcb = &p_cb->lcb[xx];
           p_lcb->lidx = xx + 1;
-          bdcpy(p_lcb->addr, p_data->str_msg.bd_addr);
+          p_lcb->addr = p_data->str_msg.bd_addr;
           p_lcb->conn_msk = 0; /* clear the connect mask */
           /* start listening when the signal channel is open */
           if (p_cb->features & BTA_AV_FEAT_RCTG) {
@@ -1422,7 +1415,7 @@
           if (p_data->hdr.offset == AVDT_ACP) {
             APPL_TRACE_DEBUG("Incoming L2CAP acquired, set state as incoming",
                              NULL);
-            bdcpy(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr);
+            p_cb->p_scb[xx]->peer_addr = p_data->str_msg.bd_addr;
             p_cb->p_scb[xx]->use_rc =
                 true; /* allowing RC for incoming connection */
             bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_ACP_CONNECT_EVT, p_data);
@@ -1442,10 +1435,10 @@
             /* Possible collision : need to avoid outgoing processing while the
              * timer is running */
             p_cb->p_scb[xx]->coll_mask = BTA_AV_COLL_INC_TMR;
-            alarm_set_on_queue(p_cb->accept_signalling_timer,
+            alarm_set_on_mloop(p_cb->accept_signalling_timer,
                                BTA_AV_ACCEPT_SIGNALLING_TIMEOUT_MS,
                                bta_av_accept_signalling_timer_cback,
-                               UINT_TO_PTR(xx), btu_bta_alarm_queue);
+                               UINT_TO_PTR(xx));
           }
           break;
         }
@@ -1476,17 +1469,19 @@
       APPL_TRACE_DEBUG("conn_msk: 0x%x", p_lcb->conn_msk);
       /* clean up ssm  */
       for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
-        if ((p_cb->p_scb[xx]) &&
-            (bdcmp(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr) == 0)) {
+        if (p_cb->p_scb[xx] &&
+            p_cb->p_scb[xx]->peer_addr == p_data->str_msg.bd_addr) {
           APPL_TRACE_DEBUG("%s: Closing timer for AVDTP service", __func__);
           bta_sys_conn_close(BTA_ID_AV, p_cb->p_scb[xx]->app_id,
                              p_cb->p_scb[xx]->peer_addr);
         }
         mask = 1 << (xx + 1);
         if (((mask & p_lcb->conn_msk) || bta_av_cb.conn_lcb) &&
-            (p_cb->p_scb[xx]) &&
-            (bdcmp(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr) == 0)) {
-          APPL_TRACE_DEBUG("%s: Sending AVDT_DISCONNECT_EVT", __func__);
+            p_cb->p_scb[xx] &&
+            p_cb->p_scb[xx]->peer_addr == p_data->str_msg.bd_addr) {
+          APPL_TRACE_WARNING("%s: Sending AVDT_DISCONNECT_EVT peer_addr=%s",
+                             __func__,
+                             p_cb->p_scb[xx]->peer_addr.ToString().c_str());
           bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_AVDT_DISCONNECT_EVT, NULL);
         }
       }
@@ -1512,7 +1507,6 @@
   int xx;
   uint8_t mask;
   tBTA_AV_LCB* p_lcb = NULL;
-  tBTA_AV_PEND pend;
 
   APPL_TRACE_DEBUG("%s", __func__);
   for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) {
@@ -1524,8 +1518,11 @@
         bta_sys_start_timer(p_cb->link_signalling_timer,
                             BTA_AV_SIGNALLING_TIMEOUT_MS,
                             BTA_AV_SIGNALLING_TIMER_EVT, 0);
-        bdcpy(pend.bd_addr, p_lcb->addr);
-        (*p_cb->p_cback)(BTA_AV_PENDING_EVT, (tBTA_AV*)&pend);
+        tBTA_AV_PEND pend;
+        pend.bd_addr = p_lcb->addr;
+        tBTA_AV bta_av_data;
+        bta_av_data.pend = pend;
+        (*p_cb->p_cback)(BTA_AV_PENDING_EVT, &bta_av_data);
       }
     }
   }
@@ -1561,10 +1558,10 @@
           /* We are still doing SDP. Run the timer again. */
           p_scb->coll_mask |= BTA_AV_COLL_INC_TMR;
 
-          alarm_set_on_queue(p_cb->accept_signalling_timer,
+          alarm_set_on_mloop(p_cb->accept_signalling_timer,
                              BTA_AV_ACCEPT_SIGNALLING_TIMEOUT_MS,
                              bta_av_accept_signalling_timer_cback,
-                             UINT_TO_PTR(inx), btu_bta_alarm_queue);
+                             UINT_TO_PTR(inx));
         } else {
           /* SNK did not start signalling, resume signalling process. */
           bta_av_discover_req(p_scb, NULL);
@@ -1743,8 +1740,6 @@
   tBTA_AV_CB* p_cb = &bta_av_cb;
   tBTA_AV_SCB* p_scb = NULL;
   tBTA_AV_LCB* p_lcb;
-  tBTA_AV_RC_OPEN rc_open;
-  tBTA_AV_RC_FEAT rc_feat;
   uint8_t rc_handle;
   tBTA_AV_FEAT peer_features = 0; /* peer features mask */
 
@@ -1838,13 +1833,17 @@
       } else if (p_scb->use_rc) {
         /* can not find AVRC on peer device. report failure */
         p_scb->use_rc = false;
-        bdcpy(rc_open.peer_addr, p_scb->peer_addr);
+        tBTA_AV_RC_OPEN rc_open;
+        rc_open.peer_addr = p_scb->peer_addr;
         rc_open.peer_features = 0;
         rc_open.status = BTA_AV_FAIL_SDP;
-        (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV*)&rc_open);
+        tBTA_AV bta_av_data;
+        bta_av_data.rc_open = rc_open;
+        (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data);
       }
     }
   } else {
+    tBTA_AV_RC_FEAT rc_feat;
     p_cb->rcb[rc_handle].peer_features = peer_features;
     rc_feat.rc_handle = rc_handle;
     rc_feat.peer_features = peer_features;
@@ -1854,10 +1853,13 @@
        * we still need to send RC feature event. So we need to get BD
        * from Message
        */
-      bdcpy(rc_feat.peer_addr, p_cb->lcb[p_cb->rcb[rc_handle].lidx].addr);
-    } else
-      bdcpy(rc_feat.peer_addr, p_scb->peer_addr);
-    (*p_cb->p_cback)(BTA_AV_RC_FEAT_EVT, (tBTA_AV*)&rc_feat);
+      rc_feat.peer_addr = p_cb->lcb[p_cb->rcb[rc_handle].lidx].addr;
+    } else {
+      rc_feat.peer_addr = p_scb->peer_addr;
+    }
+    tBTA_AV bta_av_data;
+    bta_av_data.rc_feat = rc_feat;
+    (*p_cb->p_cback)(BTA_AV_RC_FEAT_EVT, &bta_av_data);
   }
 }
 
@@ -1897,7 +1899,7 @@
           p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
         }
         if (p_scb) {
-          bdcpy(rc_close.peer_addr, p_scb->peer_addr);
+          rc_close.peer_addr = p_scb->peer_addr;
           if (p_scb->rc_handle == p_rcb->handle)
             p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE;
           APPL_TRACE_DEBUG("shdl:%d, srch:%d", p_rcb->shdl, p_scb->rc_handle);
@@ -1906,11 +1908,8 @@
       } else if (p_rcb->lidx == (BTA_AV_NUM_LINKS + 1)) {
         /* if the RCB uses the extra LCB, use the addr for event and clean it */
         p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS];
-        bdcpy(rc_close.peer_addr, p_msg->peer_addr);
-        APPL_TRACE_DEBUG("rc_only closed bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
-                         p_msg->peer_addr[0], p_msg->peer_addr[1],
-                         p_msg->peer_addr[2], p_msg->peer_addr[3],
-                         p_msg->peer_addr[4], p_msg->peer_addr[5]);
+        rc_close.peer_addr = p_msg->peer_addr;
+        VLOG(1) << "rc_only closed bd_addr:" << p_msg->peer_addr;
         p_lcb->conn_msk = 0;
         p_lcb->lidx = 0;
       }
@@ -1943,9 +1942,11 @@
 
   if (rc_close.rc_handle == BTA_AV_RC_HANDLE_NONE) {
     rc_close.rc_handle = p_msg->handle;
-    bdcpy(rc_close.peer_addr, p_msg->peer_addr);
+    rc_close.peer_addr = p_msg->peer_addr;
   }
-  (*p_cb->p_cback)(BTA_AV_RC_CLOSE_EVT, (tBTA_AV*)&rc_close);
+  tBTA_AV bta_av_data;
+  bta_av_data.rc_close = rc_close;
+  (*p_cb->p_cback)(BTA_AV_RC_CLOSE_EVT, &bta_av_data);
 }
 
 /*******************************************************************************
@@ -1962,17 +1963,16 @@
   tBTA_AV_RC_CONN_CHG* p_msg = (tBTA_AV_RC_CONN_CHG*)p_data;
   tBTA_AV_RC_BROWSE_OPEN rc_browse_open;
 
-  APPL_TRACE_DEBUG(
-      "bta_av_rc_browse_opened bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
-      p_msg->peer_addr[0], p_msg->peer_addr[1], p_msg->peer_addr[2],
-      p_msg->peer_addr[3], p_msg->peer_addr[4], p_msg->peer_addr[5]);
+  VLOG(1) << "bta_av_rc_browse_opened bd_addr:" << p_msg->peer_addr;
   APPL_TRACE_DEBUG("bta_av_rc_browse_opened rc_handle:%d", p_msg->handle);
 
   rc_browse_open.status = BTA_AV_SUCCESS;
   rc_browse_open.rc_handle = p_msg->handle;
-  bdcpy(rc_browse_open.peer_addr, p_msg->peer_addr);
+  rc_browse_open.peer_addr = p_msg->peer_addr;
 
-  (*p_cb->p_cback)(BTA_AV_RC_BROWSE_OPEN_EVT, (tBTA_AV*)&rc_browse_open);
+  tBTA_AV bta_av_data;
+  bta_av_data.rc_browse_open = rc_browse_open;
+  (*p_cb->p_cback)(BTA_AV_RC_BROWSE_OPEN_EVT, &bta_av_data);
 }
 
 /*******************************************************************************
@@ -1989,16 +1989,15 @@
   tBTA_AV_RC_CONN_CHG* p_msg = (tBTA_AV_RC_CONN_CHG*)p_data;
   tBTA_AV_RC_BROWSE_CLOSE rc_browse_close;
 
-  APPL_TRACE_DEBUG(
-      "bta_av_rc_browse_closed bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
-      p_msg->peer_addr[0], p_msg->peer_addr[1], p_msg->peer_addr[2],
-      p_msg->peer_addr[3], p_msg->peer_addr[4], p_msg->peer_addr[5]);
+  VLOG(1) << "bta_av_rc_browse_closed bd_addr:" << p_msg->peer_addr;
   APPL_TRACE_DEBUG("bta_av_rc_browse_closed rc_handle:%d", p_msg->handle);
 
   rc_browse_close.rc_handle = p_msg->handle;
-  bdcpy(rc_browse_close.peer_addr, p_msg->peer_addr);
+  rc_browse_close.peer_addr = p_msg->peer_addr;
 
-  (*p_cb->p_cback)(BTA_AV_RC_BROWSE_CLOSE_EVT, (tBTA_AV*)&rc_browse_close);
+  tBTA_AV bta_av_data;
+  bta_av_data.rc_browse_close = rc_browse_close;
+  (*p_cb->p_cback)(BTA_AV_RC_BROWSE_CLOSE_EVT, &bta_av_data);
 }
 
 /*******************************************************************************
@@ -2018,7 +2017,7 @@
                           ATTR_ID_SUPPORTED_FEATURES};
   uint8_t hdi;
   tBTA_AV_SCB* p_scb;
-  uint8_t* p_addr = NULL;
+  RawAddress* p_addr = NULL;
   uint8_t rc_handle;
 
   APPL_TRACE_DEBUG("bta_av_rc_disc 0x%x, %d", disc, bta_av_cb.disc);
@@ -2028,7 +2027,7 @@
     /* this is the rc handle/index to tBTA_AV_RCB */
     rc_handle = disc & (~BTA_AV_CHNL_MSK);
     if (p_cb->rcb[rc_handle].lidx) {
-      p_addr = p_cb->lcb[p_cb->rcb[rc_handle].lidx - 1].addr;
+      p_addr = &p_cb->lcb[p_cb->rcb[rc_handle].lidx - 1].addr;
     }
   } else {
     hdi = (disc & BTA_AV_HNDL_MSK) - 1;
@@ -2036,7 +2035,7 @@
 
     if (p_scb) {
       APPL_TRACE_DEBUG("rc_handle %d", p_scb->rc_handle);
-      p_addr = p_scb->peer_addr;
+      p_addr = &p_scb->peer_addr;
     }
   }
 
@@ -2052,7 +2051,7 @@
     db_params.p_attrs = attr_list;
 
     /* searching for UUID_SERVCLASS_AV_REMOTE_CONTROL gets both TG and CT */
-    if (AVRC_FindService(UUID_SERVCLASS_AV_REMOTE_CONTROL, p_addr, &db_params,
+    if (AVRC_FindService(UUID_SERVCLASS_AV_REMOTE_CONTROL, *p_addr, &db_params,
                          bta_av_avrc_sdp_cback) == AVRC_SUCCESS) {
       p_cb->disc = disc;
       APPL_TRACE_DEBUG("disc %d", p_cb->disc);
diff --git a/bta/av/bta_av_api.cc b/bta/av/bta_av_api.cc
index 581a920..82ed10c 100644
--- a/bta/av/bta_av_api.cc
+++ b/bta/av/bta_av_api.cc
@@ -151,14 +151,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, bool use_rc,
+void BTA_AvOpen(const RawAddress& bd_addr, tBTA_AV_HNDL handle, bool use_rc,
                 tBTA_SEC sec_mask, uint16_t uuid) {
   tBTA_AV_API_OPEN* p_buf =
       (tBTA_AV_API_OPEN*)osi_malloc(sizeof(tBTA_AV_API_OPEN));
 
   p_buf->hdr.event = BTA_AV_API_OPEN_EVT;
   p_buf->hdr.layer_specific = handle;
-  bdcpy(p_buf->bd_addr, bd_addr);
+  p_buf->bd_addr = bd_addr;
   p_buf->use_rc = use_rc;
   p_buf->sec_mask = sec_mask;
   p_buf->switch_res = BTA_AV_RS_NONE;
@@ -194,12 +194,12 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_AvDisconnect(BD_ADDR bd_addr) {
+void BTA_AvDisconnect(const RawAddress& bd_addr) {
   tBTA_AV_API_DISCNT* p_buf =
       (tBTA_AV_API_DISCNT*)osi_malloc(sizeof(tBTA_AV_API_DISCNT));
 
   p_buf->hdr.event = BTA_AV_API_DISCONNECT_EVT;
-  bdcpy(p_buf->bd_addr, bd_addr);
+  p_buf->bd_addr = bd_addr;
 
   bta_sys_sendmsg(p_buf);
 }
diff --git a/bta/av/bta_av_cfg.cc b/bta/av/bta_av_cfg.cc
index 10baa33..688af45 100644
--- a/bta/av/bta_av_cfg.cc
+++ b/bta/av/bta_av_cfg.cc
@@ -84,7 +84,7 @@
 #endif
 
 /*
- * If the number of event IDs is changed in this array, BTA_AV_ NUM_RC_EVT_IDS
+ * If the number of event IDs is changed in this array, BTA_AV_NUM_RC_EVT_IDS
  * also needs to be changed.
  */
 const uint8_t bta_av_meta_caps_evt_ids[] = {
@@ -96,6 +96,7 @@
     AVRC_EVT_APP_SETTING_CHANGE,
     */
 };
+
 #ifndef BTA_AV_NUM_RC_EVT_IDS
 #define BTA_AV_NUM_RC_EVT_IDS \
   (sizeof(bta_av_meta_caps_evt_ids) / sizeof(bta_av_meta_caps_evt_ids[0]))
@@ -106,6 +107,7 @@
     AVRC_EVT_VOLUME_CHANGE,
 #endif
 };
+
 #ifndef BTA_AVK_NUM_RC_EVT_IDS
 #define BTA_AVK_NUM_RC_EVT_IDS \
   (sizeof(bta_avk_meta_caps_evt_ids) / sizeof(bta_avk_meta_caps_evt_ids[0]))
@@ -208,18 +210,18 @@
     48,                   /* AVRCP MTU at L2CAP for control channel */
     BTA_AV_MAX_RC_BR_MTU, /* AVRCP MTU at L2CAP for browsing channel */
 #endif
-    BTA_AV_RC_SUPF_CT,     /* AVRCP controller categories */
-    AVRC_SUPF_TG_CAT1,     /* Only support CAT1 for AVRCP1.3 */
-    672,                   /* AVDTP signaling channel MTU at L2CAP */
-    BTA_AV_MAX_A2DP_MTU,   /* AVDTP audio transport channel MTU at L2CAP
-                            */
+    BTA_AV_RC_SUPF_CT, /* AVRCP controller categories */
+    AVRC_SUPF_TG_CAT1, /* Only support CAT1 for AVRCP1.3 */
+    672,               /* AVDTP signaling channel MTU at L2CAP */
+    BTA_AV_MAX_A2DP_MTU, /* AVDTP audio transport channel MTU at L2CAP
+                          */
     bta_av_audio_flush_to, /* AVDTP audio transport channel flush
                               timeout */
-    6,                     /* AVDTP audio channel max data queue size */
-    BTA_AV_MAX_VDP_MTU,    /* AVDTP video transport channel MTU at L2CAP */
-    600,                   /* AVDTP video transport channel flush timeout */
-    false, /* true, to accept AVRC 1.3 group nevigation command */
-    2,     /* company id count in p_meta_co_ids */
+    6,                  /* AVDTP audio channel max data queue size */
+    BTA_AV_MAX_VDP_MTU, /* AVDTP video transport channel MTU at L2CAP */
+    600,                /* AVDTP video transport channel flush timeout */
+    false,              /* true, to accept AVRC 1.3 group nevigation command */
+    2,                  /* company id count in p_meta_co_ids */
     BTA_AV_NUM_RC_EVT_IDS_AVRCP13,    /* event id count for AVRCP1.3*/
     BTA_AV_RC_PASS_RSP_CODE,          /* the default response code for pass
                                          through commands */
diff --git a/bta/av/bta_av_int.h b/bta/av/bta_av_int.h
index 6688f71..963a84a 100644
--- a/bta/av/bta_av_int.h
+++ b/bta/av/bta_av_int.h
@@ -161,7 +161,8 @@
                                 tAVDT_CFG* p_cfg);
 typedef void (*tBTA_AV_CO_DISC_RES)(tBTA_AV_HNDL hndl, uint8_t num_seps,
                                     uint8_t num_snk, uint8_t num_src,
-                                    BD_ADDR addr, uint16_t uuid_local);
+                                    const RawAddress& addr,
+                                    uint16_t uuid_local);
 typedef tA2DP_STATUS (*tBTA_AV_CO_GETCFG)(tBTA_AV_HNDL hndl,
                                           uint8_t* p_codec_info,
                                           uint8_t* p_sep_info_idx, uint8_t seid,
@@ -169,7 +170,7 @@
                                           uint8_t* p_protect_info);
 typedef void (*tBTA_AV_CO_SETCFG)(tBTA_AV_HNDL hndl,
                                   const uint8_t* p_codec_info, uint8_t seid,
-                                  BD_ADDR addr, uint8_t num_protect,
+                                  const RawAddress& addr, uint8_t num_protect,
                                   const uint8_t* p_protect_info,
                                   uint8_t t_local_sep, uint8_t avdt_handle);
 typedef void (*tBTA_AV_CO_OPEN)(tBTA_AV_HNDL hndl, uint16_t mtu);
@@ -224,7 +225,7 @@
 /* data type for BTA_AV_API_OPEN_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   bool use_rc;
   tBTA_SEC sec_mask;
   tBTA_AV_RS_RES switch_res;
@@ -242,7 +243,7 @@
 /* data type for BTA_AV_API_DISCONNECT_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
 } tBTA_AV_API_DISCNT;
 
 /* data type for BTA_AV_API_PROTECT_REQ_EVT */
@@ -316,7 +317,7 @@
   BT_HDR hdr;
   tAVDT_CFG cfg;   /* configuration/capabilities parameters */
   tAVDT_CTRL msg;  /* AVDTP callback message parameters */
-  BD_ADDR bd_addr; /* bd address */
+  RawAddress bd_addr; /* bd address */
   uint8_t handle;
   uint8_t avdt_event;
   bool initiator; /* true, if local device initiates the SUSPEND */
@@ -334,14 +335,14 @@
 /* data type for BTA_AV_AVRC_OPEN_EVT, BTA_AV_AVRC_CLOSE_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
   uint8_t handle;
 } tBTA_AV_RC_CONN_CHG;
 
 /* data type for BTA_AV_CONN_CHG_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
   bool is_up;
 } tBTA_AV_CONN_CHG;
 
@@ -453,7 +454,7 @@
   tAVDT_SEP_INFO sep_info[BTA_AV_NUM_SEPS]; /* stream discovery results */
   tAVDT_CFG cfg;                            /* local SEP configuration */
   alarm_t* avrc_ct_timer;                   /* delay timer for AVRC CT */
-  BD_ADDR peer_addr;                        /* peer BD address */
+  RawAddress peer_addr;                     /* peer BD address */
   uint16_t l2c_cid;                         /* L2CAP channel ID */
   uint16_t stream_mtu;                      /* MTU of stream */
   uint16_t avdt_version;      /* the avdt version of peer device */
@@ -522,7 +523,7 @@
 
 /* type for AV ACL Link control block */
 typedef struct {
-  BD_ADDR addr;     /* peer BD address */
+  RawAddress addr;  /* peer BD address */
   uint8_t conn_msk; /* handle mask of connected stream handle */
   uint8_t lidx;     /* index + 1 */
 } tBTA_AV_LCB;
@@ -596,8 +597,8 @@
 extern bool bta_av_chk_start(tBTA_AV_SCB* p_scb);
 extern void bta_av_restore_switch(void);
 extern uint16_t bta_av_chk_mtu(tBTA_AV_SCB* p_scb, uint16_t mtu);
-extern void bta_av_conn_cback(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                              tAVDT_CTRL* p_data);
+extern void bta_av_conn_cback(uint8_t handle, const RawAddress* bd_addr,
+                              uint8_t event, tAVDT_CTRL* p_data);
 extern uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl,
                                 uint8_t lidx);
 extern void bta_av_stream_chg(tBTA_AV_SCB* p_scb, bool started);
@@ -606,7 +607,7 @@
 extern void bta_av_set_scb_sst_init(tBTA_AV_SCB* p_scb);
 extern bool bta_av_is_scb_init(tBTA_AV_SCB* p_scb);
 extern void bta_av_set_scb_sst_incoming(tBTA_AV_SCB* p_scb);
-extern tBTA_AV_LCB* bta_av_find_lcb(BD_ADDR addr, uint8_t op);
+extern tBTA_AV_LCB* bta_av_find_lcb(const RawAddress& addr, uint8_t op);
 
 /* main functions */
 extern void bta_av_api_deregister(tBTA_AV_DATA* p_data);
diff --git a/bta/av/bta_av_main.cc b/bta/av/bta_av_main.cc
index 8e7eba8..0d7c360 100644
--- a/bta/av/bta_av_main.cc
+++ b/bta/av/bta_av_main.cc
@@ -80,6 +80,10 @@
 #define AVRCP_1_4_STRING "avrcp14"
 #endif
 
+#ifndef AVRCP_1_3_STRING
+#define AVRCP_1_3_STRING "avrcp13"
+#endif
+
 /* state machine states */
 enum { BTA_AV_INIT_ST, BTA_AV_OPEN_ST };
 
@@ -167,9 +171,9 @@
 static void bta_av_api_to_ssm(tBTA_AV_DATA* p_data);
 
 static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                                 uint8_t app_id, BD_ADDR peer_addr);
+                                 uint8_t app_id, const RawAddress* peer_addr);
 static void bta_av_sys_rs_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                                uint8_t app_id, BD_ADDR peer_addr);
+                                uint8_t app_id, const RawAddress* peer_addr);
 
 /* action functions */
 const tBTA_AV_NSM_ACT bta_av_nsm_act[] = {
@@ -243,7 +247,9 @@
   }
 
   /* call callback with enable event */
-  (*bta_av_cb.p_cback)(BTA_AV_ENABLE_EVT, (tBTA_AV*)&enable);
+  tBTA_AV bta_av_data;
+  bta_av_data.enable = enable;
+  (*bta_av_cb.p_cback)(BTA_AV_ENABLE_EVT, &bta_av_data);
 }
 
 /*******************************************************************************
@@ -255,13 +261,13 @@
  * Returns          void
  *
  ******************************************************************************/
-static tBTA_AV_SCB* bta_av_addr_to_scb(BD_ADDR bd_addr) {
+static tBTA_AV_SCB* bta_av_addr_to_scb(const RawAddress& bd_addr) {
   tBTA_AV_SCB* p_scb = NULL;
   int xx;
 
   for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
     if (bta_av_cb.p_scb[xx]) {
-      if (!bdcmp(bd_addr, bta_av_cb.p_scb[xx]->peer_addr)) {
+      if (bd_addr == bta_av_cb.p_scb[xx]->peer_addr) {
         p_scb = bta_av_cb.p_scb[xx];
         break;
       }
@@ -343,7 +349,7 @@
 
 /*******************************************************************************
  ******************************************************************************/
-void bta_av_conn_cback(UNUSED_ATTR uint8_t handle, BD_ADDR bd_addr,
+void bta_av_conn_cback(UNUSED_ATTR uint8_t handle, const RawAddress* bd_addr,
                        uint8_t event, tAVDT_CTRL* p_data) {
   uint16_t evt = 0;
   tBTA_AV_SCB* p_scb = NULL;
@@ -357,7 +363,7 @@
   {
     evt = BTA_AV_SIG_CHG_EVT;
     if (event == AVDT_DISCONNECT_IND_EVT) {
-      p_scb = bta_av_addr_to_scb(bd_addr);
+      p_scb = bta_av_addr_to_scb(*bd_addr);
     } else if (event == AVDT_CONNECT_IND_EVT) {
       APPL_TRACE_DEBUG("%s: CONN_IND is ACP:%d", __func__,
                        p_data->hdr.err_param);
@@ -368,13 +374,11 @@
     p_msg->hdr.event = evt;
     p_msg->hdr.layer_specific = event;
     p_msg->hdr.offset = p_data->hdr.err_param;
-    bdcpy(p_msg->bd_addr, bd_addr);
+    p_msg->bd_addr = *bd_addr;
     if (p_scb) {
       APPL_TRACE_DEBUG("scb hndl x%x, role x%x", p_scb->hndl, p_scb->role);
     }
-    APPL_TRACE_DEBUG("conn_cback bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
-                     bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-                     bd_addr[5]);
+    VLOG(1) << "conn_cback bd_addr:" << bd_addr;
     bta_sys_sendmsg(p_msg);
   }
 }
@@ -422,11 +426,20 @@
   registr.app_id = p_data->api_reg.app_id;
   registr.chnl = (tBTA_AV_CHNL)p_data->hdr.layer_specific;
 
+  char avrcp_version[PROPERTY_VALUE_MAX] = {0};
+  osi_property_get(AVRCP_VERSION_PROPERTY, avrcp_version, AVRCP_1_4_STRING);
+  LOG_INFO(LOG_TAG, "AVRCP version used for sdp: \"%s\"", avrcp_version);
+
   uint16_t profile_initialized = p_data->api_reg.service_uuid;
   if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
     p_bta_av_cfg = (tBTA_AV_CFG*)&bta_avk_cfg;
   } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
     p_bta_av_cfg = (tBTA_AV_CFG*)&bta_av_cfg;
+
+    if (!strncmp(AVRCP_1_3_STRING, avrcp_version, sizeof(AVRCP_1_3_STRING))) {
+      LOG_INFO(LOG_TAG, "AVRCP 1.3 capabilites used");
+      p_bta_av_cfg = (tBTA_AV_CFG*)&bta_av_cfg_compatibility;
+    }
   }
 
   APPL_TRACE_DEBUG("%s: profile: 0x%x", __func__, profile_initialized);
@@ -479,19 +492,15 @@
         uint16_t profile_version = AVRC_REV_1_0;
 
         if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
-          // This check can override the AVRCP profile version with a property
-          char avrcp_version[PROPERTY_VALUE_MAX] = {0};
-          osi_property_get(AVRCP_VERSION_PROPERTY, avrcp_version,
-                           AVRCP_1_4_STRING);
-          LOG_INFO(LOG_TAG, "AVRCP version used for sdp: \"%s\"",
-                   avrcp_version);
-
           if (!strncmp(AVRCP_1_6_STRING, avrcp_version,
                        sizeof(AVRCP_1_6_STRING))) {
             profile_version = AVRC_REV_1_6;
           } else if (!strncmp(AVRCP_1_5_STRING, avrcp_version,
                               sizeof(AVRCP_1_5_STRING))) {
             profile_version = AVRC_REV_1_5;
+          } else if (!strncmp(AVRCP_1_3_STRING, avrcp_version,
+                              sizeof(AVRCP_1_3_STRING))) {
+            profile_version = AVRC_REV_1_3;
           } else {
             profile_version = AVRC_REV_1_4;
           }
@@ -671,7 +680,9 @@
   } while (0);
 
   /* call callback with register event */
-  (*bta_av_cb.p_cback)(BTA_AV_REGISTER_EVT, (tBTA_AV*)&registr);
+  tBTA_AV bta_av_data;
+  bta_av_data.registr = registr;
+  (*bta_av_cb.p_cback)(BTA_AV_REGISTER_EVT, &bta_av_data);
 }
 
 /*******************************************************************************
@@ -835,7 +846,8 @@
  *
  ******************************************************************************/
 static void bta_av_sys_rs_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,
-                                uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+                                uint8_t id, uint8_t app_id,
+                                const RawAddress* peer_addr) {
   int i;
   tBTA_AV_SCB* p_scb = NULL;
   uint8_t cur_role;
@@ -847,7 +859,7 @@
      * role change event */
     /* note that more than one SCB (a2dp & vdp) maybe waiting for this event */
     p_scb = bta_av_cb.p_scb[i];
-    if (p_scb && (bdcmp(peer_addr, p_scb->peer_addr) == 0)) {
+    if (p_scb && p_scb->peer_addr == *peer_addr) {
       tBTA_AV_ROLE_RES* p_buf =
           (tBTA_AV_ROLE_RES*)osi_malloc(sizeof(tBTA_AV_ROLE_RES));
       APPL_TRACE_DEBUG("new_role:%d, hci_status:x%x hndl: x%x", id, app_id,
@@ -871,9 +883,9 @@
 
   /* restore role switch policy, if role switch failed */
   if ((HCI_SUCCESS != app_id) &&
-      (BTM_GetRole(peer_addr, &cur_role) == BTM_SUCCESS) &&
+      (BTM_GetRole(*peer_addr, &cur_role) == BTM_SUCCESS) &&
       (cur_role == BTM_ROLE_SLAVE)) {
-    bta_sys_set_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH, peer_addr);
+    bta_sys_set_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH, *peer_addr);
   }
 
   /* if BTA_AvOpen() was called for other device, which caused the role switch
@@ -913,7 +925,7 @@
  ******************************************************************************/
 static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
                                  UNUSED_ATTR uint8_t app_id,
-                                 UNUSED_ATTR BD_ADDR peer_addr) {
+                                 UNUSED_ATTR const RawAddress* peer_addr) {
   tBTA_AV_SCB* p_scb;
   int i;
   tBTA_AV_API_STOP stop;
diff --git a/bta/closure/bta_closure.cc b/bta/closure/bta_closure.cc
deleted file mode 100644
index 599ee33..0000000
--- a/bta/closure/bta_closure.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2016 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-
-#include "base/pending_task.h"
-#include "base/time/time.h"
-#include "bta_closure_int.h"
-#include "bta_sys.h"
-
-using base::PendingTask;
-using base::TaskQueue;
-using base::TimeTicks;
-
-namespace {
-
-enum {
-  /* these events are handled by the state machine */
-  BTA_CLOSURE_EXECUTE_EVT = BTA_SYS_EVT_START(BTA_ID_CLOSURE),
-};
-
-struct tBTA_CLOSURE_EXECUTE {
-  BT_HDR hdr;
-  PendingTask pending_task;
-};
-
-static const tBTA_SYS_REG bta_closure_hw_reg = {bta_closure_execute, NULL};
-tBTA_SYS_SENDMSG bta_closure_sys_sendmsg = NULL;
-
-}  // namespace
-
-/* Accept bta_sys_register, and bta_sys_sendmsg. Those parameters can be used to
- * override system methods for tests.
- */
-void bta_closure_init(tBTA_SYS_REGISTER registerer, tBTA_SYS_SENDMSG sender) {
-  /* register closure message handler */
-  registerer(BTA_ID_CLOSURE, &bta_closure_hw_reg);
-  bta_closure_sys_sendmsg = sender;
-}
-
-bool bta_closure_execute(BT_HDR* p_raw_msg) {
-  if (p_raw_msg->event != BTA_CLOSURE_EXECUTE_EVT) {
-    APPL_TRACE_ERROR("%s: don't know how to execute event type %d", __func__,
-                     p_raw_msg->event);
-    return false;
-  }
-
-  tBTA_CLOSURE_EXECUTE* p_msg = ((tBTA_CLOSURE_EXECUTE*)p_raw_msg);
-
-  APPL_TRACE_API("%s: executing closure %s", __func__,
-                 p_msg->pending_task.posted_from.ToString().c_str());
-  p_msg->pending_task.task.Run();
-
-  p_msg->pending_task.~PendingTask();
-  return true;
-}
-
-/*
- * This function posts a closure for execution on the btu_bta_msg_queue. Please
- * see documentation at
- * https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures
- * for how to handle dynamic memory ownership/smart pointers with base::Owned(),
- * base::Passed(), base::ConstRef() and others.
- */
-void do_in_bta_thread(const tracked_objects::Location& from_here,
-                      const base::Closure& task) {
-  APPL_TRACE_API("%s: posting %s", __func__, from_here.ToString().c_str());
-  tBTA_CLOSURE_EXECUTE* p_msg =
-      (tBTA_CLOSURE_EXECUTE*)osi_malloc(sizeof(tBTA_CLOSURE_EXECUTE));
-
-  new (&p_msg->pending_task) PendingTask(from_here, task, TimeTicks(), true);
-  p_msg->hdr.event = BTA_CLOSURE_EXECUTE_EVT;
-  bta_closure_sys_sendmsg(p_msg);
-}
diff --git a/bta/closure/bta_closure_int.h b/bta/closure/bta_closure_int.h
deleted file mode 100644
index b0cc726..0000000
--- a/bta/closure/bta_closure_int.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2016 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.
- *
- ******************************************************************************/
-
-#ifndef BTA_CLOSURE_INT_H
-#define BTA_CLOSURE_INT_H
-
-#include <stdbool.h>
-
-#include "bta/sys/bta_sys.h"
-#include "bta_api.h"
-#include "include/bt_trace.h"
-
-/* Accept bta_sys_register, and bta_sys_sendmsg. Those parameters can be used to
- * override system methods for tests.
- */
-void bta_closure_init(tBTA_SYS_REGISTER registerer, tBTA_SYS_SENDMSG sender);
-bool bta_closure_execute(BT_HDR* p_msg);
-
-#endif /* BTA_CLOSURE_INT_H */
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
index df082ae..eaa61ab 100644
--- a/bta/dm/bta_dm_act.cc
+++ b/bta/dm/bta_dm_act.cc
@@ -39,7 +39,6 @@
 #include "bta_dm_co.h"
 #include "bta_dm_int.h"
 #include "bta_sys.h"
-#include "btcore/include/bdaddr.h"
 #include "btm_api.h"
 #include "btm_int.h"
 #include "btu.h"
@@ -57,30 +56,31 @@
 static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir,
                                   uint16_t eir_len);
 static void bta_dm_inq_cmpl_cb(void* p_result);
-static void bta_dm_service_search_remname_cback(BD_ADDR bd_addr, DEV_CLASS dc,
-                                                BD_NAME bd_name);
+static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr,
+                                                DEV_CLASS dc, BD_NAME bd_name);
 static void bta_dm_remname_cback(tBTM_REMOTE_DEV_NAME* p_remote_name);
-static void bta_dm_find_services(BD_ADDR bd_addr);
+static void bta_dm_find_services(const RawAddress& bd_addr);
 static void bta_dm_discover_next_device(void);
 static void bta_dm_sdp_callback(uint16_t sdp_status);
-static uint8_t bta_dm_authorize_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
-                                      BD_NAME bd_name, uint8_t* service_name,
-                                      uint8_t service_id, bool is_originator);
-static uint8_t bta_dm_pin_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
+static uint8_t bta_dm_authorize_cback(const RawAddress& bd_addr,
+                                      DEV_CLASS dev_class, BD_NAME bd_name,
+                                      uint8_t* service_name, uint8_t service_id,
+                                      bool is_originator);
+static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class,
                                 BD_NAME bd_name, bool min_16_digit);
-static uint8_t bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
-                                         BD_NAME bd_name, LINK_KEY key,
-                                         uint8_t key_type);
-static uint8_t bta_dm_authentication_complete_cback(BD_ADDR bd_addr,
+static uint8_t bta_dm_new_link_key_cback(const RawAddress& bd_addr,
+                                         DEV_CLASS dev_class, BD_NAME bd_name,
+                                         LINK_KEY key, uint8_t key_type);
+static uint8_t bta_dm_authentication_complete_cback(const RawAddress& bd_addr,
                                                     DEV_CLASS dev_class,
                                                     BD_NAME bd_name,
                                                     int result);
-static void bta_dm_local_name_cback(BD_ADDR bd_addr);
+static void bta_dm_local_name_cback(const RawAddress& bd_addr);
 static bool bta_dm_check_av(uint16_t event);
 static void bta_dm_bl_change_cback(tBTM_BL_EVENT_DATA* p_data);
 
 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                                uint8_t app_id, BD_ADDR peer_addr);
+                                uint8_t app_id, const RawAddress* peer_addr);
 
 /* Extended Inquiry Response */
 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
@@ -96,25 +96,25 @@
 static void bta_dm_search_timer_cback(void* data);
 static void bta_dm_disable_conn_down_timer_cback(void* data);
 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                            uint8_t app_id, BD_ADDR peer_addr);
+                            uint8_t app_id, const RawAddress* peer_addr);
 static void bta_dm_adjust_roles(bool delay_role_switch);
 static char* bta_dm_get_remname(void);
 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
 
-static bool bta_dm_read_remote_device_name(BD_ADDR bd_addr,
+static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
                                            tBT_TRANSPORT transport);
-static void bta_dm_discover_device(BD_ADDR remote_bd_addr);
+static void bta_dm_discover_device(const RawAddress& remote_bd_addr);
 
 static void bta_dm_sys_hw_cback(tBTA_SYS_HW_EVT status);
 static void bta_dm_disable_search_and_disc(void);
 
-static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, BD_ADDR bda,
+static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda,
                                     tBTM_LE_EVT_DATA* p_data);
 static void bta_dm_ble_id_key_cback(uint8_t key_type,
                                     tBTM_BLE_LOCAL_KEYS* p_key);
 static void bta_dm_gattc_register(void);
-static void btm_dm_start_gatt_discovery(BD_ADDR bd_addr);
-static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr);
+static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr);
+static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr);
 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
 extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
 
@@ -149,8 +149,8 @@
 
 #define BTA_MAX_SERVICES 32
 
-static void bta_dm_reset_sec_dev_pending(BD_ADDR remote_bd_addr);
-static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
+static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr);
+static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr);
 static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir,
                                       uint16_t eir_len);
 static void bta_dm_observe_cmpl_cb(void* p_result);
@@ -251,7 +251,6 @@
 uint8_t g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF];
 
 extern DEV_CLASS local_device_default_class;
-extern fixed_queue_t* btu_bta_alarm_queue;
 
 /*******************************************************************************
  *
@@ -489,8 +488,8 @@
 void bta_dm_disable(UNUSED_ATTR tBTA_DM_MSG* p_data) {
   /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after
    * last channel is closed) */
-  L2CA_SetIdleTimeoutByBdAddr((uint8_t*)BT_BD_ANY, 0, BT_TRANSPORT_BR_EDR);
-  L2CA_SetIdleTimeoutByBdAddr((uint8_t*)BT_BD_ANY, 0, BT_TRANSPORT_LE);
+  L2CA_SetIdleTimeoutByBdAddr(RawAddress::kAny, 0, BT_TRANSPORT_BR_EDR);
+  L2CA_SetIdleTimeoutByBdAddr(RawAddress::kAny, 0, BT_TRANSPORT_LE);
 
   /* disable all active subsystems */
   bta_sys_disable(BTA_SYS_HW_BLUETOOTH);
@@ -512,16 +511,14 @@
      */
     APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms", __func__,
                        BTA_DISABLE_DELAY);
-    alarm_set_on_queue(bta_dm_cb.disable_timer, BTA_DISABLE_DELAY,
-                       bta_dm_disable_conn_down_timer_cback, NULL,
-                       btu_bta_alarm_queue);
+    alarm_set_on_mloop(bta_dm_cb.disable_timer, BTA_DISABLE_DELAY,
+                       bta_dm_disable_conn_down_timer_cback, NULL);
 #else
     bta_dm_disable_conn_down_timer_cback(NULL);
 #endif
   } else {
-    alarm_set_on_queue(bta_dm_cb.disable_timer, BTA_DM_DISABLE_TIMER_MS,
-                       bta_dm_disable_timer_cback, UINT_TO_PTR(0),
-                       btu_bta_alarm_queue);
+    alarm_set_on_mloop(bta_dm_cb.disable_timer, BTA_DM_DISABLE_TIMER_MS,
+                       bta_dm_disable_timer_cback, UINT_TO_PTR(0));
   }
 }
 
@@ -557,9 +554,9 @@
        need
         to be sent out to avoid jave layer disable timeout */
     if (trigger_disc) {
-      alarm_set_on_queue(
-          bta_dm_cb.disable_timer, BTA_DM_DISABLE_TIMER_RETRIAL_MS,
-          bta_dm_disable_timer_cback, UINT_TO_PTR(1), btu_bta_alarm_queue);
+      alarm_set_on_mloop(bta_dm_cb.disable_timer,
+                         BTA_DM_DISABLE_TIMER_RETRIAL_MS,
+                         bta_dm_disable_timer_cback, UINT_TO_PTR(1));
     }
   } else {
     bta_dm_cb.disabling = false;
@@ -662,20 +659,19 @@
  * Description      Removes device, Disconnects ACL link if required.
  ***
  ******************************************************************************/
-void bta_dm_process_remove_device(BD_ADDR bd_addr) {
+void bta_dm_process_remove_device(const RawAddress& bd_addr) {
   /* need to remove all pending background connection before unpair */
   BTA_GATTC_CancelOpen(0, bd_addr, false);
 
   BTM_SecDeleteDevice(bd_addr);
 
   /* remove all cached GATT information */
-  bt_bdaddr_t tmp_addr;
-  memcpy(tmp_addr.address, bd_addr, BD_ADDR_LEN);
-  BTA_GATTC_Refresh(tmp_addr);
+  BTA_GATTC_Refresh(bd_addr);
 
   if (bta_dm_cb.p_sec_cback) {
     tBTA_DM_SEC sec_event;
-    bdcpy(sec_event.link_down.bd_addr, bd_addr);
+    sec_event.link_down.bd_addr = bd_addr;
+    ;
     /* No connection, set status to success (acl disc code not valid) */
     sec_event.link_down.status = HCI_SUCCESS;
     bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
@@ -694,8 +690,7 @@
   bool continue_delete_other_dev = false;
   if (p_dev == NULL) return;
 
-  BD_ADDR other_address;
-  bdcpy(other_address, p_dev->bd_addr);
+  RawAddress other_address = p_dev->bd_addr;
 
   /* If ACL exists for the device in the remove_bond message*/
   bool continue_delete_dev = false;
@@ -710,8 +705,7 @@
     /* Take the link down first, and mark the device for removal when
      * disconnected */
     for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
-      if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
-                 p_dev->bd_addr)) {
+      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == p_dev->bd_addr) {
         uint8_t transport = BT_TRANSPORT_BR_EDR;
 
         transport = bta_dm_cb.device_list.peer_device[i].transport;
@@ -737,16 +731,16 @@
   // device
   // if different address
   if ((other_transport &&
-       (BTM_ReadConnectedTransportAddress(other_address, other_transport))) ||
+       (BTM_ReadConnectedTransportAddress(&other_address, other_transport))) ||
       (!other_transport &&
-       (BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_BR_EDR) ||
-        BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_LE)))) {
+       (BTM_ReadConnectedTransportAddress(&other_address,
+                                          BT_TRANSPORT_BR_EDR) ||
+        BTM_ReadConnectedTransportAddress(&other_address, BT_TRANSPORT_LE)))) {
     continue_delete_other_dev = false;
     /* Take the link down first, and mark the device for removal when
      * disconnected */
     for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
-      if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
-                 other_address)) {
+      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == other_address) {
         bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
         btm_remove_acl(other_address,
                        bta_dm_cb.device_list.peer_device[i].transport);
@@ -761,8 +755,7 @@
   if (continue_delete_dev) bta_dm_process_remove_device(p_dev->bd_addr);
 
   /* Delete the other paired device too */
-  BD_ADDR dummy_bda = {0};
-  if (continue_delete_other_dev && (bdcmp(other_address, dummy_bda) != 0))
+  if (continue_delete_other_dev && !other_address.IsEmpty())
     bta_dm_process_remove_device(other_address);
 }
 
@@ -809,10 +802,7 @@
   if (!BTM_SecAddDevice(p_dev->bd_addr, p_dc, p_dev->bd_name, p_dev->features,
                         trusted_services_mask, p_lc, p_dev->key_type,
                         p_dev->io_cap, p_dev->pin_length)) {
-    APPL_TRACE_ERROR("BTA_DM: Error adding device %08x%04x",
-                     (p_dev->bd_addr[0] << 24) + (p_dev->bd_addr[1] << 16) +
-                         (p_dev->bd_addr[2] << 8) + p_dev->bd_addr[3],
-                     (p_dev->bd_addr[4] << 8) + p_dev->bd_addr[5]);
+    LOG(ERROR) << "BTA_DM: Error adding device " << p_dev->bd_addr;
   }
 }
 
@@ -833,8 +823,8 @@
 
   if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr, p_remove_acl->transport)) {
     for (index = 0; index < bta_dm_cb.device_list.count; index++) {
-      if (!bdcmp(bta_dm_cb.device_list.peer_device[index].peer_bdaddr,
-                 p_remove_acl->bd_addr))
+      if (bta_dm_cb.device_list.peer_device[index].peer_bdaddr ==
+          p_remove_acl->bd_addr)
         break;
     }
     if (index != bta_dm_cb.device_list.count) {
@@ -854,9 +844,7 @@
     /* need to remove all pending background connection if any */
     BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, false);
     /* remove all cached GATT information */
-    bt_bdaddr_t tmp_addr;
-    memcpy(tmp_addr.address, p_remove_acl->bd_addr, BD_ADDR_LEN);
-    BTA_GATTC_Refresh(tmp_addr);
+    BTA_GATTC_Refresh(p_remove_acl->bd_addr);
   }
   /* otherwise, no action needed */
 }
@@ -876,8 +864,6 @@
   APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type);
 
   for (uint8_t i = 0; i < bta_dm_cb.device_list.count; i++) {
-    BD_ADDR addr = {0};
-    bdcpy(addr, bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
     transport = bta_dm_cb.device_list.peer_device[i].transport;
     if ((link_type == BTA_DM_LINK_TYPE_ALL) ||
         ((link_type == BTA_DM_LINK_TYPE_LE) &&
@@ -885,7 +871,8 @@
         ((link_type == BTA_DM_LINK_TYPE_BR_EDR) &&
          (transport == BT_TRANSPORT_BR_EDR))) {
       /* Disconnect the ACL link */
-      btm_remove_acl(addr, transport);
+      btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
+                     transport);
     }
   }
 }
@@ -913,7 +900,7 @@
 
   if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) {
     memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
-    bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);
+    sec_event.auth_cmpl.bd_addr = p_data->bond.bd_addr;
     p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
     if (p_name != NULL) {
       memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN - 1));
@@ -1002,12 +989,12 @@
  *
  ******************************************************************************/
 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                                uint8_t app_id, BD_ADDR peer_addr) {
+                                uint8_t app_id, const RawAddress* peer_addr) {
   tBTA_DM_PEER_DEVICE* p_dev = NULL;
   uint16_t policy = app_id;
   uint32_t mask = (uint32_t)(1 << id);
 
-  if (peer_addr) p_dev = bta_dm_find_peer_device(peer_addr);
+  if (peer_addr) p_dev = bta_dm_find_peer_device(*peer_addr);
 
   APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x", status, policy);
   switch (status) {
@@ -1262,7 +1249,7 @@
   tBTA_DM_DI_DISC_CMPL di_disc;
 
   memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
-  bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
+  di_disc.bd_addr = bta_dm_search_cb.peer_bdaddr;
 
   if ((p_data->hdr.offset == SDP_SUCCESS) ||
       (p_data->hdr.offset == SDP_DB_FULL)) {
@@ -1313,7 +1300,7 @@
 
   if (bta_dm_di_cb.p_di_db != NULL) {
     memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
-    bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
+    di_disc.bd_addr = bta_dm_search_cb.peer_bdaddr;
     di_disc.result = BTA_FAILURE;
 
     bta_dm_di_cb.p_di_db = NULL;
@@ -1335,7 +1322,7 @@
   uint16_t result = BTA_FAILURE;
 
   bta_dm_search_cb.p_search_cback = p_data->di_disc.p_cback;
-  bdcpy(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.bd_addr);
+  bta_dm_search_cb.peer_bdaddr = p_data->di_disc.bd_addr;
   bta_dm_di_cb.p_di_db = p_data->di_disc.p_sdp_db;
 
   bta_dm_search_cb.p_sdp_db =
@@ -1365,13 +1352,13 @@
  * Returns          true if started to get remote name
  *
  ******************************************************************************/
-static bool bta_dm_read_remote_device_name(BD_ADDR bd_addr,
+static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
                                            tBT_TRANSPORT transport) {
   tBTM_STATUS btm_status;
 
-  APPL_TRACE_DEBUG("bta_dm_read_remote_device_name");
+  APPL_TRACE_DEBUG("%s", __func__);
 
-  bdcpy(bta_dm_search_cb.peer_bdaddr, bd_addr);
+  bta_dm_search_cb.peer_bdaddr = bd_addr;
   bta_dm_search_cb.peer_name[0] = 0;
 
   btm_status =
@@ -1379,13 +1366,11 @@
                                (tBTM_CMPL_CB*)bta_dm_remname_cback, transport);
 
   if (btm_status == BTM_CMD_STARTED) {
-    APPL_TRACE_DEBUG(
-        "bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is started");
+    APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is started", __func__);
 
     return (true);
   } else if (btm_status == BTM_BUSY) {
-    APPL_TRACE_DEBUG(
-        "bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy");
+    APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is busy", __func__);
 
     /* Remote name discovery is on going now so BTM cannot notify through
      * "bta_dm_remname_cback" */
@@ -1394,10 +1379,8 @@
 
     return (true);
   } else {
-    APPL_TRACE_WARNING(
-        "bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName returns "
-        "0x%02X",
-        btm_status);
+    APPL_TRACE_WARNING("%s: BTM_ReadRemoteDeviceName returns 0x%02X", __func__,
+                       btm_status);
 
     return (false);
   }
@@ -1546,7 +1529,7 @@
           if (p_sdp_rec) {
             if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
               /* send result back to app now, one by one */
-              bdcpy(result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
+              result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
               strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(),
                       BD_NAME_LEN);
               result.disc_ble_res.service.len = service_uuid.len;
@@ -1684,8 +1667,7 @@
         APPL_TRACE_EVENT(" Piggy back the SCN over result field  SCN=%d",
                          bta_dm_search_cb.peer_scn);
       }
-      bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
-            bta_dm_search_cb.peer_bdaddr);
+      p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
       strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
               bta_dm_get_remname(), BD_NAME_LEN);
 
@@ -1709,8 +1691,7 @@
     p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
     p_msg->disc_result.result.disc_res.services =
         bta_dm_search_cb.services_found;
-    bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
-          bta_dm_search_cb.peer_bdaddr);
+    p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
     strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
             bta_dm_get_remname(), BD_NAME_LEN);
 
@@ -1796,9 +1777,9 @@
   } else {
     /* wait until link is disconnected or timeout */
     bta_dm_search_cb.sdp_results = true;
-    alarm_set_on_queue(bta_dm_search_cb.search_timer,
+    alarm_set_on_mloop(bta_dm_search_cb.search_timer,
                        1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1),
-                       bta_dm_search_timer_cback, NULL, btu_bta_alarm_queue);
+                       bta_dm_search_timer_cback, NULL);
   }
 }
 
@@ -1939,7 +1920,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_find_services(BD_ADDR bd_addr) {
+static void bta_dm_find_services(const RawAddress& bd_addr) {
   tSDP_UUID uuid;
 
   memset(&uuid, 0, sizeof(tSDP_UUID));
@@ -2039,8 +2020,7 @@
     p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
     p_msg->disc_result.result.disc_res.services =
         bta_dm_search_cb.services_found;
-    bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
-          bta_dm_search_cb.peer_bdaddr);
+    p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
     strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
             bta_dm_get_remname(), BD_NAME_LEN);
 
@@ -2090,7 +2070,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_discover_device(BD_ADDR remote_bd_addr) {
+static void bta_dm_discover_device(const RawAddress& remote_bd_addr) {
   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
   if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) {
     tBT_DEVICE_TYPE dev_type;
@@ -2106,11 +2086,9 @@
   /* Reset transport state for next discovery */
   bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN;
 
-  APPL_TRACE_DEBUG("%s BDA:0x%02X%02X%02X%02X%02X%02X", __func__,
-                   remote_bd_addr[0], remote_bd_addr[1], remote_bd_addr[2],
-                   remote_bd_addr[3], remote_bd_addr[4], remote_bd_addr[5]);
+  VLOG(1) << __func__ << " BDA: " << remote_bd_addr;
 
-  bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
+  bta_dm_search_cb.peer_bdaddr = remote_bd_addr;
 
   APPL_TRACE_DEBUG(
       "%s name_discover_done = %d p_btm_inq_info 0x%x state = %d, transport=%d",
@@ -2205,8 +2183,7 @@
   memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
   p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
   p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
-  bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
-        bta_dm_search_cb.peer_bdaddr);
+  p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
   strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
           (char*)bta_dm_search_cb.peer_name, BD_NAME_LEN);
 
@@ -2247,7 +2224,7 @@
   tBTM_INQ_INFO* p_inq_info;
   uint16_t service_class;
 
-  bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
+  result.inq_res.bd_addr = p_inq->remote_bd_addr;
   memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
   BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
   result.inq_res.is_limited =
@@ -2317,16 +2294,16 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_service_search_remname_cback(BD_ADDR bd_addr,
+static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr,
                                                 UNUSED_ATTR DEV_CLASS dc,
                                                 BD_NAME bd_name) {
   tBTM_REMOTE_DEV_NAME rem_name;
   tBTM_STATUS btm_status;
 
-  APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name);
+  APPL_TRACE_DEBUG("%s name=<%s>", __func__, bd_name);
 
   /* if this is what we are looking for */
-  if (!bdcmp(bta_dm_search_cb.peer_bdaddr, bd_addr)) {
+  if (bta_dm_search_cb.peer_bdaddr == bd_addr) {
     rem_name.length = strlen((char*)bd_name);
     if (rem_name.length > (BD_NAME_LEN - 1)) {
       rem_name.length = (BD_NAME_LEN - 1);
@@ -2343,15 +2320,11 @@
                                           BT_TRANSPORT_BR_EDR);
     if (btm_status == BTM_BUSY) {
       /* wait for next chance(notification of remote name discovery done) */
-      APPL_TRACE_DEBUG(
-          "bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is "
-          "busy");
+      APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is busy", __func__);
     } else if (btm_status != BTM_CMD_STARTED) {
       /* if failed to start getting remote name then continue */
-      APPL_TRACE_WARNING(
-          "bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName "
-          "returns 0x%02X",
-          btm_status);
+      APPL_TRACE_WARNING("%s: BTM_ReadRemoteDeviceName returns 0x%02X",
+                         __func__, btm_status);
 
       rem_name.length = 0;
       rem_name.remote_bd_name[0] = 0;
@@ -2387,7 +2360,7 @@
 
   tBTA_DM_REM_NAME* p_msg =
       (tBTA_DM_REM_NAME*)osi_malloc(sizeof(tBTA_DM_REM_NAME));
-  bdcpy(p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
+  p_msg->result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
   strlcpy((char*)p_msg->result.disc_res.bd_name,
           (char*)p_remote_name->remote_bd_name, BD_NAME_LEN);
   p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
@@ -2404,15 +2377,15 @@
  * Returns          void
  *
  ******************************************************************************/
-static uint8_t bta_dm_authorize_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
-                                      BD_NAME bd_name,
+static uint8_t bta_dm_authorize_cback(const RawAddress& bd_addr,
+                                      DEV_CLASS dev_class, BD_NAME bd_name,
                                       UNUSED_ATTR uint8_t* service_name,
                                       uint8_t service_id,
                                       UNUSED_ATTR bool is_originator) {
   tBTA_DM_SEC sec_event;
   uint8_t index = 1;
 
-  bdcpy(sec_event.authorize.bd_addr, bd_addr);
+  sec_event.authorize.bd_addr = bd_addr;
   memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
   strlcpy((char*)sec_event.authorize.bd_name, (char*)bd_name, BD_NAME_LEN);
 
@@ -2461,7 +2434,7 @@
 
   if (BTA_DM_SP_CFM_REQ_EVT == event) {
     /* Retrieved saved device class and bd_addr */
-    bdcpy(sec_event.cfm_req.bd_addr, bta_dm_cb.pin_bd_addr);
+    sec_event.cfm_req.bd_addr = bta_dm_cb.pin_bd_addr;
     BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
 
     if (p_result && p_result->status == BTM_SUCCESS) {
@@ -2481,7 +2454,7 @@
     sec_event.cfm_req.just_works = bta_dm_cb.just_works;
   } else {
     /* Retrieved saved device class and bd_addr */
-    bdcpy(sec_event.pin_req.bd_addr, bta_dm_cb.pin_bd_addr);
+    sec_event.pin_req.bd_addr = bta_dm_cb.pin_bd_addr;
     BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
 
     if (p_result && p_result->status == BTM_SUCCESS) {
@@ -2511,7 +2484,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static uint8_t bta_dm_pin_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
+static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class,
                                 BD_NAME bd_name, bool min_16_digit) {
   tBTA_DM_SEC sec_event;
 
@@ -2521,7 +2494,7 @@
    * name request */
   if (bd_name[0] == 0) {
     bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
-    bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
+    bta_dm_cb.pin_bd_addr = bd_addr;
     BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
     if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback,
                                   BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
@@ -2531,7 +2504,7 @@
         " bta_dm_pin_cback() -> Failed to start Remote Name Request  ");
   }
 
-  bdcpy(sec_event.pin_req.bd_addr, bd_addr);
+  sec_event.pin_req.bd_addr = bd_addr;
   BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
   strlcpy((char*)sec_event.pin_req.bd_name, (char*)bd_name, BD_NAME_LEN);
   sec_event.pin_req.min_16_digit = min_16_digit;
@@ -2549,7 +2522,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static uint8_t bta_dm_new_link_key_cback(BD_ADDR bd_addr,
+static uint8_t bta_dm_new_link_key_cback(const RawAddress& bd_addr,
                                          UNUSED_ATTR DEV_CLASS dev_class,
                                          BD_NAME bd_name, LINK_KEY key,
                                          uint8_t key_type) {
@@ -2564,7 +2537,7 @@
     event = BTA_DM_AUTH_CMPL_EVT;
     p_auth_cmpl = &sec_event.auth_cmpl;
 
-    bdcpy(p_auth_cmpl->bd_addr, bd_addr);
+    p_auth_cmpl->bd_addr = bd_addr;
 
     memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN - 1));
     p_auth_cmpl->bd_name[BD_NAME_LEN - 1] = 0;
@@ -2604,13 +2577,13 @@
  *
  ******************************************************************************/
 static uint8_t bta_dm_authentication_complete_cback(
-    BD_ADDR bd_addr, UNUSED_ATTR DEV_CLASS dev_class, BD_NAME bd_name,
+    const RawAddress& bd_addr, UNUSED_ATTR DEV_CLASS dev_class, BD_NAME bd_name,
     int result) {
   tBTA_DM_SEC sec_event;
 
   if (result != BTM_SUCCESS) {
     memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
-    bdcpy(sec_event.auth_cmpl.bd_addr, bd_addr);
+    sec_event.auth_cmpl.bd_addr = bd_addr;
 
     memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN - 1));
     sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
@@ -2626,11 +2599,8 @@
     if (result == HCI_ERR_AUTH_FAILURE || result == HCI_ERR_KEY_MISSING ||
         result == HCI_ERR_HOST_REJECT_SECURITY ||
         result == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) {
-      bdstr_t bd_addr_str;
       APPL_TRACE_WARNING("%s deleting %s - result: 0x%02x", __func__,
-                         bdaddr_to_string((bt_bdaddr_t*)bd_addr, bd_addr_str,
-                                          sizeof(bd_addr_str)),
-                         result);
+                         bd_addr.ToString().c_str(), result);
       bta_dm_remove_sec_dev_entry(bd_addr);
     }
   }
@@ -2693,7 +2663,7 @@
            call remote name request using values from cfm_req */
         if (p_data->cfm_req.bd_name[0] == 0) {
           bta_dm_cb.pin_evt = pin_evt;
-          bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
+          bta_dm_cb.pin_bd_addr = p_data->cfm_req.bd_addr;
           BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
                                 p_data->cfm_req.dev_class);
           if ((BTM_ReadRemoteDeviceName(
@@ -2706,7 +2676,7 @@
           /* Due to the switch case falling through below to
              BTM_SP_KEY_NOTIF_EVT,
              copy these values into key_notif from cfm_req */
-          bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
+          sec_event.key_notif.bd_addr = p_data->cfm_req.bd_addr;
           BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class,
                                 p_data->cfm_req.dev_class);
           strlcpy((char*)sec_event.key_notif.bd_name,
@@ -2719,7 +2689,7 @@
            and initiate a name request with values from key_notif */
         if (p_data->key_notif.bd_name[0] == 0) {
           bta_dm_cb.pin_evt = pin_evt;
-          bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
+          bta_dm_cb.pin_bd_addr = p_data->key_notif.bd_addr;
           BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
                                 p_data->key_notif.dev_class);
           if ((BTM_ReadRemoteDeviceName(
@@ -2729,7 +2699,7 @@
           APPL_TRACE_WARNING(
               " bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
         } else {
-          bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
+          sec_event.key_notif.bd_addr = p_data->key_notif.bd_addr;
           BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class,
                                 p_data->key_notif.dev_class);
           strlcpy((char*)sec_event.key_notif.bd_name,
@@ -2752,7 +2722,7 @@
        * a name request */
       if (p_data->rmt_oob.bd_name[0] == 0) {
         bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
-        bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
+        bta_dm_cb.pin_bd_addr = p_data->rmt_oob.bd_addr;
         BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
                               p_data->rmt_oob.dev_class);
         if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr,
@@ -2763,7 +2733,7 @@
             " bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
       }
 
-      bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
+      sec_event.rmt_oob.bd_addr = p_data->rmt_oob.bd_addr;
       BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class,
                             p_data->rmt_oob.dev_class);
       strlcpy((char*)sec_event.rmt_oob.bd_name, (char*)p_data->rmt_oob.bd_name,
@@ -2808,7 +2778,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_local_name_cback(UNUSED_ATTR uint8_t* p_name) {
+static void bta_dm_local_name_cback(UNUSED_ATTR const RawAddress& p_name) {
   tBTA_DM_SEC sec_event;
 
   sec_event.enable.status = BTA_SUCCESS;
@@ -2837,12 +2807,12 @@
   switch (p_msg->event) {
     case BTM_BL_CONN_EVT:
       p_msg->is_new = true;
-      bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
+      p_msg->bd_addr = *p_data->conn.p_bda;
       p_msg->transport = p_data->conn.transport;
       p_msg->handle = p_data->conn.handle;
       break;
     case BTM_BL_DISCN_EVT:
-      bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
+      p_msg->bd_addr = *p_data->discn.p_bda;
       p_msg->transport = p_data->discn.transport;
       p_msg->handle = p_data->discn.handle;
       break;
@@ -2853,10 +2823,10 @@
     case BTM_BL_ROLE_CHG_EVT:
       p_msg->new_role = p_data->role_chg.new_role;
       p_msg->hci_status = p_data->role_chg.hci_status;
-      bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
+      p_msg->bd_addr = *p_data->role_chg.p_bda;
       break;
     case BTM_BL_COLLISION_EVT:
-      bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
+      p_msg->bd_addr = *p_data->conn.p_bda;
       break;
   }
 
@@ -2926,7 +2896,7 @@
         }
         /* else either already master or can not switch for some reasons */
         bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH,
-                            p_dev->peer_bdaddr);
+                            &p_dev->peer_bdaddr);
         break;
       }
     }
@@ -2949,7 +2919,7 @@
   uint8_t* p;
   tBTA_DM_SEC conn;
   bool is_new = p_data->acl_change.is_new;
-  BD_ADDR_PTR p_bda = p_data->acl_change.bd_addr;
+  const RawAddress& p_bda = p_data->acl_change.bd_addr;
   bool need_policy_change = false;
   bool issue_unpair_cb = false;
 
@@ -2992,7 +2962,7 @@
           if (need_policy_change) {
             bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0,
                                 HCI_ENABLE_MASTER_SLAVE_SWITCH,
-                                p_dev->peer_bdaddr);
+                                &p_dev->peer_bdaddr);
           }
         } else {
           /* there's AV no activity on this link and role switch happened
@@ -3003,7 +2973,7 @@
         bta_sys_notify_role_chg(p_data->acl_change.bd_addr,
                                 p_data->acl_change.new_role,
                                 p_data->acl_change.hci_status);
-        bdcpy(conn.role_chg.bd_addr, p_bda);
+        conn.role_chg.bd_addr = p_bda;
         conn.role_chg.new_role = (uint8_t)p_data->acl_change.new_role;
         if (bta_dm_cb.p_sec_cback)
           bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC*)&conn);
@@ -3019,7 +2989,7 @@
 
   if (is_new) {
     for (i = 0; i < bta_dm_cb.device_list.count; i++) {
-      if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda) &&
+      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == p_bda &&
           bta_dm_cb.device_list.peer_device[i].conn_handle ==
               p_data->acl_change.handle)
         break;
@@ -3027,9 +2997,8 @@
 
     if (i == bta_dm_cb.device_list.count) {
       if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) {
-        bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count]
-                  .peer_bdaddr,
-              p_bda);
+        bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count]
+            .peer_bdaddr = p_bda;
         bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count]
             .link_policy = bta_dm_cb.cur_policy;
         bta_dm_cb.device_list.count++;
@@ -3046,7 +3015,7 @@
 
     bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
     bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
-    bdcpy(conn.link_up.bd_addr, p_bda);
+    conn.link_up.bd_addr = p_bda;
     bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
     conn.link_up.link_type = p_data->acl_change.transport;
     bta_dm_cb.device_list.peer_device[i].transport =
@@ -3066,7 +3035,7 @@
       bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC*)&conn);
   } else {
     for (i = 0; i < bta_dm_cb.device_list.count; i++) {
-      if (bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda) ||
+      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr != p_bda ||
           bta_dm_cb.device_list.peer_device[i].transport !=
               p_data->acl_change.transport)
         continue;
@@ -3104,8 +3073,7 @@
       bta_dm_cb.device_list.le_count--;
     conn.link_down.link_type = p_data->acl_change.transport;
 
-    if (bta_dm_search_cb.wait_disc &&
-        !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) {
+    if (bta_dm_search_cb.wait_disc && bta_dm_search_cb.peer_bdaddr == p_bda) {
       bta_dm_search_cb.wait_disc = false;
 
       if (bta_dm_search_cb.sdp_results) {
@@ -3121,9 +3089,9 @@
          * Start a timer to make sure that the profiles
          * get the disconnect event.
          */
-        alarm_set_on_queue(
-            bta_dm_cb.disable_timer, BTA_DM_DISABLE_CONN_DOWN_TIMER_MS,
-            bta_dm_disable_conn_down_timer_cback, NULL, btu_bta_alarm_queue);
+        alarm_set_on_mloop(bta_dm_cb.disable_timer,
+                           BTA_DM_DISABLE_CONN_DOWN_TIMER_MS,
+                           bta_dm_disable_conn_down_timer_cback, NULL);
       }
     }
     if (conn.link_down.is_removed) {
@@ -3131,12 +3099,10 @@
       /* need to remove all pending background connection */
       BTA_GATTC_CancelOpen(0, p_bda, false);
       /* remove all cached GATT information */
-      bt_bdaddr_t tmp_addr;
-      memcpy(tmp_addr.address, p_bda, BD_ADDR_LEN);
-      BTA_GATTC_Refresh(tmp_addr);
+      BTA_GATTC_Refresh(p_bda);
     }
 
-    bdcpy(conn.link_down.bd_addr, p_bda);
+    conn.link_down.bd_addr = p_bda;
     conn.link_down.status = (uint8_t)btm_get_acl_disc_reason_code();
     if (bta_dm_cb.p_sec_cback) {
       bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
@@ -3187,12 +3153,12 @@
  *
  ******************************************************************************/
 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                            uint8_t app_id, BD_ADDR peer_addr) {
+                            uint8_t app_id, const RawAddress* peer_addr) {
   uint8_t j;
   tBTA_PREF_ROLES role;
   tBTA_DM_PEER_DEVICE* p_dev;
 
-  p_dev = bta_dm_find_peer_device(peer_addr);
+  p_dev = bta_dm_find_peer_device(*peer_addr);
   if (status == BTA_SYS_CONN_OPEN) {
     if (p_dev) {
       /* Do not set to connected if we are in the middle of unpairing. When AV
@@ -3264,10 +3230,9 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_reset_sec_dev_pending(BD_ADDR remote_bd_addr) {
+static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr) {
   for (size_t i = 0; i < bta_dm_cb.device_list.count; i++) {
-    if (bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
-              remote_bd_addr) == 0) {
+    if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
       bta_dm_cb.device_list.peer_device[i].remove_dev_pending = false;
       return;
     }
@@ -3287,7 +3252,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr) {
+static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr) {
   if (BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
       BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
     APPL_TRACE_DEBUG(
@@ -3295,20 +3260,20 @@
         __func__);
     BTM_SecClearSecurityFlags(remote_bd_addr);
     for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
-      if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
-                 remote_bd_addr)) {
+      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
         bta_dm_cb.device_list.peer_device[i].remove_dev_pending = TRUE;
         break;
       }
     }
   } else {
-    BTM_SecDeleteDevice(remote_bd_addr);
+    // remote_bd_addr comes from security record, which is removed in
+    // BTM_SecDeleteDevice.
+    RawAddress addr_copy = remote_bd_addr;
+    BTM_SecDeleteDevice(addr_copy);
     /* need to remove all pending background connection */
-    BTA_GATTC_CancelOpen(0, remote_bd_addr, false);
+    BTA_GATTC_CancelOpen(0, addr_copy, false);
     /* remove all cached GATT information */
-    bt_bdaddr_t tmp_addr;
-    memcpy(tmp_addr.address, remote_bd_addr, BD_ADDR_LEN);
-    BTA_GATTC_Refresh(tmp_addr);
+    BTA_GATTC_Refresh(addr_copy);
   }
 }
 
@@ -3365,9 +3330,9 @@
             BTM_SwitchRole(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
                            HCI_ROLE_MASTER, NULL);
           } else {
-            alarm_set_on_queue(
-                bta_dm_cb.switch_delay_timer, BTA_DM_SWITCH_DELAY_TIMER_MS,
-                bta_dm_delay_role_switch_cback, NULL, btu_bta_alarm_queue);
+            alarm_set_on_mloop(bta_dm_cb.switch_delay_timer,
+                               BTA_DM_SWITCH_DELAY_TIMER_MS,
+                               bta_dm_delay_role_switch_cback, NULL);
           }
         }
       }
@@ -3722,11 +3687,8 @@
   tBTA_SERVICE_MASK service_index = 0;
   tBTM_EIR_SEARCH_RESULT result;
 
-  APPL_TRACE_DEBUG(
-      "BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
-      p_result->remote_bd_addr[0], p_result->remote_bd_addr[1],
-      p_result->remote_bd_addr[2], p_result->remote_bd_addr[3],
-      p_result->remote_bd_addr[4], p_result->remote_bd_addr[5]);
+  VLOG(1) << "BTA searching services in EIR of BDA:"
+          << p_result->remote_bd_addr;
 
   APPL_TRACE_DEBUG("    with services_to_search=0x%08X", *p_services_to_search);
 
@@ -3860,14 +3822,14 @@
  * Returns         None
  *
  ******************************************************************************/
-void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport,
+void bta_dm_encrypt_cback(const RawAddress* bd_addr, tBT_TRANSPORT transport,
                           UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) {
   tBTA_STATUS bta_status = BTA_SUCCESS;
   tBTA_DM_ENCRYPT_CBACK* p_callback = NULL;
   uint8_t i;
 
   for (i = 0; i < bta_dm_cb.device_list.count; i++) {
-    if (bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
+    if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == *bd_addr &&
         bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
       break;
   }
@@ -3898,7 +3860,7 @@
                    bta_status, p_callback);
 
   if (p_callback) {
-    (*p_callback)(bd_addr, transport, bta_status);
+    (*p_callback)(*bd_addr, transport, bta_status);
   }
 }
 
@@ -3920,8 +3882,8 @@
     return;
   }
   for (i = 0; i < bta_dm_cb.device_list.count; i++) {
-    if (bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
-              p_data->set_encryption.bd_addr) == 0 &&
+    if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr ==
+            p_data->set_encryption.bd_addr &&
         bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
       break;
   }
@@ -3944,13 +3906,13 @@
   }
 }
 
-bool bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr) {
+bool bta_dm_check_if_only_hd_connected(const RawAddress& peer_addr) {
   APPL_TRACE_DEBUG("%s: count(%d)", __func__, bta_dm_conn_srvcs.count);
 
   for (uint8_t j = 0; j < bta_dm_conn_srvcs.count; j++) {
     // Check if profiles other than hid are connected
     if ((bta_dm_conn_srvcs.conn_srvc[j].id != BTA_ID_HD) &&
-        !bdcmp(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, peer_addr)) {
+        bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr == peer_addr) {
       APPL_TRACE_DEBUG("%s: Another profile (id=%d) is connected", __func__,
                        bta_dm_conn_srvcs.conn_srvc[j].id);
       return false;
@@ -3976,7 +3938,7 @@
   tBTM_INQ_INFO* p_inq_info;
   APPL_TRACE_DEBUG("bta_dm_observe_results_cb");
 
-  bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
+  result.inq_res.bd_addr = p_inq->remote_bd_addr;
   result.inq_res.rssi = p_inq->rssi;
   result.inq_res.ble_addr_type = p_inq->ble_addr_type;
   result.inq_res.inq_result_type = p_inq->inq_result_type;
@@ -4042,7 +4004,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, BD_ADDR bda,
+static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda,
                                     tBTM_LE_EVT_DATA* p_data) {
   tBTM_STATUS status = BTM_SUCCESS;
   tBTA_DM_SEC sec_event;
@@ -4066,7 +4028,7 @@
       break;
 
     case BTM_LE_SEC_REQUEST_EVT:
-      bdcpy(sec_event.ble_req.bd_addr, bda);
+      sec_event.ble_req.bd_addr = bda;
       p_name = BTM_SecReadDevName(bda);
       if (p_name != NULL)
         strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
@@ -4076,7 +4038,7 @@
       break;
 
     case BTM_LE_KEY_NOTIF_EVT:
-      bdcpy(sec_event.key_notif.bd_addr, bda);
+      sec_event.key_notif.bd_addr = bda;
       p_name = BTM_SecReadDevName(bda);
       if (p_name != NULL)
         strlcpy((char*)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN);
@@ -4087,17 +4049,17 @@
       break;
 
     case BTM_LE_KEY_REQ_EVT:
-      bdcpy(sec_event.ble_req.bd_addr, bda);
+      sec_event.ble_req.bd_addr = bda;
       bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
       break;
 
     case BTM_LE_OOB_REQ_EVT:
-      bdcpy(sec_event.ble_req.bd_addr, bda);
+      sec_event.ble_req.bd_addr = bda;
       bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
       break;
 
     case BTM_LE_NC_REQ_EVT:
-      bdcpy(sec_event.key_notif.bd_addr, bda);
+      sec_event.key_notif.bd_addr = bda;
       strlcpy((char*)sec_event.key_notif.bd_name, bta_dm_get_remname(),
               (BD_NAME_LEN));
       sec_event.key_notif.passkey = p_data->key_notif;
@@ -4105,19 +4067,19 @@
       break;
 
     case BTM_LE_SC_OOB_REQ_EVT:
-      bdcpy(sec_event.ble_req.bd_addr, bda);
+      sec_event.ble_req.bd_addr = bda;
       bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_OOB_REQ_EVT, &sec_event);
       break;
 
     case BTM_LE_KEY_EVT:
-      bdcpy(sec_event.ble_key.bd_addr, bda);
+      sec_event.ble_key.bd_addr = bda;
       sec_event.ble_key.key_type = p_data->key.key_type;
       sec_event.ble_key.p_key_value = p_data->key.p_key_value;
       bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
       break;
 
     case BTM_LE_COMPLT_EVT:
-      bdcpy(sec_event.auth_cmpl.bd_addr, bda);
+      sec_event.auth_cmpl.bd_addr = bda;
       BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type,
                       &sec_event.auth_cmpl.addr_type);
       p_name = BTM_SecReadDevName(bda);
@@ -4199,13 +4161,8 @@
   if (!BTM_SecAddBleKey(p_data->add_ble_key.bd_addr,
                         (tBTM_LE_KEY_VALUE*)&p_data->add_ble_key.blekey,
                         p_data->add_ble_key.key_type)) {
-    APPL_TRACE_ERROR(
-        "BTA_DM: Error adding BLE Key for device %08x%04x",
-        (p_data->add_ble_key.bd_addr[0] << 24) +
-            (p_data->add_ble_key.bd_addr[1] << 16) +
-            (p_data->add_ble_key.bd_addr[2] << 8) +
-            p_data->add_ble_key.bd_addr[3],
-        (p_data->add_ble_key.bd_addr[4] << 8) + p_data->add_ble_key.bd_addr[5]);
+    LOG(ERROR) << "BTA_DM: Error adding BLE Key for device "
+               << p_data->add_ble_key.bd_addr;
   }
 }
 
@@ -4225,13 +4182,8 @@
   if (!BTM_SecAddBleDevice(p_data->add_ble_device.bd_addr, NULL,
                            p_data->add_ble_device.dev_type,
                            p_data->add_ble_device.addr_type)) {
-    APPL_TRACE_ERROR("BTA_DM: Error adding BLE Device for device %08x%04x",
-                     (p_data->add_ble_device.bd_addr[0] << 24) +
-                         (p_data->add_ble_device.bd_addr[1] << 16) +
-                         (p_data->add_ble_device.bd_addr[2] << 8) +
-                         p_data->add_ble_device.bd_addr[3],
-                     (p_data->add_ble_device.bd_addr[4] << 8) +
-                         p_data->add_ble_device.bd_addr[5]);
+    LOG(ERROR) << "BTA_DM: Error adding BLE Device for device "
+               << p_data->add_ble_device.bd_addr;
   }
 }
 
@@ -4562,7 +4514,7 @@
            service_id.uuid.len);
   if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
     /* send result back to app now, one by one */
-    bdcpy(result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
+    result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
     strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(),
             BD_NAME_LEN);
     memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
@@ -4603,8 +4555,7 @@
         bta_dm_search_cb.services_found;
     p_msg->disc_result.result.disc_res.num_uuids = 0;
     p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
-    bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
-          bta_dm_search_cb.peer_bdaddr);
+    p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
     strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
             bta_dm_get_remname(), BD_NAME_LEN);
 
@@ -4630,7 +4581,7 @@
       bta_sys_start_timer(bta_dm_search_cb.gatt_close_timer,
                           BTA_DM_GATT_CLOSE_DELAY_TOUT,
                           BTA_DM_DISC_CLOSE_TOUT_EVT, 0);
-      bdcpy(bta_dm_search_cb.pending_close_bda, bta_dm_search_cb.peer_bdaddr);
+      bta_dm_search_cb.pending_close_bda = bta_dm_search_cb.peer_bdaddr;
     }
     bta_dm_search_cb.gatt_disc_active = false;
   }
@@ -4650,7 +4601,7 @@
   if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
     BTA_GATTC_Close(bta_dm_search_cb.conn_id);
 
-  memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
+  bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty;
   bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
 }
 /*******************************************************************************
@@ -4663,13 +4614,13 @@
  * Parameters:
  *
  ******************************************************************************/
-void btm_dm_start_gatt_discovery(BD_ADDR bd_addr) {
+void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) {
   bta_dm_search_cb.gatt_disc_active = true;
 
   /* connection is already open */
-  if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
+  if (bta_dm_search_cb.pending_close_bda == bd_addr &&
       bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
-    memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
+    bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty;
     alarm_cancel(bta_dm_search_cb.gatt_close_timer);
     btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
   } else {
@@ -4692,7 +4643,7 @@
  * Parameters:
  *
  ******************************************************************************/
-static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr) {
+static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr) {
   if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID) {
     BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, true);
   }
@@ -4711,20 +4662,9 @@
  *
  ******************************************************************************/
 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
-  uint8_t* p1;
-  uint8_t* p2;
-
-  p1 = bta_dm_search_cb.peer_bdaddr;
-  p2 = p_data->remote_bda;
-
-  APPL_TRACE_DEBUG(
-      "DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= "
-      "[%08x%04x] ",
-      bta_dm_search_cb.state,
-      ((p1[0]) << 24) + ((p1[1]) << 16) + ((p1[2]) << 8) + (p1[3]),
-      ((p1[4]) << 8) + p1[5],
-      ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]),
-      ((p2[4]) << 8) + p2[5]);
+  VLOG(1) << "DM Search state= " << bta_dm_search_cb.state
+          << " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr
+          << " connected_bda=" << p_data->remote_bda.address;
 
   APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d",
                    p_data->conn_id, p_data->client_if, p_data->status);
@@ -4770,8 +4710,7 @@
       /* in case of disconnect before search is completed */
       if ((bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
           (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
-          !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr,
-                  BD_ADDR_LEN)) {
+          p_data->close.remote_bda == bta_dm_search_cb.peer_bdaddr) {
         bta_dm_gatt_disc_complete((uint16_t)BTA_GATT_INVALID_CONN_ID,
                                   (tBTA_GATT_STATUS)BTA_GATT_ERROR);
       }
diff --git a/bta/dm/bta_dm_api.cc b/bta/dm/bta_dm_api.cc
index 90ca94b..c06de60 100644
--- a/bta/dm/bta_dm_api.cc
+++ b/bta/dm/bta_dm_api.cc
@@ -235,13 +235,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmDiscover(BD_ADDR bd_addr, tBTA_SERVICE_MASK services,
+void BTA_DmDiscover(const RawAddress& bd_addr, tBTA_SERVICE_MASK services,
                     tBTA_DM_SEARCH_CBACK* p_cback, bool sdp_search) {
   tBTA_DM_API_DISCOVER* p_msg =
       (tBTA_DM_API_DISCOVER*)osi_calloc(sizeof(tBTA_DM_API_DISCOVER));
 
   p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->services = services;
   p_msg->p_cback = p_cback;
   p_msg->sdp_search = sdp_search;
@@ -260,13 +260,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmDiscoverUUID(BD_ADDR bd_addr, tSDP_UUID* uuid,
+void BTA_DmDiscoverUUID(const RawAddress& bd_addr, tSDP_UUID* uuid,
                         tBTA_DM_SEARCH_CBACK* p_cback, bool sdp_search) {
   tBTA_DM_API_DISCOVER* p_msg =
       (tBTA_DM_API_DISCOVER*)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
 
   p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->services = BTA_USER_SERVICE_MASK;  // Not exposed at API level
   p_msg->p_cback = p_cback;
   p_msg->sdp_search = sdp_search;
@@ -290,12 +290,12 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmBond(BD_ADDR bd_addr) {
+void BTA_DmBond(const RawAddress& bd_addr) {
   tBTA_DM_API_BOND* p_msg =
       (tBTA_DM_API_BOND*)osi_malloc(sizeof(tBTA_DM_API_BOND));
 
   p_msg->hdr.event = BTA_DM_API_BOND_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->transport = BTA_TRANSPORT_UNKNOWN;
 
   bta_sys_sendmsg(p_msg);
@@ -312,12 +312,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport) {
+void BTA_DmBondByTransport(const RawAddress& bd_addr,
+                           tBTA_TRANSPORT transport) {
   tBTA_DM_API_BOND* p_msg =
       (tBTA_DM_API_BOND*)osi_malloc(sizeof(tBTA_DM_API_BOND));
 
   p_msg->hdr.event = BTA_DM_API_BOND_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->transport = transport;
 
   bta_sys_sendmsg(p_msg);
@@ -334,12 +335,12 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmBondCancel(BD_ADDR bd_addr) {
+void BTA_DmBondCancel(const RawAddress& bd_addr) {
   tBTA_DM_API_BOND_CANCEL* p_msg =
       (tBTA_DM_API_BOND_CANCEL*)osi_malloc(sizeof(tBTA_DM_API_BOND_CANCEL));
 
   p_msg->hdr.event = BTA_DM_API_BOND_CANCEL_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
 
   bta_sys_sendmsg(p_msg);
 }
@@ -355,7 +356,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmPinReply(BD_ADDR bd_addr, bool accept, uint8_t pin_len,
+void BTA_DmPinReply(const RawAddress& bd_addr, bool accept, uint8_t pin_len,
                     uint8_t* p_pin)
 
 {
@@ -363,7 +364,7 @@
       (tBTA_DM_API_PIN_REPLY*)osi_malloc(sizeof(tBTA_DM_API_PIN_REPLY));
 
   p_msg->hdr.event = BTA_DM_API_PIN_REPLY_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->accept = accept;
   if (accept) {
     p_msg->pin_len = pin_len;
@@ -404,12 +405,12 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmConfirm(BD_ADDR bd_addr, bool accept) {
+void BTA_DmConfirm(const RawAddress& bd_addr, bool accept) {
   tBTA_DM_API_CONFIRM* p_msg =
       (tBTA_DM_API_CONFIRM*)osi_malloc(sizeof(tBTA_DM_API_CONFIRM));
 
   p_msg->hdr.event = BTA_DM_API_CONFIRM_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->accept = accept;
 
   bta_sys_sendmsg(p_msg);
@@ -426,14 +427,15 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, LINK_KEY link_key,
-                     tBTA_SERVICE_MASK trusted_mask, bool is_trusted,
-                     uint8_t key_type, tBTA_IO_CAP io_cap, uint8_t pin_length) {
+void BTA_DmAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class,
+                     LINK_KEY link_key, tBTA_SERVICE_MASK trusted_mask,
+                     bool is_trusted, uint8_t key_type, tBTA_IO_CAP io_cap,
+                     uint8_t pin_length) {
   tBTA_DM_API_ADD_DEVICE* p_msg =
       (tBTA_DM_API_ADD_DEVICE*)osi_calloc(sizeof(tBTA_DM_API_ADD_DEVICE));
 
   p_msg->hdr.event = BTA_DM_API_ADD_DEVICE_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->tm = trusted_mask;
   p_msg->is_trusted = is_trusted;
   p_msg->io_cap = io_cap;
@@ -469,12 +471,12 @@
  * Returns          void
  *
  ******************************************************************************/
-tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr) {
+tBTA_STATUS BTA_DmRemoveDevice(const RawAddress& bd_addr) {
   tBTA_DM_API_REMOVE_DEVICE* p_msg =
       (tBTA_DM_API_REMOVE_DEVICE*)osi_calloc(sizeof(tBTA_DM_API_REMOVE_DEVICE));
 
   p_msg->hdr.event = BTA_DM_API_REMOVE_DEVICE_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
 
   bta_sys_sendmsg(p_msg);
 
@@ -535,7 +537,7 @@
  * Returns          0 if the device is NOT connected.
  *
  ******************************************************************************/
-uint16_t BTA_DmGetConnectionState(const BD_ADDR bd_addr) {
+uint16_t BTA_DmGetConnectionState(const RawAddress& bd_addr) {
   tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
   return (p_dev && p_dev->conn_state == BTA_DM_CONNECTED);
 }
@@ -611,14 +613,14 @@
  *                  BTA_FAIL if operation failed.
  *
  ******************************************************************************/
-void BTA_DmAddBleKey(BD_ADDR bd_addr, tBTA_LE_KEY_VALUE* p_le_key,
+void BTA_DmAddBleKey(const RawAddress& bd_addr, tBTA_LE_KEY_VALUE* p_le_key,
                      tBTA_LE_KEY_TYPE key_type) {
   tBTA_DM_API_ADD_BLEKEY* p_msg =
       (tBTA_DM_API_ADD_BLEKEY*)osi_calloc(sizeof(tBTA_DM_API_ADD_BLEKEY));
 
   p_msg->hdr.event = BTA_DM_API_ADD_BLEKEY_EVT;
   p_msg->key_type = key_type;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   memcpy(&p_msg->blekey, p_le_key, sizeof(tBTA_LE_KEY_VALUE));
 
   bta_sys_sendmsg(p_msg);
@@ -639,13 +641,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type,
+void BTA_DmAddBleDevice(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
                         tBT_DEVICE_TYPE dev_type) {
   tBTA_DM_API_ADD_BLE_DEVICE* p_msg = (tBTA_DM_API_ADD_BLE_DEVICE*)osi_calloc(
       sizeof(tBTA_DM_API_ADD_BLE_DEVICE));
 
   p_msg->hdr.event = BTA_DM_API_ADD_BLEDEVICE_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->addr_type = addr_type;
   p_msg->dev_type = dev_type;
 
@@ -666,12 +668,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmBlePasskeyReply(BD_ADDR bd_addr, bool accept, uint32_t passkey) {
+void BTA_DmBlePasskeyReply(const RawAddress& bd_addr, bool accept,
+                           uint32_t passkey) {
   tBTA_DM_API_PASSKEY_REPLY* p_msg =
       (tBTA_DM_API_PASSKEY_REPLY*)osi_calloc(sizeof(tBTA_DM_API_PASSKEY_REPLY));
 
   p_msg->hdr.event = BTA_DM_API_BLE_PASSKEY_REPLY_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->accept = accept;
 
   if (accept) p_msg->passkey = passkey;
@@ -692,12 +695,12 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmBleConfirmReply(BD_ADDR bd_addr, bool accept) {
+void BTA_DmBleConfirmReply(const RawAddress& bd_addr, bool accept) {
   tBTA_DM_API_CONFIRM* p_msg =
       (tBTA_DM_API_CONFIRM*)osi_calloc(sizeof(tBTA_DM_API_CONFIRM));
 
   p_msg->hdr.event = BTA_DM_API_BLE_CONFIRM_REPLY_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->accept = accept;
 
   bta_sys_sendmsg(p_msg);
@@ -715,12 +718,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmBleSecurityGrant(BD_ADDR bd_addr, tBTA_DM_BLE_SEC_GRANT res) {
+void BTA_DmBleSecurityGrant(const RawAddress& bd_addr,
+                            tBTA_DM_BLE_SEC_GRANT res) {
   tBTA_DM_API_BLE_SEC_GRANT* p_msg =
       (tBTA_DM_API_BLE_SEC_GRANT*)osi_calloc(sizeof(tBTA_DM_API_BLE_SEC_GRANT));
 
   p_msg->hdr.event = BTA_DM_API_BLE_SEC_GRANT_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->res = res;
 
   bta_sys_sendmsg(p_msg);
@@ -745,14 +749,15 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmSetBlePrefConnParams(const BD_ADDR bd_addr, uint16_t min_conn_int,
-                                uint16_t max_conn_int, uint16_t slave_latency,
+void BTA_DmSetBlePrefConnParams(const RawAddress& bd_addr,
+                                uint16_t min_conn_int, uint16_t max_conn_int,
+                                uint16_t slave_latency,
                                 uint16_t supervision_tout) {
   tBTA_DM_API_BLE_CONN_PARAMS* p_msg = (tBTA_DM_API_BLE_CONN_PARAMS*)osi_calloc(
       sizeof(tBTA_DM_API_BLE_CONN_PARAMS));
 
   p_msg->hdr.event = BTA_DM_API_BLE_CONN_PARAM_EVT;
-  memcpy(p_msg->peer_bda, bd_addr, BD_ADDR_LEN);
+  p_msg->peer_bda = bd_addr;
   p_msg->conn_int_max = max_conn_int;
   p_msg->conn_int_min = min_conn_int;
   p_msg->slave_latency = slave_latency;
@@ -805,7 +810,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_discover_send_msg(BD_ADDR bd_addr,
+static void bta_dm_discover_send_msg(const RawAddress& bd_addr,
                                      tBTA_SERVICE_MASK_EXT* p_services,
                                      tBTA_DM_SEARCH_CBACK* p_cback,
                                      bool sdp_search,
@@ -816,7 +821,7 @@
   tBTA_DM_API_DISCOVER* p_msg = (tBTA_DM_API_DISCOVER*)osi_calloc(len);
 
   p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->p_cback = p_cback;
   p_msg->sdp_search = sdp_search;
   p_msg->transport = transport;
@@ -850,7 +855,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmDiscoverByTransport(BD_ADDR bd_addr,
+void BTA_DmDiscoverByTransport(const RawAddress& bd_addr,
                                tBTA_SERVICE_MASK_EXT* p_services,
                                tBTA_DM_SEARCH_CBACK* p_cback, bool sdp_search,
                                tBTA_TRANSPORT transport) {
@@ -872,7 +877,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT* p_services,
+void BTA_DmDiscoverExt(const RawAddress& bd_addr,
+                       tBTA_SERVICE_MASK_EXT* p_services,
                        tBTA_DM_SEARCH_CBACK* p_cback, bool sdp_search) {
   bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search,
                            BTA_TRANSPORT_UNKNOWN);
@@ -944,7 +950,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmBleUpdateConnectionParam(BD_ADDR bd_addr, uint16_t min_int,
+void BTA_DmBleUpdateConnectionParam(const RawAddress& bd_addr, uint16_t min_int,
                                     uint16_t max_int, uint16_t latency,
                                     uint16_t timeout) {
   tBTA_DM_API_UPDATE_CONN_PARAM* p_msg =
@@ -952,7 +958,7 @@
           sizeof(tBTA_DM_API_UPDATE_CONN_PARAM));
 
   p_msg->hdr.event = BTA_DM_API_UPDATE_CONN_PARAM_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->min_int = min_int;
   p_msg->max_int = max_int;
   p_msg->latency = latency;
@@ -1027,15 +1033,15 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmBleUpdateConnectionParams(const BD_ADDR bd_addr, uint16_t min_int,
-                                     uint16_t max_int, uint16_t latency,
-                                     uint16_t timeout) {
+void BTA_DmBleUpdateConnectionParams(const RawAddress& bd_addr,
+                                     uint16_t min_int, uint16_t max_int,
+                                     uint16_t latency, uint16_t timeout) {
   tBTA_DM_API_UPDATE_CONN_PARAM* p_msg =
       (tBTA_DM_API_UPDATE_CONN_PARAM*)osi_calloc(
           sizeof(tBTA_DM_API_UPDATE_CONN_PARAM));
 
   p_msg->hdr.event = BTA_DM_API_UPDATE_CONN_PARAM_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->min_int = min_int;
   p_msg->max_int = max_int;
   p_msg->latency = latency;
@@ -1054,12 +1060,13 @@
  *
  *
  ******************************************************************************/
-void BTA_DmBleSetDataLength(BD_ADDR remote_device, uint16_t tx_data_length) {
+void BTA_DmBleSetDataLength(const RawAddress& remote_device,
+                            uint16_t tx_data_length) {
   tBTA_DM_API_BLE_SET_DATA_LENGTH* p_msg =
       (tBTA_DM_API_BLE_SET_DATA_LENGTH*)osi_malloc(
           sizeof(tBTA_DM_API_BLE_SET_DATA_LENGTH));
 
-  bdcpy(p_msg->remote_bda, remote_device);
+  p_msg->remote_bda = remote_device;
   p_msg->hdr.event = BTA_DM_API_SET_DATA_LENGTH_EVT;
   p_msg->tx_data_length = tx_data_length;
 
@@ -1088,7 +1095,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport,
+void BTA_DmSetEncryption(const RawAddress& bd_addr, tBTA_TRANSPORT transport,
                          tBTA_DM_ENCRYPT_CBACK* p_callback,
                          tBTA_DM_BLE_SEC_ACT sec_act) {
   tBTA_DM_API_SET_ENCRYPTION* p_msg = (tBTA_DM_API_SET_ENCRYPTION*)osi_calloc(
@@ -1097,7 +1104,7 @@
   APPL_TRACE_API("%s", __func__);
 
   p_msg->hdr.event = BTA_DM_API_SET_ENCRYPTION_EVT;
-  memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
+  p_msg->bd_addr = bd_addr;
   p_msg->transport = transport;
   p_msg->p_callback = p_callback;
   p_msg->sec_act = sec_act;
@@ -1118,7 +1125,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_DmCloseACL(BD_ADDR bd_addr, bool remove_dev,
+void BTA_DmCloseACL(const RawAddress& bd_addr, bool remove_dev,
                     tBTA_TRANSPORT transport) {
   tBTA_DM_API_REMOVE_ACL* p_msg =
       (tBTA_DM_API_REMOVE_ACL*)osi_calloc(sizeof(tBTA_DM_API_REMOVE_ACL));
@@ -1126,7 +1133,7 @@
   APPL_TRACE_API("%s", __func__);
 
   p_msg->hdr.event = BTA_DM_API_REMOVE_ACL_EVT;
-  memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
+  p_msg->bd_addr = bd_addr;
   p_msg->remove_dev = remove_dev;
   p_msg->transport = transport;
 
diff --git a/bta/dm/bta_dm_ci.cc b/bta/dm/bta_dm_ci.cc
index d3616d4..7ff9da2 100644
--- a/bta/dm/bta_dm_ci.cc
+++ b/bta/dm/bta_dm_ci.cc
@@ -40,7 +40,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_dm_ci_io_req(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
+void bta_dm_ci_io_req(const RawAddress& bd_addr, tBTA_IO_CAP io_cap,
                       tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req)
 
 {
@@ -48,7 +48,7 @@
       (tBTA_DM_CI_IO_REQ*)osi_malloc(sizeof(tBTA_DM_CI_IO_REQ));
 
   p_msg->hdr.event = BTA_DM_CI_IO_REQ_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->io_cap = io_cap;
   p_msg->oob_data = oob_data;
   p_msg->auth_req = auth_req;
@@ -67,13 +67,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_dm_ci_rmt_oob(bool accept, BD_ADDR bd_addr, BT_OCTET16 c,
+void bta_dm_ci_rmt_oob(bool accept, const RawAddress& bd_addr, BT_OCTET16 c,
                        BT_OCTET16 r) {
   tBTA_DM_CI_RMT_OOB* p_msg =
       (tBTA_DM_CI_RMT_OOB*)osi_malloc(sizeof(tBTA_DM_CI_RMT_OOB));
 
   p_msg->hdr.event = BTA_DM_CI_RMT_OOB_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->accept = accept;
   memcpy(p_msg->c, c, BT_OCTET16_LEN);
   memcpy(p_msg->r, r, BT_OCTET16_LEN);
diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h
index de6b728..12a4074 100644
--- a/bta/dm/bta_dm_int.h
+++ b/bta/dm/bta_dm_int.h
@@ -157,7 +157,7 @@
 /* data type for BTA_DM_API_DISCOVER_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_SERVICE_MASK services;
   tBTA_DM_SEARCH_CBACK* p_cback;
   bool sdp_search;
@@ -170,7 +170,7 @@
 /* data type for BTA_DM_API_DI_DISC_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_DISCOVERY_DB* p_sdp_db;
   uint32_t len;
   tBTA_DM_SEARCH_CBACK* p_cback;
@@ -179,21 +179,21 @@
 /* data type for BTA_DM_API_BOND_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_TRANSPORT transport;
 } tBTA_DM_API_BOND;
 
 /* data type for BTA_DM_API_BOND_CANCEL_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_TRANSPORT transport;
 } tBTA_DM_API_BOND_CANCEL;
 
 /* data type for BTA_DM_API_PIN_REPLY_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   bool accept;
   uint8_t pin_len;
   uint8_t p_pin[PIN_CODE_LEN];
@@ -205,14 +205,14 @@
 /* data type for BTA_DM_API_CONFIRM_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   bool accept;
 } tBTA_DM_API_CONFIRM;
 
 /* data type for BTA_DM_CI_IO_REQ_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_IO_CAP io_cap;
   tBTA_OOB_DATA oob_data;
   tBTA_AUTH_REQ auth_req;
@@ -221,7 +221,7 @@
 /* data type for BTA_DM_CI_RMT_OOB_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   BT_OCTET16 c;
   BT_OCTET16 r;
   bool accept;
@@ -259,7 +259,7 @@
   uint8_t busy_level_flags;
   bool is_new;
   uint8_t new_role;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t hci_status;
   uint16_t handle;
   tBT_TRANSPORT transport;
@@ -268,7 +268,7 @@
 /* data type for BTA_DM_PM_BTM_STATUS_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTM_PM_STATUS status;
   uint16_t value;
   uint8_t hci_status;
@@ -278,14 +278,14 @@
 /* data type for BTA_DM_PM_TIMER_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_DM_PM_ACTION pm_request;
 } tBTA_DM_PM_TIMER;
 
 /* data type for BTA_DM_API_ADD_DEVICE_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   DEV_CLASS dc;
   LINK_KEY link_key;
   tBTA_SERVICE_MASK tm;
@@ -303,7 +303,7 @@
 /* data type for BTA_DM_API_REMOVE_ACL_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
 } tBTA_DM_API_REMOVE_DEVICE;
 
 /* data type for BTA_DM_API_EXECUTE_CBACK_EVT */
@@ -319,12 +319,12 @@
   tBTA_TRANSPORT transport;
   tBTA_DM_ENCRYPT_CBACK* p_callback;
   tBTA_DM_BLE_SEC_ACT sec_act;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
 } tBTA_DM_API_SET_ENCRYPTION;
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_LE_KEY_VALUE blekey;
   tBTA_LE_KEY_TYPE key_type;
 
@@ -332,7 +332,7 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBT_DEVICE_TYPE dev_type;
   tBLE_ADDR_TYPE addr_type;
 
@@ -340,21 +340,21 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   bool accept;
   uint32_t passkey;
 } tBTA_DM_API_PASSKEY_REPLY;
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_DM_BLE_SEC_GRANT res;
 } tBTA_DM_API_BLE_SEC_GRANT;
 
 /* set prefered BLE connection parameters for a device */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR peer_bda;
+  RawAddress peer_bda;
   uint16_t conn_int_min;
   uint16_t conn_int_max;
   uint16_t supervision_tout;
@@ -364,7 +364,7 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR peer_bda;
+  RawAddress peer_bda;
   bool privacy_enable;
 
 } tBTA_DM_API_ENABLE_PRIVACY;
@@ -401,7 +401,7 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   uint16_t tx_data_length;
 } tBTA_DM_API_BLE_SET_DATA_LENGTH;
 
@@ -421,10 +421,9 @@
 /* data type for BTA_DM_API_REMOVE_ACL_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   bool remove_dev;
   tBTA_TRANSPORT transport;
-
 } tBTA_DM_API_REMOVE_ACL;
 
 /* data type for BTA_DM_API_REMOVE_ALL_ACL_EVT */
@@ -435,7 +434,7 @@
 } tBTA_DM_API_REMOVE_ALL_ACL;
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t min_int;
   uint16_t max_int;
   uint16_t latency;
@@ -536,7 +535,7 @@
 typedef uint8_t tBTA_DM_PM_REQ;
 
 typedef struct {
-  BD_ADDR peer_bdaddr;
+  RawAddress peer_bdaddr;
   uint16_t link_policy;
   tBTA_DM_CONN_STATE conn_state;
   tBTA_PREF_ROLES pref_role;
@@ -562,7 +561,7 @@
 } tBTA_DM_ACTIVE_LINK;
 
 typedef struct {
-  BD_ADDR peer_bdaddr;
+  RawAddress peer_bdaddr;
   tBTA_SYS_ID id;
   uint8_t app_id;
   tBTA_SYS_CONN_STATUS state;
@@ -595,7 +594,7 @@
   uint8_t pm_action[BTA_DM_PM_MODE_TIMER_MAX];
   uint8_t active; /* number of active timer */
 
-  BD_ADDR peer_bdaddr;
+  RawAddress peer_bdaddr;
   bool in_use;
 } tBTA_PM_TIMER;
 
@@ -632,7 +631,7 @@
   uint16_t inquiry_scan_window;
 
   /* Storage for pin code request parameters */
-  BD_ADDR pin_bd_addr;
+  RawAddress pin_bd_addr;
   DEV_CLASS pin_dev_class;
   tBTA_DM_SEC_EVT pin_evt;
   uint32_t num_val; /* the numeric value for comparison. If just_works, do not
@@ -661,7 +660,7 @@
   tBTA_SERVICE_MASK services_found;
   tSDP_DISCOVERY_DB* p_sdp_db;
   uint16_t state;
-  BD_ADDR peer_bdaddr;
+  RawAddress peer_bdaddr;
   bool name_discover_done;
   BD_NAME peer_name;
   alarm_t* search_timer;
@@ -686,7 +685,7 @@
   uint32_t ble_raw_size;
   uint32_t ble_raw_used;
   alarm_t* gatt_close_timer; /* GATT channel close delay timer */
-  BD_ADDR pending_close_bda; /* pending GATT channel remote device address */
+  RawAddress pending_close_bda; /* pending GATT channel remote device address */
 
 } tBTA_DM_SEARCH_CB;
 
@@ -861,7 +860,8 @@
 extern void bta_dm_search_cancel_notify(tBTA_DM_MSG* p_data);
 extern void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG* p_data);
 extern void bta_dm_disc_rmt_name(tBTA_DM_MSG* p_data);
-extern tBTA_DM_PEER_DEVICE* bta_dm_find_peer_device(const BD_ADDR peer_addr);
+extern tBTA_DM_PEER_DEVICE* bta_dm_find_peer_device(
+    const RawAddress& peer_addr);
 
 void bta_dm_eir_update_uuid(uint16_t uuid16, bool adding);
 
diff --git a/bta/dm/bta_dm_pm.cc b/bta/dm/bta_dm_pm.cc
index 472b7e1..23716c1 100644
--- a/bta/dm/bta_dm_pm.cc
+++ b/bta/dm/bta_dm_pm.cc
@@ -35,16 +35,16 @@
 #include "bta_sys.h"
 #include "btm_api.h"
 
-extern fixed_queue_t* btu_bta_alarm_queue;
-
 static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                            uint8_t app_id, BD_ADDR peer_addr);
-static void bta_dm_pm_set_mode(BD_ADDR peer_addr, tBTA_DM_PM_ACTION pm_mode,
+                            uint8_t app_id, const RawAddress& peer_addr);
+static void bta_dm_pm_set_mode(const RawAddress& peer_addr,
+                               tBTA_DM_PM_ACTION pm_mode,
                                tBTA_DM_PM_REQ pm_req);
 static void bta_dm_pm_timer_cback(void* data);
-static void bta_dm_pm_btm_cback(BD_ADDR bd_addr, tBTM_PM_STATUS status,
-                                uint16_t value, uint8_t hci_status);
-static bool bta_dm_pm_park(BD_ADDR peer_addr);
+static void bta_dm_pm_btm_cback(const RawAddress& bd_addr,
+                                tBTM_PM_STATUS status, uint16_t value,
+                                uint8_t hci_status);
+static bool bta_dm_pm_park(const RawAddress& peer_addr);
 static bool bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index);
 static bool bta_dm_pm_is_sco_active();
 static int bta_dm_get_sco_index();
@@ -61,7 +61,7 @@
  * can use it */
 #define BTA_DM_PM_SSR_HH BTA_DM_PM_SSR1
 #endif
-static void bta_dm_pm_ssr(BD_ADDR peer_addr);
+static void bta_dm_pm_ssr(const RawAddress& peer_addr);
 #endif
 
 tBTA_DM_CONNECTED_SRVCS bta_dm_conn_srvcs;
@@ -152,12 +152,12 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_pm_stop_timer(BD_ADDR peer_addr) {
+static void bta_dm_pm_stop_timer(const RawAddress& peer_addr) {
   APPL_TRACE_DEBUG("%s: ", __func__);
 
   for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
     if (bta_dm_cb.pm_timer[i].in_use &&
-        !bdcmp(bta_dm_cb.pm_timer[i].peer_bdaddr, peer_addr)) {
+        bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
       for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
         bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], j);
         /*
@@ -209,14 +209,14 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_pm_stop_timer_by_mode(BD_ADDR peer_addr,
+static void bta_dm_pm_stop_timer_by_mode(const RawAddress& peer_addr,
                                          uint8_t power_mode) {
   const uint8_t timer_idx = bta_pm_action_to_timer_idx(power_mode);
   if (timer_idx == BTA_DM_PM_MODE_TIMER_MAX) return;
 
   for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
     if (bta_dm_cb.pm_timer[i].in_use &&
-        !bdcmp(bta_dm_cb.pm_timer[i].peer_bdaddr, peer_addr)) {
+        bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
       if (bta_dm_cb.pm_timer[i].srvc_id[timer_idx] != BTA_ID_MAX) {
         bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], timer_idx);
         /*
@@ -242,11 +242,11 @@
  * Returns          index of the power mode delay timer
  *
  ******************************************************************************/
-static void bta_dm_pm_stop_timer_by_srvc_id(BD_ADDR peer_addr,
+static void bta_dm_pm_stop_timer_by_srvc_id(const RawAddress& peer_addr,
                                             uint8_t srvc_id) {
   for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
     if (bta_dm_cb.pm_timer[i].in_use &&
-        !bdcmp(bta_dm_cb.pm_timer[i].peer_bdaddr, peer_addr)) {
+        bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
       for (int j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
         if (bta_dm_cb.pm_timer[i].srvc_id[j] == srvc_id) {
           bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], j);
@@ -283,9 +283,8 @@
   p_timer->srvc_id[timer_idx] = srvc_id;
   state_lock.unlock();
 
-  alarm_set_on_queue(p_timer->timer[timer_idx], timeout_ms,
-                     bta_dm_pm_timer_cback, p_timer->timer[timer_idx],
-                     btu_bta_alarm_queue);
+  alarm_set_on_mloop(p_timer->timer[timer_idx], timeout_ms,
+                     bta_dm_pm_timer_cback, p_timer->timer[timer_idx]);
 }
 
 /*******************************************************************************
@@ -330,7 +329,7 @@
  *
  ******************************************************************************/
 static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                            uint8_t app_id, BD_ADDR peer_addr) {
+                            uint8_t app_id, const RawAddress& peer_addr) {
   uint8_t i, j;
   uint8_t* p = NULL;
   tBTA_DM_PEER_DEVICE* p_dev;
@@ -381,7 +380,7 @@
     /* check if an entry already present */
     if ((bta_dm_conn_srvcs.conn_srvc[j].id == id) &&
         (bta_dm_conn_srvcs.conn_srvc[j].app_id == app_id) &&
-        !bdcmp(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, peer_addr)) {
+        bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr == peer_addr) {
       bta_dm_conn_srvcs.conn_srvc[j].new_request = true;
       break;
     }
@@ -415,7 +414,7 @@
     bta_dm_conn_srvcs.conn_srvc[j].id = id;
     bta_dm_conn_srvcs.conn_srvc[j].app_id = app_id;
     bta_dm_conn_srvcs.conn_srvc[j].new_request = true;
-    bdcpy(bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr, peer_addr);
+    bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr = peer_addr;
 
     APPL_TRACE_WARNING("new conn_srvc id:%d, app_id:%d", id, app_id);
 
@@ -497,7 +496,8 @@
  *
  ******************************************************************************/
 
-static void bta_dm_pm_set_mode(BD_ADDR peer_addr, tBTA_DM_PM_ACTION pm_request,
+static void bta_dm_pm_set_mode(const RawAddress& peer_addr,
+                               tBTA_DM_PM_ACTION pm_request,
                                tBTA_DM_PM_REQ pm_req) {
   tBTA_DM_PM_ACTION pm_action = BTA_DM_PM_NO_ACTION;
   period_ms_t timeout_ms = 0;
@@ -525,7 +525,7 @@
 
   for (i = 0; i < bta_dm_conn_srvcs.count; i++) {
     p_srvcs = &bta_dm_conn_srvcs.conn_srvc[i];
-    if (!bdcmp(p_srvcs->peer_bdaddr, peer_addr)) {
+    if (p_srvcs->peer_bdaddr == peer_addr) {
       /* p_bta_dm_pm_cfg[0].app_id is the number of entries */
       for (j = 1; j <= p_bta_dm_pm_cfg[0].app_id; j++) {
         if ((p_bta_dm_pm_cfg[j].id == p_srvcs->id) &&
@@ -588,7 +588,7 @@
   if ((pm_req != BTA_DM_PM_EXECUTE) && (timeout_ms > 0)) {
     for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
       if (bta_dm_cb.pm_timer[i].in_use &&
-          bdcmp(bta_dm_cb.pm_timer[i].peer_bdaddr, peer_addr) == 0) {
+          bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) {
         timer_idx = bta_pm_action_to_timer_idx(pm_action);
         if (timer_idx != BTA_DM_PM_MODE_TIMER_MAX) {
           remaining_ms =
@@ -617,7 +617,7 @@
     /* new power mode for a new active connection */
     if (!timer_started) {
       if (available_timer != BTA_DM_PM_MODE_TIMER_MAX) {
-        bdcpy(bta_dm_cb.pm_timer[available_timer].peer_bdaddr, peer_addr);
+        bta_dm_cb.pm_timer[available_timer].peer_bdaddr = peer_addr;
         timer_idx = bta_pm_action_to_timer_idx(pm_action);
         if (timer_idx != BTA_DM_PM_MODE_TIMER_MAX) {
           bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[available_timer], timer_idx,
@@ -664,7 +664,7 @@
  * Returns          true if park attempted, false otherwise.
  *
  ******************************************************************************/
-static bool bta_dm_pm_park(BD_ADDR peer_addr) {
+static bool bta_dm_pm_park(const RawAddress& peer_addr) {
   tBTM_PM_MODE mode = BTM_PM_STS_ACTIVE;
 
   /* if not in park mode, switch to park */
@@ -755,14 +755,14 @@
  *
  ******************************************************************************/
 #if (BTM_SSR_INCLUDED == TRUE)
-static void bta_dm_pm_ssr(BD_ADDR peer_addr) {
+static void bta_dm_pm_ssr(const RawAddress& peer_addr) {
   tBTA_DM_SSR_SPEC *p_spec, *p_spec_cur;
   uint8_t i, j;
   int ssr = BTA_DM_PM_SSR0;
 
   /* go through the connected services */
   for (i = 0; i < bta_dm_conn_srvcs.count; i++) {
-    if (!bdcmp(bta_dm_conn_srvcs.conn_srvc[i].peer_bdaddr, peer_addr)) {
+    if (bta_dm_conn_srvcs.conn_srvc[i].peer_bdaddr == peer_addr) {
       /* p_bta_dm_pm_cfg[0].app_id is the number of entries */
       for (j = 1; j <= p_bta_dm_pm_cfg[0].app_id; j++) {
         /* find the associated p_bta_dm_pm_cfg */
@@ -809,8 +809,7 @@
     if (bta_dm_pm_is_sco_active()) {
       int idx = bta_dm_get_sco_index();
       if (idx != -1) {
-        if (bdcmp(bta_dm_conn_srvcs.conn_srvc[idx].peer_bdaddr, peer_addr) ==
-            0) {
+        if (bta_dm_conn_srvcs.conn_srvc[idx].peer_bdaddr == peer_addr) {
           APPL_TRACE_WARNING("%s SCO is active on device, ignore SSR",
                              __func__);
           return;
@@ -834,7 +833,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_dm_pm_active(BD_ADDR peer_addr) {
+void bta_dm_pm_active(const RawAddress& peer_addr) {
   tBTM_PM_PWR_MD pm;
 
   memset((void*)&pm, 0, sizeof(pm));
@@ -854,8 +853,9 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_dm_pm_btm_cback(BD_ADDR bd_addr, tBTM_PM_STATUS status,
-                                uint16_t value, uint8_t hci_status) {
+static void bta_dm_pm_btm_cback(const RawAddress& bd_addr,
+                                tBTM_PM_STATUS status, uint16_t value,
+                                uint8_t hci_status) {
   tBTA_DM_PM_BTM_STATUS* p_buf =
       (tBTA_DM_PM_BTM_STATUS*)osi_malloc(sizeof(tBTA_DM_PM_BTM_STATUS));
 
@@ -863,7 +863,7 @@
   p_buf->status = status;
   p_buf->value = value;
   p_buf->hci_status = hci_status;
-  bdcpy(p_buf->bd_addr, bd_addr);
+  p_buf->bd_addr = bd_addr;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -909,7 +909,7 @@
       (tBTA_DM_PM_TIMER*)osi_malloc(sizeof(tBTA_DM_PM_TIMER));
   p_buf->hdr.event = BTA_DM_PM_TIMER_EVT;
   p_buf->pm_request = bta_dm_cb.pm_timer[i].pm_action[j];
-  bdcpy(p_buf->bd_addr, bta_dm_cb.pm_timer[i].peer_bdaddr);
+  p_buf->bd_addr = bta_dm_cb.pm_timer[i].peer_bdaddr;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -1037,11 +1037,11 @@
  * Returns          tBTA_DM_PEER_DEVICE
  *
  ******************************************************************************/
-tBTA_DM_PEER_DEVICE* bta_dm_find_peer_device(const BD_ADDR peer_addr) {
+tBTA_DM_PEER_DEVICE* bta_dm_find_peer_device(const RawAddress& peer_addr) {
   tBTA_DM_PEER_DEVICE* p_dev = NULL;
 
   for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
-    if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, peer_addr)) {
+    if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == peer_addr) {
       p_dev = &bta_dm_cb.device_list.peer_device[i];
       break;
     }
diff --git a/bta/gatt/bta_gattc_act.cc b/bta/gatt/bta_gattc_act.cc
index 5d9a127..8b482b8 100644
--- a/bta/gatt/bta_gattc_act.cc
+++ b/bta/gatt/bta_gattc_act.cc
@@ -47,7 +47,7 @@
 /*****************************************************************************
  *  Constants
  ****************************************************************************/
-static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda,
+static void bta_gattc_conn_cback(tGATT_IF gattc_if, const RawAddress& bda,
                                  uint16_t conn_id, bool connected,
                                  tGATT_DISCONN_REASON reason,
                                  tBT_TRANSPORT transport);
@@ -60,7 +60,7 @@
                                    tGATT_CL_COMPLETE* p_data);
 
 static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB* p_clreg);
-static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda);
+static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, const RawAddress& bda);
 static void bta_gattc_cong_cback(uint16_t conn_id, bool congested);
 static void bta_gattc_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id,
                                        uint8_t tx_phy, uint8_t rx_phy,
@@ -105,14 +105,14 @@
  *
  ******************************************************************************/
 static void bta_gattc_enable() {
-  APPL_TRACE_DEBUG("bta_gattc_enable");
+  APPL_TRACE_DEBUG("%s", __func__);
 
   if (bta_gattc_cb.state == BTA_GATTC_STATE_DISABLED) {
     /* initialize control block */
     memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
     bta_gattc_cb.state = BTA_GATTC_STATE_ENABLED;
   } else {
-    APPL_TRACE_DEBUG("GATTC is arelady enabled");
+    APPL_TRACE_DEBUG("GATTC is already enabled");
   }
 }
 
@@ -129,10 +129,10 @@
 void bta_gattc_disable() {
   uint8_t i;
 
-  APPL_TRACE_DEBUG("bta_gattc_disable");
+  APPL_TRACE_DEBUG("%s", __func__);
 
   if (bta_gattc_cb.state != BTA_GATTC_STATE_ENABLED) {
-    APPL_TRACE_ERROR("not enabled or disable in pogress");
+    APPL_TRACE_ERROR("not enabled, or disabled in progress");
     return;
   }
 
@@ -173,7 +173,7 @@
                         BtaAppRegisterCallback cb) {
   tBTA_GATT_STATUS status = BTA_GATT_NO_RESOURCES;
   uint8_t client_if = 0;
-  APPL_TRACE_DEBUG("bta_gattc_register state %d", bta_gattc_cb.state);
+  APPL_TRACE_DEBUG("%s: state %d", __func__, bta_gattc_cb.state);
 
   /* check if  GATTC module is already enabled . Else enable */
   if (bta_gattc_cb.state == BTA_GATTC_STATE_DISABLED) {
@@ -284,7 +284,7 @@
       bta_gattc_init_bk_conn(&p_msg->api_conn, p_clreg);
     }
   } else {
-    APPL_TRACE_ERROR("bta_gattc_process_api_open Failed, unknown client_if: %d",
+    APPL_TRACE_ERROR("%s: Failed, unknown client_if: %d", __func__,
                      p_msg->api_conn.client_if);
   }
 }
@@ -325,7 +325,7 @@
 }
 
 /** process encryption complete message */
-void bta_gattc_process_enc_cmpl(tGATT_IF client_if, bt_bdaddr_t bda) {
+void bta_gattc_process_enc_cmpl(tGATT_IF client_if, const RawAddress& bda) {
   tBTA_GATTC_RCB* p_clreg;
   tBTA_GATTC cb_data;
 
@@ -335,7 +335,7 @@
     memset(&cb_data, 0, sizeof(tBTA_GATTC));
 
     cb_data.enc_cmpl.client_if = client_if;
-    memcpy(cb_data.enc_cmpl.remote_bda, bda.address, BD_ADDR_LEN);
+    cb_data.enc_cmpl.remote_bda = bda;
 
     (*p_clreg->p_cback)(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
   }
@@ -444,12 +444,9 @@
     /* always call open to hold a connection */
     if (!GATT_Connect(p_data->client_if, p_data->remote_bda, false,
                       p_data->transport, false)) {
-      uint8_t* bda = (uint8_t*)p_data->remote_bda;
       status = BTA_GATT_ERROR;
-      APPL_TRACE_ERROR(
-          "%s unable to connect to remote "
-          "bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-          __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+      LOG(ERROR) << __func__ << " unable to connect to remote bd_addr:"
+                 << p_data->remote_bda;
 
     } else {
       status = BTA_GATT_OK;
@@ -496,7 +493,7 @@
     if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, false)) {
       cb_data.status = BTA_GATT_OK;
     } else {
-      APPL_TRACE_ERROR("bta_gattc_cancel_bk_conn failed");
+      APPL_TRACE_ERROR("%s: failed", __func__);
     }
   }
   p_clreg = bta_gattc_cl_get_regcb(p_data->client_if);
@@ -558,11 +555,11 @@
  ******************************************************************************/
 void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
   tBTA_GATTC_IF gatt_if;
-  APPL_TRACE_DEBUG("bta_gattc_conn server cache state=%d",
+  APPL_TRACE_DEBUG("%s: server cache state=%d", __func__,
                    p_clcb->p_srcb->state);
 
   if (p_data != NULL) {
-    APPL_TRACE_DEBUG("bta_gattc_conn conn_id=%d", p_data->hdr.layer_specific);
+    APPL_TRACE_DEBUG("%s: conn_id=%d", __func__, p_data->hdr.layer_specific);
     p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific;
 
     GATT_GetConnectionInfor(p_data->hdr.layer_specific, &gatt_if, p_clcb->bda,
@@ -625,7 +622,7 @@
     memset(&cb_data, 0, sizeof(tBTA_GATTC));
     cb_data.close.client_if = p_clcb->p_rcb->client_if;
     cb_data.close.conn_id = p_data->hdr.layer_specific;
-    bdcpy(cb_data.close.remote_bda, p_clcb->bda);
+    cb_data.close.remote_bda = p_clcb->bda;
     cb_data.close.status = BTA_GATT_ERROR;
     cb_data.close.reason = BTA_GATT_CONN_NONE;
 
@@ -646,13 +643,13 @@
   tBTA_GATTC_RCB* p_clreg = p_clcb->p_rcb;
   tBTA_GATTC cb_data;
 
-  APPL_TRACE_DEBUG("bta_gattc_close conn_id=%d", p_clcb->bta_conn_id);
+  APPL_TRACE_DEBUG("%s: conn_id=%d", __func__, p_clcb->bta_conn_id);
 
   cb_data.close.client_if = p_clcb->p_rcb->client_if;
   cb_data.close.conn_id = p_clcb->bta_conn_id;
   cb_data.close.reason = p_clcb->reason;
   cb_data.close.status = p_clcb->status;
-  bdcpy(cb_data.close.remote_bda, p_clcb->bda);
+  cb_data.close.remote_bda = p_clcb->bda;
 
   if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
     bta_sys_conn_close(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
@@ -666,7 +663,7 @@
     cb_data.close.reason = p_data->int_conn.reason;
   }
 
-  if (p_cback) (*p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&cb_data);
+  if (p_cback) (*p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data);
 
   if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) {
     bta_gattc_deregister_cmpl(p_clreg);
@@ -795,9 +792,8 @@
  ******************************************************************************/
 void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb,
                               UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
-  APPL_TRACE_DEBUG(
-      "bta_gattc_start_discover conn_id=%d p_clcb->p_srcb->state = %d ",
-      p_clcb->bta_conn_id, p_clcb->p_srcb->state);
+  APPL_TRACE_DEBUG("%s: conn_id=%d p_clcb->p_srcb->state = %d ", __func__,
+                   p_clcb->bta_conn_id, p_clcb->p_srcb->state);
 
   if (((p_clcb->p_q_cmd == NULL ||
         p_clcb->auto_update == BTA_GATTC_REQ_WAITING) &&
@@ -854,7 +850,7 @@
                          UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
   tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd;
 
-  APPL_TRACE_DEBUG("bta_gattc_disc_cmpl conn_id=%d", p_clcb->bta_conn_id);
+  APPL_TRACE_DEBUG("%s: conn_id=%d", __func__, p_clcb->bta_conn_id);
 
   if (p_clcb->transport == BTA_TRANSPORT_LE)
     L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, true);
@@ -885,8 +881,7 @@
   else if (p_q_cmd != NULL) {
     p_clcb->p_q_cmd = NULL;
     /* execute pending operation of link block still present */
-    if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) !=
-        NULL) {
+    if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE)) {
       bta_gattc_sm_execute(p_clcb, p_q_cmd->hdr.event, p_q_cmd);
     }
     /* if the command executed requeued the cmd, we don't
@@ -1043,7 +1038,7 @@
 
   if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific,
                                    handle) != GATT_SUCCESS) {
-    APPL_TRACE_ERROR("bta_gattc_confirm to handle [0x%04x] failed", handle);
+    APPL_TRACE_ERROR("%s: to handle [0x%04x] failed", __func__, handle);
   } else {
     /* if over BR_EDR, inform PM for mode change */
     if (p_clcb->transport == BTA_TRANSPORT_BR_EDR) {
@@ -1065,8 +1060,9 @@
   GATT_READ_OP_CB cb = p_clcb->p_q_cmd->api_read.read_cb;
   void* my_cb_data = p_clcb->p_q_cmd->api_read.read_cb_data;
 
-  // if it was read by handle, return the handle requested, if read by UUID, use
-  // handle returned from remote
+  /* if it was read by handle, return the handle requested, if read by UUID, use
+   * handle returned from remote
+   */
   uint16_t handle = p_clcb->p_q_cmd->api_read.handle;
   if (handle == 0) handle = p_data->p_cmpl->att_value.handle;
 
@@ -1159,7 +1155,7 @@
   uint8_t op = (uint8_t)p_data->op_cmpl.op_code;
   uint8_t mapped_op = 0;
 
-  APPL_TRACE_DEBUG("bta_gattc_op_cmpl op = %d", op);
+  APPL_TRACE_DEBUG("%s: op = %d", __func__, op);
 
   if (op == GATTC_OPTYPE_INDICATION || op == GATTC_OPTYPE_NOTIFICATION) {
     APPL_TRACE_ERROR("unexpected operation, ignored");
@@ -1182,7 +1178,8 @@
     }
 
     /* Except for MTU configuration, discard responses if service change
-     * indication is received before operation completed */
+     * indication is received before operation completed
+     */
     if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING &&
         p_clcb->p_srcb->srvc_hdl_chg && op != GATTC_OPTYPE_CONFIG) {
       APPL_TRACE_DEBUG(
@@ -1222,8 +1219,7 @@
                               tBTA_GATTC_DATA* p_data) {
   /* receive op complete when discovery is started, ignore the response,
       and wait for discovery finish and resent */
-  APPL_TRACE_DEBUG("bta_gattc_ignore_op_cmpl op = %d",
-                   p_data->hdr.layer_specific);
+  APPL_TRACE_DEBUG("%s: op = %d", __func__, p_data->hdr.layer_specific);
 }
 /*******************************************************************************
  *
@@ -1237,7 +1233,7 @@
 void bta_gattc_search(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
   tBTA_GATT_STATUS status = GATT_INTERNAL_ERROR;
   tBTA_GATTC cb_data;
-  APPL_TRACE_DEBUG("bta_gattc_search conn_id=%d", p_clcb->bta_conn_id);
+  APPL_TRACE_DEBUG("%s: conn_id=%d", __func__, p_clcb->bta_conn_id);
   if (p_clcb->p_srcb && p_clcb->p_srcb->p_srvc_cache) {
     status = BTA_GATT_OK;
     /* search the local cache of a server device */
@@ -1303,7 +1299,7 @@
   cb_data.reg_oper.status = BTA_GATT_OK;
 
   if (p_cback) /* callback with de-register event */
-    (*p_cback)(BTA_GATTC_DEREG_EVT, (tBTA_GATTC*)&cb_data);
+    (*p_cback)(BTA_GATTC_DEREG_EVT, &cb_data);
 
   if (bta_gattc_num_reg_app() == 0 &&
       bta_gattc_cb.state == BTA_GATTC_STATE_DISABLING) {
@@ -1319,7 +1315,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda,
+static void bta_gattc_conn_cback(tGATT_IF gattc_if, const RawAddress& bdaddr,
                                  uint16_t conn_id, bool connected,
                                  tGATT_DISCONN_REASON reason,
                                  tBT_TRANSPORT transport) {
@@ -1328,8 +1324,6 @@
                        __func__, gattc_if, connected, conn_id, reason);
   }
 
-  bt_bdaddr_t bdaddr;
-  bdcpy(bdaddr.address, bda);
   if (connected)
     btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
   else
@@ -1341,10 +1335,10 @@
       connected ? BTA_GATTC_INT_CONN_EVT : BTA_GATTC_INT_DISCONN_EVT;
   p_buf->int_conn.hdr.layer_specific = conn_id;
   p_buf->int_conn.client_if = gattc_if;
-  p_buf->int_conn.role = L2CA_GetBleConnRole(bda);
+  p_buf->int_conn.role = L2CA_GetBleConnRole(bdaddr);
   p_buf->int_conn.reason = reason;
   p_buf->int_conn.transport = transport;
-  bdcpy(p_buf->int_conn.remote_bda, bda);
+  p_buf->int_conn.remote_bda = bdaddr;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -1358,7 +1352,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda) {
+static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, const RawAddress& bda) {
   tBTA_GATTC_CLCB* p_clcb =
       bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE);
 
@@ -1366,8 +1360,9 @@
 
 #if (BTA_HH_LE_INCLUDED == TRUE)
   /* filter this event just for BTA HH LE GATT client,
-     In the future, if we want to enable encryption complete event
-     for all GATT clients, we can remove this code */
+   * In the future, if we want to enable encryption complete event
+   * for all GATT clients, we can remove this code
+   */
   if (!bta_hh_le_is_hh_gatt_if(gattc_if)) {
     return;
   }
@@ -1375,10 +1370,8 @@
 
   APPL_TRACE_DEBUG("%s: cif = %d", __func__, gattc_if);
 
-  bt_bdaddr_t addr;
-  memcpy(addr.address, bda, BD_ADDR_LEN);
   do_in_bta_thread(FROM_HERE,
-                   base::Bind(&bta_gattc_process_enc_cmpl, gattc_if, addr));
+                   base::Bind(&bta_gattc_process_enc_cmpl, gattc_if, bda));
 }
 
 /*******************************************************************************
@@ -1391,8 +1384,8 @@
  * Returns          None.
  *
  ******************************************************************************/
-void bta_gattc_process_api_refresh(bt_bdaddr_t remote_bda) {
-  tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_srvr_cache(remote_bda.address);
+void bta_gattc_process_api_refresh(const RawAddress& remote_bda) {
+  tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_srvr_cache(remote_bda);
   tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
   bool found = false;
   uint8_t i;
@@ -1418,7 +1411,7 @@
     }
   }
   /* used to reset cache in application */
-  bta_gattc_cache_reset(remote_bda.address);
+  bta_gattc_cache_reset(remote_bda);
 }
 /*******************************************************************************
  *
@@ -1491,8 +1484,9 @@
     }
     /* notify applicationf or service change */
     if (p_clrcb->p_cback != NULL) {
-      (*p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT,
-                          (tBTA_GATTC*)p_srcb->server_bda);
+      tBTA_GATTC bta_gattc;
+      bta_gattc.remote_bda = p_srcb->server_bda;
+      (*p_clrcb->p_cback)(BTA_GATTC_SRVC_CHG_EVT, &bta_gattc);
     }
   }
 
@@ -1510,20 +1504,21 @@
 void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB* p_clcb, uint8_t op,
                                      tGATT_CL_COMPLETE* p_data,
                                      tBTA_GATTC_NOTIFY* p_notify) {
-  APPL_TRACE_DEBUG(
-      "bta_gattc_proc_other_indication check \
-                       p_data->att_value.handle=%d p_data->handle=%d",
-      p_data->att_value.handle, p_data->handle);
+  APPL_TRACE_DEBUG("%s: check p_data->att_value.handle=%d p_data->handle=%d",
+                   __func__, p_data->att_value.handle, p_data->handle);
   APPL_TRACE_DEBUG("is_notify", p_notify->is_notify);
 
   p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? false : true;
   p_notify->len = p_data->att_value.len;
-  bdcpy(p_notify->bda, p_clcb->bda);
+  p_notify->bda = p_clcb->bda;
   memcpy(p_notify->value, p_data->att_value.value, p_data->att_value.len);
   p_notify->conn_id = p_clcb->bta_conn_id;
 
-  if (p_clcb->p_rcb->p_cback)
-    (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)p_notify);
+  if (p_clcb->p_rcb->p_cback) {
+    tBTA_GATTC bta_gattc;
+    bta_gattc.notify = *p_notify;
+    (*p_clcb->p_rcb->p_cback)(BTA_GATTC_NOTIF_EVT, &bta_gattc);
+  }
 }
 /*******************************************************************************
  *
@@ -1541,7 +1536,7 @@
   tBTA_GATTC_RCB* p_clrcb = NULL;
   tBTA_GATTC_SERV* p_srcb = NULL;
   tBTA_GATTC_NOTIFY notify;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_GATTC_IF gatt_if;
   tBTA_TRANSPORT transport;
 
@@ -1627,8 +1622,8 @@
   else {
     p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
     if (p_clcb == NULL) {
-      APPL_TRACE_ERROR(
-          "bta_gattc_cmpl_cback unknown conn_id =  %d, ignore data", conn_id);
+      APPL_TRACE_ERROR("%s: unknown conn_id =  %d, ignore data", __func__,
+                       conn_id);
       return;
     }
   }
diff --git a/bta/gatt/bta_gattc_api.cc b/bta/gatt/bta_gattc_api.cc
index 36fc36e..4815f24 100644
--- a/bta/gatt/bta_gattc_api.cc
+++ b/bta/gatt/bta_gattc_api.cc
@@ -125,16 +125,17 @@
  *                                 and don't impact the disconnection timer
  *
  ******************************************************************************/
-void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, bool is_direct,
-                    tBTA_GATT_TRANSPORT transport, bool opportunistic) {
+void BTA_GATTC_Open(tBTA_GATTC_IF client_if, const RawAddress& remote_bda,
+                    bool is_direct, tBTA_GATT_TRANSPORT transport,
+                    bool opportunistic) {
   uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
   BTA_GATTC_Open(client_if, remote_bda, is_direct, transport, opportunistic,
                  phy);
 }
 
-void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, bool is_direct,
-                    tBTA_GATT_TRANSPORT transport, bool opportunistic,
-                    uint8_t initiating_phys) {
+void BTA_GATTC_Open(tBTA_GATTC_IF client_if, const RawAddress& remote_bda,
+                    bool is_direct, tBTA_GATT_TRANSPORT transport,
+                    bool opportunistic, uint8_t initiating_phys) {
   tBTA_GATTC_API_OPEN* p_buf =
       (tBTA_GATTC_API_OPEN*)osi_malloc(sizeof(tBTA_GATTC_API_OPEN));
 
@@ -144,7 +145,7 @@
   p_buf->transport = transport;
   p_buf->initiating_phys = initiating_phys;
   p_buf->opportunistic = opportunistic;
-  memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
+  p_buf->remote_bda = remote_bda;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -164,7 +165,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_GATTC_CancelOpen(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+void BTA_GATTC_CancelOpen(tBTA_GATTC_IF client_if, const RawAddress& remote_bda,
                           bool is_direct) {
   tBTA_GATTC_API_CANCEL_OPEN* p_buf = (tBTA_GATTC_API_CANCEL_OPEN*)osi_malloc(
       sizeof(tBTA_GATTC_API_CANCEL_OPEN));
@@ -172,7 +173,7 @@
   p_buf->hdr.event = BTA_GATTC_API_CANCEL_OPEN_EVT;
   p_buf->client_if = client_if;
   p_buf->is_direct = is_direct;
-  memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
+  p_buf->remote_bda = remote_bda;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -625,7 +626,7 @@
  *
  ******************************************************************************/
 tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications(tBTA_GATTC_IF client_if,
-                                                    const BD_ADDR bda,
+                                                    const RawAddress& bda,
                                                     uint16_t handle) {
   tBTA_GATTC_RCB* p_clreg;
   tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
@@ -640,7 +641,7 @@
   if (p_clreg != NULL) {
     for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
       if (p_clreg->notif_reg[i].in_use &&
-          !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
+          p_clreg->notif_reg[i].remote_bda == bda &&
           p_clreg->notif_reg[i].handle == handle) {
         APPL_TRACE_WARNING("notification already registered");
         status = BTA_GATT_OK;
@@ -654,7 +655,7 @@
                  sizeof(tBTA_GATTC_NOTIF_REG));
 
           p_clreg->notif_reg[i].in_use = true;
-          memcpy(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN);
+          p_clreg->notif_reg[i].remote_bda = bda;
 
           p_clreg->notif_reg[i].handle = handle;
           status = BTA_GATT_OK;
@@ -688,7 +689,7 @@
  *
  ******************************************************************************/
 tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications(tBTA_GATTC_IF client_if,
-                                                      const BD_ADDR bda,
+                                                      const RawAddress& bda,
                                                       uint16_t handle) {
   if (!handle) {
     APPL_TRACE_ERROR("%s: deregistration failed, handle is 0", __func__);
@@ -697,27 +698,22 @@
 
   tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(client_if);
   if (p_clreg == NULL) {
-    APPL_TRACE_ERROR(
-        "%s client_if: %d not registered bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-        __func__, client_if, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+    LOG(ERROR) << __func__ << " client_if: " << +client_if
+               << " not registered bd_addr:" << bda;
     return BTA_GATT_ILLEGAL_PARAMETER;
   }
 
   for (int i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
     if (p_clreg->notif_reg[i].in_use &&
-        !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
+        p_clreg->notif_reg[i].remote_bda == bda &&
         p_clreg->notif_reg[i].handle == handle) {
-      APPL_TRACE_DEBUG("%s deregistered bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-                       __func__, bda[0], bda[1], bda[2], bda[3], bda[4],
-                       bda[5]);
+      VLOG(1) << __func__ << " deregistered bd_addr:" << bda;
       memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
       return BTA_GATT_OK;
     }
   }
 
-  APPL_TRACE_ERROR(
-      "%s registration not found bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-      __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+  LOG(ERROR) << __func__ << " registration not found bd_addr:" << bda;
   return BTA_GATT_ERROR;
 }
 
@@ -732,7 +728,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_GATTC_Refresh(const bt_bdaddr_t& remote_bda) {
+void BTA_GATTC_Refresh(const RawAddress& remote_bda) {
   do_in_bta_thread(FROM_HERE,
                    base::Bind(&bta_gattc_process_api_refresh, remote_bda));
 }
diff --git a/bta/gatt/bta_gattc_cache.cc b/bta/gatt/bta_gattc_cache.cc
index adcb62d..110e534 100644
--- a/bta/gatt/bta_gattc_cache.cc
+++ b/bta/gatt/bta_gattc_cache.cc
@@ -44,8 +44,8 @@
 #include "sdpdefs.h"
 #include "utl.h"
 
-static void bta_gattc_cache_write(BD_ADDR server_bda, uint16_t num_attr,
-                                  tBTA_GATTC_NV_ATTR* attr);
+static void bta_gattc_cache_write(const RawAddress& server_bda,
+                                  uint16_t num_attr, tBTA_GATTC_NV_ATTR* attr);
 static void bta_gattc_char_dscpt_disc_cmpl(uint16_t conn_id,
                                            tBTA_GATTC_SERV* p_srvc_cb);
 static tBTA_GATT_STATUS bta_gattc_sdp_service_disc(
@@ -64,9 +64,10 @@
 #define GATT_CACHE_VERSION 2
 
 static void bta_gattc_generate_cache_file_name(char* buffer, size_t buffer_len,
-                                               BD_ADDR bda) {
+                                               const RawAddress& bda) {
   snprintf(buffer, buffer_len, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX,
-           bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+           bda.address[0], bda.address[1], bda.address[2], bda.address[3],
+           bda.address[4], bda.address[5]);
 }
 
 /*****************************************************************************
@@ -1462,6 +1463,11 @@
     goto done;
   }
 
+  if (num_attr > 0xFFFF) {
+    APPL_TRACE_ERROR("%s: more than 0xFFFF GATT attributes: %s", __func__, fname);
+    goto done;
+  }
+
   attr = (tBTA_GATTC_NV_ATTR*)osi_malloc(sizeof(tBTA_GATTC_NV_ATTR) * num_attr);
 
   if (fread(attr, sizeof(tBTA_GATTC_NV_ATTR), num_attr, fd) != num_attr) {
@@ -1492,8 +1498,8 @@
  * Returns
  *
  ******************************************************************************/
-static void bta_gattc_cache_write(BD_ADDR server_bda, uint16_t num_attr,
-                                  tBTA_GATTC_NV_ATTR* attr) {
+static void bta_gattc_cache_write(const RawAddress& server_bda,
+                                  uint16_t num_attr, tBTA_GATTC_NV_ATTR* attr) {
   char fname[255] = {0};
   bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);
 
@@ -1540,7 +1546,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-void bta_gattc_cache_reset(BD_ADDR server_bda) {
+void bta_gattc_cache_reset(const RawAddress& server_bda) {
   BTIF_TRACE_DEBUG("%s", __func__);
   char fname[255] = {0};
   bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);
diff --git a/bta/gatt/bta_gattc_int.h b/bta/gatt/bta_gattc_int.h
index 598262b..8055090 100644
--- a/bta/gatt/bta_gattc_int.h
+++ b/bta/gatt/bta_gattc_int.h
@@ -83,7 +83,7 @@
 /* internal strucutre for GATTC register API  */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_GATTC_IF client_if;
   bool is_direct;
   tBTA_TRANSPORT transport;
@@ -160,7 +160,7 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_GATTC_IF client_if;
   uint8_t role;
   tBT_TRANSPORT transport;
@@ -212,7 +212,7 @@
 
 typedef struct {
   bool in_use;
-  BD_ADDR server_bda;
+  RawAddress server_bda;
   bool connected;
 
 #define BTA_GATTC_SERV_IDLE 0
@@ -246,7 +246,7 @@
 
 typedef struct {
   bool in_use;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   uint16_t handle;
 } tBTA_GATTC_NOTIF_REG;
 
@@ -265,7 +265,7 @@
  * address */
 typedef struct {
   uint16_t bta_conn_id; /* client channel ID, unique for clcb */
-  BD_ADDR bda;
+  RawAddress bda;
   tBTA_TRANSPORT transport; /* channel transport */
   tBTA_GATTC_RCB* p_rcb;    /* pointer to the registration CB */
   tBTA_GATTC_SERV* p_srcb;  /* server cache CB */
@@ -294,14 +294,14 @@
 
 typedef struct {
   bool in_use;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_GATTC_CIF_MASK cif_mask;
 
 } tBTA_GATTC_BG_TCK;
 
 typedef struct {
   bool in_use;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
 } tBTA_GATTC_CONN;
 
 enum {
@@ -392,28 +392,29 @@
 extern void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN* p_data);
 extern void bta_gattc_send_open_cback(tBTA_GATTC_RCB* p_clreg,
                                       tBTA_GATT_STATUS status,
-                                      BD_ADDR remote_bda, uint16_t conn_id,
+                                      const RawAddress& remote_bda,
+                                      uint16_t conn_id,
                                       tBTA_TRANSPORT transport, uint16_t mtu);
-extern void bta_gattc_process_api_refresh(bt_bdaddr_t remote_bda);
+extern void bta_gattc_process_api_refresh(const RawAddress& remote_bda);
 extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data);
 extern void bta_gattc_listen(tBTA_GATTC_DATA* p_msg);
 extern void bta_gattc_broadcast(tBTA_GATTC_DATA* p_msg);
 
 /* utility functions */
 extern tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if,
-                                                   BD_ADDR remote_bda,
+                                                   const RawAddress& remote_bda,
                                                    tBTA_TRANSPORT transport);
 extern tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id);
 extern tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if,
-                                             BD_ADDR remote_bda,
+                                             const RawAddress& remote_bda,
                                              tBTA_TRANSPORT transport);
 extern void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb);
 extern tBTA_GATTC_CLCB* bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if,
-                                                  BD_ADDR remote_bda,
+                                                  const RawAddress& remote_bda,
                                                   tBTA_TRANSPORT transport);
 extern tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if);
-extern tBTA_GATTC_SERV* bta_gattc_find_srcb(BD_ADDR bda);
-extern tBTA_GATTC_SERV* bta_gattc_srcb_alloc(BD_ADDR bda);
+extern tBTA_GATTC_SERV* bta_gattc_find_srcb(const RawAddress& bda);
+extern tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda);
 extern tBTA_GATTC_SERV* bta_gattc_find_scb_by_cid(uint16_t conn_id);
 extern tBTA_GATTC_CLCB* bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA* p_msg);
 extern tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg);
@@ -426,15 +427,15 @@
                                            tBTA_GATTC_SERV* p_srcb,
                                            tBTA_GATTC_NOTIFY* p_notify);
 extern bool bta_gattc_mark_bg_conn(tBTA_GATTC_IF client_if,
-                                   BD_ADDR_PTR remote_bda, bool add);
-extern bool bta_gattc_check_bg_conn(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
-                                    uint8_t role);
+                                   const RawAddress& remote_bda, bool add);
+extern bool bta_gattc_check_bg_conn(tBTA_GATTC_IF client_if,
+                                    const RawAddress& remote_bda, uint8_t role);
 extern uint8_t bta_gattc_num_reg_app(void);
 extern void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV* p_srcb,
                                                uint16_t conn_id,
                                                uint16_t start_handle,
                                                uint16_t end_handle);
-extern tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(BD_ADDR bda);
+extern tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(const RawAddress& bda);
 
 /* discovery functions */
 extern void bta_gattc_disc_res_cback(uint16_t conn_id,
@@ -467,12 +468,12 @@
 extern void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb,
                                         tBTA_GATT_STATUS status);
 
-extern tBTA_GATTC_CONN* bta_gattc_conn_alloc(BD_ADDR remote_bda);
-extern tBTA_GATTC_CONN* bta_gattc_conn_find(BD_ADDR remote_bda);
-extern tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(BD_ADDR remote_bda);
-extern bool bta_gattc_conn_dealloc(BD_ADDR remote_bda);
+extern tBTA_GATTC_CONN* bta_gattc_conn_alloc(const RawAddress& remote_bda);
+extern tBTA_GATTC_CONN* bta_gattc_conn_find(const RawAddress& remote_bda);
+extern tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(const RawAddress& remote_bda);
+extern bool bta_gattc_conn_dealloc(const RawAddress& remote_bda);
 
 extern bool bta_gattc_cache_load(tBTA_GATTC_CLCB* p_clcb);
-extern void bta_gattc_cache_reset(BD_ADDR server_bda);
+extern void bta_gattc_cache_reset(const RawAddress& server_bda);
 
 #endif /* BTA_GATTC_INT_H */
diff --git a/bta/gatt/bta_gattc_utils.cc b/bta/gatt/bta_gattc_utils.cc
index 53e4c18..f14f469 100644
--- a/bta/gatt/bta_gattc_utils.cc
+++ b/bta/gatt/bta_gattc_utils.cc
@@ -26,12 +26,12 @@
 
 #include "bt_target.h"
 
+#include <base/logging.h>
 #include <string.h>
 
 #include "bt_common.h"
 #include "bta_gattc_int.h"
 #include "bta_sys.h"
-#include "btcore/include/bdaddr.h"
 #include "l2c_api.h"
 #include "utl.h"
 
@@ -43,8 +43,6 @@
     0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
-static const BD_ADDR dummy_bda = {0, 0, 0, 0, 0, 0};
-
 /*******************************************************************************
  *
  * Function         bta_gatt_convert_uuid16_to_uuid128
@@ -152,14 +150,14 @@
  *
  ******************************************************************************/
 tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if,
-                                            BD_ADDR remote_bda,
+                                            const RawAddress& remote_bda,
                                             tBTA_TRANSPORT transport) {
   tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
   uint8_t i;
 
   for (i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
     if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if &&
-        p_clcb->transport == transport && bdcmp(p_clcb->bda, remote_bda) == 0)
+        p_clcb->transport == transport && p_clcb->bda == remote_bda)
       return p_clcb;
   }
   return NULL;
@@ -193,7 +191,7 @@
  *
  ******************************************************************************/
 tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if,
-                                      BD_ADDR remote_bda,
+                                      const RawAddress& remote_bda,
                                       tBTA_TRANSPORT transport) {
   uint8_t i_clcb = 0;
   tBTA_GATTC_CLCB* p_clcb = NULL;
@@ -208,7 +206,7 @@
       p_clcb->in_use = true;
       p_clcb->status = BTA_GATT_OK;
       p_clcb->transport = transport;
-      bdcpy(p_clcb->bda, remote_bda);
+      p_clcb->bda = remote_bda;
 
       p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
 
@@ -239,7 +237,7 @@
  *
  ******************************************************************************/
 tBTA_GATTC_CLCB* bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if,
-                                           BD_ADDR remote_bda,
+                                           const RawAddress& remote_bda,
                                            tBTA_TRANSPORT transport) {
   tBTA_GATTC_CLCB* p_clcb;
 
@@ -297,12 +295,12 @@
  * Returns          pointer to the server cache.
  *
  ******************************************************************************/
-tBTA_GATTC_SERV* bta_gattc_find_srcb(BD_ADDR bda) {
+tBTA_GATTC_SERV* bta_gattc_find_srcb(const RawAddress& bda) {
   tBTA_GATTC_SERV* p_srcb = &bta_gattc_cb.known_server[0];
   uint8_t i;
 
   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++, p_srcb++) {
-    if (p_srcb->in_use && bdcmp(p_srcb->server_bda, bda) == 0) return p_srcb;
+    if (p_srcb->in_use && p_srcb->server_bda == bda) return p_srcb;
   }
   return NULL;
 }
@@ -316,12 +314,12 @@
  * Returns          pointer to the server cache.
  *
  ******************************************************************************/
-tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(BD_ADDR bda) {
+tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(const RawAddress& bda) {
   tBTA_GATTC_SERV* p_srcb = &bta_gattc_cb.known_server[0];
   uint8_t i;
 
   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++, p_srcb++) {
-    if (bdcmp(p_srcb->server_bda, bda) == 0) return p_srcb;
+    if (p_srcb->server_bda == bda) return p_srcb;
   }
   return NULL;
 }
@@ -351,7 +349,7 @@
  * Returns          pointer to the server cache.
  *
  ******************************************************************************/
-tBTA_GATTC_SERV* bta_gattc_srcb_alloc(BD_ADDR bda) {
+tBTA_GATTC_SERV* bta_gattc_srcb_alloc(const RawAddress& bda) {
   tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0], *p_recycle = NULL;
   bool found = false;
   uint8_t i;
@@ -378,7 +376,7 @@
     memset(p_tcb, 0, sizeof(tBTA_GATTC_SERV));
 
     p_tcb->in_use = true;
-    bdcpy(p_tcb->server_bda, bda);
+    p_tcb->server_bda = bda;
   }
   return p_tcb;
 }
@@ -418,7 +416,7 @@
 
   for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
     if (p_clreg->notif_reg[i].in_use &&
-        bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
+        p_clreg->notif_reg[i].remote_bda == p_srcb->server_bda &&
         p_clreg->notif_reg[i].handle == p_notify->handle) {
       APPL_TRACE_DEBUG("Notification registered!");
       return true;
@@ -431,7 +429,7 @@
  * Function         bta_gattc_clear_notif_registration
  *
  * Description      Clear up the notification registration information by
- *                  BD_ADDR.
+ *                  RawAddress.
  *                  Where handle is between start_handle and end_handle, and
  *                  start_handle and end_handle are boundaries of service
  *                  containing characteristic.
@@ -442,7 +440,7 @@
 void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV* p_srcb,
                                         uint16_t conn_id, uint16_t start_handle,
                                         uint16_t end_handle) {
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_GATTC_IF gatt_if;
   tBTA_GATTC_RCB* p_clrcb;
   uint8_t i;
@@ -454,7 +452,7 @@
     if (p_clrcb != NULL) {
       for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i++) {
         if (p_clrcb->notif_reg[i].in_use &&
-            !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda)) {
+            p_clrcb->notif_reg[i].remote_bda == remote_bda) {
           /* It's enough to get service or characteristic handle, as
            * clear boundaries are always around service.
            */
@@ -481,18 +479,15 @@
  * Returns          true if success; false otherwise.
  *
  ******************************************************************************/
-bool bta_gattc_mark_bg_conn(tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda_ptr,
-                            bool add) {
+bool bta_gattc_mark_bg_conn(tBTA_GATTC_IF client_if,
+                            const RawAddress& remote_bda_ptr, bool add) {
   tBTA_GATTC_BG_TCK* p_bg_tck = &bta_gattc_cb.bg_track[0];
   uint8_t i = 0;
   tBTA_GATTC_CIF_MASK* p_cif_mask;
 
   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i++, p_bg_tck++) {
-    if (p_bg_tck->in_use &&
-        ((remote_bda_ptr != NULL &&
-          bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) ||
-         (remote_bda_ptr == NULL &&
-          bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0))) {
+    if (p_bg_tck->in_use && ((p_bg_tck->remote_bda == remote_bda_ptr) ||
+                             (p_bg_tck->remote_bda.IsEmpty()))) {
       p_cif_mask = &p_bg_tck->cif_mask;
 
       if (add) /* mask on the cif bit */
@@ -511,12 +506,8 @@
     }
   }
   if (!add) {
-    if (remote_bda_ptr) {
-      bdstr_t bdstr = {0};
-      APPL_TRACE_ERROR(
-          "%s unable to find the bg connection mask for: %s", __func__,
-          bdaddr_to_string((bt_bdaddr_t*)remote_bda_ptr, bdstr, sizeof(bdstr)));
-    }
+    LOG(ERROR) << __func__ << " unable to find the bg connection mask for: "
+               << remote_bda_ptr;
     return false;
   } else /* adding a new device mask */
   {
@@ -524,10 +515,7 @@
          i < BTA_GATTC_KNOWN_SR_MAX; i++, p_bg_tck++) {
       if (!p_bg_tck->in_use) {
         p_bg_tck->in_use = true;
-        if (remote_bda_ptr)
-          bdcpy(p_bg_tck->remote_bda, remote_bda_ptr);
-        else
-          bdcpy(p_bg_tck->remote_bda, dummy_bda);
+        p_bg_tck->remote_bda = remote_bda_ptr;
 
         p_cif_mask = &p_bg_tck->cif_mask;
 
@@ -549,15 +537,15 @@
  * Returns          true if success; false otherwise.
  *
  ******************************************************************************/
-bool bta_gattc_check_bg_conn(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
-                             uint8_t role) {
+bool bta_gattc_check_bg_conn(tBTA_GATTC_IF client_if,
+                             const RawAddress& remote_bda, uint8_t role) {
   tBTA_GATTC_BG_TCK* p_bg_tck = &bta_gattc_cb.bg_track[0];
   uint8_t i = 0;
   bool is_bg_conn = false;
 
   for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i++, p_bg_tck++) {
-    if (p_bg_tck->in_use && (bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 ||
-                             bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0)) {
+    if (p_bg_tck->in_use && (p_bg_tck->remote_bda == remote_bda ||
+                             p_bg_tck->remote_bda.IsEmpty())) {
       if (((p_bg_tck->cif_mask & (1 << (client_if - 1))) != 0) &&
           role == HCI_ROLE_MASTER)
         is_bg_conn = true;
@@ -575,7 +563,7 @@
  *
  ******************************************************************************/
 void bta_gattc_send_open_cback(tBTA_GATTC_RCB* p_clreg, tBTA_GATT_STATUS status,
-                               BD_ADDR remote_bda, uint16_t conn_id,
+                               const RawAddress& remote_bda, uint16_t conn_id,
                                tBTA_TRANSPORT transport, uint16_t mtu) {
   tBTA_GATTC cb_data;
 
@@ -587,7 +575,7 @@
     cb_data.open.conn_id = conn_id;
     cb_data.open.mtu = mtu;
     cb_data.open.transport = transport;
-    bdcpy(cb_data.open.remote_bda, remote_bda);
+    cb_data.open.remote_bda = remote_bda;
 
     (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
   }
@@ -601,7 +589,7 @@
  * Returns          pointer to the clcb
  *
  ******************************************************************************/
-tBTA_GATTC_CONN* bta_gattc_conn_alloc(BD_ADDR remote_bda) {
+tBTA_GATTC_CONN* bta_gattc_conn_alloc(const RawAddress& remote_bda) {
   uint8_t i_conn = 0;
   tBTA_GATTC_CONN* p_conn = &bta_gattc_cb.conn_track[0];
 
@@ -612,7 +600,7 @@
                        i_conn);
 #endif
       p_conn->in_use = true;
-      bdcpy(p_conn->remote_bda, remote_bda);
+      p_conn->remote_bda = remote_bda;
       return p_conn;
     }
   }
@@ -628,12 +616,12 @@
  * Returns          pointer to the clcb
  *
  ******************************************************************************/
-tBTA_GATTC_CONN* bta_gattc_conn_find(BD_ADDR remote_bda) {
+tBTA_GATTC_CONN* bta_gattc_conn_find(const RawAddress& remote_bda) {
   uint8_t i_conn = 0;
   tBTA_GATTC_CONN* p_conn = &bta_gattc_cb.conn_track[0];
 
   for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn++) {
-    if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0) {
+    if (p_conn->in_use && remote_bda == p_conn->remote_bda) {
 #if (BTA_GATT_DEBUG == TRUE)
       APPL_TRACE_DEBUG("bta_gattc_conn_find: found conn_track[%d] matched",
                        i_conn);
@@ -653,7 +641,7 @@
  * Returns          pointer to the clcb
  *
  ******************************************************************************/
-tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(BD_ADDR remote_bda) {
+tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(const RawAddress& remote_bda) {
   tBTA_GATTC_CONN* p_conn = bta_gattc_conn_find(remote_bda);
 
   if (p_conn == NULL) {
@@ -671,12 +659,12 @@
  * Returns          pointer to the clcb
  *
  ******************************************************************************/
-bool bta_gattc_conn_dealloc(BD_ADDR remote_bda) {
+bool bta_gattc_conn_dealloc(const RawAddress& remote_bda) {
   tBTA_GATTC_CONN* p_conn = bta_gattc_conn_find(remote_bda);
 
   if (p_conn != NULL) {
     p_conn->in_use = false;
-    memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
+    p_conn->remote_bda = RawAddress::kEmpty;
     return true;
   }
   return false;
diff --git a/bta/gatt/bta_gatts_act.cc b/bta/gatt/bta_gatts_act.cc
index 15b48db..b328093 100644
--- a/bta/gatt/bta_gatts_act.cc
+++ b/bta/gatt/bta_gatts_act.cc
@@ -25,6 +25,7 @@
 
 #include "bt_target.h"
 
+#include <base/logging.h>
 #include <string.h>
 #include "bt_common.h"
 #include "bta_gatts_co.h"
@@ -41,7 +42,7 @@
                                        tGATTS_SRV_CHG_REQ* p_req,
                                        tGATTS_SRV_CHG_RSP* p_rsp);
 
-static void bta_gatts_conn_cback(tGATT_IF gatt_if, BD_ADDR bda,
+static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bda,
                                  uint16_t conn_id, bool connected,
                                  tGATT_DISCONN_REASON reason,
                                  tGATT_TRANSPORT transport);
@@ -372,7 +373,7 @@
   tBTA_GATTS_RCB* p_rcb = NULL;
   tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
   tGATT_IF gatt_if;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_TRANSPORT transport;
   tBTA_GATTS cb_data;
 
@@ -493,7 +494,7 @@
   tBTA_GATTS_RCB* p_rcb;
   tBTA_GATT_STATUS status = BTA_GATT_ERROR;
   tGATT_IF gatt_if;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_GATT_TRANSPORT transport;
 
   if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda,
@@ -574,7 +575,7 @@
  * Returns          none.
  *
  ******************************************************************************/
-static void bta_gatts_conn_cback(tGATT_IF gatt_if, BD_ADDR bda,
+static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bdaddr,
                                  uint16_t conn_id, bool connected,
                                  tGATT_DISCONN_REASON reason,
                                  tGATT_TRANSPORT transport) {
@@ -585,11 +586,8 @@
   APPL_TRACE_DEBUG(
       "bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
       gatt_if, conn_id, connected, reason);
-  APPL_TRACE_DEBUG("bta_gatts_conn_cback  bda :%02x-%02x-%02x-%02x-%02x-%02x ",
-                   bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+  VLOG(1) << __func__ << "  bda :" << bdaddr;
 
-  bt_bdaddr_t bdaddr;
-  bdcpy(bdaddr.address, bda);
   if (connected)
     btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
   else
@@ -601,16 +599,16 @@
     /* there is no RM for GATT */
     if (transport == BTA_TRANSPORT_BR_EDR) {
       if (connected)
-        bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
+        bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bdaddr);
       else
-        bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
+        bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, bdaddr);
     }
 
     cb_data.conn.conn_id = conn_id;
     cb_data.conn.server_if = gatt_if;
     cb_data.conn.reason = reason;
     cb_data.conn.transport = transport;
-    memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
+    cb_data.conn.remote_bda = bdaddr;
     (*p_reg->p_cback)(evt, &cb_data);
   } else {
     APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found", gatt_if);
diff --git a/bta/gatt/bta_gatts_api.cc b/bta/gatt/bta_gatts_api.cc
index 556185d..7d45043 100644
--- a/bta/gatt/bta_gatts_api.cc
+++ b/bta/gatt/bta_gatts_api.cc
@@ -281,8 +281,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, bool is_direct,
-                    tBTA_GATT_TRANSPORT transport) {
+void BTA_GATTS_Open(tBTA_GATTS_IF server_if, const RawAddress& remote_bda,
+                    bool is_direct, tBTA_GATT_TRANSPORT transport) {
   tBTA_GATTS_API_OPEN* p_buf =
       (tBTA_GATTS_API_OPEN*)osi_malloc(sizeof(tBTA_GATTS_API_OPEN));
 
@@ -290,7 +290,7 @@
   p_buf->server_if = server_if;
   p_buf->is_direct = is_direct;
   p_buf->transport = transport;
-  memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
+  p_buf->remote_bda = remote_bda;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -309,7 +309,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda,
+void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, const RawAddress& remote_bda,
                           bool is_direct) {
   tBTA_GATTS_API_CANCEL_OPEN* p_buf = (tBTA_GATTS_API_CANCEL_OPEN*)osi_malloc(
       sizeof(tBTA_GATTS_API_CANCEL_OPEN));
@@ -317,7 +317,7 @@
   p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT;
   p_buf->server_if = server_if;
   p_buf->is_direct = is_direct;
-  memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
+  p_buf->remote_bda = remote_bda;
 
   bta_sys_sendmsg(p_buf);
 }
diff --git a/bta/gatt/bta_gatts_int.h b/bta/gatt/bta_gatts_int.h
index 91bd9fe..df5d706 100644
--- a/bta/gatt/bta_gatts_int.h
+++ b/bta/gatt/bta_gatts_int.h
@@ -99,7 +99,7 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_GATTS_IF server_if;
   bool is_direct;
   tBTA_GATT_TRANSPORT transport;
diff --git a/bta/hd/bta_hd_act.cc b/bta/hd/bta_hd_act.cc
index b061d29..b8cdb7d 100644
--- a/bta/hd/bta_hd_act.cc
+++ b/bta/hd/bta_hd_act.cc
@@ -39,8 +39,8 @@
 #include "log/log.h"
 #include "osi/include/osi.h"
 
-static void bta_hd_cback(BD_ADDR bd_addr, uint8_t event, uint32_t data,
-                         BT_HDR* pdata);
+static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event,
+                         uint32_t data, BT_HDR* pdata);
 
 static bool check_descriptor(uint8_t* data, uint16_t length,
                              bool* has_report_id) {
@@ -286,7 +286,7 @@
     return;
   }
 
-  bdcpy(cback_data.conn.bda, p_ctrl->addr);
+  cback_data.conn.bda = p_ctrl->addr;
   cback_data.conn.status = BTHD_CONN_STATE_CONNECTING;
 
   bta_hd_cb.p_cback(BTA_HD_CONN_STATE_EVT, &cback_data);
@@ -450,8 +450,8 @@
   HID_DevPlugDevice(p_cback->addr);
   bta_sys_conn_open(BTA_ID_HD, 1, p_cback->addr);
 
-  bdcpy(cback_data.conn.bda, p_cback->addr);
-  bdcpy(bta_hd_cb.bd_addr, p_cback->addr);
+  cback_data.conn.bda = p_cback->addr;
+  bta_hd_cb.bd_addr = p_cback->addr;
 
   bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data);
 }
@@ -480,8 +480,8 @@
     cback_event = BTA_HD_VC_UNPLUG_EVT;
   }
 
-  bdcpy(cback_data.conn.bda, p_cback->addr);
-  memset(bta_hd_cb.bd_addr, 0, sizeof(BD_ADDR));
+  cback_data.conn.bda = p_cback->addr;
+  bta_hd_cb.bd_addr = RawAddress::kEmpty;
 
   bta_hd_cb.p_cback(cback_event, &cback_data);
 }
@@ -657,8 +657,8 @@
 
   HID_DevUnplugDevice(p_cback->addr);
 
-  bdcpy(cback_data.conn.bda, p_cback->addr);
-  bdcpy(bta_hd_cb.bd_addr, p_cback->addr);
+  cback_data.conn.bda = p_cback->addr;
+  bta_hd_cb.bd_addr = p_cback->addr;
 
   (*bta_hd_cb.p_cback)(BTA_HD_VC_UNPLUG_EVT, &cback_data);
 }
@@ -707,8 +707,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_hd_cback(BD_ADDR bd_addr, uint8_t event, uint32_t data,
-                         BT_HDR* pdata) {
+static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event,
+                         uint32_t data, BT_HDR* pdata) {
   tBTA_HD_CBACK_DATA* p_buf = NULL;
   uint16_t sm_event = BTA_HD_INVALID_EVT;
 
@@ -756,7 +756,7 @@
       (p_buf = (tBTA_HD_CBACK_DATA*)osi_malloc(sizeof(tBTA_HD_CBACK_DATA) +
                                                sizeof(BT_HDR))) != NULL) {
     p_buf->hdr.event = sm_event;
-    bdcpy(p_buf->addr, bd_addr);
+    p_buf->addr = bd_addr;
     p_buf->data = data;
     p_buf->p_data = pdata;
 
diff --git a/bta/hd/bta_hd_api.cc b/bta/hd/bta_hd_api.cc
index 773348d..199bc7b 100644
--- a/bta/hd/bta_hd_api.cc
+++ b/bta/hd/bta_hd_api.cc
@@ -218,14 +218,14 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HdConnect(BD_ADDR addr) {
+extern void BTA_HdConnect(const RawAddress& addr) {
   APPL_TRACE_API("%s", __func__);
 
   tBTA_HD_DEVICE_CTRL* p_buf =
       (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL));
   p_buf->hdr.event = BTA_HD_API_CONNECT_EVT;
 
-  memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
+  p_buf->addr = addr;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -256,13 +256,13 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HdAddDevice(BD_ADDR addr) {
+extern void BTA_HdAddDevice(const RawAddress& addr) {
   APPL_TRACE_API("%s", __func__);
   tBTA_HD_DEVICE_CTRL* p_buf =
       (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL));
   p_buf->hdr.event = BTA_HD_API_ADD_DEVICE_EVT;
 
-  memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
+  p_buf->addr = addr;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -276,13 +276,13 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HdRemoveDevice(BD_ADDR addr) {
+extern void BTA_HdRemoveDevice(const RawAddress& addr) {
   APPL_TRACE_API("%s", __func__);
   tBTA_HD_DEVICE_CTRL* p_buf =
       (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL));
   p_buf->hdr.event = BTA_HD_API_REMOVE_DEVICE_EVT;
 
-  memcpy(p_buf->addr, addr, sizeof(BD_ADDR));
+  p_buf->addr = addr;
 
   bta_sys_sendmsg(p_buf);
 }
diff --git a/bta/hd/bta_hd_int.h b/bta/hd/bta_hd_int.h
index d024709..318e350 100644
--- a/bta/hd/bta_hd_int.h
+++ b/bta/hd/bta_hd_int.h
@@ -101,7 +101,7 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR addr;
+  RawAddress addr;
 } tBTA_HD_DEVICE_CTRL;
 
 typedef struct {
@@ -121,7 +121,7 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR addr;
+  RawAddress addr;
   uint32_t data;
   BT_HDR* p_data;
 } tBTA_HD_CBACK_DATA;
@@ -134,7 +134,7 @@
   uint32_t sdp_handle;
   uint8_t trace_level;
   uint8_t state;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   bool use_report_id;
   bool boot_mode;
   bool vc_unplug;
diff --git a/bta/hf_client/bta_hf_client_act.cc b/bta/hf_client/bta_hf_client_act.cc
index 6b82f13..b633bd0 100644
--- a/bta/hf_client/bta_hf_client_act.cc
+++ b/bta/hf_client/bta_hf_client_act.cc
@@ -98,17 +98,17 @@
 
   /* store parameters */
   if (p_data) {
-    bdcpy(client_cb->peer_addr, p_data->api_open.bd_addr);
+    client_cb->peer_addr = p_data->api_open.bd_addr;
     client_cb->cli_sec_mask = p_data->api_open.sec_mask;
   }
 
   /* Check if RFCOMM has any incoming connection to avoid collision. */
-  BD_ADDR pending_bd_addr;
+  RawAddress pending_bd_addr;
   if (PORT_IsOpening(pending_bd_addr)) {
     /* Let the incoming connection goes through.                        */
     /* Issue collision for now.                                         */
     /* We will decide what to do when we find incoming connection later.*/
-    bta_hf_client_collision_cback(0, BTA_ID_HS, 0, client_cb->peer_addr);
+    bta_hf_client_collision_cback(0, BTA_ID_HS, 0, &client_cb->peer_addr);
     return;
   }
 
@@ -166,7 +166,7 @@
   }
 
   uint16_t lcid;
-  BD_ADDR dev_addr;
+  RawAddress dev_addr;
   int status;
 
   /* set role */
@@ -185,7 +185,7 @@
   if (alarm_is_scheduled(client_cb->collision_timer)) {
     alarm_cancel(client_cb->collision_timer);
 
-    if (bdcmp(dev_addr, client_cb->peer_addr) == 0) {
+    if (dev_addr == client_cb->peer_addr) {
       /* If incoming and outgoing device are same, nothing more to do. */
       /* Outgoing conn will be aborted because we have successful incoming conn.
        */
@@ -195,7 +195,7 @@
     }
   }
 
-  bdcpy(client_cb->peer_addr, dev_addr);
+  client_cb->peer_addr = dev_addr;
 
   /* do service discovery to get features */
   bta_hf_client_do_disc(client_cb);
@@ -300,7 +300,7 @@
   /* call close cback */
   tBTA_HF_CLIENT evt;
   memset(&evt, 0, sizeof(evt));
-  bdcpy(evt.conn.bd_addr, client_cb->peer_addr);
+  evt.conn.bd_addr = client_cb->peer_addr;
 
   /* if not deregistering reopen server */
   if (bta_hf_client_cb_arr.deregister == false) {
@@ -313,7 +313,7 @@
   else {
     tBTA_HF_CLIENT evt;
     memset(&evt, 0, sizeof(evt));
-    bdcpy(evt.reg.bd_addr, client_cb->peer_addr);
+    evt.reg.bd_addr = client_cb->peer_addr;
     bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
   }
 }
@@ -454,7 +454,7 @@
     client_cb->svc_conn = true;
 
     /* call callback */
-    bdcpy(evt.conn.bd_addr, client_cb->peer_addr);
+    evt.conn.bd_addr = client_cb->peer_addr;
     evt.conn.peer_feat = client_cb->peer_features;
     evt.conn.chld_feat = client_cb->chld_features;
 
diff --git a/bta/hf_client/bta_hf_client_api.cc b/bta/hf_client/bta_hf_client_api.cc
index 7c90255..d1ec0b7 100644
--- a/bta/hf_client/bta_hf_client_api.cc
+++ b/bta/hf_client/bta_hf_client_api.cc
@@ -76,7 +76,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_HfClientOpen(BD_ADDR bd_addr, tBTA_SEC sec_mask, uint16_t* p_handle) {
+void BTA_HfClientOpen(const RawAddress& bd_addr, tBTA_SEC sec_mask,
+                      uint16_t* p_handle) {
   APPL_TRACE_DEBUG("%s", __func__);
   tBTA_HF_CLIENT_API_OPEN* p_buf =
       (tBTA_HF_CLIENT_API_OPEN*)osi_malloc(sizeof(tBTA_HF_CLIENT_API_OPEN));
@@ -88,7 +89,7 @@
 
   p_buf->hdr.event = BTA_HF_CLIENT_API_OPEN_EVT;
   p_buf->hdr.layer_specific = *p_handle;
-  bdcpy(p_buf->bd_addr, bd_addr);
+  p_buf->bd_addr = bd_addr;
   p_buf->sec_mask = sec_mask;
 
   bta_sys_sendmsg(p_buf);
diff --git a/bta/hf_client/bta_hf_client_at.cc b/bta/hf_client/bta_hf_client_at.cc
index 4076e1e..5d8493b 100644
--- a/bta/hf_client/bta_hf_client_at.cc
+++ b/bta/hf_client/bta_hf_client_at.cc
@@ -42,13 +42,6 @@
 #define BTA_HF_CLIENT_AT_HOLD_TIMEOUT 41
 
 /******************************************************************************
- *
- *          DATA TYPES AND CONTAINERS
- *
- ******************************************************************************/
-extern fixed_queue_t* btu_bta_alarm_queue;
-
-/******************************************************************************
  *       SUPPORTED EVENT MESSAGES
  ******************************************************************************/
 
@@ -164,9 +157,8 @@
 }
 
 static void bta_hf_client_start_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
-  alarm_set_on_queue(client_cb->at_cb.resp_timer, BTA_HF_CLIENT_AT_TIMEOUT,
-                     bta_hf_client_at_resp_timer_cback, (void*)client_cb,
-                     btu_bta_alarm_queue);
+  alarm_set_on_mloop(client_cb->at_cb.resp_timer, BTA_HF_CLIENT_AT_TIMEOUT,
+                     bta_hf_client_at_resp_timer_cback, (void*)client_cb);
 }
 
 static void bta_hf_client_stop_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
@@ -234,9 +226,8 @@
 
 static void bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
   APPL_TRACE_DEBUG("%s", __func__);
-  alarm_set_on_queue(client_cb->at_cb.hold_timer, BTA_HF_CLIENT_AT_HOLD_TIMEOUT,
-                     bta_hf_client_at_hold_timer_cback, (void*)client_cb,
-                     btu_bta_alarm_queue);
+  alarm_set_on_mloop(client_cb->at_cb.hold_timer, BTA_HF_CLIENT_AT_HOLD_TIMEOUT,
+                     bta_hf_client_at_hold_timer_cback, (void*)client_cb);
 }
 
 /******************************************************************************
@@ -573,7 +564,7 @@
   evt.ind.type = type;
   evt.ind.value = value;
 
-  bdcpy(evt.ind.bd_addr, client_cb->peer_addr);
+  evt.ind.bd_addr = client_cb->peer_addr;
   bta_hf_client_app_callback(BTA_HF_CLIENT_IND_EVT, &evt);
 }
 
@@ -594,7 +585,7 @@
 
   memset(&evt, 0, sizeof(evt));
 
-  bdcpy(evt.val.bd_addr, client_cb->peer_addr);
+  evt.val.bd_addr = client_cb->peer_addr;
   evt.val.value = value;
 
   bta_hf_client_app_callback(type, &evt);
@@ -618,7 +609,7 @@
   strlcpy(evt.operator_name.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
   evt.operator_name.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
 
-  bdcpy(evt.operator_name.bd_addr, client_cb->peer_addr);
+  evt.operator_name.bd_addr = client_cb->peer_addr;
   bta_hf_client_app_callback(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
 }
 
@@ -640,7 +631,7 @@
   strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
   evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
 
-  bdcpy(evt.number.bd_addr, client_cb->peer_addr);
+  evt.number.bd_addr = client_cb->peer_addr;
   bta_hf_client_app_callback(BTA_HF_CLIENT_CLIP_EVT, &evt);
 }
 
@@ -662,7 +653,7 @@
   strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
   evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
 
-  bdcpy(evt.number.bd_addr, client_cb->peer_addr);
+  evt.number.bd_addr = client_cb->peer_addr;
   bta_hf_client_app_callback(BTA_HF_CLIENT_CCWA_EVT, &evt);
 }
 
@@ -685,7 +676,7 @@
   evt.result.type = type;
   evt.result.cme = cme;
 
-  bdcpy(evt.result.bd_addr, client_cb->peer_addr);
+  evt.result.bd_addr = client_cb->peer_addr;
   bta_hf_client_app_callback(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
 }
 
@@ -717,7 +708,7 @@
     evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
   }
 
-  bdcpy(evt.clcc.bd_addr, client_cb->peer_addr);
+  evt.clcc.bd_addr = client_cb->peer_addr;
   bta_hf_client_app_callback(BTA_HF_CLIENT_CLCC_EVT, &evt);
 }
 
@@ -741,7 +732,7 @@
   strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
   evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
 
-  bdcpy(evt.cnum.bd_addr, client_cb->peer_addr);
+  evt.cnum.bd_addr = client_cb->peer_addr;
   bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
 }
 
@@ -763,7 +754,7 @@
   strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
   evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
 
-  bdcpy(evt.number.bd_addr, client_cb->peer_addr);
+  evt.number.bd_addr = client_cb->peer_addr;
   bta_hf_client_app_callback(BTA_HF_CLIENT_BINP_EVT, &evt);
 }
 
@@ -1933,11 +1924,6 @@
   buf = "AT+BCC\r";
 
   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCC, buf, strlen(buf));
-
-  // At this point we should also open up an incoming SCO connection
-  tBTA_HF_CLIENT_DATA p_data;
-  p_data.hdr.layer_specific = client_cb->handle;
-  bta_hf_client_sco_listen(&p_data);
 }
 
 void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) {
diff --git a/bta/hf_client/bta_hf_client_int.h b/bta/hf_client/bta_hf_client_int.h
index 6a03d45..9ff7fa1 100644
--- a/bta/hf_client/bta_hf_client_int.h
+++ b/bta/hf_client/bta_hf_client_int.h
@@ -105,7 +105,7 @@
 /* data type for BTA_HF_CLIENT_API_OPEN_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t* handle;
   tBTA_SEC sec_mask;
 } tBTA_HF_CLIENT_API_OPEN;
@@ -162,7 +162,7 @@
   // Fields useful for particular control block.
   uint8_t handle;               /* Handle of the control block to be
                                    used by upper layer */
-  BD_ADDR peer_addr;            /* peer bd address */
+  RawAddress peer_addr;         /* peer bd address */
   tSDP_DISCOVERY_DB* p_disc_db; /* pointer to discovery database */
   uint16_t conn_handle;         /* RFCOMM handle of connected service */
   tBTA_SEC cli_sec_mask;        /* client security mask */
@@ -205,19 +205,20 @@
 
 /* main functions */
 extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle);
-extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const BD_ADDR bd_addr);
+extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(
+    const RawAddress& bd_addr);
 extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle);
 extern tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle);
 extern bool bta_hf_client_hdl_event(BT_HDR* p_msg);
 extern void bta_hf_client_sm_execute(uint16_t event,
                                      tBTA_HF_CLIENT_DATA* p_data);
 extern void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error);
-extern bool bta_hf_client_allocate_handle(const BD_ADDR bd_addr,
+extern bool bta_hf_client_allocate_handle(const RawAddress& bd_addr,
                                           uint16_t* p_handle);
 extern void bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data);
 extern void bta_hf_client_collision_cback(tBTA_SYS_CONN_STATUS status,
                                           uint8_t id, uint8_t app_id,
-                                          BD_ADDR peer_addr);
+                                          const RawAddress* peer_addr);
 extern void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb);
 extern tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
                                             tBTA_SEC sec_mask,
diff --git a/bta/hf_client/bta_hf_client_main.cc b/bta/hf_client/bta_hf_client_main.cc
index 7c9293e..e52994c 100644
--- a/bta/hf_client/bta_hf_client_main.cc
+++ b/bta/hf_client/bta_hf_client_main.cc
@@ -17,6 +17,7 @@
  *
  ******************************************************************************/
 
+#include <base/logging.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -26,13 +27,10 @@
 #include "bta_hf_client_api.h"
 #include "bta_hf_client_int.h"
 #include "bta_sys.h"
-#include "btcore/include/bdaddr.h"
 #include "osi/include/osi.h"
 #include "osi/include/properties.h"
 #include "utl.h"
 
-extern fixed_queue_t* btu_bta_alarm_queue;
-
 static const char* bta_hf_client_evt_str(uint16_t event);
 static const char* bta_hf_client_state_str(uint8_t state);
 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle);
@@ -365,8 +363,8 @@
  ******************************************************************************/
 void bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,
                                    uint8_t id, UNUSED_ATTR uint8_t app_id,
-                                   BD_ADDR peer_addr) {
-  tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(peer_addr);
+                                   const RawAddress* peer_addr) {
+  tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(*peer_addr);
   if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) {
     if (id == BTA_ID_SYS) /* ACL collision */
     {
@@ -391,10 +389,9 @@
     // bta_hf_client_start_server();
 
     /* Start timer to handle connection opening restart */
-    alarm_set_on_queue(client_cb->collision_timer,
+    alarm_set_on_mloop(client_cb->collision_timer,
                        BTA_HF_CLIENT_COLLISION_TIMER_MS,
-                       bta_hf_client_collision_timer_cback, (void*)client_cb,
-                       btu_bta_alarm_queue);
+                       bta_hf_client_collision_timer_cback, (void*)client_cb);
   }
 }
 
@@ -482,19 +479,19 @@
  *
  * Description      Finds the control block by handle provided
  *
- *                  bda: BD_ADDR of the device to find the handle for.
+ *                  bda: address of the device to find the handle for.
  *                  Since there can only be one HF connection for a device
  *                  we should always find a unique block
  *
- * Returns          Control block corresponding to the BD_ADDR and NULL if
+ * Returns          Control block corresponding to the address and NULL if
  *                  none exists
  *
  ******************************************************************************/
-tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const BD_ADDR peer_addr) {
+tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const RawAddress& peer_addr) {
   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
     // Check if the associated index is allocated and that BD ADDR matches
     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
-    if (client_cb->is_allocated && !bdcmp(peer_addr, client_cb->peer_addr)) {
+    if (client_cb->is_allocated && peer_addr == client_cb->peer_addr) {
       return client_cb;
     } else {
       APPL_TRACE_WARNING("%s: bdaddr mismatch for handle %d alloc %d", __func__,
@@ -580,7 +577,8 @@
  * Returns          true if the creation of p_handle succeeded, false otherwise
  *
  ******************************************************************************/
-bool bta_hf_client_allocate_handle(const BD_ADDR bd_addr, uint16_t* p_handle) {
+bool bta_hf_client_allocate_handle(const RawAddress& bd_addr,
+                                   uint16_t* p_handle) {
   tBTA_HF_CLIENT_CB* existing_cb = bta_hf_client_find_cb_by_bda(bd_addr);
   if (existing_cb != NULL) {
     BTIF_TRACE_ERROR("%s: cannot allocate handle since BDADDR already exists",
@@ -605,7 +603,7 @@
                      client_cb->handle);
 
     client_cb->is_allocated = true;
-    bdcpy(client_cb->peer_addr, bd_addr);
+    client_cb->peer_addr = bd_addr;
     bta_hf_client_at_init(client_cb);
     return true;
   }
@@ -744,16 +742,11 @@
 
   /* If the state has changed then notify the app of the corresponding change */
   if (in_state != client_cb->state) {
-    APPL_TRACE_DEBUG(
-        "%s: notifying state change to %d -> %d "
-        "device %02x:%02x:%02x:%02x:%02x:%02x",
-        __func__, in_state, client_cb->state, client_cb->peer_addr[0],
-        client_cb->peer_addr[1], client_cb->peer_addr[2],
-        client_cb->peer_addr[3], client_cb->peer_addr[4],
-        client_cb->peer_addr[5]);
+    VLOG(1) << __func__ << ": notifying state change to " << in_state << " -> "
+            << client_cb->state << " device " << client_cb->peer_addr;
     tBTA_HF_CLIENT evt;
     memset(&evt, 0, sizeof(evt));
-    bdcpy(evt.bd_addr, client_cb->peer_addr);
+    evt.bd_addr = client_cb->peer_addr;
     if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
       bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);
     } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
@@ -769,19 +762,18 @@
     client_cb->is_allocated = false;
   }
 
-  APPL_TRACE_EVENT(
-      "%s: device %02x:%02x:%02x:%02x:%02x:%02x "
-      "state change: [%s] -> [%s] after Event [%s]",
-      __func__, client_cb->peer_addr[0], client_cb->peer_addr[1],
-      client_cb->peer_addr[2], client_cb->peer_addr[3], client_cb->peer_addr[4],
-      client_cb->peer_addr[5], bta_hf_client_state_str(in_state),
-      bta_hf_client_state_str(client_cb->state),
-      bta_hf_client_evt_str(in_event));
+  VLOG(2) << __func__ << ": device " << client_cb->peer_addr
+          << "state change: [" << bta_hf_client_state_str(in_state) << "] -> ["
+          << bta_hf_client_state_str(client_cb->state) << "] after Event ["
+          << bta_hf_client_evt_str(in_event) << "]";
 }
 
 static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) {
   client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
 
+  tBTA_HF_CLIENT_DATA p_data;
+  p_data.hdr.layer_specific = client_cb->handle;
+  bta_hf_client_sco_listen(&p_data);
   bta_hf_client_send_at_bia(client_cb);
   bta_hf_client_send_at_ccwa(client_cb, true);
   bta_hf_client_send_at_cmee(client_cb, true);
@@ -938,11 +930,10 @@
 
     dprintf(fd, "  Control block #%d\n", i + 1);
 
+    uint8_t* a = client_cb->peer_addr.address;
     // Device name
-    dprintf(fd, "    Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n",
-            client_cb->peer_addr[0], client_cb->peer_addr[1],
-            client_cb->peer_addr[2], client_cb->peer_addr[3],
-            client_cb->peer_addr[4], client_cb->peer_addr[5]);
+    dprintf(fd, "    Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n", a[0], a[1],
+            a[2], a[3], a[4], a[5]);
 
     // State machine state
     dprintf(fd, "    State Machine State: %s\n",
diff --git a/bta/hf_client/bta_hf_client_rfc.cc b/bta/hf_client/bta_hf_client_rfc.cc
index 7a0d356..3e2aa59 100644
--- a/bta/hf_client/bta_hf_client_rfc.cc
+++ b/bta/hf_client/bta_hf_client_rfc.cc
@@ -24,6 +24,7 @@
  *
  ******************************************************************************/
 
+#include <base/logging.h>
 #include <string.h>
 
 #include "bt_utils.h"
@@ -97,7 +98,7 @@
       APPL_TRACE_DEBUG("%s: allocating a new CB for incoming connection",
                        __func__);
       // Find the BDADDR of the peer device
-      BD_ADDR peer_addr;
+      RawAddress peer_addr;
       uint16_t lcid;
       PORT_CheckConnection(port_handle, peer_addr, &lcid);
 
@@ -127,12 +128,8 @@
     }
   } else if (client_cb != NULL &&
              port_handle == client_cb->conn_handle) { /* code != PORT_SUC */
-    APPL_TRACE_ERROR(
-        "%s: closing port handle %d "
-        "dev %02x:%02x:%02x:%02x:%02x:%02x",
-        __func__, port_handle, client_cb->peer_addr[0], client_cb->peer_addr[1],
-        client_cb->peer_addr[2], client_cb->peer_addr[3],
-        client_cb->peer_addr[4], client_cb->peer_addr[5]);
+    LOG(ERROR) << __func__ << ": closing port handle " << port_handle << "dev "
+               << client_cb->peer_addr;
 
     RFCOMM_RemoveServer(port_handle);
     p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT;
@@ -182,8 +179,8 @@
 
   port_status = RFCOMM_CreateConnection(
       UUID_SERVCLASS_HF_HANDSFREE, bta_hf_client_cb_arr.scn, true,
-      BTA_HF_CLIENT_MTU, (uint8_t*)bd_addr_any,
-      &(bta_hf_client_cb_arr.serv_handle), bta_hf_client_mgmt_cback);
+      BTA_HF_CLIENT_MTU, RawAddress::kAny, &(bta_hf_client_cb_arr.serv_handle),
+      bta_hf_client_mgmt_cback);
 
   APPL_TRACE_DEBUG("%s: started rfcomm server with handle %d", __func__,
                    bta_hf_client_cb_arr.serv_handle);
diff --git a/bta/hf_client/bta_hf_client_sco.cc b/bta/hf_client/bta_hf_client_sco.cc
index e792c3f..6181ba1 100644
--- a/bta/hf_client/bta_hf_client_sco.cc
+++ b/bta/hf_client/bta_hf_client_sco.cc
@@ -34,8 +34,8 @@
   BTA_HF_CLIENT_SCO_OPEN_E,       /* open request */
   BTA_HF_CLIENT_SCO_CLOSE_E,      /* close request */
   BTA_HF_CLIENT_SCO_SHUTDOWN_E,   /* shutdown request */
-  BTA_HF_CLIENT_SCO_CONN_OPEN_E,  /* sco opened */
-  BTA_HF_CLIENT_SCO_CONN_CLOSE_E, /* sco closed */
+  BTA_HF_CLIENT_SCO_CONN_OPEN_E,  /* SCO opened */
+  BTA_HF_CLIENT_SCO_CONN_CLOSE_E, /* SCO closed */
 };
 
 /*******************************************************************************
@@ -62,7 +62,7 @@
     if (status == BTM_CMD_STARTED) {
       removed_started = true;
     }
-    /* If no connection reset the sco handle */
+    /* If no connection reset the SCO handle */
     else if ((status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR)) {
       client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
     }
@@ -84,7 +84,7 @@
   tBTA_HF_CLIENT evt;
 
   memset(&evt, 0, sizeof(evt));
-  bdcpy(evt.bd_addr, client_cb->peer_addr);
+  evt.bd_addr = client_cb->peer_addr;
 
   /* call app cback */
   bta_hf_client_app_callback(event, (tBTA_HF_CLIENT*)&evt);
@@ -111,10 +111,12 @@
     if (p_data->link_type == BTM_LINK_TYPE_SCO) {
       resp = esco_parameters_for_codec(ESCO_CODEC_CVSD);
     } else {
-      if (client_cb->negotiated_codec == BTA_AG_CODEC_CVSD)
-        resp = esco_parameters_for_codec(ESCO_CODEC_CVSD);
-      if (client_cb->negotiated_codec == BTA_AG_CODEC_MSBC)
+      if (client_cb->negotiated_codec == BTA_AG_CODEC_MSBC) {
         resp = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1);
+      } else {
+        // default codec
+        resp = esco_parameters_for_codec(ESCO_CODEC_CVSD);
+      }
     }
 
     /* tell sys to stop av if any */
@@ -143,7 +145,7 @@
   tBTA_HF_CLIENT_CB* client_cb =
       bta_hf_client_find_cb_by_sco_handle(p_data->conn_evt.sco_inx);
   if (client_cb == NULL) {
-    APPL_TRACE_ERROR("%s: wrong sco handle to control block %d", __func__,
+    APPL_TRACE_ERROR("%s: wrong SCO handle to control block %d", __func__,
                      p_data->conn_evt.sco_inx);
     return;
   }
@@ -221,11 +223,10 @@
 static void bta_hf_client_sco_create(tBTA_HF_CLIENT_CB* client_cb,
                                      bool is_orig) {
   tBTM_STATUS status;
-  uint8_t* p_bd_addr = NULL;
 
   APPL_TRACE_DEBUG("%s: %d", __func__, is_orig);
 
-  /* Make sure this sco handle is not already in use */
+  /* Make sure this SCO handle is not already in use */
   if (client_cb->sco_idx != BTM_INVALID_SCO_INDEX) {
     APPL_TRACE_WARNING("%s: Index 0x%04x already in use", __func__,
                        client_cb->sco_idx);
@@ -241,9 +242,7 @@
     bta_sys_sco_use(BTA_ID_HS, 1, client_cb->peer_addr);
   }
 
-  p_bd_addr = client_cb->peer_addr;
-
-  status = BTM_CreateSco(p_bd_addr, is_orig, params.packet_types,
+  status = BTM_CreateSco(&client_cb->peer_addr, is_orig, params.packet_types,
                          &client_cb->sco_idx, bta_hf_client_sco_conn_cback,
                          bta_hf_client_sco_disc_cback);
   if (status == BTM_CMD_STARTED && !is_orig) {
@@ -278,7 +277,7 @@
         // For WBS we only listen to SCO requests. Even for outgoing SCO
         // requests we first do a AT+BCC and wait for remote to initiate SCO
         case BTA_HF_CLIENT_SCO_LISTEN_E:
-          /* create sco listen connection */
+          /* create SCO listen connection */
           bta_hf_client_sco_create(client_cb, false);
           client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
           break;
@@ -289,7 +288,7 @@
           /* remove listening connection */
           bta_hf_client_sco_remove(client_cb);
 
-          /* create sco connection to peer */
+          /* create SCO connection to peer */
           bta_hf_client_sco_create(client_cb, true);
           client_cb->sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
           break;
@@ -303,11 +302,15 @@
 
     case BTA_HF_CLIENT_SCO_LISTEN_ST:
       switch (event) {
+        case BTA_HF_CLIENT_SCO_LISTEN_E:
+          /* create SCO listen connection */
+          bta_hf_client_sco_create(client_cb, false);
+
         case BTA_HF_CLIENT_SCO_OPEN_E:
           /* remove listening connection */
           bta_hf_client_sco_remove(client_cb);
 
-          /* create sco connection to peer */
+          /* create SCO connection to peer */
           bta_hf_client_sco_create(client_cb, true);
           client_cb->sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
           break;
@@ -321,7 +324,7 @@
           break;
 
         case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
-          /* sco failed; create sco listen connection */
+          /* SCO failed; create SCO listen connection */
           bta_hf_client_sco_create(client_cb, false);
           client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
           break;
@@ -349,9 +352,9 @@
           break;
 
         case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
-          /* sco failed; create sco listen connection */
-          // bta_hf_client_sco_create(client_cb, false);
-          client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
+          /* SCO failed; create SCO listen connection */
+          bta_hf_client_sco_create(client_cb, false);
+          client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
           break;
 
         default:
@@ -372,14 +375,14 @@
           break;
 
         case BTA_HF_CLIENT_SCO_CONN_OPEN_E:
-          /* close sco connection */
+          /* close SCO connection */
           bta_hf_client_sco_remove(client_cb);
 
           client_cb->sco_state = BTA_HF_CLIENT_SCO_CLOSING_ST;
           break;
 
         case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
-          /* sco failed; create sco listen connection */
+          /* SCO failed; create SCO listen connection */
 
           client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
           break;
@@ -407,8 +410,9 @@
           break;
 
         case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
-          /* peer closed sco */
-          client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
+          /* peer closed SCO */
+          bta_hf_client_sco_create(client_cb, false);
+          client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
           break;
 
         default:
@@ -429,8 +433,9 @@
           break;
 
         case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
-          /* peer closed sco; create sco listen connection */
-          client_cb->sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
+          /* peer closed sco; create SCO listen connection */
+          bta_hf_client_sco_create(client_cb, false);
+          client_cb->sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
           break;
 
         default:
@@ -451,7 +456,7 @@
           break;
 
         case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
-          /* open sco connection */
+          /* open SCO connection */
           bta_hf_client_sco_create(client_cb, true);
           client_cb->sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
           break;
@@ -466,7 +471,7 @@
     case BTA_HF_CLIENT_SCO_SHUTTING_ST:
       switch (event) {
         case BTA_HF_CLIENT_SCO_CONN_OPEN_E:
-          /* close sco connection; wait for conn close event */
+          /* close SCO connection; wait for conn close event */
           bta_hf_client_sco_remove(client_cb);
           break;
 
diff --git a/bta/hf_client/bta_hf_client_sdp.cc b/bta/hf_client/bta_hf_client_sdp.cc
index 36f5436..475ce16 100644
--- a/bta/hf_client/bta_hf_client_sdp.cc
+++ b/bta/hf_client/bta_hf_client_sdp.cc
@@ -1,21 +1,21 @@
 /******************************************************************************
- *
- *  Copyright (c) 2014 The Android Open Source Project
- *  Copyright (C) 2003-2012 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
+*
+*  Copyright (c) 2014 The Android Open Source Project
+*  Copyright (C) 2003-2012 Broadcom Corporation
+*
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at:
+*
+*  http://www.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*
+******************************************************************************/
 
 /******************************************************************************
  *
diff --git a/bta/hh/bta_hh_act.cc b/bta/hh/bta_hh_act.cc
index f7d9525..f0c0230 100644
--- a/bta/hh/bta_hh_act.cc
+++ b/bta/hh/bta_hh_act.cc
@@ -44,8 +44,8 @@
 /*****************************************************************************
  *  Local Function prototypes
  ****************************************************************************/
-static void bta_hh_cback(uint8_t dev_handle, BD_ADDR addr, uint8_t event,
-                         uint32_t data, BT_HDR* pdata);
+static void bta_hh_cback(uint8_t dev_handle, const RawAddress& addr,
+                         uint8_t event, uint32_t data, BT_HDR* pdata);
 static tBTA_HH_STATUS bta_hh_get_trans_status(uint32_t result);
 
 #if (BTA_HH_DEBUG == TRUE)
@@ -183,10 +183,8 @@
     if (p_cb->sec_mask) attr_mask |= HID_SEC_REQUIRED;
 
 #if (BTA_HH_DEBUG == TRUE)
-    APPL_TRACE_EVENT(
-        "bta_hh_sdp_cback: p_cb: %d result 0x%02x, \
-                            attr_mask 0x%02x, handle %x",
-        p_cb, result, attr_mask, p_cb->hid_handle);
+    APPL_TRACE_EVENT("%s: p_cb: %d result 0x%02x, attr_mask 0x%02x, handle %x",
+                     __func__, p_cb, result, attr_mask, p_cb->hid_handle);
 #endif
 
     /* check to see type of device is supported , and should not been added
@@ -246,17 +244,15 @@
   tSDP_DI_GET_RECORD di_rec;
   tHID_STATUS ret;
 #if (BTA_HH_DEBUG == TRUE)
-  APPL_TRACE_EVENT("bta_hh_di_sdp_cback: p_cb: %d result 0x%02x", p_cb, result);
+  APPL_TRACE_EVENT("%s: p_cb: %d result 0x%02x", __func__, p_cb, result);
 #endif
 
   /* if DI record does not exist on remote device, vendor_id in
-   * tBTA_HH_DEV_DSCP_INFO will be
-       * set to 0xffff and we will allow the connection to go through. Spec
-   * mandates that DI
-       * record be set, but many HID devices do not set this. So for IOP
-   * purposes, we allow the
-       * connection to go through and update the DI record to invalid DI
-   * entry.*/
+   * tBTA_HH_DEV_DSCP_INFO will be set to 0xffff and we will allow the
+   * connection to go through. Spec mandates that DI record be set, but many
+   * HID devices do not set this. So for IOP purposes, we allow the connection
+   * to go through and update the DI record to invalid DI entry.
+   */
   if (((result == SDP_SUCCESS) || (result == SDP_NO_RECS_MATCH)) &&
       (p_cb != NULL)) {
     if (result == SDP_SUCCESS &&
@@ -278,9 +274,8 @@
       status = BTA_HH_OK;
     } else {
 #if (BTA_HH_DEBUG == TRUE)
-      APPL_TRACE_DEBUG(
-          "bta_hh_di_sdp_cback:  HID_HostGetSDPRecord failed: Status 0x%2x",
-          ret);
+      APPL_TRACE_DEBUG("%s:  HID_HostGetSDPRecord failed: Status 0x%2x",
+                       __func__, ret);
 #endif
     }
   }
@@ -324,7 +319,7 @@
   if (p_cb->app_id) {
     status = BTA_HH_OK;
 #if (BTA_HH_DEBUG == TRUE)
-    APPL_TRACE_DEBUG("bta_hh_start_sdp:: skip SDP for known devices");
+    APPL_TRACE_DEBUG("%s: skip SDP for known devices", __func__);
 #endif
     if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
       if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) {
@@ -352,10 +347,8 @@
                        p_bta_hh_cfg->sdp_db_size,
                        bta_hh_di_sdp_cback) != SDP_SUCCESS) {
 #if (BTA_HH_DEBUG == TRUE)
-      APPL_TRACE_DEBUG(
-          "bta_hh_start_sdp:  SDP_DiDiscover failed: \
-                    Status 0x%2X",
-          status);
+      APPL_TRACE_DEBUG("%s:  SDP_DiDiscover failed: Status 0x%2X", __func__,
+                       status);
 #endif
       status = BTA_HH_ERR_SDP;
       osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
@@ -395,13 +388,13 @@
   tBTA_HH_STATUS status = p_data->status;
 
 #if (BTA_HH_DEBUG == TRUE)
-  APPL_TRACE_DEBUG("bta_hh_sdp_cmpl:  status 0x%2X", p_data->status);
+  APPL_TRACE_DEBUG("%s:  status 0x%2X", __func__, p_data->status);
 #endif
 
   /* initialize call back data */
   memset((void*)&conn_dat, 0, sizeof(tBTA_HH_CONN));
   conn_dat.handle = p_cb->hid_handle;
-  bdcpy(conn_dat.bda, p_cb->addr);
+  conn_dat.bda = p_cb->addr;
 
   /* if SDP compl success */
   if (status == BTA_HH_OK) {
@@ -439,12 +432,13 @@
 
   if (status != BTA_HH_OK) {
     /* Check if this was incoming connection request  from an unknown device
-       **and connection failed due to missing HID Device SDP UUID
-       **In above condition, disconnect the link as well as remove the
-       **device from list of HID devices*/
+     * and connection failed due to missing HID Device SDP UUID
+     * In above condition, disconnect the link as well as remove the
+     * device from list of HID devices
+     */
     if ((status == BTA_HH_ERR_SDP) && (p_cb->incoming_conn) &&
         (p_cb->app_id == 0)) {
-      APPL_TRACE_DEBUG("bta_hh_sdp_cmpl:SDP failed for  incoming conn :hndl %d",
+      APPL_TRACE_DEBUG("%s: SDP failed for  incoming conn :hndl %d", __func__,
                        p_cb->incoming_hid_handle);
       HID_HostRemoveDev(p_cb->incoming_hid_handle);
     }
@@ -515,7 +509,7 @@
 
   memset((void*)&conn, 0, sizeof(tBTA_HH_CONN));
   conn.handle = dev_handle;
-  bdcpy(conn.bda, p_cb->addr);
+  conn.bda = p_cb->addr;
 
   /* increase connection number */
   bta_hh_cb.cnt_num++;
@@ -574,7 +568,7 @@
       p_data ? (uint8_t)p_data->hid_cback.hdr.layer_specific : p_cb->hid_handle;
 
 #if (BTA_HH_DEBUG == TRUE)
-  APPL_TRACE_EVENT("bta_hh_open_act:  Device[%d] connected", dev_handle);
+  APPL_TRACE_EVENT("%s:  Device[%d] connected", __func__, dev_handle);
 #endif
 
   /* SDP has been done */
@@ -582,14 +576,15 @@
     bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, p_data);
   } else
   /*  app_id == 0 indicates an incoming conenction request arrives without SDP
-      performed, do it first */
+   *  performed, do it first
+   */
   {
     p_cb->incoming_conn = true;
     /* store the handle here in case sdp fails - need to disconnect */
     p_cb->incoming_hid_handle = dev_handle;
 
     memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN));
-    bdcpy(conn_data.bd_addr, p_cb->addr);
+    conn_data.bd_addr = p_cb->addr;
     bta_hh_start_sdp(p_cb, (tBTA_HH_DATA*)&conn_data);
   }
 
@@ -670,7 +665,7 @@
     case BTA_HH_OPEN_EVT:
       conn.status = p_data->hid_cback.data ? BTA_HH_ERR_PROTO : BTA_HH_OK;
       conn.handle = p_cb->hid_handle;
-      bdcpy(conn.bda, p_cb->addr);
+      conn.bda = p_cb->addr;
       (*bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH*)&conn);
 #if (BTA_HH_DEBUG == TRUE)
       bta_hh_trace_dev_db();
@@ -779,7 +774,7 @@
   conn_dat.handle = p_cb->hid_handle;
   conn_dat.status =
       (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
-  bdcpy(conn_dat.bda, p_cb->addr);
+  conn_dat.bda = p_cb->addr;
   HID_HostCloseDev(p_cb->hid_handle);
 
   /* Report OPEN fail event */
@@ -835,7 +830,7 @@
     conn_dat.handle = p_cb->hid_handle;
     conn_dat.status =
         (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR;
-    bdcpy(conn_dat.bda, p_cb->addr);
+    conn_dat.bda = p_cb->addr;
     HID_HostCloseDev(p_cb->hid_handle);
 
     /* Report OPEN fail event */
@@ -922,7 +917,7 @@
 
   switch (p_dev_info->sub_event) {
     case BTA_HH_ADD_DEV_EVT: /* add a device */
-      bdcpy(dev_info.bda, p_dev_info->bda);
+      dev_info.bda = p_dev_info->bda;
       /* initialize callback data */
       if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
 #if (BTA_HH_LE_INCLUDED == TRUE)
@@ -970,7 +965,7 @@
       break;
     case BTA_HH_RMV_DEV_EVT: /* remove device */
       dev_info.handle = (uint8_t)p_dev_info->hdr.layer_specific;
-      bdcpy(dev_info.bda, p_cb->addr);
+      dev_info.bda = p_cb->addr;
 
 #if (BTA_HH_LE_INCLUDED == TRUE)
       if (p_cb->is_le_device) {
@@ -1067,7 +1062,7 @@
         /* currently not expected */
         case HID_TRANS_DATAC:
         default:
-          APPL_TRACE_DEBUG("bta_hh_write_dev_act:: cmd type = %d",
+          APPL_TRACE_DEBUG("%s: cmd type = %d", __func__,
                            p_data->api_sndcmd.t_type);
           break;
       }
@@ -1100,13 +1095,13 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_hh_cback(uint8_t dev_handle, BD_ADDR addr, uint8_t event,
-                         uint32_t data, BT_HDR* pdata) {
+static void bta_hh_cback(uint8_t dev_handle, const RawAddress& addr,
+                         uint8_t event, uint32_t data, BT_HDR* pdata) {
   uint16_t sm_event = BTA_HH_INVALID_EVT;
   uint8_t xx = 0;
 
 #if (BTA_HH_DEBUG == TRUE)
-  APPL_TRACE_DEBUG("bta_hh_cback::HID_event [%s]",
+  APPL_TRACE_DEBUG("%s::HID_event [%s]", __func__,
                    bta_hh_hid_event_name(event));
 #endif
 
@@ -1149,7 +1144,7 @@
     p_buf->hdr.event = sm_event;
     p_buf->hdr.layer_specific = (uint16_t)dev_handle;
     p_buf->data = data;
-    bdcpy(p_buf->addr, addr);
+    p_buf->addr = addr;
     p_buf->p_data = pdata;
 
     bta_sys_sendmsg(p_buf);
diff --git a/bta/hh/bta_hh_api.cc b/bta/hh/bta_hh_api.cc
index be30ccb..164633c 100644
--- a/bta/hh/bta_hh_api.cc
+++ b/bta/hh/bta_hh_api.cc
@@ -122,7 +122,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, tBTA_SEC sec_mask) {
+void BTA_HhOpen(const RawAddress& dev_bda, tBTA_HH_PROTO_MODE mode,
+                tBTA_SEC sec_mask) {
   tBTA_HH_API_CONN* p_buf =
       (tBTA_HH_API_CONN*)osi_calloc(sizeof(tBTA_HH_API_CONN));
 
@@ -130,7 +131,7 @@
   p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
   p_buf->sec_mask = sec_mask;
   p_buf->mode = mode;
-  bdcpy(p_buf->bd_addr, dev_bda);
+  p_buf->bd_addr = dev_bda;
 
   bta_sys_sendmsg((void*)p_buf);
 }
@@ -271,7 +272,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_HhSendData(uint8_t dev_handle, UNUSED_ATTR BD_ADDR dev_bda,
+void BTA_HhSendData(uint8_t dev_handle, UNUSED_ATTR const RawAddress& dev_bda,
                     BT_HDR* p_data) {
 #if (BTA_HH_LE_INCLUDED == TRUE)
   if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT) {
@@ -315,8 +316,9 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, uint8_t sub_class,
-                  uint8_t app_id, tBTA_HH_DEV_DSCP_INFO dscp_info) {
+void BTA_HhAddDev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask,
+                  uint8_t sub_class, uint8_t app_id,
+                  tBTA_HH_DEV_DSCP_INFO dscp_info) {
   size_t len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len;
   tBTA_HH_MAINT_DEV* p_buf = (tBTA_HH_MAINT_DEV*)osi_calloc(len);
 
@@ -327,7 +329,7 @@
   p_buf->attr_mask = (uint16_t)attr_mask;
   p_buf->sub_class = sub_class;
   p_buf->app_id = app_id;
-  bdcpy(p_buf->bda, bda);
+  p_buf->bda = bda;
 
   memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO));
   if (dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list) {
diff --git a/bta/hh/bta_hh_int.h b/bta/hh/bta_hh_int.h
index ec5bcf4..128a078 100644
--- a/bta/hh/bta_hh_int.h
+++ b/bta/hh/bta_hh_int.h
@@ -115,7 +115,7 @@
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t sec_mask;
   tBTA_HH_PROTO_MODE mode;
 } tBTA_HH_API_CONN;
@@ -123,14 +123,14 @@
 /* internal event data from BTE HID callback */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR addr;
+  RawAddress addr;
   uint32_t data;
   BT_HDR* p_data;
 } tBTA_HH_CBACK_DATA;
 
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bda;
+  RawAddress bda;
   uint16_t attr_mask;
   uint16_t sub_event;
   uint8_t sub_class;
@@ -217,7 +217,7 @@
 /* device control block */
 typedef struct {
   tBTA_HH_DEV_DSCP_INFO dscp_info; /* report descriptor and DI information */
-  BD_ADDR addr;                    /* BD-Addr of the HID device */
+  RawAddress addr;                 /* BD-Addr of the HID device */
   uint16_t attr_mask;              /* attribute mask */
   uint16_t w4_evt;                 /* W4_handshake event name */
   uint8_t index;                   /* index number referenced to handle index */
@@ -323,7 +323,7 @@
 extern void bta_hh_open_failure(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data);
 
 /* utility functions */
-extern uint8_t bta_hh_find_cb(BD_ADDR bda);
+extern uint8_t bta_hh_find_cb(const RawAddress& bda);
 extern void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT* p_kb_data,
                                    uint8_t* p_report, uint16_t report_len);
 extern void bta_hh_parse_mice_rpt(tBTA_HH_BOOT_RPT* p_kb_data,
@@ -348,7 +348,7 @@
 extern void bta_hh_api_disable(void);
 extern void bta_hh_disc_cmpl(void);
 
-extern tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr,
+extern tBTA_HH_STATUS bta_hh_read_ssr_param(const RawAddress& bd_addr,
                                             uint16_t* p_max_ssr_lat,
                                             uint16_t* p_min_ssr_tout);
 
@@ -356,8 +356,10 @@
 extern void bta_hh_le_enable(void);
 extern bool bta_hh_le_is_hh_gatt_if(tBTA_GATTC_IF client_if);
 extern void bta_hh_le_deregister(void);
-extern bool bta_hh_is_le_device(tBTA_HH_DEV_CB* p_cb, BD_ADDR remote_bda);
-extern void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, BD_ADDR remote_bda);
+extern bool bta_hh_is_le_device(tBTA_HH_DEV_CB* p_cb,
+                                const RawAddress& remote_bda);
+extern void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb,
+                                const RawAddress& remote_bda);
 extern void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB* p_cb);
 extern void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB* p_cb);
 extern void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB* p_cb, tBTA_HH_DATA* p_data);
diff --git a/bta/hh/bta_hh_le.cc b/bta/hh/bta_hh_le.cc
index da503ac..b4827a2 100644
--- a/bta/hh/bta_hh_le.cc
+++ b/bta/hh/bta_hh_le.cc
@@ -378,7 +378,7 @@
  * Parameters:
  *
  ******************************************************************************/
-bool bta_hh_is_le_device(tBTA_HH_DEV_CB* p_cb, BD_ADDR remote_bda) {
+bool bta_hh_is_le_device(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) {
   p_cb->is_le_device = BTM_UseLeLink(remote_bda);
 
   return p_cb->is_le_device;
@@ -393,10 +393,10 @@
  * Parameters:
  *
  ******************************************************************************/
-void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, BD_ADDR remote_bda) {
+void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) {
   /* update cb_index[] map */
   p_cb->hid_handle = BTA_HH_GET_LE_DEV_HDL(p_cb->index);
-  memcpy(p_cb->addr, remote_bda, BD_ADDR_LEN);
+  p_cb->addr = remote_bda;
   bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
   p_cb->in_use = true;
 
@@ -429,13 +429,12 @@
  * Description      Utility function find a device control block by BD address.
  *
  ******************************************************************************/
-tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda(BD_ADDR bda) {
+tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda(const RawAddress& bda) {
   uint8_t i;
   tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0];
 
   for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) {
-    if (p_dev_cb->in_use && memcmp(p_dev_cb->addr, bda, BD_ADDR_LEN) == 0)
-      return p_dev_cb;
+    if (p_dev_cb->in_use && p_dev_cb->addr == bda) return p_dev_cb;
   }
   return NULL;
 }
@@ -1037,7 +1036,7 @@
  * Parameters:
  *
  ******************************************************************************/
-void bta_hh_le_dis_cback(BD_ADDR addr, tDIS_VALUE* p_dis_value) {
+void bta_hh_le_dis_cback(const RawAddress& addr, tDIS_VALUE* p_dis_value) {
   tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(addr);
 
   if (p_cb == NULL || p_dis_value == NULL) {
@@ -1101,10 +1100,10 @@
  * Returns          None
  *
  ******************************************************************************/
-void bta_hh_le_encrypt_cback(BD_ADDR bd_addr,
+void bta_hh_le_encrypt_cback(const RawAddress* bd_addr,
                              UNUSED_ATTR tBTA_GATT_TRANSPORT transport,
                              UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) {
-  uint8_t idx = bta_hh_find_cb(bd_addr);
+  uint8_t idx = bta_hh_find_cb(*bd_addr);
   tBTA_HH_DEV_CB* p_dev_cb;
 
   if (idx != BTA_HH_IDX_INVALID)
@@ -1275,7 +1274,7 @@
   /* if received invalid callback data , ignore it */
   if (p_cb == NULL || p_data == NULL) return;
 
-  p2 = p_data->remote_bda;
+  p2 = p_data->remote_bda.address;
 
   APPL_TRACE_DEBUG(
       "bta_hh_gatt_open BTA_GATTC_OPEN_EVT bda= [%08x%04x] status =%d",
@@ -1489,7 +1488,7 @@
   tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data;
 
   if (interop_match_addr(INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S,
-                         (bt_bdaddr_t*)&p_dev_cb->addr) == true) {
+                         (RawAddress*)&p_dev_cb->addr) == true) {
     if (tout < 300) tout = 300;
   }
 
@@ -1763,7 +1762,7 @@
   p_cb->disc_active = BTA_HH_LE_DISC_NONE;
   /* Failure in opening connection or GATT discovery failure */
   conn_dat.handle = p_cb->hid_handle;
-  memcpy(conn_dat.bda, p_cb->addr, BD_ADDR_LEN);
+  conn_dat.bda = p_cb->addr;
   conn_dat.le_hid = true;
   conn_dat.scps_supported = p_cb->scps_supported;
 
@@ -2257,7 +2256,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_hh_le_hid_read_rpt_clt_cfg(BD_ADDR bd_addr, uint8_t rpt_id) {
+void bta_hh_le_hid_read_rpt_clt_cfg(const RawAddress& bd_addr, uint8_t rpt_id) {
   tBTA_HH_DEV_CB* p_cb = NULL;
   tBTA_HH_LE_RPT* p_rpt;
   uint8_t index = BTA_HH_IDX_INVALID;
diff --git a/bta/hh/bta_hh_main.cc b/bta/hh/bta_hh_main.cc
index a403f22..e747773 100644
--- a/bta/hh/bta_hh_main.cc
+++ b/bta/hh/bta_hh_main.cc
@@ -249,7 +249,7 @@
         case BTA_HH_API_OPEN_EVT:
           cback_event = BTA_HH_OPEN_EVT;
           /* build cback data */
-          bdcpy(cback_data.conn.bda, ((tBTA_HH_API_CONN*)p_data)->bd_addr);
+          cback_data.conn.bda = ((tBTA_HH_API_CONN*)p_data)->bd_addr;
           cback_data.conn.status = BTA_HH_ERR_DB_FULL;
           cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
           break;
@@ -258,7 +258,7 @@
           cback_event = p_data->api_maintdev.sub_event;
 
           if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) {
-            bdcpy(cback_data.dev_info.bda, p_data->api_maintdev.bda);
+            cback_data.dev_info.bda = p_data->api_maintdev.bda;
             cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
             cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
           } else {
diff --git a/bta/hh/bta_hh_utils.cc b/bta/hh/bta_hh_utils.cc
index d0f6031..c687a2a 100644
--- a/bta/hh/bta_hh_utils.cc
+++ b/bta/hh/bta_hh_utils.cc
@@ -54,14 +54,13 @@
  * Returns          void
  *
  ******************************************************************************/
-uint8_t bta_hh_find_cb(BD_ADDR bda) {
+uint8_t bta_hh_find_cb(const RawAddress& bda) {
   uint8_t xx;
 
   /* See how many active devices there are. */
   for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
     /* check if any active/known devices is a match */
-    if ((!bdcmp(bda, bta_hh_cb.kdev[xx].addr) &&
-         bdcmp(bda, bd_addr_null) != 0)) {
+    if ((bda == bta_hh_cb.kdev[xx].addr && !bda.IsEmpty())) {
 #if (BTA_HH_DEBUG == TRUE)
       APPL_TRACE_DEBUG("found kdev_cb[%d] hid_handle = %d ", xx,
                        bta_hh_cb.kdev[xx].hid_handle)
@@ -79,7 +78,7 @@
   /* if no active device match, find a spot for it */
   for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
     if (!bta_hh_cb.kdev[xx].in_use) {
-      bdcpy(bta_hh_cb.kdev[xx].addr, bda);
+      bta_hh_cb.kdev[xx].addr = bda;
       break;
     }
   }
@@ -371,14 +370,15 @@
  * Returns          tBTA_HH_STATUS  operation status
  *
  ******************************************************************************/
-tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr, uint16_t* p_max_ssr_lat,
+tBTA_HH_STATUS bta_hh_read_ssr_param(const RawAddress& bd_addr,
+                                     uint16_t* p_max_ssr_lat,
                                      uint16_t* p_min_ssr_tout) {
   tBTA_HH_STATUS status = BTA_HH_ERR;
   tBTA_HH_CB* p_cb = &bta_hh_cb;
   uint8_t i;
   uint16_t ssr_max_latency;
   for (i = 0; i < BTA_HH_MAX_KNOWN; i++) {
-    if (memcmp(p_cb->kdev[i].addr, bd_addr, BD_ADDR_LEN) == 0) {
+    if (p_cb->kdev[i].addr == bd_addr) {
       /* if remote device does not have HIDSSRHostMaxLatency attribute in SDP,
       set SSR max latency default value here.  */
       if (p_cb->kdev[i].dscp_info.ssr_max_latency == HID_SSR_PARAM_INVALID) {
diff --git a/bta/hl/bta_hl_act.cc b/bta/hl/bta_hl_act.cc
index 569f66c..6c896f1 100644
--- a/bta/hl/bta_hl_act.cc
+++ b/bta/hl/bta_hl_act.cc
@@ -1254,7 +1254,7 @@
     evt_data.dch_create_ind.local_mdep_id = p_dcb->local_mdep_id;
     evt_data.dch_create_ind.mdl_id = p_dcb->mdl_id;
     evt_data.dch_create_ind.cfg = p_dcb->remote_cfg;
-    bdcpy(evt_data.dch_create_ind.bd_addr, p_mcb->bd_addr);
+    evt_data.dch_create_ind.bd_addr = p_mcb->bd_addr;
     p_acb->p_cback(BTA_HL_DCH_CREATE_IND_EVT, (tBTA_HL*)&evt_data);
   } else {
     if (MCA_CreateMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id,
@@ -2131,7 +2131,7 @@
 #endif
 
   p_mcb->mcl_handle = p_data->mca_evt.mcl_handle;
-  bdcpy(p_mcb->bd_addr, p_data->mca_evt.mca_data.connect_ind.bd_addr);
+  p_mcb->bd_addr = p_data->mca_evt.mca_data.connect_ind.bd_addr;
   p_mcb->cch_mtu = p_data->mca_evt.mca_data.connect_ind.mtu;
 
   bta_sys_conn_open(BTA_ID_HL, p_acb->app_id, p_mcb->bd_addr);
diff --git a/bta/hl/bta_hl_api.cc b/bta/hl/bta_hl_api.cc
index cc0ae06..145c4f2 100644
--- a/bta/hl/bta_hl_api.cc
+++ b/bta/hl/bta_hl_api.cc
@@ -227,7 +227,7 @@
   p_buf->app_handle = app_handle;
   p_buf->sec_mask =
       (p_open_param->sec_mask | BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
-  bdcpy(p_buf->bd_addr, p_open_param->bd_addr);
+  p_buf->bd_addr = p_open_param->bd_addr;
   p_buf->ctrl_psm = p_open_param->ctrl_psm;
 
   bta_sys_sendmsg(p_buf);
@@ -443,14 +443,14 @@
  *
  ******************************************************************************/
 void BTA_HlSdpQuery(uint8_t app_id, tBTA_HL_APP_HANDLE app_handle,
-                    BD_ADDR bd_addr) {
+                    const RawAddress& bd_addr) {
   tBTA_HL_API_SDP_QUERY* p_buf =
       (tBTA_HL_API_SDP_QUERY*)osi_malloc(sizeof(tBTA_HL_API_SDP_QUERY));
 
   p_buf->hdr.event = BTA_HL_API_SDP_QUERY_EVT;
   p_buf->app_id = app_id;
   p_buf->app_handle = app_handle;
-  bdcpy(p_buf->bd_addr, bd_addr);
+  p_buf->bd_addr = bd_addr;
 
   bta_sys_sendmsg(p_buf);
 }
diff --git a/bta/hl/bta_hl_int.h b/bta/hl/bta_hl_int.h
index 4d5168d..c0ba647 100644
--- a/bta/hl/bta_hl_int.h
+++ b/bta/hl/bta_hl_int.h
@@ -267,8 +267,8 @@
   uint8_t app_id;
   tBTA_HL_APP_HANDLE app_handle;
   uint16_t ctrl_psm;
-  BD_ADDR bd_addr;   /* Address of peer device */
-  tBTA_SEC sec_mask; /* security mask for initiating connection*/
+  RawAddress bd_addr;  /* Address of peer device */
+  tBTA_SEC sec_mask;   /* security mask for initiating connection*/
 } tBTA_HL_API_CCH_OPEN;
 
 typedef struct {
@@ -359,7 +359,7 @@
   BT_HDR hdr;
   tBTA_HL_APP_HANDLE app_handle;
   uint8_t app_id;
-  BD_ADDR bd_addr; /* Address of peer device */
+  RawAddress bd_addr; /* Address of peer device */
 } tBTA_HL_API_SDP_QUERY;
 
 typedef struct {
@@ -455,7 +455,7 @@
   uint16_t req_ctrl_psm;
   uint16_t ctrl_psm;
   uint16_t data_psm;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t cch_mtu;
   uint16_t sec_mask;
   tBTA_HL_MCL_HANDLE mcl_handle;
@@ -720,7 +720,7 @@
 extern bool bta_hl_find_mcl_idx_using_handle(tBTA_HL_MCL_HANDLE mcl_handle,
                                              uint8_t* p_app_idx,
                                              uint8_t* p_mcl_idx);
-extern bool bta_hl_find_mcl_idx(uint8_t app_idx, BD_ADDR p_bd_addr,
+extern bool bta_hl_find_mcl_idx(uint8_t app_idx, const RawAddress& p_bd_addr,
                                 uint8_t* p_mcl_idx);
 extern bool bta_hl_is_the_first_reliable_existed(uint8_t app_idx,
                                                  uint8_t mcl_idx);
@@ -735,9 +735,10 @@
 extern bool bta_hl_get_cur_time(uint8_t app_idx, uint8_t* p_cur_time);
 extern void bta_hl_sort_cfg_time_idx(uint8_t app_idx, uint8_t* a, uint8_t n);
 extern void bta_hl_compact_mdl_cfg_time(uint8_t app_idx, uint8_t mdep_id);
-extern bool bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx, BD_ADDR bd_addr,
+extern bool bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx,
+                                       const RawAddress& bd_addr,
                                        tBTA_HL_MDL_ID mdl_id);
-extern bool bta_hl_delete_mdl_cfg(uint8_t app_idx, BD_ADDR bd_addr,
+extern bool bta_hl_delete_mdl_cfg(uint8_t app_idx, const RawAddress& bd_addr,
                                   tBTA_HL_MDL_ID mdl_id);
 extern bool bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id);
 extern bool bta_hl_find_mdep_cfg_idx(uint8_t app_idx,
@@ -774,7 +775,7 @@
                                  tBTA_HL_L2CAP_CFG_INFO* p_cfg);
 extern bool bta_hl_validate_chan_cfg(uint8_t app_idx, uint8_t mcl_idx,
                                      uint8_t mdl_idx);
-extern bool bta_hl_is_cong_on(uint8_t app_id, BD_ADDR bd_addr,
+extern bool bta_hl_is_cong_on(uint8_t app_id, const RawAddress& bd_addr,
                               tBTA_HL_MDL_ID mdl_id);
 extern void bta_hl_check_cch_close(uint8_t app_idx, uint8_t mcl_idx,
                                    tBTA_HL_DATA* p_data, bool check_dch_setup);
@@ -810,11 +811,12 @@
 extern void bta_hl_build_cch_open_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
                                       tBTA_HL_APP_HANDLE app_handle,
                                       tBTA_HL_MCL_HANDLE mcl_handle,
-                                      BD_ADDR bd_addr, tBTA_HL_STATUS status);
+                                      const RawAddress& bd_addr,
+                                      tBTA_HL_STATUS status);
 extern void bta_hl_build_cch_open_ind(tBTA_HL* p_evt_data,
                                       tBTA_HL_APP_HANDLE app_handle,
                                       tBTA_HL_MCL_HANDLE mcl_handle,
-                                      BD_ADDR bd_addr);
+                                      const RawAddress& bd_addr);
 extern void bta_hl_build_cch_close_cfm(tBTA_HL* p_evt_data,
                                        tBTA_HL_APP_HANDLE app_handle,
                                        tBTA_HL_MCL_HANDLE mcl_handle,
@@ -842,7 +844,8 @@
                                        tBTA_HL_STATUS status);
 extern void bta_hl_build_sdp_query_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
                                        tBTA_HL_APP_HANDLE app_handle,
-                                       BD_ADDR bd_addr, tBTA_HL_SDP* p_sdp,
+                                       const RawAddress& bd_addr,
+                                       tBTA_HL_SDP* p_sdp,
                                        tBTA_HL_STATUS status);
 
 #if (BTA_HL_DEBUG == TRUE)
diff --git a/bta/hl/bta_hl_main.cc b/bta/hl/bta_hl_main.cc
index b4860e7..4e0d7de 100644
--- a/bta/hl/bta_hl_main.cc
+++ b/bta/hl/bta_hl_main.cc
@@ -780,7 +780,7 @@
         p_mcb->in_use = true;
         p_mcb->req_ctrl_psm = p_data->api_cch_open.ctrl_psm;
         p_mcb->sec_mask = p_data->api_cch_open.sec_mask;
-        bdcpy(p_mcb->bd_addr, p_data->api_cch_open.bd_addr);
+        p_mcb->bd_addr = p_data->api_cch_open.bd_addr;
         p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_OPEN;
       } else {
         status = BTA_HL_STATUS_NO_RESOURCE;
@@ -1328,7 +1328,7 @@
       if (bta_hl_find_avail_mcl_idx(app_idx, &mcl_idx)) {
         p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
         p_mcb->in_use = true;
-        bdcpy(p_mcb->bd_addr, p_data->api_sdp_query.bd_addr);
+        p_mcb->bd_addr = p_data->api_sdp_query.bd_addr;
         APPL_TRACE_DEBUG(
             "bta_hl_api_sdp_query p_mcb->app_id %d app_idx %d mcl_idx %d",
             p_mcb->app_id, app_idx, mcl_idx);
diff --git a/bta/hl/bta_hl_utils.cc b/bta/hl/bta_hl_utils.cc
index 3510cfd..8cdacc9 100644
--- a/bta/hl/bta_hl_utils.cc
+++ b/bta/hl/bta_hl_utils.cc
@@ -1026,15 +1026,14 @@
  * Returns      bool true-found
  *
  ******************************************************************************/
-bool bta_hl_find_mcl_idx(uint8_t app_idx, BD_ADDR p_bd_addr,
+bool bta_hl_find_mcl_idx(uint8_t app_idx, const RawAddress& p_bd_addr,
                          uint8_t* p_mcl_idx) {
   bool found = false;
   uint8_t i;
 
   for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
     if (bta_hl_cb.acb[app_idx].mcb[i].in_use &&
-        (!memcmp(bta_hl_cb.acb[app_idx].mcb[i].bd_addr, p_bd_addr,
-                 BD_ADDR_LEN))) {
+        bta_hl_cb.acb[app_idx].mcb[i].bd_addr == p_bd_addr) {
       found = true;
       *p_mcl_idx = i;
       break;
@@ -1155,8 +1154,7 @@
     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
     for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
       p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, j);
-      if (p_mcb->in_use &&
-          !memcmp(p_mdl->peer_bd_addr, p_mcb->bd_addr, BD_ADDR_LEN)) {
+      if (p_mcb->in_use && p_mdl->peer_bd_addr == p_mcb->bd_addr) {
         for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
           p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, j, k);
 
@@ -1284,8 +1282,7 @@
     if (p_mdl->active)
       APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx: mdl_id =%d, p_mdl->mdl_id=%d",
                        mdl_id, p_mdl->mdl_id);
-    if (p_mdl->active &&
-        (!memcmp(p_mcb->bd_addr, p_mdl->peer_bd_addr, BD_ADDR_LEN)) &&
+    if (p_mdl->active && p_mcb->bd_addr == p_mdl->peer_bd_addr &&
         (p_mdl->mdl_id == mdl_id)) {
       found = true;
       *p_mdl_cfg_idx = i;
@@ -1434,7 +1431,7 @@
  *                        false does not exist
  *
  ******************************************************************************/
-bool bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx, BD_ADDR bd_addr,
+bool bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx, const RawAddress& bd_addr,
                                 tBTA_HL_MDL_ID mdl_id) {
   tBTA_HL_MDL_CFG* p_mdl;
   bool found = false;
@@ -1442,7 +1439,7 @@
 
   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
-    if (p_mdl->active && !memcmp(p_mdl->peer_bd_addr, bd_addr, BD_ADDR_LEN)) {
+    if (p_mdl->active && p_mdl->peer_bd_addr == bd_addr) {
       if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
         if (p_mdl->mdl_id == mdl_id) {
           found = true;
@@ -1468,7 +1465,7 @@
  *                        false Failed
  *
  ******************************************************************************/
-bool bta_hl_delete_mdl_cfg(uint8_t app_idx, BD_ADDR bd_addr,
+bool bta_hl_delete_mdl_cfg(uint8_t app_idx, const RawAddress& bd_addr,
                            tBTA_HL_MDL_ID mdl_id) {
   tBTA_HL_MDL_CFG* p_mdl;
   bool success = false;
@@ -1476,7 +1473,7 @@
 
   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
-    if (p_mdl->active && !memcmp(p_mdl->peer_bd_addr, bd_addr, BD_ADDR_LEN)) {
+    if (p_mdl->active && p_mdl->peer_bd_addr == bd_addr) {
       if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
         if (p_mdl->mdl_id == mdl_id) {
           bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
@@ -2196,7 +2193,7 @@
     mdl_cfg.mtu = l2cap_cfg.mtu;
     mdl_cfg.fcs = l2cap_cfg.fcs;
 
-    bdcpy(mdl_cfg.peer_bd_addr, p_mcb->bd_addr);
+    mdl_cfg.peer_bd_addr = p_mcb->bd_addr;
     mdl_cfg.local_mdep_id = p_dcb->local_mdep_id;
     p_mdep_cfg = &p_acb->sup_feature.mdep[p_dcb->local_mdep_cfg_idx];
     mdl_cfg.local_mdep_role = p_mdep_cfg->mdep_cfg.mdep_role;
@@ -2422,7 +2419,8 @@
  *                        false not congested
  *
  ******************************************************************************/
-bool bta_hl_is_cong_on(uint8_t app_id, BD_ADDR bd_addr, tBTA_HL_MDL_ID mdl_id)
+bool bta_hl_is_cong_on(uint8_t app_id, const RawAddress& bd_addr,
+                       tBTA_HL_MDL_ID mdl_id)
 
 {
   tBTA_HL_MDL_CB* p_dcb;
@@ -2723,12 +2721,13 @@
  ******************************************************************************/
 void bta_hl_build_cch_open_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
                                tBTA_HL_APP_HANDLE app_handle,
-                               tBTA_HL_MCL_HANDLE mcl_handle, BD_ADDR bd_addr,
+                               tBTA_HL_MCL_HANDLE mcl_handle,
+                               const RawAddress& bd_addr,
                                tBTA_HL_STATUS status) {
   p_evt_data->cch_open_cfm.app_id = app_id;
   p_evt_data->cch_open_cfm.app_handle = app_handle;
   p_evt_data->cch_open_cfm.mcl_handle = mcl_handle;
-  bdcpy(p_evt_data->cch_open_cfm.bd_addr, bd_addr);
+  p_evt_data->cch_open_cfm.bd_addr = bd_addr;
   p_evt_data->cch_open_cfm.status = status;
   APPL_TRACE_DEBUG("bta_hl_build_cch_open_cfm: status=%d", status);
 }
@@ -2744,10 +2743,11 @@
  ******************************************************************************/
 void bta_hl_build_cch_open_ind(tBTA_HL* p_evt_data,
                                tBTA_HL_APP_HANDLE app_handle,
-                               tBTA_HL_MCL_HANDLE mcl_handle, BD_ADDR bd_addr) {
+                               tBTA_HL_MCL_HANDLE mcl_handle,
+                               const RawAddress& bd_addr) {
   p_evt_data->cch_open_ind.app_handle = app_handle;
   p_evt_data->cch_open_ind.mcl_handle = mcl_handle;
-  bdcpy(p_evt_data->cch_open_ind.bd_addr, bd_addr);
+  p_evt_data->cch_open_ind.bd_addr = bd_addr;
 }
 
 /*******************************************************************************
@@ -2826,15 +2826,16 @@
  *
  ******************************************************************************/
 void bta_hl_build_sdp_query_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
-                                tBTA_HL_APP_HANDLE app_handle, BD_ADDR bd_addr,
-                                tBTA_HL_SDP* p_sdp, tBTA_HL_STATUS status)
+                                tBTA_HL_APP_HANDLE app_handle,
+                                const RawAddress& bd_addr, tBTA_HL_SDP* p_sdp,
+                                tBTA_HL_STATUS status)
 
 {
   APPL_TRACE_DEBUG("bta_hl_build_sdp_query_cfm: app_id = %d, app_handle=%d",
                    app_id, app_handle);
   p_evt_data->sdp_query_cfm.app_id = app_id;
   p_evt_data->sdp_query_cfm.app_handle = app_handle;
-  bdcpy(p_evt_data->sdp_query_cfm.bd_addr, bd_addr);
+  p_evt_data->sdp_query_cfm.bd_addr = bd_addr;
   p_evt_data->sdp_query_cfm.p_sdp = p_sdp;
   p_evt_data->sdp_query_cfm.status = status;
 }
diff --git a/bta/include/bta_ag_api.h b/bta/include/bta_ag_api.h
index 88f9d60..1322368 100644
--- a/bta/include/bta_ag_api.h
+++ b/bta/include/bta_ag_api.h
@@ -332,7 +332,7 @@
 /* data associated with BTA_AG_OPEN_EVT */
 typedef struct {
   tBTA_AG_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_SERVICE_ID service_id;
   tBTA_AG_STATUS status;
 } tBTA_AG_OPEN;
@@ -340,21 +340,21 @@
 /* data associated with BTA_AG_CLOSE_EVT */
 typedef struct {
   tBTA_AG_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
 } tBTA_AG_CLOSE;
 
 /* data associated with BTA_AG_CONN_EVT */
 typedef struct {
   tBTA_AG_HDR hdr;
   tBTA_AG_PEER_FEAT peer_feat;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_AG_PEER_CODEC peer_codec;
 } tBTA_AG_CONN;
 
 /* data associated with AT command event */
 typedef struct {
   tBTA_AG_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   char str[BTA_AG_AT_MAX_LEN + 1];
   uint16_t num;
   uint8_t idx;   /* call number used by CLCC and CHLD */
@@ -512,7 +512,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_AgOpen(uint16_t handle, BD_ADDR bd_addr, tBTA_SEC sec_mask,
+void BTA_AgOpen(uint16_t handle, const RawAddress& bd_addr, tBTA_SEC sec_mask,
                 tBTA_SERVICE_MASK services);
 
 /*******************************************************************************
@@ -583,4 +583,6 @@
  ******************************************************************************/
 void BTA_AgSetCodec(uint16_t handle, tBTA_AG_PEER_CODEC codec);
 
+void BTA_AgSetScoAllowed(bool value);
+
 #endif /* BTA_AG_API_H */
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index e27ba43..814038c 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -277,7 +277,7 @@
 
 /* Inquiry Filter Condition */
 typedef union {
-  BD_ADDR bd_addr;                 /* BD address of  device to filter. */
+  RawAddress bd_addr;              /* BD address of  device to filter. */
   tBTA_DM_COD_COND dev_class_cond; /* Device class filter condition */
 } tBTA_DM_INQ_COND;
 
@@ -346,7 +346,7 @@
 #define BTA_BLE_RSSI_ALERT_LO_BIT BTM_BLE_RSSI_ALERT_LO_BIT /*    (1 << 2) */
 typedef uint8_t tBTA_DM_BLE_RSSI_ALERT_MASK;
 
-typedef void(tBTA_DM_BLE_RSSI_CBACK)(BD_ADDR bd_addr,
+typedef void(tBTA_DM_BLE_RSSI_CBACK)(const RawAddress& bd_addr,
                                      tBTA_DM_BLE_RSSI_ALERT_TYPE alert_type,
                                      int8_t rssi);
 
@@ -402,7 +402,7 @@
 typedef struct {
   /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in
    * order */
-  BD_ADDR bd_addr;     /* BD address peer device. */
+  RawAddress bd_addr;  /* BD address peer device. */
   DEV_CLASS dev_class; /* Class of Device */
   BD_NAME bd_name;     /* Name of peer device. */
   bool min_16_digit;   /* true if the pin returned must be at least 16 digits */
@@ -501,19 +501,19 @@
 
 /* Structure associated with BTA_DM_BLE_SEC_REQ_EVT */
 typedef struct {
-  BD_ADDR bd_addr; /* peer address */
+  RawAddress bd_addr; /* peer address */
   BD_NAME bd_name; /* peer device name */
 } tBTA_DM_BLE_SEC_REQ;
 
 typedef struct {
-  BD_ADDR bd_addr; /* peer address */
+  RawAddress bd_addr; /* peer address */
   tBTM_LE_KEY_TYPE key_type;
   tBTM_LE_KEY_VALUE* p_key_value;
 } tBTA_DM_BLE_KEY;
 
 /* Structure associated with BTA_DM_AUTH_CMPL_EVT */
 typedef struct {
-  BD_ADDR bd_addr;     /* BD address peer device. */
+  RawAddress bd_addr;  /* BD address peer device. */
   BD_NAME bd_name;     /* Name of peer device. */
   bool key_present;    /* Valid link key value in key element */
   LINK_KEY key;        /* Link key associated with peer device. */
@@ -526,7 +526,7 @@
 
 /* Structure associated with BTA_DM_AUTHORIZE_EVT */
 typedef struct {
-  BD_ADDR bd_addr;         /* BD address peer device. */
+  RawAddress bd_addr;      /* BD address peer device. */
   BD_NAME bd_name;         /* Name of peer device. */
   tBTA_SERVICE_ID service; /* Service ID to authorize. */
   DEV_CLASS dev_class;
@@ -534,13 +534,13 @@
 
 /* Structure associated with BTA_DM_LINK_UP_EVT */
 typedef struct {
-  BD_ADDR bd_addr; /* BD address peer device. */
+  RawAddress bd_addr; /* BD address peer device. */
   tBTA_TRANSPORT link_type;
 } tBTA_DM_LINK_UP;
 
 /* Structure associated with BTA_DM_LINK_DOWN_EVT */
 typedef struct {
-  BD_ADDR bd_addr; /* BD address peer device. */
+  RawAddress bd_addr; /* BD address peer device. */
   uint8_t status;  /* connection open/closed */
   bool is_removed; /* true if device is removed when link is down */
   tBTA_TRANSPORT link_type;
@@ -548,7 +548,7 @@
 
 /* Structure associated with BTA_DM_ROLE_CHG_EVT */
 typedef struct {
-  BD_ADDR bd_addr;  /* BD address peer device. */
+  RawAddress bd_addr; /* BD address peer device. */
   uint8_t new_role; /* the new connection role */
 } tBTA_DM_ROLE_CHG;
 
@@ -622,7 +622,7 @@
 typedef struct {
   /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in
    * order */
-  BD_ADDR bd_addr;     /* peer address */
+  RawAddress bd_addr;  /* peer address */
   DEV_CLASS dev_class; /* peer CoD */
   BD_NAME bd_name;     /* peer device name */
   uint32_t num_val; /* the numeric value for comparison. If just_works, do not
@@ -645,7 +645,7 @@
 
 /* Structure associated with BTA_DM_SP_KEYPRESS_EVT */
 typedef struct {
-  BD_ADDR bd_addr; /* peer address */
+  RawAddress bd_addr; /* peer address */
   tBTA_SP_KEY_TYPE notif_type;
 } tBTA_DM_SP_KEY_PRESS;
 
@@ -653,7 +653,7 @@
 typedef struct {
   /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in
    * order */
-  BD_ADDR bd_addr;     /* peer address */
+  RawAddress bd_addr;  /* peer address */
   DEV_CLASS dev_class; /* peer CoD */
   BD_NAME bd_name;     /* peer device name */
   uint32_t passkey; /* the numeric value for comparison. If just_works, do not
@@ -664,7 +664,7 @@
 typedef struct {
   /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in
    * order */
-  BD_ADDR bd_addr;     /* peer address */
+  RawAddress bd_addr;  /* peer address */
   DEV_CLASS dev_class; /* peer CoD */
   BD_NAME bd_name;     /* peer device name */
 } tBTA_DM_SP_RMT_OOB;
@@ -719,7 +719,7 @@
 
 /* Structure associated with BTA_DM_INQ_RES_EVT */
 typedef struct {
-  BD_ADDR bd_addr;             /* BD address peer device. */
+  RawAddress bd_addr;          /* BD address peer device. */
   DEV_CLASS dev_class;         /* Device class of peer device. */
   bool remt_name_not_required; /* Application sets this flag if it already knows
                                   the name of the device */
@@ -748,14 +748,14 @@
 
 /* Structure associated with BTA_DM_DI_DISC_CMPL_EVT */
 typedef struct {
-  BD_ADDR bd_addr;    /* BD address peer device. */
+  RawAddress bd_addr; /* BD address peer device. */
   uint8_t num_record; /* Number of DI record */
   tBTA_STATUS result;
 } tBTA_DM_DI_DISC_CMPL;
 
 /* Structure associated with BTA_DM_DISC_RES_EVT */
 typedef struct {
-  BD_ADDR bd_addr;             /* BD address peer device. */
+  RawAddress bd_addr;          /* BD address peer device. */
   BD_NAME bd_name;             /* Name of peer device. */
   tBTA_SERVICE_MASK services;  /* Services found on peer device. */
   uint8_t* p_raw_data;         /* Raw data for discovery DB */
@@ -768,7 +768,7 @@
 
 /* Structure associated with tBTA_DM_DISC_BLE_RES */
 typedef struct {
-  BD_ADDR bd_addr;  /* BD address peer device. */
+  RawAddress bd_addr; /* BD address peer device. */
   BD_NAME bd_name;  /* Name of peer device. */
   tBT_UUID service; /* GATT based Services UUID found on peer device. */
 } tBTA_DM_DISC_BLE_RES;
@@ -792,7 +792,8 @@
 typedef void(tBTA_DM_EXEC_CBACK)(void* p_param);
 
 /* Encryption callback*/
-typedef void(tBTA_DM_ENCRYPT_CBACK)(BD_ADDR bd_addr, tBTA_TRANSPORT transport,
+typedef void(tBTA_DM_ENCRYPT_CBACK)(const RawAddress& bd_addr,
+                                    tBTA_TRANSPORT transport,
                                     tBTA_STATUS result);
 
 #define BTA_DM_BLE_SEC_NONE BTM_BLE_SEC_NONE
@@ -1156,7 +1157,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmDiscover(BD_ADDR bd_addr, tBTA_SERVICE_MASK services,
+extern void BTA_DmDiscover(const RawAddress& bd_addr,
+                           tBTA_SERVICE_MASK services,
                            tBTA_DM_SEARCH_CBACK* p_cback, bool sdp_search);
 
 /*******************************************************************************
@@ -1170,7 +1172,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmDiscoverUUID(BD_ADDR bd_addr, tSDP_UUID* uuid,
+extern void BTA_DmDiscoverUUID(const RawAddress& bd_addr, tSDP_UUID* uuid,
                                tBTA_DM_SEARCH_CBACK* p_cback, bool sdp_search);
 
 /*******************************************************************************
@@ -1183,7 +1185,7 @@
  *                  BTA_FAILURE if cached name is not available
  *
  ******************************************************************************/
-tBTA_STATUS BTA_DmGetCachedRemoteName(BD_ADDR remote_device,
+tBTA_STATUS BTA_DmGetCachedRemoteName(const RawAddress& remote_device,
                                       uint8_t** pp_cached_name);
 
 /*******************************************************************************
@@ -1198,7 +1200,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBond(BD_ADDR bd_addr);
+extern void BTA_DmBond(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1213,7 +1215,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport);
+extern void BTA_DmBondByTransport(const RawAddress& bd_addr,
+                                  tBTA_TRANSPORT transport);
 
 /*******************************************************************************
  *
@@ -1226,7 +1229,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBondCancel(BD_ADDR bd_addr);
+extern void BTA_DmBondCancel(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1241,8 +1244,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmPinReply(BD_ADDR bd_addr, bool accept, uint8_t pin_len,
-                           uint8_t* p_pin);
+extern void BTA_DmPinReply(const RawAddress& bd_addr, bool accept,
+                           uint8_t pin_len, uint8_t* p_pin);
 
 /*******************************************************************************
  *
@@ -1266,7 +1269,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmConfirm(BD_ADDR bd_addr, bool accept);
+extern void BTA_DmConfirm(const RawAddress& bd_addr, bool accept);
 
 /*******************************************************************************
  *
@@ -1281,7 +1284,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class,
+extern void BTA_DmAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class,
                             LINK_KEY link_key, tBTA_SERVICE_MASK trusted_mask,
                             bool is_trusted, uint8_t key_type,
                             tBTA_IO_CAP io_cap, uint8_t pin_length);
@@ -1299,7 +1302,7 @@
  *                  BTA_FAIL if operation failed.
  *
  ******************************************************************************/
-extern tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr);
+extern tBTA_STATUS BTA_DmRemoveDevice(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1326,7 +1329,7 @@
  * Returns          0 if the device is NOT connected.
  *
  ******************************************************************************/
-extern uint16_t BTA_DmGetConnectionState(const BD_ADDR bd_addr);
+extern uint16_t BTA_DmGetConnectionState(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1357,7 +1360,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-extern void BTA_DmCloseACL(BD_ADDR bd_addr, bool remove_dev,
+extern void BTA_DmCloseACL(const RawAddress& bd_addr, bool remove_dev,
                            tBTA_TRANSPORT transport);
 
 /*******************************************************************************
@@ -1426,7 +1429,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBleSecurityGrant(BD_ADDR bd_addr, tBTA_DM_BLE_SEC_GRANT res);
+extern void BTA_DmBleSecurityGrant(const RawAddress& bd_addr,
+                                   tBTA_DM_BLE_SEC_GRANT res);
 
 /**
  * Set BLE connectable mode to auto connect
@@ -1447,7 +1451,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBlePasskeyReply(BD_ADDR bd_addr, bool accept,
+extern void BTA_DmBlePasskeyReply(const RawAddress& bd_addr, bool accept,
                                   uint32_t passkey);
 
 /*******************************************************************************
@@ -1463,7 +1467,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBleConfirmReply(BD_ADDR bd_addr, bool accept);
+extern void BTA_DmBleConfirmReply(const RawAddress& bd_addr, bool accept);
 
 /*******************************************************************************
  *
@@ -1480,7 +1484,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type,
+extern void BTA_DmAddBleDevice(const RawAddress& bd_addr,
+                               tBLE_ADDR_TYPE addr_type,
                                tBT_DEVICE_TYPE dev_type);
 
 /*******************************************************************************
@@ -1498,7 +1503,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmAddBleKey(BD_ADDR bd_addr, tBTA_LE_KEY_VALUE* p_le_key,
+extern void BTA_DmAddBleKey(const RawAddress& bd_addr,
+                            tBTA_LE_KEY_VALUE* p_le_key,
                             tBTA_LE_KEY_TYPE key_type);
 
 /*******************************************************************************
@@ -1518,7 +1524,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmSetBlePrefConnParams(const BD_ADDR bd_addr,
+extern void BTA_DmSetBlePrefConnParams(const RawAddress& bd_addr,
                                        uint16_t min_conn_int,
                                        uint16_t max_conn_int,
                                        uint16_t slave_latency,
@@ -1580,7 +1586,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmDiscoverExt(BD_ADDR bd_addr,
+extern void BTA_DmDiscoverExt(const RawAddress& bd_addr,
                               tBTA_SERVICE_MASK_EXT* p_services,
                               tBTA_DM_SEARCH_CBACK* p_cback, bool sdp_search);
 
@@ -1600,7 +1606,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmDiscoverByTransport(BD_ADDR bd_addr,
+extern void BTA_DmDiscoverByTransport(const RawAddress& bd_addr,
                                       tBTA_SERVICE_MASK_EXT* p_services,
                                       tBTA_DM_SEARCH_CBACK* p_cback,
                                       bool sdp_search,
@@ -1629,7 +1635,8 @@
  *
  *
  ******************************************************************************/
-extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport,
+extern void BTA_DmSetEncryption(const RawAddress& bd_addr,
+                                tBTA_TRANSPORT transport,
                                 tBTA_DM_ENCRYPT_CBACK* p_callback,
                                 tBTA_DM_BLE_SEC_ACT sec_act);
 
@@ -1676,7 +1683,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBleEnableRemotePrivacy(BD_ADDR bd_addr, bool privacy_enable);
+extern void BTA_DmBleEnableRemotePrivacy(const RawAddress& bd_addr,
+                                         bool privacy_enable);
 
 /*******************************************************************************
  *
@@ -1694,7 +1702,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBleUpdateConnectionParams(const BD_ADDR bd_addr,
+extern void BTA_DmBleUpdateConnectionParams(const RawAddress& bd_addr,
                                             uint16_t min_int, uint16_t max_int,
                                             uint16_t latency, uint16_t timeout);
 
@@ -1707,7 +1715,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_DmBleSetDataLength(BD_ADDR remote_device,
+extern void BTA_DmBleSetDataLength(const RawAddress& remote_device,
                                    uint16_t tx_data_length);
 
 /*******************************************************************************
diff --git a/bta/include/bta_ar_api.h b/bta/include/bta_ar_api.h
index 75a5096..ffa9c19 100644
--- a/bta/include/bta_ar_api.h
+++ b/bta/include/bta_ar_api.h
@@ -86,7 +86,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, BD_ADDR bd_addr);
+extern void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
diff --git a/bta/include/bta_av_api.h b/bta/include/bta_av_api.h
index 7bd57f3..9add76b 100644
--- a/bta/include/bta_av_api.h
+++ b/bta/include/bta_av_api.h
@@ -263,7 +263,7 @@
 typedef struct {
   tBTA_AV_CHNL chnl;
   tBTA_AV_HNDL hndl;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_AV_STATUS status;
   bool starting;
   tBTA_AV_EDR edr; /* 0, if peer device does not support EDR */
@@ -321,34 +321,34 @@
 typedef struct {
   uint8_t rc_handle;
   tBTA_AV_FEAT peer_features;
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
   tBTA_AV_STATUS status;
 } tBTA_AV_RC_OPEN;
 
 /* data associated with BTA_AV_RC_CLOSE_EVT */
 typedef struct {
   uint8_t rc_handle;
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
 } tBTA_AV_RC_CLOSE;
 
 /* data associated with BTA_AV_RC_BROWSE_OPEN_EVT */
 typedef struct {
   uint8_t rc_handle;
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
   tBTA_AV_STATUS status;
 } tBTA_AV_RC_BROWSE_OPEN;
 
 /* data associated with BTA_AV_RC_BROWSE_CLOSE_EVT */
 typedef struct {
   uint8_t rc_handle;
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
 } tBTA_AV_RC_BROWSE_CLOSE;
 
 /* data associated with BTA_AV_RC_FEAT_EVT */
 typedef struct {
   uint8_t rc_handle;
   tBTA_AV_FEAT peer_features;
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
 } tBTA_AV_RC_FEAT;
 
 /* data associated with BTA_AV_REMOTE_CMD_EVT */
@@ -395,11 +395,11 @@
 } tBTA_AV_META_MSG;
 
 /* data associated with BTA_AV_PENDING_EVT */
-typedef struct { BD_ADDR bd_addr; } tBTA_AV_PEND;
+typedef struct { RawAddress bd_addr; } tBTA_AV_PEND;
 
 /* data associated with BTA_AV_REJECT_EVT */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_AV_HNDL hndl; /* Handle associated with the stream that rejected the
                         connection. */
 } tBTA_AV_REJECT;
@@ -433,8 +433,7 @@
 
 typedef struct {
   uint8_t* codec_info;
-  BD_ADDR bd_addr;
-  ;
+  RawAddress bd_addr;
 } tBTA_AVK_CONFIG;
 
 /* union of data associated with AV Media callback */
@@ -556,7 +555,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, bool use_rc,
+void BTA_AvOpen(const RawAddress& bd_addr, tBTA_AV_HNDL handle, bool use_rc,
                 tBTA_SEC sec_mask, uint16_t uuid);
 
 /*******************************************************************************
@@ -579,7 +578,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_AvDisconnect(BD_ADDR bd_addr);
+void BTA_AvDisconnect(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
diff --git a/bta/include/bta_av_co.h b/bta/include/bta_av_co.h
index 5817e4c..0e71ac2 100644
--- a/bta/include/bta_av_co.h
+++ b/bta/include/bta_av_co.h
@@ -60,8 +60,8 @@
  *
  ******************************************************************************/
 void bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl, uint8_t num_seps,
-                              uint8_t num_snk, uint8_t num_src, BD_ADDR addr,
-                              uint16_t uuid_local);
+                              uint8_t num_snk, uint8_t num_src,
+                              const RawAddress& addr, uint16_t uuid_local);
 
 /*******************************************************************************
  *
@@ -93,7 +93,8 @@
  *
  ******************************************************************************/
 void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, const uint8_t* p_codec_info,
-                               uint8_t seid, BD_ADDR addr, uint8_t num_protect,
+                               uint8_t seid, const RawAddress& addr,
+                               uint8_t num_protect,
                                const uint8_t* p_protect_info,
                                uint8_t t_local_sep, uint8_t avdt_handle);
 
diff --git a/bta/include/bta_dm_api.h b/bta/include/bta_dm_api.h
index 5a42f27..76cb618 100644
--- a/bta/include/bta_dm_api.h
+++ b/bta/include/bta_dm_api.h
@@ -27,6 +27,6 @@
 #include "stack/include/bt_types.h"
 
 // Brings connection to active mode
-void bta_dm_pm_active(BD_ADDR peer_addr);
+void bta_dm_pm_active(const RawAddress& peer_addr);
 
 #endif /* BTA_DM_API_H */
diff --git a/bta/include/bta_dm_ci.h b/bta/include/bta_dm_ci.h
index f6f0abd..a517da5 100644
--- a/bta/include/bta_dm_ci.h
+++ b/bta/include/bta_dm_ci.h
@@ -40,7 +40,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void bta_dm_ci_io_req(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
+extern void bta_dm_ci_io_req(const RawAddress& bd_addr, tBTA_IO_CAP io_cap,
                              tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req);
 
 /*******************************************************************************
@@ -54,8 +54,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void bta_dm_ci_rmt_oob(bool accept, BD_ADDR bd_addr, BT_OCTET16 c,
-                              BT_OCTET16 r);
+extern void bta_dm_ci_rmt_oob(bool accept, const RawAddress& bd_addr,
+                              BT_OCTET16 c, BT_OCTET16 r);
 /*******************************************************************************
  *
  * Function         bta_dm_sco_ci_data_ready
diff --git a/bta/include/bta_dm_co.h b/bta/include/bta_dm_co.h
index 5e7dacd..80e99c4 100644
--- a/bta/include/bta_dm_co.h
+++ b/bta/include/bta_dm_co.h
@@ -52,7 +52,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-extern void bta_dm_co_io_req(BD_ADDR bd_addr, tBTA_IO_CAP* p_io_cap,
+extern void bta_dm_co_io_req(const RawAddress& bd_addr, tBTA_IO_CAP* p_io_cap,
                              tBTA_OOB_DATA* p_oob_data,
                              tBTA_AUTH_REQ* p_auth_req, bool is_orig);
 
@@ -73,7 +73,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-extern void bta_dm_co_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
+extern void bta_dm_co_io_rsp(const RawAddress& bd_addr, tBTA_IO_CAP io_cap,
                              tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req);
 
 /*******************************************************************************
@@ -89,7 +89,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-extern void bta_dm_co_lk_upgrade(BD_ADDR bd_addr, bool* p_upgrade);
+extern void bta_dm_co_lk_upgrade(const RawAddress& bd_addr, bool* p_upgrade);
 
 /*******************************************************************************
  *
@@ -119,7 +119,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-extern void bta_dm_co_rmt_oob(BD_ADDR bd_addr);
+extern void bta_dm_co_rmt_oob(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -189,12 +189,10 @@
  * Returns          void.
  *
  ******************************************************************************/
-extern void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP* p_io_cap,
-                                 tBTA_OOB_DATA* p_oob_data,
-                                 tBTA_LE_AUTH_REQ* p_auth_req,
-                                 uint8_t* p_max_key_size,
-                                 tBTA_LE_KEY_TYPE* p_init_key,
-                                 tBTA_LE_KEY_TYPE* p_resp_key);
+extern void bta_dm_co_ble_io_req(
+    const RawAddress& bd_addr, tBTA_IO_CAP* p_io_cap, tBTA_OOB_DATA* p_oob_data,
+    tBTA_LE_AUTH_REQ* p_auth_req, uint8_t* p_max_key_size,
+    tBTA_LE_KEY_TYPE* p_init_key, tBTA_LE_KEY_TYPE* p_resp_key);
 
 /*******************************************************************************
  *
@@ -212,31 +210,4 @@
     tBTA_DM_BLE_LOCAL_KEY_MASK* p_key_mask, BT_OCTET16 er,
     tBTA_BLE_LOCAL_ID_KEYS* p_id_keys);
 
-/*******************************************************************************
- *
- * Function         bta_dm_co_ble_io_req
- *
- * Description      This callout function is executed by DM to get BLE IO
- *                  capabilities before SMP pairing gets going.
- *
- * Parameters       bd_addr  - The peer device
- *                  *p_io_cap - The local Input/Output capabilities
- *                  *p_oob_data - true, if OOB data is available for the peer
- *                                device.
- *                  *p_auth_req -  Auth request setting (Bonding and MITM
- *                                                       required or not)
- *                  *p_max_key_size - max key size local device supported.
- *                  *p_init_key - initiator keys.
- *                  *p_resp_key - responder keys.
- *
- * Returns          void.
- *
- ******************************************************************************/
-extern void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP* p_io_cap,
-                                 tBTA_OOB_DATA* p_oob_data,
-                                 tBTA_LE_AUTH_REQ* p_auth_req,
-                                 uint8_t* p_max_key_size,
-                                 tBTA_LE_KEY_TYPE* p_init_key,
-                                 tBTA_LE_KEY_TYPE* p_resp_key);
-
 #endif /* BTA_DM_CO_H */
diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h
index fb8581e..8034dc7 100644
--- a/bta/include/bta_gatt_api.h
+++ b/bta/include/bta_gatt_api.h
@@ -266,7 +266,7 @@
   tBTA_GATT_STATUS status;
   uint16_t conn_id;
   tBTA_GATTC_IF client_if;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_TRANSPORT transport;
   uint16_t mtu;
 } tBTA_GATTC_OPEN;
@@ -275,14 +275,14 @@
   tBTA_GATT_STATUS status;
   uint16_t conn_id;
   tBTA_GATTC_IF client_if;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBTA_GATT_REASON reason; /* disconnect reason code, not useful when connect
                               event is reported */
 } tBTA_GATTC_CLOSE;
 
 typedef struct {
   uint16_t conn_id;
-  BD_ADDR bda;
+  RawAddress bda;
   uint16_t handle;
   uint16_t len;
   uint8_t value[BTA_GATT_MAX_ATTR_LEN];
@@ -298,12 +298,12 @@
   tBTA_GATT_STATUS status;
   tBTA_GATTC_IF client_if;
   uint16_t conn_id;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
 } tBTA_GATTC_OPEN_CLOSE;
 
 typedef struct {
   tBTA_GATTC_IF client_if;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
 } tBTA_GATTC_ENC_CMPL_CB;
 
 typedef struct {
@@ -336,7 +336,7 @@
   tBTA_GATTC_EXEC_CMPL exec_cmpl; /*  execute complete */
   tBTA_GATTC_NOTIFY notify;       /* notification/indication event data */
   tBTA_GATTC_ENC_CMPL_CB enc_cmpl;
-  BD_ADDR remote_bda;         /* service change event */
+  RawAddress remote_bda;      /* service change event */
   tBTA_GATTC_CFG_MTU cfg_mtu; /* configure MTU operation */
   tBTA_GATTC_CONGEST congest;
   tBTA_GATTC_PHY_UPDATE phy_update;
@@ -465,7 +465,7 @@
 
 typedef struct {
   tBTA_GATT_STATUS status;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   uint32_t trans_id;
   uint16_t conn_id;
   tBTA_GATTS_REQ_DATA* p_data;
@@ -494,7 +494,7 @@
 
 typedef struct {
   tBTA_GATTS_IF server_if;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   uint16_t conn_id;
   tBTA_GATT_REASON reason; /* report disconnect reason */
   tBTA_GATT_TRANSPORT transport;
@@ -638,12 +638,13 @@
  *                  initiating_phys: LE PHY to use, optional
  *
  ******************************************************************************/
-extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
-                           bool is_direct, tBTA_GATT_TRANSPORT transport,
-                           bool opportunistic);
-extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
-                           bool is_direct, tBTA_GATT_TRANSPORT transport,
-                           bool opportunistic, uint8_t initiating_phys);
+extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if,
+                           const RawAddress& remote_bda, bool is_direct,
+                           tBTA_GATT_TRANSPORT transport, bool opportunistic);
+extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if,
+                           const RawAddress& remote_bda, bool is_direct,
+                           tBTA_GATT_TRANSPORT transport, bool opportunistic,
+                           uint8_t initiating_phys);
 
 /*******************************************************************************
  *
@@ -659,8 +660,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_GATTC_CancelOpen(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
-                                 bool is_direct);
+extern void BTA_GATTC_CancelOpen(tBTA_GATTC_IF client_if,
+                                 const RawAddress& remote_bda, bool is_direct);
 
 /*******************************************************************************
  *
@@ -877,7 +878,7 @@
  *
  ******************************************************************************/
 extern tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications(
-    tBTA_GATTC_IF client_if, const BD_ADDR remote_bda, uint16_t handle);
+    tBTA_GATTC_IF client_if, const RawAddress& remote_bda, uint16_t handle);
 
 /*******************************************************************************
  *
@@ -894,7 +895,7 @@
  *
  ******************************************************************************/
 extern tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications(
-    tBTA_GATTC_IF client_if, const BD_ADDR remote_bda, uint16_t handle);
+    tBTA_GATTC_IF client_if, const RawAddress& remote_bda, uint16_t handle);
 
 /*******************************************************************************
  *
@@ -959,7 +960,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_GATTC_Refresh(const bt_bdaddr_t& remote_bda);
+extern void BTA_GATTC_Refresh(const RawAddress& remote_bda);
 
 /*******************************************************************************
  *
@@ -1132,8 +1133,9 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda,
-                           bool is_direct, tBTA_GATT_TRANSPORT transport);
+extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if,
+                           const RawAddress& remote_bda, bool is_direct,
+                           tBTA_GATT_TRANSPORT transport);
 
 /*******************************************************************************
  *
@@ -1149,8 +1151,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda,
-                                 bool is_direct);
+extern void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if,
+                                 const RawAddress& remote_bda, bool is_direct);
 
 /*******************************************************************************
  *
diff --git a/bta/include/bta_hd_api.h b/bta/include/bta_hd_api.h
index 8dcca7c..31cb7a0 100644
--- a/bta/include/bta_hd_api.h
+++ b/bta/include/bta_hd_api.h
@@ -79,11 +79,11 @@
 typedef struct {
   tBTA_HD_STATUS status;
   bool in_use;
-  BD_ADDR bda;
+  RawAddress bda;
 } tBTA_HD_REG_STATUS;
 
 typedef struct {
-  BD_ADDR bda;
+  RawAddress bda;
   tBTA_HD_STATUS status;
 } tBTA_HD_CONN;
 
@@ -215,7 +215,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HdConnect(BD_ADDR addr);
+extern void BTA_HdConnect(const RawAddress& addr);
 
 /*******************************************************************************
  *
@@ -237,7 +237,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HdAddDevice(BD_ADDR addr);
+extern void BTA_HdAddDevice(const RawAddress& addr);
 
 /*******************************************************************************
  *
@@ -248,7 +248,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HdRemoveDevice(BD_ADDR addr);
+extern void BTA_HdRemoveDevice(const RawAddress& addr);
 
 /*******************************************************************************
  *
diff --git a/bta/include/bta_hf_client_api.h b/bta/include/bta_hf_client_api.h
index 10db4ec..5d725e7 100644
--- a/bta/include/bta_hf_client_api.h
+++ b/bta/include/bta_hf_client_api.h
@@ -164,27 +164,27 @@
 
 /* data associated with BTA_HF_CLIENT_REGISTER_EVT */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_HF_CLIENT_STATUS status;
 } tBTA_HF_CLIENT_REGISTER;
 
 /* data associated with BTA_HF_CLIENT_OPEN_EVT */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t handle;  // Handle for client control block
   tBTA_HF_CLIENT_STATUS status;
 } tBTA_HF_CLIENT_OPEN;
 
 /* data associated with BTA_HF_CLIENT_CONN_EVT */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_HF_CLIENT_PEER_FEAT peer_feat;
   tBTA_HF_CLIENT_CHLD_FEAT chld_feat;
 } tBTA_HF_CLIENT_CONN;
 
 /* data associated with BTA_HF_CLIENT_IND_EVT event */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_HF_CLIENT_IND_TYPE type;
   uint16_t value;
 } tBTA_HF_CLIENT_IND;
@@ -192,27 +192,27 @@
 /* data associated with BTA_HF_CLIENT_OPERATOR_NAME_EVT */
 #define BTA_HF_CLIENT_OPERATOR_NAME_LEN 16
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   char name[BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1];
 } tBTA_HF_CLIENT_OPERATOR_NAME;
 
 /* data associated with BTA_HF_CLIENT_CLIP_EVT  and BTA_HF_CLIENT_CCWA_EVT*/
 #define BTA_HF_CLIENT_NUMBER_LEN 32
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   char number[BTA_HF_CLIENT_NUMBER_LEN + 1];
 } tBTA_HF_CLIENT_NUMBER;
 
 /* data associated with BTA_HF_CLIENT_AT_RESULT_EVT event */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_HF_CLIENT_AT_RESULT_TYPE type;
   uint16_t cme;
 } tBTA_HF_CLIENT_AT_RESULT;
 
 /* data associated with BTA_HF_CLIENT_CLCC_EVT event */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint32_t idx;
   bool inc;
   uint8_t status;
@@ -223,21 +223,21 @@
 
 /* data associated with BTA_HF_CLIENT_CNUM_EVT event */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t service;
   char number[BTA_HF_CLIENT_NUMBER_LEN + 1];
 } tBTA_HF_CLIENT_CNUM;
 
 /* data associated with other events */
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t value;
 } tBTA_HF_CLIENT_VAL;
 
 /* union of data associated with AG callback */
 typedef union {
   // Common BD ADDR field for all tyepdefs
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_HF_CLIENT_REGISTER reg;
   tBTA_HF_CLIENT_OPEN open;
   tBTA_HF_CLIENT_CONN conn;
@@ -303,7 +303,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_HfClientOpen(BD_ADDR bd_addr, tBTA_SEC sec_mask, uint16_t* p_handle);
+void BTA_HfClientOpen(const RawAddress& bd_addr, tBTA_SEC sec_mask,
+                      uint16_t* p_handle);
 
 /*******************************************************************************
  *
diff --git a/bta/include/bta_hh_api.h b/bta/include/bta_hh_api.h
index 1e68a9a..6960d6f 100644
--- a/bta/include/bta_hh_api.h
+++ b/bta/include/bta_hh_api.h
@@ -204,7 +204,7 @@
 
 /* callback event data for BTA_HH_OPEN_EVT */
 typedef struct {
-  BD_ADDR bda;           /* HID device bd address    */
+  RawAddress bda;        /* HID device bd address    */
   tBTA_HH_STATUS status; /* operation status         */
   uint8_t handle;        /* device handle            */
 #if (BTA_HH_LE_INCLUDED == TRUE)
@@ -330,7 +330,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode,
+extern void BTA_HhOpen(const RawAddress& dev_bda, tBTA_HH_PROTO_MODE mode,
                        tBTA_SEC sec_mask);
 
 /*******************************************************************************
@@ -453,7 +453,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HhSendData(uint8_t dev_handle, BD_ADDR dev_bda, BT_HDR* p_buf);
+extern void BTA_HhSendData(uint8_t dev_handle, const RawAddress& dev_bda,
+                           BT_HDR* p_buf);
 
 /*******************************************************************************
  *
@@ -477,7 +478,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask,
+extern void BTA_HhAddDev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask,
                          uint8_t sub_class, uint8_t app_id,
                          tBTA_HH_DEV_DSCP_INFO dscp_info);
 /*******************************************************************************
@@ -509,6 +510,7 @@
                                uint16_t report_len);
 
 /* test commands */
-extern void bta_hh_le_hid_read_rpt_clt_cfg(BD_ADDR bd_addr, uint8_t rpt_id);
+extern void bta_hh_le_hid_read_rpt_clt_cfg(const RawAddress& bd_addr,
+                                           uint8_t rpt_id);
 
 #endif /* BTA_HH_API_H */
diff --git a/bta/include/bta_hh_co.h b/bta/include/bta_hh_co.h
index d2b0382..7781d00 100644
--- a/bta/include/bta_hh_co.h
+++ b/bta/include/bta_hh_co.h
@@ -48,7 +48,7 @@
  ******************************************************************************/
 extern void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len,
                            tBTA_HH_PROTO_MODE mode, uint8_t sub_class,
-                           uint8_t ctry_code, BD_ADDR peer_addr,
+                           uint8_t ctry_code, const RawAddress& peer_addr,
                            uint8_t app_id);
 
 /*******************************************************************************
@@ -94,7 +94,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-extern void bta_hh_le_co_rpt_info(BD_ADDR remote_bda,
+extern void bta_hh_le_co_rpt_info(const RawAddress& remote_bda,
                                   tBTA_HH_RPT_CACHE_ENTRY* p_entry,
                                   uint8_t app_id);
 
@@ -114,9 +114,8 @@
  * Returns          the acched report array
  *
  ******************************************************************************/
-extern tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(BD_ADDR remote_bda,
-                                                        uint8_t* p_num_rpt,
-                                                        uint8_t app_id);
+extern tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(
+    const RawAddress& remote_bda, uint8_t* p_num_rpt, uint8_t app_id);
 
 /*******************************************************************************
  *
@@ -129,7 +128,8 @@
  * Returns          none
  *
  ******************************************************************************/
-extern void bta_hh_le_co_reset_rpt_cache(BD_ADDR remote_bda, uint8_t app_id);
+extern void bta_hh_le_co_reset_rpt_cache(const RawAddress& remote_bda,
+                                         uint8_t app_id);
 
 #endif /* #if (BTA_HH_LE_INCLUDED == TRUE) */
 
diff --git a/bta/include/bta_hl_api.h b/bta/include/bta_hl_api.h
index 5ba9d84..414d42d 100644
--- a/bta/include/bta_hl_api.h
+++ b/bta/include/bta_hl_api.h
@@ -263,7 +263,7 @@
   bool active; /* true if this item is in use */
   tBTA_HL_DCH_MODE dch_mode;
   uint8_t fcs;
-  BD_ADDR peer_bd_addr;
+  RawAddress peer_bd_addr;
 } tBTA_HL_MDL_CFG;
 
 /* Maximum number of supported feature list items (list_elem in
@@ -297,7 +297,7 @@
 
 typedef struct {
   uint16_t ctrl_psm;
-  BD_ADDR bd_addr;   /* Address of peer device */
+  RawAddress bd_addr; /* Address of peer device */
   tBTA_SEC sec_mask; /* security mask for initiating connection*/
 } tBTA_HL_CCH_OPEN_PARAM;
 
@@ -429,7 +429,7 @@
 typedef struct {
   tBTA_HL_MCL_HANDLE mcl_handle;
   tBTA_HL_APP_HANDLE app_handle;
-  BD_ADDR bd_addr; /* address of peer device */
+  RawAddress bd_addr; /* address of peer device */
 } tBTA_HL_CCH_OPEN_IND;
 
 typedef struct {
@@ -437,7 +437,7 @@
   uint8_t app_id;
   tBTA_HL_MCL_HANDLE mcl_handle;
   tBTA_HL_APP_HANDLE app_handle;
-  BD_ADDR bd_addr; /* address of peer device */
+  RawAddress bd_addr; /* address of peer device */
 } tBTA_HL_CCH_OPEN_CFM;
 
 typedef struct {
@@ -447,7 +447,7 @@
   tBTA_HL_MDL_ID mdl_id; /* MCAP data link ID for this
                             data channel conenction    */
   tBTA_HL_DCH_CFG cfg;   /* dch cfg requested by the peer device */
-  BD_ADDR bd_addr;       /* address of peer device */
+  RawAddress bd_addr;    /* address of peer device */
 
 } tBTA_HL_DCH_CREATE_IND;
 
@@ -529,7 +529,7 @@
   tBTA_HL_STATUS status;
   uint8_t app_id;
   tBTA_HL_APP_HANDLE app_handle;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTA_HL_SDP* p_sdp;
 } tBTA_HL_SDP_QUERY_CFM;
 
@@ -800,7 +800,7 @@
  *
  ******************************************************************************/
 extern void BTA_HlSdpQuery(uint8_t app_id, tBTA_HL_APP_HANDLE app_handle,
-                           BD_ADDR bd_addr);
+                           const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
diff --git a/bta/include/bta_jv_api.h b/bta/include/bta_jv_api.h
index 046ed81..54824c4 100644
--- a/bta/include/bta_jv_api.h
+++ b/bta/include/bta_jv_api.h
@@ -187,7 +187,7 @@
 typedef struct {
   tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
   uint32_t handle;       /* The connection handle */
-  BD_ADDR rem_bda;       /* The peer address */
+  RawAddress rem_bda;    /* The peer address */
   int32_t tx_mtu;        /* The transmit MTU */
 } tBTA_JV_L2CAP_OPEN;
 
@@ -195,7 +195,7 @@
 typedef struct {
   tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
   uint32_t handle;       /* The connection handle */
-  BD_ADDR rem_bda;       /* The peer address */
+  RawAddress rem_bda;    /* The peer address */
   int32_t tx_mtu;        /* The transmit MTU */
   void** p_p_cback;      /* set them for new socket */
   void** p_user_data;    /* set them for new socket */
@@ -254,7 +254,7 @@
 typedef struct {
   tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
   uint16_t channel;      /* The connection channel */
-  BD_ADDR addr;          /* The peer address */
+  RawAddress addr;       /* The peer address */
   uint32_t req_id;       /* The req_id in the associated BTA_JvL2capWrite() */
   uint8_t* p_data;       /* The buffer where data is held */
   uint16_t len;          /* The length of the data written. */
@@ -265,14 +265,14 @@
 typedef struct {
   tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
   uint32_t handle;       /* The connection handle */
-  BD_ADDR rem_bda;       /* The peer address */
+  RawAddress rem_bda;    /* The peer address */
 } tBTA_JV_RFCOMM_OPEN;
 /* data associated with BTA_JV_RFCOMM_SRV_OPEN_EVT */
 typedef struct {
   tBTA_JV_STATUS status;      /* Whether the operation succeeded or failed. */
   uint32_t handle;            /* The connection handle */
   uint32_t new_listen_handle; /* The new listen handle */
-  BD_ADDR rem_bda;            /* The peer address */
+  RawAddress rem_bda;         /* The peer address */
 } tBTA_JV_RFCOMM_SRV_OPEN;
 
 /* data associated with BTA_JV_RFCOMM_CLOSE_EVT */
@@ -423,7 +423,7 @@
  *                  false if not.
  *
  ******************************************************************************/
-bool BTA_JvIsEncrypted(BD_ADDR bd_addr);
+bool BTA_JvIsEncrypted(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -474,8 +474,8 @@
  *                  BTA_JV_FAILURE, otherwise.
  *
  ******************************************************************************/
-tBTA_JV_STATUS BTA_JvStartDiscovery(BD_ADDR bd_addr, uint16_t num_uuid,
-                                    tSDP_UUID* p_uuid_list,
+tBTA_JV_STATUS BTA_JvStartDiscovery(const RawAddress& bd_addr,
+                                    uint16_t num_uuid, tSDP_UUID* p_uuid_list,
                                     uint32_t rfcomm_slot_id);
 
 /*******************************************************************************
@@ -521,7 +521,8 @@
 tBTA_JV_STATUS BTA_JvL2capConnectLE(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
                                     const tL2CAP_ERTM_INFO* ertm_info,
                                     uint16_t remote_chan, uint16_t rx_mtu,
-                                    tL2CAP_CFG_INFO* cfg, BD_ADDR peer_bd_addr,
+                                    tL2CAP_CFG_INFO* cfg,
+                                    const RawAddress& peer_bd_addr,
                                     tBTA_JV_L2CAP_CBACK* p_cback,
                                     uint32_t l2cap_socket_id);
 
@@ -540,13 +541,11 @@
  *                  BTA_JV_FAILURE, otherwise.
  *
  ******************************************************************************/
-tBTA_JV_STATUS BTA_JvL2capConnect(int conn_type, tBTA_SEC sec_mask,
-                                  tBTA_JV_ROLE role,
-                                  const tL2CAP_ERTM_INFO* ertm_info,
-                                  uint16_t remote_psm, uint16_t rx_mtu,
-                                  tL2CAP_CFG_INFO* cfg, BD_ADDR peer_bd_addr,
-                                  tBTA_JV_L2CAP_CBACK* p_cback,
-                                  uint32_t l2cap_socket_id);
+tBTA_JV_STATUS BTA_JvL2capConnect(
+    int conn_type, tBTA_SEC sec_mask, tBTA_JV_ROLE role,
+    const tL2CAP_ERTM_INFO* ertm_info, uint16_t remote_psm, uint16_t rx_mtu,
+    tL2CAP_CFG_INFO* cfg, const RawAddress& peer_bd_addr,
+    tBTA_JV_L2CAP_CBACK* p_cback, uint32_t l2cap_socket_id);
 
 /*******************************************************************************
  *
@@ -704,7 +703,7 @@
  *                  BTA_JV_FAILURE, otherwise.
  *
  ******************************************************************************/
-tBTA_JV_STATUS BTA_JvL2capWriteFixed(uint16_t channel, BD_ADDR* addr,
+tBTA_JV_STATUS BTA_JvL2capWriteFixed(uint16_t channel, const RawAddress& addr,
                                      uint32_t req_id,
                                      tBTA_JV_L2CAP_CBACK* p_cback,
                                      uint8_t* p_data, uint16_t len,
@@ -727,7 +726,8 @@
  *
  ******************************************************************************/
 tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
-                                   uint8_t remote_scn, BD_ADDR peer_bd_addr,
+                                   uint8_t remote_scn,
+                                   const RawAddress& peer_bd_addr,
                                    tBTA_JV_RFCOMM_CBACK* p_cback,
                                    uint32_t rfcomm_slot_id);
 
diff --git a/bta/include/bta_mce_api.h b/bta/include/bta_mce_api.h
index e773689..27d6236 100644
--- a/bta/include/bta_mce_api.h
+++ b/bta/include/bta_mce_api.h
@@ -61,7 +61,7 @@
 /* data associated with BTA_MCE_MAS_DISCOVERY_COMP_EVT */
 typedef struct {
   tBTA_MCE_STATUS status;
-  BD_ADDR remote_addr;
+  RawAddress remote_addr;
   int num_mas;
   tBTA_MCE_MAS_INFO mas[BTA_MCE_MAX_MAS_INSTANCES];
 } tBTA_MCE_MAS_DISCOVERY_COMP;
@@ -116,6 +116,6 @@
  *                  BTA_MCE_FAILURE, otherwise.
  *
  ******************************************************************************/
-extern tBTA_MCE_STATUS BTA_MceGetRemoteMasInstances(BD_ADDR bd_addr);
+extern tBTA_MCE_STATUS BTA_MceGetRemoteMasInstances(const RawAddress& bd_addr);
 
 #endif /* BTA_MCE_API_H */
diff --git a/bta/include/bta_pan_api.h b/bta/include/bta_pan_api.h
index bb4e724..1eaaa2d 100644
--- a/bta/include/bta_pan_api.h
+++ b/bta/include/bta_pan_api.h
@@ -69,14 +69,14 @@
 
 /* Event associated with BTA_PAN_OPENING_EVT */
 typedef struct {
-  BD_ADDR bd_addr; /* BD address of peer device. */
+  RawAddress bd_addr; /* BD address of peer device. */
   uint16_t handle; /* Handle associated with this connection. */
 
 } tBTA_PAN_OPENING;
 
 /* Event associated with BTA_PAN_OPEN_EVT */
 typedef struct {
-  BD_ADDR bd_addr;          /* BD address of peer device. */
+  RawAddress bd_addr;       /* BD address of peer device. */
   uint16_t handle;          /* Handle associated with this connection. */
   tBTA_PAN_STATUS status;   /* status of open event */
   tBTA_PAN_ROLE local_role; /* Local device PAN role for the connection */
@@ -161,7 +161,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_PanOpen(BD_ADDR bd_addr, tBTA_PAN_ROLE local_role,
+void BTA_PanOpen(const RawAddress& bd_addr, tBTA_PAN_ROLE local_role,
                  tBTA_PAN_ROLE peer_role);
 
 /*******************************************************************************
diff --git a/bta/include/bta_pan_ci.h b/bta/include/bta_pan_ci.h
index d14ea2b..889d77b 100644
--- a/bta/include/bta_pan_ci.h
+++ b/bta/include/bta_pan_ci.h
@@ -91,8 +91,9 @@
  * Returns          true if flow enabled
  *
  ******************************************************************************/
-extern void bta_pan_ci_rx_writebuf(uint16_t handle, BD_ADDR src, BD_ADDR dst,
-                                   uint16_t protocol, BT_HDR* p_buf, bool ext);
+extern void bta_pan_ci_rx_writebuf(uint16_t handle, const RawAddress& src,
+                                   const RawAddress& dst, uint16_t protocol,
+                                   BT_HDR* p_buf, bool ext);
 
 /*******************************************************************************
  *
@@ -107,9 +108,9 @@
  * Returns          void
  *
  ******************************************************************************/
-extern BT_HDR* bta_pan_ci_readbuf(uint16_t handle, BD_ADDR src, BD_ADDR dst,
-                                  uint16_t* p_protocol, bool* p_ext,
-                                  bool* p_forward);
+extern BT_HDR* bta_pan_ci_readbuf(uint16_t handle, RawAddress& src,
+                                  RawAddress& dst, uint16_t* p_protocol,
+                                  bool* p_ext, bool* p_forward);
 
 /*******************************************************************************
  *
diff --git a/bta/include/bta_pan_co.h b/bta/include/bta_pan_co.h
index 14a45b3..1ce512d 100644
--- a/bta/include/bta_pan_co.h
+++ b/bta/include/bta_pan_co.h
@@ -75,7 +75,7 @@
  ******************************************************************************/
 extern void bta_pan_co_open(uint16_t handle, uint8_t app_id,
                             tBTA_PAN_ROLE local_role, tBTA_PAN_ROLE peer_role,
-                            BD_ADDR peer_addr);
+                            const RawAddress& peer_addr);
 
 /*******************************************************************************
  *
@@ -133,8 +133,9 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void bta_pan_co_tx_write(uint16_t handle, uint8_t app_id, BD_ADDR src,
-                                BD_ADDR dst, uint16_t protocol, uint8_t* p_data,
+extern void bta_pan_co_tx_write(uint16_t handle, uint8_t app_id,
+                                const RawAddress& src, const RawAddress& dst,
+                                uint16_t protocol, uint8_t* p_data,
                                 uint16_t len, bool ext, bool forward);
 
 /*******************************************************************************
@@ -150,9 +151,10 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void bta_pan_co_tx_writebuf(uint16_t handle, uint8_t app_id, BD_ADDR src,
-                                   BD_ADDR dst, uint16_t protocol,
-                                   BT_HDR* p_buf, bool ext, bool forward);
+extern void bta_pan_co_tx_writebuf(uint16_t handle, uint8_t app_id,
+                                   const RawAddress& src, const RawAddress& dst,
+                                   uint16_t protocol, BT_HDR* p_buf, bool ext,
+                                   bool forward);
 
 /*******************************************************************************
  *
diff --git a/bta/include/bta_sdp_api.h b/bta/include/bta_sdp_api.h
index 1b98787..4dc5885 100644
--- a/bta/include/bta_sdp_api.h
+++ b/bta/include/bta_sdp_api.h
@@ -54,7 +54,7 @@
 /* data associated with BTA_SDP_DISCOVERY_COMP_EVT */
 typedef struct {
   tBTA_SDP_STATUS status;
-  BD_ADDR remote_addr;
+  RawAddress remote_addr;
   tBT_UUID uuid;
   int record_count;
   bluetooth_sdp_record records[BTA_SDP_MAX_RECORDS];
@@ -103,7 +103,8 @@
  *                  BTA_SDP_FAIL if internal failure.
  *
  ******************************************************************************/
-extern tBTA_SDP_STATUS BTA_SdpSearch(BD_ADDR bd_addr, tSDP_UUID* uuid);
+extern tBTA_SDP_STATUS BTA_SdpSearch(const RawAddress& bd_addr,
+                                     tSDP_UUID* uuid);
 
 /*******************************************************************************
  *
diff --git a/bta/jv/bta_jv_act.cc b/bta/jv/bta_jv_act.cc
index dccb37a..d1d66aa 100644
--- a/bta/jv/bta_jv_act.cc
+++ b/bta/jv/bta_jv_act.cc
@@ -52,7 +52,7 @@
 struct fc_client {
   struct fc_client* next_all_list;
   struct fc_client* next_chan_list;
-  BD_ADDR remote_addr;
+  RawAddress remote_addr;
   uint32_t id;
   tBTA_JV_L2CAP_CBACK* p_cback;
   uint32_t l2cap_socket_id;
@@ -75,9 +75,11 @@
 static struct fc_channel* fc_channels;
 static uint32_t fc_next_id;
 
-static void fcchan_conn_chng_cbk(uint16_t chan, BD_ADDR bd_addr, bool connected,
-                                 uint16_t reason, tBT_TRANSPORT);
-static void fcchan_data_cbk(uint16_t chan, BD_ADDR bd_addr, BT_HDR* p_buf);
+static void fcchan_conn_chng_cbk(uint16_t chan, const RawAddress& bd_addr,
+                                 bool connected, uint16_t reason,
+                                 tBT_TRANSPORT);
+static void fcchan_data_cbk(uint16_t chan, const RawAddress& bd_addr,
+                            BT_HDR* p_buf);
 
 extern void uuid_to_string_legacy(bt_uuid_t* p_uuid, char* str, size_t str_len);
 static inline void logu(const char* title, const uint8_t* p_uuid) {
@@ -399,7 +401,7 @@
   p_pm_cb->state = BTA_JV_PM_FREE_ST;
   p_pm_cb->app_id = BTA_JV_PM_ALL;
   p_pm_cb->handle = BTA_JV_PM_HANDLE_CLEAR;
-  bdcpy(p_pm_cb->peer_bd_addr, bd_addr_null);
+  p_pm_cb->peer_bd_addr = RawAddress::kEmpty;
 }
 
 /*******************************************************************************
@@ -423,8 +425,7 @@
     if ((bta_jv_cb.pm_cb[i].state != BTA_JV_PM_FREE_ST) &&
         (jv_handle == bta_jv_cb.pm_cb[i].handle)) {
       for (j = 0; j < BTA_JV_PM_MAX_NUM; j++) {
-        if (bdcmp(bta_jv_cb.pm_cb[j].peer_bd_addr,
-                  bta_jv_cb.pm_cb[i].peer_bd_addr) == 0)
+        if (bta_jv_cb.pm_cb[j].peer_bd_addr == bta_jv_cb.pm_cb[i].peer_bd_addr)
           bd_counter++;
         if (bta_jv_cb.pm_cb[j].app_id == bta_jv_cb.pm_cb[i].app_id)
           appid_counter++;
@@ -499,7 +500,7 @@
 static tBTA_JV_PM_CB* bta_jv_alloc_set_pm_profile_cb(uint32_t jv_handle,
                                                      tBTA_JV_PM_ID app_id) {
   bool bRfcHandle = (jv_handle & BTA_JV_RFCOMM_MASK) != 0;
-  BD_ADDR peer_bd_addr;
+  RawAddress peer_bd_addr;
   int i, j;
   tBTA_JV_PM_CB** pp_cb;
 
@@ -523,9 +524,10 @@
         for (j = 0; j < BTA_JV_MAX_L2C_CONN; j++) {
           if (jv_handle == bta_jv_cb.l2c_cb[j].handle) {
             pp_cb = &bta_jv_cb.l2c_cb[j].p_pm_cb;
-            uint8_t* p_bd_addr = GAP_ConnGetRemoteAddr((uint16_t)jv_handle);
-            if (NULL != p_bd_addr)
-              bdcpy(peer_bd_addr, p_bd_addr);
+            const RawAddress* p_bd_addr =
+                GAP_ConnGetRemoteAddr((uint16_t)jv_handle);
+            if (p_bd_addr)
+              peer_bd_addr = *p_bd_addr;
             else
               i = BTA_JV_PM_MAX_NUM;
             break;
@@ -544,7 +546,7 @@
     *pp_cb = &bta_jv_cb.pm_cb[i];
     bta_jv_cb.pm_cb[i].handle = jv_handle;
     bta_jv_cb.pm_cb[i].app_id = app_id;
-    bdcpy(bta_jv_cb.pm_cb[i].peer_bd_addr, peer_bd_addr);
+    bta_jv_cb.pm_cb[i].peer_bd_addr = peer_bd_addr;
     bta_jv_cb.pm_cb[i].state = BTA_JV_PM_IDLE_ST;
     return &bta_jv_cb.pm_cb[i];
   }
@@ -625,7 +627,9 @@
 void bta_jv_enable(tBTA_JV_MSG* p_data) {
   tBTA_JV_STATUS status = BTA_JV_SUCCESS;
   bta_jv_cb.p_dm_cback = p_data->enable.p_cback;
-  bta_jv_cb.p_dm_cback(BTA_JV_ENABLE_EVT, (tBTA_JV*)&status, 0);
+  tBTA_JV bta_jv;
+  bta_jv.status = status;
+  bta_jv_cb.p_dm_cback(BTA_JV_ENABLE_EVT, &bta_jv, 0);
   memset(bta_jv_cb.free_psm_list, 0, sizeof(bta_jv_cb.free_psm_list));
 }
 
@@ -716,9 +720,12 @@
         bta_jv_cb.scn[channel - 1] = true;
         scn = (uint8_t)channel;
       }
-      if (bta_jv_cb.p_dm_cback)
-        bta_jv_cb.p_dm_cback(BTA_JV_GET_SCN_EVT, (tBTA_JV*)&scn,
+      if (bta_jv_cb.p_dm_cback) {
+        tBTA_JV bta_jv;
+        bta_jv.scn = scn;
+        bta_jv_cb.p_dm_cback(BTA_JV_GET_SCN_EVT, &bta_jv,
                              p_data->alloc_channel.rfcomm_slot_id);
+      }
       return;
     }
     case BTA_JV_CONN_TYPE_L2CAP:
@@ -734,9 +741,12 @@
       break;
   }
 
-  if (bta_jv_cb.p_dm_cback)
-    bta_jv_cb.p_dm_cback(BTA_JV_GET_PSM_EVT, (tBTA_JV*)&psm,
+  if (bta_jv_cb.p_dm_cback) {
+    tBTA_JV bta_jv;
+    bta_jv.psm = psm;
+    bta_jv_cb.p_dm_cback(BTA_JV_GET_PSM_EVT, &bta_jv,
                          p_data->alloc_channel.l2cap_socket_id);
+  }
 }
 
 /*******************************************************************************
@@ -838,8 +848,9 @@
     }
 
     dcomp.status = status;
-    bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV*)&dcomp,
-                         *p_rfcomm_slot_id);
+    tBTA_JV bta_jv;
+    bta_jv.disc_comp = dcomp;
+    bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, &bta_jv, *p_rfcomm_slot_id);
     osi_free(p_rfcomm_slot_id);
   }
 }
@@ -860,9 +871,12 @@
   if (bta_jv_cb.sdp_active != BTA_JV_SDP_ACT_NONE) {
     /* SDP is still in progress */
     status = BTA_JV_BUSY;
-    if (bta_jv_cb.p_dm_cback)
-      bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV*)&status,
+    if (bta_jv_cb.p_dm_cback) {
+      tBTA_JV bta_jv;
+      bta_jv.status = status;
+      bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, &bta_jv,
                            p_data->start_discovery.rfcomm_slot_id);
+    }
     return;
   }
 
@@ -891,9 +905,12 @@
           bta_jv_start_discovery_cback, (void*)rfcomm_slot_id)) {
     bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE;
     /* failed to start SDP. report the failure right away */
-    if (bta_jv_cb.p_dm_cback)
-      bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, (tBTA_JV*)&status,
+    if (bta_jv_cb.p_dm_cback) {
+      tBTA_JV bta_jv;
+      bta_jv.status = status;
+      bta_jv_cb.p_dm_cback(BTA_JV_DISCOVERY_COMP_EVT, &bta_jv,
                            p_data->start_discovery.rfcomm_slot_id);
+    }
   }
   /*
   else report the result when the cback is called
@@ -913,11 +930,12 @@
   tBTA_JV_API_CREATE_RECORD* cr = &(p_data->create_record);
   tBTA_JV_CREATE_RECORD evt_data;
   evt_data.status = BTA_JV_SUCCESS;
-  if (bta_jv_cb.p_dm_cback)
-    // callback user immediately to create his own sdp record in stack thread
-    // context
-    bta_jv_cb.p_dm_cback(BTA_JV_CREATE_RECORD_EVT, (tBTA_JV*)&evt_data,
-                         cr->rfcomm_slot_id);
+  if (bta_jv_cb.p_dm_cback) {
+    // callback immediately to create the sdp record in stack thread context
+    tBTA_JV bta_jv;
+    bta_jv.create_rec = evt_data;
+    bta_jv_cb.p_dm_cback(BTA_JV_CREATE_RECORD_EVT, &bta_jv, cr->rfcomm_slot_id);
+  }
 }
 
 /*******************************************************************************
@@ -959,7 +977,7 @@
 
   switch (event) {
     case GAP_EVT_CONN_OPENED:
-      bdcpy(evt_data.l2c_open.rem_bda, GAP_ConnGetRemoteAddr(gap_handle));
+      evt_data.l2c_open.rem_bda = *GAP_ConnGetRemoteAddr(gap_handle);
       evt_data.l2c_open.tx_mtu = GAP_ConnGetRemMtuSize(gap_handle);
       p_cb->state = BTA_JV_ST_CL_OPEN;
       p_cb->p_cback(BTA_JV_L2CAP_OPEN_EVT, &evt_data, p_cb->l2cap_socket_id);
@@ -1048,7 +1066,7 @@
     if ((cc->type != BTA_JV_CONN_TYPE_L2CAP) ||
         (bta_jv_check_psm(cc->remote_psm))) /* allowed */
     {
-      handle = GAP_ConnOpen("", sec_id, 0, cc->peer_bd_addr, cc->remote_psm,
+      handle = GAP_ConnOpen("", sec_id, 0, &cc->peer_bd_addr, cc->remote_psm,
                             &cfg, ertm_info, cc->sec_mask, chan_mode_mask,
                             bta_jv_l2cap_client_cback, cc->type);
       if (handle != GAP_INVALID_HANDLE) {
@@ -1070,9 +1088,11 @@
   }
 
   evt_data.handle = handle;
-  if (cc->p_cback)
-    cc->p_cback(BTA_JV_L2CAP_CL_INIT_EVT, (tBTA_JV*)&evt_data,
-                cc->l2cap_socket_id);
+  if (cc->p_cback) {
+    tBTA_JV bta_jv;
+    bta_jv.l2c_cl_init = evt_data;
+    cc->p_cback(BTA_JV_L2CAP_CL_INIT_EVT, &bta_jv, cc->l2cap_socket_id);
+  }
 }
 
 /*******************************************************************************
@@ -1094,8 +1114,11 @@
   evt_data.status = bta_jv_free_l2c_cb(cc->p_cb);
   evt_data.async = false;
 
-  if (p_cback)
-    p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV*)&evt_data, l2cap_socket_id);
+  if (p_cback) {
+    tBTA_JV bta_jv;
+    bta_jv.l2c_close = evt_data;
+    p_cback(BTA_JV_L2CAP_CLOSE_EVT, &bta_jv, l2cap_socket_id);
+  }
 }
 
 /*******************************************************************************
@@ -1121,7 +1144,7 @@
 
   switch (event) {
     case GAP_EVT_CONN_OPENED:
-      bdcpy(evt_data.l2c_open.rem_bda, GAP_ConnGetRemoteAddr(gap_handle));
+      evt_data.l2c_open.rem_bda = *GAP_ConnGetRemoteAddr(gap_handle);
       evt_data.l2c_open.tx_mtu = GAP_ConnGetRemMtuSize(gap_handle);
       p_cb->state = BTA_JV_ST_SR_OPEN;
       p_cb->p_cback(BTA_JV_L2CAP_OPEN_EVT, &evt_data, p_cb->l2cap_socket_id);
@@ -1210,8 +1233,8 @@
   /* PSM checking is not required for LE COC */
   if (0 == sec_id || ((ls->type == BTA_JV_CONN_TYPE_L2CAP) &&
                       (false == bta_jv_check_psm(ls->local_psm))) ||
-      (handle = GAP_ConnOpen("JV L2CAP", sec_id, 1, 0, ls->local_psm, &cfg,
-                             ertm_info, ls->sec_mask, chan_mode_mask,
+      (handle = GAP_ConnOpen("JV L2CAP", sec_id, 1, nullptr, ls->local_psm,
+                             &cfg, ertm_info, ls->sec_mask, chan_mode_mask,
                              bta_jv_l2cap_server_cback, ls->type)) ==
           GAP_INVALID_HANDLE) {
     bta_jv_free_sec_id(&sec_id);
@@ -1229,9 +1252,11 @@
     p_cb->psm = ls->local_psm;
   }
 
-  if (ls->p_cback)
-    ls->p_cback(BTA_JV_L2CAP_START_EVT, (tBTA_JV*)&evt_data,
-                ls->l2cap_socket_id);
+  if (ls->p_cback) {
+    tBTA_JV bta_jv;
+    bta_jv.l2c_start = evt_data;
+    ls->p_cback(BTA_JV_L2CAP_START_EVT, &bta_jv, ls->l2cap_socket_id);
+  }
 }
 
 /*******************************************************************************
@@ -1256,8 +1281,11 @@
       evt_data.handle = p_cb->handle;
       evt_data.status = bta_jv_free_l2c_cb(p_cb);
       evt_data.async = false;
-      if (p_cback)
-        p_cback(BTA_JV_L2CAP_CLOSE_EVT, (tBTA_JV*)&evt_data, l2cap_socket_id);
+      if (p_cback) {
+        tBTA_JV bta_jv;
+        bta_jv.l2c_close = evt_data;
+        p_cback(BTA_JV_L2CAP_CLOSE_EVT, &bta_jv, l2cap_socket_id);
+      }
       break;
     }
   }
@@ -1287,7 +1315,9 @@
     evt_data.status = BTA_JV_SUCCESS;
   }
 
-  rc->p_cback(BTA_JV_L2CAP_READ_EVT, (tBTA_JV*)&evt_data, rc->l2cap_socket_id);
+  tBTA_JV bta_jv;
+  bta_jv.l2c_read = evt_data;
+  rc->p_cback(BTA_JV_L2CAP_READ_EVT, &bta_jv, rc->l2cap_socket_id);
 }
 
 /*******************************************************************************
@@ -1339,7 +1369,9 @@
             GAP_ConnWriteData(ls->handle, ls->p_data, ls->len, &evt_data.len)) {
       evt_data.status = BTA_JV_SUCCESS;
     }
-    ls->p_cb->p_cback(BTA_JV_L2CAP_WRITE_EVT, (tBTA_JV*)&evt_data, ls->user_id);
+    tBTA_JV bta_jv;
+    bta_jv.l2c_write = evt_data;
+    ls->p_cb->p_cback(BTA_JV_L2CAP_WRITE_EVT, &bta_jv, ls->user_id);
   } else {
     /* As this pointer is checked in the API function, this occurs only when the
      * channel is
@@ -1366,7 +1398,7 @@
 
   evt_data.status = BTA_JV_FAILURE;
   evt_data.channel = ls->channel;
-  memcpy(evt_data.addr, ls->addr, sizeof(evt_data.addr));
+  evt_data.addr = ls->addr;
   evt_data.req_id = ls->req_id;
   evt_data.p_data = ls->p_data;
   evt_data.len = 0;
@@ -1377,7 +1409,9 @@
 
   L2CA_SendFixedChnlData(ls->channel, ls->addr, msg);
 
-  ls->p_cback(BTA_JV_L2CAP_WRITE_FIXED_EVT, (tBTA_JV*)&evt_data, ls->user_id);
+  tBTA_JV bta_jv;
+  bta_jv.l2c_write_fixed = evt_data;
+  ls->p_cback(BTA_JV_L2CAP_WRITE_FIXED_EVT, &bta_jv, ls->user_id);
 }
 
 /*******************************************************************************
@@ -1426,7 +1460,7 @@
   tBTA_JV_RFC_CB* p_cb = bta_jv_rfc_port_to_cb(port_handle);
   tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
   tBTA_JV evt_data;
-  BD_ADDR rem_bda;
+  RawAddress rem_bda;
   uint16_t lcid;
   tBTA_JV_RFCOMM_CBACK* p_cback; /* the callback function */
 
@@ -1442,7 +1476,7 @@
   if (code == PORT_SUCCESS) {
     evt_data.rfc_open.handle = p_cb->handle;
     evt_data.rfc_open.status = BTA_JV_SUCCESS;
-    bdcpy(evt_data.rfc_open.rem_bda, rem_bda);
+    evt_data.rfc_open.rem_bda = rem_bda;
     p_pcb->state = BTA_JV_ST_CL_OPEN;
     p_cb->p_cback(BTA_JV_RFCOMM_OPEN_EVT, &evt_data, p_pcb->rfcomm_slot_id);
   } else {
@@ -1568,9 +1602,10 @@
       APPL_TRACE_ERROR("run out of rfc control block");
     }
   }
-  cc->p_cback(BTA_JV_RFCOMM_CL_INIT_EVT, (tBTA_JV*)&evt_data,
-              cc->rfcomm_slot_id);
-  if (evt_data.status == BTA_JV_FAILURE) {
+  tBTA_JV bta_jv;
+  bta_jv.rfc_cl_init = evt_data;
+  cc->p_cback(BTA_JV_RFCOMM_CL_INIT_EVT, &bta_jv, cc->rfcomm_slot_id);
+  if (bta_jv.rfc_cl_init.status == BTA_JV_FAILURE) {
     if (sec_id) bta_jv_free_sec_id(&sec_id);
     if (handle) RFCOMM_RemoveConnection(handle);
   }
@@ -1638,7 +1673,7 @@
   tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
   tBTA_JV_RFC_CB* p_cb = bta_jv_rfc_port_to_cb(port_handle);
   tBTA_JV evt_data;
-  BD_ADDR rem_bda;
+  RawAddress rem_bda;
   uint16_t lcid;
   APPL_TRACE_DEBUG("bta_jv_port_mgmt_sr_cback, code:%d, port_handle:%d", code,
                    port_handle);
@@ -1658,7 +1693,7 @@
   if (code == PORT_SUCCESS) {
     evt_data.rfc_srv_open.handle = p_pcb->handle;
     evt_data.rfc_srv_open.status = BTA_JV_SUCCESS;
-    bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda);
+    evt_data.rfc_srv_open.rem_bda = rem_bda;
     tBTA_JV_PCB* p_pcb_new_listen = bta_jv_add_rfc_port(p_cb, p_pcb);
     if (p_pcb_new_listen) {
       evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle;
@@ -1783,7 +1818,7 @@
     if (used < p_cb->max_sess && listen == 1 && si) {
       si--;
       if (RFCOMM_CreateConnection(p_cb->sec_id, p_cb->scn, true,
-                                  BTA_JV_DEF_RFC_MTU, (uint8_t*)bd_addr_any,
+                                  BTA_JV_DEF_RFC_MTU, RawAddress::kAny,
                                   &(p_cb->rfc_hdl[si]),
                                   bta_jv_port_mgmt_sr_cback) == PORT_SUCCESS) {
         p_cb->curr_sess++;
@@ -1856,7 +1891,7 @@
     }
 
     if (RFCOMM_CreateConnection(sec_id, rs->local_scn, true, BTA_JV_DEF_RFC_MTU,
-                                (uint8_t*)bd_addr_any, &handle,
+                                RawAddress::kAny, &handle,
                                 bta_jv_port_mgmt_sr_cback) != PORT_SUCCESS) {
       APPL_TRACE_ERROR(
           "bta_jv_rfcomm_start_server, RFCOMM_CreateConnection failed");
@@ -1891,8 +1926,10 @@
     PORT_SetState(handle, &port_state);
   } while (0);
 
-  rs->p_cback(BTA_JV_RFCOMM_START_EVT, (tBTA_JV*)&evt_data, rs->rfcomm_slot_id);
-  if (evt_data.status == BTA_JV_SUCCESS) {
+  tBTA_JV bta_jv;
+  bta_jv.rfc_start = evt_data;
+  rs->p_cback(BTA_JV_RFCOMM_START_EVT, &bta_jv, rs->rfcomm_slot_id);
+  if (bta_jv.rfc_start.status == BTA_JV_SUCCESS) {
     PORT_SetDataCOCallback(handle, bta_jv_port_data_co_cback);
   } else {
     if (sec_id) bta_jv_free_sec_id(&sec_id);
@@ -1966,8 +2003,9 @@
   evt_data.cong = p_pcb->cong;
 
   if (p_cb->p_cback) {
-    p_cb->p_cback(BTA_JV_RFCOMM_WRITE_EVT, (tBTA_JV*)&evt_data,
-                  p_pcb->rfcomm_slot_id);
+    tBTA_JV bta_jv;
+    bta_jv.rfc_write = evt_data;
+    p_cb->p_cback(BTA_JV_RFCOMM_WRITE_EVT, &bta_jv, p_pcb->rfcomm_slot_id);
   } else {
     APPL_TRACE_ERROR("%s No JV callback set", __func__);
   }
@@ -2191,12 +2229,12 @@
 
 /* pass NULL to find servers */
 static struct fc_client* fcclient_find_by_addr(struct fc_client* start,
-                                               BD_ADDR addr) {
+                                               const RawAddress* addr) {
   struct fc_client* t = start;
 
   while (t) {
     /* match client if have addr */
-    if (addr && !memcmp(addr, &t->remote_addr, sizeof(t->remote_addr))) break;
+    if (addr && addr == &t->remote_addr) break;
 
     /* match server if do not have addr */
     if (!addr && t->server) break;
@@ -2293,8 +2331,9 @@
   osi_free(fc);
 }
 
-static void fcchan_conn_chng_cbk(uint16_t chan, BD_ADDR bd_addr, bool connected,
-                                 uint16_t reason, tBT_TRANSPORT transport) {
+static void fcchan_conn_chng_cbk(uint16_t chan, const RawAddress& bd_addr,
+                                 bool connected, uint16_t reason,
+                                 tBT_TRANSPORT transport) {
   tBTA_JV init_evt;
   tBTA_JV open_evt;
   struct fc_channel* tc;
@@ -2306,7 +2345,8 @@
   tc = fcchan_get(chan, false);
   if (tc) {
     t = fcclient_find_by_addr(
-        tc->clients, bd_addr);  // try to find an open socked for that addr
+        tc->clients,
+        &bd_addr);  // try to find an open socked for that addr
     if (t) {
       p_cback = t->p_cback;
       l2cap_socket_id = t->l2cap_socket_id;
@@ -2319,8 +2359,7 @@
         // it
         new_conn = fcclient_alloc(chan, false, &t->sec_id);
         if (new_conn) {
-          memcpy(&new_conn->remote_addr, bd_addr,
-                 sizeof(new_conn->remote_addr));
+          new_conn->remote_addr = bd_addr;
           new_conn->p_cback = NULL;     // for now
           new_conn->init_called = true; /*nop need to do it again */
 
@@ -2374,7 +2413,8 @@
   }
 }
 
-static void fcchan_data_cbk(uint16_t chan, BD_ADDR bd_addr, BT_HDR* p_buf) {
+static void fcchan_data_cbk(uint16_t chan, const RawAddress& bd_addr,
+                            BT_HDR* p_buf) {
   tBTA_JV evt_data;
   struct fc_channel* tc;
   struct fc_client* t = NULL;
@@ -2383,9 +2423,8 @@
 
   tc = fcchan_get(chan, false);
   if (tc) {
-    t = fcclient_find_by_addr(
-        tc->clients,
-        bd_addr);  // try to find an open socked for that addr and channel
+    // try to find an open socked for that addr and channel
+    t = fcclient_find_by_addr(tc->clients, &bd_addr);
     if (!t) {
       // no socket -> drop it
       return;
@@ -2427,7 +2466,7 @@
 
   t->p_cback = cc->p_cback;
   t->l2cap_socket_id = cc->l2cap_socket_id;
-  memcpy(&t->remote_addr, &cc->peer_bd_addr, sizeof(t->remote_addr));
+  t->remote_addr = cc->peer_bd_addr;
   id = t->id;
   t->init_called = false;
 
@@ -2516,7 +2555,9 @@
   evt_data.sec_id = t->sec_id;
 
 out:
-  ss->p_cback(BTA_JV_L2CAP_START_EVT, (tBTA_JV*)&evt_data, ss->l2cap_socket_id);
+  tBTA_JV bta_jv;
+  bta_jv.l2c_start = evt_data;
+  ss->p_cback(BTA_JV_L2CAP_START_EVT, &bta_jv, ss->l2cap_socket_id);
 }
 
 /*******************************************************************************
diff --git a/bta/jv/bta_jv_api.cc b/bta/jv/bta_jv_api.cc
index 4633a28..0478a3b 100644
--- a/bta/jv/bta_jv_api.cc
+++ b/bta/jv/bta_jv_api.cc
@@ -113,7 +113,7 @@
  *                  false if not.
  *
  ******************************************************************************/
-bool BTA_JvIsEncrypted(BD_ADDR bd_addr) {
+bool BTA_JvIsEncrypted(const RawAddress& bd_addr) {
   bool is_encrypted = false;
   uint8_t sec_flags, le_flags;
 
@@ -213,8 +213,8 @@
  *                  BTA_JV_FAILURE, otherwise.
  *
  ******************************************************************************/
-tBTA_JV_STATUS BTA_JvStartDiscovery(BD_ADDR bd_addr, uint16_t num_uuid,
-                                    tSDP_UUID* p_uuid_list,
+tBTA_JV_STATUS BTA_JvStartDiscovery(const RawAddress& bd_addr,
+                                    uint16_t num_uuid, tSDP_UUID* p_uuid_list,
                                     uint32_t rfcomm_slot_id) {
   tBTA_JV_API_START_DISCOVERY* p_msg = (tBTA_JV_API_START_DISCOVERY*)osi_malloc(
       sizeof(tBTA_JV_API_START_DISCOVERY));
@@ -222,7 +222,7 @@
   APPL_TRACE_API("%s", __func__);
 
   p_msg->hdr.event = BTA_JV_API_START_DISCOVERY_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   p_msg->num_uuid = num_uuid;
   memcpy(p_msg->uuid_list, p_uuid_list, num_uuid * sizeof(tSDP_UUID));
   p_msg->num_attr = 0;
@@ -301,7 +301,8 @@
 tBTA_JV_STATUS BTA_JvL2capConnectLE(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
                                     const tL2CAP_ERTM_INFO* ertm_info,
                                     uint16_t remote_chan, uint16_t rx_mtu,
-                                    tL2CAP_CFG_INFO* cfg, BD_ADDR peer_bd_addr,
+                                    tL2CAP_CFG_INFO* cfg,
+                                    const RawAddress& peer_bd_addr,
                                     tBTA_JV_L2CAP_CBACK* p_cback,
                                     uint32_t l2cap_socket_id) {
   APPL_TRACE_API("%s", __func__);
@@ -327,7 +328,7 @@
   } else {
     p_msg->has_ertm_info = false;
   }
-  memcpy(p_msg->peer_bd_addr, peer_bd_addr, sizeof(BD_ADDR));
+  p_msg->peer_bd_addr = peer_bd_addr;
   p_msg->p_cback = p_cback;
   p_msg->l2cap_socket_id = l2cap_socket_id;
 
@@ -351,13 +352,11 @@
  *                  BTA_JV_FAILURE, otherwise.
  *
  ******************************************************************************/
-tBTA_JV_STATUS BTA_JvL2capConnect(int conn_type, tBTA_SEC sec_mask,
-                                  tBTA_JV_ROLE role,
-                                  const tL2CAP_ERTM_INFO* ertm_info,
-                                  uint16_t remote_psm, uint16_t rx_mtu,
-                                  tL2CAP_CFG_INFO* cfg, BD_ADDR peer_bd_addr,
-                                  tBTA_JV_L2CAP_CBACK* p_cback,
-                                  uint32_t l2cap_socket_id) {
+tBTA_JV_STATUS BTA_JvL2capConnect(
+    int conn_type, tBTA_SEC sec_mask, tBTA_JV_ROLE role,
+    const tL2CAP_ERTM_INFO* ertm_info, uint16_t remote_psm, uint16_t rx_mtu,
+    tL2CAP_CFG_INFO* cfg, const RawAddress& peer_bd_addr,
+    tBTA_JV_L2CAP_CBACK* p_cback, uint32_t l2cap_socket_id) {
   APPL_TRACE_API("%s", __func__);
 
   if (p_cback == NULL) return BTA_JV_FAILURE; /* Nothing to do */
@@ -382,7 +381,7 @@
   } else {
     p_msg->has_ertm_info = false;
   }
-  memcpy(p_msg->peer_bd_addr, peer_bd_addr, sizeof(BD_ADDR));
+  p_msg->peer_bd_addr = peer_bd_addr;
   p_msg->p_cback = p_cback;
   p_msg->l2cap_socket_id = l2cap_socket_id;
 
@@ -721,7 +720,7 @@
  *                  BTA_JV_FAILURE, otherwise.
  *
  ******************************************************************************/
-tBTA_JV_STATUS BTA_JvL2capWriteFixed(uint16_t channel, BD_ADDR* addr,
+tBTA_JV_STATUS BTA_JvL2capWriteFixed(uint16_t channel, const RawAddress& addr,
                                      uint32_t req_id,
                                      tBTA_JV_L2CAP_CBACK* p_cback,
                                      uint8_t* p_data, uint16_t len,
@@ -734,7 +733,7 @@
 
   p_msg->hdr.event = BTA_JV_API_L2CAP_WRITE_FIXED_EVT;
   p_msg->channel = channel;
-  memcpy(p_msg->addr, addr, sizeof(p_msg->addr));
+  p_msg->addr = addr;
   p_msg->req_id = req_id;
   p_msg->p_data = p_data;
   p_msg->p_cback = p_cback;
@@ -763,7 +762,8 @@
  *
  ******************************************************************************/
 tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask, tBTA_JV_ROLE role,
-                                   uint8_t remote_scn, BD_ADDR peer_bd_addr,
+                                   uint8_t remote_scn,
+                                   const RawAddress& peer_bd_addr,
                                    tBTA_JV_RFCOMM_CBACK* p_cback,
                                    uint32_t rfcomm_slot_id) {
   APPL_TRACE_API("%s", __func__);
@@ -776,7 +776,7 @@
   p_msg->sec_mask = sec_mask;
   p_msg->role = role;
   p_msg->remote_scn = remote_scn;
-  memcpy(p_msg->peer_bd_addr, peer_bd_addr, sizeof(BD_ADDR));
+  p_msg->peer_bd_addr = peer_bd_addr;
   p_msg->p_cback = p_cback;
   p_msg->rfcomm_slot_id = rfcomm_slot_id;
 
diff --git a/bta/jv/bta_jv_int.h b/bta/jv/bta_jv_int.h
index 6b445ab..94ee085 100644
--- a/bta/jv/bta_jv_int.h
+++ b/bta/jv/bta_jv_int.h
@@ -78,7 +78,7 @@
 /* data type for BTA_JV_API_START_DISCOVERY_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t num_uuid;
   tSDP_UUID uuid_list[BTA_JV_MAX_UUIDS];
   uint16_t num_attr;
@@ -97,7 +97,7 @@
   uint32_t handle;      /* The connection handle */
   uint8_t state;        /* state: see above enum */
   tBTA_JV_PM_ID app_id; /* JV app specific id indicating power table to use */
-  BD_ADDR peer_bd_addr; /* Peer BD address */
+  RawAddress peer_bd_addr; /* Peer BD address */
 } tBTA_JV_PM_CB;
 
 enum {
@@ -163,7 +163,7 @@
     uint16_t remote_chan;
   };
   uint16_t rx_mtu;
-  BD_ADDR peer_bd_addr;
+  RawAddress peer_bd_addr;
   int32_t has_cfg;
   tL2CAP_CFG_INFO cfg;
   int32_t has_ertm_info;
@@ -224,7 +224,7 @@
 typedef struct {
   BT_HDR hdr;
   uint16_t channel;
-  BD_ADDR addr;
+  RawAddress addr;
   uint32_t req_id;
   tBTA_JV_L2CAP_CBACK* p_cback;
   uint8_t* p_data;
@@ -238,7 +238,7 @@
   tBTA_SEC sec_mask;
   tBTA_JV_ROLE role;
   uint8_t remote_scn;
-  BD_ADDR peer_bd_addr;
+  RawAddress peer_bd_addr;
   tBTA_JV_RFCOMM_CBACK* p_cback;
   uint32_t rfcomm_slot_id;
 } tBTA_JV_API_RFCOMM_CONNECT;
diff --git a/bta/mce/bta_mce_act.cc b/bta/mce/bta_mce_act.cc
index 7851c76..f188b01 100644
--- a/bta/mce/bta_mce_act.cc
+++ b/bta/mce/bta_mce_act.cc
@@ -67,7 +67,7 @@
   if (bta_mce_cb.p_dm_cback == NULL) return;
 
   evt_data.status = BTA_MCE_FAILURE;
-  bdcpy(evt_data.remote_addr, bta_mce_cb.remote_addr);
+  evt_data.remote_addr = bta_mce_cb.remote_addr;
   evt_data.num_mas = 0;
 
   if (result == SDP_SUCCESS || result == SDP_DB_FULL) {
@@ -111,8 +111,9 @@
     evt_data.status = BTA_MCE_SUCCESS;
   }
 
-  bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, (tBTA_MCE*)&evt_data,
-                        user_data);
+  tBTA_MCE bta_mce;
+  bta_mce.mas_disc_comp = evt_data;
+  bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, &bta_mce, user_data);
 }
 
 /*******************************************************************************
@@ -127,7 +128,9 @@
 void bta_mce_enable(tBTA_MCE_MSG* p_data) {
   tBTA_MCE_STATUS status = BTA_MCE_SUCCESS;
   bta_mce_cb.p_dm_cback = p_data->enable.p_cback;
-  bta_mce_cb.p_dm_cback(BTA_MCE_ENABLE_EVT, (tBTA_MCE*)&status, NULL);
+  tBTA_MCE bta_mce;
+  bta_mce.status = status;
+  bta_mce_cb.p_dm_cback(BTA_MCE_ENABLE_EVT, &bta_mce, NULL);
 }
 
 /*******************************************************************************
@@ -151,15 +154,17 @@
   if (bta_mce_cb.sdp_active != BTA_MCE_SDP_ACT_NONE) {
     /* SDP is still in progress */
     status = BTA_MCE_BUSY;
-    if (bta_mce_cb.p_dm_cback)
-      bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, (tBTA_MCE*)&status,
-                            NULL);
+    if (bta_mce_cb.p_dm_cback) {
+      tBTA_MCE bta_mce;
+      bta_mce.status = status;
+      bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, &bta_mce, NULL);
+    }
 
     return;
   }
 
   bta_mce_cb.sdp_active = BTA_MCE_SDP_ACT_YES;
-  bdcpy(bta_mce_cb.remote_addr, p_data->get_rmt_mas.bd_addr);
+  bta_mce_cb.remote_addr = p_data->get_rmt_mas.bd_addr;
 
   SDP_InitDiscoveryDb(p_bta_mce_cfg->p_sdp_db, p_bta_mce_cfg->sdp_db_size, 1,
                       (tBT_UUID*)&bta_mce_mas_uuid, 0, NULL);
@@ -170,9 +175,11 @@
     bta_mce_cb.sdp_active = BTA_MCE_SDP_ACT_NONE;
 
     /* failed to start SDP. report the failure right away */
-    if (bta_mce_cb.p_dm_cback)
-      bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, (tBTA_MCE*)&status,
-                            NULL);
+    if (bta_mce_cb.p_dm_cback) {
+      tBTA_MCE bta_mce;
+      bta_mce.status = status;
+      bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, &bta_mce, NULL);
+    }
   }
   /*
   else report the result when the cback is called
diff --git a/bta/mce/bta_mce_api.cc b/bta/mce/bta_mce_api.cc
index e9233d9..b44c210 100644
--- a/bta/mce/bta_mce_api.cc
+++ b/bta/mce/bta_mce_api.cc
@@ -91,7 +91,7 @@
  *                  BTA_MCE_FAILURE, otherwise.
  *
  ******************************************************************************/
-tBTA_MCE_STATUS BTA_MceGetRemoteMasInstances(BD_ADDR bd_addr) {
+tBTA_MCE_STATUS BTA_MceGetRemoteMasInstances(const RawAddress& bd_addr) {
   tBTA_MCE_API_GET_REMOTE_MAS_INSTANCES* p_msg =
       (tBTA_MCE_API_GET_REMOTE_MAS_INSTANCES*)osi_malloc(
           sizeof(tBTA_MCE_API_GET_REMOTE_MAS_INSTANCES));
@@ -99,7 +99,7 @@
   APPL_TRACE_API("%s", __func__);
 
   p_msg->hdr.event = BTA_MCE_API_GET_REMOTE_MAS_INSTANCES_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
 
   bta_sys_sendmsg(p_msg);
 
diff --git a/bta/mce/bta_mce_int.h b/bta/mce/bta_mce_int.h
index e249d74..cff5875 100644
--- a/bta/mce/bta_mce_int.h
+++ b/bta/mce/bta_mce_int.h
@@ -49,7 +49,7 @@
 /* data type for BTA_MCE_API_GET_REMOTE_MAS_INSTANCES_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
 } tBTA_MCE_API_GET_REMOTE_MAS_INSTANCES;
 
 /* union of all data types */
@@ -63,7 +63,7 @@
 /* MCE control block */
 typedef struct {
   uint8_t sdp_active; /* see BTA_MCE_SDP_ACT_* */
-  BD_ADDR remote_addr;
+  RawAddress remote_addr;
   tBTA_MCE_DM_CBACK* p_dm_cback;
 } tBTA_MCE_CB;
 
diff --git a/bta/pan/bta_pan_act.cc b/bta/pan/bta_pan_act.cc
index fe63ba5..41e0bf6 100644
--- a/bta/pan/bta_pan_act.cc
+++ b/bta/pan/bta_pan_act.cc
@@ -86,7 +86,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_pan_conn_state_cback(uint16_t handle, BD_ADDR bd_addr,
+static void bta_pan_conn_state_cback(uint16_t handle, const RawAddress& bd_addr,
                                      tPAN_RESULT state, bool is_role_change,
                                      uint8_t src_role, uint8_t dst_role) {
   tBTA_PAN_SCB* p_scb;
@@ -109,7 +109,7 @@
     p_scb->local_role = src_role;
     p_scb->peer_role = dst_role;
     p_scb->pan_flow_enable = true;
-    bdcpy(p_scb->bd_addr, bd_addr);
+    p_scb->bd_addr = bd_addr;
     p_scb->data_queue = fixed_queue_new(SIZE_MAX);
 
     if (src_role == PAN_ROLE_CLIENT)
@@ -168,8 +168,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bta_pan_data_buf_ind_cback(uint16_t handle, BD_ADDR src,
-                                       BD_ADDR dst, uint16_t protocol,
+static void bta_pan_data_buf_ind_cback(uint16_t handle, const RawAddress& src,
+                                       const RawAddress& dst, uint16_t protocol,
                                        BT_HDR* p_buf, bool ext, bool forward) {
   tBTA_PAN_SCB* p_scb;
   BT_HDR* p_new_buf;
@@ -197,8 +197,8 @@
     p_new_buf = p_buf;
   }
   /* copy params into the space before the data */
-  bdcpy(((tBTA_PAN_DATA_PARAMS*)p_new_buf)->src, src);
-  bdcpy(((tBTA_PAN_DATA_PARAMS*)p_new_buf)->dst, dst);
+  ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->src = src;
+  ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->dst = dst;
   ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->protocol = protocol;
   ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->ext = ext;
   ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->forward = forward;
@@ -264,13 +264,13 @@
 static bool bta_pan_has_multiple_connections(uint8_t app_id) {
   tBTA_PAN_SCB* p_scb = NULL;
   bool found = false;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
 
   for (uint8_t index = 0; index < BTA_PAN_NUM_CONN; index++) {
     p_scb = &bta_pan_cb.scb[index];
     if (p_scb->in_use == true && app_id == p_scb->app_id) {
       /* save temp bd_addr */
-      bdcpy(bd_addr, p_scb->bd_addr);
+      bd_addr = p_scb->bd_addr;
       found = true;
       break;
     }
@@ -285,7 +285,7 @@
   for (uint8_t index = 0; index < BTA_PAN_NUM_CONN; index++) {
     p_scb = &bta_pan_cb.scb[index];
     if (p_scb->in_use == true && p_scb->app_id != bta_pan_cb.app_id[0] &&
-        bdcmp(bd_addr, p_scb->bd_addr)) {
+        bd_addr != p_scb->bd_addr) {
       return true;
     }
   }
@@ -451,16 +451,16 @@
   APPL_TRACE_DEBUG("%s pan connect status: %d", __func__, status);
 
   if (status == PAN_SUCCESS) {
-    bdcpy(p_scb->bd_addr, p_data->api_open.bd_addr);
+    p_scb->bd_addr = p_data->api_open.bd_addr;
     p_scb->local_role = p_data->api_open.local_role;
     p_scb->peer_role = p_data->api_open.peer_role;
-    bdcpy(bta_pan.opening.bd_addr, p_data->api_open.bd_addr);
+    bta_pan.opening.bd_addr = p_data->api_open.bd_addr;
     bta_pan.opening.handle = p_scb->handle;
     bta_pan_cb.p_cback(BTA_PAN_OPENING_EVT, &bta_pan);
 
   } else {
     bta_pan_scb_dealloc(p_scb);
-    bdcpy(bta_pan.open.bd_addr, p_data->api_open.bd_addr);
+    bta_pan.open.bd_addr = p_data->api_open.bd_addr;
     bta_pan.open.status = BTA_PAN_FAIL;
     bta_pan.open.local_role = p_data->api_open.local_role;
     bta_pan.open.peer_role = p_data->api_open.peer_role;
@@ -509,7 +509,7 @@
   APPL_TRACE_DEBUG("%s pan connection result: %d", __func__,
                    p_data->conn.result);
 
-  bdcpy(bta_pan.open.bd_addr, p_scb->bd_addr);
+  bta_pan.open.bd_addr = p_scb->bd_addr;
   bta_pan.open.handle = p_scb->handle;
   bta_pan.open.local_role = p_scb->local_role;
   bta_pan.open.peer_role = p_scb->peer_role;
diff --git a/bta/pan/bta_pan_api.cc b/bta/pan/bta_pan_api.cc
index cfb0588..0011522 100644
--- a/bta/pan/bta_pan_api.cc
+++ b/bta/pan/bta_pan_api.cc
@@ -142,7 +142,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTA_PanOpen(BD_ADDR bd_addr, tBTA_PAN_ROLE local_role,
+void BTA_PanOpen(const RawAddress& bd_addr, tBTA_PAN_ROLE local_role,
                  tBTA_PAN_ROLE peer_role) {
   tBTA_PAN_API_OPEN* p_buf =
       (tBTA_PAN_API_OPEN*)osi_malloc(sizeof(tBTA_PAN_API_OPEN));
@@ -150,7 +150,7 @@
   p_buf->hdr.event = BTA_PAN_API_OPEN_EVT;
   p_buf->local_role = local_role;
   p_buf->peer_role = peer_role;
-  bdcpy(p_buf->bd_addr, bd_addr);
+  p_buf->bd_addr = bd_addr;
 
   bta_sys_sendmsg(p_buf);
 }
@@ -184,7 +184,7 @@
                     UNUSED_ATTR tBTA_PAN_ROLE_INFO* p_gn_info,
                     UNUSED_ATTR tBTA_PAN_ROLE_INFO* p_nap_info) {}
 
-void BTA_PanOpen(UNUSED_ATTR BD_ADDR bd_addr,
+void BTA_PanOpen(UNUSED_ATTR const RawAddress& bd_addr,
                  UNUSED_ATTR tBTA_PAN_ROLE local_role,
                  UNUSED_ATTR tBTA_PAN_ROLE peer_role) {}
 
diff --git a/bta/pan/bta_pan_ci.cc b/bta/pan/bta_pan_ci.cc
index f44ebee..9863e78 100644
--- a/bta/pan/bta_pan_ci.cc
+++ b/bta/pan/bta_pan_ci.cc
@@ -120,16 +120,16 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_pan_ci_rx_write(uint16_t handle, BD_ADDR dst, BD_ADDR src,
-                         uint16_t protocol, uint8_t* p_data, uint16_t len,
-                         bool ext) {
+void bta_pan_ci_rx_write(uint16_t handle, const RawAddress& dst,
+                         const RawAddress& src, uint16_t protocol,
+                         uint8_t* p_data, uint16_t len, bool ext) {
   BT_HDR* p_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
 
   p_buf->offset = PAN_MINIMUM_OFFSET;
 
   /* copy all other params before the data */
-  bdcpy(((tBTA_PAN_DATA_PARAMS*)p_buf)->src, src);
-  bdcpy(((tBTA_PAN_DATA_PARAMS*)p_buf)->dst, dst);
+  ((tBTA_PAN_DATA_PARAMS*)p_buf)->src = src;
+  ((tBTA_PAN_DATA_PARAMS*)p_buf)->dst = dst;
   ((tBTA_PAN_DATA_PARAMS*)p_buf)->protocol = protocol;
   ((tBTA_PAN_DATA_PARAMS*)p_buf)->ext = ext;
   p_buf->len = len;
@@ -157,11 +157,12 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_pan_ci_rx_writebuf(uint16_t handle, BD_ADDR dst, BD_ADDR src,
-                            uint16_t protocol, BT_HDR* p_buf, bool ext) {
+void bta_pan_ci_rx_writebuf(uint16_t handle, const RawAddress& dst,
+                            const RawAddress& src, uint16_t protocol,
+                            BT_HDR* p_buf, bool ext) {
   /* copy all other params before the data */
-  bdcpy(((tBTA_PAN_DATA_PARAMS*)p_buf)->src, src);
-  bdcpy(((tBTA_PAN_DATA_PARAMS*)p_buf)->dst, dst);
+  ((tBTA_PAN_DATA_PARAMS*)p_buf)->src = src;
+  ((tBTA_PAN_DATA_PARAMS*)p_buf)->dst = dst;
   ((tBTA_PAN_DATA_PARAMS*)p_buf)->protocol = protocol;
   ((tBTA_PAN_DATA_PARAMS*)p_buf)->ext = ext;
 
@@ -180,7 +181,7 @@
  * Returns          void
  *
  ******************************************************************************/
-BT_HDR* bta_pan_ci_readbuf(uint16_t handle, BD_ADDR src, BD_ADDR dst,
+BT_HDR* bta_pan_ci_readbuf(uint16_t handle, RawAddress& src, RawAddress& dst,
                            uint16_t* p_protocol, bool* p_ext, bool* p_forward) {
   tBTA_PAN_SCB* p_scb;
   BT_HDR* p_buf;
@@ -189,8 +190,8 @@
 
   p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_scb->data_queue);
   if (p_buf != NULL) {
-    bdcpy(src, ((tBTA_PAN_DATA_PARAMS*)p_buf)->src);
-    bdcpy(dst, ((tBTA_PAN_DATA_PARAMS*)p_buf)->dst);
+    src = ((tBTA_PAN_DATA_PARAMS*)p_buf)->src;
+    dst = ((tBTA_PAN_DATA_PARAMS*)p_buf)->dst;
     *p_protocol = ((tBTA_PAN_DATA_PARAMS*)p_buf)->protocol;
     *p_ext = ((tBTA_PAN_DATA_PARAMS*)p_buf)->ext;
     *p_forward = ((tBTA_PAN_DATA_PARAMS*)p_buf)->forward;
@@ -238,12 +239,14 @@
 void bta_pan_ci_tx_flow(UNUSED_ATTR uint16_t handle, UNUSED_ATTR bool enable) {}
 
 void bta_pan_ci_rx_writebuf(UNUSED_ATTR uint16_t handle,
-                            UNUSED_ATTR BD_ADDR src, UNUSED_ATTR BD_ADDR dst,
+                            UNUSED_ATTR const RawAddress& src,
+                            UNUSED_ATTR const RawAddress& dst,
                             UNUSED_ATTR uint16_t protocol,
                             UNUSED_ATTR BT_HDR* p_buf, UNUSED_ATTR bool ext) {}
 
-BT_HDR* bta_pan_ci_readbuf(UNUSED_ATTR uint16_t handle, UNUSED_ATTR BD_ADDR src,
-                           UNUSED_ATTR BD_ADDR dst,
+BT_HDR* bta_pan_ci_readbuf(UNUSED_ATTR uint16_t handle,
+                           UNUSED_ATTR RawAddress& src,
+                           UNUSED_ATTR RawAddress& dst,
                            UNUSED_ATTR uint16_t* p_protocol,
                            UNUSED_ATTR bool* p_ext,
                            UNUSED_ATTR bool* p_forward) {
diff --git a/bta/pan/bta_pan_int.h b/bta/pan/bta_pan_int.h
index 71658f2..089fd1d 100644
--- a/bta/pan/bta_pan_int.h
+++ b/bta/pan/bta_pan_int.h
@@ -87,7 +87,7 @@
   BT_HDR hdr;               /* Event header */
   tBTA_PAN_ROLE local_role; /* local role */
   tBTA_PAN_ROLE peer_role;  /* peer role */
-  BD_ADDR bd_addr;          /* peer bdaddr */
+  RawAddress bd_addr;       /* peer bdaddr */
 } tBTA_PAN_API_OPEN;
 
 /* data type for BTA_PAN_CI_TX_FLOW_EVT */
@@ -115,7 +115,7 @@
 
 /* state machine control block */
 typedef struct {
-  BD_ADDR bd_addr; /* peer bdaddr */
+  RawAddress bd_addr; /* peer bdaddr */
   fixed_queue_t*
       data_queue;    /* Queue of buffers waiting to be passed to application */
   uint16_t handle;   /* BTA PAN/BNEP handle */
@@ -143,8 +143,8 @@
 /* pan data param */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR src;
-  BD_ADDR dst;
+  RawAddress src;
+  RawAddress dst;
   uint16_t protocol;
   bool ext;
   bool forward;
diff --git a/bta/pan/bta_pan_main.cc b/bta/pan/bta_pan_main.cc
index 276e842..9ee5e0a 100644
--- a/bta/pan/bta_pan_main.cc
+++ b/bta/pan/bta_pan_main.cc
@@ -244,7 +244,7 @@
   if (p_scb != NULL) {
     bta_pan_open(p_scb, p_data);
   } else {
-    bdcpy(bta_pan.open.bd_addr, p_data->api_open.bd_addr);
+    bta_pan.open.bd_addr = p_data->api_open.bd_addr;
     bta_pan.open.status = BTA_PAN_FAIL;
     bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, &bta_pan);
   }
diff --git a/bta/sdp/bta_sdp_act.cc b/bta/sdp/bta_sdp_act.cc
index 9b8a8e0..172875f 100644
--- a/bta/sdp/bta_sdp_act.cc
+++ b/bta/sdp/bta_sdp_act.cc
@@ -395,7 +395,7 @@
 
   if (bta_sdp_cb.p_dm_cback == NULL) return;
 
-  bdcpy(evt_data.remote_addr, bta_sdp_cb.remote_addr);
+  evt_data.remote_addr = bta_sdp_cb.remote_addr;
   tBT_UUID* uuid = (tBT_UUID*)user_data;
   memcpy(&evt_data.uuid, uuid, sizeof(tBT_UUID));
   su = shorten_sdp_uuid(uuid);
@@ -447,7 +447,9 @@
   }
   evt_data.status = status;
 
-  bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&evt_data,
+  tBTA_SDP bta_sdp;
+  bta_sdp.sdp_search_comp = evt_data;
+  bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp,
                         (void*)&uuid->uu.uuid128);
   osi_free(user_data);  // We no longer need the user data to track the search
 }
@@ -465,7 +467,9 @@
   APPL_TRACE_DEBUG("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active);
   tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
   bta_sdp_cb.p_dm_cback = p_data->enable.p_cback;
-  bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, (tBTA_SDP*)&status, NULL);
+  tBTA_SDP bta_sdp;
+  bta_sdp.status = status;
+  bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, &bta_sdp, NULL);
 }
 
 /*******************************************************************************
@@ -493,15 +497,17 @@
       tBTA_SDP_SEARCH_COMP result;
       memset(&result, 0, sizeof(result));
       result.uuid = p_data->get_search.uuid;
-      bdcpy(result.remote_addr, p_data->get_search.bd_addr);
+      result.remote_addr = p_data->get_search.bd_addr;
       result.status = status;
-      bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&result, NULL);
+      tBTA_SDP bta_sdp;
+      bta_sdp.sdp_search_comp = result;
+      bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp, NULL);
     }
     return;
   }
 
   bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_YES;
-  bdcpy(bta_sdp_cb.remote_addr, p_data->get_search.bd_addr);
+  bta_sdp_cb.remote_addr = p_data->get_search.bd_addr;
   /* set the uuid used in the search */
   tBT_UUID* bta_sdp_search_uuid =
       static_cast<tBT_UUID*>(osi_malloc(sizeof(tBT_UUID)));
@@ -526,9 +532,11 @@
       tBTA_SDP_SEARCH_COMP result;
       memset(&result, 0, sizeof(result));
       result.uuid = p_data->get_search.uuid;
-      bdcpy(result.remote_addr, p_data->get_search.bd_addr);
+      result.remote_addr = p_data->get_search.bd_addr;
       result.status = status;
-      bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP*)&result, NULL);
+      tBTA_SDP bta_sdp;
+      bta_sdp.sdp_search_comp = result;
+      bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, &bta_sdp, NULL);
     }
   }
   /*
diff --git a/bta/sdp/bta_sdp_api.cc b/bta/sdp/bta_sdp_api.cc
index 7160423..bc6a9b9 100644
--- a/bta/sdp/bta_sdp_api.cc
+++ b/bta/sdp/bta_sdp_api.cc
@@ -87,14 +87,14 @@
  *                  BTA_SDP_FAILURE, otherwise.
  *
  ******************************************************************************/
-tBTA_SDP_STATUS BTA_SdpSearch(BD_ADDR bd_addr, tSDP_UUID* uuid) {
+tBTA_SDP_STATUS BTA_SdpSearch(const RawAddress& bd_addr, tSDP_UUID* uuid) {
   tBTA_SDP_API_SEARCH* p_msg =
       (tBTA_SDP_API_SEARCH*)osi_malloc(sizeof(tBTA_SDP_API_SEARCH));
 
   APPL_TRACE_API("%s", __func__);
 
   p_msg->hdr.event = BTA_SDP_API_SEARCH_EVT;
-  bdcpy(p_msg->bd_addr, bd_addr);
+  p_msg->bd_addr = bd_addr;
   // p_msg->uuid = uuid;
   memcpy(&(p_msg->uuid), uuid, sizeof(tSDP_UUID));
 
diff --git a/bta/sdp/bta_sdp_int.h b/bta/sdp/bta_sdp_int.h
index 21d814b..0cb5b93 100644
--- a/bta/sdp/bta_sdp_int.h
+++ b/bta/sdp/bta_sdp_int.h
@@ -58,7 +58,7 @@
 /* data type for BTA_SDP_API_SEARCH_EVT */
 typedef struct {
   BT_HDR hdr;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tSDP_UUID uuid;
 } tBTA_SDP_API_SEARCH;
 
@@ -80,7 +80,7 @@
 /* SDP control block */
 typedef struct {
   uint8_t sdp_active; /* see BTA_SDP_SDP_ACT_* */
-  BD_ADDR remote_addr;
+  RawAddress remote_addr;
   tBTA_SDP_DM_CBACK* p_dm_cback;
 } tBTA_SDP_CB;
 
diff --git a/bta/sys/bta_sys.h b/bta/sys/bta_sys.h
index 093952e..4edcfb3 100644
--- a/bta/sys/bta_sys.h
+++ b/bta/sys/bta_sys.h
@@ -28,6 +28,9 @@
 #include "bt_target.h"
 #include "osi/include/alarm.h"
 
+#include <base/logging.h>
+#include <base/threading/thread.h>
+
 /*****************************************************************************
  *  Constants and data types
  ****************************************************************************/
@@ -136,7 +139,7 @@
 
 /* conn callback for role / low power manager*/
 typedef void(tBTA_SYS_CONN_CBACK)(tBTA_SYS_CONN_STATUS status, uint8_t id,
-                                  uint8_t app_id, BD_ADDR peer_addr);
+                                  uint8_t app_id, const RawAddress* peer_addr);
 
 /* conn callback for role / low power manager*/
 typedef void(tBTA_SYS_SSR_CFG_CBACK)(uint8_t id, uint8_t app_id,
@@ -160,7 +163,6 @@
 } tBTA_SYS_HW_MSG;
 
 typedef void (*tBTA_SYS_REGISTER)(uint8_t id, const tBTA_SYS_REG* p_reg);
-typedef void (*tBTA_SYS_SENDMSG)(void* p_msg);
 
 /*****************************************************************************
  *  Global data
@@ -221,6 +223,8 @@
 extern bool bta_sys_is_register(uint8_t id);
 extern uint16_t bta_sys_get_sys_features(void);
 extern void bta_sys_sendmsg(void* p_msg);
+extern void do_in_bta_thread(const tracked_objects::Location& from_here,
+                             const base::Closure& task);
 extern void bta_sys_start_timer(alarm_t* alarm, period_ms_t interval,
                                 uint16_t event, uint16_t layer_specific);
 extern void bta_sys_disable(tBTA_SYS_HW_MODULE module);
@@ -235,16 +239,26 @@
 extern void bta_sys_policy_register(tBTA_SYS_CONN_CBACK* p_cback);
 extern void bta_sys_sco_register(tBTA_SYS_CONN_CBACK* p_cback);
 
-extern void bta_sys_conn_open(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_conn_close(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_app_open(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_app_close(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_sco_open(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_sco_close(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_sco_use(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_sco_unuse(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_idle(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
-extern void bta_sys_busy(uint8_t id, uint8_t app_id, BD_ADDR peer_addr);
+extern void bta_sys_conn_open(uint8_t id, uint8_t app_id,
+                              const RawAddress& peer_addr);
+extern void bta_sys_conn_close(uint8_t id, uint8_t app_id,
+                               const RawAddress& peer_addr);
+extern void bta_sys_app_open(uint8_t id, uint8_t app_id,
+                             const RawAddress& peer_addr);
+extern void bta_sys_app_close(uint8_t id, uint8_t app_id,
+                              const RawAddress& peer_addr);
+extern void bta_sys_sco_open(uint8_t id, uint8_t app_id,
+                             const RawAddress& peer_addr);
+extern void bta_sys_sco_close(uint8_t id, uint8_t app_id,
+                              const RawAddress& peer_addr);
+extern void bta_sys_sco_use(uint8_t id, uint8_t app_id,
+                            const RawAddress& peer_addr);
+extern void bta_sys_sco_unuse(uint8_t id, uint8_t app_id,
+                              const RawAddress& peer_addr);
+extern void bta_sys_idle(uint8_t id, uint8_t app_id,
+                         const RawAddress& peer_addr);
+extern void bta_sys_busy(uint8_t id, uint8_t app_id,
+                         const RawAddress& peer_addr);
 
 #if (BTM_SSR_INCLUDED == TRUE)
 extern void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK* p_cback);
@@ -253,11 +267,11 @@
 #endif
 
 extern void bta_sys_role_chg_register(tBTA_SYS_CONN_CBACK* p_cback);
-extern void bta_sys_notify_role_chg(BD_ADDR_PTR p_bda, uint8_t new_role,
+extern void bta_sys_notify_role_chg(const RawAddress& p_bda, uint8_t new_role,
                                     uint8_t hci_status);
 extern void bta_sys_collision_register(uint8_t bta_id,
                                        tBTA_SYS_CONN_CBACK* p_cback);
-extern void bta_sys_notify_collision(BD_ADDR_PTR p_bda);
+extern void bta_sys_notify_collision(const RawAddress& p_bda);
 
 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
 extern void bta_sys_eir_register(tBTA_SYS_EIR_CBACK* p_cback);
@@ -269,8 +283,10 @@
 #define bta_sys_remove_uuid(ut)
 #endif
 
-extern void bta_sys_set_policy(uint8_t id, uint8_t policy, BD_ADDR peer_addr);
-extern void bta_sys_clear_policy(uint8_t id, uint8_t policy, BD_ADDR peer_addr);
+extern void bta_sys_set_policy(uint8_t id, uint8_t policy,
+                               const RawAddress& peer_addr);
+extern void bta_sys_clear_policy(uint8_t id, uint8_t policy,
+                                 const RawAddress& peer_addr);
 extern void bta_sys_set_default_policy(uint8_t id, uint8_t policy);
 extern void bta_sys_clear_default_policy(uint8_t id, uint8_t policy);
 
diff --git a/bta/sys/bta_sys_conn.cc b/bta/sys/bta_sys_conn.cc
index 27967cc..6d9fc17 100644
--- a/bta/sys/bta_sys_conn.cc
+++ b/bta/sys/bta_sys_conn.cc
@@ -97,10 +97,10 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_notify_role_chg(BD_ADDR_PTR p_bda, uint8_t new_role,
+void bta_sys_notify_role_chg(const RawAddress& p_bda, uint8_t new_role,
                              uint8_t hci_status) {
   if (bta_sys_cb.p_role_cb) {
-    bta_sys_cb.p_role_cb(BTA_SYS_ROLE_CHANGE, new_role, hci_status, p_bda);
+    bta_sys_cb.p_role_cb(BTA_SYS_ROLE_CHANGE, new_role, hci_status, &p_bda);
   }
 }
 
@@ -137,13 +137,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_notify_collision(BD_ADDR_PTR p_bda) {
+void bta_sys_notify_collision(const RawAddress& p_bda) {
   uint8_t index;
 
   for (index = 0; index < MAX_COLLISION_REG; index++) {
     if ((bta_sys_cb.colli_reg.id[index] != 0) &&
         (bta_sys_cb.colli_reg.p_coll_cback[index] != NULL)) {
-      bta_sys_cb.colli_reg.p_coll_cback[index](0, BTA_ID_SYS, 0, p_bda);
+      bta_sys_cb.colli_reg.p_coll_cback[index](0, BTA_ID_SYS, 0, &p_bda);
     }
   }
 }
@@ -187,13 +187,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_conn_open(uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+void bta_sys_conn_open(uint8_t id, uint8_t app_id,
+                       const RawAddress& peer_addr) {
   if (bta_sys_cb.prm_cb) {
-    bta_sys_cb.prm_cb(BTA_SYS_CONN_OPEN, id, app_id, peer_addr);
+    bta_sys_cb.prm_cb(BTA_SYS_CONN_OPEN, id, app_id, &peer_addr);
   }
 
   if (bta_sys_cb.ppm_cb) {
-    bta_sys_cb.ppm_cb(BTA_SYS_CONN_OPEN, id, app_id, peer_addr);
+    bta_sys_cb.ppm_cb(BTA_SYS_CONN_OPEN, id, app_id, &peer_addr);
   }
 }
 
@@ -208,13 +209,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_conn_close(uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+void bta_sys_conn_close(uint8_t id, uint8_t app_id,
+                        const RawAddress& peer_addr) {
   if (bta_sys_cb.prm_cb) {
-    bta_sys_cb.prm_cb(BTA_SYS_CONN_CLOSE, id, app_id, peer_addr);
+    bta_sys_cb.prm_cb(BTA_SYS_CONN_CLOSE, id, app_id, &peer_addr);
   }
 
   if (bta_sys_cb.ppm_cb) {
-    bta_sys_cb.ppm_cb(BTA_SYS_CONN_CLOSE, id, app_id, peer_addr);
+    bta_sys_cb.ppm_cb(BTA_SYS_CONN_CLOSE, id, app_id, &peer_addr);
   }
 }
 
@@ -229,9 +231,9 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_app_open(uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+void bta_sys_app_open(uint8_t id, uint8_t app_id, const RawAddress& peer_addr) {
   if (bta_sys_cb.ppm_cb) {
-    bta_sys_cb.ppm_cb(BTA_SYS_APP_OPEN, id, app_id, peer_addr);
+    bta_sys_cb.ppm_cb(BTA_SYS_APP_OPEN, id, app_id, &peer_addr);
   }
 }
 
@@ -245,9 +247,10 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_app_close(uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+void bta_sys_app_close(uint8_t id, uint8_t app_id,
+                       const RawAddress& peer_addr) {
   if (bta_sys_cb.ppm_cb) {
-    bta_sys_cb.ppm_cb(BTA_SYS_APP_CLOSE, id, app_id, peer_addr);
+    bta_sys_cb.ppm_cb(BTA_SYS_APP_CLOSE, id, app_id, &peer_addr);
   }
 }
 
@@ -261,15 +264,15 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_sco_open(uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+void bta_sys_sco_open(uint8_t id, uint8_t app_id, const RawAddress& peer_addr) {
   /* AG triggers p_sco_cb by bta_sys_sco_use. */
   if ((id != BTA_ID_AG) && (bta_sys_cb.p_sco_cb)) {
     /* without querying BTM_GetNumScoLinks() */
-    bta_sys_cb.p_sco_cb(BTA_SYS_SCO_OPEN, 1, app_id, peer_addr);
+    bta_sys_cb.p_sco_cb(BTA_SYS_SCO_OPEN, 1, app_id, &peer_addr);
   }
 
   if (bta_sys_cb.ppm_cb) {
-    bta_sys_cb.ppm_cb(BTA_SYS_SCO_OPEN, id, app_id, peer_addr);
+    bta_sys_cb.ppm_cb(BTA_SYS_SCO_OPEN, id, app_id, &peer_addr);
   }
 }
 
@@ -283,16 +286,17 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_sco_close(uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+void bta_sys_sco_close(uint8_t id, uint8_t app_id,
+                       const RawAddress& peer_addr) {
   uint8_t num_sco_links;
 
   if ((id != BTA_ID_AG) && (bta_sys_cb.p_sco_cb)) {
     num_sco_links = BTM_GetNumScoLinks();
-    bta_sys_cb.p_sco_cb(BTA_SYS_SCO_CLOSE, num_sco_links, app_id, peer_addr);
+    bta_sys_cb.p_sco_cb(BTA_SYS_SCO_CLOSE, num_sco_links, app_id, &peer_addr);
   }
 
   if (bta_sys_cb.ppm_cb) {
-    bta_sys_cb.ppm_cb(BTA_SYS_SCO_CLOSE, id, app_id, peer_addr);
+    bta_sys_cb.ppm_cb(BTA_SYS_SCO_CLOSE, id, app_id, &peer_addr);
   }
 }
 
@@ -307,11 +311,11 @@
  *
  ******************************************************************************/
 void bta_sys_sco_use(UNUSED_ATTR uint8_t id, uint8_t app_id,
-                     BD_ADDR peer_addr) {
+                     const RawAddress& peer_addr) {
   /* AV streaming need to be suspended before SCO is connected. */
   if (bta_sys_cb.p_sco_cb) {
     /* without querying BTM_GetNumScoLinks() */
-    bta_sys_cb.p_sco_cb(BTA_SYS_SCO_OPEN, 1, app_id, peer_addr);
+    bta_sys_cb.p_sco_cb(BTA_SYS_SCO_OPEN, 1, app_id, &peer_addr);
   }
 }
 
@@ -325,13 +329,11 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_sco_unuse(UNUSED_ATTR uint8_t id, uint8_t app_id,
-                       BD_ADDR peer_addr) {
-  uint8_t num_sco_links;
-
+void bta_sys_sco_unuse(uint8_t id, uint8_t app_id,
+                       const RawAddress& peer_addr) {
   if ((bta_sys_cb.p_sco_cb)) {
-    num_sco_links = BTM_GetNumScoLinks();
-    bta_sys_cb.p_sco_cb(BTA_SYS_SCO_CLOSE, num_sco_links, app_id, peer_addr);
+    uint8_t num_sco_links = BTM_GetNumScoLinks();
+    bta_sys_cb.p_sco_cb(BTA_SYS_SCO_CLOSE, num_sco_links, app_id, &peer_addr);
   }
 }
 /*******************************************************************************
@@ -362,9 +364,10 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_set_policy(uint8_t id, uint8_t policy, BD_ADDR peer_addr) {
+void bta_sys_set_policy(uint8_t id, uint8_t policy,
+                        const RawAddress& peer_addr) {
   if (bta_sys_cb.p_policy_cb) {
-    bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_SET, id, policy, peer_addr);
+    bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_SET, id, policy, &peer_addr);
   }
 }
 
@@ -378,9 +381,10 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_clear_policy(uint8_t id, uint8_t policy, BD_ADDR peer_addr) {
+void bta_sys_clear_policy(uint8_t id, uint8_t policy,
+                          const RawAddress& peer_addr) {
   if (bta_sys_cb.p_policy_cb) {
-    bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_CLR, id, policy, peer_addr);
+    bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_CLR, id, policy, &peer_addr);
   }
 }
 
@@ -426,13 +430,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_idle(uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+void bta_sys_idle(uint8_t id, uint8_t app_id, const RawAddress& peer_addr) {
   if (bta_sys_cb.prm_cb) {
-    bta_sys_cb.prm_cb(BTA_SYS_CONN_IDLE, id, app_id, peer_addr);
+    bta_sys_cb.prm_cb(BTA_SYS_CONN_IDLE, id, app_id, &peer_addr);
   }
 
   if (bta_sys_cb.ppm_cb) {
-    bta_sys_cb.ppm_cb(BTA_SYS_CONN_IDLE, id, app_id, peer_addr);
+    bta_sys_cb.ppm_cb(BTA_SYS_CONN_IDLE, id, app_id, &peer_addr);
   }
 }
 
@@ -446,13 +450,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void bta_sys_busy(uint8_t id, uint8_t app_id, BD_ADDR peer_addr) {
+void bta_sys_busy(uint8_t id, uint8_t app_id, const RawAddress& peer_addr) {
   if (bta_sys_cb.prm_cb) {
-    bta_sys_cb.prm_cb(BTA_SYS_CONN_BUSY, id, app_id, peer_addr);
+    bta_sys_cb.prm_cb(BTA_SYS_CONN_BUSY, id, app_id, &peer_addr);
   }
 
   if (bta_sys_cb.ppm_cb) {
-    bta_sys_cb.ppm_cb(BTA_SYS_CONN_BUSY, id, app_id, peer_addr);
+    bta_sys_cb.ppm_cb(BTA_SYS_CONN_BUSY, id, app_id, &peer_addr);
   }
 }
 
diff --git a/bta/sys/bta_sys_main.cc b/bta/sys/bta_sys_main.cc
index 6386539..777f23a 100644
--- a/bta/sys/bta_sys_main.cc
+++ b/bta/sys/bta_sys_main.cc
@@ -32,7 +32,6 @@
 
 #include "bt_common.h"
 #include "bta_api.h"
-#include "bta_closure_int.h"
 #include "bta_sys.h"
 #include "bta_sys_int.h"
 #include "btm_api.h"
@@ -51,7 +50,6 @@
 /* system manager control block definition */
 tBTA_SYS_CB bta_sys_cb;
 
-fixed_queue_t* btu_bta_alarm_queue;
 extern thread_t* bt_workqueue_thread;
 
 /* trace level */
@@ -59,9 +57,6 @@
 uint8_t appl_trace_level = BT_TRACE_LEVEL_WARNING;  // APPL_INITIAL_TRACE_LEVEL;
 uint8_t btif_trace_level = BT_TRACE_LEVEL_WARNING;
 
-// Communication queue between btu_task and bta.
-extern fixed_queue_t* btu_bta_msg_queue;
-
 static const tBTA_SYS_REG bta_sys_hw_reg = {bta_sys_sm_execute, NULL};
 
 /* type for action functions */
@@ -180,10 +175,6 @@
 void bta_sys_init(void) {
   memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
 
-  btu_bta_alarm_queue = fixed_queue_new(SIZE_MAX);
-
-  alarm_register_processing_queue(btu_bta_alarm_queue, bt_workqueue_thread);
-
   appl_trace_level = APPL_INITIAL_TRACE_LEVEL;
 
   /* register BTA SYS message handler */
@@ -195,14 +186,9 @@
 #if (defined BTA_AR_INCLUDED) && (BTA_AR_INCLUDED == true)
   bta_ar_init();
 #endif
-
-  bta_closure_init(bta_sys_register, bta_sys_sendmsg);
 }
 
 void bta_sys_free(void) {
-  alarm_unregister_processing_queue(btu_bta_alarm_queue);
-  fixed_queue_free(btu_bta_alarm_queue, NULL);
-  btu_bta_alarm_queue = NULL;
 }
 
 /*******************************************************************************
@@ -553,6 +539,27 @@
 
 /*******************************************************************************
  *
+ * Function         do_in_bta_thread
+ *
+ * Description      Post a closure to be ran in the bta thread
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+void do_in_bta_thread(const tracked_objects::Location& from_here,
+                      const base::Closure& task) {
+  base::MessageLoop* bta_message_loop = get_message_loop();
+
+  if (!bta_message_loop || !bta_message_loop->task_runner().get()) {
+    APPL_TRACE_ERROR("%s: MessageLooper not initialized", __func__);
+    return;
+  }
+
+  bta_message_loop->task_runner()->PostTask(from_here, task);
+}
+
+/*******************************************************************************
+ *
  * Function         bta_sys_start_timer
  *
  * Description      Start a protocol timer for the specified amount
@@ -568,8 +575,7 @@
   p_buf->event = event;
   p_buf->layer_specific = layer_specific;
 
-  alarm_set_on_queue(alarm, interval, bta_sys_sendmsg, p_buf,
-                     btu_bta_alarm_queue);
+  alarm_set_on_mloop(alarm, interval, bta_sys_sendmsg, p_buf);
 }
 
 /*******************************************************************************
diff --git a/bta/test/bta_closure_test.cc b/bta/test/bta_closure_test.cc
deleted file mode 100644
index 9e1e4bb..0000000
--- a/bta/test/bta_closure_test.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2016 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 <gtest/gtest.h>
-#include <queue>
-
-#include "bta/closure/bta_closure_int.h"
-#include "bta/include/bta_closure_api.h"
-#include "include/bt_trace.h"
-
-namespace {
-
-/* There is no test class, because we talk to C code that accepts plain
- * functions as arguments.
- */
-
-int test_counter = 0;
-tBTA_SYS_EVT_HDLR* closure_handler = NULL;
-std::queue<BT_HDR*> msgs;
-
-void test_plus_one_task() { test_counter++; }
-
-void test_plus_two_task() { test_counter += 2; }
-
-void fake_bta_sys_sendmsg(void* p_msg) { msgs.push((BT_HDR*)p_msg); }
-
-void fake_bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg) {
-  closure_handler = p_reg->evt_hdlr;
-}
-
-bool fake_bta_sys_sendmsg_execute() {
-  BT_HDR* p_msg = msgs.front();
-  msgs.pop();
-  return closure_handler(p_msg);
-}
-
-}  // namespace
-
-// TODO(jpawlowski): there is some weird dependency issue in tests, and the
-// tests here fail to compile without this definition.
-void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}
-
-TEST(ClosureTest, test_post_task) {
-  test_counter = 0;
-
-  bta_closure_init(fake_bta_sys_register, fake_bta_sys_sendmsg);
-
-  do_in_bta_thread(FROM_HERE, base::Bind(&test_plus_one_task));
-  EXPECT_EQ(1U, msgs.size()) << "Message should not be NULL";
-
-  EXPECT_TRUE(fake_bta_sys_sendmsg_execute());
-  EXPECT_EQ(1, test_counter);
-}
-
-TEST(ClosureTest, test_post_multiple_tasks) {
-  test_counter = 0;
-
-  bta_closure_init(fake_bta_sys_register, fake_bta_sys_sendmsg);
-
-  do_in_bta_thread(FROM_HERE, base::Bind(&test_plus_one_task));
-  do_in_bta_thread(FROM_HERE, base::Bind(&test_plus_two_task));
-  do_in_bta_thread(FROM_HERE, base::Bind(&test_plus_one_task));
-  do_in_bta_thread(FROM_HERE, base::Bind(&test_plus_two_task));
-  do_in_bta_thread(FROM_HERE, base::Bind(&test_plus_one_task));
-  do_in_bta_thread(FROM_HERE, base::Bind(&test_plus_two_task));
-
-  EXPECT_EQ(6U, msgs.size());
-
-  EXPECT_TRUE(fake_bta_sys_sendmsg_execute());
-  EXPECT_EQ(1, test_counter);
-
-  EXPECT_TRUE(fake_bta_sys_sendmsg_execute());
-  EXPECT_EQ(3, test_counter);
-
-  EXPECT_TRUE(fake_bta_sys_sendmsg_execute());
-  EXPECT_EQ(4, test_counter);
-
-  EXPECT_TRUE(fake_bta_sys_sendmsg_execute());
-  EXPECT_EQ(6, test_counter);
-
-  EXPECT_TRUE(fake_bta_sys_sendmsg_execute());
-  EXPECT_EQ(7, test_counter);
-
-  EXPECT_TRUE(fake_bta_sys_sendmsg_execute());
-  EXPECT_EQ(9, test_counter);
-}
diff --git a/bta/test/bta_hf_client_test.cc b/bta/test/bta_hf_client_test.cc
index 72a60a3..01d9f5f 100644
--- a/bta/test/bta_hf_client_test.cc
+++ b/bta/test/bta_hf_client_test.cc
@@ -21,11 +21,21 @@
 #include "bta/hf_client/bta_hf_client_int.h"
 #include "bta/include/bta_hf_client_api.h"
 
+namespace base {
+class MessageLoop;
+}  // namespace base
+
+base::MessageLoop* get_message_loop() { return NULL; }
+
 namespace {
-const BD_ADDR bdaddr1 = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
-const BD_ADDR bdaddr2 = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
+const RawAddress bdaddr1({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
+const RawAddress bdaddr2({0x66, 0x55, 0x44, 0x33, 0x22, 0x11});
 }  // namespace
 
+// TODO(jpawlowski): there is some weird dependency issue in tests, and the
+// tests here fail to compile without this definition.
+void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}
+
 class BtaHfClientTest : public testing::Test {
  protected:
   void SetUp() override {
diff --git a/btcore/Android.bp b/btcore/Android.bp
index 442cc60..3984098 100644
--- a/btcore/Android.bp
+++ b/btcore/Android.bp
@@ -6,7 +6,6 @@
     local_include_dirs: ["include"],
     include_dirs: ["system/bt"],
     srcs: [
-        "src/bdaddr.cc",
         "src/device_class.cc",
         "src/hal_util.cc",
         "src/module.cc",
@@ -39,7 +38,6 @@
     local_include_dirs: ["include"],
     include_dirs: ["system/bt"],
     srcs: [
-        "test/bdaddr_test.cc",
         "test/device_class_test.cc",
         "test/property_test.cc",
         "test/uuid_test.cc",
diff --git a/btcore/BUILD.gn b/btcore/BUILD.gn
index dc4da9e..01d5ec1 100644
--- a/btcore/BUILD.gn
+++ b/btcore/BUILD.gn
@@ -16,7 +16,6 @@
 
 static_library("btcore") {
   sources = [
-    "src/bdaddr.cc",
     "src/device_class.cc",
     "src/hal_util.cc",
     "src/module.cc",
@@ -52,6 +51,7 @@
   deps = [
     "//btcore",
     "//osi",
+    "//types",
     "//third_party/googletest:gtest_main",
     "//third_party/libchrome:base",
   ]
diff --git a/btcore/include/bdaddr.h b/btcore/include/bdaddr.h
deleted file mode 100644
index 9dabc5d..0000000
--- a/btcore/include/bdaddr.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 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.
- *
- ******************************************************************************/
-
-#pragma once
-
-#include <hardware/bluetooth.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-// Note: the string representation of a bdaddr is expected to have the format
-// xx:xx:xx:xx:xx:xx
-// where each 'x' is a hex digit. The API presented in this header will accept
-// both uppercase and lowercase digits but will only ever produce lowercase
-// digits.
-
-typedef char bdstr_t[sizeof("xx:xx:xx:xx:xx:xx")];
-
-// Returns true if |addr| is the empty address (00:00:00:00:00:00).
-// |addr| may not be NULL.
-bool bdaddr_is_empty(const bt_bdaddr_t* addr);
-
-// Returns true if |first| and |second| refer to the same address. Neither
-// may be NULL.
-bool bdaddr_equals(const bt_bdaddr_t* first, const bt_bdaddr_t* second);
-
-// Returns destination bdaddr |dest| after copying |src| to |dest|.
-// |dest| and |src| must not be NULL.
-bt_bdaddr_t* bdaddr_copy(bt_bdaddr_t* dest, const bt_bdaddr_t* src);
-
-// Makes a string representation of |addr| and places it into |string|. |size|
-// refers to the size of |string|'s buffer and must be >= 18. On success, this
-// function returns |string|, otherwise it returns NULL. Neither |addr| nor
-// |string| may be NULL.
-const char* bdaddr_to_string(const bt_bdaddr_t* addr, char* string,
-                             size_t size);
-
-// Returns true if |string| represents a Bluetooth address. |string| may not be
-// NULL.
-bool string_is_bdaddr(const char* string);
-
-// Converts |string| to bt_bdaddr_t and places it in |addr|. If |string| does
-// not represent a Bluetooth address, |addr| is not modified and this function
-// returns false. Otherwise, it returns true. Neither |string| nor |addr| may be
-// NULL.
-bool string_to_bdaddr(const char* string, bt_bdaddr_t* addr);
diff --git a/btcore/include/property.h b/btcore/include/property.h
index 010c995..40e2f2a 100644
--- a/btcore/include/property.h
+++ b/btcore/include/property.h
@@ -41,7 +41,7 @@
 // using |property_free| or |property_free_array|.
 // Parameter must not be NULL. A copy of the parameter is made and
 // stored in the property.
-bt_property_t* property_new_addr(const bt_bdaddr_t* addr);
+bt_property_t* property_new_addr(const RawAddress* addr);
 bt_property_t* property_new_device_class(const bt_device_class_t* dc);
 bt_property_t* property_new_device_type(bt_device_type_t device_type);
 bt_property_t* property_new_discovery_timeout(const uint32_t timeout);
@@ -68,7 +68,7 @@
 
 // Value conversion convenience methods. The contents of the property are
 // properly typed and returned to the caller. |property| must not be NULL.
-const bt_bdaddr_t* property_as_addr(const bt_property_t* property);
+const RawAddress* property_as_addr(const bt_property_t* property);
 const bt_device_class_t* property_as_device_class(
     const bt_property_t* property);
 bt_device_type_t property_as_device_type(const bt_property_t* property);
diff --git a/btcore/src/bdaddr.cc b/btcore/src/bdaddr.cc
deleted file mode 100644
index c0fb2f0..0000000
--- a/btcore/src/bdaddr.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 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 <ctype.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "btcore/include/bdaddr.h"
-
-bool bdaddr_is_empty(const bt_bdaddr_t* addr) {
-  CHECK(addr != NULL);
-
-  uint8_t zero[sizeof(bt_bdaddr_t)] = {0};
-  return memcmp(addr, &zero, sizeof(bt_bdaddr_t)) == 0;
-}
-
-bool bdaddr_equals(const bt_bdaddr_t* first, const bt_bdaddr_t* second) {
-  CHECK(first != NULL);
-  CHECK(second != NULL);
-
-  return memcmp(first, second, sizeof(bt_bdaddr_t)) == 0;
-}
-
-bt_bdaddr_t* bdaddr_copy(bt_bdaddr_t* dest, const bt_bdaddr_t* src) {
-  CHECK(dest != NULL);
-  CHECK(src != NULL);
-
-  return (bt_bdaddr_t*)memcpy(dest, src, sizeof(bt_bdaddr_t));
-}
-
-const char* bdaddr_to_string(const bt_bdaddr_t* addr, char* string,
-                             size_t size) {
-  CHECK(addr != NULL);
-  CHECK(string != NULL);
-
-  if (size < 18) return NULL;
-
-  const uint8_t* ptr = addr->address;
-  snprintf(string, size, "%02x:%02x:%02x:%02x:%02x:%02x", ptr[0], ptr[1],
-           ptr[2], ptr[3], ptr[4], ptr[5]);
-  return string;
-}
-
-bool string_is_bdaddr(const char* string) {
-  CHECK(string != NULL);
-
-  size_t len = strlen(string);
-  if (len != 17) return false;
-
-  for (size_t i = 0; i < len; ++i) {
-    // Every 3rd char must be ':'.
-    if (((i + 1) % 3) == 0 && string[i] != ':') return false;
-
-    // All other chars must be a hex digit.
-    if (((i + 1) % 3) != 0 && !isxdigit(string[i])) return false;
-  }
-  return true;
-}
-
-bool string_to_bdaddr(const char* string, bt_bdaddr_t* addr) {
-  CHECK(string != NULL);
-  CHECK(addr != NULL);
-
-  bt_bdaddr_t new_addr;
-  uint8_t* ptr = new_addr.address;
-  bool ret = sscanf(string, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
-                    &ptr[0], &ptr[1], &ptr[2], &ptr[3], &ptr[4], &ptr[5]) == 6;
-
-  if (ret) memcpy(addr, &new_addr, sizeof(bt_bdaddr_t));
-
-  return ret;
-}
diff --git a/btcore/src/property.cc b/btcore/src/property.cc
index 2049131..1e314f0 100644
--- a/btcore/src/property.cc
+++ b/btcore/src/property.cc
@@ -19,7 +19,6 @@
 #include "btcore/include/property.h"
 #include <base/logging.h>
 #include <string.h>
-#include "btcore/include/bdaddr.h"
 #include "btcore/include/device_class.h"
 #include "btcore/include/uuid.h"
 #include "osi/include/allocator.h"
@@ -76,9 +75,9 @@
   return p1->len == p2->len && !memcmp(p1->val, p2->val, p1->len);
 }
 
-bt_property_t* property_new_addr(const bt_bdaddr_t* addr) {
+bt_property_t* property_new_addr(const RawAddress* addr) {
   CHECK(addr != NULL);
-  return property_new_((void*)addr, sizeof(bt_bdaddr_t), BT_PROPERTY_BDADDR);
+  return property_new_((void*)addr, sizeof(RawAddress), BT_PROPERTY_BDADDR);
 }
 
 bt_property_t* property_new_device_class(const bt_device_class_t* dc) {
@@ -172,9 +171,9 @@
 }
 
 // Convenience conversion methods to property values
-const bt_bdaddr_t* property_as_addr(const bt_property_t* property) {
+const RawAddress* property_as_addr(const bt_property_t* property) {
   CHECK(property_is_addr(property));
-  return (const bt_bdaddr_t*)property->val;
+  return (const RawAddress*)property->val;
 }
 
 const bt_device_class_t* property_as_device_class(
diff --git a/btcore/test/bdaddr_test.cc b/btcore/test/bdaddr_test.cc
deleted file mode 100644
index 573a09b..0000000
--- a/btcore/test/bdaddr_test.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 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 <gtest/gtest.h>
-
-#include "btcore/include/bdaddr.h"
-
-static const char* test_addr = "12:34:56:78:9a:bc";
-static const char* test_addr2 = "cb:a9:87:65:43:21";
-
-TEST(BdaddrTest, test_empty) {
-  bt_bdaddr_t empty;
-  string_to_bdaddr("00:00:00:00:00:00", &empty);
-  ASSERT_TRUE(bdaddr_is_empty(&empty));
-
-  bt_bdaddr_t not_empty;
-  string_to_bdaddr("00:00:00:00:00:01", &not_empty);
-  ASSERT_FALSE(bdaddr_is_empty(&not_empty));
-}
-
-TEST(BdaddrTest, test_to_from_str) {
-  char ret[19];
-  bt_bdaddr_t bdaddr;
-  string_to_bdaddr(test_addr, &bdaddr);
-
-  ASSERT_EQ(0x12, bdaddr.address[0]);
-  ASSERT_EQ(0x34, bdaddr.address[1]);
-  ASSERT_EQ(0x56, bdaddr.address[2]);
-  ASSERT_EQ(0x78, bdaddr.address[3]);
-  ASSERT_EQ(0x9A, bdaddr.address[4]);
-  ASSERT_EQ(0xBC, bdaddr.address[5]);
-
-  bdaddr_to_string(&bdaddr, ret, sizeof(ret));
-
-  ASSERT_STREQ(test_addr, ret);
-}
-
-TEST(BdaddrTest, test_equals) {
-  bt_bdaddr_t bdaddr1;
-  bt_bdaddr_t bdaddr2;
-  bt_bdaddr_t bdaddr3;
-  string_to_bdaddr(test_addr, &bdaddr1);
-  string_to_bdaddr(test_addr, &bdaddr2);
-  EXPECT_TRUE(bdaddr_equals(&bdaddr1, &bdaddr2));
-
-  string_to_bdaddr(test_addr2, &bdaddr3);
-  EXPECT_FALSE(bdaddr_equals(&bdaddr2, &bdaddr3));
-}
-
-TEST(BdaddrTest, test_copy) {
-  bt_bdaddr_t bdaddr1;
-  bt_bdaddr_t bdaddr2;
-  string_to_bdaddr(test_addr, &bdaddr1);
-  bdaddr_copy(&bdaddr2, &bdaddr1);
-
-  EXPECT_TRUE(bdaddr_equals(&bdaddr1, &bdaddr2));
-}
diff --git a/btcore/test/property_test.cc b/btcore/test/property_test.cc
index fbf5f9a..e87c186 100644
--- a/btcore/test/property_test.cc
+++ b/btcore/test/property_test.cc
@@ -25,7 +25,7 @@
 class PropertyTest : public AllocationTestHarness {};
 
 TEST_F(PropertyTest, addr) {
-  bt_bdaddr_t addr0 = {{0x1, 0x2, 0x3, 0x4, 0x5, 0x6}};
+  RawAddress addr0 = {{0x1, 0x2, 0x3, 0x4, 0x5, 0x6}};
   bt_property_t* property = property_new_addr(&addr0);
 
   EXPECT_EQ(addr0.address[0], ((uint8_t*)property->val)[0]);
@@ -35,9 +35,9 @@
   EXPECT_EQ(addr0.address[4], ((uint8_t*)property->val)[4]);
   EXPECT_EQ(addr0.address[5], ((uint8_t*)property->val)[5]);
   EXPECT_EQ(BT_PROPERTY_BDADDR, property->type);
-  EXPECT_EQ((int)sizeof(bt_bdaddr_t), property->len);
+  EXPECT_EQ((int)sizeof(RawAddress), property->len);
 
-  const bt_bdaddr_t* addr1 = property_as_addr(property);
+  const RawAddress* addr1 = property_as_addr(property);
   EXPECT_EQ(addr0.address[0], addr1->address[0]);
 
   property_free(property);
@@ -174,7 +174,7 @@
 
 TEST_F(PropertyTest, equals) {
   {
-    bt_bdaddr_t addr0 = {{0x1, 0x2, 0x3, 0x4, 0x5, 0x6}};
+    RawAddress addr0 = {{0x1, 0x2, 0x3, 0x4, 0x5, 0x6}};
     bt_property_t* property0 = property_new_addr(&addr0);
 
     bt_device_class_t dc0 = {{0x01, 0x23, 0x45}};
@@ -187,7 +187,7 @@
   }
 
   {
-    bt_bdaddr_t addr = {{0x1, 0x2, 0x3, 0x4, 0x5, 0x6}};
+    RawAddress addr = {{0x1, 0x2, 0x3, 0x4, 0x5, 0x6}};
     bt_property_t* property0 = property_new_addr(&addr);
     bt_property_t* property1 = property_new_addr(&addr);
 
@@ -198,10 +198,10 @@
   }
 
   {
-    bt_bdaddr_t addr0 = {{0x1, 0x2, 0x3, 0x4, 0x5, 0x6}};
+    RawAddress addr0 = {{0x1, 0x2, 0x3, 0x4, 0x5, 0x6}};
     bt_property_t* property0 = property_new_addr(&addr0);
 
-    bt_bdaddr_t addr1 = {{0x1, 0x2, 0x3, 0x4, 0x5, 0xff}};
+    RawAddress addr1 = {{0x1, 0x2, 0x3, 0x4, 0x5, 0xff}};
     bt_property_t* property1 = property_new_addr(&addr1);
 
     EXPECT_FALSE(property_equals(property0, property1));
diff --git a/btif/Android.bp b/btif/Android.bp
index c94b767..c5ff076 100644
--- a/btif/Android.bp
+++ b/btif/Android.bp
@@ -115,6 +115,7 @@
         "libbtcore",
         "libbtif",
         "libbt-stack",
+        "libbluetooth-types",
         "libosi",
     ],
     cflags: ["-DBUILDCFG"],
@@ -136,7 +137,7 @@
         "libcutils",
     ],
     static_libs: [
-        "libbtcore",
+        "libbluetooth-types",
         "libosi",
     ],
     cflags: ["-DBUILDCFG"],
diff --git a/btif/co/bta_av_co.cc b/btif/co/bta_av_co.cc
index 687499a..e931714 100644
--- a/btif/co/bta_av_co.cc
+++ b/btif/co/bta_av_co.cc
@@ -65,7 +65,7 @@
 } tBTA_AV_CO_SINK;
 
 typedef struct {
-  BD_ADDR addr; /* address of audio/video peer */
+  RawAddress addr; /* address of audio/video peer */
   tBTA_AV_CO_SINK
       sinks[BTAV_A2DP_CODEC_INDEX_MAX]; /* array of supported sinks */
   tBTA_AV_CO_SINK srcs[BTAV_A2DP_CODEC_INDEX_MAX]; /* array of supported srcs */
@@ -239,8 +239,8 @@
  **
  ******************************************************************************/
 void bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl, uint8_t num_seps,
-                              uint8_t num_sink, uint8_t num_src, BD_ADDR addr,
-                              uint16_t uuid_local) {
+                              uint8_t num_sink, uint8_t num_src,
+                              const RawAddress& addr, uint16_t uuid_local) {
   tBTA_AV_CO_PEER* p_peer;
 
   APPL_TRACE_DEBUG("%s: h:x%x num_seps:%d num_sink:%d num_src:%d", __func__,
@@ -259,7 +259,7 @@
   }
 
   /* Copy the discovery results */
-  bdcpy(p_peer->addr, addr);
+  p_peer->addr = addr;
   p_peer->num_sinks = num_sink;
   p_peer->num_srcs = num_src;
   p_peer->num_seps = num_seps;
@@ -493,7 +493,8 @@
  ******************************************************************************/
 void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, const uint8_t* p_codec_info,
                                UNUSED_ATTR uint8_t seid,
-                               UNUSED_ATTR BD_ADDR addr, uint8_t num_protect,
+                               UNUSED_ATTR const RawAddress& addr,
+                               uint8_t num_protect,
                                const uint8_t* p_protect_info,
                                uint8_t t_local_sep, uint8_t avdt_handle) {
   tBTA_AV_CO_PEER* p_peer;
diff --git a/btif/co/bta_dm_co.cc b/btif/co/bta_dm_co.cc
index 7a64bec..f6c7c1c 100644
--- a/btif/co/bta_dm_co.cc
+++ b/btif/co/bta_dm_co.cc
@@ -69,9 +69,9 @@
  * Returns          void.
  *
  ******************************************************************************/
-void bta_dm_co_io_req(UNUSED_ATTR BD_ADDR bd_addr, tBTA_IO_CAP* p_io_cap,
-                      tBTA_OOB_DATA* p_oob_data, tBTA_AUTH_REQ* p_auth_req,
-                      bool is_orig) {
+void bta_dm_co_io_req(UNUSED_ATTR const RawAddress& bd_addr,
+                      tBTA_IO_CAP* p_io_cap, tBTA_OOB_DATA* p_oob_data,
+                      tBTA_AUTH_REQ* p_auth_req, bool is_orig) {
   btif_dm_set_oob_for_io_req(p_oob_data);
   btif_dm_proc_io_req(bd_addr, p_io_cap, p_oob_data, p_auth_req, is_orig);
   BTIF_TRACE_DEBUG("bta_dm_co_io_req *p_oob_data = %d", *p_oob_data);
@@ -97,7 +97,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-void bta_dm_co_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
+void bta_dm_co_io_rsp(const RawAddress& bd_addr, tBTA_IO_CAP io_cap,
                       tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req) {
   btif_dm_proc_io_rsp(bd_addr, io_cap, oob_data, auth_req);
 }
@@ -115,7 +115,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-void bta_dm_co_lk_upgrade(UNUSED_ATTR BD_ADDR bd_addr,
+void bta_dm_co_lk_upgrade(UNUSED_ATTR const RawAddress& bd_addr,
                           UNUSED_ATTR bool* p_upgrade) {}
 
 /*******************************************************************************
@@ -152,7 +152,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-void bta_dm_co_rmt_oob(BD_ADDR bd_addr) {
+void bta_dm_co_rmt_oob(const RawAddress& bd_addr) {
   BT_OCTET16 p_c;
   BT_OCTET16 p_r;
   bool result = false;
@@ -274,7 +274,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-void bta_dm_co_le_io_key_req(UNUSED_ATTR BD_ADDR bd_addr,
+void bta_dm_co_le_io_key_req(UNUSED_ATTR const RawAddress& bd_addr,
                              uint8_t* p_max_key_size,
                              tBTA_LE_KEY_TYPE* p_init_key,
                              tBTA_LE_KEY_TYPE* p_resp_key) {
@@ -329,7 +329,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-void bta_dm_co_ble_io_req(UNUSED_ATTR BD_ADDR bd_addr, tBTA_IO_CAP* p_io_cap,
+void bta_dm_co_ble_io_req(const RawAddress& bd_addr, tBTA_IO_CAP* p_io_cap,
                           tBTA_OOB_DATA* p_oob_data,
                           tBTA_LE_AUTH_REQ* p_auth_req, uint8_t* p_max_key_size,
                           tBTA_LE_KEY_TYPE* p_init_key,
diff --git a/btif/co/bta_gatts_co.cc b/btif/co/bta_gatts_co.cc
index 24aea15..0466291 100644
--- a/btif/co/bta_gatts_co.cc
+++ b/btif/co/bta_gatts_co.cc
@@ -60,7 +60,7 @@
  *  Externally called functions
  ****************************************************************************/
 
-void btif_gatts_add_bonded_dev_from_nv(BD_ADDR bda) {
+void btif_gatts_add_bonded_dev_from_nv(const RawAddress& bda) {
   btif_gatts_srv_chg_cb_t* p_cb = &btif_gatts_srv_chg_cb;
   bool found = false;
   uint8_t i;
@@ -68,7 +68,7 @@
   btif_gatts_check_init();
 
   for (i = 0; i != p_cb->num_clients; ++i) {
-    if (!memcmp(p_cb->srv_chg[i].bda, bda, sizeof(BD_ADDR))) {
+    if (p_cb->srv_chg[i].bda == bda) {
       found = true;
       break;
     }
@@ -76,7 +76,7 @@
 
   if (!found) {
     if (p_cb->num_clients < BTIF_GATTS_MAX_SRV_CHG_CLT_SIZE) {
-      bdcpy(p_cb->srv_chg[p_cb->num_clients].bda, bda);
+      p_cb->srv_chg[p_cb->num_clients].bda = bda;
       p_cb->srv_chg[p_cb->num_clients].srv_changed = false;
       p_cb->num_clients++;
     }
diff --git a/btif/co/bta_hh_co.cc b/btif/co/bta_hh_co.cc
index 797bd42..f6bc7cf 100644
--- a/btif/co/bta_hh_co.cc
+++ b/btif/co/bta_hh_co.cc
@@ -31,7 +31,6 @@
 #include "bta_api.h"
 #include "bta_hh_api.h"
 #include "bta_hh_co.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_hh.h"
 #include "btif_util.h"
 #include "osi/include/osi.h"
@@ -403,7 +402,7 @@
  ******************************************************************************/
 void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len,
                     tBTA_HH_PROTO_MODE mode, uint8_t sub_class,
-                    uint8_t ctry_code, UNUSED_ATTR BD_ADDR peer_addr,
+                    uint8_t ctry_code, UNUSED_ATTR const RawAddress& peer_addr,
                     uint8_t app_id) {
   btif_hh_device_t* p_dev;
 
@@ -520,14 +519,13 @@
  * Returns          void.
  *
  ******************************************************************************/
-void bta_hh_le_co_rpt_info(BD_ADDR remote_bda, tBTA_HH_RPT_CACHE_ENTRY* p_entry,
+void bta_hh_le_co_rpt_info(const RawAddress& remote_bda,
+                           tBTA_HH_RPT_CACHE_ENTRY* p_entry,
                            UNUSED_ATTR uint8_t app_id) {
   unsigned idx = 0;
 
-  bdstr_t bdstr;
-  snprintf(bdstr, sizeof(bdstr), "%02x:%02x:%02x:%02x:%02x:%02x", remote_bda[0],
-           remote_bda[1], remote_bda[2], remote_bda[3], remote_bda[4],
-           remote_bda[5]);
+  std::string addrstr = remote_bda.ToString();
+  const char* bdstr = addrstr.c_str();
 
   size_t len = btif_config_get_bin_length(bdstr, "HidReport");
   if (len >= sizeof(tBTA_HH_RPT_CACHE_ENTRY) && len <= sizeof(sReportCache)) {
@@ -560,13 +558,11 @@
  * Returns          the acched report array
  *
  ******************************************************************************/
-tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(BD_ADDR remote_bda,
+tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const RawAddress& remote_bda,
                                                  uint8_t* p_num_rpt,
                                                  UNUSED_ATTR uint8_t app_id) {
-  bdstr_t bdstr;
-  snprintf(bdstr, sizeof(bdstr), "%02x:%02x:%02x:%02x:%02x:%02x", remote_bda[0],
-           remote_bda[1], remote_bda[2], remote_bda[3], remote_bda[4],
-           remote_bda[5]);
+  std::string addrstr = remote_bda.ToString();
+  const char* bdstr = addrstr.c_str();
 
   size_t len = btif_config_get_bin_length(bdstr, "HidReport");
   if (!p_num_rpt && len < sizeof(tBTA_HH_RPT_CACHE_ENTRY)) return NULL;
@@ -592,12 +588,11 @@
  * Returns          none
  *
  ******************************************************************************/
-void bta_hh_le_co_reset_rpt_cache(BD_ADDR remote_bda,
+void bta_hh_le_co_reset_rpt_cache(const RawAddress& remote_bda,
                                   UNUSED_ATTR uint8_t app_id) {
-  bdstr_t bdstr;
-  snprintf(bdstr, sizeof(bdstr), "%02x:%02x:%02x:%02x:%02x:%02x", remote_bda[0],
-           remote_bda[1], remote_bda[2], remote_bda[3], remote_bda[4],
-           remote_bda[5]);
+  std::string addrstr = remote_bda.ToString();
+  const char* bdstr = addrstr.c_str();
+
   btif_config_remove(bdstr, "HidReport");
 
   BTIF_TRACE_DEBUG("%s() - Reset cache for bda %s", __func__, bdstr);
diff --git a/btif/co/bta_pan_co.cc b/btif/co/bta_pan_co.cc
index ea5231a..1868c78 100644
--- a/btif/co/bta_pan_co.cc
+++ b/btif/co/bta_pan_co.cc
@@ -25,6 +25,7 @@
  *
  ******************************************************************************/
 #include "bta_pan_co.h"
+#include <base/logging.h>
 #include <hardware/bluetooth.h>
 #include <hardware/bt_pan.h>
 #include <string.h>
@@ -32,7 +33,6 @@
 #include "bta_api.h"
 #include "bta_pan_api.h"
 #include "bta_pan_ci.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_pan_internal.h"
 #include "btif_sock_thread.h"
 #include "btif_util.h"
@@ -73,7 +73,7 @@
  *
  ******************************************************************************/
 void bta_pan_co_open(uint16_t handle, uint8_t app_id, tBTA_PAN_ROLE local_role,
-                     tBTA_PAN_ROLE peer_role, BD_ADDR peer_addr) {
+                     tBTA_PAN_ROLE peer_role, const RawAddress& peer_addr) {
   BTIF_TRACE_API(
       "bta_pan_co_open:app_id:%d, local_role:%d, peer_role:%d, "
       "handle:%d",
@@ -91,7 +91,7 @@
 
     btpan_cb.open_count++;
     conn->handle = handle;
-    // bdcpy(conn->peer, peer_addr);
+    // conn->peer = peer_addr;
     if (btpan_cb.tap_fd < 0) {
       btpan_cb.tap_fd = btpan_tap_open();
       if (btpan_cb.tap_fd >= 0) create_tap_read_thread(btpan_cb.tap_fd);
@@ -153,8 +153,8 @@
  ******************************************************************************/
 void bta_pan_co_tx_path(uint16_t handle, uint8_t app_id) {
   BT_HDR* p_buf;
-  BD_ADDR src;
-  BD_ADDR dst;
+  RawAddress src;
+  RawAddress dst;
   uint16_t protocol;
   bool ext;
   bool forward;
@@ -175,20 +175,14 @@
     /* read next data buffer from pan */
     p_buf = bta_pan_ci_readbuf(handle, src, dst, &protocol, &ext, &forward);
     if (p_buf) {
-      bdstr_t bdstr;
       BTIF_TRACE_DEBUG(
           "%s, calling btapp_tap_send, "
           "p_buf->len:%d, offset:%d",
           __func__, p_buf->len, p_buf->offset);
       if (is_empty_eth_addr(conn->eth_addr) && is_valid_bt_eth_addr(src)) {
-        BTIF_TRACE_DEBUG(
-            "%s pan bt peer addr: %s", __func__,
-            bdaddr_to_string((bt_bdaddr_t*)conn->peer, bdstr, sizeof(bdstr)));
-        bdaddr_to_string((bt_bdaddr_t*)src, bdstr, sizeof(bdstr));
-        BTIF_TRACE_DEBUG(
-            "%s:     update its ethernet addr: %s", __func__,
-            bdaddr_to_string((bt_bdaddr_t*)src, bdstr, sizeof(bdstr)));
-        memcpy(conn->eth_addr, src, sizeof(conn->eth_addr));
+        VLOG(1) << __func__ << " pan bt peer addr: " << conn->peer
+                << " update its ethernet addr: " << src;
+        conn->eth_addr = src;
       }
       btpan_tap_send(btpan_cb.tap_fd, src, dst, protocol,
                      (char*)(p_buf + 1) + p_buf->offset, p_buf->len, ext,
@@ -230,8 +224,10 @@
  *
  ******************************************************************************/
 void bta_pan_co_tx_write(UNUSED_ATTR uint16_t handle,
-                         UNUSED_ATTR uint8_t app_id, UNUSED_ATTR BD_ADDR src,
-                         UNUSED_ATTR BD_ADDR dst, UNUSED_ATTR uint16_t protocol,
+                         UNUSED_ATTR uint8_t app_id,
+                         UNUSED_ATTR const RawAddress& src,
+                         UNUSED_ATTR const RawAddress& dst,
+                         UNUSED_ATTR uint16_t protocol,
                          UNUSED_ATTR uint8_t* p_data, UNUSED_ATTR uint16_t len,
                          UNUSED_ATTR bool ext, UNUSED_ATTR bool forward) {
   BTIF_TRACE_API("bta_pan_co_tx_write not used");
@@ -251,8 +247,9 @@
  *
  ******************************************************************************/
 void bta_pan_co_tx_writebuf(UNUSED_ATTR uint16_t handle,
-                            UNUSED_ATTR uint8_t app_id, UNUSED_ATTR BD_ADDR src,
-                            UNUSED_ATTR BD_ADDR dst,
+                            UNUSED_ATTR uint8_t app_id,
+                            UNUSED_ATTR const RawAddress& src,
+                            UNUSED_ATTR const RawAddress& dst,
                             UNUSED_ATTR uint16_t protocol,
                             UNUSED_ATTR BT_HDR* p_buf, UNUSED_ATTR bool ext,
                             UNUSED_ATTR bool forward) {
diff --git a/btif/include/btif_api.h b/btif/include/btif_api.h
index e066b83..739eabe 100644
--- a/btif/include/btif_api.h
+++ b/btif/include/btif_api.h
@@ -146,7 +146,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_get_remote_device_property(bt_bdaddr_t* remote_addr,
+bt_status_t btif_get_remote_device_property(RawAddress* remote_addr,
                                             bt_property_type_t type);
 
 /*******************************************************************************
@@ -158,7 +158,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_get_remote_device_properties(bt_bdaddr_t* remote_addr);
+bt_status_t btif_get_remote_device_properties(RawAddress* remote_addr);
 
 /*******************************************************************************
  *
@@ -171,7 +171,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_set_remote_device_property(bt_bdaddr_t* remote_addr,
+bt_status_t btif_set_remote_device_property(RawAddress* remote_addr,
                                             const bt_property_t* property);
 
 /*******************************************************************************
@@ -184,7 +184,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_get_remote_service_record(bt_bdaddr_t* remote_addr,
+bt_status_t btif_get_remote_service_record(RawAddress* remote_addr,
                                            bt_uuid_t* uuid);
 
 /*******************************************************************************
@@ -223,7 +223,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_create_bond(const bt_bdaddr_t* bd_addr, int transport);
+bt_status_t btif_dm_create_bond(const RawAddress* bd_addr, int transport);
 
 /*******************************************************************************
  *
@@ -235,7 +235,7 @@
  *
  ******************************************************************************/
 bt_status_t btif_dm_create_bond_out_of_band(
-    const bt_bdaddr_t* bd_addr, int transport,
+    const RawAddress* bd_addr, int transport,
     const bt_out_of_band_data_t* oob_data);
 
 /*******************************************************************************
@@ -247,7 +247,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_cancel_bond(const bt_bdaddr_t* bd_addr);
+bt_status_t btif_dm_cancel_bond(const RawAddress* bd_addr);
 
 /*******************************************************************************
  *
@@ -258,7 +258,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_remove_bond(const bt_bdaddr_t* bd_addr);
+bt_status_t btif_dm_remove_bond(const RawAddress* bd_addr);
 
 /*******************************************************************************
  *
@@ -269,7 +269,7 @@
  * Returns          0 if not connected
  *
  ******************************************************************************/
-uint16_t btif_dm_get_connection_state(const bt_bdaddr_t* bd_addr);
+uint16_t btif_dm_get_connection_state(const RawAddress* bd_addr);
 
 /*******************************************************************************
  *
@@ -280,7 +280,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_pin_reply(const bt_bdaddr_t* bd_addr, uint8_t accept,
+bt_status_t btif_dm_pin_reply(const RawAddress* bd_addr, uint8_t accept,
                               uint8_t pin_len, bt_pin_code_t* pin_code);
 
 /*******************************************************************************
@@ -292,7 +292,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_passkey_reply(const bt_bdaddr_t* bd_addr, uint8_t accept,
+bt_status_t btif_dm_passkey_reply(const RawAddress* bd_addr, uint8_t accept,
                                   uint32_t passkey);
 
 /*******************************************************************************
@@ -305,7 +305,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_ssp_reply(const bt_bdaddr_t* bd_addr,
+bt_status_t btif_dm_ssp_reply(const RawAddress* bd_addr,
                               bt_ssp_variant_t variant, uint8_t accept,
                               uint32_t passkey);
 
@@ -329,7 +329,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_get_remote_service_record(bt_bdaddr_t* remote_addr,
+bt_status_t btif_dm_get_remote_service_record(RawAddress* remote_addr,
                                               bt_uuid_t* uuid);
 
 /*******************************************************************************
@@ -341,7 +341,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_get_remote_services(bt_bdaddr_t* remote_addr);
+bt_status_t btif_dm_get_remote_services(const RawAddress& remote_addr);
 
 /*******************************************************************************
  *
@@ -352,7 +352,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_get_remote_services_by_transport(bt_bdaddr_t* remote_addr,
+bt_status_t btif_dm_get_remote_services_by_transport(RawAddress* remote_addr,
                                                      int transport);
 
 /*******************************************************************************
diff --git a/btif/include/btif_av.h b/btif/include/btif_av.h
index 6349701..3ba2d7d 100644
--- a/btif/include/btif_av.h
+++ b/btif/include/btif_av.h
@@ -64,7 +64,7 @@
  *
  ******************************************************************************/
 
-bt_bdaddr_t btif_av_get_addr(void);
+RawAddress btif_av_get_addr(void);
 
 /*******************************************************************************
  * Function         btif_av_is_sink_enabled
diff --git a/btif/include/btif_common.h b/btif/include/btif_common.h
index f283e00..ae726e7 100644
--- a/btif/include/btif_common.h
+++ b/btif/include/btif_common.h
@@ -148,37 +148,6 @@
                                          successfully */
 };
 
-/* Macro definitions for BD ADDR persistence */
-
-/**
- * PROPERTY_BT_BDADDR_PATH
- * The property key stores the storage location of Bluetooth Device Address
- */
-#ifndef PROPERTY_BT_BDADDR_PATH
-#define PROPERTY_BT_BDADDR_PATH "ro.bt.bdaddr_path"
-#endif
-
-/**
- * PERSIST_BDADDR_PROPERTY
- * If there is no valid bdaddr available from PROPERTY_BT_BDADDR_PATH,
- * generating a random BDADDR and keeping it in the PERSIST_BDADDR_DROP.
- */
-#ifndef PERSIST_BDADDR_PROPERTY
-#define PERSIST_BDADDR_PROPERTY "persist.service.bdroid.bdaddr"
-#endif
-
-/**
- * FACTORY_BT_BDADDR_PROPERTY
- * If there is no valid bdaddr available from PROPERTY_BT_BDADDR_PATH
- * and there is no available persistent bdaddr available from
- * PERSIST_BDADDR_PROPERTY use a factory set address
- */
-#ifndef FACTORY_BT_ADDR_PROPERTY
-#define FACTORY_BT_ADDR_PROPERTY "ro.boot.btmacaddr"
-#endif
-
-#define FACTORY_BT_BDADDR_STORAGE_LEN 17
-
 /*******************************************************************************
  *  Type definitions for callback functions
  ******************************************************************************/
@@ -235,7 +204,7 @@
 void btif_disable_bluetooth_evt(void);
 void btif_adapter_properties_evt(bt_status_t status, uint32_t num_props,
                                  bt_property_t* p_props);
-void btif_remote_properties_evt(bt_status_t status, bt_bdaddr_t* remote_addr,
+void btif_remote_properties_evt(bt_status_t status, RawAddress* remote_addr,
                                 uint32_t num_props, bt_property_t* p_props);
 
 void bte_load_did_conf(const char* p_path);
diff --git a/btif/include/btif_config.h b/btif/include/btif_config.h
index 5d9ea33..7031802 100644
--- a/btif/include/btif_config.h
+++ b/btif/include/btif_config.h
@@ -55,7 +55,7 @@
 
 // TODO(zachoverflow): Eww...we need to move these out. These are peer specific,
 // not config general.
-bool btif_get_address_type(const BD_ADDR bd_addr, int* p_addr_type);
-bool btif_get_device_type(const BD_ADDR bd_addr, int* p_device_type);
+bool btif_get_address_type(const RawAddress& bd_addr, int* p_addr_type);
+bool btif_get_device_type(const RawAddress& bd_addr, int* p_device_type);
 
 void btif_debug_config_dump(int fd);
diff --git a/btif/include/btif_debug_conn.h b/btif/include/btif_debug_conn.h
index 1823b8a..6ee374e 100644
--- a/btif/include/btif_debug_conn.h
+++ b/btif/include/btif_debug_conn.h
@@ -28,7 +28,7 @@
 } btif_debug_conn_state_t;
 
 // Report a connection state change
-void btif_debug_conn_state(const bt_bdaddr_t bda,
+void btif_debug_conn_state(const RawAddress& bda,
                            const btif_debug_conn_state_t state,
                            const tGATT_DISCONN_REASON disconnect_reason);
 
diff --git a/btif/include/btif_dm.h b/btif/include/btif_dm.h
index 2be6f0b..39a1cfc 100644
--- a/btif/include/btif_dm.h
+++ b/btif/include/btif_dm.h
@@ -43,25 +43,27 @@
 /**
  * Callout for handling io_capabilities request
  */
-void btif_dm_proc_io_req(BD_ADDR bd_addr, tBTA_IO_CAP* p_io_cap,
+void btif_dm_proc_io_req(const RawAddress& bd_addr, tBTA_IO_CAP* p_io_cap,
                          tBTA_OOB_DATA* p_oob_data, tBTA_AUTH_REQ* p_auth_req,
                          bool is_orig);
 /**
  * Callout for handling io_capabilities response
  */
-void btif_dm_proc_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
+void btif_dm_proc_io_rsp(const RawAddress& bd_addr, tBTA_IO_CAP io_cap,
                          tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req);
 
 /**
  * Out-of-band functions
  */
 void btif_dm_set_oob_for_io_req(tBTA_OOB_DATA* p_oob_data);
-void btif_dm_set_oob_for_le_io_req(BD_ADDR bd_addr, tBTA_OOB_DATA* p_oob_data,
+void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr,
+                                   tBTA_OOB_DATA* p_oob_data,
                                    tBTA_LE_AUTH_REQ* p_auth_req);
 #ifdef BTIF_DM_OOB_TEST
 void btif_dm_load_local_oob(void);
 void btif_dm_proc_loc_oob(bool valid, BT_OCTET16 c, BT_OCTET16 r);
-bool btif_dm_proc_rmt_oob(BD_ADDR bd_addr, BT_OCTET16 p_c, BT_OCTET16 p_r);
+bool btif_dm_proc_rmt_oob(const RawAddress& bd_addr, BT_OCTET16 p_c,
+                          BT_OCTET16 p_r);
 #endif /* BTIF_DM_OOB_TEST */
 
 /*callout for reading SMP properties from Text file*/
@@ -98,11 +100,12 @@
 void btif_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK* p_key_mask,
                                 BT_OCTET16 er,
                                 tBTA_BLE_LOCAL_ID_KEYS* p_id_keys);
-void btif_dm_save_ble_bonding_keys(bt_bdaddr_t bd_addr);
+void btif_dm_save_ble_bonding_keys(RawAddress& bd_addr);
 void btif_dm_remove_ble_bonding_keys(void);
 void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req);
 
-void btif_dm_update_ble_remote_properties(BD_ADDR bd_addr, BD_NAME bd_name,
+void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr,
+                                          BD_NAME bd_name,
                                           tBT_DEVICE_TYPE dev_type);
 
 #endif
diff --git a/btif/include/btif_gatt_util.h b/btif/include/btif_gatt_util.h
index a875a17..731f519 100644
--- a/btif/include/btif_gatt_util.h
+++ b/btif/include/btif_gatt_util.h
@@ -34,7 +34,7 @@
 uint16_t set_read_value(btgatt_read_params_t* p_dest, tBTA_GATTC_READ* p_src);
 uint16_t get_uuid16(tBT_UUID* p_uuid);
 
-void btif_gatt_check_encrypted_link(BD_ADDR bd_addr,
+void btif_gatt_check_encrypted_link(RawAddress bd_addr,
                                     tBTA_GATT_TRANSPORT transport);
 extern void btif_gatt_move_track_adv_data(btgatt_track_adv_info_t* p_dest,
                                           btgatt_track_adv_info_t* p_src);
diff --git a/btif/include/btif_hd.h b/btif/include/btif_hd.h
index 5697896..a119ebd 100644
--- a/btif/include/btif_hd.h
+++ b/btif/include/btif_hd.h
@@ -41,7 +41,7 @@
 
 extern btif_hd_cb_t btif_hd_cb;
 
-extern void btif_hd_remove_device(bt_bdaddr_t bd_addr);
+extern void btif_hd_remove_device(RawAddress bd_addr);
 extern void btif_hd_service_registration();
 
 #endif
diff --git a/btif/include/btif_hh.h b/btif/include/btif_hh.h
index 95ab382..8505b08 100644
--- a/btif/include/btif_hh.h
+++ b/btif/include/btif_hh.h
@@ -58,7 +58,7 @@
 typedef struct {
   bthh_connection_state_t dev_status;
   uint8_t dev_handle;
-  bt_bdaddr_t bd_addr;
+  RawAddress bd_addr;
   tBTA_HH_ATTR_MASK attr_mask;
   uint8_t sub_class;
   uint8_t app_id;
@@ -73,7 +73,7 @@
 /* Control block to maintain properties of devices */
 typedef struct {
   uint8_t dev_handle;
-  bt_bdaddr_t bd_addr;
+  RawAddress bd_addr;
   tBTA_HH_ATTR_MASK attr_mask;
 } btif_hh_added_device_t;
 
@@ -97,15 +97,14 @@
 extern btif_hh_cb_t btif_hh_cb;
 
 extern btif_hh_device_t* btif_hh_find_connected_dev_by_handle(uint8_t handle);
-extern void btif_hh_remove_device(bt_bdaddr_t bd_addr);
-bool btif_hh_add_added_dev(bt_bdaddr_t bda, tBTA_HH_ATTR_MASK attr_mask);
-extern bt_status_t btif_hh_virtual_unplug(bt_bdaddr_t* bd_addr);
-extern void btif_hh_disconnect(bt_bdaddr_t* bd_addr);
+extern void btif_hh_remove_device(RawAddress bd_addr);
+extern bool btif_hh_add_added_dev(const RawAddress& bda,
+                                  tBTA_HH_ATTR_MASK attr_mask);
+extern bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr);
+extern void btif_hh_disconnect(RawAddress* bd_addr);
 extern void btif_hh_setreport(btif_hh_device_t* p_dev,
                               bthh_report_type_t r_type, uint16_t size,
                               uint8_t* report);
 extern void btif_hh_service_registration(bool enable);
 
-bool btif_hh_add_added_dev(bt_bdaddr_t bd_addr, tBTA_HH_ATTR_MASK attr_mask);
-
 #endif
diff --git a/btif/include/btif_hl.h b/btif/include/btif_hl.h
index 9dc4df9..b5022ef 100644
--- a/btif/include/btif_hl.h
+++ b/btif/include/btif_hl.h
@@ -118,7 +118,7 @@
 
 typedef struct {
   int channel_id;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t mdep_cfg_idx;
   int max_s;
   int socket_id[2];
@@ -175,7 +175,7 @@
   bool in_use;
   btif_hl_chan_cb_state_t cb_state;
   btif_hl_pend_dch_op_t op;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   bool abort_pending;
 } btif_hl_pending_chan_cb_t;
 
@@ -186,7 +186,7 @@
   uint16_t req_ctrl_psm;
   uint16_t ctrl_psm;
   uint16_t data_psm;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t cch_mtu;
   tBTA_SEC sec_mask;
   tBTA_HL_MCL_HANDLE mcl_handle;
@@ -202,7 +202,7 @@
   bool active;
   uint16_t mdl_id;
   uint8_t mdep_cfg_idx;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   int channel_id;
 } btif_hl_delete_mdl_t;
 
@@ -252,7 +252,7 @@
 
 typedef struct {
   int app_id;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   int mdep_cfg_index;
   int channel_id;
   btif_hl_chan_cb_state_t cb_state;
@@ -291,7 +291,7 @@
 extern btif_hl_cb_t btif_hl_cb;
 extern btif_hl_cb_t* p_btif_hl_cb;
 
-extern bool btif_hl_find_mcl_idx(uint8_t app_idx, BD_ADDR p_bd_addr,
+extern bool btif_hl_find_mcl_idx(uint8_t app_idx, const RawAddress& p_bd_addr,
                                  uint8_t* p_mcl_idx);
 extern bool btif_hl_find_app_idx(uint8_t app_id, uint8_t* p_app_idx);
 extern bool btif_hl_find_avail_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx);
diff --git a/btif/include/btif_pan_internal.h b/btif/include/btif_pan_internal.h
index 0f47802..a902946 100644
--- a/btif/include/btif_pan_internal.h
+++ b/btif/include/btif_pan_internal.h
@@ -37,7 +37,6 @@
 #define PAN_NAP_SERVICE_NAME "Android Network Access Point"
 #define PANU_SERVICE_NAME "Android Network User"
 #define TAP_IF_NAME "bt-pan"
-#define ETH_ADDR_LEN 6
 #define TAP_MAX_PKT_WRITE_LEN 2000
 #ifndef PAN_SECURITY
 #define PAN_SECURITY                                                         \
@@ -57,8 +56,8 @@
  ******************************************************************************/
 
 typedef struct eth_hdr {
-  unsigned char h_dest[ETH_ADDR_LEN];
-  unsigned char h_src[ETH_ADDR_LEN];
+  RawAddress h_dest;
+  RawAddress h_src;
   short h_proto;
 } tETH_HDR;
 
@@ -66,10 +65,10 @@
   int handle;
   int state;
   uint16_t protocol;
-  BD_ADDR peer;
+  RawAddress peer;
   int local_role;
   int remote_role;
-  unsigned char eth_addr[ETH_ADDR_LEN];
+  RawAddress eth_addr;
 } btpan_conn_t;
 
 typedef struct {
@@ -89,9 +88,9 @@
  ******************************************************************************/
 
 extern btpan_cb_t btpan_cb;
-btpan_conn_t* btpan_new_conn(int handle, const BD_ADDR addr, int local_role,
+btpan_conn_t* btpan_new_conn(int handle, const RawAddress& addr, int local_role,
                              int peer_role);
-btpan_conn_t* btpan_find_conn_addr(const BD_ADDR addr);
+btpan_conn_t* btpan_find_conn_addr(const RawAddress& addr);
 btpan_conn_t* btpan_find_conn_handle(uint16_t handle);
 void btpan_set_flow_control(bool enable);
 int btpan_get_connected_count(void);
@@ -99,20 +98,17 @@
 void create_tap_read_thread(int tap_fd);
 void destroy_tap_read_thread(void);
 int btpan_tap_close(int tap_fd);
-int btpan_tap_send(int tap_fd, const BD_ADDR src, const BD_ADDR dst,
+int btpan_tap_send(int tap_fd, const RawAddress& src, const RawAddress& dst,
                    uint16_t protocol, const char* buff, uint16_t size, bool ext,
                    bool forward);
 
-static inline int is_empty_eth_addr(const BD_ADDR addr) {
-  int i;
-  for (i = 0; i < BD_ADDR_LEN; i++)
-    if (addr[i] != 0) return 0;
-  return 1;
+static inline int is_empty_eth_addr(const RawAddress& addr) {
+  return addr == RawAddress::kEmpty;
 }
 
-static inline int is_valid_bt_eth_addr(const BD_ADDR addr) {
+static inline int is_valid_bt_eth_addr(const RawAddress& addr) {
   if (is_empty_eth_addr(addr)) return 0;
-  return addr[0] & 1 ? 0 : 1; /* Cannot be multicasting address */
+  return addr.address[0] & 1 ? 0 : 1; /* Cannot be multicasting address */
 }
 
 #endif
diff --git a/btif/include/btif_profile_queue.h b/btif/include/btif_profile_queue.h
index fca75f3..df48c77 100644
--- a/btif/include/btif_profile_queue.h
+++ b/btif/include/btif_profile_queue.h
@@ -29,9 +29,9 @@
 
 #include <hardware/bluetooth.h>
 
-typedef bt_status_t (*btif_connect_cb_t)(bt_bdaddr_t* bda, uint16_t uuid);
+typedef bt_status_t (*btif_connect_cb_t)(RawAddress* bda, uint16_t uuid);
 
-bt_status_t btif_queue_connect(uint16_t uuid, const bt_bdaddr_t* bda,
+bt_status_t btif_queue_connect(uint16_t uuid, const RawAddress* bda,
                                btif_connect_cb_t connect_cb);
 void btif_queue_cleanup(uint16_t uuid);
 void btif_queue_advance();
diff --git a/btif/include/btif_sock_l2cap.h b/btif/include/btif_sock_l2cap.h
index 37fa90e..2715be0 100644
--- a/btif/include/btif_sock_l2cap.h
+++ b/btif/include/btif_sock_l2cap.h
@@ -16,7 +16,7 @@
 bt_status_t btsock_l2cap_cleanup();
 bt_status_t btsock_l2cap_listen(const char* name, int channel, int* sock_fd,
                                 int flags, int app_uid);
-bt_status_t btsock_l2cap_connect(const bt_bdaddr_t* bd_addr, int channel,
+bt_status_t btsock_l2cap_connect(const RawAddress* bd_addr, int channel,
                                  int* sock_fd, int flags, int app_uid);
 void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id);
 void on_l2cap_psm_assigned(int id, int psm);
diff --git a/btif/include/btif_sock_rfc.h b/btif/include/btif_sock_rfc.h
index 50aecd7..5c588b5 100644
--- a/btif/include/btif_sock_rfc.h
+++ b/btif/include/btif_sock_rfc.h
@@ -34,7 +34,7 @@
 bt_status_t btsock_rfc_listen(const char* name, const uint8_t* uuid,
                               int channel, int* sock_fd, int flags,
                               int app_uid);
-bt_status_t btsock_rfc_connect(const bt_bdaddr_t* bd_addr, const uint8_t* uuid,
+bt_status_t btsock_rfc_connect(const RawAddress* bd_addr, const uint8_t* uuid,
                                int channel, int* sock_fd, int flags,
                                int app_uid);
 void btsock_rfc_signaled(int fd, int flags, uint32_t user_id);
diff --git a/btif/include/btif_sock_sco.h b/btif/include/btif_sock_sco.h
index 66859d7..50530ce 100644
--- a/btif/include/btif_sock_sco.h
+++ b/btif/include/btif_sock_sco.h
@@ -25,5 +25,5 @@
 bt_status_t btsock_sco_init(thread_t* thread);
 bt_status_t btsock_sco_cleanup(void);
 bt_status_t btsock_sco_listen(int* sock_fd, int flags);
-bt_status_t btsock_sco_connect(const bt_bdaddr_t* bd_addr, int* sock_fd,
+bt_status_t btsock_sco_connect(const RawAddress* bd_addr, int* sock_fd,
                                int flags);
diff --git a/btif/include/btif_storage.h b/btif/include/btif_storage.h
index a787613..1f7efd3 100644
--- a/btif/include/btif_storage.h
+++ b/btif/include/btif_storage.h
@@ -79,8 +79,8 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_get_remote_device_property(bt_bdaddr_t* remote_bd_addr,
-                                                    bt_property_t* property);
+bt_status_t btif_storage_get_remote_device_property(
+    const RawAddress* remote_bd_addr, bt_property_t* property);
 
 /*******************************************************************************
  *
@@ -93,8 +93,8 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_set_remote_device_property(bt_bdaddr_t* remote_bd_addr,
-                                                    bt_property_t* property);
+bt_status_t btif_storage_set_remote_device_property(
+    const RawAddress* remote_bd_addr, bt_property_t* property);
 
 /*******************************************************************************
  *
@@ -108,7 +108,7 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_add_remote_device(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_add_remote_device(const RawAddress* remote_bd_addr,
                                            uint32_t num_properties,
                                            bt_property_t* properties);
 
@@ -123,7 +123,7 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_add_bonded_device(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_add_bonded_device(RawAddress* remote_bd_addr,
                                            LINK_KEY link_key, uint8_t key_type,
                                            uint8_t pin_length);
 
@@ -137,7 +137,7 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_remove_bonded_device(bt_bdaddr_t* remote_bd_addr);
+bt_status_t btif_storage_remove_bonded_device(const RawAddress* remote_bd_addr);
 
 /*******************************************************************************
  *
@@ -164,7 +164,7 @@
  ******************************************************************************/
 
 bt_status_t btif_storage_add_hid_device_info(
-    bt_bdaddr_t* remote_bd_addr, uint16_t attr_mask, uint8_t sub_class,
+    RawAddress* remote_bd_addr, uint16_t attr_mask, uint8_t sub_class,
     uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version,
     uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout,
     uint16_t dl_len, uint8_t* dsc_list);
@@ -192,7 +192,7 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_remove_hid_info(bt_bdaddr_t* remote_bd_addr);
+bt_status_t btif_storage_remove_hid_info(RawAddress* remote_bd_addr);
 
 /*******************************************************************************
  *
@@ -205,26 +205,27 @@
  *                  false otherwise
  *
  ******************************************************************************/
-bool btif_storage_is_restricted_device(const bt_bdaddr_t* remote_bd_addr);
+bool btif_storage_is_restricted_device(const RawAddress* remote_bd_addr);
 
-bt_status_t btif_storage_add_ble_bonding_key(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_add_ble_bonding_key(RawAddress* remote_bd_addr,
                                              char* key, uint8_t key_type,
                                              uint8_t key_length);
-bt_status_t btif_storage_get_ble_bonding_key(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_get_ble_bonding_key(RawAddress* remote_bd_addr,
                                              uint8_t key_type, char* key_value,
                                              int key_length);
 
 bt_status_t btif_storage_add_ble_local_key(char* key, uint8_t key_type,
                                            uint8_t key_length);
-bt_status_t btif_storage_remove_ble_bonding_keys(bt_bdaddr_t* remote_bd_addr);
+bt_status_t btif_storage_remove_ble_bonding_keys(
+    const RawAddress* remote_bd_addr);
 bt_status_t btif_storage_remove_ble_local_keys(void);
 bt_status_t btif_storage_get_ble_local_key(uint8_t key_type, char* key_value,
                                            int key_len);
 
-bt_status_t btif_storage_get_remote_addr_type(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_get_remote_addr_type(const RawAddress* remote_bd_addr,
                                               int* addr_type);
 
-bt_status_t btif_storage_set_remote_addr_type(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_set_remote_addr_type(const RawAddress* remote_bd_addr,
                                               uint8_t addr_type);
 
 /*******************************************************************************
@@ -247,7 +248,7 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_storage_set_hidd(bt_bdaddr_t* remote_bd_addr);
+bt_status_t btif_storage_set_hidd(RawAddress* remote_bd_addr);
 
 /*******************************************************************************
  *
@@ -259,15 +260,14 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_storage_remove_hidd(bt_bdaddr_t* remote_bd_addr);
+bt_status_t btif_storage_remove_hidd(RawAddress* remote_bd_addr);
 
 // Gets the device name for a given Bluetooth address |bd_addr|.
 // The device name (if found) is stored in |name|.
 // Returns true if the device name is found, othervise false.
 // Note: |name| should point to a buffer that can store string of length
 // |BTM_MAX_REM_BD_NAME_LEN|.
-bool btif_storage_get_stored_remote_name(const bt_bdaddr_t& bd_addr,
-                                         char* name);
+bool btif_storage_get_stored_remote_name(const RawAddress& bd_addr, char* name);
 
 /******************************************************************************
  * Exported for unit tests
diff --git a/btif/src/bluetooth.cc b/btif/src/bluetooth.cc
index 9885117..1d2c66a 100644
--- a/btif/src/bluetooth.cc
+++ b/btif/src/bluetooth.cc
@@ -189,14 +189,14 @@
   return btif_set_adapter_property(property);
 }
 
-int get_remote_device_properties(bt_bdaddr_t* remote_addr) {
+int get_remote_device_properties(RawAddress* remote_addr) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
 
   return btif_get_remote_device_properties(remote_addr);
 }
 
-int get_remote_device_property(bt_bdaddr_t* remote_addr,
+int get_remote_device_property(RawAddress* remote_addr,
                                bt_property_type_t type) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
@@ -204,7 +204,7 @@
   return btif_get_remote_device_property(remote_addr, type);
 }
 
-int set_remote_device_property(bt_bdaddr_t* remote_addr,
+int set_remote_device_property(RawAddress* remote_addr,
                                const bt_property_t* property) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
@@ -212,18 +212,18 @@
   return btif_set_remote_device_property(remote_addr, property);
 }
 
-int get_remote_service_record(bt_bdaddr_t* remote_addr, bt_uuid_t* uuid) {
+int get_remote_service_record(RawAddress* remote_addr, bt_uuid_t* uuid) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
 
   return btif_get_remote_service_record(remote_addr, uuid);
 }
 
-int get_remote_services(bt_bdaddr_t* remote_addr) {
+int get_remote_services(RawAddress* remote_addr) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
 
-  return btif_dm_get_remote_services(remote_addr);
+  return btif_dm_get_remote_services(*remote_addr);
 }
 
 static int start_discovery(void) {
@@ -240,14 +240,14 @@
   return btif_dm_cancel_discovery();
 }
 
-static int create_bond(const bt_bdaddr_t* bd_addr, int transport) {
+static int create_bond(const RawAddress* bd_addr, int transport) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
 
   return btif_dm_create_bond(bd_addr, transport);
 }
 
-static int create_bond_out_of_band(const bt_bdaddr_t* bd_addr, int transport,
+static int create_bond_out_of_band(const RawAddress* bd_addr, int transport,
                                    const bt_out_of_band_data_t* oob_data) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
@@ -255,14 +255,14 @@
   return btif_dm_create_bond_out_of_band(bd_addr, transport, oob_data);
 }
 
-static int cancel_bond(const bt_bdaddr_t* bd_addr) {
+static int cancel_bond(const RawAddress* bd_addr) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
 
   return btif_dm_cancel_bond(bd_addr);
 }
 
-static int remove_bond(const bt_bdaddr_t* bd_addr) {
+static int remove_bond(const RawAddress* bd_addr) {
   if (is_restricted_mode() && !btif_storage_is_restricted_device(bd_addr))
     return BT_STATUS_SUCCESS;
 
@@ -272,22 +272,22 @@
   return btif_dm_remove_bond(bd_addr);
 }
 
-static int get_connection_state(const bt_bdaddr_t* bd_addr) {
+static int get_connection_state(const RawAddress* bd_addr) {
   /* sanity check */
   if (interface_ready() == false) return 0;
 
   return btif_dm_get_connection_state(bd_addr);
 }
 
-static int pin_reply(const bt_bdaddr_t* bd_addr, uint8_t accept,
-                     uint8_t pin_len, bt_pin_code_t* pin_code) {
+static int pin_reply(const RawAddress* bd_addr, uint8_t accept, uint8_t pin_len,
+                     bt_pin_code_t* pin_code) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
 
   return btif_dm_pin_reply(bd_addr, accept, pin_len, pin_code);
 }
 
-static int ssp_reply(const bt_bdaddr_t* bd_addr, bt_ssp_variant_t variant,
+static int ssp_reply(const RawAddress* bd_addr, bt_ssp_variant_t variant,
                      uint8_t accept, uint32_t passkey) {
   /* sanity check */
   if (interface_ready() == false) return BT_STATUS_NOT_READY;
diff --git a/btif/src/btif_a2dp.cc b/btif/src/btif_a2dp.cc
index 7c83ff9..62a217a 100644
--- a/btif/src/btif_a2dp.cc
+++ b/btif/src/btif_a2dp.cc
@@ -33,7 +33,8 @@
 #include "osi/include/log.h"
 
 void btif_a2dp_on_idle(void) {
-  APPL_TRACE_EVENT("## ON A2DP IDLE ## peer_sep = %d", btif_av_get_peer_sep());
+  APPL_TRACE_WARNING("## ON A2DP IDLE ## peer_sep = %d",
+                     btif_av_get_peer_sep());
   if (btif_av_get_peer_sep() == AVDT_TSEP_SNK) {
     btif_a2dp_source_on_idle();
   } else if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
@@ -44,7 +45,7 @@
 bool btif_a2dp_on_started(tBTA_AV_START* p_av_start, bool pending_start) {
   bool ack = false;
 
-  APPL_TRACE_EVENT("## ON A2DP STARTED ##");
+  APPL_TRACE_WARNING("## ON A2DP STARTED ##");
 
   if (p_av_start == NULL) {
     /* ack back a local start request */
@@ -52,6 +53,11 @@
     return true;
   }
 
+  APPL_TRACE_WARNING(
+      "%s: pending_start = %d status = %d suspending = %d initiator = %d",
+      __func__, pending_start, p_av_start->status, p_av_start->suspending,
+      p_av_start->initiator);
+
   if (p_av_start->status == BTA_AV_SUCCESS) {
     if (!p_av_start->suspending) {
       if (p_av_start->initiator) {
@@ -78,7 +84,7 @@
 }
 
 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
-  APPL_TRACE_EVENT("## ON A2DP STOPPED ##");
+  APPL_TRACE_WARNING("## ON A2DP STOPPED ##");
 
   if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
     btif_a2dp_sink_on_stopped(p_av_suspend);
@@ -89,7 +95,7 @@
 }
 
 void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) {
-  APPL_TRACE_EVENT("## ON A2DP SUSPENDED ##");
+  APPL_TRACE_WARNING("## ON A2DP SUSPENDED ##");
   if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) {
     btif_a2dp_sink_on_suspended(p_av_suspend);
   } else {
diff --git a/btif/src/btif_a2dp_control.cc b/btif/src/btif_a2dp_control.cc
index 22cf7aa..af59644 100644
--- a/btif/src/btif_a2dp_control.cc
+++ b/btif/src/btif_a2dp_control.cc
@@ -63,12 +63,13 @@
 
   /* detach on ctrl channel means audioflinger process was terminated */
   if (n == 0) {
-    APPL_TRACE_EVENT("CTRL CH DETACHED");
+    APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__);
     UIPC_Close(UIPC_CH_ID_AV_CTRL);
     return;
   }
 
-  APPL_TRACE_DEBUG("a2dp-ctrl-cmd : %s", audio_a2dp_hw_dump_ctrl_event(cmd));
+  APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s", __func__,
+                     audio_a2dp_hw_dump_ctrl_event(cmd));
   a2dp_cmd_pending = cmd;
 
   switch (cmd) {
@@ -227,21 +228,24 @@
                     reinterpret_cast<uint8_t*>(&codec_config.sample_rate),
                     sizeof(btav_a2dp_codec_sample_rate_t)) !=
           sizeof(btav_a2dp_codec_sample_rate_t)) {
-        APPL_TRACE_ERROR("Error reading sample rate from audio HAL");
+        APPL_TRACE_ERROR("%s: Error reading sample rate from audio HAL",
+                         __func__);
         break;
       }
       if (UIPC_Read(UIPC_CH_ID_AV_CTRL, 0,
                     reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample),
                     sizeof(btav_a2dp_codec_bits_per_sample_t)) !=
           sizeof(btav_a2dp_codec_bits_per_sample_t)) {
-        APPL_TRACE_ERROR("Error reading bits per sample from audio HAL");
+        APPL_TRACE_ERROR("%s: Error reading bits per sample from audio HAL",
+                         __func__);
         break;
       }
       if (UIPC_Read(UIPC_CH_ID_AV_CTRL, 0,
                     reinterpret_cast<uint8_t*>(&codec_config.channel_mode),
                     sizeof(btav_a2dp_codec_channel_mode_t)) !=
           sizeof(btav_a2dp_codec_channel_mode_t)) {
-        APPL_TRACE_ERROR("Error reading channel mode from audio HAL");
+        APPL_TRACE_ERROR("%s: Error reading channel mode from audio HAL",
+                         __func__);
         break;
       }
       APPL_TRACE_DEBUG(
@@ -259,17 +263,18 @@
       break;
 
     default:
-      APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd);
+      APPL_TRACE_ERROR("%s: UNSUPPORTED CMD (%d)", __func__, cmd);
       btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
       break;
   }
-  APPL_TRACE_DEBUG("a2dp-ctrl-cmd : %s DONE",
-                   audio_a2dp_hw_dump_ctrl_event(cmd));
+  APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s DONE", __func__,
+                     audio_a2dp_hw_dump_ctrl_event(cmd));
 }
 
 static void btif_a2dp_ctrl_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,
                               tUIPC_EVENT event) {
-  APPL_TRACE_DEBUG("A2DP-CTRL-CHANNEL EVENT %s", dump_uipc_event(event));
+  APPL_TRACE_WARNING("%s: A2DP-CTRL-CHANNEL EVENT %s", __func__,
+                     dump_uipc_event(event));
 
   switch (event) {
     case UIPC_OPEN_EVT:
@@ -286,14 +291,16 @@
       break;
 
     default:
-      APPL_TRACE_ERROR("### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###", event);
+      APPL_TRACE_ERROR("%s: ### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###",
+                       __func__, event);
       break;
   }
 }
 
 static void btif_a2dp_data_cb(UNUSED_ATTR tUIPC_CH_ID ch_id,
                               tUIPC_EVENT event) {
-  APPL_TRACE_DEBUG("BTIF MEDIA (A2DP-DATA) EVENT %s", dump_uipc_event(event));
+  APPL_TRACE_WARNING("%s: BTIF MEDIA (A2DP-DATA) EVENT %s", __func__,
+                     dump_uipc_event(event));
 
   switch (event) {
     case UIPC_OPEN_EVT:
@@ -314,7 +321,7 @@
       break;
 
     case UIPC_CLOSE_EVT:
-      APPL_TRACE_EVENT("## AUDIO PATH DETACHED ##");
+      APPL_TRACE_EVENT("%s: ## AUDIO PATH DETACHED ##", __func__);
       btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS);
       /*
        * Send stop request only if we are actively streaming and haven't
@@ -328,7 +335,8 @@
       break;
 
     default:
-      APPL_TRACE_ERROR("### A2DP-DATA EVENT %d NOT HANDLED ###", event);
+      APPL_TRACE_ERROR("%s: ### A2DP-DATA EVENT %d NOT HANDLED ###", __func__,
+                       event);
       break;
   }
 }
@@ -336,12 +344,12 @@
 void btif_a2dp_command_ack(tA2DP_CTRL_ACK status) {
   uint8_t ack = status;
 
-  APPL_TRACE_EVENT("## a2dp ack : %s, status %d ##",
-                   audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status);
+  APPL_TRACE_WARNING("%s: ## a2dp ack : %s, status %d ##", __func__,
+                     audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status);
 
   /* Sanity check */
   if (a2dp_cmd_pending == A2DP_CTRL_CMD_NONE) {
-    APPL_TRACE_ERROR("warning : no command pending, ignore ack");
+    APPL_TRACE_ERROR("%s: warning : no command pending, ignore ack", __func__);
     return;
   }
 
diff --git a/btif/src/btif_a2dp_source.cc b/btif/src/btif_a2dp_source.cc
index fbe3d07..8d264ce 100644
--- a/btif/src/btif_a2dp_source.cc
+++ b/btif/src/btif_a2dp_source.cc
@@ -21,7 +21,9 @@
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include <base/logging.h>
+#ifndef OS_GENERIC
 #include <cutils/trace.h>
+#endif
 #include <limits.h>
 #include <string.h>
 #include <algorithm>
@@ -29,7 +31,6 @@
 #include "audio_a2dp_hw/include/audio_a2dp_hw.h"
 #include "bt_common.h"
 #include "bta_av_ci.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_a2dp.h"
 #include "btif_a2dp_control.h"
 #include "btif_a2dp_source.h"
@@ -187,6 +188,9 @@
 static void update_scheduling_stats(scheduling_stats_t* stats, uint64_t now_us,
                                     uint64_t expected_delta);
 static void btm_read_rssi_cb(void* data);
+static void btm_read_failed_contact_counter_cb(void* data);
+static void btm_read_automatic_flush_timeout_cb(void* data);
+static void btm_read_tx_power_cb(void* data);
 
 UNUSED_ATTR static const char* dump_media_event(uint16_t event) {
   switch (event) {
@@ -664,7 +668,9 @@
     CHECK(btif_a2dp_source_cb.encoder_interface != NULL);
     size_t transmit_queue_length =
         fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
+#ifndef OS_GENERIC
     ATRACE_INT("btif TX queue", transmit_queue_length);
+#endif
     if (btif_a2dp_source_cb.encoder_interface->set_transmit_queue_length !=
         NULL) {
       btif_a2dp_source_cb.encoder_interface->set_transmit_queue_length(
@@ -740,9 +746,30 @@
       osi_free(fixed_queue_try_dequeue(btif_a2dp_source_cb.tx_audio_queue));
     }
 
-    // Request RSSI for log purposes if we had to flush buffers
-    bt_bdaddr_t peer_bda = btif_av_get_addr();
-    BTM_ReadRSSI(peer_bda.address, btm_read_rssi_cb);
+    // Request additional debug info if we had to flush buffers
+    RawAddress peer_bda = btif_av_get_addr();
+    tBTM_STATUS status = BTM_ReadRSSI(peer_bda, btm_read_rssi_cb);
+    if (status != BTM_CMD_STARTED) {
+      LOG_WARN(LOG_TAG, "%s: Cannot read RSSI: status %d", __func__, status);
+    }
+    status = BTM_ReadFailedContactCounter(peer_bda,
+                                          btm_read_failed_contact_counter_cb);
+    if (status != BTM_CMD_STARTED) {
+      LOG_WARN(LOG_TAG, "%s: Cannot read Failed Contact Counter: status %d",
+               __func__, status);
+    }
+    status = BTM_ReadAutomaticFlushTimeout(peer_bda,
+                                           btm_read_automatic_flush_timeout_cb);
+    if (status != BTM_CMD_STARTED) {
+      LOG_WARN(LOG_TAG, "%s: Cannot read Automatic Flush Timeout: status %d",
+               __func__, status);
+    }
+    status =
+        BTM_ReadTxPower(peer_bda, BT_TRANSPORT_BR_EDR, btm_read_tx_power_cb);
+    if (status != BTM_CMD_STARTED) {
+      LOG_WARN(LOG_TAG, "%s: Cannot read Tx Power: status %d", __func__,
+               status);
+    }
   }
 
   /* Update the statistics */
@@ -1078,20 +1105,72 @@
 
 static void btm_read_rssi_cb(void* data) {
   if (data == nullptr) {
-    LOG_ERROR(LOG_TAG, "%s RSSI request timed out", __func__);
+    LOG_ERROR(LOG_TAG, "%s Read RSSI request timed out", __func__);
     return;
   }
 
-  tBTM_RSSI_RESULTS* result = (tBTM_RSSI_RESULTS*)data;
+  tBTM_RSSI_RESULT* result = (tBTM_RSSI_RESULT*)data;
   if (result->status != BTM_SUCCESS) {
     LOG_ERROR(LOG_TAG, "%s unable to read remote RSSI (status %d)", __func__,
               result->status);
     return;
   }
 
-  char temp_buffer[20] = {0};
   LOG_WARN(LOG_TAG, "%s device: %s, rssi: %d", __func__,
-           bdaddr_to_string((bt_bdaddr_t*)result->rem_bda, temp_buffer,
-                            sizeof(temp_buffer)),
-           result->rssi);
+           result->rem_bda.ToString().c_str(), result->rssi);
+}
+
+static void btm_read_failed_contact_counter_cb(void* data) {
+  if (data == nullptr) {
+    LOG_ERROR(LOG_TAG, "%s Read Failed Contact Counter request timed out",
+              __func__);
+    return;
+  }
+
+  tBTM_FAILED_CONTACT_COUNTER_RESULT* result =
+      (tBTM_FAILED_CONTACT_COUNTER_RESULT*)data;
+  if (result->status != BTM_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "%s unable to read Failed Contact Counter (status %d)",
+              __func__, result->status);
+    return;
+  }
+
+  LOG_WARN(LOG_TAG, "%s device: %s, Failed Contact Counter: %u", __func__,
+           result->rem_bda.ToString().c_str(), result->failed_contact_counter);
+}
+
+static void btm_read_automatic_flush_timeout_cb(void* data) {
+  if (data == nullptr) {
+    LOG_ERROR(LOG_TAG, "%s Read Automatic Flush Timeout request timed out",
+              __func__);
+    return;
+  }
+
+  tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT* result =
+      (tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT*)data;
+  if (result->status != BTM_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "%s unable to read Automatic Flush Timeout (status %d)",
+              __func__, result->status);
+    return;
+  }
+
+  LOG_WARN(LOG_TAG, "%s device: %s, Automatic Flush Timeout: %u", __func__,
+           result->rem_bda.ToString().c_str(), result->automatic_flush_timeout);
+}
+
+static void btm_read_tx_power_cb(void* data) {
+  if (data == nullptr) {
+    LOG_ERROR(LOG_TAG, "%s Read Tx Power request timed out", __func__);
+    return;
+  }
+
+  tBTM_TX_POWER_RESULT* result = (tBTM_TX_POWER_RESULT*)data;
+  if (result->status != BTM_SUCCESS) {
+    LOG_ERROR(LOG_TAG, "%s unable to read Tx Power (status %d)", __func__,
+              result->status);
+    return;
+  }
+
+  LOG_WARN(LOG_TAG, "%s device: %s, Tx Power: %d", __func__,
+           result->rem_bda.ToString().c_str(), result->tx_power);
 }
diff --git a/btif/src/btif_av.cc b/btif/src/btif_av.cc
index 34780ad..0178e36 100644
--- a/btif/src/btif_av.cc
+++ b/btif/src/btif_av.cc
@@ -73,7 +73,8 @@
 
 typedef struct {
   tBTA_AV_HNDL bta_handle;
-  bt_bdaddr_t peer_bda;
+  RawAddress peer_bda;
+  bool self_initiated_connection;
   btif_sm_handle_t sm_handle;
   uint8_t flags;
   tBTA_AV_EDR edr;
@@ -82,14 +83,14 @@
 } btif_av_cb_t;
 
 typedef struct {
-  bt_bdaddr_t* target_bda;
+  RawAddress* target_bda;
   uint16_t uuid;
 } btif_av_connect_req_t;
 
 typedef struct {
   int sample_rate;
   int channel_count;
-  bt_bdaddr_t peer_bd;
+  RawAddress peer_bd;
 } btif_av_sink_config_req_t;
 
 /*****************************************************************************
@@ -98,7 +99,7 @@
 static btav_source_callbacks_t* bt_av_src_callbacks = NULL;
 static btav_sink_callbacks_t* bt_av_sink_callbacks = NULL;
 static btif_av_cb_t btif_av_cb = {
-    0, {{0}}, 0, 0, 0, 0, std::vector<btav_a2dp_codec_config_t>()};
+    0, {{0}}, false, 0, 0, 0, 0, std::vector<btav_a2dp_codec_config_t>()};
 static alarm_t* av_open_on_rc_timer = NULL;
 
 /* both interface and media task needs to be ready to alloc incoming request */
@@ -142,13 +143,11 @@
  * Extern functions
  ************************************************************************/
 extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data);
-extern bool btif_rc_get_connected_peer(BD_ADDR peer_addr);
-extern uint8_t btif_rc_get_connected_peer_handle(BD_ADDR peer_addr);
-extern void btif_rc_check_handle_pending_play(BD_ADDR peer_addr,
+extern bool btif_rc_get_connected_peer(RawAddress* peer_addr);
+extern uint8_t btif_rc_get_connected_peer_handle(const RawAddress& peer_addr);
+extern void btif_rc_check_handle_pending_play(const RawAddress& peer_addr,
                                               bool bSendToApp);
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*****************************************************************************
  * Local helper functions
  *****************************************************************************/
@@ -221,14 +220,14 @@
  *
  ******************************************************************************/
 static void btif_initiate_av_open_timer_timeout(UNUSED_ATTR void* data) {
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
   btif_av_connect_req_t connect_req;
 
   /* is there at least one RC connection - There should be */
-  if (btif_rc_get_connected_peer(peer_addr)) {
-    BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __func__);
+  if (btif_rc_get_connected_peer(&peer_addr)) {
+    BTIF_TRACE_DEBUG("%s: Issuing connect to the remote RC peer", __func__);
     /* In case of AVRCP connection request, we will initiate SRC connection */
-    connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
+    connect_req.target_bda = &peer_addr;
     if (bt_av_sink_callbacks != NULL)
       connect_req.uuid = UUID_SERVCLASS_AUDIO_SINK;
     else if (bt_av_src_callbacks != NULL)
@@ -236,7 +235,7 @@
     btif_dispatch_sm_event(BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req,
                            sizeof(connect_req));
   } else {
-    BTIF_TRACE_ERROR("%s No connected RC peers", __func__);
+    BTIF_TRACE_ERROR("%s: No connected RC peers", __func__);
   }
 }
 
@@ -255,7 +254,7 @@
  *
  ******************************************************************************/
 static void btif_report_connection_state(btav_connection_state_t state,
-                                         bt_bdaddr_t* bd_addr) {
+                                         RawAddress* bd_addr) {
   if (bt_av_sink_callbacks != NULL) {
     HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
   } else if (bt_av_src_callbacks != NULL) {
@@ -277,7 +276,7 @@
  *
  ******************************************************************************/
 static void btif_report_audio_state(btav_audio_state_t state,
-                                    bt_bdaddr_t* bd_addr) {
+                                    RawAddress* bd_addr) {
   if (bt_av_sink_callbacks != NULL) {
     HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
   } else if (bt_av_src_callbacks != NULL) {
@@ -286,11 +285,12 @@
 }
 
 static void btif_update_source_codec(void* p_data) {
-  btav_a2dp_codec_config_t req;
+  BTIF_TRACE_DEBUG("%s", __func__);
+
   // copy to avoid alignment problems
+  btav_a2dp_codec_config_t req;
   memcpy(&req, p_data, sizeof(req));
 
-  BTIF_TRACE_DEBUG("BTIF_AV_SOURCE_CONFIG_REQ_EVT");
   btif_a2dp_source_encoder_user_config_update_req(req);
 }
 
@@ -305,8 +305,9 @@
           &codec_config, &codecs_local_capabilities,
           &codecs_selectable_capabilities)) {
     BTIF_TRACE_WARNING(
-        "BTIF_AV_SOURCE_CONFIG_UPDATED_EVT failed: "
-        "cannot get codec config and capabilities");
+        "%s: error reporting audio source codec state: "
+        "cannot get codec config and capabilities",
+        __func__);
     return;
   }
   if (bt_av_src_callbacks != NULL) {
@@ -326,14 +327,14 @@
  ******************************************************************************/
 
 static bool btif_av_state_idle_handler(btif_sm_event_t event, void* p_data) {
-  BTIF_TRACE_DEBUG("%s event:%s flags %x", __func__,
+  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                    dump_av_sm_event_name((btif_av_sm_event_t)event),
                    btif_av_cb.flags);
 
   switch (event) {
     case BTIF_SM_ENTER_EVT:
       /* clear the peer_bda */
-      memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
+      btif_av_cb.peer_bda = RawAddress::kEmpty;
       btif_av_cb.flags = 0;
       btif_av_cb.edr = 0;
       bta_av_co_init(btif_av_cb.codec_priorities);
@@ -353,20 +354,20 @@
     case BTA_AV_PENDING_EVT:
     case BTIF_AV_CONNECT_REQ_EVT: {
       if (event == BTIF_AV_CONNECT_REQ_EVT) {
-        memcpy(&btif_av_cb.peer_bda,
-               ((btif_av_connect_req_t*)p_data)->target_bda,
-               sizeof(bt_bdaddr_t));
-        BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle, true,
-                   BTA_SEC_AUTHENTICATE,
-                   ((btif_av_connect_req_t*)p_data)->uuid);
+        btif_av_connect_req_t* connect_req_p = (btif_av_connect_req_t*)p_data;
+        btif_av_cb.peer_bda = *connect_req_p->target_bda;
+        btif_av_cb.self_initiated_connection = true;
+        BTA_AvOpen(btif_av_cb.peer_bda, btif_av_cb.bta_handle, true,
+                   BTA_SEC_AUTHENTICATE, connect_req_p->uuid);
       } else if (event == BTA_AV_PENDING_EVT) {
-        bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
+        btif_av_cb.peer_bda = ((tBTA_AV*)p_data)->pend.bd_addr;
+        btif_av_cb.self_initiated_connection = false;
         if (bt_av_src_callbacks != NULL) {
-          BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle, true,
+          BTA_AvOpen(btif_av_cb.peer_bda, btif_av_cb.bta_handle, true,
                      BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SOURCE);
         }
         if (bt_av_sink_callbacks != NULL) {
-          BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle, true,
+          BTA_AvOpen(btif_av_cb.peer_bda, btif_av_cb.bta_handle, true,
                      BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SINK);
         }
       }
@@ -388,15 +389,14 @@
        * TODO: We may need to do this only on an AVRCP Play. FixMe
        */
 
-      BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
-      alarm_set_on_queue(av_open_on_rc_timer, BTIF_TIMEOUT_AV_OPEN_ON_RC_MS,
-                         btif_initiate_av_open_timer_timeout, NULL,
-                         btu_general_alarm_queue);
+      BTIF_TRACE_WARNING("%s: BTA_AV_RC_OPEN_EVT received w/o AV", __func__);
+      alarm_set_on_mloop(av_open_on_rc_timer, BTIF_TIMEOUT_AV_OPEN_ON_RC_MS,
+                         btif_initiate_av_open_timer_timeout, NULL);
       btif_rc_handler(event, (tBTA_AV*)p_data);
       break;
 
     case BTA_AV_RC_BROWSE_OPEN_EVT:
-      BTIF_TRACE_DEBUG("BTA_AV_RC_BROWSE_OPEN_EVT received");
+      BTIF_TRACE_DEBUG("%s: BTA_AV_RC_BROWSE_OPEN_EVT received", __func__);
       btif_rc_handler(event, (tBTA_AV*)p_data);
       break;
 
@@ -420,8 +420,10 @@
       // copy to avoid alignment problems
       memcpy(&req, p_data, sizeof(req));
 
-      BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
-                         req.channel_count);
+      BTIF_TRACE_WARNING(
+          "%s: BTIF_AV_SINK_CONFIG_REQ_EVT sample_rate=%d "
+          "channel_count=%d",
+          __func__, req.sample_rate, req.channel_count);
       if (bt_av_sink_callbacks != NULL) {
         HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(req.peer_bd),
                   req.sample_rate, req.channel_count);
@@ -432,8 +434,8 @@
       tBTA_AV* p_bta_data = (tBTA_AV*)p_data;
       btav_connection_state_t state;
       btif_sm_state_t av_state;
-      BTIF_TRACE_DEBUG("status:%d, edr 0x%x", p_bta_data->open.status,
-                       p_bta_data->open.edr);
+      BTIF_TRACE_WARNING("%s: BTA_AV_OPEN_EVT status=%d, edr=0x%x", __func__,
+                         p_bta_data->open.status, p_bta_data->open.edr);
 
       if (p_bta_data->open.status == BTA_AV_SUCCESS) {
         state = BTAV_CONNECTION_STATE_CONNECTED;
@@ -442,7 +444,7 @@
 
         btif_av_cb.peer_sep = p_bta_data->open.sep;
       } else {
-        BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
+        BTIF_TRACE_WARNING("%s: BTA_AV_OPEN_EVT::FAILED status=%d", __func__,
                            p_bta_data->open.status);
         state = BTAV_CONNECTION_STATE_DISCONNECTED;
         av_state = BTIF_AV_STATE_IDLE;
@@ -474,19 +476,20 @@
       break;
 
     case BTA_AV_RC_CLOSE_EVT:
-      BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
+      BTIF_TRACE_DEBUG("%s: BTA_AV_RC_CLOSE_EVT: Stopping AV timer.", __func__);
       alarm_cancel(av_open_on_rc_timer);
       btif_rc_handler(event, (tBTA_AV*)p_data);
       break;
 
     case BTIF_AV_OFFLOAD_START_REQ_EVT:
       BTIF_TRACE_ERROR(
-          "BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started IDLE");
+          "%s: BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started IDLE",
+          __func__);
       btif_a2dp_on_offload_started(BTA_AV_FAIL);
       break;
 
     default:
-      BTIF_TRACE_WARNING("%s : unhandled event:%s", __func__,
+      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                          dump_av_sm_event_name((btif_av_sm_event_t)event));
       return false;
   }
@@ -505,7 +508,7 @@
  ******************************************************************************/
 
 static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
-  BTIF_TRACE_DEBUG("%s event:%s flags %x", __func__,
+  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                    dump_av_sm_event_name((btif_av_sm_event_t)event),
                    btif_av_cb.flags);
 
@@ -520,18 +523,21 @@
       break;
 
     case BTA_AV_REJECT_EVT:
-      BTIF_TRACE_DEBUG(" Received  BTA_AV_REJECT_EVT ");
+      BTIF_TRACE_WARNING("%s: Received BTA_AV_REJECT_EVT", __func__);
       btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                    &(btif_av_cb.peer_bda));
       btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+      if (btif_av_cb.self_initiated_connection) {
+        btif_queue_advance();
+      }
       break;
 
     case BTA_AV_OPEN_EVT: {
       tBTA_AV* p_bta_data = (tBTA_AV*)p_data;
       btav_connection_state_t state;
       btif_sm_state_t av_state;
-      BTIF_TRACE_DEBUG("status:%d, edr 0x%x", p_bta_data->open.status,
-                       p_bta_data->open.edr);
+      BTIF_TRACE_WARNING("%s: BTA_AV_OPEN_EVT status=%d, edr=0x%x", __func__,
+                         p_bta_data->open.status, p_bta_data->open.edr);
 
       if (p_bta_data->open.status == BTA_AV_SUCCESS) {
         state = BTAV_CONNECTION_STATE_CONNECTED;
@@ -540,17 +546,18 @@
 
         btif_av_cb.peer_sep = p_bta_data->open.sep;
       } else {
-        BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
+        BTIF_TRACE_WARNING("%s: BTA_AV_OPEN_EVT::FAILED status: %d", __func__,
                            p_bta_data->open.status);
-        BD_ADDR peer_addr;
+        RawAddress peer_addr;
         uint8_t peer_handle = BTRC_HANDLE_NONE;
-        if ((btif_rc_get_connected_peer(peer_addr)) &&
-            (!bdcmp(btif_av_cb.peer_bda.address, peer_addr))) {
+        if (btif_rc_get_connected_peer(&peer_addr) &&
+            btif_av_cb.peer_bda == peer_addr) {
           /*
            * Disconnect AVRCP connection, if
            * A2DP conneciton failed, for any reason
            */
-          BTIF_TRACE_WARNING(" Disconnecting AVRCP ");
+          BTIF_TRACE_WARNING("%s: Disconnecting AVRCP: peer_addr=%s", __func__,
+                             peer_addr.ToString().c_str());
           peer_handle = btif_rc_get_connected_peer_handle(peer_addr);
           if (peer_handle != BTRC_HANDLE_NONE) {
             BTA_AvCloseRc(peer_handle);
@@ -574,7 +581,9 @@
         /* Bring up AVRCP connection too */
         BTA_AvOpenRc(btif_av_cb.bta_handle);
       }
-      btif_queue_advance();
+      if (btif_av_cb.self_initiated_connection) {
+        btif_queue_advance();
+      }
     } break;
 
     case BTIF_AV_SOURCE_CONFIG_REQ_EVT:
@@ -590,8 +599,10 @@
       // copy to avoid alignment problems
       memcpy(&req, p_data, sizeof(req));
 
-      BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
-                         req.channel_count);
+      BTIF_TRACE_WARNING(
+          "%s: BTIF_AV_SINK_CONFIG_REQ_EVT sample_rate=%d "
+          "channel_count=%d",
+          __func__, req.sample_rate, req.channel_count);
       if (btif_av_cb.peer_sep == AVDT_TSEP_SRC &&
           bt_av_sink_callbacks != NULL) {
         HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
@@ -599,45 +610,49 @@
       }
     } break;
 
-    case BTIF_AV_CONNECT_REQ_EVT:
+    case BTIF_AV_CONNECT_REQ_EVT: {
       // Check for device, if same device which moved to opening then ignore
       // callback
-      if (memcmp(((btif_av_connect_req_t*)p_data)->target_bda,
-                 &(btif_av_cb.peer_bda), sizeof(btif_av_cb.peer_bda)) == 0) {
-        BTIF_TRACE_DEBUG(
-            "%s: Same device moved to Opening state,ignore Connect Req",
-            __func__);
-        btif_queue_advance();
-        break;
+      btif_av_connect_req_t* connect_req_p = (btif_av_connect_req_t*)p_data;
+      RawAddress& target_bda = *connect_req_p->target_bda;
+      if (btif_av_cb.peer_bda == target_bda) {
+        BTIF_TRACE_WARNING(
+            "%s: device %s is already connecting, ignore Connect request",
+            __func__, btif_av_cb.peer_bda.ToString().c_str());
       } else {
-        BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request",
-                         __func__);
-        btif_report_connection_state(
-            BTAV_CONNECTION_STATE_DISCONNECTED,
-            ((btif_av_connect_req_t*)p_data)->target_bda);
-        btif_queue_advance();
-        break;
+        BTIF_TRACE_WARNING(
+            "%s: device %s is already connecting, reject Connect request to %s",
+            __func__, btif_av_cb.peer_bda.ToString().c_str(),
+            target_bda.ToString().c_str());
+        btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
+                                     &target_bda);
       }
+      // Ignore all connection request if we are already opening
+      btif_queue_advance();
+    } break;
 
-    case BTA_AV_PENDING_EVT:
+    case BTA_AV_PENDING_EVT: {
       // Check for device, if same device which moved to opening then ignore
       // callback
-      if (memcmp(((tBTA_AV*)p_data)->pend.bd_addr, &(btif_av_cb.peer_bda),
-                 sizeof(btif_av_cb.peer_bda)) == 0) {
-        BTIF_TRACE_DEBUG(
-            "%s: Same device moved to Opening state,ignore Pending Req",
-            __func__);
-        break;
+      const RawAddress& bd_addr = ((tBTA_AV*)p_data)->pend.bd_addr;
+      if (bd_addr == btif_av_cb.peer_bda) {
+        BTIF_TRACE_WARNING(
+            "%s: device %s is already connecting, ignore incoming request",
+            __func__, btif_av_cb.peer_bda.ToString().c_str());
       } else {
-        BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request",
-                         __func__);
-        BTA_AvDisconnect(((tBTA_AV*)p_data)->pend.bd_addr);
-        break;
+        BTIF_TRACE_WARNING(
+            "%s: device %s is already connecting, reject incoming request "
+            "from %s",
+            __func__, btif_av_cb.peer_bda.ToString().c_str(),
+            bd_addr.ToString().c_str());
+        BTA_AvDisconnect(bd_addr);
       }
+    } break;
 
     case BTIF_AV_OFFLOAD_START_REQ_EVT:
       BTIF_TRACE_ERROR(
-          "BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started OPENING");
+          "%s: BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started OPENING",
+          __func__);
       btif_a2dp_on_offload_started(BTA_AV_FAIL);
       break;
 
@@ -646,12 +661,25 @@
       btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                    &(btif_av_cb.peer_bda));
       btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+      if (btif_av_cb.self_initiated_connection) {
+        btif_queue_advance();
+      }
+      break;
+
+    case BTIF_AV_DISCONNECT_REQ_EVT:
+      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
+                                   &(btif_av_cb.peer_bda));
+      BTA_AvClose(btif_av_cb.bta_handle);
+      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+      if (btif_av_cb.self_initiated_connection) {
+        btif_queue_advance();
+      }
       break;
 
       CHECK_RC_EVENT(event, (tBTA_AV*)p_data);
 
     default:
-      BTIF_TRACE_WARNING("%s : unhandled event:%s", __func__,
+      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                          dump_av_sm_event_name((btif_av_sm_event_t)event));
       return false;
   }
@@ -670,7 +698,7 @@
  ******************************************************************************/
 
 static bool btif_av_state_closing_handler(btif_sm_event_t event, void* p_data) {
-  BTIF_TRACE_DEBUG("%s event:%s flags %x", __func__,
+  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                    dump_av_sm_event_name((btif_av_sm_event_t)event),
                    btif_av_cb.flags);
 
@@ -723,12 +751,13 @@
 
     case BTIF_AV_OFFLOAD_START_REQ_EVT:
       BTIF_TRACE_ERROR(
-          "BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Closing");
+          "%s: BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Closing",
+          __func__);
       btif_a2dp_on_offload_started(BTA_AV_FAIL);
       break;
 
     default:
-      BTIF_TRACE_WARNING("%s : unhandled event:%s", __func__,
+      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                          dump_av_sm_event_name((btif_av_sm_event_t)event));
       return false;
   }
@@ -748,7 +777,7 @@
 static bool btif_av_state_opened_handler(btif_sm_event_t event, void* p_data) {
   tBTA_AV* p_av = (tBTA_AV*)p_data;
 
-  BTIF_TRACE_DEBUG("%s event:%s flags %x", __func__,
+  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                    dump_av_sm_event_name((btif_av_sm_event_t)event),
                    btif_av_cb.flags);
 
@@ -776,9 +805,11 @@
       break;
 
     case BTA_AV_START_EVT: {
-      BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
-                       p_av->start.status, p_av->start.suspending,
-                       p_av->start.initiator);
+      BTIF_TRACE_WARNING(
+          "%s: BTA_AV_START_EVT status=%d suspending=%d initiator=%d "
+          "flags=0x%x",
+          __func__, p_av->start.status, p_av->start.suspending,
+          p_av->start.initiator, btif_av_cb.flags);
 
       if ((p_av->start.status == BTA_SUCCESS) &&
           (p_av->start.suspending == true))
@@ -790,8 +821,8 @@
        */
       if (!(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)) {
         if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
-          BTIF_TRACE_EVENT("%s: trigger suspend as remote initiated!!",
-                           __func__);
+          BTIF_TRACE_WARNING("%s: trigger suspend as remote initiated!!",
+                             __func__);
           btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
         }
       }
@@ -870,30 +901,35 @@
       }
       break;
 
-    case BTIF_AV_CONNECT_REQ_EVT:
-      if (memcmp((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
-                 sizeof(btif_av_cb.peer_bda)) == 0) {
-        BTIF_TRACE_DEBUG("%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device",
-                         __func__);
+    case BTIF_AV_CONNECT_REQ_EVT: {
+      btif_av_connect_req_t* connect_req_p = (btif_av_connect_req_t*)p_data;
+      RawAddress& target_bda = *connect_req_p->target_bda;
+      if (btif_av_cb.peer_bda == target_bda) {
+        BTIF_TRACE_WARNING(
+            "%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device: target_bda=%s",
+            __func__, target_bda.ToString().c_str());
       } else {
-        BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req",
-                         __func__);
+        BTIF_TRACE_WARNING(
+            "%s: Moved to opened by Other incoming Connect request: "
+            "target_bda=%s",
+            __func__, target_bda.ToString().c_str());
         btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
-                                     (bt_bdaddr_t*)p_data);
+                                     &target_bda);
       }
       btif_queue_advance();
-      break;
+    } break;
 
     case BTIF_AV_OFFLOAD_START_REQ_EVT:
       BTIF_TRACE_ERROR(
-          "BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Opened");
+          "%s: BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Opened",
+          __func__);
       btif_a2dp_on_offload_started(BTA_AV_FAIL);
       break;
 
       CHECK_RC_EVENT(event, (tBTA_AV*)p_data);
 
     default:
-      BTIF_TRACE_WARNING("%s : unhandled event:%s", __func__,
+      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                          dump_av_sm_event_name((btif_av_sm_event_t)event));
       return false;
   }
@@ -913,7 +949,7 @@
 static bool btif_av_state_started_handler(btif_sm_event_t event, void* p_data) {
   tBTA_AV* p_av = (tBTA_AV*)p_data;
 
-  BTIF_TRACE_DEBUG("%s event:%s flags %x", __func__,
+  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                    dump_av_sm_event_name((btif_av_sm_event_t)event),
                    btif_av_cb.flags);
 
@@ -951,7 +987,9 @@
     /* fixme -- use suspend = true always to work around issue with BTA AV */
     case BTIF_AV_STOP_STREAM_REQ_EVT:
     case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
-
+      BTIF_TRACE_WARNING("%s: event=%s flags=0x%x", __func__,
+                         dump_av_sm_event_name((btif_av_sm_event_t)event),
+                         btif_av_cb.flags);
       /* set pending flag to ensure btif task is not trying to restart
          stream while suspend is in progress */
       btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
@@ -976,6 +1014,9 @@
       break;
 
     case BTIF_AV_DISCONNECT_REQ_EVT:
+      BTIF_TRACE_WARNING("%s: event=%s flags=0x%x", __func__,
+                         dump_av_sm_event_name((btif_av_sm_event_t)event),
+                         btif_av_cb.flags);
 
       /* request avdtp to close */
       BTA_AvClose(btif_av_cb.bta_handle);
@@ -992,9 +1033,9 @@
       break;
 
     case BTA_AV_SUSPEND_EVT:
-
-      BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
-                       p_av->suspend.status, p_av->suspend.initiator);
+      BTIF_TRACE_WARNING(
+          "%s: BTA_AV_SUSPEND_EVT status=%d initiator=%d flags=0x%x", __func__,
+          p_av->suspend.status, p_av->suspend.initiator, btif_av_cb.flags);
 
       /* a2dp suspended, stop media task until resumed */
       btif_a2dp_on_suspended(&p_av->suspend);
@@ -1033,6 +1074,9 @@
       break;
 
     case BTA_AV_STOP_EVT:
+      BTIF_TRACE_WARNING("%s: event=%s flags=0x%x", __func__,
+                         dump_av_sm_event_name((btif_av_sm_event_t)event),
+                         btif_av_cb.flags);
 
       btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
       btif_a2dp_on_stopped(&p_av->suspend);
@@ -1046,6 +1090,9 @@
       break;
 
     case BTA_AV_CLOSE_EVT:
+      BTIF_TRACE_WARNING("%s: event=%s flags=0x%x", __func__,
+                         dump_av_sm_event_name((btif_av_sm_event_t)event),
+                         btif_av_cb.flags);
 
       btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
 
@@ -1070,7 +1117,7 @@
       CHECK_RC_EVENT(event, (tBTA_AV*)p_data);
 
     default:
-      BTIF_TRACE_WARNING("%s: unhandled event: %s", __func__,
+      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                          dump_av_sm_event_name((btif_av_sm_event_t)event));
       return false;
   }
@@ -1083,7 +1130,7 @@
  *****************************************************************************/
 
 static void btif_av_handle_event(uint16_t event, char* p_param) {
-  BTIF_TRACE_EVENT("%s event:%s", __func__,
+  BTIF_TRACE_EVENT("%s: event=%s", __func__,
                    dump_av_sm_event_name((btif_av_sm_event_t)event));
   switch (event) {
     case BTIF_AV_CLEANUP_REQ_EVT:
@@ -1206,8 +1253,7 @@
         break;
       }
 
-      memcpy(&config_req.peer_bd, (uint8_t*)(p_data->avk_config.bd_addr),
-             sizeof(config_req.peer_bd));
+      config_req.peer_bd = p_data->avk_config.bd_addr;
       btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
                             (char*)&config_req, sizeof(config_req), NULL);
       break;
@@ -1268,7 +1314,7 @@
 static bt_status_t init_src(
     btav_source_callbacks_t* callbacks,
     std::vector<btav_a2dp_codec_config_t> codec_priorities) {
-  BTIF_TRACE_EVENT("%s()", __func__);
+  BTIF_TRACE_EVENT("%s", __func__);
 
   btif_av_cb.codec_priorities = codec_priorities;
   bt_status_t status = btif_av_init(BTA_A2DP_SOURCE_SERVICE_ID);
@@ -1288,7 +1334,7 @@
  ******************************************************************************/
 
 static bt_status_t init_sink(btav_sink_callbacks_t* callbacks) {
-  BTIF_TRACE_EVENT("%s()", __func__);
+  BTIF_TRACE_EVENT("%s", __func__);
 
   bt_status_t status = btif_av_init(BTA_A2DP_SINK_SERVICE_ID);
   if (status == BT_STATUS_SUCCESS) bt_av_sink_callbacks = callbacks;
@@ -1307,7 +1353,7 @@
  *
  ******************************************************************************/
 static void update_audio_focus_state(int state) {
-  BTIF_TRACE_DEBUG("%s: state %d", __func__, state);
+  BTIF_TRACE_DEBUG("%s: state=%d", __func__, state);
   btif_a2dp_sink_set_focus_state_req((btif_a2dp_sink_focus_state_t)state);
 }
 
@@ -1321,7 +1367,7 @@
  *
  ******************************************************************************/
 static void update_audio_track_gain(float gain) {
-  BTIF_TRACE_DEBUG("%s: gain %f", __func__, gain);
+  BTIF_TRACE_DEBUG("%s: gain=%f", __func__, gain);
   btif_a2dp_sink_set_audio_track_gain(gain);
 }
 
@@ -1336,7 +1382,7 @@
  *
  ******************************************************************************/
 
-static bt_status_t connect_int(bt_bdaddr_t* bd_addr, uint16_t uuid) {
+static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) {
   btif_av_connect_req_t connect_req;
   connect_req.target_bda = bd_addr;
   connect_req.uuid = uuid;
@@ -1348,14 +1394,14 @@
   return BT_STATUS_SUCCESS;
 }
 
-static bt_status_t src_connect_sink(bt_bdaddr_t* bd_addr) {
+static bt_status_t src_connect_sink(RawAddress* bd_addr) {
   BTIF_TRACE_EVENT("%s", __func__);
   CHECK_BTAV_INIT();
 
   return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
 }
 
-static bt_status_t sink_connect_src(bt_bdaddr_t* bd_addr) {
+static bt_status_t sink_connect_src(RawAddress* bd_addr) {
   BTIF_TRACE_EVENT("%s", __func__);
   CHECK_BTAV_INIT();
 
@@ -1371,13 +1417,13 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t disconnect(bt_bdaddr_t* bd_addr) {
+static bt_status_t disconnect(RawAddress* bd_addr) {
   BTIF_TRACE_EVENT("%s", __func__);
   CHECK_BTAV_INIT();
 
   /* Switch to BTIF context */
   return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
-                               (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+                               (char*)bd_addr, sizeof(RawAddress), NULL);
 }
 
 static bt_status_t codec_config_src(
@@ -1476,7 +1522,7 @@
  *
  ******************************************************************************/
 
-bt_bdaddr_t btif_av_get_addr(void) { return btif_av_cb.peer_bda; }
+RawAddress btif_av_get_addr(void) { return btif_av_cb.peer_bda; }
 
 /*******************************************************************************
  * Function         btif_av_is_sink_enabled
@@ -1504,12 +1550,12 @@
 bool btif_av_stream_ready(void) {
   btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
 
-  BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
+  BTIF_TRACE_DEBUG("%s: sm_handle=%d, state=%d, flags=0x%x", __func__,
                    btif_av_cb.sm_handle, state, btif_av_cb.flags);
 
   /* also make sure main adapter is enabled */
   if (btif_is_enabled() == 0) {
-    BTIF_TRACE_EVENT("main adapter not enabled");
+    BTIF_TRACE_EVENT("%s: main adapter not enabled", __func__);
     return false;
   }
 
@@ -1533,17 +1579,21 @@
 
 bool btif_av_stream_started_ready(void) {
   btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
-
-  BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
-                   btif_av_cb.sm_handle, state, btif_av_cb.flags);
+  bool ready = false;
 
   /* disallow media task to start if we have pending actions */
   if (btif_av_cb.flags &
       (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND |
-       BTIF_AV_FLAG_PENDING_STOP))
-    return false;
+       BTIF_AV_FLAG_PENDING_STOP)) {
+    ready = false;
+  } else {
+    ready = (state == BTIF_AV_STATE_STARTED);
+  }
 
-  return (state == BTIF_AV_STATE_STARTED);
+  BTIF_TRACE_WARNING("%s: sm_handle=%d state=%d flags=0x%x ready=%d", __func__,
+                     btif_av_cb.sm_handle, state, btif_av_cb.flags, ready);
+
+  return ready;
 }
 
 /*******************************************************************************
@@ -1708,7 +1758,7 @@
  * Returns          void
  *****************************************************************************/
 void btif_av_clear_remote_suspend_flag(void) {
-  BTIF_TRACE_DEBUG("%s: flag :%x", __func__, btif_av_cb.flags);
+  BTIF_TRACE_DEBUG("%s: flags=0x%x", __func__, btif_av_cb.flags);
   btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
 }
 
@@ -1742,14 +1792,14 @@
  * Returns          Void
  *
  ******************************************************************************/
-void btif_av_move_idle(bt_bdaddr_t bd_addr) {
+void btif_av_move_idle(RawAddress bd_addr) {
   /* inform the application that ACL is disconnected and move to idle state */
   btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
-  BTIF_TRACE_DEBUG("%s: ACL Disconnected state %d  is same device %d", __func__,
-                   state,
-                   memcmp(&bd_addr, &(btif_av_cb.peer_bda), sizeof(bd_addr)));
-  if (state == BTIF_AV_STATE_OPENING &&
-      (memcmp(&bd_addr, &(btif_av_cb.peer_bda), sizeof(bd_addr)) == 0)) {
+  BTIF_TRACE_WARNING("%s: ACL Disconnected state %d bd_addr=%s peer_bda=%s",
+                     __func__, state, bd_addr.ToString().c_str(),
+                     btif_av_cb.peer_bda.ToString().c_str());
+
+  if (state == BTIF_AV_STATE_OPENING && (bd_addr == btif_av_cb.peer_bda)) {
     BTIF_TRACE_DEBUG(
         "%s: Moving State from Opening to Idle due to ACL disconnect",
         __func__);
diff --git a/btif/src/btif_ble_scanner.cc b/btif/src/btif_ble_scanner.cc
index 9188624..02538c6 100644
--- a/btif/src/btif_ble_scanner.cc
+++ b/btif/src/btif_ble_scanner.cc
@@ -28,7 +28,6 @@
 #include <unordered_set>
 #include "device/include/controller.h"
 
-#include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "btif_util.h"
 
@@ -64,41 +63,32 @@
     }                                                                \
   } while (0)
 
-namespace std {
-template <>
-struct hash<bt_bdaddr_t> {
-  size_t operator()(const bt_bdaddr_t& f) const {
-    return f.address[0] + f.address[1] + f.address[2] + f.address[3] +
-           f.address[4] + f.address[5];
-  }
-};
-
-template <>
-struct equal_to<bt_bdaddr_t> {
-  size_t operator()(const bt_bdaddr_t& x, const bt_bdaddr_t& y) const {
-    return (memcmp(x.address, y.address, BD_ADDR_LEN) == 0);
-  }
-};
-}
-
 namespace {
 
 // all access to this variable should be done on the jni thread
-std::unordered_set<bt_bdaddr_t> p_dev_cb;
+std::set<RawAddress> remote_bdaddr_cache;
+std::queue<RawAddress> remote_bdaddr_cache_ordered;
+const size_t remote_bdaddr_cache_max_size = 1024;
 
-void btif_gattc_add_remote_bdaddr(BD_ADDR p_bda, uint8_t addr_type) {
-  bt_bdaddr_t bd_addr;
-  memcpy(bd_addr.address, p_bda, BD_ADDR_LEN);
-  p_dev_cb.insert(bd_addr);
+void btif_gattc_add_remote_bdaddr(const RawAddress& p_bda, uint8_t addr_type) {
+  // Remove the oldest entries
+  while (remote_bdaddr_cache.size() >= remote_bdaddr_cache_max_size) {
+    const RawAddress& raw_address = remote_bdaddr_cache_ordered.front();
+    remote_bdaddr_cache.erase(raw_address);
+    remote_bdaddr_cache_ordered.pop();
+  }
+  remote_bdaddr_cache.insert(p_bda);
+  remote_bdaddr_cache_ordered.push(p_bda);
 }
 
-bool btif_gattc_find_bdaddr(BD_ADDR p_bda) {
-  bt_bdaddr_t bd_addr;
-  memcpy(bd_addr.address, p_bda, BD_ADDR_LEN);
-  return (p_dev_cb.count(bd_addr) != 0);
+bool btif_gattc_find_bdaddr(const RawAddress& p_bda) {
+  return (remote_bdaddr_cache.find(p_bda) != remote_bdaddr_cache.end());
 }
 
-void btif_gattc_init_dev_cb(void) { p_dev_cb.clear(); }
+void btif_gattc_init_dev_cb(void) {
+  remote_bdaddr_cache.clear();
+  remote_bdaddr_cache_ordered = {};
+}
 
 void btif_gatts_upstreams_evt(uint16_t event, char* p_param) {
   LOG_VERBOSE(LOG_TAG, "%s: Event %d", __func__, event);
@@ -138,7 +128,7 @@
                     num_records, std::move(data));
 }
 
-void bta_scan_results_cb_impl(bt_bdaddr_t bd_addr, tBT_DEVICE_TYPE device_type,
+void bta_scan_results_cb_impl(RawAddress bd_addr, tBT_DEVICE_TYPE device_type,
                               int8_t rssi, uint8_t addr_type,
                               uint16_t ble_evt_type, uint8_t ble_primary_phy,
                               uint8_t ble_secondary_phy,
@@ -158,8 +148,8 @@
   }
 
   if ((addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name)) {
-    if (!btif_gattc_find_bdaddr(bd_addr.address)) {
-      btif_gattc_add_remote_bdaddr(bd_addr.address, addr_type);
+    if (!btif_gattc_find_bdaddr(bd_addr)) {
+      btif_gattc_add_remote_bdaddr(bd_addr, addr_type);
 
       if (p_eir_remote_name) {
         if (remote_name_len > BD_NAME_LEN + 1 ||
@@ -178,8 +168,7 @@
 
         LOG_VERBOSE(LOG_TAG, "%s BLE device name=%s len=%d dev_type=%d",
                     __func__, bdname.name, remote_name_len, device_type);
-        btif_dm_update_ble_remote_properties(bd_addr.address, bdname.name,
-                                             device_type);
+        btif_dm_update_ble_remote_properties(bd_addr, bdname.name, device_type);
       }
     }
   }
@@ -221,9 +210,7 @@
   }
 
   tBTA_DM_INQ_RES* r = &p_data->inq_res;
-  bt_bdaddr_t bdaddr;
-  bdcpy(bdaddr.address, r->bd_addr);
-  do_in_jni_thread(Bind(bta_scan_results_cb_impl, bdaddr, r->device_type,
+  do_in_jni_thread(Bind(bta_scan_results_cb_impl, r->bd_addr, r->device_type,
                         r->rssi, r->ble_addr_type, r->ble_evt_type,
                         r->ble_primary_phy, r->ble_secondary_phy,
                         r->ble_advertising_sid, r->ble_tx_power,
@@ -297,7 +284,7 @@
                            int company_id, int company_id_mask,
                            const bt_uuid_t* p_uuid,
                            const bt_uuid_t* p_uuid_mask,
-                           const bt_bdaddr_t* bd_addr, char addr_type,
+                           const RawAddress* bd_addr, char addr_type,
                            vector<uint8_t> data, vector<uint8_t> mask,
                            FilterConfigCallback cb) override {
     BTIF_TRACE_DEBUG("%s, %d, %d", __func__, action, filt_type);
@@ -309,7 +296,7 @@
     switch (filt_type) {
       case BTM_BLE_PF_ADDR_FILTER: {
         tBLE_BD_ADDR target_addr;
-        bdcpy(target_addr.bda, bd_addr->address);
+        target_addr.bda = *bd_addr;
         target_addr.type = addr_type;
 
         do_in_bta_thread(
@@ -439,7 +426,7 @@
                                 Bind(bta_batch_scan_reports_cb, client_if)));
   }
 
-  void StartSync(uint8_t sid, bt_bdaddr_t address, uint16_t skip,
+  void StartSync(uint8_t sid, RawAddress address, uint16_t skip,
                  uint16_t timeout, StartSyncCb start_cb, SyncReportCb report_cb,
                  SyncLostCb lost_cb) override {}
 
diff --git a/btif/src/btif_config.cc b/btif/src/btif_config.cc
index f6faa7d..1af751a 100644
--- a/btif/src/btif_config.cc
+++ b/btif/src/btif_config.cc
@@ -31,7 +31,6 @@
 #include <mutex>
 
 #include "bt_types.h"
-#include "btcore/include/bdaddr.h"
 #include "btcore/include/module.h"
 #include "btif_api.h"
 #include "btif_common.h"
@@ -89,14 +88,11 @@
 // TODO(zachoverflow): Move these two functions out, because they are too
 // specific for this file
 // {grumpy-cat/no, monty-python/you-make-me-sad}
-bool btif_get_device_type(const BD_ADDR bd_addr, int* p_device_type) {
+bool btif_get_device_type(const RawAddress& bda, int* p_device_type) {
   if (p_device_type == NULL) return false;
 
-  bt_bdaddr_t bda;
-  bdcpy(bda.address, bd_addr);
-
-  bdstr_t bd_addr_str;
-  bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
+  std::string addrstr = bda.ToString();
+  const char* bd_addr_str = addrstr.c_str();
 
   if (!btif_config_get_int(bd_addr_str, "DevType", p_device_type)) return false;
 
@@ -105,14 +101,11 @@
   return true;
 }
 
-bool btif_get_address_type(const BD_ADDR bd_addr, int* p_addr_type) {
+bool btif_get_address_type(const RawAddress& bda, int* p_addr_type) {
   if (p_addr_type == NULL) return false;
 
-  bt_bdaddr_t bda;
-  bdcpy(bda.address, bd_addr);
-
-  bdstr_t bd_addr_str;
-  bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
+  std::string addrstr = bda.ToString();
+  const char* bd_addr_str = addrstr.c_str();
 
   if (!btif_config_get_int(bd_addr_str, "AddrType", p_addr_type)) return false;
 
@@ -477,7 +470,7 @@
   const config_section_node_t* snode = config_section_begin(conf);
   while (snode != config_section_end(conf)) {
     const char* section = config_section_name(snode);
-    if (string_is_bdaddr(section)) {
+    if (RawAddress::IsValidAddress(section)) {
       if (!config_has_key(conf, section, "LinkKey") &&
           !config_has_key(conf, section, "LE_KEY_PENC") &&
           !config_has_key(conf, section, "LE_KEY_PID") &&
@@ -535,7 +528,7 @@
   const config_section_node_t* snode = config_section_begin(config);
   while (snode != config_section_end(config)) {
     const char* section = config_section_name(snode);
-    if (string_is_bdaddr(section) &&
+    if (RawAddress::IsValidAddress(section) &&
         config_has_key(config, section, "Restricted")) {
       BTIF_TRACE_DEBUG("%s: Removing restricted device %s", __func__, section);
       config_remove_section(config, section);
diff --git a/btif/src/btif_core.cc b/btif/src/btif_core.cc
index 6077f46..febf945 100644
--- a/btif/src/btif_core.cc
+++ b/btif/src/btif_core.cc
@@ -42,7 +42,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include "bdaddr.h"
 #include "bt_common.h"
 #include "bt_utils.h"
 #include "bta_api.h"
@@ -84,16 +83,17 @@
  ******************************************************************************/
 
 /* These type definitions are used when passing data from the HAL to BTIF
-* context
-*  in the downstream path for the adapter and remote_device property APIs */
+ * context in the downstream path for the adapter and remote_device property
+ * APIs
+ */
 
 typedef struct {
-  bt_bdaddr_t bd_addr;
+  RawAddress bd_addr;
   bt_property_type_t type;
 } btif_storage_read_t;
 
 typedef struct {
-  bt_bdaddr_t bd_addr;
+  RawAddress bd_addr;
   bt_property_t prop;
 } btif_storage_write_t;
 
@@ -116,11 +116,11 @@
 static tBTA_SERVICE_MASK btif_enabled_services = 0;
 
 /*
-* This variable should be set to 1, if the Bluedroid+BTIF libraries are to
-* function in DUT mode.
-*
-* To set this, the btif_init_bluetooth needs to be called with argument as 1
-*/
+ * This variable should be set to 1, if the Bluedroid+BTIF libraries are to
+ * function in DUT mode.
+ *
+ * To set this, the btif_init_bluetooth needs to be called with argument as 1
+ */
 static uint8_t btif_dut_mode = 0;
 
 static thread_t* bt_jni_workqueue_thread;
@@ -314,6 +314,8 @@
 }
 
 void run_message_loop(UNUSED_ATTR void* context) {
+  LOG_INFO(LOG_TAG, "%s entered", __func__);
+
   // TODO(jpawlowski): exit_manager should be defined in main(), but there is no
   // main method.
   // It is therefore defined in bt_jni_workqueue_thread, and will be deleted
@@ -334,6 +336,8 @@
 
   delete jni_run_loop;
   jni_run_loop = NULL;
+
+  LOG_INFO(LOG_TAG, "%s finished", __func__);
 }
 /*******************************************************************************
  *
@@ -345,6 +349,8 @@
  *
  ******************************************************************************/
 bt_status_t btif_init_bluetooth() {
+  LOG_INFO(LOG_TAG, "%s entered", __func__);
+
   bte_main_boot_entry();
 
   bt_jni_workqueue_thread = thread_new(BT_JNI_WORKQUEUE_NAME);
@@ -356,6 +362,7 @@
 
   thread_post(bt_jni_workqueue_thread, run_message_loop, nullptr);
 
+  LOG_INFO(LOG_TAG, "%s finished", __func__);
   return BT_STATUS_SUCCESS;
 
 error_exit:;
@@ -378,30 +385,27 @@
  ******************************************************************************/
 
 void btif_enable_bluetooth_evt(tBTA_STATUS status) {
-  BTIF_TRACE_DEBUG("%s: status %d", __func__, status);
+  LOG_INFO(LOG_TAG, "%s entered: status %d", __func__, status);
 
   /* Fetch the local BD ADDR */
-  bt_bdaddr_t local_bd_addr;
-  const controller_t* controller = controller_get_interface();
-  bdaddr_copy(&local_bd_addr, controller->get_address());
+  RawAddress local_bd_addr = *controller_get_interface()->get_address();
 
-  bdstr_t bdstr;
-  bdaddr_to_string(&local_bd_addr, bdstr, sizeof(bdstr));
+  std::string bdstr = local_bd_addr.ToString();
 
   char val[PROPERTY_VALUE_MAX] = "";
   int val_size = 0;
   if ((btif_config_get_str("Adapter", "Address", val, &val_size) == 0) ||
-      strcmp(bdstr, val) == 0) {
+      strcmp(bdstr.c_str(), val) == 0) {
     // This address is not present in the config file, save it there.
     BTIF_TRACE_WARNING("%s: Saving the Adapter Address", __func__);
-    btif_config_set_str("Adapter", "Address", bdstr);
+    btif_config_set_str("Adapter", "Address", bdstr.c_str());
     btif_config_save();
 
     // fire HAL callback for property change
     bt_property_t prop;
     prop.type = BT_PROPERTY_BDADDR;
     prop.val = (void*)&local_bd_addr;
-    prop.len = sizeof(bt_bdaddr_t);
+    prop.len = sizeof(RawAddress);
     HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1,
               &prop);
   }
@@ -436,6 +440,8 @@
 
     future_ready(stack_manager_get_hack_future(), FUTURE_FAIL);
   }
+
+  LOG_INFO(LOG_TAG, "%s finished", __func__);
 }
 
 /*******************************************************************************
@@ -450,7 +456,7 @@
  *
  ******************************************************************************/
 bt_status_t btif_disable_bluetooth(void) {
-  BTIF_TRACE_DEBUG("BTIF DISABLE BLUETOOTH");
+  LOG_INFO(LOG_TAG, "%s entered", __func__);
 
   btm_ble_multi_adv_cleanup();
   // TODO(jpawlowski): this should do whole BTA_VendorCleanup(), but it would
@@ -462,6 +468,8 @@
   btif_pan_cleanup();
   BTA_DisableBluetooth();
 
+  LOG_INFO(LOG_TAG, "%s finished", __func__);
+
   return BT_STATUS_SUCCESS;
 }
 
@@ -478,12 +486,14 @@
  ******************************************************************************/
 
 void btif_disable_bluetooth_evt(void) {
-  BTIF_TRACE_DEBUG("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s entered", __func__);
 
   bte_main_disable();
 
   /* callback to HAL */
   future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
+
+  LOG_INFO(LOG_TAG, "%s finished", __func__);
 }
 
 /*******************************************************************************
@@ -497,7 +507,7 @@
  ******************************************************************************/
 
 bt_status_t btif_cleanup_bluetooth(void) {
-  BTIF_TRACE_DEBUG("%s", __func__);
+  LOG_INFO(LOG_TAG, "%s entered", __func__);
 
   BTA_VendorCleanup();
 
@@ -517,7 +527,7 @@
 
   btif_dut_mode = 0;
 
-  BTIF_TRACE_DEBUG("%s done", __func__);
+  LOG_INFO(LOG_TAG, "%s finished", __func__);
 
   return BT_STATUS_SUCCESS;
 }
@@ -593,15 +603,15 @@
   bt_property_t properties[6];
   uint32_t num_props = 0;
 
-  bt_bdaddr_t addr;
+  RawAddress addr;
   bt_bdname_t name;
   bt_scan_mode_t mode;
   uint32_t disc_timeout;
-  bt_bdaddr_t bonded_devices[BTM_SEC_MAX_DEVICE_RECORDS];
+  RawAddress bonded_devices[BTM_SEC_MAX_DEVICE_RECORDS];
   bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS];
   bt_status_t status;
 
-  /* BD_ADDR */
+  /* RawAddress */
   BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_BDADDR,
                              sizeof(addr), &addr);
   status = btif_storage_get_adapter_property(&properties[num_props]);
@@ -650,7 +660,7 @@
   return BT_STATUS_SUCCESS;
 }
 
-static bt_status_t btif_in_get_remote_device_properties(bt_bdaddr_t* bd_addr) {
+static bt_status_t btif_in_get_remote_device_properties(RawAddress* bd_addr) {
   bt_property_t remote_properties[8];
   uint32_t num_props = 0;
 
@@ -815,7 +825,7 @@
                                  bt_property_t* p_props) {
   HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, num_props, p_props);
 }
-void btif_remote_properties_evt(bt_status_t status, bt_bdaddr_t* remote_addr,
+void btif_remote_properties_evt(bt_status_t status, RawAddress* remote_addr,
                                 uint32_t num_props, bt_property_t* p_props) {
   HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, status, remote_addr,
             num_props, p_props);
@@ -840,8 +850,7 @@
   switch (event) {
     case BTIF_CORE_STORAGE_REMOTE_WRITE:
     case BTIF_CORE_STORAGE_ADAPTER_WRITE: {
-      bdcpy(new_req->write_req.bd_addr.address,
-            old_req->write_req.bd_addr.address);
+      new_req->write_req.bd_addr = old_req->write_req.bd_addr;
       /* Copy the member variables one at a time */
       new_req->write_req.prop.type = old_req->write_req.prop.type;
       new_req->write_req.prop.len = old_req->write_req.prop.len;
@@ -894,7 +903,7 @@
       (type != BT_PROPERTY_BDNAME))
     return BT_STATUS_NOT_READY;
 
-  memset(&(req.read_req.bd_addr), 0, sizeof(bt_bdaddr_t));
+  req.read_req.bd_addr = RawAddress::kEmpty;
   req.read_req.type = type;
 
   return btif_transfer_context(execute_storage_request,
@@ -996,7 +1005,7 @@
   if (storage_req_id != BTIF_CORE_STORAGE_NO_ACTION) {
     /* pass on to storage for updating local database */
 
-    memset(&(req.write_req.bd_addr), 0, sizeof(bt_bdaddr_t));
+    req.write_req.bd_addr = RawAddress::kEmpty;
     memcpy(&(req.write_req.prop), property, sizeof(bt_property_t));
 
     return btif_transfer_context(execute_storage_request, storage_req_id,
@@ -1017,13 +1026,13 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_get_remote_device_property(bt_bdaddr_t* remote_addr,
+bt_status_t btif_get_remote_device_property(RawAddress* remote_addr,
                                             bt_property_type_t type) {
   btif_storage_req_t req;
 
   if (!btif_is_enabled()) return BT_STATUS_NOT_READY;
 
-  memcpy(&(req.read_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t));
+  req.read_req.bd_addr = *remote_addr;
   req.read_req.type = type;
   return btif_transfer_context(execute_storage_remote_request,
                                BTIF_CORE_STORAGE_REMOTE_READ, (char*)&req,
@@ -1039,12 +1048,12 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_get_remote_device_properties(bt_bdaddr_t* remote_addr) {
+bt_status_t btif_get_remote_device_properties(RawAddress* remote_addr) {
   btif_storage_req_t req;
 
   if (!btif_is_enabled()) return BT_STATUS_NOT_READY;
 
-  memcpy(&(req.read_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t));
+  req.read_req.bd_addr = *remote_addr;
   return btif_transfer_context(execute_storage_remote_request,
                                BTIF_CORE_STORAGE_REMOTE_READ_ALL, (char*)&req,
                                sizeof(btif_storage_req_t), NULL);
@@ -1061,13 +1070,13 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_set_remote_device_property(bt_bdaddr_t* remote_addr,
+bt_status_t btif_set_remote_device_property(RawAddress* remote_addr,
                                             const bt_property_t* property) {
   btif_storage_req_t req;
 
   if (!btif_is_enabled()) return BT_STATUS_NOT_READY;
 
-  memcpy(&(req.write_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t));
+  req.write_req.bd_addr = *remote_addr;
   memcpy(&(req.write_req.prop), property, sizeof(bt_property_t));
 
   return btif_transfer_context(execute_storage_remote_request,
@@ -1086,7 +1095,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_get_remote_service_record(bt_bdaddr_t* remote_addr,
+bt_status_t btif_get_remote_service_record(RawAddress* remote_addr,
                                            bt_uuid_t* uuid) {
   if (!btif_is_enabled()) return BT_STATUS_NOT_READY;
 
diff --git a/btif/src/btif_debug_conn.cc b/btif/src/btif_debug_conn.cc
index 1a59456..9252a02 100644
--- a/btif/src/btif_debug_conn.cc
+++ b/btif/src/btif_debug_conn.cc
@@ -20,7 +20,6 @@
 #include <string.h>
 #include <time.h>
 
-#include "btcore/include/bdaddr.h"
 #include "btif/include/btif_debug_conn.h"
 #include "osi/include/time.h"
 
@@ -30,7 +29,7 @@
 typedef struct conn_event_t {
   uint64_t ts;
   btif_debug_conn_state_t state;
-  bt_bdaddr_t bda;
+  RawAddress bda;
   tGATT_DISCONN_REASON disconnect_reason;
 } conn_event_t;
 
@@ -64,7 +63,7 @@
   if (current_event == NUM_CONNECTION_EVENTS) current_event = 0;
 }
 
-void btif_debug_conn_state(const bt_bdaddr_t bda,
+void btif_debug_conn_state(const RawAddress& bda,
                            const btif_debug_conn_state_t state,
                            const tGATT_DISCONN_REASON disconnect_reason) {
   next_event();
@@ -73,7 +72,7 @@
   evt->ts = time_gettimeofday_us();
   evt->state = state;
   evt->disconnect_reason = disconnect_reason;
-  memcpy(&evt->bda, &bda, sizeof(bt_bdaddr_t));
+  evt->bda = bda;
 }
 
 void btif_debug_conn_dump(int fd) {
@@ -81,7 +80,6 @@
       current_event;  // Cache to avoid threading issues
   uint8_t dump_event = current_event_local;
   char ts_buffer[TEMP_BUFFER_SIZE] = {0};
-  char name_buffer[TEMP_BUFFER_SIZE] = {0};
 
   dprintf(fd, "\nConnection Events:\n");
   if (connection_events[dump_event].ts == 0) dprintf(fd, "  None\n");
@@ -89,8 +87,7 @@
   while (connection_events[dump_event].ts) {
     conn_event_t* evt = &connection_events[dump_event];
     dprintf(fd, "  %s %s %s", format_ts(evt->ts, ts_buffer, sizeof(ts_buffer)),
-            format_state(evt->state),
-            bdaddr_to_string(&evt->bda, name_buffer, sizeof(name_buffer)));
+            format_state(evt->state), evt->bda.ToString().c_str());
     if (evt->state == BTIF_DEBUG_DISCONNECTED)
       dprintf(fd, " reason=%d", evt->disconnect_reason);
     dprintf(fd, "\n");
diff --git a/btif/src/btif_dm.cc b/btif/src/btif_dm.cc
index 3aa56d2..ce2ca9a 100644
--- a/btif/src/btif_dm.cc
+++ b/btif/src/btif_dm.cc
@@ -44,7 +44,6 @@
 #include <hardware/bluetooth.h>
 
 #include "advertise_data_parser.h"
-#include "bdaddr.h"
 #include "bt_common.h"
 #include "bta_closure_api.h"
 #include "bta_gatt_api.h"
@@ -110,8 +109,8 @@
 
 typedef struct {
   bt_bond_state_t state;
-  bt_bdaddr_t static_bdaddr;
-  BD_ADDR bd_addr;
+  RawAddress static_bdaddr;
+  RawAddress bd_addr;
   tBTM_BOND_TYPE bond_type;
   uint8_t pin_code_len;
   uint8_t is_ssp;
@@ -141,18 +140,18 @@
 } btif_dm_local_key_cb_t;
 
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   BD_NAME bd_name;
 } btif_dm_remote_name_t;
 
 /* this structure holds optional OOB data for remote device */
 typedef struct {
-  BD_ADDR bdaddr; /* peer bdaddr */
+  RawAddress bdaddr; /* peer bdaddr */
   bt_out_of_band_data_t oob_data;
 } btif_dm_oob_cb_t;
 
 typedef struct {
-  bt_bdaddr_t bdaddr;
+  RawAddress bdaddr;
   uint8_t transport; /* 0=Unknown, 1=BR/EDR, 2=LE */
 } btif_dm_create_bond_cb_t;
 
@@ -175,7 +174,7 @@
 } bt_bond_function_t;
 
 typedef struct {
-  bt_bdaddr_t bd_addr;
+  RawAddress bd_addr;
   bt_bond_function_t function;
   bt_bond_state_t state;
   struct timespec timestamp;
@@ -216,11 +215,11 @@
 static btif_dm_pairing_cb_t pairing_cb;
 static btif_dm_oob_cb_t oob_cb;
 static void btif_dm_generic_evt(uint16_t event, char* p_param);
-static void btif_dm_cb_create_bond(bt_bdaddr_t* bd_addr,
+static void btif_dm_cb_create_bond(const RawAddress& bd_addr,
                                    tBTA_TRANSPORT transport);
 static void btif_dm_cb_hid_remote_name(tBTM_REMOTE_DEV_NAME* p_remote_name);
-static void btif_update_remote_properties(BD_ADDR bd_addr, BD_NAME bd_name,
-                                          DEV_CLASS dev_class,
+static void btif_update_remote_properties(const RawAddress& bd_addr,
+                                          BD_NAME bd_name, DEV_CLASS dev_class,
                                           tBT_DEVICE_TYPE dev_type);
 static btif_dm_local_key_cb_t ble_local_key_cb;
 static void btif_dm_ble_key_notif_evt(tBTA_DM_SP_KEY_NOTIF* p_ssp_key_notif);
@@ -235,7 +234,7 @@
 
 static char* btif_get_default_local_name();
 
-static void btif_stats_add_bond_event(const bt_bdaddr_t* bd_addr,
+static void btif_stats_add_bond_event(const RawAddress& bd_addr,
                                       bt_bond_function_t function,
                                       bt_bond_state_t state);
 
@@ -248,10 +247,10 @@
 extern bt_status_t btif_hh_execute_service(bool b_enable);
 extern bt_status_t btif_hf_client_execute_service(bool b_enable);
 extern bt_status_t btif_sdp_execute_service(bool b_enable);
-extern int btif_hh_connect(bt_bdaddr_t* bd_addr);
+extern int btif_hh_connect(const RawAddress* bd_addr);
 extern void bta_gatt_convert_uuid16_to_uuid128(uint8_t uuid_128[LEN_UUID_128],
                                                uint16_t uuid_16);
-extern void btif_av_move_idle(bt_bdaddr_t bd_addr);
+extern void btif_av_move_idle(RawAddress bd_addr);
 extern bt_status_t btif_hd_execute_service(bool b_enable);
 
 /******************************************************************************
@@ -392,15 +391,14 @@
                                      uint8_t* p_remote_name,
                                      uint8_t* p_remote_name_len) {
   bt_bdname_t bdname;
-  bt_bdaddr_t remote_bdaddr;
   bt_property_t prop_name;
 
   /* check if we already have it in our btif_storage cache */
-  bdcpy(remote_bdaddr.address, p_search_data->inq_res.bd_addr);
+
   BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME,
                              sizeof(bt_bdname_t), &bdname);
-  if (btif_storage_get_remote_device_property(&remote_bdaddr, &prop_name) ==
-      BT_STATUS_SUCCESS) {
+  if (btif_storage_get_remote_device_property(
+          &p_search_data->inq_res.bd_addr, &prop_name) == BT_STATUS_SUCCESS) {
     if (p_remote_name && p_remote_name_len) {
       strcpy((char*)p_remote_name, (char*)bdname.name);
       *p_remote_name_len = strlen((char*)p_remote_name);
@@ -411,7 +409,7 @@
   return false;
 }
 
-static uint32_t get_cod(const bt_bdaddr_t* remote_bdaddr) {
+static uint32_t get_cod(const RawAddress* remote_bdaddr) {
   uint32_t remote_cod;
   bt_property_t prop_name;
 
@@ -419,7 +417,7 @@
   BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_CLASS_OF_DEVICE,
                              sizeof(uint32_t), &remote_cod);
   if (btif_storage_get_remote_device_property(
-          (bt_bdaddr_t*)remote_bdaddr, &prop_name) == BT_STATUS_SUCCESS) {
+          (RawAddress*)remote_bdaddr, &prop_name) == BT_STATUS_SUCCESS) {
     LOG_INFO(LOG_TAG, "%s remote_cod = 0x%08x", __func__, remote_cod);
     return remote_cod & COD_MASK;
   }
@@ -427,15 +425,15 @@
   return 0;
 }
 
-bool check_cod(const bt_bdaddr_t* remote_bdaddr, uint32_t cod) {
+bool check_cod(const RawAddress* remote_bdaddr, uint32_t cod) {
   return get_cod(remote_bdaddr) == cod;
 }
 
-bool check_cod_hid(const bt_bdaddr_t* remote_bdaddr) {
+bool check_cod_hid(const RawAddress* remote_bdaddr) {
   return (get_cod(remote_bdaddr) & COD_HID_MASK) == COD_HID_MAJOR;
 }
 
-bool check_hid_le(const bt_bdaddr_t* remote_bdaddr) {
+bool check_hid_le(const RawAddress* remote_bdaddr) {
   uint32_t remote_dev_type;
   bt_property_t prop_name;
 
@@ -443,11 +441,10 @@
   BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_TYPE_OF_DEVICE,
                              sizeof(uint32_t), &remote_dev_type);
   if (btif_storage_get_remote_device_property(
-          (bt_bdaddr_t*)remote_bdaddr, &prop_name) == BT_STATUS_SUCCESS) {
+          (RawAddress*)remote_bdaddr, &prop_name) == BT_STATUS_SUCCESS) {
     if (remote_dev_type == BT_DEVICE_DEVTYPE_BLE) {
-      bdstr_t bdstr;
-      bdaddr_to_string(remote_bdaddr, bdstr, sizeof(bdstr));
-      if (btif_config_exist(bdstr, "HidAppId")) return true;
+      if (btif_config_exist(remote_bdaddr->ToString().c_str(), "HidAppId"))
+        return true;
     }
   }
   return false;
@@ -464,7 +461,7 @@
  * Returns         true if the device is present in blacklist, else false
  *
  ******************************************************************************/
-bool check_sdp_bl(const bt_bdaddr_t* remote_bdaddr) {
+bool check_sdp_bl(const RawAddress* remote_bdaddr) {
   uint16_t manufacturer = 0;
   uint8_t lmp_ver = 0;
   uint16_t lmp_subver = 0;
@@ -474,15 +471,14 @@
   if (remote_bdaddr == NULL) return false;
 
   /* fetch additional info about remote device used in iop query */
-  BTM_ReadRemoteVersion(*(BD_ADDR*)remote_bdaddr, &lmp_ver, &manufacturer,
-                        &lmp_subver);
+  BTM_ReadRemoteVersion(*remote_bdaddr, &lmp_ver, &manufacturer, &lmp_subver);
 
   /* if not available yet, try fetching from config database */
   BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_REMOTE_VERSION_INFO,
                              sizeof(bt_remote_version_t), &info);
 
-  if (btif_storage_get_remote_device_property(
-          (bt_bdaddr_t*)remote_bdaddr, &prop_name) != BT_STATUS_SUCCESS) {
+  if (btif_storage_get_remote_device_property(remote_bdaddr, &prop_name) !=
+      BT_STATUS_SUCCESS) {
     return false;
   }
   manufacturer = info.manufacturer;
@@ -493,14 +489,15 @@
   return false;
 }
 
-static void bond_state_changed(bt_status_t status, bt_bdaddr_t* bd_addr,
+static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr,
                                bt_bond_state_t state) {
   btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_BOND_STATE_CHANGED, state);
 
   if ((pairing_cb.state == state) && (state == BT_BOND_STATE_BONDING)) {
     // Cross key pairing so send callback for static address
-    if (!bdaddr_is_empty(&pairing_cb.static_bdaddr)) {
-      HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);
+    if (!pairing_cb.static_bdaddr.IsEmpty()) {
+      auto tmp = bd_addr;
+      HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state);
     }
     return;
   }
@@ -510,13 +507,14 @@
   BTIF_TRACE_DEBUG("%s: state=%d, prev_state=%d, sdp_attempts = %d", __func__,
                    state, pairing_cb.state, pairing_cb.sdp_attempts);
 
-  HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, bd_addr, state);
+  auto tmp = bd_addr;
+  HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state);
 
   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;
-    bdcpy(pairing_cb.bd_addr, bd_addr->address);
+    pairing_cb.bd_addr = bd_addr;
   } else {
     pairing_cb = {};
   }
@@ -524,7 +522,7 @@
 
 /* store remote version in bt config to always have access
    to it post pairing*/
-static void btif_update_remote_version_property(bt_bdaddr_t* p_bd) {
+static void btif_update_remote_version_property(RawAddress* p_bd) {
   bt_property_t property;
   uint8_t lmp_ver = 0;
   uint16_t lmp_subver = 0;
@@ -532,14 +530,11 @@
   tBTM_STATUS btm_status;
   bt_remote_version_t info;
   bt_status_t status;
-  bdstr_t bdstr;
 
-  btm_status =
-      BTM_ReadRemoteVersion(*(BD_ADDR*)p_bd, &lmp_ver, &mfct_set, &lmp_subver);
+  btm_status = BTM_ReadRemoteVersion(*p_bd, &lmp_ver, &mfct_set, &lmp_subver);
 
   LOG_DEBUG(LOG_TAG, "remote version info [%s]: %x, %x, %x",
-            bdaddr_to_string(p_bd, bdstr, sizeof(bdstr)), lmp_ver, mfct_set,
-            lmp_subver);
+            p_bd->ToString().c_str(), lmp_ver, mfct_set, lmp_subver);
 
   if (btm_status == BTM_SUCCESS) {
     // Always update cache to ensure we have availability whenever BTM API is
@@ -555,18 +550,16 @@
   }
 }
 
-static void btif_update_remote_properties(BD_ADDR bd_addr, BD_NAME bd_name,
-                                          DEV_CLASS dev_class,
+static void btif_update_remote_properties(const RawAddress& bdaddr,
+                                          BD_NAME bd_name, DEV_CLASS dev_class,
                                           tBT_DEVICE_TYPE device_type) {
   int num_properties = 0;
   bt_property_t properties[3];
-  bt_bdaddr_t bdaddr;
   bt_status_t status;
   uint32_t cod;
   bt_device_type_t dev_type;
 
   memset(properties, 0, sizeof(properties));
-  bdcpy(bdaddr.address, bd_addr);
 
   /* remote name */
   if (strlen((const char*)bd_name)) {
@@ -624,7 +617,8 @@
           status);
   num_properties++;
 
-  HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, status, &bdaddr,
+  auto tmp = bdaddr;
+  HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, status, &tmp,
             num_properties, properties);
 }
 
@@ -642,14 +636,12 @@
   BTIF_TRACE_DEBUG("%s: status=%d pairing_cb.state=%d", __func__,
                    p_remote_name->status, pairing_cb.state);
   if (pairing_cb.state == BT_BOND_STATE_BONDING) {
-    bt_bdaddr_t remote_bd;
-
-    bdcpy(remote_bd.address, pairing_cb.bd_addr);
-
     if (p_remote_name->status == BTM_SUCCESS) {
-      bond_state_changed(BT_STATUS_SUCCESS, &remote_bd, BT_BOND_STATE_BONDED);
+      bond_state_changed(BT_STATUS_SUCCESS, pairing_cb.bd_addr,
+                         BT_BOND_STATE_BONDED);
     } else
-      bond_state_changed(BT_STATUS_FAIL, &remote_bd, BT_BOND_STATE_NONE);
+      bond_state_changed(BT_STATUS_FAIL, pairing_cb.bd_addr,
+                         BT_BOND_STATE_NONE);
   }
 }
 
@@ -663,46 +655,46 @@
  * Returns          void
  *
  ******************************************************************************/
-static void btif_dm_cb_create_bond(bt_bdaddr_t* bd_addr,
+static void btif_dm_cb_create_bond(const RawAddress& bd_addr,
                                    tBTA_TRANSPORT transport) {
-  bool is_hid = check_cod(bd_addr, COD_HID_POINTING);
+  bool is_hid = check_cod(&bd_addr, COD_HID_POINTING);
   bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
 
   int device_type;
   int addr_type;
-  bdstr_t bdstr;
-  bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr));
+  std::string addrstr = bd_addr.ToString();
+  const char* bdstr = addrstr.c_str();
   if (transport == BT_TRANSPORT_LE) {
-    if (!btif_config_get_int((char const*)&bdstr, "DevType", &device_type)) {
+    if (!btif_config_get_int(bdstr, "DevType", &device_type)) {
       btif_config_set_int(bdstr, "DevType", BT_DEVICE_TYPE_BLE);
     }
-    if (btif_storage_get_remote_addr_type(bd_addr, &addr_type) !=
+    if (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) !=
         BT_STATUS_SUCCESS) {
       // Try to read address type. OOB pairing might have set it earlier, but
       // didn't store it, it defaults to BLE_ADDR_PUBLIC
       uint8_t tmp_dev_type;
       uint8_t tmp_addr_type;
-      BTM_ReadDevInfo(bd_addr->address, &tmp_dev_type, &tmp_addr_type);
+      BTM_ReadDevInfo(bd_addr, &tmp_dev_type, &tmp_addr_type);
       addr_type = tmp_addr_type;
 
-      btif_storage_set_remote_addr_type(bd_addr, addr_type);
+      btif_storage_set_remote_addr_type(&bd_addr, addr_type);
     }
   }
-  if ((btif_config_get_int((char const*)&bdstr, "DevType", &device_type) &&
-       (btif_storage_get_remote_addr_type(bd_addr, &addr_type) ==
+  if ((btif_config_get_int(bdstr, "DevType", &device_type) &&
+       (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) ==
         BT_STATUS_SUCCESS) &&
        (device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE) ||
       (transport == BT_TRANSPORT_LE)) {
-    BTA_DmAddBleDevice(bd_addr->address, addr_type, device_type);
+    BTA_DmAddBleDevice(bd_addr, addr_type, device_type);
   }
 
   if (is_hid && (device_type & BT_DEVICE_TYPE_BLE) == 0) {
     bt_status_t status;
-    status = (bt_status_t)btif_hh_connect(bd_addr);
+    status = (bt_status_t)btif_hh_connect(&bd_addr);
     if (status != BT_STATUS_SUCCESS)
       bond_state_changed(status, bd_addr, BT_BOND_STATE_NONE);
   } else {
-    BTA_DmBondByTransport((uint8_t*)bd_addr->address, transport);
+    BTA_DmBondByTransport(bd_addr, transport);
   }
   /*  Track  originator of bond creation  */
   pairing_cb.is_local_initiated = true;
@@ -718,7 +710,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btif_dm_cb_remove_bond(bt_bdaddr_t* bd_addr) {
+void btif_dm_cb_remove_bond(const RawAddress* bd_addr) {
 /*special handling for HID devices */
 /*  VUP needs to be sent if its a HID Device. The HID HOST module will check if
 there
@@ -728,7 +720,7 @@
 #endif
   {
     BTIF_TRACE_DEBUG("%s: Removing HH device", __func__);
-    BTA_DmRemoveDevice((uint8_t*)bd_addr->address);
+    BTA_DmRemoveDevice(*bd_addr);
   }
 }
 
@@ -743,18 +735,17 @@
  *                  encrypted
  *
  ******************************************************************************/
-uint16_t btif_dm_get_connection_state(const bt_bdaddr_t* bd_addr) {
-  uint8_t* bda = (uint8_t*)bd_addr->address;
-  uint16_t rc = BTA_DmGetConnectionState(bda);
+uint16_t btif_dm_get_connection_state(const RawAddress* bd_addr) {
+  uint16_t rc = BTA_DmGetConnectionState(*bd_addr);
 
   if (rc != 0) {
     uint8_t flags = 0;
 
-    BTM_GetSecurityFlagsByTransport(bda, &flags, BT_TRANSPORT_BR_EDR);
+    BTM_GetSecurityFlagsByTransport(*bd_addr, &flags, BT_TRANSPORT_BR_EDR);
     BTIF_TRACE_DEBUG("%s: security flags (BR/EDR)=0x%02x", __func__, flags);
     if (flags & BTM_SEC_FLAG_ENCRYPTED) rc |= ENCRYPTED_BREDR;
 
-    BTM_GetSecurityFlagsByTransport(bda, &flags, BT_TRANSPORT_LE);
+    BTM_GetSecurityFlagsByTransport(*bd_addr, &flags, BT_TRANSPORT_LE);
     BTIF_TRACE_DEBUG("%s: security flags (LE)=0x%02x", __func__, flags);
     if (flags & BTM_SEC_FLAG_ENCRYPTED) rc |= ENCRYPTED_LE;
   }
@@ -841,7 +832,6 @@
  *
  ******************************************************************************/
 static void btif_dm_pin_req_evt(tBTA_DM_PIN_REQ* p_pin_req) {
-  bt_bdaddr_t bd_addr;
   bt_bdname_t bd_name;
   uint32_t cod;
   bt_pin_code_t pin_code;
@@ -855,10 +845,10 @@
                                 p_pin_req->dev_class,
                                 (tBT_DEVICE_TYPE)dev_type);
 
-  bdcpy(bd_addr.address, p_pin_req->bd_addr);
+  const RawAddress& bd_addr = p_pin_req->bd_addr;
   memcpy(bd_name.name, p_pin_req->bd_name, BD_NAME_LEN);
 
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
 
   cod = devclass2uint(p_pin_req->dev_class);
 
@@ -887,7 +877,7 @@
         pin_code.pin[3] = 0x30;
 
         pairing_cb.autopair_attempts++;
-        BTA_DmPinReply((uint8_t*)bd_addr.address, true, 4, pin_code.pin);
+        BTA_DmPinReply(bd_addr, true, 4, pin_code.pin);
         return;
       }
     } else if (check_cod(&bd_addr, COD_HID_KEYBOARD) ||
@@ -902,12 +892,14 @@
         pin_code.pin[3] = 0x30;
 
         pairing_cb.autopair_attempts++;
-        BTA_DmPinReply((uint8_t*)bd_addr.address, true, 4, pin_code.pin);
+        BTA_DmPinReply(bd_addr, true, 4, pin_code.pin);
         return;
       }
     }
   }
-  HAL_CBACK(bt_hal_cbacks, pin_request_cb, &bd_addr, &bd_name, cod,
+  // TODO: make cback accept const and get rid of tmp!
+  auto tmp = bd_addr;
+  HAL_CBACK(bt_hal_cbacks, pin_request_cb, &tmp, &bd_name, cod,
             p_pin_req->min_16_digit);
 }
 
@@ -921,7 +913,6 @@
  *
  ******************************************************************************/
 static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ* p_ssp_cfm_req) {
-  bt_bdaddr_t bd_addr;
   bt_bdname_t bd_name;
   uint32_t cod;
   bool is_incoming = !(pairing_cb.state == BT_BOND_STATE_BONDING);
@@ -937,18 +928,18 @@
                                 p_ssp_cfm_req->dev_class,
                                 (tBT_DEVICE_TYPE)dev_type);
 
-  bdcpy(bd_addr.address, p_ssp_cfm_req->bd_addr);
+  RawAddress bd_addr = p_ssp_cfm_req->bd_addr;
   memcpy(bd_name.name, p_ssp_cfm_req->bd_name, BD_NAME_LEN);
 
   /* Set the pairing_cb based on the local & remote authentication requirements
    */
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
 
   /* if just_works and bonding bit is not set treat this as temporary */
   if (p_ssp_cfm_req->just_works &&
       !(p_ssp_cfm_req->loc_auth_req & BTM_AUTH_BONDS) &&
       !(p_ssp_cfm_req->rmt_auth_req & BTM_AUTH_BONDS) &&
-      !(check_cod((bt_bdaddr_t*)&p_ssp_cfm_req->bd_addr, COD_HID_POINTING)))
+      !(check_cod((RawAddress*)&p_ssp_cfm_req->bd_addr, COD_HID_POINTING)))
     pairing_cb.bond_type = BOND_TYPE_TEMPORARY;
   else
     pairing_cb.bond_type = BOND_TYPE_PERSISTENT;
@@ -985,7 +976,6 @@
 }
 
 static void btif_dm_ssp_key_notif_evt(tBTA_DM_SP_KEY_NOTIF* p_ssp_key_notif) {
-  bt_bdaddr_t bd_addr;
   bt_bdname_t bd_name;
   uint32_t cod;
   int dev_type;
@@ -1000,10 +990,10 @@
       p_ssp_key_notif->bd_addr, p_ssp_key_notif->bd_name,
       p_ssp_key_notif->dev_class, (tBT_DEVICE_TYPE)dev_type);
 
-  bdcpy(bd_addr.address, p_ssp_key_notif->bd_addr);
+  RawAddress bd_addr = p_ssp_key_notif->bd_addr;
   memcpy(bd_name.name, p_ssp_key_notif->bd_name, BD_NAME_LEN);
 
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
   pairing_cb.is_ssp = true;
   cod = devclass2uint(p_ssp_key_notif->dev_class);
 
@@ -1026,14 +1016,13 @@
  ******************************************************************************/
 static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) {
   /* Save link key, if not temporary */
-  bt_bdaddr_t bd_addr;
   bt_status_t status = BT_STATUS_FAIL;
   bt_bond_state_t state = BT_BOND_STATE_NONE;
   bool skip_sdp = false;
 
   BTIF_TRACE_DEBUG("%s: bond state=%d", __func__, pairing_cb.state);
 
-  bdcpy(bd_addr.address, p_auth_cmpl->bd_addr);
+  RawAddress bd_addr = p_auth_cmpl->bd_addr;
   if ((p_auth_cmpl->success == true) && (p_auth_cmpl->key_present)) {
     if ((p_auth_cmpl->key_type < HCI_LKEY_TYPE_DEBUG_COMB) ||
         (p_auth_cmpl->key_type == HCI_LKEY_TYPE_AUTH_COMB) ||
@@ -1055,7 +1044,7 @@
         BTIF_TRACE_DEBUG("%s: sending BT_BOND_STATE_NONE for Temp pairing",
                          __func__);
         btif_storage_remove_bonded_device(&bd_addr);
-        bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_NONE);
+        bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_NONE);
         return;
       }
     }
@@ -1068,16 +1057,11 @@
   // derivation to allow bond state change notification for the BR/EDR transport
   // so that the subsequent BR/EDR connections to the remote can use the derived
   // link key.
-  if ((bdcmp(p_auth_cmpl->bd_addr, pairing_cb.bd_addr) != 0) &&
+  if (p_auth_cmpl->bd_addr != pairing_cb.bd_addr &&
       (!pairing_cb.ble.is_penc_key_rcvd)) {
-    char address[32];
-    bt_bdaddr_t bt_bdaddr;
-
-    memcpy(bt_bdaddr.address, p_auth_cmpl->bd_addr, sizeof(bt_bdaddr.address));
-    bdaddr_to_string(&bt_bdaddr, address, sizeof(address));
-    LOG_INFO(LOG_TAG,
-             "%s skipping SDP since we did not initiate pairing to %s.",
-             __func__, address);
+    LOG(INFO) << __func__
+              << " skipping SDP since we did not initiate pairing to "
+              << p_auth_cmpl->bd_addr;
     return;
   }
 
@@ -1089,18 +1073,18 @@
     pairing_cb.timeout_retries = 0;
     status = BT_STATUS_SUCCESS;
     state = BT_BOND_STATE_BONDED;
-    bdcpy(bd_addr.address, p_auth_cmpl->bd_addr);
+    bd_addr = p_auth_cmpl->bd_addr;
 
     if (check_sdp_bl(&bd_addr) && check_cod_hid(&bd_addr)) {
       LOG_WARN(LOG_TAG, "%s:skip SDP", __func__);
       skip_sdp = true;
     }
     if (!pairing_cb.is_local_initiated && skip_sdp) {
-      bond_state_changed(status, &bd_addr, state);
+      bond_state_changed(status, bd_addr, state);
 
       LOG_WARN(LOG_TAG, "%s: Incoming HID Connection", __func__);
       bt_property_t prop;
-      bt_bdaddr_t bd_addr;
+      RawAddress bd_addr;
       bt_uuid_t uuid;
       char uuid_str[128] = UUID_HUMAN_INTERFACE_DEVICE;
 
@@ -1117,11 +1101,11 @@
       bool is_crosskey = false;
       /* If bonded due to cross-key, save the static address too*/
       if (pairing_cb.state == BT_BOND_STATE_BONDING &&
-          (bdcmp(p_auth_cmpl->bd_addr, pairing_cb.bd_addr) != 0)) {
+          p_auth_cmpl->bd_addr != pairing_cb.bd_addr) {
         BTIF_TRACE_DEBUG(
             "%s: bonding initiated due to cross key, adding static address",
             __func__);
-        bdcpy(pairing_cb.static_bdaddr.address, p_auth_cmpl->bd_addr);
+        pairing_cb.static_bdaddr = bd_addr;
         is_crosskey = true;
       }
       if (!is_crosskey ||
@@ -1135,16 +1119,14 @@
         if (is_crosskey) {
           // If bonding occurred due to cross-key pairing, send bonding callback
           // for static address now
-          bdstr_t bdstr;
           LOG_INFO(LOG_TAG,
                    "%s: send bonding state update for static address %s",
-                   __func__, bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr)));
-          bond_state_changed(BT_STATUS_SUCCESS, &bd_addr,
-                             BT_BOND_STATE_BONDING);
+                   __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);
+        bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDED);
 
-        btif_dm_get_remote_services(&bd_addr);
+        btif_dm_get_remote_services(bd_addr);
       }
     }
     // Do not call bond_state_changed_cb yet. Wait until remote service
@@ -1159,7 +1141,7 @@
           BTIF_TRACE_WARNING("%s() - Pairing timeout; retrying (%d) ...",
                              __func__, pairing_cb.timeout_retries);
           --pairing_cb.timeout_retries;
-          btif_dm_cb_create_bond(&bd_addr, BTA_TRANSPORT_UNKNOWN);
+          btif_dm_cb_create_bond(bd_addr, BTA_TRANSPORT_UNKNOWN);
           return;
         }
       /* Fall-through */
@@ -1189,7 +1171,7 @@
           /* Create the Bond once again */
           BTIF_TRACE_WARNING("%s() auto pair failed. Reinitiate Bond",
                              __func__);
-          btif_dm_cb_create_bond(&bd_addr, BTA_TRANSPORT_UNKNOWN);
+          btif_dm_cb_create_bond(bd_addr, BTA_TRANSPORT_UNKNOWN);
           return;
         } else {
           /* if autopair attempts are more than 1, or not attempted */
@@ -1207,7 +1189,7 @@
                        __func__);
       btif_storage_remove_bonded_device(&bd_addr);
     }
-    bond_state_changed(status, &bd_addr, state);
+    bond_state_changed(status, bd_addr, state);
   }
 }
 
@@ -1230,13 +1212,12 @@
       /* Remote name update */
       if (strlen((const char*)p_search_data->disc_res.bd_name)) {
         bt_property_t properties[1];
-        bt_bdaddr_t bdaddr;
         bt_status_t status;
 
         properties[0].type = BT_PROPERTY_BDNAME;
         properties[0].val = p_search_data->disc_res.bd_name;
         properties[0].len = strlen((char*)p_search_data->disc_res.bd_name);
-        bdcpy(bdaddr.address, p_search_data->disc_res.bd_addr);
+        RawAddress& bdaddr = p_search_data->disc_res.bd_addr;
 
         status =
             btif_storage_set_remote_device_property(&bdaddr, &properties[0]);
@@ -1251,16 +1232,14 @@
     case BTA_DM_INQ_RES_EVT: {
       /* inquiry result */
       bt_bdname_t bdname;
-      bt_bdaddr_t bdaddr;
       uint8_t remote_name_len;
       tBTA_SERVICE_MASK services = 0;
-      bdstr_t bdstr;
 
       p_search_data = (tBTA_DM_SEARCH*)p_param;
-      bdcpy(bdaddr.address, p_search_data->inq_res.bd_addr);
+      RawAddress& bdaddr = p_search_data->inq_res.bd_addr;
 
       BTIF_TRACE_DEBUG("%s() %s device_type = 0x%x\n", __func__,
-                       bdaddr_to_string(&bdaddr, bdstr, sizeof(bdstr)),
+                       bdaddr.ToString().c_str(),
                        p_search_data->inq_res.device_type);
       bdname.name[0] = 0;
 
@@ -1285,7 +1264,7 @@
         int addr_type = 0;
 
         memset(properties, 0, sizeof(properties));
-        /* BD_ADDR */
+        /* RawAddress */
         BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
                                    BT_PROPERTY_BDADDR, sizeof(bdaddr), &bdaddr);
         num_properties++;
@@ -1313,7 +1292,7 @@
 
         /* Verify if the device is dual mode in NVRAM */
         int stored_device_type = 0;
-        if (btif_get_device_type(bdaddr.address, &stored_device_type) &&
+        if (btif_get_device_type(bdaddr, &stored_device_type) &&
             ((stored_device_type != BT_DEVICE_TYPE_BREDR &&
               p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BREDR) ||
              (stored_device_type != BT_DEVICE_TYPE_BLE &&
@@ -1398,10 +1377,9 @@
     case BTA_DM_DISC_RES_EVT: {
       bt_property_t prop;
       uint32_t i = 0;
-      bt_bdaddr_t bd_addr;
       bt_status_t ret;
 
-      bdcpy(bd_addr.address, p_data->disc_res.bd_addr);
+      RawAddress& bd_addr = p_data->disc_res.bd_addr;
 
       BTIF_TRACE_DEBUG("%s:(result=0x%x, services 0x%x)", __func__,
                        p_data->disc_res.result, p_data->disc_res.services);
@@ -1411,7 +1389,7 @@
         BTIF_TRACE_WARNING("%s:SDP failed after bonding re-attempting",
                            __func__);
         pairing_cb.sdp_attempts++;
-        btif_dm_get_remote_services(&bd_addr);
+        btif_dm_get_remote_services(bd_addr);
         return;
       }
       prop.type = BT_PROPERTY_UUIDS;
@@ -1432,13 +1410,11 @@
       /* 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_BONDED && pairing_cb.sdp_attempts &&
-          ((bdcmp(p_data->disc_res.bd_addr, pairing_cb.bd_addr) == 0) ||
-           (bdcmp(p_data->disc_res.bd_addr, pairing_cb.static_bdaddr.address) ==
-            0))) {
-        bdstr_t bdstr;
+      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)) {
         LOG_INFO(LOG_TAG, "%s: SDP search done for %s", __func__,
-                 bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr)));
+                 bd_addr.ToString().c_str());
         pairing_cb.sdp_attempts = 0;
 
         // Both SDP and bonding are done, clear pairing control block
@@ -1448,10 +1424,9 @@
         // or no UUID is discovered
         if (p_data->disc_res.result != BTA_SUCCESS ||
             p_data->disc_res.num_uuids == 0) {
-          bdstr_t bdstr;
           LOG_INFO(LOG_TAG,
                    "%s: SDP failed, send empty UUID to unblock bonding %s",
-                   __func__, bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr)));
+                   __func__, bd_addr.ToString().c_str());
           bt_property_t prop;
           bt_uuid_t uuid = {};
           char uuid_str[128] = UUID_EMPTY;
@@ -1498,7 +1473,6 @@
       if (p_data->disc_ble_res.service.uu.uuid16 == UUID_SERVCLASS_LE_HID) {
         BTIF_TRACE_DEBUG("%s: Found HOGP UUID", __func__);
         bt_property_t prop[2];
-        bt_bdaddr_t bd_addr;
         char temp[256];
         bt_status_t ret;
 
@@ -1516,7 +1490,7 @@
         uuid_to_string_legacy(&uuid, temp, sizeof(temp));
         LOG_INFO(LOG_TAG, "%s uuid:%s", __func__, temp);
 
-        bdcpy(bd_addr.address, p_data->disc_ble_res.bd_addr);
+        RawAddress& bd_addr = p_data->disc_ble_res.bd_addr;
         prop[0].type = BT_PROPERTY_UUIDS;
         prop[0].val = uuid.uu;
         prop[0].len = MAX_UUID_SIZE;
@@ -1567,10 +1541,9 @@
     case BTA_DM_DISC_RES_EVT: {
       bt_service_record_t rec;
       bt_property_t prop;
-      bt_bdaddr_t bd_addr;
 
       memset(&rec, 0, sizeof(bt_service_record_t));
-      bdcpy(bd_addr.address, p_data->disc_res.bd_addr);
+      RawAddress& bd_addr = p_data->disc_res.bd_addr;
 
       BTIF_TRACE_DEBUG("%s:(result=0x%x, services 0x%x)", __func__,
                        p_data->disc_res.result, p_data->disc_res.services);
@@ -1608,7 +1581,7 @@
   tBTA_DM_SEC* p_data = (tBTA_DM_SEC*)p_param;
   tBTA_SERVICE_MASK service_mask;
   uint32_t i;
-  bt_bdaddr_t bd_addr;
+  RawAddress bd_addr;
 
   BTIF_TRACE_EVENT("%s: ev: %s", __func__, dump_dm_event(event));
 
@@ -1679,10 +1652,10 @@
 
     case BTA_DM_BOND_CANCEL_CMPL_EVT:
       if (is_bonding_or_sdp()) {
-        bdcpy(bd_addr.address, pairing_cb.bd_addr);
+        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,
-                           &bd_addr, BT_BOND_STATE_NONE);
+                           bd_addr, BT_BOND_STATE_NONE);
       }
       break;
 
@@ -1694,7 +1667,7 @@
       break;
 
     case BTA_DM_DEV_UNPAIRED_EVT:
-      bdcpy(bd_addr.address, p_data->link_down.bd_addr);
+      bd_addr = p_data->link_down.bd_addr;
       btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
 
 /*special handling for HID devices */
@@ -1705,7 +1678,7 @@
       btif_hd_remove_device(bd_addr);
 #endif
       btif_storage_remove_bonded_device(&bd_addr);
-      bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_NONE);
+      bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_NONE);
       break;
 
     case BTA_DM_BUSY_LEVEL_EVT: {
@@ -1725,7 +1698,7 @@
     } break;
 
     case BTA_DM_LINK_UP_EVT:
-      bdcpy(bd_addr.address, p_data->link_up.bd_addr);
+      bd_addr = p_data->link_up.bd_addr;
       BTIF_TRACE_DEBUG("BTA_DM_LINK_UP_EVT. Sending BT_ACL_STATE_CONNECTED");
 
       btif_update_remote_version_property(&bd_addr);
@@ -1735,7 +1708,7 @@
       break;
 
     case BTA_DM_LINK_DOWN_EVT:
-      bdcpy(bd_addr.address, p_data->link_down.bd_addr);
+      bd_addr = p_data->link_down.bd_addr;
       btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
       btif_av_move_idle(bd_addr);
       BTIF_TRACE_DEBUG(
@@ -1766,11 +1739,9 @@
       if (pairing_cb.state != BT_BOND_STATE_BONDING) {
         BTIF_TRACE_DEBUG(
             "Bond state not sent to App so far.Notify the app now");
-        bond_state_changed(BT_STATUS_SUCCESS,
-                           (bt_bdaddr_t*)p_data->ble_key.bd_addr,
+        bond_state_changed(BT_STATUS_SUCCESS, p_data->ble_key.bd_addr,
                            BT_BOND_STATE_BONDING);
-      } else if (memcmp(pairing_cb.bd_addr, p_data->ble_key.bd_addr,
-                        BD_ADDR_LEN) != 0) {
+      } else if (pairing_cb.bd_addr != p_data->ble_key.bd_addr) {
         BTIF_TRACE_ERROR("BD mismatch discard BLE key_type=%d ",
                          p_data->ble_key.key_type);
         break;
@@ -1975,12 +1946,11 @@
       pairing_cb.timeout_retries = NUM_TIMEOUT_RETRIES;
       btif_dm_create_bond_cb_t* create_bond_cb =
           (btif_dm_create_bond_cb_t*)p_param;
-      btif_dm_cb_create_bond(&create_bond_cb->bdaddr,
-                             create_bond_cb->transport);
+      btif_dm_cb_create_bond(create_bond_cb->bdaddr, create_bond_cb->transport);
     } break;
 
     case BTIF_DM_CB_REMOVE_BOND: {
-      btif_dm_cb_remove_bond((bt_bdaddr_t*)p_param);
+      btif_dm_cb_remove_bond((RawAddress*)p_param);
     } break;
 
     case BTIF_DM_CB_HID_REMOTE_NAME: {
@@ -1988,7 +1958,7 @@
     } break;
 
     case BTIF_DM_CB_BOND_STATE_BONDING: {
-      bond_state_changed(BT_STATUS_SUCCESS, (bt_bdaddr_t*)p_param,
+      bond_state_changed(BT_STATUS_SUCCESS, *((RawAddress*)p_param),
                          BT_BOND_STATE_BONDING);
     } break;
     case BTIF_DM_CB_LE_TX_TEST:
@@ -2256,17 +2226,16 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_create_bond(const bt_bdaddr_t* bd_addr, int transport) {
+bt_status_t btif_dm_create_bond(const RawAddress* bd_addr, int transport) {
   btif_dm_create_bond_cb_t create_bond_cb;
   create_bond_cb.transport = transport;
-  bdcpy(create_bond_cb.bdaddr.address, bd_addr->address);
+  create_bond_cb.bdaddr = *bd_addr;
 
-  bdstr_t bdstr;
   BTIF_TRACE_EVENT("%s: bd_addr=%s, transport=%d", __func__,
-                   bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)), transport);
+                   bd_addr->ToString().c_str(), transport);
   if (pairing_cb.state != BT_BOND_STATE_NONE) return BT_STATUS_BUSY;
 
-  btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_CREATE_BOND,
+  btif_stats_add_bond_event(*bd_addr, BTIF_DM_FUNC_CREATE_BOND,
                             pairing_cb.state);
 
   btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_CREATE_BOND,
@@ -2287,9 +2256,9 @@
  *
  ******************************************************************************/
 bt_status_t btif_dm_create_bond_out_of_band(
-    const bt_bdaddr_t* bd_addr, int transport,
+    const RawAddress* bd_addr, int transport,
     const bt_out_of_band_data_t* oob_data) {
-  bdcpy(oob_cb.bdaddr, bd_addr->address);
+  oob_cb.bdaddr = *bd_addr;
   memcpy(&oob_cb.oob_data, oob_data, sizeof(bt_out_of_band_data_t));
 
   uint8_t empty[] = {0, 0, 0, 0, 0, 0, 0};
@@ -2301,14 +2270,12 @@
     if (address_type == BLE_ADDR_PUBLIC || address_type == BLE_ADDR_RANDOM) {
       // bd_addr->address is already reversed, so use it instead of
       // oob_data->le_bt_dev_addr
-      BTM_SecAddBleDevice(bd_addr->address, NULL, BT_DEVICE_TYPE_BLE,
-                          address_type);
+      BTM_SecAddBleDevice(*bd_addr, NULL, BT_DEVICE_TYPE_BLE, address_type);
     }
   }
 
-  bdstr_t bdstr;
   BTIF_TRACE_EVENT("%s: bd_addr=%s, transport=%d", __func__,
-                   bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)), transport);
+                   bd_addr->ToString().c_str(), transport);
   return btif_dm_create_bond(bd_addr, transport);
 }
 
@@ -2322,13 +2289,10 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_dm_cancel_bond(const bt_bdaddr_t* bd_addr) {
-  bdstr_t bdstr;
+bt_status_t btif_dm_cancel_bond(const RawAddress* bd_addr) {
+  BTIF_TRACE_EVENT("%s: bd_addr=%s", __func__, bd_addr->ToString().c_str());
 
-  BTIF_TRACE_EVENT("%s: bd_addr=%s", __func__,
-                   bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)));
-
-  btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_CANCEL_BOND,
+  btif_stats_add_bond_event(*bd_addr, BTIF_DM_FUNC_CANCEL_BOND,
                             pairing_cb.state);
 
   /* TODO:
@@ -2338,21 +2302,20 @@
   if (is_bonding_or_sdp()) {
     if (pairing_cb.is_ssp) {
       if (pairing_cb.is_le_only) {
-        BTA_DmBleSecurityGrant((uint8_t*)bd_addr->address,
-                               BTA_DM_SEC_PAIR_NOT_SPT);
+        BTA_DmBleSecurityGrant(*bd_addr, BTA_DM_SEC_PAIR_NOT_SPT);
       } else {
-        BTA_DmConfirm((uint8_t*)bd_addr->address, false);
-        BTA_DmBondCancel((uint8_t*)bd_addr->address);
-        btif_storage_remove_bonded_device((bt_bdaddr_t*)bd_addr);
+        BTA_DmConfirm(*bd_addr, false);
+        BTA_DmBondCancel(*bd_addr);
+        btif_storage_remove_bonded_device(bd_addr);
       }
     } else {
       if (pairing_cb.is_le_only) {
-        BTA_DmBondCancel((uint8_t*)bd_addr->address);
+        BTA_DmBondCancel(*bd_addr);
       } else {
-        BTA_DmPinReply((uint8_t*)bd_addr->address, false, 0, NULL);
+        BTA_DmPinReply(*bd_addr, false, 0, NULL);
       }
       /* Cancel bonding, in case it is in ACL connection setup state */
-      BTA_DmBondCancel((uint8_t*)bd_addr->address);
+      BTA_DmBondCancel(*bd_addr);
     }
   }
 
@@ -2370,10 +2333,10 @@
  *
  ******************************************************************************/
 
-void btif_dm_hh_open_failed(bt_bdaddr_t* bdaddr) {
+void btif_dm_hh_open_failed(RawAddress* bdaddr) {
   if (pairing_cb.state == BT_BOND_STATE_BONDING &&
-      bdcmp(bdaddr->address, pairing_cb.bd_addr) == 0) {
-    bond_state_changed(BT_STATUS_FAIL, bdaddr, BT_BOND_STATE_NONE);
+      *bdaddr == pairing_cb.bd_addr) {
+    bond_state_changed(BT_STATUS_FAIL, *bdaddr, BT_BOND_STATE_NONE);
   }
 }
 
@@ -2387,17 +2350,14 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_dm_remove_bond(const bt_bdaddr_t* bd_addr) {
-  bdstr_t bdstr;
+bt_status_t btif_dm_remove_bond(const RawAddress* bd_addr) {
+  BTIF_TRACE_EVENT("%s: bd_addr=%s", __func__, bd_addr->ToString().c_str());
 
-  BTIF_TRACE_EVENT("%s: bd_addr=%s", __func__,
-                   bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)));
-
-  btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_REMOVE_BOND,
+  btif_stats_add_bond_event(*bd_addr, BTIF_DM_FUNC_REMOVE_BOND,
                             pairing_cb.state);
 
   btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_REMOVE_BOND,
-                        (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+                        (char*)bd_addr, sizeof(RawAddress), NULL);
 
   return BT_STATUS_SUCCESS;
 }
@@ -2412,7 +2372,7 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_dm_pin_reply(const bt_bdaddr_t* bd_addr, uint8_t accept,
+bt_status_t btif_dm_pin_reply(const RawAddress* bd_addr, uint8_t accept,
                               uint8_t pin_len, bt_pin_code_t* pin_code) {
   BTIF_TRACE_EVENT("%s: accept=%d", __func__, accept);
   if (pin_code == NULL || pin_len > PIN_CODE_LEN) return BT_STATUS_FAIL;
@@ -2420,16 +2380,14 @@
     int i;
     uint32_t passkey = 0;
     int multi[] = {100000, 10000, 1000, 100, 10, 1};
-    BD_ADDR remote_bd_addr;
-    bdcpy(remote_bd_addr, bd_addr->address);
     for (i = 0; i < 6; i++) {
       passkey += (multi[i] * (pin_code->pin[i] - '0'));
     }
     BTIF_TRACE_DEBUG("btif_dm_pin_reply: passkey: %d", passkey);
-    BTA_DmBlePasskeyReply(remote_bd_addr, accept, passkey);
+    BTA_DmBlePasskeyReply(*bd_addr, accept, passkey);
 
   } else {
-    BTA_DmPinReply((uint8_t*)bd_addr->address, accept, pin_len, pin_code->pin);
+    BTA_DmPinReply(*bd_addr, accept, pin_len, pin_code->pin);
     if (accept) pairing_cb.pin_code_len = pin_len;
   }
   return BT_STATUS_SUCCESS;
@@ -2445,7 +2403,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_ssp_reply(const bt_bdaddr_t* bd_addr,
+bt_status_t btif_dm_ssp_reply(const RawAddress* bd_addr,
                               bt_ssp_variant_t variant, uint8_t accept,
                               UNUSED_ATTR uint32_t passkey) {
   if (variant == BT_SSP_VARIANT_PASSKEY_ENTRY) {
@@ -2459,16 +2417,15 @@
   BTIF_TRACE_EVENT("%s: accept=%d", __func__, accept);
   if (pairing_cb.is_le_only) {
     if (pairing_cb.is_le_nc) {
-      BTA_DmBleConfirmReply((uint8_t*)bd_addr->address, accept);
+      BTA_DmBleConfirmReply(*bd_addr, accept);
     } else {
       if (accept)
-        BTA_DmBleSecurityGrant((uint8_t*)bd_addr->address, BTA_DM_SEC_GRANTED);
+        BTA_DmBleSecurityGrant(*bd_addr, BTA_DM_SEC_GRANTED);
       else
-        BTA_DmBleSecurityGrant((uint8_t*)bd_addr->address,
-                               BTA_DM_SEC_PAIR_NOT_SPT);
+        BTA_DmBleSecurityGrant(*bd_addr, BTA_DM_SEC_PAIR_NOT_SPT);
     }
   } else {
-    BTA_DmConfirm((uint8_t*)bd_addr->address, accept);
+    BTA_DmConfirm(*bd_addr, accept);
   }
   return BT_STATUS_SUCCESS;
 }
@@ -2523,14 +2480,11 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_get_remote_services(bt_bdaddr_t* remote_addr) {
-  bdstr_t bdstr;
+bt_status_t btif_dm_get_remote_services(const RawAddress& remote_addr) {
+  BTIF_TRACE_EVENT("%s: bd_addr=%s", __func__, remote_addr.ToString().c_str());
 
-  BTIF_TRACE_EVENT("%s: remote_addr=%s", __func__,
-                   bdaddr_to_string(remote_addr, bdstr, sizeof(bdstr)));
-
-  BTA_DmDiscover(remote_addr->address, BTA_ALL_SERVICE_MASK,
-                 bte_dm_search_services_evt, true);
+  BTA_DmDiscover(remote_addr, BTA_ALL_SERVICE_MASK, bte_dm_search_services_evt,
+                 true);
 
   return BT_STATUS_SUCCESS;
 }
@@ -2544,7 +2498,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-bt_status_t btif_dm_get_remote_services_by_transport(bt_bdaddr_t* remote_addr,
+bt_status_t btif_dm_get_remote_services_by_transport(RawAddress* remote_addr,
                                                      const int transport) {
   BTIF_TRACE_EVENT("%s", __func__);
 
@@ -2554,8 +2508,8 @@
   mask_ext.p_uuid = NULL;
   mask_ext.srvc_mask = BTA_ALL_SERVICE_MASK;
 
-  BTA_DmDiscoverByTransport(remote_addr->address, &mask_ext,
-                            bte_dm_search_services_evt, true, transport);
+  BTA_DmDiscoverByTransport(*remote_addr, &mask_ext, bte_dm_search_services_evt,
+                            true, transport);
 
   return BT_STATUS_SUCCESS;
 }
@@ -2569,19 +2523,16 @@
  *
  * Returns          bt_status_t
  ******************************************************************************/
-bt_status_t btif_dm_get_remote_service_record(bt_bdaddr_t* remote_addr,
+bt_status_t btif_dm_get_remote_service_record(RawAddress* remote_addr,
                                               bt_uuid_t* uuid) {
+  BTIF_TRACE_EVENT("%s: bd_addr=%s", __func__, remote_addr->ToString().c_str());
+
   tSDP_UUID sdp_uuid;
-  bdstr_t bdstr;
-
-  BTIF_TRACE_EVENT("%s: remote_addr=%s", __func__,
-                   bdaddr_to_string(remote_addr, bdstr, sizeof(bdstr)));
-
   sdp_uuid.len = MAX_UUID_SIZE;
   memcpy(sdp_uuid.uu.uuid128, uuid->uu, MAX_UUID_SIZE);
 
-  BTA_DmDiscoverUUID(remote_addr->address, &sdp_uuid,
-                     bte_dm_remote_service_record_evt, true);
+  BTA_DmDiscoverUUID(*remote_addr, &sdp_uuid, bte_dm_remote_service_record_evt,
+                     true);
 
   return BT_STATUS_SUCCESS;
 }
@@ -2608,7 +2559,7 @@
   return;
 }
 
-void btif_dm_proc_io_req(UNUSED_ATTR BD_ADDR bd_addr,
+void btif_dm_proc_io_req(UNUSED_ATTR const RawAddress& bd_addr,
                          UNUSED_ATTR tBTA_IO_CAP* p_io_cap,
                          UNUSED_ATTR tBTA_OOB_DATA* p_oob_data,
                          tBTA_AUTH_REQ* p_auth_req, bool is_orig) {
@@ -2645,8 +2596,8 @@
   BTIF_TRACE_DEBUG("-%s: p_auth_req=%d", __func__, *p_auth_req);
 }
 
-void btif_dm_proc_io_rsp(UNUSED_ATTR BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
-                         UNUSED_ATTR tBTA_OOB_DATA oob_data,
+void btif_dm_proc_io_rsp(UNUSED_ATTR const RawAddress& bd_addr,
+                         tBTA_IO_CAP io_cap, UNUSED_ATTR tBTA_OOB_DATA oob_data,
                          tBTA_AUTH_REQ auth_req) {
   if (auth_req & BTA_AUTH_BONDS) {
     BTIF_TRACE_DEBUG("%s auth_req:%d", __func__, auth_req);
@@ -2664,7 +2615,7 @@
   BTIF_TRACE_DEBUG("%s: *p_has_oob_data=%d", __func__, *p_has_oob_data);
 }
 
-void btif_dm_set_oob_for_le_io_req(BD_ADDR bd_addr,
+void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr,
                                    tBTA_OOB_DATA* p_has_oob_data,
                                    tBTA_LE_AUTH_REQ* p_auth_req) {
   if (!is_empty_128bit(oob_cb.oob_data.le_sc_c) &&
@@ -2672,7 +2623,7 @@
     /* We have LE SC OOB data */
 
     /* make sure OOB data is for this particular device */
-    if (memcmp(bd_addr, oob_cb.bdaddr, BD_ADDR_LEN) == 0) {
+    if (bd_addr == oob_cb.bdaddr) {
       *p_auth_req = ((*p_auth_req) | BTM_LE_AUTH_REQ_SC_ONLY);
       *p_has_oob_data = true;
     } else {
@@ -2684,7 +2635,7 @@
     /* We have security manager TK */
 
     /* make sure OOB data is for this particular device */
-    if (memcmp(bd_addr, oob_cb.bdaddr, BD_ADDR_LEN) == 0) {
+    if (bd_addr == oob_cb.bdaddr) {
       // When using OOB with TK, SC Secure Connections bit must be disabled.
       tBTA_LE_AUTH_REQ mask = ~BTM_LE_AUTH_REQ_SC_ONLY;
       *p_auth_req = ((*p_auth_req) & mask);
@@ -2810,64 +2761,43 @@
   return true;
 }
 
-bool btif_dm_proc_rmt_oob(BD_ADDR bd_addr, BT_OCTET16 p_c, BT_OCTET16 p_r) {
-  char t[128];
-  FILE* fp;
+bool btif_dm_proc_rmt_oob(const RawAddress& bd_addr, BT_OCTET16 p_c,
+                          BT_OCTET16 p_r) {
   const char* path_a = "/data/misc/bluedroid/LOCAL/a.key";
   const char* path_b = "/data/misc/bluedroid/LOCAL/b.key";
   const char* path = NULL;
   char prop_oob[PROPERTY_VALUE_MAX];
-  bool result = false;
-  bt_bdaddr_t bt_bd_addr;
-  bdcpy(oob_cb.bdaddr, bd_addr);
   osi_property_get("service.brcm.bt.oob", prop_oob, "3");
   BTIF_TRACE_DEBUG("%s: prop_oob = %s", __func__, prop_oob);
   if (prop_oob[0] == '1')
     path = path_b;
   else if (prop_oob[0] == '2')
     path = path_a;
-  if (path) {
-    fp = fopen(path, "rb");
-    if (fp == NULL) {
-      BTIF_TRACE_DEBUG("%s: failed to read OOB keys from %s", __func__, path);
-      return false;
-    } else {
-      BTIF_TRACE_DEBUG("%s: read OOB data from %s", __func__, path);
-      fread(p_c, 1, BT_OCTET16_LEN, fp);
-      fread(p_r, 1, BT_OCTET16_LEN, fp);
-      fclose(fp);
-    }
-    BTIF_TRACE_DEBUG("----%s: true", __func__);
-    snprintf(t, sizeof(t), "%02x:%02x:%02x:%02x:%02x:%02x", oob_cb.bdaddr[0],
-             oob_cb.bdaddr[1], oob_cb.bdaddr[2], oob_cb.bdaddr[3],
-             oob_cb.bdaddr[4], oob_cb.bdaddr[5]);
-    BTIF_TRACE_DEBUG("----%s: peer_bdaddr = %s", __func__, t);
-    snprintf(t, sizeof(t),
-             "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x "
-             "%02x %02x %02x",
-             p_c[0], p_c[1], p_c[2], p_c[3], p_c[4], p_c[5], p_c[6], p_c[7],
-             p_c[8], p_c[9], p_c[10], p_c[11], p_c[12], p_c[13], p_c[14],
-             p_c[15]);
-    BTIF_TRACE_DEBUG("----%s: c = %s", __func__, t);
-    snprintf(t, sizeof(t),
-             "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x "
-             "%02x %02x %02x",
-             p_r[0], p_r[1], p_r[2], p_r[3], p_r[4], p_r[5], p_r[6], p_r[7],
-             p_r[8], p_r[9], p_r[10], p_r[11], p_r[12], p_r[13], p_r[14],
-             p_r[15]);
-    BTIF_TRACE_DEBUG("----%s: r = %s", __func__, t);
-    bdcpy(bt_bd_addr.address, bd_addr);
-    btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_BOND_STATE_BONDING,
-                          (char*)&bt_bd_addr, sizeof(bt_bdaddr_t), NULL);
-    result = true;
+  if (!path) {
+    BTIF_TRACE_DEBUG("%s: can't open path!", __func__);
+    return false;
   }
-  BTIF_TRACE_DEBUG("%s: result=%d", __func__, result);
-  return result;
+
+  FILE* fp = fopen(path, "rb");
+  if (fp == NULL) {
+    BTIF_TRACE_DEBUG("%s: failed to read OOB keys from %s", __func__, path);
+    return false;
+  }
+
+  BTIF_TRACE_DEBUG("%s: read OOB data from %s", __func__, path);
+  fread(p_c, 1, BT_OCTET16_LEN, fp);
+  fread(p_r, 1, BT_OCTET16_LEN, fp);
+  fclose(fp);
+
+  RawAddress bt_bd_addr = bd_addr;
+  btif_transfer_context(btif_dm_generic_evt, BTIF_DM_CB_BOND_STATE_BONDING,
+                        (char*)&bt_bd_addr, sizeof(RawAddress), NULL);
+  return true;
 }
 #endif /*  BTIF_DM_OOB_TEST */
 
 static void btif_dm_ble_key_notif_evt(tBTA_DM_SP_KEY_NOTIF* p_ssp_key_notif) {
-  bt_bdaddr_t bd_addr;
+  RawAddress bd_addr;
   bt_bdname_t bd_name;
   uint32_t cod;
   int dev_type;
@@ -2881,10 +2811,10 @@
   btif_dm_update_ble_remote_properties(p_ssp_key_notif->bd_addr,
                                        p_ssp_key_notif->bd_name,
                                        (tBT_DEVICE_TYPE)dev_type);
-  bdcpy(bd_addr.address, p_ssp_key_notif->bd_addr);
+  bd_addr = p_ssp_key_notif->bd_addr;
   memcpy(bd_name.name, p_ssp_key_notif->bd_name, BD_NAME_LEN);
 
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
   pairing_cb.is_ssp = false;
   cod = COD_UNCLASSIFIED;
 
@@ -2903,11 +2833,10 @@
  ******************************************************************************/
 static void btif_dm_ble_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) {
   /* Save link key, if not temporary */
-  bt_bdaddr_t bd_addr;
   bt_status_t status = BT_STATUS_FAIL;
   bt_bond_state_t state = BT_BOND_STATE_NONE;
 
-  bdcpy(bd_addr.address, p_auth_cmpl->bd_addr);
+  RawAddress bd_addr = p_auth_cmpl->bd_addr;
 
   /* Clear OOB data */
   memset(&oob_cb, 0, sizeof(oob_cb));
@@ -2919,8 +2848,7 @@
     status = BT_STATUS_SUCCESS;
     state = BT_BOND_STATE_BONDED;
     int addr_type;
-    bt_bdaddr_t bdaddr;
-    bdcpy(bdaddr.address, p_auth_cmpl->bd_addr);
+    RawAddress bdaddr = p_auth_cmpl->bd_addr;
     if (btif_storage_get_remote_addr_type(&bdaddr, &addr_type) !=
         BT_STATUS_SUCCESS)
       btif_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type);
@@ -2955,12 +2883,11 @@
         break;
     }
   }
-  if (state == BT_BOND_STATE_BONDED &&
-      memcmp(&bd_addr, &pairing_cb.static_bdaddr, BD_ADDR_LEN)) {
+  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, BT_BOND_STATE_BONDING);
   }
-  bond_state_changed(status, &bd_addr, state);
+  bond_state_changed(status, bd_addr, state);
 }
 
 void btif_dm_load_ble_local_keys(void) {
@@ -3006,7 +2933,7 @@
   BTIF_TRACE_DEBUG("%s  *p_key_mask=0x%02x", __func__, *p_key_mask);
 }
 
-void btif_dm_save_ble_bonding_keys(bt_bdaddr_t bd_addr) {
+void btif_dm_save_ble_bonding_keys(RawAddress& bd_addr) {
   BTIF_TRACE_DEBUG("%s", __func__);
 
   if (pairing_cb.ble.is_penc_key_rcvd) {
@@ -3045,11 +2972,9 @@
 }
 
 void btif_dm_remove_ble_bonding_keys(void) {
-  bt_bdaddr_t bd_addr;
-
   BTIF_TRACE_DEBUG("%s", __func__);
 
-  bdcpy(bd_addr.address, pairing_cb.bd_addr);
+  RawAddress bd_addr = pairing_cb.bd_addr;
   btif_storage_remove_ble_bonding_keys(&bd_addr);
 }
 
@@ -3063,7 +2988,6 @@
  *
  ******************************************************************************/
 void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req) {
-  bt_bdaddr_t bd_addr;
   bt_bdname_t bd_name;
   uint32_t cod;
   int dev_type;
@@ -3082,10 +3006,10 @@
   btif_dm_update_ble_remote_properties(p_ble_req->bd_addr, p_ble_req->bd_name,
                                        (tBT_DEVICE_TYPE)dev_type);
 
-  bdcpy(bd_addr.address, p_ble_req->bd_addr);
+  RawAddress bd_addr = p_ble_req->bd_addr;
   memcpy(bd_name.name, p_ble_req->bd_name, BD_NAME_LEN);
 
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
 
   pairing_cb.bond_type = BOND_TYPE_PERSISTENT;
   pairing_cb.is_le_only = true;
@@ -3109,7 +3033,6 @@
  *
  ******************************************************************************/
 static void btif_dm_ble_passkey_req_evt(tBTA_DM_PIN_REQ* p_pin_req) {
-  bt_bdaddr_t bd_addr;
   bt_bdname_t bd_name;
   uint32_t cod;
   int dev_type;
@@ -3121,10 +3044,10 @@
   btif_dm_update_ble_remote_properties(p_pin_req->bd_addr, p_pin_req->bd_name,
                                        (tBT_DEVICE_TYPE)dev_type);
 
-  bdcpy(bd_addr.address, p_pin_req->bd_addr);
+  RawAddress bd_addr = p_pin_req->bd_addr;
   memcpy(bd_name.name, p_pin_req->bd_name, BD_NAME_LEN);
 
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
   pairing_cb.is_le_only = true;
 
   cod = COD_UNCLASSIFIED;
@@ -3139,13 +3062,12 @@
   btif_update_remote_properties(p_notif_req->bd_addr, p_notif_req->bd_name,
                                 NULL, BT_DEVICE_TYPE_BLE);
 
-  bt_bdaddr_t bd_addr;
-  bdcpy(bd_addr.address, p_notif_req->bd_addr);
+  RawAddress bd_addr = p_notif_req->bd_addr;
 
   bt_bdname_t bd_name;
   memcpy(bd_name.name, p_notif_req->bd_name, BD_NAME_LEN);
 
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
   pairing_cb.is_ssp = false;
   pairing_cb.is_le_only = true;
   pairing_cb.is_le_nc = true;
@@ -3157,8 +3079,7 @@
 static void btif_dm_ble_oob_req_evt(tBTA_DM_SP_RMT_OOB* req_oob_type) {
   BTIF_TRACE_DEBUG("%s", __func__);
 
-  bt_bdaddr_t bd_addr;
-  bdcpy(bd_addr.address, req_oob_type->bd_addr);
+  RawAddress bd_addr = req_oob_type->bd_addr;
   /* We already checked if OOB data is present in
    * btif_dm_set_oob_for_le_io_req, but check here again. If it's not present
    * do nothing, pairing will timeout.
@@ -3168,7 +3089,7 @@
   }
 
   /* make sure OOB data is for this particular device */
-  if (memcmp(req_oob_type->bd_addr, oob_cb.bdaddr, BD_ADDR_LEN) != 0) {
+  if (req_oob_type->bd_addr != oob_cb.bdaddr) {
     BTIF_TRACE_WARNING("%s: remote address didn't match OOB data address",
                        __func__);
     return;
@@ -3178,7 +3099,7 @@
   btif_update_remote_properties(req_oob_type->bd_addr, req_oob_type->bd_name,
                                 NULL, BT_DEVICE_TYPE_BLE);
 
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
   pairing_cb.is_ssp = false;
   pairing_cb.is_le_only = true;
   pairing_cb.is_le_nc = false;
@@ -3189,8 +3110,7 @@
 static void btif_dm_ble_sc_oob_req_evt(tBTA_DM_SP_RMT_OOB* req_oob_type) {
   BTIF_TRACE_DEBUG("%s", __func__);
 
-  bt_bdaddr_t bd_addr;
-  bdcpy(bd_addr.address, req_oob_type->bd_addr);
+  RawAddress bd_addr = req_oob_type->bd_addr;
 
   /* We already checked if OOB data is present in
    * btif_dm_set_oob_for_le_io_req, but check here again. If it's not present
@@ -3203,7 +3123,7 @@
   }
 
   /* make sure OOB data is for this particular device */
-  if (memcmp(req_oob_type->bd_addr, oob_cb.bdaddr, BD_ADDR_LEN) != 0) {
+  if (req_oob_type->bd_addr != oob_cb.bdaddr) {
     BTIF_TRACE_WARNING("%s: remote address didn't match OOB data address",
                        __func__);
     return;
@@ -3213,7 +3133,7 @@
   btif_update_remote_properties(req_oob_type->bd_addr, req_oob_type->bd_name,
                                 NULL, BT_DEVICE_TYPE_BLE);
 
-  bond_state_changed(BT_STATUS_SUCCESS, &bd_addr, BT_BOND_STATE_BONDING);
+  bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
   pairing_cb.is_ssp = false;
   pairing_cb.is_le_only =
       true;  // TODO: we can derive classic pairing from this one
@@ -3223,7 +3143,8 @@
       req_oob_type->bd_addr, oob_cb.oob_data.le_sc_c, oob_cb.oob_data.le_sc_r);
 }
 
-void btif_dm_update_ble_remote_properties(BD_ADDR bd_addr, BD_NAME bd_name,
+void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr,
+                                          BD_NAME bd_name,
                                           tBT_DEVICE_TYPE dev_type) {
   btif_update_remote_properties(bd_addr, bd_name, NULL, dev_type);
 }
@@ -3275,11 +3196,8 @@
 void btif_dm_on_disable() {
   /* cancel any pending pairing requests */
   if (is_bonding_or_sdp()) {
-    bt_bdaddr_t bd_addr;
-
     BTIF_TRACE_DEBUG("%s: Cancel pending pairing request", __func__);
-    bdcpy(bd_addr.address, pairing_cb.bd_addr);
-    btif_dm_cancel_bond(&bd_addr);
+    btif_dm_cancel_bond(&pairing_cb.bd_addr);
   }
 }
 
@@ -3309,13 +3227,13 @@
   return btif_default_local_name;
 }
 
-static void btif_stats_add_bond_event(const bt_bdaddr_t* bd_addr,
+static void btif_stats_add_bond_event(const RawAddress& bd_addr,
                                       bt_bond_function_t function,
                                       bt_bond_state_t state) {
   std::unique_lock<std::mutex> lock(bond_event_lock);
 
   btif_bond_event_t* event = &btif_dm_bond_events[btif_events_end_index];
-  memcpy(&event->bd_addr, bd_addr, sizeof(bt_bdaddr_t));
+  event->bd_addr = bd_addr;
   event->function = function;
   event->state = state;
   clock_gettime(CLOCK_REALTIME, &event->timestamp);
@@ -3329,7 +3247,7 @@
   }
 
   int type;
-  btif_get_device_type(bd_addr->address, &type);
+  btif_get_device_type(bd_addr, &type);
 
   system_bt_osi::device_type_t device_type;
   switch (type) {
@@ -3347,7 +3265,7 @@
       break;
   }
 
-  uint32_t cod = get_cod(bd_addr);
+  uint32_t cod = get_cod(&bd_addr);
   uint64_t ts =
       event->timestamp.tv_sec * 1000 + event->timestamp.tv_nsec / 1000000;
   system_bt_osi::BluetoothMetricsLogger::GetInstance()->LogPairEvent(
@@ -3360,7 +3278,7 @@
   dprintf(fd, "  Total Number of events: %zu\n", btif_num_bond_events);
   if (btif_num_bond_events > 0)
     dprintf(fd,
-            "  Time          BD_ADDR            Function             State\n");
+            "  Time          address            Function             State\n");
 
   for (size_t i = btif_events_start_index; i != btif_events_end_index;
        i = (i + 1) % (MAX_BTIF_BOND_EVENT_ENTRIES + 1)) {
@@ -3373,9 +3291,6 @@
     snprintf(eventtime, sizeof(eventtime), "%s.%03ld", temptime,
              event->timestamp.tv_nsec / 1000000);
 
-    char bdaddr[18];
-    bdaddr_to_string(&event->bd_addr, bdaddr, sizeof(bdaddr));
-
     const char* func_name;
     switch (event->function) {
       case BTIF_DM_FUNC_CREATE_BOND:
@@ -3407,6 +3322,8 @@
         bond_state = "Invalid bond state";
         break;
     }
-    dprintf(fd, "  %s  %s  %s  %s\n", eventtime, bdaddr, func_name, bond_state);
+
+    dprintf(fd, "  %s  %s  %s  %s\n", eventtime,
+            event->bd_addr.ToString().c_str(), func_name, bond_state);
   }
 }
diff --git a/btif/src/btif_gatt_client.cc b/btif/src/btif_gatt_client.cc
index e0636ff..262234b 100644
--- a/btif/src/btif_gatt_client.cc
+++ b/btif/src/btif_gatt_client.cc
@@ -35,7 +35,6 @@
 #include <string.h>
 #include "device/include/controller.h"
 
-#include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "btif_util.h"
 
@@ -56,8 +55,8 @@
 using base::Owned;
 using std::vector;
 
-extern bt_status_t btif_gattc_test_command_impl(int command,
-                                                btgatt_test_params_t* params);
+extern bt_status_t btif_gattc_test_command_impl(
+    int command, const btgatt_test_params_t* params);
 extern const btgatt_callbacks_t* bt_gatt_callbacks;
 
 /*******************************************************************************
@@ -88,9 +87,9 @@
   0x40                             /* bit7, bit6 is 01 to be resolvable random \
                                       */
 #define BLE_RESOLVE_ADDR_MASK 0xc0 /* bit 6, and bit7 */
-#define BTM_BLE_IS_RESOLVE_BDA(x) \
-  (((x)[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
-
+inline bool BTM_BLE_IS_RESOLVE_BDA(const RawAddress& x) {
+  return ((x.address)[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB;
+}
 namespace {
 
 uint8_t rssi_request_client_if;
@@ -118,7 +117,7 @@
     case BTA_GATTC_NOTIF_EVT: {
       btgatt_notify_params_t data;
 
-      bdcpy(data.bda.address, p_data->notify.bda);
+      data.bda = p_data->notify.bda;
       memcpy(data.value, p_data->notify.value, p_data->notify.len);
 
       data.handle = p_data->notify.handle;
@@ -126,7 +125,7 @@
       data.len = p_data->notify.len;
 
       HAL_CBACK(bt_gatt_callbacks, client->notify_cb, p_data->notify.conn_id,
-                &data);
+                data);
 
       if (p_data->notify.is_notify == false)
         BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.handle);
@@ -135,11 +134,10 @@
     }
 
     case BTA_GATTC_OPEN_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->open.remote_bda);
-
+      DVLOG(1) << "BTA_GATTC_OPEN_EVT " << p_data->open.remote_bda;
       HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id,
-                p_data->open.status, p_data->open.client_if, &bda);
+                p_data->open.status, p_data->open.client_if,
+                p_data->open.remote_bda);
 
       if (GATT_DEF_BLE_MTU_SIZE != p_data->open.mtu && p_data->open.mtu) {
         HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb,
@@ -153,10 +151,9 @@
     }
 
     case BTA_GATTC_CLOSE_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->close.remote_bda);
       HAL_CBACK(bt_gatt_callbacks, client->close_cb, p_data->close.conn_id,
-                p_data->status, p_data->close.client_if, &bda);
+                p_data->status, p_data->close.client_if,
+                p_data->close.remote_bda);
       break;
     }
 
@@ -206,24 +203,22 @@
   ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
 }
 
-void btm_read_rssi_cb(tBTM_RSSI_RESULTS* p_result) {
+void btm_read_rssi_cb(tBTM_RSSI_RESULT* p_result) {
   if (!p_result) return;
 
-  bt_bdaddr_t* addr = new bt_bdaddr_t;
-  bdcpy(addr->address, p_result->rem_bda);
   CLI_CBACK_IN_JNI(read_remote_rssi_cb, rssi_request_client_if,
-                   base::Owned(addr), p_result->rssi, p_result->status);
+                   p_result->rem_bda, p_result->rssi, p_result->status);
 }
 
 /*******************************************************************************
  *  Client API Functions
  ******************************************************************************/
 
-bt_status_t btif_gattc_register_app(bt_uuid_t* uuid) {
+bt_status_t btif_gattc_register_app(const bt_uuid_t& uuid) {
   CHECK_BTGATT_INIT();
 
   tBT_UUID bt_uuid;
-  btif_to_bta_uuid(&bt_uuid, uuid);
+  btif_to_bta_uuid(&bt_uuid, &uuid);
 
   return do_in_jni_thread(Bind(
       [](tBT_UUID bt_uuid) {
@@ -236,7 +231,7 @@
                         bt_uuid_t app_uuid;
                         bta_to_btif_uuid(&app_uuid, &bt_uuid);
                         HAL_CBACK(bt_gatt_callbacks, client->register_client_cb,
-                                  status, client_id, &app_uuid);
+                                  status, client_id, app_uuid);
                       },
                       bt_uuid, client_id, status));
                 },
@@ -254,7 +249,7 @@
   return do_in_jni_thread(Bind(&btif_gattc_unregister_app_impl, client_if));
 }
 
-void btif_gattc_open_impl(int client_if, BD_ADDR address, bool is_direct,
+void btif_gattc_open_impl(int client_if, RawAddress address, bool is_direct,
                           int transport_p, bool opportunistic,
                           int initiating_phys) {
   // Ensure device is in inquiry database
@@ -279,7 +274,7 @@
       BTM_BleGetVendorCapabilities(&vnd_capabilities);
       if (!vnd_capabilities.rpa_offloading) {
         HAL_CBACK(bt_gatt_callbacks, client->open_cb, 0, BT_STATUS_UNSUPPORTED,
-                  client_if, (bt_bdaddr_t*)&address);
+                  client_if, address);
         return;
       }
     }
@@ -309,26 +304,23 @@
   }
 
   // Connect!
-  BTIF_TRACE_DEBUG("%s Transport=%d, device type=%d, opportunistic=%d, phy=%d",
-                   __func__, transport, device_type, opportunistic,
-                   initiating_phys);
+  BTIF_TRACE_DEBUG("%s Transport=%d, device type=%d, phy=%d", __func__,
+                   transport, device_type, initiating_phys);
   BTA_GATTC_Open(client_if, address, is_direct, transport, opportunistic,
                  initiating_phys);
 }
 
-bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t* bd_addr,
+bt_status_t btif_gattc_open(int client_if, const RawAddress& bd_addr,
                             bool is_direct, int transport, bool opportunistic,
                             int initiating_phys) {
   CHECK_BTGATT_INIT();
   // Closure will own this value and free it.
-  uint8_t* address = new BD_ADDR;
-  bdcpy(address, bd_addr->address);
-  return do_in_jni_thread(Bind(&btif_gattc_open_impl, client_if,
-                               base::Owned(address), is_direct, transport,
-                               opportunistic, initiating_phys));
+  return do_in_jni_thread(Bind(&btif_gattc_open_impl, client_if, bd_addr,
+                               is_direct, transport, opportunistic,
+                               initiating_phys));
 }
 
-void btif_gattc_close_impl(int client_if, BD_ADDR address, int conn_id) {
+void btif_gattc_close_impl(int client_if, RawAddress address, int conn_id) {
   // Disconnect established connections
   if (conn_id != 0)
     BTA_GATTC_Close(conn_id);
@@ -339,22 +331,20 @@
   BTA_GATTC_CancelOpen(client_if, address, false);
 }
 
-bt_status_t btif_gattc_close(int client_if, const bt_bdaddr_t* bd_addr,
+bt_status_t btif_gattc_close(int client_if, const RawAddress& bd_addr,
                              int conn_id) {
   CHECK_BTGATT_INIT();
-  // Closure will own this value and free it.
-  uint8_t* address = new BD_ADDR;
-  bdcpy(address, bd_addr->address);
   return do_in_jni_thread(
-      Bind(&btif_gattc_close_impl, client_if, base::Owned(address), conn_id));
+      Bind(&btif_gattc_close_impl, client_if, bd_addr, conn_id));
 }
 
-bt_status_t btif_gattc_refresh(int client_if, const bt_bdaddr_t* bd_addr) {
+bt_status_t btif_gattc_refresh(int client_if, const RawAddress& bd_addr) {
   CHECK_BTGATT_INIT();
-  return do_in_jni_thread(Bind(&BTA_GATTC_Refresh, *bd_addr));
+  return do_in_jni_thread(Bind(&BTA_GATTC_Refresh, bd_addr));
 }
 
-bt_status_t btif_gattc_search_service(int conn_id, bt_uuid_t* filter_uuid) {
+bt_status_t btif_gattc_search_service(int conn_id,
+                                      const bt_uuid_t* filter_uuid) {
   CHECK_BTGATT_INIT();
 
   if (filter_uuid) {
@@ -368,11 +358,9 @@
   }
 }
 
-void btif_gattc_discover_service_by_uuid(int conn_id, bt_uuid_t* p_uuid) {
-  LOG_ASSERT(p_uuid);
-
+void btif_gattc_discover_service_by_uuid(int conn_id, const bt_uuid_t& p_uuid) {
   tBT_UUID* uuid = new tBT_UUID;
-  btif_to_bta_uuid(uuid, p_uuid);
+  btif_to_bta_uuid(uuid, &p_uuid);
   do_in_jni_thread(
       Bind(&BTA_GATTC_DiscoverServiceByUuid, conn_id, base::Owned(uuid)));
 }
@@ -430,12 +418,12 @@
                    base::Owned(params));
 }
 
-bt_status_t btif_gattc_read_using_char_uuid(int conn_id, bt_uuid_t* uuid,
+bt_status_t btif_gattc_read_using_char_uuid(int conn_id, const bt_uuid_t& uuid,
                                             uint16_t s_handle,
                                             uint16_t e_handle, int auth_req) {
   CHECK_BTGATT_INIT();
   tBT_UUID bt_uuid;
-  btif_to_bta_uuid(&bt_uuid, uuid);
+  btif_to_bta_uuid(&bt_uuid, &uuid);
   return do_in_jni_thread(Bind(&BTA_GATTC_ReadUsingCharUuid, conn_id, bt_uuid,
                                s_handle, e_handle, auth_req,
                                read_using_char_uuid_cb, nullptr));
@@ -443,18 +431,15 @@
 
 void read_desc_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
                   uint16_t len, uint8_t* value, void* data) {
-  btgatt_read_params_t* params = new btgatt_read_params_t;
-  params->value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
-  params->status = status;
-  params->handle = handle;
-  params->value.len = len;
+  btgatt_read_params_t params;
+  params.value_type = 0x00 /* GATTC_READ_VALUE_TYPE_VALUE */;
+  params.status = status;
+  params.handle = handle;
+  params.value.len = len;
   CHECK(len <= BTGATT_MAX_ATTR_LEN);
-  if (len > 0) memcpy(params->value.value, value, len);
+  if (len > 0) memcpy(params.value.value, value, len);
 
-  // clang-tidy analyzer complains about |params| is leaked.  It doesn't know
-  // that |param| will be freed by the callback function.
-  CLI_CBACK_IN_JNI(read_descriptor_cb, conn_id, status,
-                   base::Owned(params)); /* NOLINT */
+  CLI_CBACK_IN_JNI(read_descriptor_cb, conn_id, status, params);
 }
 
 bt_status_t btif_gattc_read_char_descr(int conn_id, uint16_t handle,
@@ -503,9 +488,10 @@
 }
 
 void btif_gattc_reg_for_notification_impl(tBTA_GATTC_IF client_if,
-                                          const BD_ADDR bda, uint16_t handle) {
-  tBTA_GATT_STATUS status = BTA_GATTC_RegisterForNotifications(
-      client_if, const_cast<uint8_t*>(bda), handle);
+                                          const RawAddress& bda,
+                                          uint16_t handle) {
+  tBTA_GATT_STATUS status =
+      BTA_GATTC_RegisterForNotifications(client_if, bda, handle);
 
   // TODO(jpawlowski): conn_id is currently unused
   HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
@@ -513,22 +499,20 @@
 }
 
 bt_status_t btif_gattc_reg_for_notification(int client_if,
-                                            const bt_bdaddr_t* bd_addr,
+                                            const RawAddress& bd_addr,
                                             uint16_t handle) {
   CHECK_BTGATT_INIT();
 
-  uint8_t* address = new BD_ADDR;
-  bdcpy(address, bd_addr->address);
   return do_in_jni_thread(
       Bind(base::IgnoreResult(&btif_gattc_reg_for_notification_impl), client_if,
-           base::Owned(address), handle));
+           bd_addr, handle));
 }
 
 void btif_gattc_dereg_for_notification_impl(tBTA_GATTC_IF client_if,
-                                            const BD_ADDR bda,
+                                            const RawAddress& bda,
                                             uint16_t handle) {
-  tBTA_GATT_STATUS status = BTA_GATTC_DeregisterForNotifications(
-      client_if, const_cast<uint8_t*>(bda), handle);
+  tBTA_GATT_STATUS status =
+      BTA_GATTC_DeregisterForNotifications(client_if, bda, handle);
 
   // TODO(jpawlowski): conn_id is currently unused
   HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
@@ -536,26 +520,21 @@
 }
 
 bt_status_t btif_gattc_dereg_for_notification(int client_if,
-                                              const bt_bdaddr_t* bd_addr,
+                                              const RawAddress& bd_addr,
                                               uint16_t handle) {
   CHECK_BTGATT_INIT();
 
-  uint8_t* address = new BD_ADDR;
-  bdcpy(address, bd_addr->address);
   return do_in_jni_thread(
       Bind(base::IgnoreResult(&btif_gattc_dereg_for_notification_impl),
-           client_if, base::Owned(address), handle));
+           client_if, bd_addr, handle));
 }
 
 bt_status_t btif_gattc_read_remote_rssi(int client_if,
-                                        const bt_bdaddr_t* bd_addr) {
+                                        const RawAddress& bd_addr) {
   CHECK_BTGATT_INIT();
   rssi_request_client_if = client_if;
-  // Closure will own this value and free it.
-  uint8_t* address = new BD_ADDR;
-  bdcpy(address, bd_addr->address);
-  return do_in_jni_thread(Bind(base::IgnoreResult(&BTM_ReadRSSI),
-                               base::Owned(address),
+
+  return do_in_jni_thread(Bind(base::IgnoreResult(&BTM_ReadRSSI), bd_addr,
                                (tBTM_CMPL_CB*)btm_read_rssi_cb));
 }
 
@@ -565,55 +544,55 @@
       Bind(base::IgnoreResult(&BTA_GATTC_ConfigureMTU), conn_id, mtu));
 }
 
-void btif_gattc_conn_parameter_update_impl(bt_bdaddr_t addr, int min_interval,
+void btif_gattc_conn_parameter_update_impl(RawAddress addr, int min_interval,
                                            int max_interval, int latency,
                                            int timeout) {
-  if (BTA_DmGetConnectionState(addr.address))
-    BTA_DmBleUpdateConnectionParams(addr.address, min_interval, max_interval,
-                                    latency, timeout);
+  if (BTA_DmGetConnectionState(addr))
+    BTA_DmBleUpdateConnectionParams(addr, min_interval, max_interval, latency,
+                                    timeout);
   else
-    BTA_DmSetBlePrefConnParams(addr.address, min_interval, max_interval,
-                               latency, timeout);
+    BTA_DmSetBlePrefConnParams(addr, min_interval, max_interval, latency,
+                               timeout);
 }
 
-bt_status_t btif_gattc_conn_parameter_update(const bt_bdaddr_t* bd_addr,
+bt_status_t btif_gattc_conn_parameter_update(const RawAddress& bd_addr,
                                              int min_interval, int max_interval,
                                              int latency, int timeout) {
   CHECK_BTGATT_INIT();
   return do_in_jni_thread(
-      Bind(base::IgnoreResult(&btif_gattc_conn_parameter_update_impl), *bd_addr,
+      Bind(base::IgnoreResult(&btif_gattc_conn_parameter_update_impl), bd_addr,
            min_interval, max_interval, latency, timeout));
 }
 
-bt_status_t btif_gattc_set_preferred_phy(int conn_id, uint8_t tx_phy,
-                                         uint8_t rx_phy, uint16_t phy_options) {
+bt_status_t btif_gattc_set_preferred_phy(const RawAddress& bd_addr,
+                                         uint8_t tx_phy, uint8_t rx_phy,
+                                         uint16_t phy_options) {
   CHECK_BTGATT_INIT();
-  do_in_bta_thread(FROM_HERE, Bind(&GATTC_SetPreferredPHY, conn_id, tx_phy,
-                                   rx_phy, phy_options));
+  do_in_bta_thread(FROM_HERE,
+                   Bind(&BTM_BleSetPhy, bd_addr, tx_phy, rx_phy, phy_options));
   return BT_STATUS_SUCCESS;
 }
 
 bt_status_t btif_gattc_read_phy(
-    int conn_id,
+    const RawAddress& bd_addr,
     base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
   CHECK_BTGATT_INIT();
-  do_in_bta_thread(FROM_HERE, Bind(&GATTC_ReadPHY, conn_id,
+  do_in_bta_thread(FROM_HERE, Bind(&BTM_BleReadPhy, bd_addr,
                                    jni_thread_wrapper(FROM_HERE, cb)));
   return BT_STATUS_SUCCESS;
 }
 
-int btif_gattc_get_device_type(const bt_bdaddr_t* bd_addr) {
+int btif_gattc_get_device_type(const RawAddress& bd_addr) {
   int device_type = 0;
-  char bd_addr_str[18] = {0};
 
-  bdaddr_to_string(bd_addr, bd_addr_str, sizeof(bd_addr_str));
-  if (btif_config_get_int(bd_addr_str, "DevType", &device_type))
+  if (btif_config_get_int(bd_addr.ToString().c_str(), "DevType", &device_type))
     return device_type;
   return 0;
 }
 
-bt_status_t btif_gattc_test_command(int command, btgatt_test_params_t* params) {
-  return btif_gattc_test_command_impl(command, params);
+bt_status_t btif_gattc_test_command(int command,
+                                    const btgatt_test_params_t& params) {
+  return btif_gattc_test_command_impl(command, &params);
 }
 
 }  // namespace
diff --git a/btif/src/btif_gatt_server.cc b/btif/src/btif_gatt_server.cc
index 24f0346..bd3a94ce 100644
--- a/btif/src/btif_gatt_server.cc
+++ b/btif/src/btif_gatt_server.cc
@@ -131,7 +131,7 @@
       bt_uuid_t app_uuid;
       bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.uuid);
       HAL_CBACK(bt_gatt_callbacks, server->register_server_cb,
-                p_data->reg_oper.status, p_data->reg_oper.server_if, &app_uuid);
+                p_data->reg_oper.status, p_data->reg_oper.server_if, app_uuid);
       break;
     }
 
@@ -139,23 +139,17 @@
       break;
 
     case BTA_GATTS_CONNECT_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->conn.remote_bda);
-
       btif_gatt_check_encrypted_link(p_data->conn.remote_bda,
                                      p_data->conn.transport);
 
       HAL_CBACK(bt_gatt_callbacks, server->connection_cb, p_data->conn.conn_id,
-                p_data->conn.server_if, true, &bda);
+                p_data->conn.server_if, true, p_data->conn.remote_bda);
       break;
     }
 
     case BTA_GATTS_DISCONNECT_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->conn.remote_bda);
-
       HAL_CBACK(bt_gatt_callbacks, server->connection_cb, p_data->conn.conn_id,
-                p_data->conn.server_if, false, &bda);
+                p_data->conn.server_if, false, p_data->conn.remote_bda);
       break;
     }
 
@@ -172,11 +166,9 @@
       break;
 
     case BTA_GATTS_READ_CHARACTERISTIC_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->req_data.remote_bda);
-
       HAL_CBACK(bt_gatt_callbacks, server->request_read_characteristic_cb,
-                p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
+                p_data->req_data.conn_id, p_data->req_data.trans_id,
+                p_data->req_data.remote_bda,
                 p_data->req_data.p_data->read_req.handle,
                 p_data->req_data.p_data->read_req.offset,
                 p_data->req_data.p_data->read_req.is_long);
@@ -184,11 +176,9 @@
     }
 
     case BTA_GATTS_READ_DESCRIPTOR_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->req_data.remote_bda);
-
       HAL_CBACK(bt_gatt_callbacks, server->request_read_descriptor_cb,
-                p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
+                p_data->req_data.conn_id, p_data->req_data.trans_id,
+                p_data->req_data.remote_bda,
                 p_data->req_data.p_data->read_req.handle,
                 p_data->req_data.p_data->read_req.offset,
                 p_data->req_data.p_data->read_req.is_long);
@@ -196,33 +186,29 @@
     }
 
     case BTA_GATTS_WRITE_CHARACTERISTIC_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->req_data.remote_bda);
       const auto& req = p_data->req_data.p_data->write_req;
       vector<uint8_t> value(req.value, req.value + req.len);
       HAL_CBACK(bt_gatt_callbacks, server->request_write_characteristic_cb,
-                p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
-                req.handle, req.offset, req.need_rsp, req.is_prep, value);
+                p_data->req_data.conn_id, p_data->req_data.trans_id,
+                p_data->req_data.remote_bda, req.handle, req.offset,
+                req.need_rsp, req.is_prep, value);
       break;
     }
 
     case BTA_GATTS_WRITE_DESCRIPTOR_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->req_data.remote_bda);
       const auto& req = p_data->req_data.p_data->write_req;
       vector<uint8_t> value(req.value, req.value + req.len);
       HAL_CBACK(bt_gatt_callbacks, server->request_write_descriptor_cb,
-                p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
-                req.handle, req.offset, req.need_rsp, req.is_prep, value);
+                p_data->req_data.conn_id, p_data->req_data.trans_id,
+                p_data->req_data.remote_bda, req.handle, req.offset,
+                req.need_rsp, req.is_prep, value);
       break;
     }
 
     case BTA_GATTS_EXEC_WRITE_EVT: {
-      bt_bdaddr_t bda;
-      bdcpy(bda.address, p_data->req_data.remote_bda);
-
       HAL_CBACK(bt_gatt_callbacks, server->request_exec_write_cb,
-                p_data->req_data.conn_id, p_data->req_data.trans_id, &bda,
+                p_data->req_data.conn_id, p_data->req_data.trans_id,
+                p_data->req_data.remote_bda,
                 p_data->req_data.p_data->exec_write);
       break;
     }
@@ -280,10 +266,10 @@
 /*******************************************************************************
  *  Server API Functions
  ******************************************************************************/
-static bt_status_t btif_gatts_register_app(bt_uuid_t* bt_uuid) {
+static bt_status_t btif_gatts_register_app(const bt_uuid_t& bt_uuid) {
   CHECK_BTGATT_INIT();
   tBT_UUID* uuid = new tBT_UUID;
-  btif_to_bta_uuid(uuid, bt_uuid);
+  btif_to_bta_uuid(uuid, &bt_uuid);
 
   return do_in_jni_thread(
       Bind(&BTA_GATTS_AppRegister, base::Owned(uuid), &btapp_gatts_cback));
@@ -294,8 +280,8 @@
   return do_in_jni_thread(Bind(&BTA_GATTS_AppDeregister, server_if));
 }
 
-static void btif_gatts_open_impl(int server_if, BD_ADDR address, bool is_direct,
-                                 int transport_param) {
+static void btif_gatts_open_impl(int server_if, const RawAddress& address,
+                                 bool is_direct, int transport_param) {
   // Ensure device is in inquiry database
   int addr_type = 0;
   int device_type = 0;
@@ -329,10 +315,6 @@
         else
           transport = BTA_GATT_TRANSPORT_BR_EDR;
         break;
-
-      default:
-        BTIF_TRACE_ERROR("%s: Invalid device type %d", __func__, device_type);
-        return;
     }
   }
 
@@ -340,17 +322,15 @@
   BTA_GATTS_Open(server_if, address, is_direct, transport);
 }
 
-static bt_status_t btif_gatts_open(int server_if, const bt_bdaddr_t* bd_addr,
+static bt_status_t btif_gatts_open(int server_if, const RawAddress& bd_addr,
                                    bool is_direct, int transport) {
   CHECK_BTGATT_INIT();
-  uint8_t* address = new BD_ADDR;
-  bdcpy(address, bd_addr->address);
-
-  return do_in_jni_thread(Bind(&btif_gatts_open_impl, server_if,
-                               base::Owned(address), is_direct, transport));
+  return do_in_jni_thread(
+      Bind(&btif_gatts_open_impl, server_if, bd_addr, is_direct, transport));
 }
 
-static void btif_gatts_close_impl(int server_if, BD_ADDR address, int conn_id) {
+static void btif_gatts_close_impl(int server_if, const RawAddress& address,
+                                  int conn_id) {
   // Close active connection
   if (conn_id != 0)
     BTA_GATTS_Close(conn_id);
@@ -361,14 +341,11 @@
   BTA_GATTS_CancelOpen(server_if, address, false);
 }
 
-static bt_status_t btif_gatts_close(int server_if, const bt_bdaddr_t* bd_addr,
+static bt_status_t btif_gatts_close(int server_if, const RawAddress& bd_addr,
                                     int conn_id) {
   CHECK_BTGATT_INIT();
-  uint8_t* address = new BD_ADDR;
-  bdcpy(address, bd_addr->address);
-
   return do_in_jni_thread(
-      Bind(&btif_gatts_close_impl, server_if, base::Owned(address), conn_id));
+      Bind(&btif_gatts_close_impl, server_if, bd_addr, conn_id));
 }
 
 static void add_service_impl(int server_if,
@@ -438,26 +415,26 @@
 
 static bt_status_t btif_gatts_send_response(int conn_id, int trans_id,
                                             int status,
-                                            btgatt_response_t* response) {
+                                            const btgatt_response_t& response) {
   CHECK_BTGATT_INIT();
   return do_in_jni_thread(Bind(&btif_gatts_send_response_impl, conn_id,
-                               trans_id, status, *response));
+                               trans_id, status, response));
 }
 
-static bt_status_t btif_gattc_set_preferred_phy(int conn_id, uint8_t tx_phy,
-                                                uint8_t rx_phy,
+static bt_status_t btif_gatts_set_preferred_phy(const RawAddress& bd_addr,
+                                                uint8_t tx_phy, uint8_t rx_phy,
                                                 uint16_t phy_options) {
   CHECK_BTGATT_INIT();
-  do_in_bta_thread(FROM_HERE, Bind(&GATTC_SetPreferredPHY, conn_id, tx_phy,
-                                   rx_phy, phy_options));
+  do_in_bta_thread(FROM_HERE,
+                   Bind(&BTM_BleSetPhy, bd_addr, tx_phy, rx_phy, phy_options));
   return BT_STATUS_SUCCESS;
 }
 
-static bt_status_t btif_gattc_read_phy(
-    int conn_id,
+static bt_status_t btif_gatts_read_phy(
+    const RawAddress& bd_addr,
     base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
   CHECK_BTGATT_INIT();
-  do_in_bta_thread(FROM_HERE, Bind(&GATTC_ReadPHY, conn_id,
+  do_in_bta_thread(FROM_HERE, Bind(&BTM_BleReadPhy, bd_addr,
                                    jni_thread_wrapper(FROM_HERE, cb)));
   return BT_STATUS_SUCCESS;
 }
@@ -467,5 +444,5 @@
     btif_gatts_open,           btif_gatts_close,
     btif_gatts_add_service,    btif_gatts_stop_service,
     btif_gatts_delete_service, btif_gatts_send_indication,
-    btif_gatts_send_response,  btif_gattc_set_preferred_phy,
-    btif_gattc_read_phy};
+    btif_gatts_send_response,  btif_gatts_set_preferred_phy,
+    btif_gatts_read_phy};
diff --git a/btif/src/btif_gatt_test.cc b/btif/src/btif_gatt_test.cc
index 73cffc5..4312533 100644
--- a/btif/src/btif_gatt_test.cc
+++ b/btif/src/btif_gatt_test.cc
@@ -86,11 +86,9 @@
   return str_buf;
 }
 
-static void btif_test_connect_cback(UNUSED_ATTR tGATT_IF gatt_if,
-                                    UNUSED_ATTR BD_ADDR bda, uint16_t conn_id,
-                                    bool connected,
-                                    UNUSED_ATTR tGATT_DISCONN_REASON reason,
-                                    UNUSED_ATTR tBT_TRANSPORT transport) {
+static void btif_test_connect_cback(tGATT_IF, const RawAddress&,
+                                    uint16_t conn_id, bool connected,
+                                    tGATT_DISCONN_REASON, tBT_TRANSPORT) {
   LOG_DEBUG(LOG_TAG, "%s: conn_id=%d, connected=%d", __func__, conn_id,
             connected);
   test_cb.conn_id = connected ? conn_id : 0;
@@ -201,7 +199,7 @@
  ******************************************************************************/
 
 bt_status_t btif_gattc_test_command_impl(int command,
-                                         btgatt_test_params_t* params) {
+                                         const btgatt_test_params_t* params) {
   switch (command) {
     case 0x01: /* Enable */
     {
@@ -228,11 +226,11 @@
                 params->u2);
 
       if (params->u1 == BT_DEVICE_TYPE_BLE)
-        BTM_SecAddBleDevice(params->bda1->address, NULL, BT_DEVICE_TYPE_BLE,
+        BTM_SecAddBleDevice(*params->bda1, NULL, BT_DEVICE_TYPE_BLE,
                             params->u2);
 
-      if (!GATT_Connect(test_cb.gatt_if, params->bda1->address, true,
-                        BT_TRANSPORT_LE, false)) {
+      if (!GATT_Connect(test_cb.gatt_if, *params->bda1, true, BT_TRANSPORT_LE,
+                        false)) {
         LOG_ERROR(LOG_TAG, "%s: GATT_Connect failed!", __func__);
       }
       break;
diff --git a/btif/src/btif_gatt_util.cc b/btif/src/btif_gatt_util.cc
index 3d0e603..9745917 100644
--- a/btif/src/btif_gatt_util.cc
+++ b/btif/src/btif_gatt_util.cc
@@ -28,7 +28,6 @@
 #include <hardware/bluetooth.h>
 #include <hardware/bt_gatt.h>
 
-#include "bdaddr.h"
 #include "bt_common.h"
 #include "bta_api.h"
 #include "bta_gatt_api.h"
@@ -212,13 +211,11 @@
  ******************************************************************************/
 
 #if (BLE_DELAY_REQUEST_ENC == FALSE)
-static bool btif_gatt_is_link_encrypted(BD_ADDR bd_addr) {
-  if (bd_addr == NULL) return false;
-
+static bool btif_gatt_is_link_encrypted(const RawAddress& bd_addr) {
   return BTA_JvIsEncrypted(bd_addr);
 }
 
-static void btif_gatt_set_encryption_cb(UNUSED_ATTR BD_ADDR bd_addr,
+static void btif_gatt_set_encryption_cb(UNUSED_ATTR const RawAddress& bd_addr,
                                         UNUSED_ATTR tBTA_TRANSPORT transport,
                                         tBTA_STATUS result) {
   if (result != BTA_SUCCESS && result != BTA_BUSY) {
@@ -228,14 +225,11 @@
 #endif
 
 #if (BLE_DELAY_REQUEST_ENC == FALSE)
-void btif_gatt_check_encrypted_link(BD_ADDR bd_addr,
+void btif_gatt_check_encrypted_link(RawAddress bd_addr,
                                     tBTA_GATT_TRANSPORT transport_link) {
   char buf[100];
 
-  bt_bdaddr_t bda;
-  bdcpy(bda.address, bd_addr);
-
-  if ((btif_storage_get_ble_bonding_key(&bda, BTIF_DM_LE_KEY_PENC, buf,
+  if ((btif_storage_get_ble_bonding_key(&bd_addr, BTIF_DM_LE_KEY_PENC, buf,
                                         sizeof(tBTM_LE_PENC_KEYS)) ==
        BT_STATUS_SUCCESS) &&
       !btif_gatt_is_link_encrypted(bd_addr)) {
@@ -245,7 +239,7 @@
   }
 }
 #else
-void btif_gatt_check_encrypted_link(UNUSED_ATTR BD_ADDR bd_addr,
+void btif_gatt_check_encrypted_link(UNUSED_ATTR RawAddress bd_addr,
                                     UNUSED_ATTR tBTA_GATT_TRANSPORT
                                         transport_link) {}
 #endif
diff --git a/btif/src/btif_hd.cc b/btif/src/btif_hd.cc
index c7f0ef4..eb3dbbb 100644
--- a/btif/src/btif_hd.cc
+++ b/btif/src/btif_hd.cc
@@ -53,8 +53,8 @@
 #define COD_HID_COMBO 0x05C0
 #define COD_HID_MAJOR 0x0500
 
-extern bool bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr);
-extern bool check_cod_hid(const bt_bdaddr_t* remote_bdaddr);
+extern bool bta_dm_check_if_only_hd_connected(const RawAddress& peer_addr);
+extern bool check_cod_hid(const RawAddress* remote_bdaddr);
 extern void btif_hh_service_registration(bool enable);
 
 /* HD request events */
@@ -123,8 +123,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btif_hd_remove_device(bt_bdaddr_t bd_addr) {
-  BTA_HdRemoveDevice((uint8_t*)&bd_addr);
+void btif_hd_remove_device(RawAddress bd_addr) {
+  BTA_HdRemoveDevice(bd_addr);
   btif_storage_remove_hidd(&bd_addr);
 }
 
@@ -176,7 +176,7 @@
       break;
 
     case BTA_HD_REGISTER_APP_EVT: {
-      bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->reg_status.bda;
+      RawAddress* addr = (RawAddress*)&p_data->reg_status.bda;
 
       if (!p_data->reg_status.in_use) {
         addr = NULL;
@@ -199,7 +199,7 @@
       break;
 
     case BTA_HD_OPEN_EVT: {
-      bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->conn.bda;
+      RawAddress* addr = (RawAddress*)&p_data->conn.bda;
       BTIF_TRACE_WARNING(
           "BTA_HD_OPEN_EVT, address (%02x:%02x:%02x:%02x:%02x:%02x)",
           addr->address[0], addr->address[1], addr->address[2],
@@ -212,22 +212,22 @@
         BTA_HdDisconnect();
         break;
       }
-      btif_storage_set_hidd((bt_bdaddr_t*)&p_data->conn.bda);
+      btif_storage_set_hidd((RawAddress*)&p_data->conn.bda);
 
       HAL_CBACK(bt_hd_callbacks, connection_state_cb,
-                (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_CONNECTED);
+                (RawAddress*)&p_data->conn.bda, BTHD_CONN_STATE_CONNECTED);
     } break;
 
     case BTA_HD_CLOSE_EVT:
       if (btif_hd_cb.forced_disc) {
-        bt_bdaddr_t* addr = (bt_bdaddr_t*)&p_data->conn.bda;
+        RawAddress* addr = (RawAddress*)&p_data->conn.bda;
         BTIF_TRACE_WARNING("remote device was forcefully disconnected");
         btif_hd_remove_device(*addr);
         btif_hd_cb.forced_disc = FALSE;
         break;
       }
       HAL_CBACK(bt_hd_callbacks, connection_state_cb,
-                (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED);
+                (RawAddress*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED);
       break;
 
     case BTA_HD_GET_REPORT_EVT:
@@ -252,13 +252,13 @@
 
     case BTA_HD_VC_UNPLUG_EVT:
       HAL_CBACK(bt_hd_callbacks, connection_state_cb,
-                (bt_bdaddr_t*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED);
+                (RawAddress*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED);
       if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) {
         BTIF_TRACE_DEBUG("%s: Removing bonding as only HID profile connected",
                          __func__);
-        BTA_DmRemoveDevice((uint8_t*)&p_data->conn.bda);
+        BTA_DmRemoveDevice(p_data->conn.bda);
       } else {
-        bt_bdaddr_t* bd_addr = (bt_bdaddr_t*)&p_data->conn.bda;
+        RawAddress* bd_addr = (RawAddress*)&p_data->conn.bda;
         BTIF_TRACE_DEBUG(
             "%s: Only removing HID data as some other profiles "
             "connected",
@@ -270,7 +270,7 @@
 
     case BTA_HD_CONN_STATE_EVT:
       HAL_CBACK(bt_hd_callbacks, connection_state_cb,
-                (bt_bdaddr_t*)&p_data->conn.bda,
+                (RawAddress*)&p_data->conn.bda,
                 (bthd_connection_state_t)p_data->conn.status);
       break;
 
@@ -477,7 +477,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t connect(bt_bdaddr_t* bd_addr) {
+static bt_status_t connect(RawAddress* bd_addr) {
   BTIF_TRACE_API("%s", __func__);
 
   if (!btif_hd_cb.app_registered) {
@@ -491,7 +491,7 @@
     return BT_STATUS_NOT_READY;
   }
 
-  BTA_HdConnect(bd_addr->address);
+  BTA_HdConnect(*bd_addr);
 
   return BT_STATUS_SUCCESS;
 }
diff --git a/btif/src/btif_hf.cc b/btif/src/btif_hf.cc
index 765ad21..9ec6da8 100644
--- a/btif/src/btif_hf.cc
+++ b/btif/src/btif_hf.cc
@@ -36,7 +36,6 @@
 
 #include "bta/include/utl.h"
 #include "bta_ag_api.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "btif_hf.h"
 #include "btif_profile_queue.h"
@@ -126,7 +125,7 @@
 /* BTIF-HF control block to map bdaddr to BTA handle */
 typedef struct _btif_hf_cb {
   uint16_t handle;
-  bt_bdaddr_t connected_bda;
+  RawAddress connected_bda;
   bthf_connection_state_t state;
   bthf_vr_state_t vr_state;
   tBTA_AG_PEER_FEAT peer_feat;
@@ -147,9 +146,9 @@
  *  Externs
  ******************************************************************************/
 /* By default, even though codec negotiation is enabled, we will not use WBS as
-* the default
-* codec unless this variable is set to true.
-*/
+ * the default
+ * codec unless this variable is set to true.
+ */
 #ifndef BTIF_HF_WBS_PREFERRED
 #define BTIF_HF_WBS_PREFERRED false
 #endif
@@ -169,13 +168,12 @@
  * Returns          true if connected
  *
  ******************************************************************************/
-static bool is_connected(bt_bdaddr_t* bd_addr) {
+static bool is_connected(RawAddress* bd_addr) {
   int i;
   for (i = 0; i < btif_max_hf_clients; ++i) {
     if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
          (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)) &&
-        ((bd_addr == NULL) ||
-         (bdcmp(bd_addr->address, btif_hf_cb[i].connected_bda.address) == 0)))
+        (!bd_addr || *bd_addr == btif_hf_cb[i].connected_bda))
       return true;
   }
   return false;
@@ -190,11 +188,10 @@
  * Returns          idx
  *
  ******************************************************************************/
-static int btif_hf_idx_by_bdaddr(bt_bdaddr_t* bd_addr) {
+static int btif_hf_idx_by_bdaddr(RawAddress* bd_addr) {
   int i;
   for (i = 0; i < btif_max_hf_clients; ++i) {
-    if ((bdcmp(bd_addr->address, btif_hf_cb[i].connected_bda.address) == 0))
-      return i;
+    if (*bd_addr == btif_hf_cb[i].connected_bda) return i;
   }
   return BTIF_HF_INVALID_IDX;
 }
@@ -338,7 +335,6 @@
  ******************************************************************************/
 static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
   tBTA_AG* p_data = (tBTA_AG*)p_param;
-  bdstr_t bdstr;
   int idx = p_data->hdr.handle - 1;
 
   BTIF_TRACE_DEBUG("%s: event=%s", __func__, dump_hf_event(event));
@@ -363,7 +359,7 @@
 
     case BTA_AG_OPEN_EVT:
       if (p_data->open.status == BTA_AG_SUCCESS) {
-        bdcpy(btif_hf_cb[idx].connected_bda.address, p_data->open.bd_addr);
+        btif_hf_cb[idx].connected_bda = p_data->open.bd_addr;
         btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_CONNECTED;
         btif_hf_cb[idx].peer_feat = 0;
         clear_phone_state_multihf(idx);
@@ -374,8 +370,7 @@
             "%s: AG open failed, but another device connected. status=%d "
             "state=%d connected device=%s",
             __func__, p_data->open.status, btif_hf_cb[idx].state,
-            bdaddr_to_string(&btif_hf_cb[idx].connected_bda, bdstr,
-                             sizeof(bdstr)));
+            btif_hf_cb[idx].connected_bda.ToString().c_str());
         break;
       }
 
@@ -383,7 +378,7 @@
                 &btif_hf_cb[idx].connected_bda);
 
       if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_DISCONNECTED)
-        bdsetany(btif_hf_cb[idx].connected_bda.address);
+        btif_hf_cb[idx].connected_bda = RawAddress::kAny;
 
       if (p_data->open.status != BTA_AG_SUCCESS) btif_queue_advance();
       break;
@@ -397,14 +392,14 @@
           __func__, idx, btif_hf_cb[idx].handle);
       HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
                 &btif_hf_cb[idx].connected_bda);
-      bdsetany(btif_hf_cb[idx].connected_bda.address);
+      btif_hf_cb[idx].connected_bda = RawAddress::kAny;
       btif_hf_cb[idx].peer_feat = 0;
       clear_phone_state_multihf(idx);
       hf_idx = btif_hf_latest_connected_idx();
       /* If AG_OPEN was received but SLC was not setup in a specified time (10
-      *seconds),
-      ** then AG_CLOSE may be received. We need to advance the queue here
-      */
+       *seconds),
+       ** then AG_CLOSE may be received. We need to advance the queue here
+       */
       btif_queue_advance();
       break;
 
@@ -643,7 +638,7 @@
  *
  ******************************************************************************/
 static void btif_in_hf_generic_evt(uint16_t event, char* p_param) {
-  int idx = btif_hf_idx_by_bdaddr((bt_bdaddr_t*)p_param);
+  int idx = btif_hf_idx_by_bdaddr((RawAddress*)p_param);
 
   BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
 
@@ -704,7 +699,7 @@
  * Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled
  * (phone)
  * othwerwise only HSP is enabled (tablet)
-*/
+ */
 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
   btif_enable_service(BTA_HFP_SERVICE_ID);
 #else
@@ -725,7 +720,7 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t connect_int(bt_bdaddr_t* bd_addr, uint16_t uuid) {
+static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) {
   CHECK_BTHF_INIT();
   int i;
   for (i = 0; i < btif_max_hf_clients;) {
@@ -740,9 +735,9 @@
 
   if (!is_connected(bd_addr)) {
     btif_hf_cb[i].state = BTHF_CONNECTION_STATE_CONNECTING;
-    bdcpy(btif_hf_cb[i].connected_bda.address, bd_addr->address);
+    btif_hf_cb[i].connected_bda = *bd_addr;
 
-    BTA_AgOpen(btif_hf_cb[i].handle, btif_hf_cb[i].connected_bda.address,
+    BTA_AgOpen(btif_hf_cb[i].handle, btif_hf_cb[i].connected_bda,
                BTIF_HF_SECURITY, BTIF_HF_SERVICES);
     return BT_STATUS_SUCCESS;
   }
@@ -750,7 +745,7 @@
   return BT_STATUS_BUSY;
 }
 
-static bt_status_t connect(bt_bdaddr_t* bd_addr) {
+static bt_status_t connect(RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
   return btif_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_int);
 }
@@ -764,7 +759,7 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t disconnect(bt_bdaddr_t* bd_addr) {
+static bt_status_t disconnect(RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -791,7 +786,7 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t connect_audio(bt_bdaddr_t* bd_addr) {
+static bt_status_t connect_audio(RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -811,7 +806,7 @@
     /* Inform the application that the audio connection has been initiated
      * successfully */
     btif_transfer_context(btif_in_hf_generic_evt, BTIF_HFP_CB_AUDIO_CONNECTING,
-                          (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+                          (char*)bd_addr, sizeof(RawAddress), NULL);
     return BT_STATUS_SUCCESS;
   }
 
@@ -827,7 +822,7 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t disconnect_audio(bt_bdaddr_t* bd_addr) {
+static bt_status_t disconnect_audio(RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -854,7 +849,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t start_voice_recognition(bt_bdaddr_t* bd_addr) {
+static bt_status_t start_voice_recognition(RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -889,7 +884,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t stop_voice_recognition(bt_bdaddr_t* bd_addr) {
+static bt_status_t stop_voice_recognition(RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -925,7 +920,7 @@
  *
  ******************************************************************************/
 static bt_status_t volume_control(bthf_volume_type_t type, int volume,
-                                  bt_bdaddr_t* bd_addr) {
+                                  RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -988,7 +983,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t cops_response(const char* cops, bt_bdaddr_t* bd_addr) {
+static bt_status_t cops_response(const char* cops, RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -1022,7 +1017,7 @@
  ******************************************************************************/
 static bt_status_t cind_response(int svc, int num_active, int num_held,
                                  bthf_call_state_t call_setup_state, int signal,
-                                 int roam, int batt_chg, bt_bdaddr_t* bd_addr) {
+                                 int roam, int batt_chg, RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -1037,9 +1032,9 @@
 
     memset(&ag_res, 0, sizeof(ag_res));
     /* per the errata 2043, call=1 implies atleast one call is in progress
-    *(active/held)
-    ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
-    **/
+     *(active/held)
+     ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
+     **/
     snprintf(
         ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d,%d,%d",
         (num_active + num_held) ? 1 : 0,          /* Call state */
@@ -1069,7 +1064,7 @@
  ******************************************************************************/
 static bt_status_t bind_response(bthf_hf_ind_type_t ind_id,
                                  bthf_hf_ind_status_t ind_status,
-                                 bt_bdaddr_t* bd_addr) {
+                                 RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int index = btif_hf_idx_by_bdaddr(bd_addr);
@@ -1085,6 +1080,13 @@
   return BT_STATUS_SUCCESS;
 }
 
+static bt_status_t set_sco_allowed(bool value) {
+  CHECK_BTHF_INIT();
+
+  BTA_AgSetScoAllowed(value);
+  return BT_STATUS_SUCCESS;
+}
+
 /*******************************************************************************
  *
  * Function         formatted_at_response
@@ -1095,8 +1097,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t formatted_at_response(const char* rsp,
-                                         bt_bdaddr_t* bd_addr) {
+static bt_status_t formatted_at_response(const char* rsp, RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
   tBTA_AG_RES_DATA ag_res;
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -1128,7 +1129,7 @@
  *
  ******************************************************************************/
 static bt_status_t at_response(bthf_at_response_t response_code, int error_code,
-                               bt_bdaddr_t* bd_addr) {
+                               RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -1164,7 +1165,7 @@
                                  bthf_call_state_t state, bthf_call_mode_t mode,
                                  bthf_call_mpty_type_t mpty, const char* number,
                                  bthf_call_addrtype_t type,
-                                 bt_bdaddr_t* bd_addr) {
+                                 RawAddress* bd_addr) {
   CHECK_BTHF_INIT();
 
   int idx = btif_hf_idx_by_bdaddr(bd_addr);
@@ -1397,10 +1398,10 @@
   memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
 
   /* per the errata 2043, call=1 implies atleast one call is in progress
-  *(active/held)
-  ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
-  ** Handle call indicator change
-  **/
+   *(active/held)
+   ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
+   ** Handle call indicator change
+   **/
   if (!activeCallUpdated &&
       ((num_active + num_held) !=
        (btif_hf_cb[idx].num_active + btif_hf_cb[idx].num_held))) {
@@ -1515,7 +1516,7 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t configure_wbs(bt_bdaddr_t* bd_addr,
+static bt_status_t configure_wbs(RawAddress* bd_addr,
                                  bthf_wbs_config_t config) {
   CHECK_BTHF_INIT();
 
@@ -1557,6 +1558,7 @@
     cleanup,
     configure_wbs,
     bind_response,
+    set_sco_allowed,
 };
 
 /*******************************************************************************
diff --git a/btif/src/btif_hf_client.cc b/btif/src/btif_hf_client.cc
index 0de1c7e..c1f3c8b 100644
--- a/btif/src/btif_hf_client.cc
+++ b/btif/src/btif_hf_client.cc
@@ -52,7 +52,6 @@
 
 #include "bt_utils.h"
 #include "bta_hf_client_api.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "btif_profile_queue.h"
 #include "btif_util.h"
@@ -84,7 +83,7 @@
 /* BTIF-HF control block to map bdaddr to BTA handle */
 typedef struct {
   uint16_t handle;                       // Handle obtained frm the BTA
-  bt_bdaddr_t peer_bda;                  // Device corresponding to handle
+  RawAddress peer_bda;                   // Device corresponding to handle
   bthf_client_connection_state_t state;  // State of current connection
   tBTA_HF_CLIENT_PEER_FEAT peer_feat;    // HF features
   tBTA_HF_CLIENT_CHLD_FEAT chld_feat;    // AT+CHLD=<> command features
@@ -100,7 +99,7 @@
  * Local function declarations
  ******************************************************************************/
 btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle);
-btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const uint8_t* addr);
+btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& addr);
 bool is_connected(const btif_hf_client_cb_t* cb);
 
 /*******************************************************************************
@@ -153,8 +152,8 @@
  ******************************************************************************/
 static void btif_in_hf_client_generic_evt(uint16_t event, char* p_param) {
   BTIF_TRACE_DEBUG("%s", __func__);
-  bt_bdaddr_t* bd_addr = (bt_bdaddr_t*)p_param;
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+  RawAddress* bd_addr = (RawAddress*)p_param;
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) {
     BTIF_TRACE_ERROR("%s: failed to find block for bda", __func__);
   }
@@ -215,16 +214,14 @@
  * Returns         btif_hf_client_cb_t pointer if available NULL otherwise
  *
  ******************************************************************************/
-btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const uint8_t* bd_addr) {
-  BTIF_TRACE_DEBUG("%s incoming addr %02x:%02x:%02x:%02x:%02x:%02x", __func__,
-                   bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-                   bd_addr[5]);
+btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& bd_addr) {
+  VLOG(1) << __func__ << " incoming addr " << bd_addr;
 
   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
     // Block is valid only if it is allocated i.e. state is not DISCONNECTED
     if (btif_hf_client_cb_arr.cb[i].state !=
             BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED &&
-        !bdcmp(btif_hf_client_cb_arr.cb[i].peer_bda.address, bd_addr)) {
+        btif_hf_client_cb_arr.cb[i].peer_bda == bd_addr) {
       return &btif_hf_client_cb_arr.cb[i];
     }
   }
@@ -252,7 +249,6 @@
   return NULL;
 }
 
-
 /*****************************************************************************
  *
  *   btif hf api functions (no context switch)
@@ -289,29 +285,29 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t connect_int(bt_bdaddr_t* bd_addr, uint16_t uuid) {
+static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) {
   btif_hf_client_cb_t* cb = btif_hf_client_allocate_cb();
   if (cb == NULL) {
     BTIF_TRACE_ERROR("%s: could not allocate block!", __func__);
     return BT_STATUS_BUSY;
   }
 
-  bdcpy(cb->peer_bda.address, bd_addr->address);
+  cb->peer_bda = *bd_addr;
   if (is_connected(cb)) return BT_STATUS_BUSY;
 
   cb->state = BTHF_CLIENT_CONNECTION_STATE_CONNECTING;
-  bdcpy(cb->peer_bda.address, bd_addr->address);
+  cb->peer_bda = *bd_addr;
 
   /* Open HF connection to remote device and get the relevant handle.
    * The handle is valid until we have called BTA_HfClientClose or the LL
    * has notified us of channel close due to remote closing, error etc.
    */
-  BTA_HfClientOpen(cb->peer_bda.address, BTIF_HF_CLIENT_SECURITY, &cb->handle);
+  BTA_HfClientOpen(cb->peer_bda, BTIF_HF_CLIENT_SECURITY, &cb->handle);
 
   return BT_STATUS_SUCCESS;
 }
 
-static bt_status_t connect(bt_bdaddr_t* bd_addr) {
+static bt_status_t connect(RawAddress* bd_addr) {
   BTIF_TRACE_EVENT("HFP Client version is  %s", btif_hf_client_version);
   CHECK_BTHF_CLIENT_INIT();
   return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
@@ -326,10 +322,10 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t disconnect(const bt_bdaddr_t* bd_addr) {
+static bt_status_t disconnect(const RawAddress* bd_addr) {
   CHECK_BTHF_CLIENT_INIT();
 
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb != NULL) {
     BTA_HfClientClose(cb->handle);
     return BT_STATUS_SUCCESS;
@@ -347,8 +343,8 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t connect_audio(const bt_bdaddr_t* bd_addr) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t connect_audio(const RawAddress* bd_addr) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -364,7 +360,7 @@
    * successfully */
   btif_transfer_context(btif_in_hf_client_generic_evt,
                         BTIF_HF_CLIENT_CB_AUDIO_CONNECTING, (char*)bd_addr,
-                        sizeof(bt_bdaddr_t), NULL);
+                        sizeof(RawAddress), NULL);
   return BT_STATUS_SUCCESS;
 }
 
@@ -377,8 +373,8 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t disconnect_audio(const bt_bdaddr_t* bd_addr) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t disconnect_audio(const RawAddress* bd_addr) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -396,8 +392,8 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t start_voice_recognition(const bt_bdaddr_t* bd_addr) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t start_voice_recognition(const RawAddress* bd_addr) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -418,8 +414,8 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t stop_voice_recognition(const bt_bdaddr_t* bd_addr) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t stop_voice_recognition(const RawAddress* bd_addr) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -440,9 +436,9 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t volume_control(const bt_bdaddr_t* bd_addr,
+static bt_status_t volume_control(const RawAddress* bd_addr,
                                   bthf_client_volume_type_t type, int volume) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -470,9 +466,9 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t dial(UNUSED_ATTR const bt_bdaddr_t* bd_addr,
+static bt_status_t dial(UNUSED_ATTR const RawAddress* bd_addr,
                         const char* number) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -494,8 +490,8 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t dial_memory(const bt_bdaddr_t* bd_addr, int location) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t dial_memory(const RawAddress* bd_addr, int location) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -513,10 +509,10 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t handle_call_action(const bt_bdaddr_t* bd_addr,
+static bt_status_t handle_call_action(const RawAddress* bd_addr,
                                       bthf_client_call_action_t action,
                                       int idx) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -603,8 +599,8 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t query_current_calls(UNUSED_ATTR const bt_bdaddr_t* bd_addr) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t query_current_calls(UNUSED_ATTR const RawAddress* bd_addr) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -626,8 +622,8 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t query_current_operator_name(const bt_bdaddr_t* bd_addr) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t query_current_operator_name(const RawAddress* bd_addr) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -645,8 +641,8 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t retrieve_subscriber_info(const bt_bdaddr_t* bd_addr) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t retrieve_subscriber_info(const RawAddress* bd_addr) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -664,8 +660,8 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t send_dtmf(const bt_bdaddr_t* bd_addr, char code) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t send_dtmf(const RawAddress* bd_addr, char code) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -683,8 +679,8 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t request_last_voice_tag_number(const bt_bdaddr_t* bd_addr) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+static bt_status_t request_last_voice_tag_number(const RawAddress* bd_addr) {
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -724,9 +720,9 @@
  * Returns          bt_status_t
  *
  ******************************************************************************/
-static bt_status_t send_at_cmd(const bt_bdaddr_t* bd_addr, int cmd, int val1,
+static bt_status_t send_at_cmd(const RawAddress* bd_addr, int cmd, int val1,
                                int val2, const char* arg) {
-  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(bd_addr->address);
+  btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
   if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
 
   CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
@@ -817,7 +813,6 @@
  ******************************************************************************/
 static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) {
   tBTA_HF_CLIENT* p_data = (tBTA_HF_CLIENT*)p_param;
-  bdstr_t bdstr;
 
   btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(p_data->bd_addr);
   if (cb == NULL && event == BTA_HF_CLIENT_OPEN_EVT) {
@@ -825,7 +820,7 @@
                      __func__);
     cb = btif_hf_client_allocate_cb();
     cb->handle = p_data->open.handle;
-    bdcpy(cb->peer_bda.address, p_data->open.bd_addr);
+    cb->peer_bda = p_data->open.bd_addr;
   } else if (cb == NULL) {
     BTIF_TRACE_ERROR("%s: event %d but not allocating block: cb not found",
                      __func__, event);
@@ -848,7 +843,7 @@
             "%s: HF CLient open failed, but another device connected. "
             "status=%d state=%d connected device=%s",
             __func__, p_data->open.status, cb->state,
-            bdaddr_to_string(&cb->peer_bda, bdstr, sizeof(bdstr)));
+            cb->peer_bda.ToString().c_str());
         break;
       }
 
@@ -857,7 +852,7 @@
                 0 /* AT+CHLD feat */);
 
       if (cb->state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
-        bdsetany(cb->peer_bda.address);
+        cb->peer_bda = RawAddress::kAny;
 
       if (p_data->open.status != BTA_HF_CLIENT_SUCCESS) btif_queue_advance();
       break;
@@ -883,7 +878,7 @@
       cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
       HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, &cb->peer_bda,
                 cb->state, 0, 0);
-      bdsetany(cb->peer_bda.address);
+      cb->peer_bda = RawAddress::kAny;
       cb->peer_feat = 0;
       cb->chld_feat = 0;
       btif_queue_advance();
diff --git a/btif/src/btif_hh.cc b/btif/src/btif_hh.cc
index eac9eeb..7c7352e 100644
--- a/btif/src/btif_hh.cc
+++ b/btif/src/btif_hh.cc
@@ -38,7 +38,6 @@
 
 #include "bt_common.h"
 #include "bta_api.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "btif_storage.h"
 #include "btif_util.h"
@@ -67,7 +66,6 @@
 #define LOGITECH_KB_MX5500_VENDOR_ID 0x046D
 #define LOGITECH_KB_MX5500_PRODUCT_ID 0xB30B
 
-extern fixed_queue_t* btu_general_alarm_queue;
 extern const int BT_UID;
 extern const int BT_GID;
 static int btif_hh_keylockstates = 0;  // The current key state of each key
@@ -138,17 +136,17 @@
  ******************************************************************************/
 extern void bta_hh_co_destroy(int fd);
 extern void bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len);
-extern bt_status_t btif_dm_remove_bond(const bt_bdaddr_t* bd_addr);
+extern bt_status_t btif_dm_remove_bond(const RawAddress* bd_addr);
 extern void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev,
                                     const char* dev_name, uint16_t vendor_id,
                                     uint16_t product_id, uint16_t version,
                                     uint8_t ctry_code, int dscp_len,
                                     uint8_t* p_dscp);
-extern bool check_cod(const bt_bdaddr_t* remote_bdaddr, uint32_t cod);
-extern void btif_dm_cb_remove_bond(bt_bdaddr_t* bd_addr);
-extern bool check_cod_hid(const bt_bdaddr_t* remote_bdaddr);
+extern bool check_cod(const RawAddress* remote_bdaddr, uint32_t cod);
+extern void btif_dm_cb_remove_bond(const RawAddress* bd_addr);
+extern bool check_cod_hid(const RawAddress* remote_bdaddr);
 extern int scru_ascii_2_hex(char* p_ascii, int len, uint8_t* p_hex);
-extern void btif_dm_hh_open_failed(bt_bdaddr_t* bdaddr);
+extern void btif_dm_hh_open_failed(RawAddress* bdaddr);
 extern void btif_hd_service_registration();
 
 /*****************************************************************************
@@ -265,7 +263,6 @@
  ******************************************************************************/
 static void update_keyboard_lockstates(btif_hh_device_t* p_dev) {
   uint8_t len = 2; /* reportid + 1 byte report*/
-  BD_ADDR* bda;
   BT_HDR* p_buf;
   uint8_t data[] = {0x01, /* report id */
                     static_cast<uint8_t>(btif_hh_keylockstates)}; /* keystate */
@@ -278,8 +275,7 @@
   p_buf = create_pbuf(len, data);
   if (p_buf != NULL) {
     p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
-    bda = (BD_ADDR*)(&p_dev->bd_addr);
-    BTA_HhSendData(p_dev->dev_handle, *bda, p_buf);
+    BTA_HhSendData(p_dev->dev_handle, p_dev->bd_addr, p_buf);
   }
 }
 
@@ -346,15 +342,15 @@
  *
  * Function         btif_hh_find_dev_by_bda
  *
- * Description      Return the device pointer of the specified bt_bdaddr_t.
+ * Description      Return the device pointer of the specified RawAddress.
  *
  * Returns          Device entry pointer in the device table
  ******************************************************************************/
-static btif_hh_device_t* btif_hh_find_dev_by_bda(bt_bdaddr_t* bd_addr) {
+static btif_hh_device_t* btif_hh_find_dev_by_bda(const RawAddress& bd_addr) {
   uint32_t i;
   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
     if (btif_hh_cb.devices[i].dev_status != BTHH_CONN_STATE_UNKNOWN &&
-        memcmp(&(btif_hh_cb.devices[i].bd_addr), bd_addr, BD_ADDR_LEN) == 0) {
+        btif_hh_cb.devices[i].bd_addr == bd_addr) {
       return &btif_hh_cb.devices[i];
     }
   }
@@ -366,16 +362,16 @@
  * Function         btif_hh_find_connected_dev_by_bda
  *
  * Description      Return the connected device pointer of the specified
- *                  bt_bdaddr_t.
+ *                  RawAddress.
  *
  * Returns          Device entry pointer in the device table
  ******************************************************************************/
 static btif_hh_device_t* btif_hh_find_connected_dev_by_bda(
-    bt_bdaddr_t* bd_addr) {
+    const RawAddress& bd_addr) {
   uint32_t i;
   for (i = 0; i < BTIF_HH_MAX_HID; i++) {
     if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED &&
-        memcmp(&(btif_hh_cb.devices[i].bd_addr), bd_addr, BD_ADDR_LEN) == 0) {
+        btif_hh_cb.devices[i].bd_addr == bd_addr) {
       return &btif_hh_cb.devices[i];
     }
   }
@@ -390,8 +386,8 @@
  *
  * Returns      void
  ******************************************************************************/
-void btif_hh_stop_vup_timer(bt_bdaddr_t* bd_addr) {
-  btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+void btif_hh_stop_vup_timer(RawAddress* bd_addr) {
+  btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
 
   if (p_dev != NULL) {
     BTIF_TRACE_DEBUG("stop VUP timer");
@@ -407,16 +403,16 @@
  *
  * Returns      void
  ******************************************************************************/
-void btif_hh_start_vup_timer(bt_bdaddr_t* bd_addr) {
+void btif_hh_start_vup_timer(const RawAddress* bd_addr) {
   BTIF_TRACE_DEBUG("%s", __func__);
 
-  btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   CHECK(p_dev != NULL);
 
   alarm_free(p_dev->vup_timer);
   p_dev->vup_timer = alarm_new("btif_hh.vup_timer");
-  alarm_set_on_queue(p_dev->vup_timer, BTIF_TIMEOUT_VUP_MS,
-                     btif_hh_timer_timeout, p_dev, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_dev->vup_timer, BTIF_TIMEOUT_VUP_MS,
+                     btif_hh_timer_timeout, p_dev);
 }
 
 /*******************************************************************************
@@ -427,28 +423,18 @@
  *
  * Returns          true if add successfully, otherwise false.
  ******************************************************************************/
-bool btif_hh_add_added_dev(bt_bdaddr_t bda, tBTA_HH_ATTR_MASK attr_mask) {
+bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask) {
   int i;
   for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
-    if (memcmp(&(btif_hh_cb.added_devices[i].bd_addr), &bda, BD_ADDR_LEN) ==
-        0) {
-      BTIF_TRACE_WARNING(" Device %02X:%02X:%02X:%02X:%02X:%02X already added",
-                         bda.address[0], bda.address[1], bda.address[2],
-                         bda.address[3], bda.address[4], bda.address[5]);
+    if (btif_hh_cb.added_devices[i].bd_addr == bda) {
+      LOG(WARNING) << " Device " << bda << " already added";
       return false;
     }
   }
   for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
-    if (btif_hh_cb.added_devices[i].bd_addr.address[0] == 0 &&
-        btif_hh_cb.added_devices[i].bd_addr.address[1] == 0 &&
-        btif_hh_cb.added_devices[i].bd_addr.address[2] == 0 &&
-        btif_hh_cb.added_devices[i].bd_addr.address[3] == 0 &&
-        btif_hh_cb.added_devices[i].bd_addr.address[4] == 0 &&
-        btif_hh_cb.added_devices[i].bd_addr.address[5] == 0) {
-      BTIF_TRACE_WARNING(" Added device %02X:%02X:%02X:%02X:%02X:%02X",
-                         bda.address[0], bda.address[1], bda.address[2],
-                         bda.address[3], bda.address[4], bda.address[5]);
-      memcpy(&(btif_hh_cb.added_devices[i].bd_addr), &bda, BD_ADDR_LEN);
+    if (btif_hh_cb.added_devices[i].bd_addr.IsEmpty()) {
+      LOG(WARNING) << " Added device " << bda;
+      btif_hh_cb.added_devices[i].bd_addr = bda;
       btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
       btif_hh_cb.added_devices[i].attr_mask = attr_mask;
       return true;
@@ -467,18 +453,16 @@
  **
  ** Returns          void
  ******************************************************************************/
-void btif_hh_remove_device(bt_bdaddr_t bd_addr) {
+void btif_hh_remove_device(RawAddress bd_addr) {
   int i;
   btif_hh_device_t* p_dev;
   btif_hh_added_device_t* p_added_dev;
 
-  LOG_INFO(LOG_TAG, "%s: bda = %02x:%02x:%02x:%02x:%02x:%02x", __func__,
-           bd_addr.address[0], bd_addr.address[1], bd_addr.address[2],
-           bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
+  LOG(INFO) << __func__ << ": bda = " << bd_addr;
 
   for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
     p_added_dev = &btif_hh_cb.added_devices[i];
-    if (memcmp(&(p_added_dev->bd_addr), &bd_addr, 6) == 0) {
+    if (p_added_dev->bd_addr == bd_addr) {
       BTA_HhRemoveDev(p_added_dev->dev_handle);
       btif_storage_remove_hid_info(&(p_added_dev->bd_addr));
       memset(&(p_added_dev->bd_addr), 0, 6);
@@ -487,12 +471,9 @@
     }
   }
 
-  p_dev = btif_hh_find_dev_by_bda(&bd_addr);
+  p_dev = btif_hh_find_dev_by_bda(bd_addr);
   if (p_dev == NULL) {
-    BTIF_TRACE_WARNING(
-        " Oops, can't find device [%02x:%02x:%02x:%02x:%02x:%02x]",
-        bd_addr.address[0], bd_addr.address[1], bd_addr.address[2],
-        bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]);
+    LOG(WARNING) << " Oops, can't find device " << bd_addr;
     return;
   }
 
@@ -549,14 +530,14 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_hh_virtual_unplug(bt_bdaddr_t* bd_addr) {
+bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr) {
   BTIF_TRACE_DEBUG("%s", __func__);
   btif_hh_device_t* p_dev;
   char bd_str[18];
   snprintf(bd_str, sizeof(bd_str), "%02X:%02X:%02X:%02X:%02X:%02X",
            bd_addr->address[0], bd_addr->address[1], bd_addr->address[2],
            bd_addr->address[3], bd_addr->address[4], bd_addr->address[5]);
-  p_dev = btif_hh_find_dev_by_bda(bd_addr);
+  p_dev = btif_hh_find_dev_by_bda(*bd_addr);
   if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) &&
       (p_dev->attr_mask & HID_VIRTUAL_CABLE)) {
     BTIF_TRACE_DEBUG("%s Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG", __func__);
@@ -581,18 +562,12 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_hh_connect(bt_bdaddr_t* bd_addr) {
-  btif_hh_device_t* dev;
+bt_status_t btif_hh_connect(const RawAddress* bd_addr) {
   btif_hh_added_device_t* added_dev = NULL;
-  char bda_str[20];
-  int i;
-  BD_ADDR* bda = (BD_ADDR*)bd_addr;
   CHECK_BTHH_INIT();
   BTIF_TRACE_EVENT("BTHH: %s", __func__);
-  dev = btif_hh_find_dev_by_bda(bd_addr);
-  snprintf(bda_str, sizeof(bda_str), "%02X:%02X:%02X:%02X:%02X:%02X", (*bda)[0],
-           (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
-  if (dev == NULL && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
+  btif_hh_device_t* dev = btif_hh_find_dev_by_bda(*bd_addr);
+  if (!dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) {
     // No space for more HID device now.
     BTIF_TRACE_WARNING(
         "%s: Error, exceeded the maximum supported HID device number %d",
@@ -600,21 +575,21 @@
     return BT_STATUS_FAIL;
   }
 
-  for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
-    if (memcmp(&(btif_hh_cb.added_devices[i].bd_addr), bd_addr, BD_ADDR_LEN) ==
-        0) {
+  for (int i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
+    if (btif_hh_cb.added_devices[i].bd_addr == *bd_addr) {
       added_dev = &btif_hh_cb.added_devices[i];
-      BTIF_TRACE_WARNING("%s: Device %s already added, attr_mask = 0x%x",
-                         __func__, bda_str, added_dev->attr_mask);
+      LOG(WARNING) << __func__ << ": Device " << *bd_addr
+                   << " already added, attr_mask = 0x" << std::hex
+                   << added_dev->attr_mask;
     }
   }
 
   if (added_dev != NULL) {
     if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) {
       // No space for more HID device now.
-      BTIF_TRACE_ERROR("%s: Error, device %s added but addition failed",
-                       __func__, bda_str);
-      memset(&(added_dev->bd_addr), 0, 6);
+      LOG(ERROR) << __func__ << ": Error, device " << *bd_addr
+                 << " added but addition failed";
+      added_dev->bd_addr = RawAddress::kEmpty;
       added_dev->dev_handle = BTA_HH_INVALID_HANDLE;
       return BT_STATUS_FAIL;
     }
@@ -627,9 +602,11 @@
    pagescan mode, we will do 2 retries to connect before giving up */
   tBTA_SEC sec_mask = BTUI_HH_SECURITY;
   btif_hh_cb.status = BTIF_HH_DEV_CONNECTING;
-  BTA_HhOpen(*bda, BTA_HH_PROTO_RPT_MODE, sec_mask);
+  BTA_HhOpen(*bd_addr, BTA_HH_PROTO_RPT_MODE, sec_mask);
 
-  HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr,
+  // TODO(jpawlowski); make cback accept const and remove tmp!
+  auto tmp = *bd_addr;
+  HAL_CBACK(bt_hh_callbacks, connection_state_cb, &tmp,
             BTHH_CONN_STATE_CONNECTING);
   return BT_STATUS_SUCCESS;
 }
@@ -644,9 +621,9 @@
  *
  ******************************************************************************/
 
-void btif_hh_disconnect(bt_bdaddr_t* bd_addr) {
+void btif_hh_disconnect(RawAddress* bd_addr) {
   btif_hh_device_t* p_dev;
-  p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   if (p_dev != NULL) {
     BTA_HhClose(p_dev->dev_handle);
   } else
@@ -784,12 +761,12 @@
           // HID device number.
           BTA_HhClose(p_data->conn.handle);
           HAL_CBACK(bt_hh_callbacks, connection_state_cb,
-                    (bt_bdaddr_t*)&p_data->conn.bda,
+                    (RawAddress*)&p_data->conn.bda,
                     BTHH_CONN_STATE_DISCONNECTED);
         } else if (p_dev->fd < 0) {
           BTIF_TRACE_WARNING(
               "BTA_HH_OPEN_EVT: Error, failed to find the uhid driver...");
-          memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN);
+          p_dev->bd_addr = p_data->conn.bda;
           // remove the connection  and then try again to reconnect from the
           // mouse side to recover
           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
@@ -799,11 +776,11 @@
               "BTA_HH_OPEN_EVT: Found device...Getting dscp info for handle "
               "... %d",
               p_data->conn.handle);
-          memcpy(&(p_dev->bd_addr), p_data->conn.bda, BD_ADDR_LEN);
+          p_dev->bd_addr = p_data->conn.bda;
           btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_CONNECTED;
           // Send set_idle if the peer_device is a keyboard
-          if (check_cod((bt_bdaddr_t*)p_data->conn.bda, COD_HID_KEYBOARD) ||
-              check_cod((bt_bdaddr_t*)p_data->conn.bda, COD_HID_COMBO))
+          if (check_cod(&p_data->conn.bda, COD_HID_KEYBOARD) ||
+              check_cod(&p_data->conn.bda, COD_HID_COMBO))
             BTA_HhSetIdle(p_data->conn.handle, 0);
           btif_hh_cb.p_curr_dev =
               btif_hh_find_connected_dev_by_handle(p_data->conn.handle);
@@ -813,9 +790,9 @@
                     p_dev->dev_status);
         }
       } else {
-        bt_bdaddr_t* bdaddr = (bt_bdaddr_t*)p_data->conn.bda;
+        RawAddress* bdaddr = &p_data->conn.bda;
         btif_dm_hh_open_failed(bdaddr);
-        p_dev = btif_hh_find_dev_by_bda(bdaddr);
+        p_dev = btif_hh_find_dev_by_bda(*bdaddr);
         if (p_dev != NULL) {
           btif_hh_stop_vup_timer(&(p_dev->bd_addr));
           if (p_dev->fd >= 0) {
@@ -825,8 +802,7 @@
           p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
         }
         HAL_CBACK(bt_hh_callbacks, connection_state_cb,
-                  (bt_bdaddr_t*)&p_data->conn.bda,
-                  BTHH_CONN_STATE_DISCONNECTED);
+                  (RawAddress*)&p_data->conn.bda, BTHH_CONN_STATE_DISCONNECTED);
         btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
       }
       break;
@@ -844,7 +820,7 @@
          */
         if (p_dev->local_vup) {
           p_dev->local_vup = false;
-          BTA_DmRemoveDevice((uint8_t*)p_dev->bd_addr.address);
+          BTA_DmRemoveDevice(p_dev->bd_addr);
         }
 
         btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
@@ -876,11 +852,11 @@
           data = (uint8_t*)(hdr + 1) + hdr->offset;
           len = hdr->len;
           HAL_CBACK(bt_hh_callbacks, get_report_cb,
-                    (bt_bdaddr_t*)&(p_dev->bd_addr),
+                    (RawAddress*)&(p_dev->bd_addr),
                     (bthh_status_t)p_data->hs_data.status, data, len);
         } else {
           HAL_CBACK(bt_hh_callbacks, handshake_cb,
-                    (bt_bdaddr_t*)&(p_dev->bd_addr),
+                    (RawAddress*)&(p_dev->bd_addr),
                     (bthh_status_t)p_data->hs_data.status);
         }
       } else {
@@ -895,8 +871,7 @@
                        p_data->dev_status.status, p_data->dev_status.handle);
       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
       if (p_dev != NULL) {
-        HAL_CBACK(bt_hh_callbacks, handshake_cb,
-                  (bt_bdaddr_t*)&(p_dev->bd_addr),
+        HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
                   (bthh_status_t)p_data->hs_data.status);
       }
       break;
@@ -914,12 +889,11 @@
                     : "Unsupported");
       if (p_data->hs_data.rsp_data.proto_mode != BTA_HH_PROTO_UNKNOWN) {
         HAL_CBACK(bt_hh_callbacks, protocol_mode_cb,
-                  (bt_bdaddr_t*)&(p_dev->bd_addr),
+                  (RawAddress*)&(p_dev->bd_addr),
                   (bthh_status_t)p_data->hs_data.status,
                   (bthh_protocol_mode_t)p_data->hs_data.rsp_data.proto_mode);
       } else {
-        HAL_CBACK(bt_hh_callbacks, handshake_cb,
-                  (bt_bdaddr_t*)&(p_dev->bd_addr),
+        HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
                   (bthh_status_t)p_data->hs_data.status);
       }
       break;
@@ -929,8 +903,7 @@
                        p_data->dev_status.status, p_data->dev_status.handle);
       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
       if (p_dev) {
-        HAL_CBACK(bt_hh_callbacks, handshake_cb,
-                  (bt_bdaddr_t*)&(p_dev->bd_addr),
+        HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr),
                   (bthh_status_t)p_data->hs_data.status);
       }
       break;
@@ -941,7 +914,7 @@
           p_data->hs_data.handle, p_data->hs_data.status,
           p_data->hs_data.rsp_data.idle_rate);
       p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle);
-      HAL_CBACK(bt_hh_callbacks, idle_time_cb, (bt_bdaddr_t*)&(p_dev->bd_addr),
+      HAL_CBACK(bt_hh_callbacks, idle_time_cb, (RawAddress*)&(p_dev->bd_addr),
                 (bthh_status_t)p_data->hs_data.status,
                 p_data->hs_data.rsp_data.idle_rate);
       break;
@@ -986,19 +959,12 @@
                                 p_data->dscp_info.ctry_code, len,
                                 p_data->dscp_info.descriptor.dsc_list);
         if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) {
-          BD_ADDR bda;
-          bdcpy(bda, p_dev->bd_addr.address);
           tBTA_HH_DEV_DSCP_INFO dscp_info;
           bt_status_t ret;
-          bdcpy(bda, p_dev->bd_addr.address);
           btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info);
-          BTIF_TRACE_DEBUG(
-              "BTA_HH_GET_DSCP_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x",
-              p_dev->bd_addr.address[0], p_dev->bd_addr.address[1],
-              p_dev->bd_addr.address[2], p_dev->bd_addr.address[3],
-              p_dev->bd_addr.address[4], p_dev->bd_addr.address[5]);
-          BTA_HhAddDev(bda, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id,
-                       dscp_info);
+          VLOG(1) << "BTA_HH_GET_DSCP_EVT:bda = " << p_dev->bd_addr;
+          BTA_HhAddDev(p_dev->bd_addr, p_dev->attr_mask, p_dev->sub_class,
+                       p_dev->app_id, dscp_info);
           // write hid info to nvram
           ret = btif_storage_add_hid_device_info(
               &(p_dev->bd_addr), p_dev->attr_mask, p_dev->sub_class,
@@ -1048,12 +1014,11 @@
                          p_data->dev_info.status, p_data->dev_info.handle);
       int i;
       for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) {
-        if (memcmp(btif_hh_cb.added_devices[i].bd_addr.address,
-                   p_data->dev_info.bda, 6) == 0) {
+        if (btif_hh_cb.added_devices[i].bd_addr == p_data->dev_info.bda) {
           if (p_data->dev_info.status == BTA_HH_OK) {
             btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle;
           } else {
-            memset(btif_hh_cb.added_devices[i].bd_addr.address, 0, 6);
+            btif_hh_cb.added_devices[i].bd_addr = RawAddress::kEmpty;
             btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE;
           }
           break;
@@ -1063,10 +1028,7 @@
     case BTA_HH_RMV_DEV_EVT:
       BTIF_TRACE_DEBUG("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d",
                        p_data->dev_info.status, p_data->dev_info.handle);
-      BTIF_TRACE_DEBUG("BTA_HH_RMV_DEV_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x",
-                       p_data->dev_info.bda[0], p_data->dev_info.bda[1],
-                       p_data->dev_info.bda[2], p_data->dev_info.bda[3],
-                       p_data->dev_info.bda[4], p_data->dev_info.bda[5]);
+      VLOG(1) << "BTA_HH_RMV_DEV_EVT:bda = " << p_data->dev_info.bda;
       break;
 
     case BTA_HH_VC_UNPLUG_EVT:
@@ -1075,11 +1037,8 @@
       p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle);
       btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
       if (p_dev != NULL) {
-        BTIF_TRACE_DEBUG(
-            "BTA_HH_VC_UNPLUG_EVT:bda = %02x:%02x:%02x:%02x:%02x:%02x",
-            p_dev->bd_addr.address[0], p_dev->bd_addr.address[1],
-            p_dev->bd_addr.address[2], p_dev->bd_addr.address[3],
-            p_dev->bd_addr.address[4], p_dev->bd_addr.address[5]);
+        VLOG(1) << "BTA_HH_VC_UNPLUG_EVT:bda = " << p_dev->bd_addr;
+
         /* Stop the VUP timer */
         btif_hh_stop_vup_timer(&(p_dev->bd_addr));
         p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
@@ -1091,7 +1050,7 @@
         Peripheral removed the bond.*/
         if (p_dev->local_vup || check_cod_hid(&(p_dev->bd_addr))) {
           p_dev->local_vup = false;
-          BTA_DmRemoveDevice((uint8_t*)p_dev->bd_addr.address);
+          BTA_DmRemoveDevice(p_dev->bd_addr);
         } else
           btif_hh_remove_device(p_dev->bd_addr);
         HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb, &(p_dev->bd_addr),
@@ -1163,7 +1122,7 @@
  ******************************************************************************/
 
 static void btif_hh_handle_evt(uint16_t event, char* p_param) {
-  bt_bdaddr_t* bd_addr = (bt_bdaddr_t*)p_param;
+  RawAddress* bd_addr = (RawAddress*)p_param;
   BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
   int ret;
   switch (event) {
@@ -1254,10 +1213,10 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t connect(bt_bdaddr_t* bd_addr) {
+static bt_status_t connect(RawAddress* bd_addr) {
   if (btif_hh_cb.status != BTIF_HH_DEV_CONNECTING) {
     btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT,
-                          (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+                          (char*)bd_addr, sizeof(RawAddress), NULL);
     return BT_STATUS_SUCCESS;
   } else
     return BT_STATUS_BUSY;
@@ -1272,7 +1231,7 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t disconnect(bt_bdaddr_t* bd_addr) {
+static bt_status_t disconnect(RawAddress* bd_addr) {
   CHECK_BTHH_INIT();
   BTIF_TRACE_EVENT("BTHH: %s", __func__);
   btif_hh_device_t* p_dev;
@@ -1282,10 +1241,10 @@
                        btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
-  p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   if (p_dev != NULL) {
     return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT,
-                                 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+                                 (char*)bd_addr, sizeof(RawAddress), NULL);
   } else {
     BTIF_TRACE_WARNING("%s: Error, device  not opened.", __func__);
     return BT_STATUS_FAIL;
@@ -1301,7 +1260,7 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t virtual_unplug(bt_bdaddr_t* bd_addr) {
+static bt_status_t virtual_unplug(RawAddress* bd_addr) {
   CHECK_BTHH_INIT();
   BTIF_TRACE_EVENT("BTHH: %s", __func__);
   btif_hh_device_t* p_dev;
@@ -1313,13 +1272,13 @@
     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
-  p_dev = btif_hh_find_dev_by_bda(bd_addr);
+  p_dev = btif_hh_find_dev_by_bda(*bd_addr);
   if (!p_dev) {
     BTIF_TRACE_ERROR("%s: Error, device %s not opened.", __func__, bd_str);
     return BT_STATUS_FAIL;
   }
   btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, (char*)bd_addr,
-                        sizeof(bt_bdaddr_t), NULL);
+                        sizeof(RawAddress), NULL);
   return BT_STATUS_SUCCESS;
 }
 
@@ -1332,19 +1291,17 @@
 ** Returns         bt_status_t
 **
 *******************************************************************************/
-static bt_status_t get_idle_time(bt_bdaddr_t* bd_addr) {
+static bt_status_t get_idle_time(RawAddress* bd_addr) {
   CHECK_BTHH_INIT();
 
-  char bdstr[20] = {0};
-  BTIF_TRACE_DEBUG("%s: addr = %s", __func__,
-                   bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)));
+  BTIF_TRACE_DEBUG("%s: addr = %s", __func__, bd_addr->ToString().c_str());
 
   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
 
-  btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   if (p_dev == NULL) return BT_STATUS_FAIL;
 
   BTA_HhGetIdle(p_dev->dev_handle);
@@ -1360,22 +1317,21 @@
 ** Returns         bt_status_t
 **
 *******************************************************************************/
-static bt_status_t set_idle_time(bt_bdaddr_t* bd_addr, uint8_t idle_time) {
+static bt_status_t set_idle_time(RawAddress* bd_addr, uint8_t idle_time) {
   CHECK_BTHH_INIT();
 
-  char bdstr[20] = {0};
   BTIF_TRACE_DEBUG("%s: addr = %s, idle time = %d", __func__,
-                   bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)), idle_time);
+                   bd_addr->ToString().c_str(), idle_time);
 
   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
 
-  btif_hh_device_t* p_dev = p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  btif_hh_device_t* p_dev = p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   if (p_dev == NULL) {
     BTIF_TRACE_WARNING("%s: addr = %s not opened", __func__,
-                       bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)));
+                       bd_addr->ToString().c_str());
     return BT_STATUS_FAIL;
   }
 
@@ -1392,14 +1348,11 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t set_info(bt_bdaddr_t* bd_addr, bthh_hid_info_t hid_info) {
+static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) {
   CHECK_BTHH_INIT();
   tBTA_HH_DEV_DSCP_INFO dscp_info;
-  BD_ADDR* bda = (BD_ADDR*)bd_addr;
 
-  BTIF_TRACE_DEBUG("BTHH: %s: addr = %02X:%02X:%02X:%02X:%02X:%02X", __func__,
-                   (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4],
-                   (*bda)[5]);
+  VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
   BTIF_TRACE_DEBUG(
       "BTHH: %s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, "
       "product_id = 0x%04x, version= 0x%04x",
@@ -1422,8 +1375,8 @@
   memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len);
 
   if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) {
-    BTA_HhAddDev(*bda, hid_info.attr_mask, hid_info.sub_class, hid_info.app_id,
-                 dscp_info);
+    BTA_HhAddDev(*bd_addr, hid_info.attr_mask, hid_info.sub_class,
+                 hid_info.app_id, dscp_info);
   }
 
   osi_free_and_reset((void**)&dscp_info.descriptor.dsc_list);
@@ -1440,27 +1393,21 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t get_protocol(bt_bdaddr_t* bd_addr,
+static bt_status_t get_protocol(RawAddress* bd_addr,
                                 UNUSED_ATTR bthh_protocol_mode_t protocolMode) {
   CHECK_BTHH_INIT();
-  btif_hh_device_t* p_dev;
-  BD_ADDR* bda = (BD_ADDR*)bd_addr;
 
-  BTIF_TRACE_DEBUG("BTHH: %s: addr = %02X:%02X:%02X:%02X:%02X:%02X", __func__,
-                   (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4],
-                   (*bda)[5]);
+  VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr;
 
   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
 
-  p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
-  if (p_dev != NULL) {
-    BTA_HhGetProtoMode(p_dev->dev_handle);
-  } else {
-    return BT_STATUS_FAIL;
-  }
+  btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
+  if (!p_dev) return BT_STATUS_FAIL;
+
+  BTA_HhGetProtoMode(p_dev->dev_handle);
   return BT_STATUS_SUCCESS;
 }
 
@@ -1473,29 +1420,23 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t set_protocol(bt_bdaddr_t* bd_addr,
+static bt_status_t set_protocol(RawAddress* bd_addr,
                                 bthh_protocol_mode_t protocolMode) {
   CHECK_BTHH_INIT();
   btif_hh_device_t* p_dev;
   uint8_t proto_mode = protocolMode;
-  BD_ADDR* bda = (BD_ADDR*)bd_addr;
 
-  BTIF_TRACE_DEBUG(
-      "BTHH: %s: proto_mode = %d"
-      " addr = %02X:%02X:%02X:%02X:%02X:%02X",
-      __func__, protocolMode, (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3],
-      (*bda)[4], (*bda)[5]);
+  VLOG(1) << __func__ << " BTHH: proto_mod=" << protocolMode
+          << " addr = " << *bd_addr;
 
   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
 
-  p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   if (p_dev == NULL) {
-    BTIF_TRACE_WARNING(
-        " Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", (*bda)[0],
-        (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
+    LOG(WARNING) << " Error, device" << *bd_addr << " not opened";
     return BT_STATUS_FAIL;
   } else if (protocolMode != BTA_HH_PROTO_RPT_MODE &&
              protocolMode != BTA_HH_PROTO_BOOT_MODE) {
@@ -1518,35 +1459,28 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t get_report(bt_bdaddr_t* bd_addr,
+static bt_status_t get_report(RawAddress* bd_addr,
                               bthh_report_type_t reportType, uint8_t reportId,
                               int bufferSize) {
   CHECK_BTHH_INIT();
   btif_hh_device_t* p_dev;
-  BD_ADDR* bda = (BD_ADDR*)bd_addr;
 
-  BTIF_TRACE_DEBUG(
-      "BTHH: %s: r_type = %d, rpt_id = %d, buf_size = %d"
-      " addr = %02X:%02X:%02X:%02X:%02X:%02X",
-      __func__, reportType, reportId, bufferSize, (*bda)[0], (*bda)[1],
-      (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
+  VLOG(1) << __func__ << " BTHH: r_type = " << reportType
+          << ", rpt_id = " << reportId << ", buf_size = " << bufferSize
+          << " addr = " << *bd_addr;
 
   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
 
-  p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   if (p_dev == NULL) {
-    BTIF_TRACE_ERROR(
-        "%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", __func__,
-        (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
+    LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
     return BT_STATUS_FAIL;
   } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
              ((int)reportType) > BTA_HH_RPTT_FEATURE) {
-    BTIF_TRACE_ERROR(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
-                     (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4],
-                     (*bda)[5]);
+    LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
     return BT_STATUS_FAIL;
   } else {
     BTA_HhGetReport(p_dev->dev_handle, reportType, reportId, bufferSize);
@@ -1564,34 +1498,26 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t set_report(bt_bdaddr_t* bd_addr,
+static bt_status_t set_report(RawAddress* bd_addr,
                               bthh_report_type_t reportType, char* report) {
   CHECK_BTHH_INIT();
   btif_hh_device_t* p_dev;
-  BD_ADDR* bda = (BD_ADDR*)bd_addr;
 
-  BTIF_TRACE_DEBUG(
-      "BTHH %s: reportType = %d"
-      " addr = %02X:%02X:%02X:%02X:%02X:%02X",
-      __func__, reportType, (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3],
-      (*bda)[4], (*bda)[5]);
+  VLOG(1) << __func__ << " BTHH: reportType=" << reportType
+          << " addr=" << *bd_addr;
 
   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
 
-  p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   if (p_dev == NULL) {
-    BTIF_TRACE_ERROR(
-        "%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", __func__,
-        (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
+    LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
     return BT_STATUS_FAIL;
   } else if (((int)reportType) <= BTA_HH_RPTT_RESRV ||
              ((int)reportType) > BTA_HH_RPTT_FEATURE) {
-    BTIF_TRACE_ERROR(" Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.",
-                     (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4],
-                     (*bda)[5]);
+    LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
     return BT_STATUS_FAIL;
   } else {
     int hex_bytes_filled;
@@ -1628,25 +1554,20 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t send_data(bt_bdaddr_t* bd_addr, char* data) {
+static bt_status_t send_data(RawAddress* bd_addr, char* data) {
   CHECK_BTHH_INIT();
   btif_hh_device_t* p_dev;
-  BD_ADDR* bda = (BD_ADDR*)bd_addr;
 
-  BTIF_TRACE_DEBUG("BTHH %s: addr = %02X:%02X:%02X:%02X:%02X:%02X", __func__,
-                   (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4],
-                   (*bda)[5]);
+  VLOG(1) << __func__ << " addr=" << *bd_addr;
 
   if (btif_hh_cb.status == BTIF_HH_DISABLED) {
     BTIF_TRACE_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status);
     return BT_STATUS_FAIL;
   }
 
-  p_dev = btif_hh_find_connected_dev_by_bda(bd_addr);
+  p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr);
   if (p_dev == NULL) {
-    BTIF_TRACE_ERROR(
-        "%s: Error, device %02X:%02X:%02X:%02X:%02X:%02X not opened.", __func__,
-        (*bda)[0], (*bda)[1], (*bda)[2], (*bda)[3], (*bda)[4], (*bda)[5]);
+    LOG(ERROR) << " Error, device" << *bd_addr << " not opened";
     return BT_STATUS_FAIL;
   }
 
@@ -1669,7 +1590,7 @@
         return BT_STATUS_FAIL;
       }
       p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
-      BTA_HhSendData(p_dev->dev_handle, *bda, p_buf);
+      BTA_HhSendData(p_dev->dev_handle, *bd_addr, p_buf);
       osi_free(hexbuf);
       return BT_STATUS_SUCCESS;
     }
diff --git a/btif/src/btif_hl.cc b/btif/src/btif_hl.cc
index c9214f1..c66b276 100644
--- a/btif/src/btif_hl.cc
+++ b/btif/src/btif_hl.cc
@@ -77,8 +77,6 @@
 extern void btif_hl_release_socket(uint8_t app_idx, uint8_t mcl_idx,
                                    uint8_t mdl_idx);
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 btif_hl_cb_t btif_hl_cb;
 btif_hl_cb_t* p_btif_hl_cb = &btif_hl_cb;
 
@@ -307,8 +305,8 @@
 
   alarm_free(p_mcb->cch_timer);
   p_mcb->cch_timer = alarm_new("btif_hl.mcl_cch_timer");
-  alarm_set_on_queue(p_mcb->cch_timer, BTIF_TIMEOUT_CCH_NO_DCH_MS,
-                     btif_hl_timer_timeout, p_mcb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_mcb->cch_timer, BTIF_TIMEOUT_CCH_NO_DCH_MS,
+                     btif_hl_timer_timeout, p_mcb);
 }
 
 /*******************************************************************************
@@ -573,8 +571,7 @@
     if (p_mdl->base.active && p_mdl->extra.data_type == data_type &&
         (p_mdl->extra.peer_mdep_id != BTA_HL_INVALID_MDEP_ID &&
          p_mdl->extra.peer_mdep_id == peer_mdep_id) &&
-        memcpy(p_mdl->base.peer_bd_addr, p_mcb->bd_addr, sizeof(BD_ADDR)) &&
-        p_mdl->base.mdl_id &&
+        p_mdl->base.peer_bd_addr != p_mcb->bd_addr && p_mdl->base.mdl_id &&
         !btif_hl_find_mdl_idx(app_idx, mcl_idx, p_mdl->base.mdl_id, &mdl_idx)) {
       BTIF_TRACE_DEBUG("i=%d Matched active=%d   mdl_id =%d, mdl_dch_mode=%d",
                        i, p_mdl->base.active, p_mdl->base.mdl_id,
@@ -594,8 +591,7 @@
           if (p_mdl1->base.active && p_mdl1->extra.data_type == data_type &&
               (p_mdl1->extra.peer_mdep_id != BTA_HL_INVALID_MDEP_ID &&
                p_mdl1->extra.peer_mdep_id == peer_mdep_id) &&
-              memcpy(p_mdl1->base.peer_bd_addr, p_mcb->bd_addr,
-                     sizeof(BD_ADDR)) &&
+              p_mdl1->base.peer_bd_addr != p_mcb->bd_addr &&
               p_mdl1->base.dch_mode == BTA_HL_DCH_MODE_STREAMING) {
             stream_mode_avail = true;
             BTIF_TRACE_DEBUG("found streaming mode mdl index=%d", j);
@@ -635,7 +631,7 @@
  * Returns      bool
  *
  ******************************************************************************/
-bool btif_hl_dch_open(uint8_t app_id, BD_ADDR bd_addr,
+bool btif_hl_dch_open(uint8_t app_id, const RawAddress& bd_addr,
                       tBTA_HL_DCH_OPEN_PARAM* p_dch_open_api, int mdep_cfg_idx,
                       btif_hl_pend_dch_op_t op, int* channel_id) {
   btif_hl_app_cb_t* p_acb;
@@ -647,8 +643,7 @@
   tBTA_HL_DCH_RECONNECT_PARAM reconnect_param;
 
   BTIF_TRACE_DEBUG("%s app_id=%d ", __func__, app_id);
-  BTIF_TRACE_DEBUG("DB [%02x:%02x:%02x:%02x:%02x:%02x]", bd_addr[0], bd_addr[1],
-                   bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
+  VLOG(0) << "DB " << bd_addr;
 
   if (btif_hl_find_app_idx(app_id, &app_idx)) {
     if (btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) {
@@ -663,7 +658,7 @@
             (int)btif_hl_get_next_channel_id(app_id);
         p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING;
         p_pcb->mdep_cfg_idx = mdep_cfg_idx;
-        memcpy(p_pcb->bd_addr, bd_addr, sizeof(BD_ADDR));
+        p_pcb->bd_addr = bd_addr;
         p_pcb->op = op;
 
         if (p_mcb->sdp.num_recs) {
@@ -698,36 +693,6 @@
   BTIF_TRACE_DEBUG("status=%d ", status);
   return status;
 }
-/*******************************************************************************
- *
- * Function      btif_hl_copy_bda
- *
- * Description  copy bt_bdaddr_t to BD_ADDR format
- *
- * Returns      void
- *
- ******************************************************************************/
-void btif_hl_copy_bda(bt_bdaddr_t* bd_addr, BD_ADDR bda) {
-  uint8_t i;
-  for (i = 0; i < 6; i++) {
-    bd_addr->address[i] = bda[i];
-  }
-}
-/*******************************************************************************
- *
- * Function      btif_hl_copy_bda
- *
- * Description  display bt_bdaddr_t
- *
- * Returns      bool
- *
- ******************************************************************************/
-void btif_hl_display_bt_bda(bt_bdaddr_t* bd_addr) {
-  BTIF_TRACE_DEBUG("DB [%02x:%02x:%02x:%02x:%02x:%02x]", bd_addr->address[0],
-                   bd_addr->address[1], bd_addr->address[2],
-                   bd_addr->address[3], bd_addr->address[4],
-                   bd_addr->address[5]);
-}
 
 /*******************************************************************************
  *
@@ -758,9 +723,9 @@
  * Returns     Nothing
  *
  ******************************************************************************/
-bool btif_hl_cch_open(uint8_t app_id, BD_ADDR bd_addr, uint16_t ctrl_psm,
-                      int mdep_cfg_idx, btif_hl_pend_dch_op_t op,
-                      int* channel_id) {
+bool btif_hl_cch_open(uint8_t app_id, const RawAddress& bd_addr,
+                      uint16_t ctrl_psm, int mdep_cfg_idx,
+                      btif_hl_pend_dch_op_t op, int* channel_id) {
   btif_hl_app_cb_t* p_acb;
   btif_hl_mcl_cb_t* p_mcb;
   btif_hl_pending_chan_cb_t* p_pcb;
@@ -769,8 +734,7 @@
 
   BTIF_TRACE_DEBUG("%s app_id=%d ctrl_psm=%d mdep_cfg_idx=%d op=%d", __func__,
                    app_id, ctrl_psm, mdep_cfg_idx, op);
-  BTIF_TRACE_DEBUG("DB [%02x:%02x:%02x:%02x:%02x:%02x]", bd_addr[0], bd_addr[1],
-                   bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
+  VLOG(1) << "DB " << bd_addr;
 
   if (btif_hl_find_app_idx(app_id, &app_idx)) {
     p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
@@ -781,7 +745,7 @@
         alarm_free(p_mcb->cch_timer);
         memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t));
         p_mcb->in_use = true;
-        bdcpy(p_mcb->bd_addr, bd_addr);
+        p_mcb->bd_addr = bd_addr;
 
         if (!ctrl_psm) {
           p_mcb->cch_oper = BTIF_HL_CCH_OP_MDEP_FILTERING;
@@ -793,7 +757,7 @@
         p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
         p_pcb->in_use = true;
         p_pcb->mdep_cfg_idx = mdep_cfg_idx;
-        memcpy(p_pcb->bd_addr, bd_addr, sizeof(BD_ADDR));
+        p_pcb->bd_addr = bd_addr;
         p_pcb->op = op;
 
         switch (op) {
@@ -996,7 +960,7 @@
  * Returns          bool
  *
  ******************************************************************************/
-static bool btif_hl_find_peer_mdep_id(uint8_t app_id, BD_ADDR bd_addr,
+static bool btif_hl_find_peer_mdep_id(uint8_t app_id, const RawAddress& bd_addr,
                                       tBTA_HL_MDEP_ROLE local_mdep_role,
                                       uint16_t data_type,
                                       tBTA_HL_MDEP_ID* p_peer_mdep_id) {
@@ -1009,9 +973,7 @@
 
   BTIF_TRACE_DEBUG("%s app_id=%d local_mdep_role=%d, data_type=%d", __func__,
                    app_id, local_mdep_role, data_type);
-
-  BTIF_TRACE_DEBUG("DB [%02x:%02x:%02x:%02x:%02x:%02x]", bd_addr[0], bd_addr[1],
-                   bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
+  VLOG(1) << "DB " << bd_addr;
 
   BTIF_TRACE_DEBUG("local_mdep_role=%d", local_mdep_role);
   BTIF_TRACE_DEBUG("data_type=%d", data_type);
@@ -1095,7 +1057,7 @@
  * Returns      bool
  *
  ******************************************************************************/
-bool btif_hl_find_mcl_idx(uint8_t app_idx, BD_ADDR p_bd_addr,
+bool btif_hl_find_mcl_idx(uint8_t app_idx, const RawAddress& p_bd_addr,
                           uint8_t* p_mcl_idx) {
   bool found = false;
   uint8_t i;
@@ -1104,7 +1066,7 @@
   *p_mcl_idx = 0;
   for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
     p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, i);
-    if (p_mcb->in_use && (!memcmp(p_mcb->bd_addr, p_bd_addr, BD_ADDR_LEN))) {
+    if (p_mcb->in_use && p_mcb->bd_addr == p_bd_addr) {
       found = true;
       *p_mcl_idx = i;
       break;
@@ -1672,8 +1634,8 @@
   btif_hl_app_cb_t* p_acb;
   btif_hl_mcl_cb_t* p_mcb;
   btif_hl_mdl_cb_t* p_dcb;
-  uint8_t j, x, y;
-  bt_bdaddr_t bd_addr;
+  uint8_t j, x;
+  RawAddress bd_addr;
 
   p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
   for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
@@ -1685,9 +1647,7 @@
         if (p_mcb->mdl[x].in_use) {
           p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, j, x);
           btif_hl_release_socket(app_idx, j, x);
-          for (y = 0; y < 6; y++) {
-            bd_addr.address[y] = p_mcb->bd_addr[y];
-          }
+          bd_addr = p_mcb->bd_addr;
           BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, p_acb->app_id,
                              &bd_addr, p_dcb->local_mdep_cfg_idx,
                              p_dcb->channel_id, BTHL_CONN_STATE_DISCONNECTED,
@@ -1936,17 +1896,16 @@
  *
  ******************************************************************************/
 void btif_hl_send_destroyed_cb(btif_hl_app_cb_t* p_acb) {
-  bt_bdaddr_t bd_addr;
   int app_id = (int)btif_hl_get_app_id(p_acb->delete_mdl.channel_id);
 
-  btif_hl_copy_bda(&bd_addr, p_acb->delete_mdl.bd_addr);
+  RawAddress bd_addr = p_acb->delete_mdl.bd_addr;
   BTIF_TRACE_DEBUG("%s", __func__);
   BTIF_TRACE_DEBUG(
       "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d, state=%d "
       "fd=%d",
       p_acb->delete_mdl.channel_id, p_acb->delete_mdl.mdep_cfg_idx,
       BTHL_CONN_STATE_DESTROYED, 0);
-  btif_hl_display_bt_bda(&bd_addr);
+  VLOG(1) << "BD " << bd_addr;
 
   BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
                      p_acb->delete_mdl.mdep_cfg_idx,
@@ -1966,10 +1925,9 @@
                                    uint8_t mdl_idx) {
   btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   btif_hl_soc_cb_t* p_scb = p_dcb->p_scb;
-  bt_bdaddr_t bd_addr;
   int app_id = (int)btif_hl_get_app_id(p_scb->channel_id);
 
-  btif_hl_copy_bda(&bd_addr, p_scb->bd_addr);
+  RawAddress bd_addr = p_scb->bd_addr;
 
   BTIF_TRACE_DEBUG("%s", __func__);
   BTIF_TRACE_DEBUG(
@@ -1977,7 +1935,7 @@
       "state=%d fd=%d",
       p_scb->channel_id, p_scb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTING,
       p_scb->socket_id[0]);
-  btif_hl_display_bt_bda(&bd_addr);
+  VLOG(1) << "BD " << bd_addr;
   BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
                      p_scb->mdep_cfg_idx, p_scb->channel_id,
                      BTHL_CONN_STATE_DISCONNECTING, p_scb->socket_id[0]);
@@ -1993,10 +1951,9 @@
  ******************************************************************************/
 void btif_hl_send_setup_connecting_cb(uint8_t app_idx, uint8_t mcl_idx) {
   btif_hl_pending_chan_cb_t* p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
-  bt_bdaddr_t bd_addr;
   int app_id = (int)btif_hl_get_app_id(p_pcb->channel_id);
 
-  btif_hl_copy_bda(&bd_addr, p_pcb->bd_addr);
+  RawAddress bd_addr = p_pcb->bd_addr;
 
   if (p_pcb->in_use &&
       p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING) {
@@ -2005,7 +1962,7 @@
         "call channel state callback  channel_id=0x%08x mdep_cfg_idx=%d "
         "state=%d fd=%d",
         p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_CONNECTING, 0);
-    btif_hl_display_bt_bda(&bd_addr);
+    VLOG(1) << "BD " << bd_addr;
 
     BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
                        p_pcb->mdep_cfg_idx, p_pcb->channel_id,
@@ -2025,10 +1982,9 @@
  ******************************************************************************/
 void btif_hl_send_setup_disconnected_cb(uint8_t app_idx, uint8_t mcl_idx) {
   btif_hl_pending_chan_cb_t* p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
-  bt_bdaddr_t bd_addr;
   int app_id = (int)btif_hl_get_app_id(p_pcb->channel_id);
 
-  btif_hl_copy_bda(&bd_addr, p_pcb->bd_addr);
+  RawAddress bd_addr = p_pcb->bd_addr;
 
   BTIF_TRACE_DEBUG("%s p_pcb->in_use=%d", __func__, p_pcb->in_use);
   if (p_pcb->in_use) {
@@ -2039,7 +1995,7 @@
           "state=%d fd=%d",
           p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_CONNECTING,
           0);
-      btif_hl_display_bt_bda(&bd_addr);
+      VLOG(1) << "BD " << bd_addr;
       BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
                          p_pcb->mdep_cfg_idx, p_pcb->channel_id,
                          BTHL_CONN_STATE_CONNECTING, 0);
@@ -2049,7 +2005,7 @@
           "state=%d fd=%d",
           p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTED,
           0);
-      btif_hl_display_bt_bda(&bd_addr);
+      VLOG(1) << "BD " << bd_addr;
       BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
                          p_pcb->mdep_cfg_idx, p_pcb->channel_id,
                          BTHL_CONN_STATE_DISCONNECTED, 0);
@@ -2059,7 +2015,7 @@
           "state=%d fd=%d",
           p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTED,
           0);
-      btif_hl_display_bt_bda(&bd_addr);
+      VLOG(1) << "BD " << bd_addr;
       BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
                          p_pcb->mdep_cfg_idx, p_pcb->channel_id,
                          BTHL_CONN_STATE_DISCONNECTED, 0);
@@ -2148,7 +2104,7 @@
                       break;
                   }
                   open_param.ctrl_psm = p_mcb->ctrl_psm;
-                  bdcpy(open_param.bd_addr, p_mcb->bd_addr);
+                  open_param.bd_addr = p_mcb->bd_addr;
                   open_param.sec_mask =
                       (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
                   BTA_HlCchOpen(p_acb->app_id, p_acb->app_handle, &open_param);
@@ -2206,7 +2162,7 @@
           p_mcb->in_use = true;
           p_mcb->is_connected = true;
           p_mcb->mcl_handle = p_data->cch_open_ind.mcl_handle;
-          bdcpy(p_mcb->bd_addr, p_data->cch_open_ind.bd_addr);
+          p_mcb->bd_addr = p_data->cch_open_ind.bd_addr;
           btif_hl_start_cch_timer(i, mcl_idx);
         }
       } else {
@@ -2952,7 +2908,6 @@
  ******************************************************************************/
 static void btif_hl_proc_cb_evt(uint16_t event, char* p_param) {
   btif_hl_evt_cb_t* p_data = (btif_hl_evt_cb_t*)p_param;
-  bt_bdaddr_t bd_addr;
   bthl_channel_state_t state = BTHL_CONN_STATE_DISCONNECTED;
   bool send_chan_cb = true;
   tBTA_HL_REG_PARAM reg_param;
@@ -2973,12 +2928,12 @@
         send_chan_cb = false;
 
       if (send_chan_cb) {
-        btif_hl_copy_bda(&bd_addr, p_data->chan_cb.bd_addr);
+        RawAddress bd_addr = p_data->chan_cb.bd_addr;
         BTIF_TRACE_DEBUG(
             "state callbk: ch_id=0x%08x cb_state=%d state=%d  fd=%d",
             p_data->chan_cb.channel_id, p_data->chan_cb.cb_state, state,
             p_data->chan_cb.fd);
-        btif_hl_display_bt_bda(&bd_addr);
+        VLOG(1) << "BD " << bd_addr;
         BTIF_HL_CALL_CBACK(
             bt_hl_callbacks, channel_state_cb, p_data->chan_cb.app_id, &bd_addr,
             p_data->chan_cb.mdep_cfg_index, p_data->chan_cb.channel_id, state,
@@ -3085,12 +3040,7 @@
                        p_data->sdp_query_cfm.app_handle,
                        p_data->sdp_query_cfm.app_id,
                        p_data->sdp_query_cfm.status);
-
-      BTIF_TRACE_DEBUG(
-          "DB [%02x] [%02x] [%02x] [%02x] [%02x] [%02x]",
-          p_data->sdp_query_cfm.bd_addr[0], p_data->sdp_query_cfm.bd_addr[1],
-          p_data->sdp_query_cfm.bd_addr[2], p_data->sdp_query_cfm.bd_addr[3],
-          p_data->sdp_query_cfm.bd_addr[4], p_data->sdp_query_cfm.bd_addr[5]);
+      VLOG(0) << "DB " << p_data->sdp_query_cfm.bd_addr;
 
       if (p_data->sdp_query_cfm.status == BTA_HL_STATUS_OK)
         status = btif_hl_proc_sdp_query_cfm(p_data);
@@ -3132,11 +3082,7 @@
           "app_id=%d,app_handle=%d mcl_handle=%d status =%d",
           p_data->cch_open_cfm.app_id, p_data->cch_open_cfm.app_handle,
           p_data->cch_open_cfm.mcl_handle, p_data->cch_open_cfm.status);
-      BTIF_TRACE_DEBUG(
-          "DB [%02x] [%02x] [%02x] [%02x] [%02x] [%02x]",
-          p_data->cch_open_cfm.bd_addr[0], p_data->cch_open_cfm.bd_addr[1],
-          p_data->cch_open_cfm.bd_addr[2], p_data->cch_open_cfm.bd_addr[3],
-          p_data->cch_open_cfm.bd_addr[4], p_data->cch_open_cfm.bd_addr[5]);
+      VLOG(1) << "BD " << p_data->cch_open_cfm.bd_addr;
 
       if (p_data->cch_open_cfm.status == BTA_HL_STATUS_OK ||
           p_data->cch_open_cfm.status == BTA_HL_STATUS_DUPLICATE_CCH_OPEN) {
@@ -3208,11 +3154,7 @@
       BTIF_TRACE_DEBUG("app_handle=%d mcl_handle=%d",
                        p_data->cch_open_ind.app_handle,
                        p_data->cch_open_ind.mcl_handle);
-      BTIF_TRACE_DEBUG(
-          "DB [%02x] [%02x] [%02x] [%02x] [%02x] [%02x]",
-          p_data->cch_open_ind.bd_addr[0], p_data->cch_open_ind.bd_addr[1],
-          p_data->cch_open_ind.bd_addr[2], p_data->cch_open_ind.bd_addr[3],
-          p_data->cch_open_ind.bd_addr[4], p_data->cch_open_ind.bd_addr[5]);
+      VLOG(0) << "DB " << p_data->cch_open_ind.bd_addr;
 
       btif_hl_proc_cch_open_ind(p_data);
       break;
@@ -3604,7 +3546,7 @@
  * Returns         bt_status_t
  *
  ******************************************************************************/
-static bt_status_t connect_channel(int app_id, bt_bdaddr_t* bd_addr,
+static bt_status_t connect_channel(int app_id, RawAddress* bd_addr,
                                    int mdep_cfg_index, int* channel_id) {
   uint8_t app_idx, mcl_idx;
   btif_hl_app_cb_t* p_acb = NULL;
@@ -3612,19 +3554,14 @@
   btif_hl_mcl_cb_t* p_mcb = NULL;
   bt_status_t status = BT_STATUS_SUCCESS;
   tBTA_HL_DCH_OPEN_PARAM dch_open;
-  BD_ADDR bda;
-  uint8_t i;
 
   CHECK_BTHL_INIT();
   BTIF_TRACE_EVENT("%s", __func__);
   btif_hl_display_calling_process_name();
 
-  for (i = 0; i < 6; i++) {
-    bda[i] = (uint8_t)bd_addr->address[i];
-  }
   if (btif_hl_find_app_idx(((uint8_t)app_id), &app_idx)) {
     p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
-    if (btif_hl_find_mcl_idx(app_idx, bda, &mcl_idx)) {
+    if (btif_hl_find_mcl_idx(app_idx, *bd_addr, &mcl_idx)) {
       p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
       if (p_mcb->is_connected) {
         dch_open.ctrl_psm = p_mcb->ctrl_psm;
@@ -3649,8 +3586,9 @@
           }
           dch_open.sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
 
-          if (!btif_hl_dch_open(p_acb->app_id, bda, &dch_open, mdep_cfg_index,
-                                BTIF_HL_PEND_DCH_OP_OPEN, channel_id)) {
+          if (!btif_hl_dch_open(p_acb->app_id, *bd_addr, &dch_open,
+                                mdep_cfg_index, BTIF_HL_PEND_DCH_OP_OPEN,
+                                channel_id)) {
             status = BT_STATUS_FAIL;
             BTIF_TRACE_EVENT("%s loc0 status = BT_STATUS_FAIL", __func__);
           }
@@ -3660,9 +3598,9 @@
           p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
           p_pcb->in_use = true;
           p_pcb->mdep_cfg_idx = mdep_cfg_index;
-          memcpy(p_pcb->bd_addr, bda, sizeof(BD_ADDR));
+          p_pcb->bd_addr = *bd_addr;
           p_pcb->op = BTIF_HL_PEND_DCH_OP_OPEN;
-          BTA_HlSdpQuery(app_id, p_acb->app_handle, bda);
+          BTA_HlSdpQuery(app_id, p_acb->app_handle, *bd_addr);
         }
       } else {
         status = BT_STATUS_FAIL;
@@ -3678,7 +3616,7 @@
       else
         p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SINK;
 
-      if (!btif_hl_cch_open(p_acb->app_id, bda, 0, mdep_cfg_index,
+      if (!btif_hl_cch_open(p_acb->app_id, *bd_addr, 0, mdep_cfg_index,
                             BTIF_HL_PEND_DCH_OP_OPEN, channel_id)) {
         status = BT_STATUS_FAIL;
       }
@@ -3727,8 +3665,7 @@
         p_acb->delete_mdl.mdl_id = p_mdl->base.mdl_id;
         p_acb->delete_mdl.channel_id = channel_id;
         p_acb->delete_mdl.mdep_cfg_idx = p_mdl->extra.mdep_cfg_idx;
-        memcpy(p_acb->delete_mdl.bd_addr, p_mdl->base.peer_bd_addr,
-               sizeof(BD_ADDR));
+        p_acb->delete_mdl.bd_addr = p_mdl->base.peer_bd_addr;
 
         if (btif_hl_find_mcl_idx(app_idx, p_mdl->base.peer_bd_addr, &mcl_idx)) {
           p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
@@ -4239,7 +4176,7 @@
       p_scb->mdl_idx = mdl_idx;
       p_scb->channel_id = p_dcb->channel_id;
       p_scb->mdep_cfg_idx = p_dcb->local_mdep_cfg_idx;
-      memcpy(p_scb->bd_addr, p_mcb->bd_addr, sizeof(BD_ADDR));
+      p_scb->bd_addr = p_mcb->bd_addr;
       btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_ADD);
       p_scb->max_s = p_scb->socket_id[1];
       list_append(soc_queue, (void*)p_scb);
@@ -4290,7 +4227,7 @@
       if (p_mcb && p_dcb) {
         btif_hl_stop_timer_using_handle(p_mcb->mcl_handle);
         evt_param.chan_cb.app_id = p_acb->app_id;
-        memcpy(evt_param.chan_cb.bd_addr, p_mcb->bd_addr, sizeof(BD_ADDR));
+        evt_param.chan_cb.bd_addr = p_mcb->bd_addr;
         evt_param.chan_cb.channel_id = p_dcb->channel_id;
         evt_param.chan_cb.fd = p_scb->socket_id[0];
         evt_param.chan_cb.mdep_cfg_index = (int)p_dcb->local_mdep_cfg_idx;
@@ -4331,7 +4268,7 @@
 
         btif_hl_evt_cb_t evt_param;
         evt_param.chan_cb.app_id = (int)btif_hl_get_app_id(p_scb->channel_id);
-        memcpy(evt_param.chan_cb.bd_addr, p_scb->bd_addr, sizeof(BD_ADDR));
+        evt_param.chan_cb.bd_addr = p_scb->bd_addr;
         evt_param.chan_cb.channel_id = p_scb->channel_id;
         evt_param.chan_cb.fd = p_scb->socket_id[0];
         evt_param.chan_cb.mdep_cfg_index = (int)p_scb->mdep_cfg_idx;
diff --git a/btif/src/btif_mce.cc b/btif/src/btif_mce.cc
index 5c03d71..53102e8 100644
--- a/btif/src/btif_mce.cc
+++ b/btif/src/btif_mce.cc
@@ -37,7 +37,6 @@
 #include "bt_types.h"
 #include "bta_api.h"
 #include "bta_mce_api.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "btif_profile_queue.h"
 #include "btif_util.h"
@@ -51,7 +50,6 @@
 static void btif_mce_mas_discovery_comp_evt(uint16_t event, char* p_param) {
   tBTA_MCE_MAS_DISCOVERY_COMP* evt_data = (tBTA_MCE_MAS_DISCOVERY_COMP*)p_param;
   btmce_mas_instance_t insts[BTA_MCE_MAX_MAS_INSTANCES];
-  bt_bdaddr_t addr;
   int i;
 
   BTIF_TRACE_EVENT("%s:  event = %d", __func__, event);
@@ -65,8 +63,7 @@
     insts[i].p_name = evt_data->mas[i].p_srv_name;
   }
 
-  bdcpy(addr.address, evt_data->remote_addr);
-
+  RawAddress addr = evt_data->remote_addr;
   HAL_CBACK(bt_mce_callbacks, remote_mas_instances_cb,
             (bt_status_t)evt_data->status, &addr, evt_data->num_mas, insts);
 }
@@ -127,13 +124,10 @@
   return BT_STATUS_SUCCESS;
 }
 
-static bt_status_t get_remote_mas_instances(bt_bdaddr_t* bd_addr) {
-  bdstr_t bdstr;
+static bt_status_t get_remote_mas_instances(RawAddress* bd_addr) {
+  VLOG(2) << __func__ << ": remote_addr=" << bd_addr;
 
-  BTIF_TRACE_EVENT("%s: remote_addr=%s", __func__,
-                   bdaddr_to_string(bd_addr, bdstr, sizeof(bdstr)));
-
-  BTA_MceGetRemoteMasInstances(bd_addr->address);
+  BTA_MceGetRemoteMasInstances(*bd_addr);
 
   return BT_STATUS_SUCCESS;
 }
diff --git a/btif/src/btif_pan.cc b/btif/src/btif_pan.cc
index 9562a1f..7b2c861 100644
--- a/btif/src/btif_pan.cc
+++ b/btif/src/btif_pan.cc
@@ -54,7 +54,6 @@
 #include "bt_common.h"
 #include "bta_api.h"
 #include "bta_pan_api.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "btif_pan_internal.h"
 #include "btif_sock_thread.h"
@@ -96,9 +95,9 @@
 
 static bt_status_t btpan_jni_init(const btpan_callbacks_t* callbacks);
 static void btpan_jni_cleanup();
-static bt_status_t btpan_connect(const bt_bdaddr_t* bd_addr, int local_role,
+static bt_status_t btpan_connect(const RawAddress* bd_addr, int local_role,
                                  int remote_role);
-static bt_status_t btpan_disconnect(const bt_bdaddr_t* bd_addr);
+static bt_status_t btpan_disconnect(const RawAddress* bd_addr);
 static bt_status_t btpan_enable(int local_role);
 static int btpan_get_local_role(void);
 
@@ -218,13 +217,13 @@
   return btpan_dev_local_role;
 }
 
-static bt_status_t btpan_connect(const bt_bdaddr_t* bd_addr, int local_role,
+static bt_status_t btpan_connect(const RawAddress* bd_addr, int local_role,
                                  int remote_role) {
   BTIF_TRACE_DEBUG("local_role:%d, remote_role:%d", local_role, remote_role);
   int bta_local_role = btpan_role_to_bta(local_role);
   int bta_remote_role = btpan_role_to_bta(remote_role);
-  btpan_new_conn(-1, bd_addr->address, bta_local_role, bta_remote_role);
-  BTA_PanOpen((uint8_t*)bd_addr->address, bta_local_role, bta_remote_role);
+  btpan_new_conn(-1, *bd_addr, bta_local_role, bta_remote_role);
+  BTA_PanOpen(*bd_addr, bta_local_role, bta_remote_role);
   return BT_STATUS_SUCCESS;
 }
 
@@ -232,8 +231,8 @@
   BTIF_TRACE_EVENT("%s: event=%d", __func__, event);
   switch (event) {
     case BTIF_PAN_CB_DISCONNECTING: {
-      bt_bdaddr_t* bd_addr = (bt_bdaddr_t*)p_param;
-      btpan_conn_t* conn = btpan_find_conn_addr(bd_addr->address);
+      RawAddress* bd_addr = (RawAddress*)p_param;
+      btpan_conn_t* conn = btpan_find_conn_addr(*bd_addr);
       int btpan_conn_local_role;
       int btpan_remote_role;
       asrt(conn != NULL);
@@ -241,8 +240,7 @@
         btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
         btpan_remote_role = bta_role_to_btpan(conn->remote_role);
         callback.connection_state_cb(BTPAN_STATE_DISCONNECTING,
-                                     BT_STATUS_SUCCESS,
-                                     (const bt_bdaddr_t*)conn->peer,
+                                     BT_STATUS_SUCCESS, &conn->peer,
                                      btpan_conn_local_role, btpan_remote_role);
       }
     } break;
@@ -252,13 +250,13 @@
   }
 }
 
-static bt_status_t btpan_disconnect(const bt_bdaddr_t* bd_addr) {
-  btpan_conn_t* conn = btpan_find_conn_addr(bd_addr->address);
+static bt_status_t btpan_disconnect(const RawAddress* bd_addr) {
+  btpan_conn_t* conn = btpan_find_conn_addr(*bd_addr);
   if (conn && conn->handle >= 0) {
     /* Inform the application that the disconnect has been initiated
      * successfully */
     btif_transfer_context(btif_in_pan_generic_evt, BTIF_PAN_CB_DISCONNECTING,
-                          (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+                          (char*)bd_addr, sizeof(RawAddress), NULL);
     BTA_PanClose(conn->handle);
     return BT_STATUS_SUCCESS;
   }
@@ -279,7 +277,7 @@
   }
 }
 
-static int tap_if_up(const char* devname, const bt_bdaddr_t* addr) {
+static int tap_if_up(const char* devname, const RawAddress* addr) {
   struct ifreq ifr;
   int sk, err;
 
@@ -408,13 +406,13 @@
   return INVALID_FD;
 }
 
-int btpan_tap_send(int tap_fd, const BD_ADDR src, const BD_ADDR dst,
+int btpan_tap_send(int tap_fd, const RawAddress& src, const RawAddress& dst,
                    uint16_t proto, const char* buf, uint16_t len,
                    UNUSED_ATTR bool ext, UNUSED_ATTR bool forward) {
   if (tap_fd != INVALID_FD) {
     tETH_HDR eth_hdr;
-    memcpy(&eth_hdr.h_dest, dst, ETH_ADDR_LEN);
-    memcpy(&eth_hdr.h_src, src, ETH_ADDR_LEN);
+    eth_hdr.h_dest = dst;
+    eth_hdr.h_src = src;
     eth_hdr.h_proto = htons(proto);
     char packet[TAP_MAX_PKT_WRITE_LEN + sizeof(tETH_HDR)];
     memcpy(packet, &eth_hdr, sizeof(tETH_HDR));
@@ -447,10 +445,9 @@
   return NULL;
 }
 
-btpan_conn_t* btpan_find_conn_addr(const BD_ADDR addr) {
+btpan_conn_t* btpan_find_conn_addr(const RawAddress& addr) {
   for (int i = 0; i < MAX_PAN_CONNS; i++) {
-    if (memcmp(btpan_cb.conns[i].peer, addr, sizeof(BD_ADDR)) == 0)
-      return &btpan_cb.conns[i];
+    if (btpan_cb.conns[i].peer == addr) return &btpan_cb.conns[i];
   }
   return NULL;
 }
@@ -514,7 +511,7 @@
   }
 }
 
-btpan_conn_t* btpan_new_conn(int handle, const BD_ADDR addr, int local_role,
+btpan_conn_t* btpan_new_conn(int handle, const RawAddress& addr, int local_role,
                              int remote_role) {
   for (int i = 0; i < MAX_PAN_CONNS; i++) {
     BTIF_TRACE_DEBUG("conns[%d]:%d", i, btpan_cb.conns[i].handle);
@@ -523,7 +520,7 @@
                        local_role, remote_role);
 
       btpan_cb.conns[i].handle = handle;
-      bdcpy(btpan_cb.conns[i].peer, addr);
+      btpan_cb.conns[i].peer = addr;
       btpan_cb.conns[i].local_role = local_role;
       btpan_cb.conns[i].remote_role = remote_role;
       return &btpan_cb.conns[i];
@@ -551,17 +548,14 @@
 }
 
 static int forward_bnep(tETH_HDR* eth_hdr, BT_HDR* hdr) {
-  int broadcast = eth_hdr->h_dest[0] & 1;
+  int broadcast = eth_hdr->h_dest.address[0] & 1;
 
   // Find the right connection to send this frame over.
   for (int i = 0; i < MAX_PAN_CONNS; i++) {
     uint16_t handle = btpan_cb.conns[i].handle;
     if (handle != (uint16_t)-1 &&
-        (broadcast ||
-         memcmp(btpan_cb.conns[i].eth_addr, eth_hdr->h_dest, sizeof(BD_ADDR)) ==
-             0 ||
-         memcmp(btpan_cb.conns[i].peer, eth_hdr->h_dest, sizeof(BD_ADDR)) ==
-             0)) {
+        (broadcast || btpan_cb.conns[i].eth_addr == eth_hdr->h_dest ||
+         btpan_cb.conns[i].peer == eth_hdr->h_dest)) {
       int result = PAN_WriteBuf(handle, eth_hdr->h_dest, eth_hdr->h_src,
                                 ntohs(eth_hdr->h_proto), hdr, 0);
       switch (result) {
@@ -597,10 +591,9 @@
     }
     case BTA_PAN_OPENING_EVT: {
       btpan_conn_t* conn;
-      bdstr_t bds;
-      bdaddr_to_string((bt_bdaddr_t*)p_data->opening.bd_addr, bds, sizeof(bds));
       BTIF_TRACE_DEBUG("BTA_PAN_OPENING_EVT handle %d, addr: %s",
-                       p_data->opening.handle, bds);
+                       p_data->opening.handle,
+                       p_data->opening.bd_addr.ToString().c_str());
       conn = btpan_find_conn_addr(p_data->opening.bd_addr);
 
       asrt(conn != NULL);
@@ -608,10 +601,9 @@
         conn->handle = p_data->opening.handle;
         int btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
         int btpan_remote_role = bta_role_to_btpan(conn->remote_role);
-        callback.connection_state_cb(
-            BTPAN_STATE_CONNECTING, BT_STATUS_SUCCESS,
-            (const bt_bdaddr_t*)p_data->opening.bd_addr, btpan_conn_local_role,
-            btpan_remote_role);
+        callback.connection_state_cb(BTPAN_STATE_CONNECTING, BT_STATUS_SUCCESS,
+                                     &p_data->opening.bd_addr,
+                                     btpan_conn_local_role, btpan_remote_role);
       } else
         BTIF_TRACE_ERROR("connection not found");
       break;
@@ -638,8 +630,7 @@
        * conn->remote_role); */
       int btpan_conn_local_role = bta_role_to_btpan(p_data->open.local_role);
       int btpan_remote_role = bta_role_to_btpan(p_data->open.peer_role);
-      callback.connection_state_cb(state, status,
-                                   (const bt_bdaddr_t*)p_data->open.bd_addr,
+      callback.connection_state_cb(state, status, &p_data->open.bd_addr,
                                    btpan_conn_local_role, btpan_remote_role);
       break;
     }
@@ -653,8 +644,8 @@
         int btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
         int btpan_remote_role = bta_role_to_btpan(conn->remote_role);
         callback.connection_state_cb(BTPAN_STATE_DISCONNECTED, (bt_status_t)0,
-                                     (const bt_bdaddr_t*)conn->peer,
-                                     btpan_conn_local_role, btpan_remote_role);
+                                     &conn->peer, btpan_conn_local_role,
+                                     btpan_remote_role);
         btpan_cleanup_conn(conn);
       } else
         BTIF_TRACE_ERROR("pan handle not found (%d)", p_data->close.handle);
diff --git a/btif/src/btif_profile_queue.cc b/btif/src/btif_profile_queue.cc
index d5061d6..152f11d 100644
--- a/btif/src/btif_profile_queue.cc
+++ b/btif/src/btif_profile_queue.cc
@@ -32,7 +32,6 @@
 #include <string.h>
 
 #include "bt_common.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_common.h"
 #include "osi/include/allocator.h"
 #include "osi/include/list.h"
@@ -49,7 +48,7 @@
 } btif_queue_event_t;
 
 typedef struct {
-  bt_bdaddr_t bda;
+  RawAddress bda;
   uint16_t uuid;
   bool busy;
   btif_connect_cb_t connect_cb;
@@ -80,26 +79,32 @@
   for (const list_node_t* node = list_begin(connect_queue);
        node != list_end(connect_queue); node = list_next(node)) {
     if (((connect_node_t*)list_node(node))->uuid == p_param->uuid) {
-      bdstr_t bd_addr_str;
-      LOG_ERROR(
-          LOG_TAG,
-          "%s dropping duplicate connection request UUID=%04X, "
-          "bd_addr=%s, busy=%d",
-          __func__, p_param->uuid,
-          bdaddr_to_string(&p_param->bda, bd_addr_str, sizeof(bd_addr_str)),
-          p_param->busy);
+      LOG_ERROR(LOG_TAG,
+                "%s dropping duplicate connection request UUID=%04X, "
+                "bd_addr=%s, busy=%d",
+                __func__, p_param->uuid, p_param->bda.ToString().c_str(),
+                p_param->busy);
       return;
     }
   }
 
+  LOG_INFO(
+      LOG_TAG, "%s: adding connection request UUID=%04X, bd_addr=%s, busy=%d",
+      __func__, p_param->uuid, p_param->bda.ToString().c_str(), p_param->busy);
   connect_node_t* p_node = (connect_node_t*)osi_malloc(sizeof(connect_node_t));
   memcpy(p_node, p_param, sizeof(connect_node_t));
   list_append(connect_queue, p_node);
 }
 
 static void queue_int_advance() {
-  if (connect_queue && !list_is_empty(connect_queue))
-    list_remove(connect_queue, list_front(connect_queue));
+  if (connect_queue && !list_is_empty(connect_queue)) {
+    connect_node_t* p_head = (connect_node_t*)list_front(connect_queue);
+    LOG_INFO(LOG_TAG,
+             "%s: removing connection request UUID=%04X, bd_addr=%s, busy=%d",
+             __func__, p_head->uuid, p_head->bda.ToString().c_str(),
+             p_head->busy);
+    list_remove(connect_queue, p_head);
+  }
 }
 
 static void queue_int_cleanup(uint16_t* p_uuid) {
@@ -118,12 +123,10 @@
     connection_request = (connect_node_t*)list_node(node);
     node = list_next(node);
     if (connection_request->uuid == uuid) {
-      bdstr_t bd_addr_str;
       LOG_INFO(LOG_TAG,
                "%s: removing connection request UUID=%04X, bd_addr=%s, busy=%d",
                __func__, connection_request->uuid,
-               bdaddr_to_string(&connection_request->bda, bd_addr_str,
-                                sizeof(bd_addr_str)),
+               connection_request->bda.ToString().c_str(),
                connection_request->busy);
       list_remove(connect_queue, connection_request);
     }
@@ -159,11 +162,11 @@
  * Returns          BT_STATUS_SUCCESS if successful
  *
  ******************************************************************************/
-bt_status_t btif_queue_connect(uint16_t uuid, const bt_bdaddr_t* bda,
+bt_status_t btif_queue_connect(uint16_t uuid, const RawAddress* bda,
                                btif_connect_cb_t connect_cb) {
   connect_node_t node;
   memset(&node, 0, sizeof(connect_node_t));
-  memcpy(&node.bda, bda, sizeof(bt_bdaddr_t));
+  node.bda = *bda;
   node.uuid = uuid;
   node.connect_cb = connect_cb;
 
@@ -207,11 +210,9 @@
 
   connect_node_t* p_head = (connect_node_t*)list_front(connect_queue);
 
-  bdstr_t bd_addr_str;
   LOG_INFO(LOG_TAG,
            "%s: executing connection request UUID=%04X, bd_addr=%s, busy=%d",
-           __func__, p_head->uuid,
-           bdaddr_to_string(&p_head->bda, bd_addr_str, sizeof(bd_addr_str)),
+           __func__, p_head->uuid, p_head->bda.ToString().c_str(),
            p_head->busy);
   // If the queue is currently busy, we return success anyway,
   // since the connection has been queued...
diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc
index 2e33842..edd0730 100644
--- a/btif/src/btif_rc.cc
+++ b/btif/src/btif_rc.cc
@@ -37,7 +37,6 @@
 #include <hardware/bt_rc.h>
 
 #include "avrc_defs.h"
-#include "bdaddr.h"
 #include "bt_common.h"
 #include "bta_api.h"
 #include "bta_av_api.h"
@@ -151,7 +150,7 @@
     btif_rc_status_cmd_timer_t rc_status_cmd;
     btif_rc_control_cmd_timer_t rc_control_cmd;
   };
-  BD_ADDR rc_addr;
+  RawAddress rc_addr;
 } btif_rc_timer_context_t;
 
 typedef struct {
@@ -174,7 +173,7 @@
   uint8_t rc_handle;
   tBTA_AV_FEAT rc_features;
   btrc_connection_state_t rc_state;
-  BD_ADDR rc_addr;
+  RawAddress rc_addr;
   uint16_t rc_pending_play;
   btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN];
   btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
@@ -208,7 +207,7 @@
 
 typedef struct {
   uint8_t label;
-  BD_ADDR rc_addr;
+  RawAddress rc_addr;
 } rc_context_t;
 
 typedef struct { uint8_t handle; } btif_rc_handle_t;
@@ -320,7 +319,7 @@
                                  btrc_folder_items_t* btrc_item);
 void get_folder_item_type_player(const tAVRC_ITEM* avrc_item,
                                  btrc_folder_items_t* btrc_item);
-static bt_status_t get_folder_items_cmd(bt_bdaddr_t* bd_addr, uint8_t scope,
+static bt_status_t get_folder_items_cmd(RawAddress* bd_addr, uint8_t scope,
                                         uint8_t start_item, uint8_t num_items);
 
 static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* p_param,
@@ -350,9 +349,7 @@
  *  Externs
  *****************************************************************************/
 extern bool btif_hf_call_terminated_recently();
-extern bool check_cod(const bt_bdaddr_t* remote_bdaddr, uint32_t cod);
-
-extern fixed_queue_t* btu_general_alarm_queue;
+extern bool check_cod(const RawAddress* remote_bdaddr, uint32_t cod);
 
 /*****************************************************************************
  *  Functions
@@ -395,15 +392,13 @@
   return connected_devices;
 }
 
-btif_rc_device_cb_t* btif_rc_get_device_by_bda(bt_bdaddr_t* bd_addr) {
-  BTIF_TRACE_DEBUG("%s: bd_addr: %02x-%02x-%02x-%02x-%02x-%02x", __func__,
-                   bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-                   bd_addr[5]);
+btif_rc_device_cb_t* btif_rc_get_device_by_bda(const RawAddress* bd_addr) {
+  VLOG(1) << __func__ << ": bd_addr: " << *bd_addr;
 
   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
     if ((btif_rc_cb.rc_multi_cb[idx].rc_state !=
          BTRC_CONNECTION_STATE_DISCONNECTED) &&
-        (bdcmp(btif_rc_cb.rc_multi_cb[idx].rc_addr, bd_addr->address) == 0)) {
+        btif_rc_cb.rc_multi_cb[idx].rc_addr == *bd_addr) {
       return (&btif_rc_cb.rc_multi_cb[idx]);
     }
   }
@@ -458,9 +453,7 @@
     return;
   }
 
-  bt_bdaddr_t rc_addr;
   int rc_features = 0;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
 
   if ((p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL) &&
       (p_dev->rc_features & BTA_AV_FEAT_RCCT)) {
@@ -488,26 +481,23 @@
   }
 
   BTIF_TRACE_DEBUG("%s: Update rc features to CTRL: %d", __func__, rc_features);
+  RawAddress rc_addr = p_dev->rc_addr;
   HAL_CBACK(bt_rc_ctrl_callbacks, getrcfeatures_cb, &rc_addr, rc_features);
 }
 
 void handle_rc_features(btif_rc_device_cb_t* p_dev) {
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
-  bdstr_t addr1, addr2;
+  RawAddress rc_addr = p_dev->rc_addr;
 
   CHECK(bt_rc_callbacks);
 
   btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
-  bt_bdaddr_t avdtp_addr = btif_av_get_addr();
+  RawAddress avdtp_addr = btif_av_get_addr();
 
   BTIF_TRACE_DEBUG("%s: AVDTP Address: %s AVCTP address: %s", __func__,
-                   bdaddr_to_string(&avdtp_addr, addr1, sizeof(addr1)),
-                   bdaddr_to_string(&rc_addr, addr2, sizeof(addr2)));
+                   avdtp_addr.ToString().c_str(), rc_addr.ToString().c_str());
 
   if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, &rc_addr) ||
-      absolute_volume_disabled() ||
-      bdcmp(avdtp_addr.address, rc_addr.address)) {
+      absolute_volume_disabled() || avdtp_addr != rc_addr) {
     p_dev->rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
   }
 
@@ -582,8 +572,7 @@
    * to a browse when not connected to the control channel over AVRCP is
    * probably not preferred anyways. */
   if (p_rc_br_open->status == BTA_AV_SUCCESS) {
-    bt_bdaddr_t rc_addr;
-    bdcpy(rc_addr.address, p_dev->rc_addr);
+    RawAddress rc_addr = p_dev->rc_addr;
     p_dev->br_connected = true;
     HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, true, true, &rc_addr);
   }
@@ -618,14 +607,14 @@
         "%s: Got RC OPEN in connected state, Connected RC: %d \
             and Current RC: %d",
         __func__, p_dev->rc_handle, p_rc_open->rc_handle);
-    if ((p_dev->rc_handle != p_rc_open->rc_handle) &&
-        (bdcmp(p_dev->rc_addr, p_rc_open->peer_addr))) {
+    if (p_dev->rc_handle != p_rc_open->rc_handle &&
+        p_dev->rc_addr != p_rc_open->peer_addr) {
       BTIF_TRACE_DEBUG("%s: Got RC connected for some other handle", __func__);
       BTA_AvCloseRc(p_rc_open->rc_handle);
       return;
     }
   }
-  memcpy(p_dev->rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
+  p_dev->rc_addr = p_rc_open->peer_addr;
   p_dev->rc_features = p_rc_open->peer_features;
   BTIF_TRACE_DEBUG("%s: handle_rc_connect in features: 0x%x out features 0x%x",
                    __func__, p_rc_open->peer_features, p_dev->rc_features);
@@ -642,9 +631,8 @@
   }
 
   p_dev->rc_playing_uid = RC_INVALID_TRACK_ID;
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
   if (bt_rc_ctrl_callbacks != NULL) {
+    RawAddress rc_addr = p_dev->rc_addr;
     HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, true, false, &rc_addr);
   }
   /* report connection state if remote device is AVRCP target */
@@ -669,13 +657,12 @@
     return;
   }
 
-  if ((p_rc_close->rc_handle != p_dev->rc_handle) &&
-      (bdcmp(p_dev->rc_addr, p_rc_close->peer_addr))) {
+  if (p_rc_close->rc_handle != p_dev->rc_handle &&
+      p_dev->rc_addr != p_rc_close->peer_addr) {
     BTIF_TRACE_ERROR("Got disconnect of unknown device");
     return;
   }
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
   /* Clean up AVRCP procedure flags */
   memset(&p_dev->rc_app_settings, 0, sizeof(btif_rc_player_app_settings_t));
   p_dev->rc_features_processed = false;
@@ -699,14 +686,14 @@
     p_dev->rc_vol_label = MAX_LABEL;
     p_dev->rc_volume = MAX_VOLUME;
 
-    memset(p_dev->rc_addr, 0, sizeof(BD_ADDR));
+    p_dev->rc_addr = RawAddress::kEmpty;
   }
   if (get_num_connected_devices() == 0) {
     BTIF_TRACE_DEBUG("%s: Closing all handles", __func__);
     init_all_transactions();
   }
 
-  memset(p_dev->rc_addr, 0, sizeof(BD_ADDR));
+  p_dev->rc_addr = RawAddress::kEmpty;
   /* report connection state if device is AVRCP target */
   if (bt_rc_ctrl_callbacks != NULL) {
     HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, false, false,
@@ -737,8 +724,7 @@
     return;
   }
 
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id: %d", __func__,
                    p_remote_cmd->rc_id);
@@ -787,7 +773,6 @@
  ***************************************************************************/
 void handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) {
   btif_rc_device_cb_t* p_dev = NULL;
-  bt_bdaddr_t rc_addr;
 
   p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle);
   if (p_dev == NULL) {
@@ -796,7 +781,7 @@
     return;
   }
 
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG)) {
     BTIF_TRACE_ERROR("%s: DUT does not support AVRCP controller role",
@@ -1093,18 +1078,14 @@
  **
  ** Function       btif_rc_get_connected_peer
  **
- ** Description    Fetches the connected headset's BD_ADDR if any
+ ** Description    Fetches the connected headset's address if any
  **
  ***************************************************************************/
-bool btif_rc_get_connected_peer(BD_ADDR peer_addr) {
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, peer_addr);
-  btif_rc_device_cb_t* p_dev = NULL;
-
+bool btif_rc_get_connected_peer(RawAddress* peer_addr) {
   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
-    p_dev = get_connected_device(idx);
+    btif_rc_device_cb_t* p_dev = get_connected_device(idx);
     if (p_dev != NULL && (p_dev->rc_connected == TRUE)) {
-      bdcpy(peer_addr, p_dev->rc_addr);
+      *peer_addr = p_dev->rc_addr;
       return true;
     }
   }
@@ -1118,12 +1099,9 @@
  ** Description    Fetches the connected headset's handle if any
  **
  ***************************************************************************/
-uint8_t btif_rc_get_connected_peer_handle(BD_ADDR peer_addr) {
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, peer_addr);
-
+uint8_t btif_rc_get_connected_peer_handle(const RawAddress& peer_addr) {
   btif_rc_device_cb_t* p_dev = NULL;
-  p_dev = btif_rc_get_device_by_bda(&rc_addr);
+  p_dev = btif_rc_get_device_by_bda(&peer_addr);
 
   if (p_dev == NULL) {
     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
@@ -1142,12 +1120,10 @@
  ***************************************************************************/
 
 /* clear the queued PLAY command. if |bSendToApp| is true, forward to app */
-void btif_rc_check_handle_pending_play(BD_ADDR peer_addr, bool bSendToApp) {
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, peer_addr);
-
+void btif_rc_check_handle_pending_play(const RawAddress& peer_addr,
+                                       bool bSendToApp) {
   btif_rc_device_cb_t* p_dev = NULL;
-  p_dev = btif_rc_get_device_by_bda(&rc_addr);
+  p_dev = btif_rc_get_device_by_bda(&peer_addr);
 
   if (p_dev == NULL) {
     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
@@ -1438,9 +1414,7 @@
   BTIF_TRACE_EVENT("%s: pdu: %s handle: 0x%x ctype: %x label: %x event ID: %x",
                    __func__, dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle,
                    ctype, label, pavrc_cmd->reg_notif.event_id);
-  bt_bdaddr_t rc_addr;
-
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   switch (event) {
     case AVRC_PDU_GET_PLAY_STATUS: {
@@ -1659,8 +1633,7 @@
                                            btif_rc_device_cb_t* p_dev) {
   BTIF_TRACE_DEBUG("%s: pdu: %s: handle: 0x%x", __func__,
                    dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle);
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
   switch (event) {
     case AVRC_PDU_SET_ABSOLUTE_VOLUME:
       HAL_CBACK(bt_rc_ctrl_callbacks, setabsvol_cmd_cb, &rc_addr,
@@ -1691,8 +1664,7 @@
   BTIF_TRACE_EVENT("%s: pdu: %s: handle: 0x%x ctype: %x label: %x", __func__,
                    dump_rc_pdu(pavrc_resp->pdu), p_dev->rc_handle, ctype,
                    label);
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   switch (event) {
     case AVRC_PDU_REGISTER_NOTIFICATION: {
@@ -1806,7 +1778,7 @@
  * Returns          bt_status_t
  *
  **************************************************************************/
-static bt_status_t get_play_status_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t get_play_status_rsp(RawAddress* bd_addr,
                                        btrc_play_status_t play_status,
                                        uint32_t song_len, uint32_t song_pos) {
   tAVRC_RESPONSE avrc_rsp;
@@ -1846,7 +1818,7 @@
  * Returns          bt_status_t
  *
  **************************************************************************/
-static bt_status_t get_element_attr_rsp(bt_bdaddr_t* bd_addr, uint8_t num_attr,
+static bt_status_t get_element_attr_rsp(RawAddress* bd_addr, uint8_t num_attr,
                                         btrc_element_attr_val_t* p_attrs) {
   tAVRC_RESPONSE avrc_rsp;
   uint32_t i;
@@ -1991,7 +1963,7 @@
  *                                            get_folder_items_list PDU
  *
  **************************************************************************/
-static bt_status_t get_folder_items_list_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t get_folder_items_list_rsp(RawAddress* bd_addr,
                                              btrc_status_t rsp_status,
                                              uint16_t uid_counter,
                                              uint8_t num_items,
@@ -2155,7 +2127,7 @@
  *                      BT_STATUS_SUCCESS   - always if RC is connected
  *
  **************************************************************************/
-static bt_status_t set_addressed_player_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t set_addressed_player_rsp(RawAddress* bd_addr,
                                             btrc_status_t rsp_status) {
   tAVRC_RESPONSE avrc_rsp;
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
@@ -2193,7 +2165,7 @@
  *                                            set_browsed_player PDU
  *
  **************************************************************************/
-static bt_status_t set_browsed_player_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t set_browsed_player_rsp(RawAddress* bd_addr,
                                           btrc_status_t rsp_status,
                                           uint32_t num_items,
                                           uint16_t charset_id,
@@ -2311,7 +2283,7 @@
  *                      BT_STATUS_SUCCESS   - always if RC is connected
  *
  **************************************************************************/
-static bt_status_t change_path_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t change_path_rsp(RawAddress* bd_addr,
                                    btrc_status_t rsp_status,
                                    uint32_t num_items) {
   tAVRC_RESPONSE avrc_rsp;
@@ -2344,7 +2316,7 @@
  *                      BT_STATUS_SUCCESS   - always if RC is connected
  *
  **************************************************************************/
-static bt_status_t search_rsp(bt_bdaddr_t* bd_addr, btrc_status_t rsp_status,
+static bt_status_t search_rsp(RawAddress* bd_addr, btrc_status_t rsp_status,
                               uint32_t uid_counter, uint32_t num_items) {
   tAVRC_RESPONSE avrc_rsp;
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
@@ -2377,7 +2349,7 @@
  *                      BT_STATUS_SUCCESS   - always if RC is connected
  *
  **************************************************************************/
-static bt_status_t get_item_attr_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t get_item_attr_rsp(RawAddress* bd_addr,
                                      btrc_status_t rsp_status, uint8_t num_attr,
                                      btrc_element_attr_val_t* p_attrs) {
   tAVRC_RESPONSE avrc_rsp;
@@ -2419,7 +2391,7 @@
  *                      BT_STATUS_SUCCESS   - always if RC is connected
  *
  **************************************************************************/
-static bt_status_t add_to_now_playing_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t add_to_now_playing_rsp(RawAddress* bd_addr,
                                           btrc_status_t rsp_status) {
   tAVRC_RESPONSE avrc_rsp;
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
@@ -2451,7 +2423,7 @@
  *                      BT_STATUS_SUCCESS   - always if RC is connected
  *
  **************************************************************************/
-static bt_status_t play_item_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t play_item_rsp(RawAddress* bd_addr,
                                  btrc_status_t rsp_status) {
   tAVRC_RESPONSE avrc_rsp;
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
@@ -2483,7 +2455,7 @@
  *                      BT_STATUS_SUCCESS   - always if RC is connected
  *
  **************************************************************************/
-static bt_status_t get_total_num_of_items_rsp(bt_bdaddr_t* bd_addr,
+static bt_status_t get_total_num_of_items_rsp(RawAddress* bd_addr,
                                               btrc_status_t rsp_status,
                                               uint32_t uid_counter,
                                               uint32_t num_items) {
@@ -2752,11 +2724,9 @@
  *
  **************************************************************************/
 bool iterate_supported_event_list_for_timeout(void* data, void* cb_data) {
-  bt_bdaddr_t bd_addr;
   rc_context_t* cntxt = (rc_context_t*)cb_data;
   uint8_t label = cntxt->label & 0xFF;
-  bdcpy(bd_addr.address, cntxt->rc_addr);
-  btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(&bd_addr);
+  btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(&cntxt->rc_addr);
   btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)data;
 
   if (p_event->label == label) {
@@ -2782,7 +2752,7 @@
   rc_context_t cntxt;
   memset(&cntxt, 0, sizeof(rc_context_t));
   cntxt.label = label;
-  bdcpy(cntxt.rc_addr, p_dev->rc_addr);
+  cntxt.rc_addr = p_dev->rc_addr;
 
   list_foreach(p_dev->rc_supported_event_list,
                iterate_supported_event_list_for_timeout, &cntxt);
@@ -2819,12 +2789,10 @@
   tAVRC_RESPONSE avrc_response = {0};
   tBTA_AV_META_MSG meta_msg;
   btif_rc_device_cb_t* p_dev = NULL;
-  bt_bdaddr_t bd_addr;
 
   p_context = (btif_rc_timer_context_t*)data;
-  bdcpy(bd_addr.address, p_context->rc_addr);
   memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
-  p_dev = btif_rc_get_device_by_bda(&bd_addr);
+  p_dev = btif_rc_get_device_by_bda(&p_context->rc_addr);
   if (p_dev == NULL) {
     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
     return;
@@ -2909,9 +2877,7 @@
   btif_rc_timer_context_t* p_context = (btif_rc_timer_context_t*)data;
   tAVRC_RESPONSE avrc_response = {0};
   tBTA_AV_META_MSG meta_msg;
-  bt_bdaddr_t bd_addr;
-  bdcpy(bd_addr.address, p_context->rc_addr);
-  btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(&bd_addr);
+  btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(&p_context->rc_addr);
   if (p_dev == NULL) {
     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
     return;
@@ -2999,10 +2965,9 @@
     if (p_dev->rc_play_status_timer == NULL) {
       p_dev->rc_play_status_timer = alarm_new("p_dev->rc_play_status_timer");
     }
-    alarm_set_on_queue(p_dev->rc_play_status_timer,
-                       BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
-                       btif_rc_play_status_timer_timeout,
-                       UINT_TO_PTR(p_dev->rc_handle), btu_general_alarm_queue);
+    alarm_set_on_mloop(
+        p_dev->rc_play_status_timer, BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
+        btif_rc_play_status_timer_timeout, UINT_TO_PTR(p_dev->rc_handle));
   }
 }
 
@@ -3051,13 +3016,12 @@
   p_event->status = eREGISTERED;
   p_context->rc_status_cmd.label = p_transaction->lbl;
   p_context->rc_status_cmd.pdu_id = AVRC_PDU_REGISTER_NOTIFICATION;
-  bdcpy(p_context->rc_addr, p_dev->rc_addr);
+  p_context->rc_addr = p_dev->rc_addr;
 
   alarm_free(p_transaction->txn_timer);
   p_transaction->txn_timer = alarm_new("btif_rc.status_command_txn_timer");
-  alarm_set_on_queue(p_transaction->txn_timer, BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
-                     btif_rc_status_cmd_timer_timeout, p_context,
-                     btu_general_alarm_queue);
+  alarm_set_on_mloop(p_transaction->txn_timer, BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
+                     btif_rc_status_cmd_timer_timeout, p_context);
 }
 
 static void start_status_command_timer(uint8_t pdu_id, rc_transaction_t* p_txn,
@@ -3065,13 +3029,12 @@
   btif_rc_timer_context_t* p_context = &p_txn->txn_timer_context;
   p_context->rc_status_cmd.label = p_txn->lbl;
   p_context->rc_status_cmd.pdu_id = pdu_id;
-  bdcpy(p_context->rc_addr, p_dev->rc_addr);
+  p_context->rc_addr = p_dev->rc_addr;
 
   alarm_free(p_txn->txn_timer);
   p_txn->txn_timer = alarm_new("btif_rc.status_command_txn_timer");
-  alarm_set_on_queue(p_txn->txn_timer, BTIF_TIMEOUT_RC_STATUS_CMD_MS,
-                     btif_rc_status_cmd_timer_timeout, p_context,
-                     btu_general_alarm_queue);
+  alarm_set_on_mloop(p_txn->txn_timer, BTIF_TIMEOUT_RC_STATUS_CMD_MS,
+                     btif_rc_status_cmd_timer_timeout, p_context);
 }
 
 static void start_control_command_timer(uint8_t pdu_id, rc_transaction_t* p_txn,
@@ -3079,13 +3042,12 @@
   btif_rc_timer_context_t* p_context = &p_txn->txn_timer_context;
   p_context->rc_control_cmd.label = p_txn->lbl;
   p_context->rc_control_cmd.pdu_id = pdu_id;
-  bdcpy(p_context->rc_addr, p_dev->rc_addr);
+  p_context->rc_addr = p_dev->rc_addr;
 
   alarm_free(p_txn->txn_timer);
   p_txn->txn_timer = alarm_new("btif_rc.control_command_txn_timer");
-  alarm_set_on_queue(p_txn->txn_timer, BTIF_TIMEOUT_RC_CONTROL_CMD_MS,
-                     btif_rc_control_cmd_timer_timeout, p_context,
-                     btu_general_alarm_queue);
+  alarm_set_on_mloop(p_txn->txn_timer, BTIF_TIMEOUT_RC_CONTROL_CMD_MS,
+                     btif_rc_control_cmd_timer_timeout, p_context);
 }
 
 bt_status_t build_and_send_vendor_cmd(tAVRC_COMMAND* avrc_cmd,
@@ -3204,7 +3166,6 @@
  **************************************************************************/
 static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg,
                                          tAVRC_REG_NOTIF_RSP* p_rsp) {
-  bt_bdaddr_t rc_addr;
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
   uint32_t attr_list[] = {
@@ -3218,7 +3179,7 @@
     return;
   }
 
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   if (pmeta_msg->code == AVRC_RSP_INTERIM) {
     btif_rc_supported_event_t* p_event;
@@ -3330,6 +3291,8 @@
          */
         if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING) {
           rc_start_play_status_timer(p_dev);
+          get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list,
+                                    p_dev);
         } else {
           rc_stop_play_status_timer(p_dev);
         }
@@ -3447,7 +3410,6 @@
   uint8_t xx, attr_index;
   uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
   btif_rc_player_app_settings_t* p_app_settings;
-  bt_bdaddr_t rc_addr;
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
 
@@ -3459,7 +3421,7 @@
   }
 
   p_app_settings = &p_dev->rc_app_settings;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   if (p_app_settings->attr_index < p_app_settings->num_attrs) {
     attr_index = p_app_settings->attr_index;
@@ -3522,7 +3484,6 @@
 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg,
                                         tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp) {
   btrc_player_settings_t app_settings;
-  bt_bdaddr_t rc_addr;
   uint16_t xx;
   btif_rc_device_cb_t* p_dev = NULL;
 
@@ -3539,7 +3500,7 @@
     return;
   }
 
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   app_settings.num_attr = p_rsp->num_val;
 
@@ -3579,7 +3540,6 @@
   uint8_t xx;
   uint8_t vals[AVRC_MAX_APP_ATTR_SIZE];
   btif_rc_player_app_settings_t* p_app_settings;
-  bt_bdaddr_t rc_addr;
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
 
@@ -3588,7 +3548,7 @@
     return;
   }
 
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
   p_app_settings = &p_dev->rc_app_settings;
 
   /* Todo: Do we need to retry on command timeout */
@@ -3653,7 +3613,6 @@
   uint8_t vals[AVRC_MAX_APP_ATTR_SIZE];
   uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
   btif_rc_player_app_settings_t* p_app_settings;
-  bt_bdaddr_t rc_addr;
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
 
@@ -3662,7 +3621,7 @@
     return;
   }
 
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
   p_app_settings = &p_dev->rc_app_settings;
 
   /* Todo: Do we need to retry on command timeout */
@@ -3761,7 +3720,6 @@
 static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg,
                                              tAVRC_RSP* p_rsp) {
   uint8_t accepted = 0;
-  bt_bdaddr_t rc_addr;
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
 
@@ -3770,7 +3728,7 @@
     return;
   }
 
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   /* For timeout pmeta_msg will be NULL, else we need to
    * check if this is accepted by TG
@@ -3797,7 +3755,6 @@
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
 
   if (p_rsp->status == AVRC_STS_NO_ERROR) {
-    bt_bdaddr_t rc_addr;
     size_t buf_size = p_rsp->num_attrs * sizeof(btrc_element_attr_val_t);
     btrc_element_attr_val_t* p_attr =
         (btrc_element_attr_val_t*)osi_calloc(buf_size);
@@ -3807,7 +3764,7 @@
       return;
     }
 
-    bdcpy(rc_addr.address, p_dev->rc_addr);
+    RawAddress rc_addr = p_dev->rc_addr;
 
     for (int i = 0; i < p_rsp->num_attrs; i++) {
       p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id;
@@ -3848,7 +3805,6 @@
  **************************************************************************/
 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg,
                                            tAVRC_GET_PLAY_STATUS_RSP* p_rsp) {
-  bt_bdaddr_t rc_addr;
 
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
@@ -3858,7 +3814,7 @@
     return;
   }
 
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   if (p_rsp->status == AVRC_STS_NO_ERROR) {
     HAL_CBACK(bt_rc_ctrl_callbacks, play_position_changed_cb, &rc_addr,
@@ -3880,7 +3836,6 @@
  **************************************************************************/
 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg,
                                                  tAVRC_RSP* p_rsp) {
-  bt_bdaddr_t rc_addr;
 
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
@@ -3890,7 +3845,7 @@
     return;
   }
 
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   if (p_rsp->status == AVRC_STS_NO_ERROR) {
     HAL_CBACK(bt_rc_ctrl_callbacks, set_addressed_player_cb, &rc_addr,
@@ -3914,8 +3869,7 @@
                                              tAVRC_GET_ITEMS_RSP* p_rsp) {
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   if (p_rsp->status == AVRC_STS_NO_ERROR) {
     /* Convert the internal folder listing into a response that can
@@ -4152,8 +4106,7 @@
                                         tAVRC_CHG_PATH_RSP* p_rsp) {
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   if (p_rsp->status == AVRC_STS_NO_ERROR) {
     HAL_CBACK(bt_rc_ctrl_callbacks, change_folder_path_cb, &rc_addr,
@@ -4177,8 +4130,7 @@
                                                tAVRC_SET_BR_PLAYER_RSP* p_rsp) {
   btif_rc_device_cb_t* p_dev =
       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
-  bt_bdaddr_t rc_addr;
-  bdcpy(rc_addr.address, p_dev->rc_addr);
+  RawAddress rc_addr = p_dev->rc_addr;
 
   if (p_rsp->status == AVRC_STS_NO_ERROR) {
     HAL_CBACK(bt_rc_ctrl_callbacks, set_browsed_player_cb, &rc_addr,
@@ -4527,7 +4479,7 @@
  *                  BT_STATUS_FAIL.
  *
  **************************************************************************/
-static bt_status_t get_playback_state_cmd(bt_bdaddr_t* bd_addr) {
+static bt_status_t get_playback_state_cmd(RawAddress* bd_addr) {
   BTIF_TRACE_DEBUG("%s", __func__);
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
   return get_play_status_cmd(p_dev);
@@ -4546,7 +4498,7 @@
  *                  BT_STATUS_FAIL.
  *
  **************************************************************************/
-static bt_status_t get_now_playing_list_cmd(bt_bdaddr_t* bd_addr,
+static bt_status_t get_now_playing_list_cmd(RawAddress* bd_addr,
                                             uint8_t start_item,
                                             uint8_t num_items) {
   BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, num_items);
@@ -4567,7 +4519,7 @@
  *                  BT_STATUS_FAIL.
  *
  **************************************************************************/
-static bt_status_t get_folder_list_cmd(bt_bdaddr_t* bd_addr, uint8_t start_item,
+static bt_status_t get_folder_list_cmd(RawAddress* bd_addr, uint8_t start_item,
                                        uint8_t num_items) {
   BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, num_items);
   return get_folder_items_cmd(bd_addr, AVRC_SCOPE_FILE_SYSTEM, start_item,
@@ -4587,7 +4539,7 @@
  *                  BT_STATUS_FAIL.
  *
  **************************************************************************/
-static bt_status_t get_player_list_cmd(bt_bdaddr_t* bd_addr, uint8_t start_item,
+static bt_status_t get_player_list_cmd(RawAddress* bd_addr, uint8_t start_item,
                                        uint8_t num_items) {
   BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, num_items);
   return get_folder_items_cmd(bd_addr, AVRC_SCOPE_PLAYER_LIST, start_item,
@@ -4609,7 +4561,7 @@
  *                  BT_STATUS_FAIL.
  *
  **************************************************************************/
-static bt_status_t change_folder_path_cmd(bt_bdaddr_t* bd_addr,
+static bt_status_t change_folder_path_cmd(RawAddress* bd_addr,
                                           uint8_t direction, uint8_t* uid) {
   BTIF_TRACE_DEBUG("%s: direction %d", __func__, direction);
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
@@ -4661,7 +4613,7 @@
  *                  BT_STATUS_FAIL.
  *
  **************************************************************************/
-static bt_status_t set_browsed_player_cmd(bt_bdaddr_t* bd_addr, uint16_t id) {
+static bt_status_t set_browsed_player_cmd(RawAddress* bd_addr, uint16_t id) {
   BTIF_TRACE_DEBUG("%s: id %d", __func__, id);
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
   CHECK_RC_CONNECTED(p_dev);
@@ -4708,7 +4660,7 @@
  **                  BT_STATUS_FAIL.
  **
  ***************************************************************************/
-static bt_status_t set_addressed_player_cmd(bt_bdaddr_t* bd_addr, uint16_t id) {
+static bt_status_t set_addressed_player_cmd(RawAddress* bd_addr, uint16_t id) {
   BTIF_TRACE_DEBUG("%s: id %d", __func__, id);
 
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
@@ -4761,7 +4713,7 @@
  *                  BT_STATUS_FAIL.
  *
  **************************************************************************/
-static bt_status_t get_folder_items_cmd(bt_bdaddr_t* bd_addr, uint8_t scope,
+static bt_status_t get_folder_items_cmd(RawAddress* bd_addr, uint8_t scope,
                                         uint8_t start_item, uint8_t end_item) {
   /* Check that both avrcp and browse channel are connected. */
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
@@ -4812,7 +4764,7 @@
  * Returns          void
  *
  **************************************************************************/
-static bt_status_t change_player_app_setting(bt_bdaddr_t* bd_addr,
+static bt_status_t change_player_app_setting(RawAddress* bd_addr,
                                              uint8_t num_attrib,
                                              uint8_t* attrib_ids,
                                              uint8_t* attrib_vals) {
@@ -4846,7 +4798,7 @@
  * Returns          void
  *
  **************************************************************************/
-static bt_status_t play_item_cmd(bt_bdaddr_t* bd_addr, uint8_t scope,
+static bt_status_t play_item_cmd(RawAddress* bd_addr, uint8_t scope,
                                  uint8_t* uid, uint16_t uid_counter) {
   BTIF_TRACE_DEBUG("%s: scope %d uid_counter %d", __func__, scope, uid_counter);
   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
@@ -5016,7 +4968,7 @@
  * Returns          void
  *
  **************************************************************************/
-static bt_status_t set_volume_rsp(bt_bdaddr_t* bd_addr, uint8_t abs_vol,
+static bt_status_t set_volume_rsp(RawAddress* bd_addr, uint8_t abs_vol,
                                   uint8_t label) {
   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
   tAVRC_RESPONSE avrc_rsp;
@@ -5059,7 +5011,7 @@
  *
  **************************************************************************/
 static bt_status_t volume_change_notification_rsp(
-    bt_bdaddr_t* bd_addr, btrc_notification_type_t rsp_type, uint8_t abs_vol,
+    RawAddress* bd_addr, btrc_notification_type_t rsp_type, uint8_t abs_vol,
     uint8_t label) {
   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
   tAVRC_RESPONSE avrc_rsp;
@@ -5105,7 +5057,7 @@
  * Returns          void
  *
  **************************************************************************/
-static bt_status_t send_groupnavigation_cmd(bt_bdaddr_t* bd_addr,
+static bt_status_t send_groupnavigation_cmd(RawAddress* bd_addr,
                                             uint8_t key_code,
                                             uint8_t key_state) {
   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
@@ -5150,7 +5102,7 @@
  * Returns          void
  *
  **************************************************************************/
-static bt_status_t send_passthrough_cmd(bt_bdaddr_t* bd_addr, uint8_t key_code,
+static bt_status_t send_passthrough_cmd(RawAddress* bd_addr, uint8_t key_code,
                                         uint8_t key_state) {
   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
   btif_rc_device_cb_t* p_dev = NULL;
diff --git a/btif/src/btif_sdp.cc b/btif/src/btif_sdp.cc
index 81b9a85..de39c42 100644
--- a/btif/src/btif_sdp.cc
+++ b/btif/src/btif_sdp.cc
@@ -64,12 +64,12 @@
 
 static void btif_sdp_search_comp_evt(uint16_t event, char* p_param) {
   tBTA_SDP_SEARCH_COMP* evt_data = (tBTA_SDP_SEARCH_COMP*)p_param;
-  bt_bdaddr_t addr;
+  RawAddress addr;
   BTIF_TRACE_DEBUG("%s:  event = %d", __func__, event);
 
   if (event != BTA_SDP_SEARCH_COMP_EVT) return;
 
-  bdcpy(addr.address, evt_data->remote_addr);
+  addr = evt_data->remote_addr;
 
   HAL_CBACK(bt_sdp_callbacks, sdp_search_cb, (bt_status_t)evt_data->status,
             &addr, (uint8_t*)(evt_data->uuid.uu.uuid128),
@@ -137,12 +137,12 @@
   return BT_STATUS_SUCCESS;
 }
 
-static bt_status_t search(bt_bdaddr_t* bd_addr, const uint8_t* uuid) {
+static bt_status_t search(RawAddress* bd_addr, const uint8_t* uuid) {
   tSDP_UUID sdp_uuid;
   sdp_uuid.len = 16;
   memcpy(sdp_uuid.uu.uuid128, uuid, sizeof(sdp_uuid.uu.uuid128));
 
-  BTA_SdpSearch(bd_addr->address, &sdp_uuid);
+  BTA_SdpSearch(*bd_addr, &sdp_uuid);
 
   return BT_STATUS_SUCCESS;
 }
diff --git a/btif/src/btif_sock.cc b/btif/src/btif_sock.cc
index 2495d46..a41ab13 100644
--- a/btif/src/btif_sock.cc
+++ b/btif/src/btif_sock.cc
@@ -39,10 +39,9 @@
 static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
                                  const uint8_t* uuid, int channel, int* sock_fd,
                                  int flags, int app_uid);
-static bt_status_t btsock_connect(const bt_bdaddr_t* bd_addr,
-                                  btsock_type_t type, const uint8_t* uuid,
-                                  int channel, int* sock_fd, int flags,
-                                  int app_uid);
+static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type,
+                                  const uint8_t* uuid, int channel,
+                                  int* sock_fd, int flags, int app_uid);
 
 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
 
@@ -154,10 +153,9 @@
   return status;
 }
 
-static bt_status_t btsock_connect(const bt_bdaddr_t* bd_addr,
-                                  btsock_type_t type, const uint8_t* uuid,
-                                  int channel, int* sock_fd, int flags,
-                                  int app_uid) {
+static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type,
+                                  const uint8_t* uuid, int channel,
+                                  int* sock_fd, int flags, int app_uid) {
   CHECK(uuid != NULL || channel > 0);
   CHECK(bd_addr != NULL);
   CHECK(sock_fd != NULL);
diff --git a/btif/src/btif_sock_l2cap.cc b/btif/src/btif_sock_l2cap.cc
index d839b55..90e3755 100644
--- a/btif/src/btif_sock_l2cap.cc
+++ b/btif/src/btif_sock_l2cap.cc
@@ -1,19 +1,19 @@
 /*
-* Copyright (C) 2014 Samsung System LSI
-* Copyright (C) 2013 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.
-*/
+ * Copyright (C) 2014 Samsung System LSI
+ * Copyright (C) 2013 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.
+ */
 
 #define LOG_TAG "bt_btif_sock"
 
@@ -62,7 +62,7 @@
 typedef struct l2cap_socket {
   struct l2cap_socket* prev;  // link to prev list item
   struct l2cap_socket* next;  // link to next list item
-  bt_bdaddr_t addr;           // other side's address
+  RawAddress addr;            // other side's address
   char name[256];             // user-friendly name of the service
   uint32_t id;                // just a tag to find this struct
   int app_uid;                // The UID of the app who requested this socket
@@ -197,14 +197,6 @@
   return true;
 }
 
-static inline void bd_copy(uint8_t* dest, uint8_t* src, bool swap) {
-  if (swap) {
-    for (int i = 0; i < 6; i++) dest[i] = src[5 - i];
-  } else {
-    memcpy(dest, src, 6);
-  }
-}
-
 static char is_inited(void) {
   std::unique_lock<std::mutex> lock(state_lock);
   return pth != -1;
@@ -281,7 +273,7 @@
 }
 
 static l2cap_socket* btsock_l2cap_alloc_l(const char* name,
-                                          const bt_bdaddr_t* addr,
+                                          const RawAddress* addr,
                                           char is_server, int flags) {
   unsigned security = 0;
   int fds[2];
@@ -364,9 +356,8 @@
                        sizeof(sock->channel)) == sizeof(sock->channel);
 }
 
-static bool send_app_connect_signal(int fd, const bt_bdaddr_t* addr,
-                                    int channel, int status, int send_fd,
-                                    int tx_mtu) {
+static bool send_app_connect_signal(int fd, const RawAddress* addr, int channel,
+                                    int status, int send_fd, int tx_mtu) {
   sock_connect_signal_t cs;
   cs.size = sizeof(cs);
   cs.bd_addr = *addr;
@@ -442,8 +433,7 @@
   uint32_t new_listen_id;
 
   // std::mutex locked by caller
-  accept_rs = btsock_l2cap_alloc_l(
-      sock->name, (const bt_bdaddr_t*)p_open->rem_bda, false, 0);
+  accept_rs = btsock_l2cap_alloc_l(sock->name, &p_open->rem_bda, false, 0);
   accept_rs->connected = true;
   accept_rs->security = sock->security;
   accept_rs->fixed_chan = sock->fixed_chan;
@@ -490,8 +480,7 @@
   uint32_t new_listen_id;
 
   // std::mutex locked by caller
-  accept_rs = btsock_l2cap_alloc_l(
-      sock->name, (const bt_bdaddr_t*)p_open->rem_bda, false, 0);
+  accept_rs = btsock_l2cap_alloc_l(sock->name, &p_open->rem_bda, false, 0);
   if (accept_rs) {
     // swap IDs
     new_listen_id = accept_rs->id;
@@ -527,7 +516,7 @@
 
 static void on_cl_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open,
                                       l2cap_socket* sock) {
-  bd_copy(sock->addr.address, p_open->rem_bda, 0);
+  sock->addr = p_open->rem_bda;
 
   if (!send_app_psm_or_chan_l(sock)) {
     APPL_TRACE_ERROR("send_app_psm_or_chan_l failed");
@@ -550,7 +539,7 @@
 
 static void on_cl_l2cap_le_connect_l(tBTA_JV_L2CAP_LE_OPEN* p_open,
                                      l2cap_socket* sock) {
-  bd_copy(sock->addr.address, p_open->rem_bda, 0);
+  sock->addr = p_open->rem_bda;
 
   if (!send_app_psm_or_chan_l(sock)) {
     APPL_TRACE_ERROR("send_app_psm_or_chan_l failed");
@@ -875,7 +864,7 @@
 }
 
 static bt_status_t btsock_l2cap_listen_or_connect(const char* name,
-                                                  const bt_bdaddr_t* addr,
+                                                  const RawAddress* addr,
                                                   int channel, int* sock_fd,
                                                   int flags, char listen,
                                                   int app_uid) {
@@ -926,7 +915,7 @@
   } else {
     if (fixed_chan) {
       if (BTA_JvL2capConnectLE(sock->security, 0, NULL, channel,
-                               L2CAP_DEFAULT_MTU, NULL, sock->addr.address,
+                               L2CAP_DEFAULT_MTU, NULL, sock->addr,
                                btsock_l2cap_cbk, sock->id) != BTA_JV_SUCCESS)
         stat = BT_STATUS_FAIL;
 
@@ -934,13 +923,13 @@
       if (sock->is_le_coc) {
         if (BTA_JvL2capConnect(BTA_JV_CONN_TYPE_L2CAP_LE, sock->security, 0,
                                NULL, channel, L2CAP_MAX_SDU_LENGTH, &cfg,
-                               sock->addr.address, btsock_l2cap_cbk,
+                               sock->addr, btsock_l2cap_cbk,
                                sock->id) != BTA_JV_SUCCESS)
           stat = BT_STATUS_FAIL;
       } else {
         if (BTA_JvL2capConnect(BTA_JV_CONN_TYPE_L2CAP, sock->security, 0,
                                &obex_l2c_etm_opt, channel, L2CAP_MAX_SDU_LENGTH,
-                               &cfg, sock->addr.address, btsock_l2cap_cbk,
+                               &cfg, sock->addr, btsock_l2cap_cbk,
                                sock->id) != BTA_JV_SUCCESS)
           stat = BT_STATUS_FAIL;
       }
@@ -972,7 +961,7 @@
                                         app_uid);
 }
 
-bt_status_t btsock_l2cap_connect(const bt_bdaddr_t* bd_addr, int channel,
+bt_status_t btsock_l2cap_connect(const RawAddress* bd_addr, int channel,
                                  int* sock_fd, int flags, int app_uid) {
   return btsock_l2cap_listen_or_connect(NULL, bd_addr, channel, sock_fd, flags,
                                         0, app_uid);
@@ -1050,7 +1039,7 @@
             "btsock_l2cap_signaled - %d bytes received from socket", count);
 
         if (sock->fixed_chan) {
-          if (BTA_JvL2capWriteFixed(sock->channel, (BD_ADDR*)&sock->addr,
+          if (BTA_JvL2capWriteFixed(sock->channel, sock->addr,
                                     PTR_TO_UINT(buffer), btsock_l2cap_cbk,
                                     buffer, count, user_id) != BTA_JV_SUCCESS) {
             // On fail, free the buffer
diff --git a/btif/src/btif_sock_rfc.cc b/btif/src/btif_sock_rfc.cc
index 1db39ae..2ea2a15 100644
--- a/btif/src/btif_sock_rfc.cc
+++ b/btif/src/btif_sock_rfc.cc
@@ -80,7 +80,7 @@
   int security;
   int scn;  // Server channel number
   int scn_notified;
-  bt_bdaddr_t addr;
+  RawAddress addr;
   int is_service_uuid_valid;
   uint8_t service_uuid[16];
   char service_name[256];
@@ -180,7 +180,7 @@
   return false;
 }
 
-static rfc_slot_t* alloc_rfc_slot(const bt_bdaddr_t* addr, const char* name,
+static rfc_slot_t* alloc_rfc_slot(const RawAddress* addr, const char* name,
                                   const uint8_t* uuid, int channel, int flags,
                                   bool server) {
   int security = 0;
@@ -236,7 +236,7 @@
 }
 
 static rfc_slot_t* create_srv_accept_rfc_slot(rfc_slot_t* srv_rs,
-                                              const bt_bdaddr_t* addr,
+                                              const RawAddress* addr,
                                               int open_handle,
                                               int new_listen_handle) {
   rfc_slot_t* accept_rs = alloc_rfc_slot(
@@ -328,7 +328,7 @@
   return BT_STATUS_SUCCESS;
 }
 
-bt_status_t btsock_rfc_connect(const bt_bdaddr_t* bd_addr,
+bt_status_t btsock_rfc_connect(const RawAddress* bd_addr,
                                const uint8_t* service_uuid, int channel,
                                int* sock_fd, int flags, int app_uid) {
   CHECK(sock_fd != NULL);
@@ -353,8 +353,8 @@
 
   if (is_uuid_empty(service_uuid)) {
     tBTA_JV_STATUS ret =
-        BTA_JvRfcommConnect(slot->security, slot->role, slot->scn,
-                            slot->addr.address, rfcomm_cback, slot->id);
+        BTA_JvRfcommConnect(slot->security, slot->role, slot->scn, slot->addr,
+                            rfcomm_cback, slot->id);
     if (ret != BTA_JV_SUCCESS) {
       LOG_ERROR(LOG_TAG, "%s unable to initiate RFCOMM connection: %d",
                 __func__, ret);
@@ -373,7 +373,7 @@
     memcpy(sdp_uuid.uu.uuid128, service_uuid, sizeof(sdp_uuid.uu.uuid128));
 
     if (!is_requesting_sdp()) {
-      BTA_JvStartDiscovery((uint8_t*)bd_addr->address, 1, &sdp_uuid, slot->id);
+      BTA_JvStartDiscovery(*bd_addr, 1, &sdp_uuid, slot->id);
       slot->f.pending_sdp_request = false;
       slot->f.doing_sdp_request = true;
     } else {
@@ -453,8 +453,8 @@
                        sizeof(slot->scn)) == sizeof(slot->scn);
 }
 
-static bool send_app_connect_signal(int fd, const bt_bdaddr_t* addr,
-                                    int channel, int status, int send_fd) {
+static bool send_app_connect_signal(int fd, const RawAddress* addr, int channel,
+                                    int status, int send_fd) {
   sock_connect_signal_t cs;
   cs.size = sizeof(cs);
   cs.bd_addr = *addr;
@@ -501,9 +501,8 @@
   rfc_slot_t* srv_rs = find_rfc_slot_by_id(id);
   if (!srv_rs) return 0;
 
-  accept_rs =
-      create_srv_accept_rfc_slot(srv_rs, (const bt_bdaddr_t*)p_open->rem_bda,
-                                 p_open->handle, p_open->new_listen_handle);
+  accept_rs = create_srv_accept_rfc_slot(
+      srv_rs, &p_open->rem_bda, p_open->handle, p_open->new_listen_handle);
   if (!accept_rs) return 0;
 
   // Start monitoring the socket.
@@ -529,7 +528,7 @@
   }
 
   slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_open->handle);
-  memcpy(slot->addr.address, p_open->rem_bda, 6);
+  slot->addr = p_open->rem_bda;
 
   if (send_app_connect_signal(slot->fd, &slot->addr, slot->scn, 0, -1)) {
     slot->f.connected = true;
@@ -710,7 +709,7 @@
           // Establish the connection if we successfully looked up a channel
           // number to connect to.
           if (BTA_JvRfcommConnect(slot->security, slot->role,
-                                  p_data->disc_comp.scn, slot->addr.address,
+                                  p_data->disc_comp.scn, slot->addr,
                                   rfcomm_cback, slot->id) == BTA_JV_SUCCESS) {
             slot->scn = p_data->disc_comp.scn;
             slot->f.doing_sdp_request = false;
@@ -737,8 +736,7 @@
         sdp_uuid.len = 16;
         memcpy(sdp_uuid.uu.uuid128, slot->service_uuid,
                sizeof(sdp_uuid.uu.uuid128));
-        BTA_JvStartDiscovery((uint8_t*)slot->addr.address, 1, &sdp_uuid,
-                             slot->id);
+        BTA_JvStartDiscovery(slot->addr, 1, &sdp_uuid, slot->id);
         slot->f.pending_sdp_request = false;
         slot->f.doing_sdp_request = true;
       }
diff --git a/btif/src/btif_sock_sco.cc b/btif/src/btif_sock_sco.cc
index 60d948b..f3e2bb9 100644
--- a/btif/src/btif_sock_sco.cc
+++ b/btif/src/btif_sock_sco.cc
@@ -65,7 +65,7 @@
 } sco_socket_t;
 
 static sco_socket_t* sco_socket_establish_locked(bool is_listening,
-                                                 const bt_bdaddr_t* bd_addr,
+                                                 const RawAddress* bd_addr,
                                                  int* sock_fd);
 static sco_socket_t* sco_socket_new(void);
 static void sco_socket_free_locked(sco_socket_t* socket);
@@ -116,7 +116,7 @@
   return BT_STATUS_SUCCESS;
 }
 
-bt_status_t btsock_sco_connect(const bt_bdaddr_t* bd_addr, int* sock_fd,
+bt_status_t btsock_sco_connect(const RawAddress* bd_addr, int* sock_fd,
                                UNUSED_ATTR int flags) {
   CHECK(bd_addr != NULL);
   CHECK(sock_fd != NULL);
@@ -130,7 +130,7 @@
 
 // Must be called with |lock| held.
 static sco_socket_t* sco_socket_establish_locked(bool is_listening,
-                                                 const bt_bdaddr_t* bd_addr,
+                                                 const RawAddress* bd_addr,
                                                  int* sock_fd) {
   int pair[2] = {INVALID_FD, INVALID_FD};
   sco_socket_t* sco_socket = NULL;
@@ -150,7 +150,7 @@
   }
 
   params = esco_parameters_for_codec(ESCO_CODEC_CVSD);
-  status = BTM_CreateSco((uint8_t*)bd_addr, !is_listening, params.packet_types,
+  status = BTM_CreateSco(bd_addr, !is_listening, params.packet_types,
                          &sco_socket->sco_handle, connect_completed_cb,
                          disconnect_completed_cb);
   if (status != BTM_CMD_STARTED) {
@@ -252,7 +252,7 @@
 
   sock_connect_signal_t connect_signal;
   connect_signal.size = sizeof(connect_signal);
-  memcpy(&connect_signal.bd_addr, conn_data->bd_addr, sizeof(bt_bdaddr_t));
+  connect_signal.bd_addr = conn_data->bd_addr;
   connect_signal.channel = 0;
   connect_signal.status = 0;
 
diff --git a/btif/src/btif_storage.cc b/btif/src/btif_storage.cc
index c8dfcde..a8fe686 100644
--- a/btif/src/btif_storage.cc
+++ b/btif/src/btif_storage.cc
@@ -35,6 +35,7 @@
 #include <alloca.h>
 #include <base/logging.h>
 #include <ctype.h>
+#include <log/log.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
@@ -42,7 +43,6 @@
 #include "bt_common.h"
 #include "bta_hd_api.h"
 #include "bta_hh_api.h"
-#include "btcore/include/bdaddr.h"
 #include "btif_api.h"
 #include "btif_config.h"
 #include "btif_hd.h"
@@ -154,14 +154,14 @@
  ******************************************************************************/
 typedef struct {
   uint32_t num_devices;
-  bt_bdaddr_t devices[BTM_SEC_MAX_DEVICE_RECORDS];
+  RawAddress devices[BTM_SEC_MAX_DEVICE_RECORDS];
 } btif_bonded_devices_t;
 
 /*******************************************************************************
  *  External functions
  ******************************************************************************/
 
-extern void btif_gatts_add_bonded_dev_from_nv(BD_ADDR bda);
+extern void btif_gatts_add_bonded_dev_from_nv(const RawAddress& bda);
 
 /*******************************************************************************
  *  Internal Functions
@@ -178,9 +178,14 @@
  *  Static functions
  ******************************************************************************/
 
-static int prop2cfg(bt_bdaddr_t* remote_bd_addr, bt_property_t* prop) {
-  bdstr_t bdstr = {0};
-  if (remote_bd_addr) bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+static int prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) {
+  std::string addrstr;
+  const char* bdstr = addrstr.c_str();
+  if (remote_bd_addr) {
+    addrstr = remote_bd_addr->ToString();
+    bdstr = addrstr.c_str();
+  }
+
   BTIF_TRACE_DEBUG("in, bd addr:%s, prop type:%d, len:%d", bdstr, prop->type,
                    prop->len);
   char value[1024];
@@ -268,9 +273,13 @@
   return true;
 }
 
-static int cfg2prop(bt_bdaddr_t* remote_bd_addr, bt_property_t* prop) {
-  bdstr_t bdstr = {0};
-  if (remote_bd_addr) bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+static int cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) {
+  std::string addrstr;
+  const char* bdstr = addrstr.c_str();
+  if (remote_bd_addr) {
+    addrstr = remote_bd_addr->ToString();
+    bdstr = addrstr.c_str();
+  }
   BTIF_TRACE_DEBUG("in, bd addr:%s, prop type:%d, len:%d", bdstr, prop->type,
                    prop->len);
   if (prop->len <= 0) {
@@ -426,7 +435,7 @@
        iter != btif_config_section_end();
        iter = btif_config_section_next(iter)) {
     const char* name = btif_config_section_name(iter);
-    if (!string_is_bdaddr(name)) continue;
+    if (!RawAddress::IsValidAddress(name)) continue;
 
     BTIF_TRACE_DEBUG("Remote device:%s", name);
     LINK_KEY link_key;
@@ -434,8 +443,8 @@
     if (btif_config_get_bin(name, "LinkKey", link_key, &size)) {
       int linkkey_type;
       if (btif_config_get_int(name, "LinkKeyType", &linkkey_type)) {
-        bt_bdaddr_t bd_addr;
-        string_to_bdaddr(name, &bd_addr);
+        RawAddress bd_addr;
+        RawAddress::FromString(name, bd_addr);
         if (add) {
           DEV_CLASS dev_class = {0, 0, 0};
           int cod;
@@ -443,17 +452,16 @@
           if (btif_config_get_int(name, "DevClass", &cod))
             uint2devclass((uint32_t)cod, dev_class);
           btif_config_get_int(name, "PinLength", &pin_length);
-          BTA_DmAddDevice(bd_addr.address, dev_class, link_key, 0, 0,
+          BTA_DmAddDevice(bd_addr, dev_class, link_key, 0, 0,
                           (uint8_t)linkkey_type, 0, pin_length);
 
           if (btif_config_get_int(name, "DevType", &device_type) &&
               (device_type == BT_DEVICE_TYPE_DUMO)) {
-            btif_gatts_add_bonded_dev_from_nv(bd_addr.address);
+            btif_gatts_add_bonded_dev_from_nv(bd_addr);
           }
         }
         bt_linkkey_file_found = true;
-        memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++],
-               &bd_addr, sizeof(bt_bdaddr_t));
+        p_bonded_devices->devices[p_bonded_devices->num_devices++] = bd_addr;
       } else {
         bt_linkkey_file_found = false;
       }
@@ -467,7 +475,7 @@
 }
 
 static void btif_read_le_key(const uint8_t key_type, const size_t key_len,
-                             bt_bdaddr_t bd_addr, const uint8_t addr_type,
+                             RawAddress bd_addr, const uint8_t addr_type,
                              const bool add_key, bool* device_added,
                              bool* key_found) {
   CHECK(device_added);
@@ -479,18 +487,14 @@
   if (btif_storage_get_ble_bonding_key(&bd_addr, key_type, buffer, key_len) ==
       BT_STATUS_SUCCESS) {
     if (add_key) {
-      BD_ADDR bta_bd_addr;
-      bdcpy(bta_bd_addr, bd_addr.address);
-
       if (!*device_added) {
-        BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
+        BTA_DmAddBleDevice(bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
         *device_added = true;
       }
 
-      char bd_str[20] = {0};
       BTIF_TRACE_DEBUG("%s() Adding key type %d for %s", __func__, key_type,
-                       bdaddr_to_string(&bd_addr, bd_str, sizeof(bd_str)));
-      BTA_DmAddBleKey(bta_bd_addr, (tBTA_LE_KEY_VALUE*)buffer, key_type);
+                       bd_addr.ToString().c_str());
+      BTA_DmAddBleKey(bd_addr, (tBTA_LE_KEY_VALUE*)buffer, key_type);
     }
 
     *key_found = true;
@@ -548,22 +552,22 @@
  *
  ******************************************************************************/
 bt_status_t btif_storage_get_adapter_property(bt_property_t* property) {
-  /* Special handling for adapter BD_ADDR and BONDED_DEVICES */
+  /* Special handling for adapter address and BONDED_DEVICES */
   if (property->type == BT_PROPERTY_BDADDR) {
-    bt_bdaddr_t* bd_addr = (bt_bdaddr_t*)property->val;
+    RawAddress* bd_addr = (RawAddress*)property->val;
     /* Fetch the local BD ADDR */
     const controller_t* controller = controller_get_interface();
     if (controller->get_is_ready() == false) {
       LOG_ERROR(LOG_TAG,
                 "%s: Controller not ready! Unable to return Bluetooth Address",
                 __func__);
-      memset(bd_addr, 0, sizeof(bt_bdaddr_t));
+      *bd_addr = RawAddress::kEmpty;
       return BT_STATUS_FAIL;
     } else {
       LOG_ERROR(LOG_TAG, "%s: Controller ready!", __func__);
-      memcpy(bd_addr, controller->get_address(), sizeof(bt_bdaddr_t));
+      *bd_addr = *controller->get_address();
     }
-    property->len = sizeof(bt_bdaddr_t);
+    property->len = RawAddress::kLength;
     return BT_STATUS_SUCCESS;
   } else if (property->type == BT_PROPERTY_ADAPTER_BONDED_DEVICES) {
     btif_bonded_devices_t bonded_devices;
@@ -576,7 +580,7 @@
         __func__, bonded_devices.num_devices);
 
     if (bonded_devices.num_devices > 0) {
-      property->len = bonded_devices.num_devices * sizeof(bt_bdaddr_t);
+      property->len = bonded_devices.num_devices * RawAddress::kLength;
       memcpy(property->val, bonded_devices.devices, property->len);
     }
 
@@ -660,8 +664,8 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_get_remote_device_property(bt_bdaddr_t* remote_bd_addr,
-                                                    bt_property_t* property) {
+bt_status_t btif_storage_get_remote_device_property(
+    const RawAddress* remote_bd_addr, bt_property_t* property) {
   return cfg2prop(remote_bd_addr, property) ? BT_STATUS_SUCCESS
                                             : BT_STATUS_FAIL;
 }
@@ -676,8 +680,8 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_set_remote_device_property(bt_bdaddr_t* remote_bd_addr,
-                                                    bt_property_t* property) {
+bt_status_t btif_storage_set_remote_device_property(
+    const RawAddress* remote_bd_addr, bt_property_t* property) {
   return prop2cfg(remote_bd_addr, property) ? BT_STATUS_SUCCESS
                                             : BT_STATUS_FAIL;
 }
@@ -694,7 +698,7 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_add_remote_device(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_add_remote_device(const RawAddress* remote_bd_addr,
                                            uint32_t num_properties,
                                            bt_property_t* properties) {
   uint32_t i = 0;
@@ -704,7 +708,7 @@
     /* Ignore the RSSI as this is not stored in DB */
     if (properties[i].type == BT_PROPERTY_REMOTE_RSSI) continue;
 
-    /* BD_ADDR for remote device needs special handling as we also store
+    /* address for remote device needs special handling as we also store
      * timestamp */
     if (properties[i].type == BT_PROPERTY_BDADDR) {
       bt_property_t addr_prop;
@@ -730,11 +734,11 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_storage_add_bonded_device(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_add_bonded_device(RawAddress* remote_bd_addr,
                                            LINK_KEY link_key, uint8_t key_type,
                                            uint8_t pin_length) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+  std::string addrstr = remote_bd_addr->ToString();
+  const char* bdstr = addrstr.c_str();
   int ret = btif_config_set_int(bdstr, "LinkKeyType", (int)key_type);
   ret &= btif_config_set_int(bdstr, "PinLength", (int)pin_length);
   ret &= btif_config_set_bin(bdstr, "LinkKey", link_key, sizeof(LINK_KEY));
@@ -760,9 +764,10 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_remove_bonded_device(bt_bdaddr_t* remote_bd_addr) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+bt_status_t btif_storage_remove_bonded_device(
+    const RawAddress* remote_bd_addr) {
+  std::string addrstr = remote_bd_addr->ToString();
+  const char* bdstr = addrstr.c_str();
   BTIF_TRACE_DEBUG("in bd addr:%s", bdstr);
 
   btif_storage_remove_ble_bonding_keys(remote_bd_addr);
@@ -779,6 +784,47 @@
   return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
+/* Some devices hardcode sample LTK value from spec, instead of generating one.
+ * Treat such devices as insecure, and remove such bonds when bluetooth
+ * restarts. Removing them after disconnection is handled separately.
+ *
+ * We still allow such devices to bond in order to give the user a chance to
+ * update firmware.
+ */
+static void remove_devices_with_sample_ltk() {
+  std::vector<RawAddress> bad_ltk;
+  for (const btif_config_section_iter_t* iter = btif_config_section_begin();
+       iter != btif_config_section_end();
+       iter = btif_config_section_next(iter)) {
+    const std::string name(btif_config_section_name(iter));
+    if (!RawAddress::IsValidAddress(name)) {
+      continue;
+    }
+
+    RawAddress bd_addr;
+    RawAddress::FromString(name, bd_addr);
+
+    tBTA_LE_KEY_VALUE key;
+    memset(&key, 0, sizeof(key));
+
+    if (btif_storage_get_ble_bonding_key(
+            &bd_addr, BTIF_DM_LE_KEY_PENC, (char*)&key,
+            sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) {
+      if (is_sample_ltk(key.penc_key.ltk)) {
+        bad_ltk.push_back(bd_addr);
+      }
+    }
+  }
+
+  for (RawAddress address : bad_ltk) {
+    android_errorWriteLog(0x534e4554, "128437297");
+    LOG(ERROR) << __func__
+               << ": removing bond to device using test TLK: " << address;
+
+    btif_storage_remove_bonded_device(&address);
+  }
+}
+
 /*******************************************************************************
  *
  * Function         btif_storage_load_bonded_devices
@@ -798,7 +844,7 @@
   bt_property_t adapter_props[6];
   uint32_t num_props = 0;
   bt_property_t remote_properties[8];
-  bt_bdaddr_t addr;
+  RawAddress addr;
   bt_bdname_t name, alias;
   bt_scan_mode_t mode;
   uint32_t disc_timeout;
@@ -806,13 +852,15 @@
   bt_uuid_t remote_uuids[BT_MAX_NUM_UUIDS];
   bt_status_t status;
 
+  remove_devices_with_sample_ltk();
+
   btif_in_fetch_bonded_devices(&bonded_devices, 1);
 
   /* Now send the adapter_properties_cb with all adapter_properties */
   {
     memset(adapter_props, 0, sizeof(adapter_props));
 
-    /* BD_ADDR */
+    /* address */
     BTIF_STORAGE_GET_ADAPTER_PROP(status, BT_PROPERTY_BDADDR, &addr,
                                   sizeof(addr), adapter_props[num_props]);
     // Add BT_PROPERTY_BDADDR property into list only when successful.
@@ -844,14 +892,14 @@
     num_props++;
 
     /* BONDED_DEVICES */
-    bt_bdaddr_t* devices_list = (bt_bdaddr_t*)osi_malloc(
-        sizeof(bt_bdaddr_t) * bonded_devices.num_devices);
+    RawAddress* devices_list = (RawAddress*)osi_malloc(
+        sizeof(RawAddress) * bonded_devices.num_devices);
     adapter_props[num_props].type = BT_PROPERTY_ADAPTER_BONDED_DEVICES;
     adapter_props[num_props].len =
-        bonded_devices.num_devices * sizeof(bt_bdaddr_t);
+        bonded_devices.num_devices * sizeof(RawAddress);
     adapter_props[num_props].val = devices_list;
     for (i = 0; i < bonded_devices.num_devices; i++) {
-      memcpy(devices_list + i, &bonded_devices.devices[i], sizeof(bt_bdaddr_t));
+      devices_list[i] = bonded_devices.devices[i];
     }
     num_props++;
 
@@ -871,7 +919,7 @@
 
   {
     for (i = 0; i < bonded_devices.num_devices; i++) {
-      bt_bdaddr_t* p_remote_addr;
+      RawAddress* p_remote_addr;
 
       /*
        * TODO: improve handling of missing fields in NVRAM.
@@ -925,11 +973,9 @@
  *
  ******************************************************************************/
 
-bt_status_t btif_storage_add_ble_bonding_key(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_add_ble_bonding_key(RawAddress* remote_bd_addr,
                                              char* key, uint8_t key_type,
                                              uint8_t key_length) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
   const char* name;
   switch (key_type) {
     case BTIF_DM_LE_KEY_PENC:
@@ -953,7 +999,8 @@
     default:
       return BT_STATUS_FAIL;
   }
-  int ret = btif_config_set_bin(bdstr, name, (const uint8_t*)key, key_length);
+  int ret = btif_config_set_bin(remote_bd_addr->ToString().c_str(), name,
+                                (const uint8_t*)key, key_length);
   btif_config_save();
   return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
@@ -968,11 +1015,9 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_get_ble_bonding_key(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_get_ble_bonding_key(RawAddress* remote_bd_addr,
                                              uint8_t key_type, char* key_value,
                                              int key_length) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
   const char* name;
   switch (key_type) {
     case BTIF_DM_LE_KEY_PENC:
@@ -996,7 +1041,8 @@
       return BT_STATUS_FAIL;
   }
   size_t length = key_length;
-  int ret = btif_config_get_bin(bdstr, name, (uint8_t*)key_value, &length);
+  int ret = btif_config_get_bin(remote_bd_addr->ToString().c_str(), name,
+                                (uint8_t*)key_value, &length);
   return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
@@ -1010,9 +1056,10 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_remove_ble_bonding_keys(bt_bdaddr_t* remote_bd_addr) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+bt_status_t btif_storage_remove_ble_bonding_keys(
+    const RawAddress* remote_bd_addr) {
+  std::string addrstr = remote_bd_addr->ToString();
+  const char* bdstr = addrstr.c_str();
   BTIF_TRACE_DEBUG(" %s in bd addr:%s", __func__, bdstr);
   int ret = 1;
   if (btif_config_exist(bdstr, "LE_KEY_PENC"))
@@ -1127,8 +1174,6 @@
     btif_bonded_devices_t* p_bonded_devices) {
   int device_type;
   int addr_type;
-  bt_bdaddr_t bd_addr;
-  BD_ADDR bta_bd_addr;
   bool device_added = false;
   bool key_found = false;
 
@@ -1139,8 +1184,8 @@
       btif_has_ble_keys(remote_bd_addr)) {
     BTIF_TRACE_DEBUG("%s Found a LE device: %s", __func__, remote_bd_addr);
 
-    string_to_bdaddr(remote_bd_addr, &bd_addr);
-    bdcpy(bta_bd_addr, bd_addr.address);
+    RawAddress bd_addr;
+    RawAddress::FromString(remote_bd_addr, bd_addr);
 
     if (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) !=
         BT_STATUS_SUCCESS) {
@@ -1168,9 +1213,8 @@
 
     // Fill in the bonded devices
     if (device_added) {
-      memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++],
-             &bd_addr, sizeof(bt_bdaddr_t));
-      btif_gatts_add_bonded_dev_from_nv(bta_bd_addr);
+      p_bonded_devices->devices[p_bonded_devices->num_devices++] = bd_addr;
+      btif_gatts_add_bonded_dev_from_nv(bd_addr);
     }
 
     if (key_found) return BT_STATUS_SUCCESS;
@@ -1178,11 +1222,10 @@
   return BT_STATUS_FAIL;
 }
 
-bt_status_t btif_storage_set_remote_addr_type(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_set_remote_addr_type(const RawAddress* remote_bd_addr,
                                               uint8_t addr_type) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
-  int ret = btif_config_set_int(bdstr, "AddrType", (int)addr_type);
+  int ret = btif_config_set_int(remote_bd_addr->ToString().c_str(), "AddrType",
+                                (int)addr_type);
   return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 
@@ -1200,11 +1243,10 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_get_remote_addr_type(bt_bdaddr_t* remote_bd_addr,
+bt_status_t btif_storage_get_remote_addr_type(const RawAddress* remote_bd_addr,
                                               int* addr_type) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
-  int ret = btif_config_get_int(bdstr, "AddrType", addr_type);
+  int ret = btif_config_get_int(remote_bd_addr->ToString().c_str(), "AddrType",
+                                addr_type);
   return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
 }
 /*******************************************************************************
@@ -1220,13 +1262,13 @@
  ******************************************************************************/
 
 bt_status_t btif_storage_add_hid_device_info(
-    bt_bdaddr_t* remote_bd_addr, uint16_t attr_mask, uint8_t sub_class,
+    RawAddress* remote_bd_addr, uint16_t attr_mask, uint8_t sub_class,
     uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version,
     uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout,
     uint16_t dl_len, uint8_t* dsc_list) {
-  bdstr_t bdstr;
   BTIF_TRACE_DEBUG("btif_storage_add_hid_device_info:");
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+  std::string addrstr = remote_bd_addr->ToString();
+  const char* bdstr = addrstr.c_str();
   btif_config_set_int(bdstr, "HidAttrMask", attr_mask);
   btif_config_set_int(bdstr, "HidSubClass", sub_class);
   btif_config_set_int(bdstr, "HidAppId", app_id);
@@ -1252,7 +1294,7 @@
  *
  ******************************************************************************/
 bt_status_t btif_storage_load_bonded_hid_info(void) {
-  bt_bdaddr_t bd_addr;
+  RawAddress bd_addr;
   tBTA_HH_DEV_DSCP_INFO dscp_info;
   uint16_t attr_mask;
   uint8_t sub_class;
@@ -1263,7 +1305,7 @@
        iter != btif_config_section_end();
        iter = btif_config_section_next(iter)) {
     const char* name = btif_config_section_name(iter);
-    if (!string_is_bdaddr(name)) continue;
+    if (!RawAddress::IsValidAddress(name)) continue;
 
     BTIF_TRACE_DEBUG("Remote device:%s", name);
     int value;
@@ -1304,17 +1346,16 @@
           btif_config_get_bin(name, "HidDescriptor",
                               (uint8_t*)dscp_info.descriptor.dsc_list, &len);
         }
-        string_to_bdaddr(name, &bd_addr);
+        RawAddress::FromString(name, bd_addr);
         // add extracted information to BTA HH
         if (btif_hh_add_added_dev(bd_addr, attr_mask)) {
-          BTA_HhAddDev(bd_addr.address, attr_mask, sub_class, app_id,
-                       dscp_info);
+          BTA_HhAddDev(bd_addr, attr_mask, sub_class, app_id, dscp_info);
         }
       }
     } else {
       if (btif_config_get_int(name, "HidAttrMask", &value)) {
         btif_storage_remove_hid_info(&bd_addr);
-        string_to_bdaddr(name, &bd_addr);
+        RawAddress::FromString(name, bd_addr);
       }
     }
   }
@@ -1333,9 +1374,9 @@
  *                  BT_STATUS_FAIL otherwise
  *
  ******************************************************************************/
-bt_status_t btif_storage_remove_hid_info(bt_bdaddr_t* remote_bd_addr) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
+bt_status_t btif_storage_remove_hid_info(RawAddress* remote_bd_addr) {
+  std::string addrstr = remote_bd_addr->ToString();
+  const char* bdstr = addrstr.c_str();
 
   btif_config_remove(bdstr, "HidAttrMask");
   btif_config_remove(bdstr, "HidSubClass");
@@ -1362,11 +1403,8 @@
  *                  false otherwise
  *
  ******************************************************************************/
-bool btif_storage_is_restricted_device(const bt_bdaddr_t* remote_bd_addr) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
-
-  return btif_config_exist(bdstr, "Restricted");
+bool btif_storage_is_restricted_device(const RawAddress* remote_bd_addr) {
+  return btif_config_exist(remote_bd_addr->ToString().c_str(), "Restricted");
 }
 
 /*******************************************************************************
@@ -1378,20 +1416,20 @@
  *
  ******************************************************************************/
 bt_status_t btif_storage_load_hidd(void) {
-  bt_bdaddr_t bd_addr;
 
   for (const btif_config_section_iter_t* iter = btif_config_section_begin();
        iter != btif_config_section_end();
        iter = btif_config_section_next(iter)) {
     const char* name = btif_config_section_name(iter);
-    if (!string_is_bdaddr(name)) continue;
+    if (!RawAddress::IsValidAddress(name)) continue;
 
     BTIF_TRACE_DEBUG("Remote device:%s", name);
     int value;
     if (btif_in_fetch_bonded_device(name) == BT_STATUS_SUCCESS) {
       if (btif_config_get_int(name, "HidDeviceCabled", &value)) {
-        string_to_bdaddr(name, &bd_addr);
-        BTA_HdAddDevice(bd_addr.address);
+        RawAddress bd_addr;
+        RawAddress::FromString(name, bd_addr);
+        BTA_HdAddDevice(bd_addr);
         break;
       }
     }
@@ -1409,10 +1447,8 @@
  * Returns          BT_STATUS_SUCCESS
  *
  ******************************************************************************/
-bt_status_t btif_storage_set_hidd(bt_bdaddr_t* remote_bd_addr) {
-  bdstr_t bdstr = {0};
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
-  btif_config_set_int(bdstr, "HidDeviceCabled", 1);
+bt_status_t btif_storage_set_hidd(RawAddress* remote_bd_addr) {
+  btif_config_set_int(remote_bd_addr->ToString().c_str(), "HidDeviceCabled", 1);
   btif_config_save();
   return BT_STATUS_SUCCESS;
 }
@@ -1426,25 +1462,21 @@
  * Returns          BT_STATUS_SUCCESS
  *
  ******************************************************************************/
-bt_status_t btif_storage_remove_hidd(bt_bdaddr_t* remote_bd_addr) {
-  bdstr_t bdstr;
-  bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
-
-  btif_config_remove(bdstr, "HidDeviceCabled");
+bt_status_t btif_storage_remove_hidd(RawAddress* remote_bd_addr) {
+  btif_config_remove(remote_bd_addr->ToString().c_str(), "HidDeviceCabled");
   btif_config_save();
 
   return BT_STATUS_SUCCESS;
 }
 
 // Get the name of a device from btif for interop database matching.
-bool btif_storage_get_stored_remote_name(const bt_bdaddr_t& bd_addr,
+bool btif_storage_get_stored_remote_name(const RawAddress& bd_addr,
                                          char* name) {
   bt_property_t property;
   property.type = BT_PROPERTY_BDNAME;
   property.len = BTM_MAX_REM_BD_NAME_LEN;
   property.val = name;
 
-  return (btif_storage_get_remote_device_property(
-              const_cast<bt_bdaddr_t*>(&bd_addr), &property) ==
+  return (btif_storage_get_remote_device_property(&bd_addr, &property) ==
           BT_STATUS_SUCCESS);
 }
diff --git a/btif/src/stack_manager.cc b/btif/src/stack_manager.cc
index 56f8c64..eb0ac22 100644
--- a/btif/src/stack_manager.cc
+++ b/btif/src/stack_manager.cc
@@ -177,10 +177,10 @@
                                                     // puts it in a restartable
                                                     // state
 
-  LOG_INFO(LOG_TAG, "%s finished", __func__);
   hack_future = future_new();
   btif_thread_post(event_signal_stack_down, NULL);
   future_await(hack_future);
+  LOG_INFO(LOG_TAG, "%s finished", __func__);
 }
 
 static void ensure_stack_is_not_running(void) {
diff --git a/btif/test/btif_profile_queue_test.cc b/btif/test/btif_profile_queue_test.cc
index 199844e..79a283f 100644
--- a/btif/test/btif_profile_queue_test.cc
+++ b/btif/test/btif_profile_queue_test.cc
@@ -19,6 +19,7 @@
 
 #include "btif/include/btif_profile_queue.h"
 #include "stack_manager.h"
+#include "types/raw_address.h"
 
 static bool sStackRunning;
 
@@ -53,8 +54,8 @@
  public:
   static const uint16_t kTestUuid1 = 0x9527;
   static const uint16_t kTestUuid2 = 0x819F;
-  static const bt_bdaddr_t kTestAddr1;
-  static const bt_bdaddr_t kTestAddr2;
+  static const RawAddress kTestAddr1;
+  static const RawAddress kTestAddr2;
 
  protected:
   void SetUp() override {
@@ -64,21 +65,20 @@
   void TearDown() override { btif_queue_release(); };
 };
 
-const bt_bdaddr_t BtifProfileQueueTest::kTestAddr1{
+const RawAddress BtifProfileQueueTest::kTestAddr1{
     {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
-const bt_bdaddr_t BtifProfileQueueTest::kTestAddr2{
+const RawAddress BtifProfileQueueTest::kTestAddr2{
     {0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56}};
 
-static bt_status_t test_connect_cb(bt_bdaddr_t* bda, uint16_t uuid) {
+static bt_status_t test_connect_cb(RawAddress* bda, uint16_t uuid) {
   sResult = UNKNOWN;
-  if (!memcmp(bda, &BtifProfileQueueTest::kTestAddr1, sizeof(bt_bdaddr_t))) {
+  if (*bda == BtifProfileQueueTest::kTestAddr1) {
     if (uuid == BtifProfileQueueTest::kTestUuid1) {
       sResult = UUID1_ADDR1;
     } else if (uuid == BtifProfileQueueTest::kTestUuid2) {
       sResult = UUID2_ADDR1;
     }
-  } else if (!memcmp(bda, &BtifProfileQueueTest::kTestAddr2,
-                     sizeof(bt_bdaddr_t))) {
+  } else if (*bda == BtifProfileQueueTest::kTestAddr2) {
     if (uuid == BtifProfileQueueTest::kTestUuid1) {
       sResult = UUID1_ADDR2;
     } else if (uuid == BtifProfileQueueTest::kTestUuid2) {
diff --git a/build/Android.bp b/build/Android.bp
index 2422430..fc6eae8 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -15,7 +15,7 @@
 }
 
 fluoride_defaults {
-    name: "fluoride_defaults",
+    name: "fluoride_types_defaults",
     cflags: [
         "-DEXPORT_SYMBOL=__attribute__((visibility(\"default\")))",
         "-fvisibility=hidden",
@@ -45,3 +45,11 @@
     shared_libs: [ "libchrome" ]
     // Setup Bluetooth local make variables for handling configuration
 }
+
+fluoride_defaults {
+    name: "fluoride_defaults",
+    defaults: ["fluoride_types_defaults"],
+    static_libs: [
+        "libbluetooth-types",
+    ],
+}
diff --git a/build/BUILD.gn b/build/BUILD.gn
index ebebf3d..af7d5d8 100644
--- a/build/BUILD.gn
+++ b/build/BUILD.gn
@@ -17,6 +17,7 @@
 config("default_include_dirs") {
   include_dirs = [
     "//third_party/libhardware/include/",
+    "//types/",
   ]
 }
 
diff --git a/build/fluoride.go b/build/fluoride.go
index c96d5fe..7b9ac97 100644
--- a/build/fluoride.go
+++ b/build/fluoride.go
@@ -14,52 +14,50 @@
 package fluoride
 
 import (
-  "strings"
+	"strings"
 
-  "android/soong/android"
-  "android/soong/cc"
-
-  "github.com/google/blueprint"
+	"android/soong/android"
+	"android/soong/cc"
 )
 
 func init() {
-  android.RegisterModuleType("fluoride_defaults", fluorideDefaultsFactory)
+	android.RegisterModuleType("fluoride_defaults", fluorideDefaultsFactory)
 }
 
-func fluorideDefaultsFactory() (blueprint.Module, []interface{}) {
-  module, props := cc.DefaultsFactory()
-  android.AddLoadHook(module, fluorideDefaults)
+func fluorideDefaultsFactory() android.Module {
+	module := cc.DefaultsFactory()
+	android.AddLoadHook(module, fluorideDefaults)
 
-  return module, props
+	return module
 }
 
 func fluorideDefaults(ctx android.LoadHookContext) {
-  type props struct {
-    Include_dirs []string
-    Cflags []string
-  }
+	type props struct {
+		Include_dirs []string
+		Cflags       []string
+	}
 
-  p := &props{}
-  p.Cflags, p.Include_dirs = globalDefaults(ctx)
+	p := &props{}
+	p.Cflags, p.Include_dirs = globalDefaults(ctx)
 
-  ctx.AppendProperties(p)
+	ctx.AppendProperties(p)
 }
 
 func globalDefaults(ctx android.BaseContext) ([]string, []string) {
-  var cflags []string
-  var includeDirs []string
+	var cflags []string
+	var includeDirs []string
 
-  board_bt_buildcfg_include_dir := ctx.DeviceConfig().BtConfigIncludeDir()
-  if (len(board_bt_buildcfg_include_dir) > 0) {
-    cflags = append(cflags, "-DHAS_BDROID_BUILDCFG")
-    board_bt_buildcfg_include_dir_list :=
-        strings.Fields(board_bt_buildcfg_include_dir)
-    for _, buildcfg_dir := range board_bt_buildcfg_include_dir_list {
-      includeDirs = append(includeDirs, buildcfg_dir)
-    }
-  } else {
-    cflags = append(cflags, "-DHAS_NO_BDROID_BUILDCFG")
-  }
+	board_bt_buildcfg_include_dir := ctx.DeviceConfig().BtConfigIncludeDir()
+	if len(board_bt_buildcfg_include_dir) > 0 {
+		cflags = append(cflags, "-DHAS_BDROID_BUILDCFG")
+		board_bt_buildcfg_include_dir_list :=
+			strings.Fields(board_bt_buildcfg_include_dir)
+		for _, buildcfg_dir := range board_bt_buildcfg_include_dir_list {
+			includeDirs = append(includeDirs, buildcfg_dir)
+		}
+	} else {
+		cflags = append(cflags, "-DHAS_NO_BDROID_BUILDCFG")
+	}
 
-  return cflags, includeDirs
+	return cflags, includeDirs
 }
diff --git a/conf/bt_stack.conf b/conf/bt_stack.conf
index 856cdc4..f1557b1 100644
--- a/conf/bt_stack.conf
+++ b/conf/bt_stack.conf
@@ -22,11 +22,9 @@
 TRC_AVDT_CCB=2
 TRC_A2D=2
 TRC_SDP=2
-TRC_GATT=2
 TRC_SMP=2
 TRC_BTAPP=2
 TRC_BTIF=2
-TRC_GAP=2
 TRC_BNEP=2
 TRC_PAN=2
 TRC_HID_HOST=2
diff --git a/device/Android.bp b/device/Android.bp
index e7dd2d0..c113113 100644
--- a/device/Android.bp
+++ b/device/Android.bp
@@ -43,5 +43,6 @@
         "libosi",
         "libosi-AllocationTestHarness",
         "libcutils",
+        "libbluetooth-types",
     ],
 }
diff --git a/device/include/controller.h b/device/include/controller.h
index 7088764..135cdcd 100644
--- a/device/include/controller.h
+++ b/device/include/controller.h
@@ -21,7 +21,6 @@
 #include <stdbool.h>
 #include <stdint.h>
 
-#include "bdaddr.h"
 #include "device_features.h"
 #include "hci_layer.h"
 #include "hci_packet_factory.h"
@@ -32,7 +31,7 @@
 typedef struct controller_t {
   bool (*get_is_ready)(void);
 
-  const bt_bdaddr_t* (*get_address)(void);
+  const RawAddress* (*get_address)(void);
   const bt_version_t* (*get_bt_version)(void);
 
   const bt_device_features_t* (*get_features_classic)(int index);
@@ -56,6 +55,7 @@
   bool (*supports_ble_packet_extension)(void);
   bool (*supports_ble_connection_parameters_request)(void);
   bool (*supports_ble_privacy)(void);
+  bool (*supports_ble_set_privacy_mode)(void);
   bool (*supports_ble_2m_phy)(void);
   bool (*supports_ble_coded_phy)(void);
   bool (*supports_ble_extended_advertising)(void);
diff --git a/device/include/interop.h b/device/include/interop.h
index ec2067a..96a3b9a 100644
--- a/device/include/interop.h
+++ b/device/include/interop.h
@@ -20,7 +20,7 @@
 
 #include <stdbool.h>
 
-#include "btcore/include/bdaddr.h"
+#include "raw_address.h"
 
 static const char INTEROP_MODULE[] = "interop_module";
 
@@ -97,7 +97,7 @@
 // address based lookups where more information is not available. No
 // look-ups or random address resolution are performed on |addr|.
 bool interop_match_addr(const interop_feature_t feature,
-                        const bt_bdaddr_t* addr);
+                        const RawAddress* addr);
 
 // Check if a given remote device |name| matches a known workaround.
 // Name comparisons are case sensitive and do not allow for partial matches.
@@ -110,10 +110,10 @@
 // Add a dynamic interop database entry for a device matching the first |length|
 // bytes of |addr|, implementing the workaround identified by |feature|.
 // |addr| may not be null.
-// |length| must be greater than 0 and less than sizeof(bt_bdaddr_t).
+// |length| must be greater than 0 and less than RawAddress::kLength.
 // As |interop_feature_t| is not exposed in the public API, feature must be a
 // valid integer representing an option in the enum.
-void interop_database_add(const uint16_t feature, const bt_bdaddr_t* addr,
+void interop_database_add(const uint16_t feature, const RawAddress* addr,
                           size_t length);
 
 // Clear the dynamic portion of the interoperability workaround database.
diff --git a/device/include/interop_database.h b/device/include/interop_database.h
index 7f4f229..38c3a24 100644
--- a/device/include/interop_database.h
+++ b/device/include/interop_database.h
@@ -19,9 +19,10 @@
 #pragma once
 
 #include "device/include/interop.h"
+#include "raw_address.h"
 
 typedef struct {
-  bt_bdaddr_t addr;
+  RawAddress addr;
   size_t length;
   interop_feature_t feature;
 } interop_addr_entry_t;
diff --git a/device/src/controller.cc b/device/src/controller.cc
index 1076bbf..df7cd43 100644
--- a/device/src/controller.cc
+++ b/device/src/controller.cc
@@ -48,7 +48,7 @@
 static const hci_packet_factory_t* packet_factory;
 static const hci_packet_parser_t* packet_parser;
 
-static bt_bdaddr_t address;
+static RawAddress address;
 static bt_version_t bt_version;
 
 static uint8_t supported_commands[HCI_SUPPORTED_COMMANDS_ARRAY_SIZE];
@@ -253,6 +253,10 @@
         response, &number_of_local_supported_codecs, local_supported_codecs);
   }
 
+  if (!HCI_READ_ENCR_KEY_SIZE_SUPPORTED(supported_commands)) {
+    LOG(FATAL) << " Controller must support Read Encryption Key Size command";
+  }
+
   readable = true;
   return future_new_immediate(FUTURE_SUCCESS);
 }
@@ -274,7 +278,7 @@
 
 static bool get_is_ready(void) { return readable; }
 
-static const bt_bdaddr_t* get_address(void) {
+static const RawAddress* get_address(void) {
   CHECK(readable);
   return &address;
 }
@@ -378,6 +382,13 @@
   return HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array);
 }
 
+static bool supports_ble_set_privacy_mode() {
+  CHECK(readable);
+  CHECK(ble_supported);
+  return HCI_LE_ENHANCED_PRIVACY_SUPPORTED(features_ble.as_array) &&
+         HCI_LE_SET_PRIVACY_MODE_SUPPORTED(supported_commands);
+}
+
 static bool supports_ble_packet_extension(void) {
   CHECK(readable);
   CHECK(ble_supported);
@@ -521,6 +532,7 @@
     supports_ble_packet_extension,
     supports_ble_connection_parameters_request,
     supports_ble_privacy,
+    supports_ble_set_privacy_mode,
     supports_ble_2m_phy,
     supports_ble_coded_phy,
     supports_ble_extended_advertising,
diff --git a/device/src/interop.cc b/device/src/interop.cc
index 8e36181..7b1fe59 100644
--- a/device/src/interop.cc
+++ b/device/src/interop.cc
@@ -38,21 +38,20 @@
 static void interop_free_entry_(void* data);
 static void interop_lazy_init_(void);
 static bool interop_match_fixed_(const interop_feature_t feature,
-                                 const bt_bdaddr_t* addr);
+                                 const RawAddress* addr);
 static bool interop_match_dynamic_(const interop_feature_t feature,
-                                   const bt_bdaddr_t* addr);
+                                   const RawAddress* addr);
 
 // Interface functions
 
 bool interop_match_addr(const interop_feature_t feature,
-                        const bt_bdaddr_t* addr) {
+                        const RawAddress* addr) {
   CHECK(addr);
 
   if (interop_match_fixed_(feature, addr) ||
       interop_match_dynamic_(feature, addr)) {
-    char bdstr[20] = {0};
     LOG_WARN(LOG_TAG, "%s() Device %s is a match for interop workaround %s.",
-             __func__, bdaddr_to_string(addr, bdstr, sizeof(bdstr)),
+             __func__, addr->ToString().c_str(),
              interop_feature_string_(feature));
     return true;
   }
@@ -77,11 +76,11 @@
   return false;
 }
 
-void interop_database_add(const uint16_t feature, const bt_bdaddr_t* addr,
+void interop_database_add(const uint16_t feature, const RawAddress* addr,
                           size_t length) {
   CHECK(addr);
   CHECK(length > 0);
-  CHECK(length < sizeof(bt_bdaddr_t));
+  CHECK(length < RawAddress::kLength);
 
   interop_addr_entry_t* entry = static_cast<interop_addr_entry_t*>(
       osi_calloc(sizeof(interop_addr_entry_t)));
@@ -146,7 +145,7 @@
 }
 
 static bool interop_match_dynamic_(const interop_feature_t feature,
-                                   const bt_bdaddr_t* addr) {
+                                   const RawAddress* addr) {
   if (interop_list == NULL || list_length(interop_list) == 0) return false;
 
   const list_node_t* node = list_begin(interop_list);
@@ -165,7 +164,7 @@
 }
 
 static bool interop_match_fixed_(const interop_feature_t feature,
-                                 const bt_bdaddr_t* addr) {
+                                 const RawAddress* addr) {
   CHECK(addr);
 
   const size_t db_size =
diff --git a/device/test/interop_test.cc b/device/test/interop_test.cc
index 5116f2c..e82a3b5 100644
--- a/device/test/interop_test.cc
+++ b/device/test/interop_test.cc
@@ -21,32 +21,32 @@
 #include "device/include/interop.h"
 
 TEST(InteropTest, test_lookup_hit) {
-  bt_bdaddr_t test_address;
-  string_to_bdaddr("38:2c:4a:e6:67:89", &test_address);
+  RawAddress test_address;
+  RawAddress::FromString("38:2c:4a:e6:67:89", test_address);
   EXPECT_TRUE(
       interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address));
-  string_to_bdaddr("9c:df:03:12:34:56", &test_address);
+  RawAddress::FromString("9c:df:03:12:34:56", test_address);
   EXPECT_TRUE(interop_match_addr(INTEROP_AUTO_RETRY_PAIRING, &test_address));
 }
 
 TEST(InteropTest, test_lookup_miss) {
-  bt_bdaddr_t test_address;
-  string_to_bdaddr("00:00:00:00:00:00", &test_address);
+  RawAddress test_address;
+  RawAddress::FromString("00:00:00:00:00:00", test_address);
   EXPECT_FALSE(
       interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address));
-  string_to_bdaddr("ff:ff:ff:ff:ff:ff", &test_address);
+  RawAddress::FromString("ff:ff:ff:ff:ff:ff", test_address);
   EXPECT_FALSE(interop_match_addr(INTEROP_AUTO_RETRY_PAIRING, &test_address));
-  string_to_bdaddr("42:08:15:ae:ae:ae", &test_address);
+  RawAddress::FromString("42:08:15:ae:ae:ae", test_address);
   EXPECT_FALSE(
       interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address));
-  string_to_bdaddr("38:2c:4a:59:67:89", &test_address);
+  RawAddress::FromString("38:2c:4a:59:67:89", test_address);
   EXPECT_FALSE(interop_match_addr(INTEROP_AUTO_RETRY_PAIRING, &test_address));
 }
 
 TEST(InteropTest, test_dynamic) {
-  bt_bdaddr_t test_address;
+  RawAddress test_address;
 
-  string_to_bdaddr("11:22:33:44:55:66", &test_address);
+  RawAddress::FromString("11:22:33:44:55:66", test_address);
   EXPECT_FALSE(
       interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address));
 
@@ -55,7 +55,7 @@
       interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, &test_address));
   EXPECT_FALSE(interop_match_addr(INTEROP_AUTO_RETRY_PAIRING, &test_address));
 
-  string_to_bdaddr("66:55:44:33:22:11", &test_address);
+  RawAddress::FromString("66:55:44:33:22:11", test_address);
   EXPECT_FALSE(interop_match_addr(INTEROP_AUTO_RETRY_PAIRING, &test_address));
 
   interop_database_add(INTEROP_AUTO_RETRY_PAIRING, &test_address, 3);
diff --git a/embdrv/sbc/decoder/include/oi_bt_spec.h b/embdrv/sbc/decoder/include/oi_bt_spec.h
index f9bb13e..077befd 100644
--- a/embdrv/sbc/decoder/include/oi_bt_spec.h
+++ b/embdrv/sbc/decoder/include/oi_bt_spec.h
@@ -42,27 +42,6 @@
 /** The maximum number of active slaves in a piconet. */
 #define OI_BT_MAX_ACTIVE_SLAVES 7
 
-/** the number of bytes in a Bluetooth device address (BD_ADDR) */
-#define OI_BD_ADDR_BYTE_SIZE 6
-
-/**
- * 48-bit Bluetooth device address
- *
- * Because 48-bit integers may not be supported on all platforms, the
- * address is defined as an array of bytes. This array is big-endian,
- * meaning that
- *  - array[0] contains bits 47-40,
- *  - array[1] contains bits 39-32,
- *  - array[2] contains bits 31-24,
- *  - array[3] contains bits 23-16,
- *  - array[4] contains bits 15-8, and
- *  - array[5] contains bits 7-0.
- */
-typedef struct {
-  /* Bluetooth device address represented as an array of 8-bit values */
-  uint8_t addr[OI_BD_ADDR_BYTE_SIZE];
-} OI_BD_ADDR;
-
 /**
  * @name Data types for working with UUIDs
  * UUIDs are 16 bytes (128 bits).
diff --git a/embdrv/sbc/decoder/include/oi_utils.h b/embdrv/sbc/decoder/include/oi_utils.h
index d91780f..9579d78 100644
--- a/embdrv/sbc/decoder/include/oi_utils.h
+++ b/embdrv/sbc/decoder/include/oi_utils.h
@@ -128,17 +128,6 @@
 OI_STATUS OI_CancelCallback(OI_SCHEDULED_CALLBACK callbackFunction);
 
 /**
- * Parse a Bluetooth device address from the specified string.
- *
- * @param str   the string to parse
- * @param addr  the parsed address, if successful
- *
- * @return true if an address was successfully parsed, false otherwise
- */
-
-OI_BOOL OI_ParseBdAddr(const OI_CHAR* str, OI_BD_ADDR* addr);
-
-/**
  * Printf function for platforms which have no stdio or printf available.
  * OI_Printf supports the basic formatting types, with the exception of
  * floating point types. Additionally, OI_Printf supports several formats
@@ -154,10 +143,6 @@
  *       @code OI_Printf("Contents of buffer %@", buffer, sizeof(buffer));
  *       @endcode
  *
- * \%:   prints a Bluetooth address in the form "HH:HH:HH:HH:HH:HH".
- *       Requires a pointer to an #OI_BD_ADDR.
- *       @code OI_Printf("Bluetooth address %:", &bdaddr); @endcode
- *
  * \%^   decodes and prints a data element as formatted XML.
  *       Requires a pointer to an #OI_DATAELEM.
  *       @code OI_Printf("Service attribute list is:\n%^", &attributes);
@@ -332,20 +317,6 @@
 const OI_CHAR* OI_ScanAlt(const OI_CHAR* str, const OI_CHAR* alts,
                           OI_INT* index);
 
-/**
- * Parse a string for a BD Addr. Skips leading whitespace (space and tabs only)
- * and parses a Bluetooth device address with nibbles optionally separated by
- * colons. Return pointet to first character following the BD Addr.
- *
- * @param str    String to parse.
- *
- * @param addr   Pointer to receive the Bluetooth device address
- *
- * @return       A pointer to the first character following the BD Addr or the
- *               pointer passed in.
- */
-const OI_CHAR* OI_ScanBdAddr(const OI_CHAR* str, OI_BD_ADDR* addr);
-
 /** Get a character from a digit integer value (0 - 9). */
 #define OI_DigitToChar(d) ((d) + '0')
 
@@ -360,13 +331,6 @@
 #define OI_MAX(a, b) (((a) < (b)) ? (b) : (a))
 #define OI_MIN(a, b) (((a) > (b)) ? (b) : (a))
 
-/**
- * Compare two BD_ADDRs
- * SAME_BD_ADDR - Boolean: true if they are the same address
- */
-
-#define SAME_BD_ADDR(x, y) (0 == OI_MemCmp((x), (y), OI_BD_ADDR_BYTE_SIZE))
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/hci/include/bt_hci_bdroid.h b/hci/include/bt_hci_bdroid.h
index b915a82..aa193d0 100644
--- a/hci/include/bt_hci_bdroid.h
+++ b/hci/include/bt_hci_bdroid.h
@@ -38,6 +38,7 @@
  *****************************************************************************/
 
 #include <stdbool.h>
+#include <stdint.h>
 
 #define HCI_ACL_MAX_SIZE 1024
 #define HCI_MAX_FRAME_SIZE (HCI_ACL_MAX_SIZE + 4)
diff --git a/hci/include/hci_packet_parser.h b/hci/include/hci_packet_parser.h
index b5117b9..0e74c29 100644
--- a/hci/include/hci_packet_parser.h
+++ b/hci/include/hci_packet_parser.h
@@ -20,7 +20,6 @@
 
 #include <stdint.h>
 
-#include "bdaddr.h"
 #include "bt_types.h"
 #include "device_features.h"
 #include "features.h"
@@ -38,7 +37,7 @@
                                                  bt_version_t* bt_version_ptr);
 
   void (*parse_read_bd_addr_response)(BT_HDR* response,
-                                      bt_bdaddr_t* address_ptr);
+                                      RawAddress* address_ptr);
 
   void (*parse_read_local_supported_commands_response)(
       BT_HDR* response, uint8_t* supported_commands_ptr,
diff --git a/hci/src/hci_layer.cc b/hci/src/hci_layer.cc
index 563379f..d1fa920 100644
--- a/hci/src/hci_layer.cc
+++ b/hci/src/hci_layer.cc
@@ -78,7 +78,7 @@
 
 // Abort if there is no response to an HCI command.
 static const uint32_t COMMAND_PENDING_TIMEOUT_MS = 2000;
-static const uint32_t COMMAND_TIMEOUT_RESTART_US = 500000;
+static const uint32_t COMMAND_TIMEOUT_RESTART_US = 5000000;
 
 // Our interface
 static bool interface_created;
diff --git a/hci/src/hci_layer_android.cc b/hci/src/hci_layer_android.cc
index ce4f42c..0598ca1 100644
--- a/hci/src/hci_layer_android.cc
+++ b/hci/src/hci_layer_android.cc
@@ -20,12 +20,14 @@
 
 #include "hci_layer.h"
 
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
 #include <base/location.h>
 #include <base/logging.h>
 #include "buffer_allocator.h"
 #include "osi/include/log.h"
-#include "sys/stat.h"
-#include "sys/types.h"
 
 #include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
 #include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
diff --git a/hci/src/hci_packet_parser.cc b/hci/src/hci_packet_parser.cc
index faf3939..e7ace27 100644
--- a/hci/src/hci_packet_parser.cc
+++ b/hci/src/hci_packet_parser.cc
@@ -86,11 +86,11 @@
 }
 
 static void parse_read_bd_addr_response(BT_HDR* response,
-                                        bt_bdaddr_t* address_ptr) {
+                                        RawAddress* address_ptr) {
   uint8_t* stream = read_command_complete_header(
-      response, HCI_READ_BD_ADDR, sizeof(bt_bdaddr_t) /* bytes after */);
+      response, HCI_READ_BD_ADDR, RawAddress::kLength /* bytes after */);
   CHECK(stream != NULL);
-  STREAM_TO_BDADDR(address_ptr->address, stream);
+  STREAM_TO_BDADDR(*address_ptr, stream);
 
   buffer_allocator->free(response);
 }
diff --git a/include/bt_trace.h b/include/bt_trace.h
index 900e41b..44ff2ff 100644
--- a/include/bt_trace.h
+++ b/include/bt_trace.h
@@ -583,33 +583,6 @@
       BT_TRACE(TRACE_LAYER_MCA, TRACE_TYPE_API, ##__VA_ARGS__); \
   }
 
-/* Define tracing for the ATT/GATT unit */
-#define GATT_TRACE_ERROR(...)                                     \
-  {                                                               \
-    if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR)              \
-      BT_TRACE(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, ##__VA_ARGS__); \
-  }
-#define GATT_TRACE_WARNING(...)                                     \
-  {                                                                 \
-    if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING)              \
-      BT_TRACE(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, ##__VA_ARGS__); \
-  }
-#define GATT_TRACE_API(...)                                     \
-  {                                                             \
-    if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API)              \
-      BT_TRACE(TRACE_LAYER_ATT, TRACE_TYPE_API, ##__VA_ARGS__); \
-  }
-#define GATT_TRACE_EVENT(...)                                     \
-  {                                                               \
-    if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT)              \
-      BT_TRACE(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, ##__VA_ARGS__); \
-  }
-#define GATT_TRACE_DEBUG(...)                                     \
-  {                                                               \
-    if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)              \
-      BT_TRACE(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, ##__VA_ARGS__); \
-  }
-
 /* Define tracing for the SMP unit */
 #define SMP_TRACE_ERROR(...)                                      \
   {                                                               \
diff --git a/main/bte_logmsg.cc b/main/bte_logmsg.cc
index 80a5372..3be38fd 100644
--- a/main/bte_logmsg.cc
+++ b/main/bte_logmsg.cc
@@ -59,7 +59,6 @@
 #include "hidd_api.h"
 #endif
 
-#include "gatt_api.h"
 #include "smp_api.h"
 
 #ifndef DEFAULT_CONF_TRACE_LEVEL
@@ -128,8 +127,6 @@
 #endif
     {BTTRC_ID_STK_SDP, BTTRC_ID_STK_SDP, SDP_SetTraceLevel, "TRC_SDP",
      DEFAULT_CONF_TRACE_LEVEL},
-    {BTTRC_ID_STK_GATT, BTTRC_ID_STK_GATT, GATT_SetTraceLevel, "TRC_GATT",
-     DEFAULT_CONF_TRACE_LEVEL},
     {BTTRC_ID_STK_SMP, BTTRC_ID_STK_SMP, SMP_SetTraceLevel, "TRC_SMP",
      DEFAULT_CONF_TRACE_LEVEL},
 #if (HID_DEV_INCLUDED == TRUE)
diff --git a/osi/include/alarm.h b/osi/include/alarm.h
index a59f12d..a01e6d0 100644
--- a/osi/include/alarm.h
+++ b/osi/include/alarm.h
@@ -74,15 +74,11 @@
 void alarm_set(alarm_t* alarm, period_ms_t interval_ms, alarm_callback_t cb,
                void* data);
 
-// Sets an |alarm| to execute a callback in the future on a
-// specific |queue|. This function is same as |alarm_set| except
-// that the |cb| callback is scheduled for execution in the
-// context of the thread responsible for processing |queue|.
-// Also, the callback execution ordering guarantee exists only
-// among alarms that are scheduled on the same queue. |queue|
-// may not be NULL.
-void alarm_set_on_queue(alarm_t* alarm, period_ms_t interval_ms,
-                        alarm_callback_t cb, void* data, fixed_queue_t* queue);
+// Sets an |alarm| to execute a callback in the main message loop. This function
+// is same as |alarm_set| except that the |cb| callback is scheduled for
+// execution in the context of the main message loop.
+void alarm_set_on_mloop(alarm_t* alarm, period_ms_t interval_ms,
+                        alarm_callback_t cb, void* data);
 
 // This function cancels the |alarm| if it was previously set.
 // When this call returns, the caller has a guarantee that the
@@ -95,15 +91,6 @@
 // Return true if the |alarm| is scheduled or NULL, otherwise false.
 bool alarm_is_scheduled(const alarm_t* alarm);
 
-// Registers |queue| for processing alarm callbacks on |thread|.
-// |queue| may not be NULL. |thread| may not be NULL.
-void alarm_register_processing_queue(fixed_queue_t* queue, thread_t* thread);
-
-// Unregisters |queue| for processing alarm callbacks on whichever thread
-// it is registered with. All alarms currently set for execution on |queue|
-// will be canceled. |queue| may not be NULL. This function is idempotent.
-void alarm_unregister_processing_queue(fixed_queue_t* queue);
-
 // Figure out how much time until next expiration.
 // Returns 0 if not armed. |alarm| may not be NULL.
 // TODO: Remove this function once PM timers can be re-factored
diff --git a/osi/src/alarm.cc b/osi/src/alarm.cc
index dd3c8e3..05fb3b4 100644
--- a/osi/src/alarm.cc
+++ b/osi/src/alarm.cc
@@ -22,7 +22,9 @@
 
 #include "osi/include/alarm.h"
 
+#include <base/cancelable_callback.h>
 #include <base/logging.h>
+#include <base/message_loop/message_loop.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
@@ -45,6 +47,12 @@
 #include "osi/include/thread.h"
 #include "osi/include/wakelock.h"
 
+using base::Bind;
+using base::CancelableClosure;
+using base::MessageLoop;
+
+extern base::MessageLoop* get_message_loop();
+
 // Callback and timer threads should run at RT priority in order to ensure they
 // meet audio deadlines.  Use this priority for all audio/timer related thread.
 static const int THREAD_RT_PRIORITY = 1;
@@ -67,6 +75,17 @@
   stat_t premature_scheduling;
 } alarm_stats_t;
 
+/* Wrapper around CancellableClosure that let it be embedded in structs, without
+ * need to define copy operator. */
+struct CancelableClosureInStruct {
+  base::CancelableClosure i;
+
+  CancelableClosureInStruct& operator=(const CancelableClosureInStruct& in) {
+    if (!in.i.callback().is_null()) i.Reset(in.i.callback());
+    return *this;
+  }
+};
+
 struct alarm_t {
   // The mutex is held while the callback for this alarm is being executed.
   // It allows us to release the coarse-grained monitor lock while a
@@ -84,6 +103,9 @@
   alarm_callback_t callback;
   void* data;
   alarm_stats_t stats;
+
+  bool for_msg_loop;  // True, if the alarm should be processed on message loop
+  CancelableClosureInStruct closure;  // posted to message loop for processing
 };
 
 // If the next wakeup time is less than this threshold, we should acquire
@@ -122,7 +144,7 @@
 static period_ms_t now(void);
 static void alarm_set_internal(alarm_t* alarm, period_ms_t period,
                                alarm_callback_t cb, void* data,
-                               fixed_queue_t* queue);
+                               fixed_queue_t* queue, bool for_msg_loop);
 static void alarm_cancel_internal(alarm_t* alarm);
 static void remove_pending_alarm(alarm_t* alarm);
 static void schedule_next_instance(alarm_t* alarm);
@@ -133,6 +155,10 @@
 static bool timer_create_internal(const clockid_t clock_id, timer_t* timer);
 static void update_scheduling_stats(alarm_stats_t* stats, period_ms_t now_ms,
                                     period_ms_t deadline_ms);
+// Registers |queue| for processing alarm callbacks on |thread|.
+// |queue| may not be NULL. |thread| may not be NULL.
+static void alarm_register_processing_queue(fixed_queue_t* queue,
+                                            thread_t* thread);
 
 static void update_stat(stat_t* stat, period_ms_t delta) {
   if (stat->max_ms < delta) stat->max_ms = delta;
@@ -159,6 +185,11 @@
   ret->callback_mutex = ptr;
   ret->is_periodic = is_periodic;
   ret->stats.name = osi_strdup(name);
+
+  ret->for_msg_loop = false;
+  // placement new
+  new (&ret->closure) CancelableClosureInStruct();
+
   // NOTE: The stats were reset by osi_calloc() above
 
   return ret;
@@ -170,6 +201,7 @@
   alarm_cancel(alarm);
 
   osi_free((void*)alarm->stats.name);
+  alarm->closure.~CancelableClosureInStruct();
   osi_free(alarm);
 }
 
@@ -186,19 +218,19 @@
 
 void alarm_set(alarm_t* alarm, period_ms_t interval_ms, alarm_callback_t cb,
                void* data) {
-  alarm_set_on_queue(alarm, interval_ms, cb, data, default_callback_queue);
+  alarm_set_internal(alarm, interval_ms, cb, data, default_callback_queue,
+                     false);
 }
 
-void alarm_set_on_queue(alarm_t* alarm, period_ms_t interval_ms,
-                        alarm_callback_t cb, void* data, fixed_queue_t* queue) {
-  CHECK(queue != NULL);
-  alarm_set_internal(alarm, interval_ms, cb, data, queue);
+void alarm_set_on_mloop(alarm_t* alarm, period_ms_t interval_ms,
+                        alarm_callback_t cb, void* data) {
+  alarm_set_internal(alarm, interval_ms, cb, data, NULL, true);
 }
 
 // Runs in exclusion with alarm_cancel and timer_callback.
 static void alarm_set_internal(alarm_t* alarm, period_ms_t period,
                                alarm_callback_t cb, void* data,
-                               fixed_queue_t* queue) {
+                               fixed_queue_t* queue, bool for_msg_loop) {
   CHECK(alarms != NULL);
   CHECK(alarm != NULL);
   CHECK(cb != NULL);
@@ -210,6 +242,7 @@
   alarm->queue = queue;
   alarm->callback = cb;
   alarm->data = data;
+  alarm->for_msg_loop = for_msg_loop;
 
   schedule_next_instance(alarm);
   alarm->stats.scheduled_count++;
@@ -374,9 +407,15 @@
 // The caller must hold the |alarms_mutex|
 static void remove_pending_alarm(alarm_t* alarm) {
   list_remove(alarms, alarm);
-  while (fixed_queue_try_remove_from_queue(alarm->queue, alarm) != NULL) {
-    // Remove all repeated alarm instances from the queue.
-    // NOTE: We are defensive here - we shouldn't have repeated alarm instances
+
+  if (alarm->for_msg_loop) {
+    alarm->closure.i.Cancel();
+  } else {
+    while (fixed_queue_try_remove_from_queue(alarm->queue, alarm) != NULL) {
+      // Remove all repeated alarm instances from the queue.
+      // NOTE: We are defensive here - we shouldn't have repeated alarm
+      // instances
+    }
   }
 }
 
@@ -510,7 +549,8 @@
   }
 }
 
-void alarm_register_processing_queue(fixed_queue_t* queue, thread_t* thread) {
+static void alarm_register_processing_queue(fixed_queue_t* queue,
+                                            thread_t* thread) {
   CHECK(queue != NULL);
   CHECK(thread != NULL);
 
@@ -518,33 +558,11 @@
                                alarm_queue_ready, NULL);
 }
 
-void alarm_unregister_processing_queue(fixed_queue_t* queue) {
-  CHECK(alarms != NULL);
-  CHECK(queue != NULL);
-
-  fixed_queue_unregister_dequeue(queue);
-
-  // Cancel all alarms that are using this queue
-  std::lock_guard<std::mutex> lock(alarms_mutex);
-  for (list_node_t* node = list_begin(alarms); node != list_end(alarms);) {
-    alarm_t* alarm = (alarm_t*)list_node(node);
-    node = list_next(node);
-    // TODO: Each module is responsible for tearing down its alarms; currently,
-    // this is not the case. In the future, this check should be replaced by
-    // an assert.
-    if (alarm->queue == queue) alarm_cancel_internal(alarm);
-  }
-}
-
-static void alarm_queue_ready(fixed_queue_t* queue, UNUSED_ATTR void* context) {
-  CHECK(queue != NULL);
-
-  std::unique_lock<std::mutex> lock(alarms_mutex);
-  alarm_t* alarm = (alarm_t*)fixed_queue_try_dequeue(queue);
+static void alarm_ready_generic(alarm_t* alarm,
+                                std::unique_lock<std::mutex>& lock) {
   if (alarm == NULL) {
     return;  // The alarm was probably canceled
   }
-
   //
   // If the alarm is not periodic, we've fully serviced it now, and can reset
   // some of its internal state. This is useful to distinguish between expired
@@ -578,6 +596,19 @@
   callback(data);
 }
 
+static void alarm_ready_mloop(alarm_t* alarm) {
+  std::unique_lock<std::mutex> lock(alarms_mutex);
+  alarm_ready_generic(alarm, lock);
+}
+
+static void alarm_queue_ready(fixed_queue_t* queue, UNUSED_ATTR void* context) {
+  CHECK(queue != NULL);
+
+  std::unique_lock<std::mutex> lock(alarms_mutex);
+  alarm_t* alarm = (alarm_t*)fixed_queue_try_dequeue(queue);
+  alarm_ready_generic(alarm, lock);
+}
+
 // Callback function for wake alarms and our posix timer
 static void timer_callback(UNUSED_ATTR void* ptr) {
   semaphore_post(alarm_expired);
@@ -614,7 +645,18 @@
     reschedule_root_alarm();
 
     // Enqueue the alarm for processing
-    fixed_queue_enqueue(alarm->queue, alarm);
+    if (alarm->for_msg_loop) {
+      if (!get_message_loop()) {
+        LOG_ERROR(LOG_TAG, "%s: message loop already NULL. Alarm: %s", __func__,
+                  alarm->stats.name);
+        continue;
+      }
+
+      alarm->closure.i.Reset(Bind(alarm_ready_mloop, alarm));
+      get_message_loop()->PostTask(FROM_HERE, alarm->closure.i.callback());
+    } else {
+      fixed_queue_enqueue(alarm->queue, alarm);
+    }
   }
 
   LOG_DEBUG(LOG_TAG, "%s Callback thread exited", __func__);
diff --git a/osi/test/alarm_test.cc b/osi/test/alarm_test.cc
index ae832a8..ea0d9af 100644
--- a/osi/test/alarm_test.cc
+++ b/osi/test/alarm_test.cc
@@ -16,6 +16,8 @@
  *
  ******************************************************************************/
 
+#include <base/message_loop/message_loop.h>
+#include <base/run_loop.h>
 #include <gtest/gtest.h>
 
 #include "AlarmTestHarness.h"
@@ -26,6 +28,9 @@
 #include "osi/include/semaphore.h"
 #include "osi/include/thread.h"
 
+using base::Closure;
+using base::TimeDelta;
+
 static semaphore_t* semaphore;
 static int cb_counter;
 static int cb_misordered_counter;
@@ -34,6 +39,26 @@
 
 static void msleep(uint64_t ms) { usleep(ms * 1000); }
 
+base::MessageLoop* message_loop_;
+base::RunLoop* run_loop_;
+static semaphore_t* msg_loop_ready;
+
+void message_loop_run(UNUSED_ATTR void* context) {
+  message_loop_ = new base::MessageLoop();
+  run_loop_ = new base::RunLoop();
+
+  semaphore_post(msg_loop_ready);
+  run_loop_->Run();
+
+  delete message_loop_;
+  message_loop_ = nullptr;
+
+  delete run_loop_;
+  run_loop_ = nullptr;
+}
+
+base::MessageLoop* get_message_loop() { return message_loop_; }
+
 class AlarmTest : public AlarmTestHarness {
  protected:
   virtual void SetUp() {
@@ -288,23 +313,29 @@
 }
 
 // Test whether the callbacks are involed in the expected order on a
-// separate queue.
-TEST_F(AlarmTest, test_callback_ordering_on_queue) {
+// message loop.
+TEST_F(AlarmTest, test_callback_ordering_on_mloop) {
   alarm_t* alarms[100];
-  fixed_queue_t* queue = fixed_queue_new(SIZE_MAX);
-  thread_t* thread =
-      thread_new("timers.test_callback_ordering_on_queue.thread");
 
-  alarm_register_processing_queue(queue, thread);
+  // Initialize MesageLoop, and wait till it's initialized.
+  msg_loop_ready = semaphore_new(0);
+  thread_t* message_loop_thread_ = thread_new("btu message loop");
+  if (!message_loop_thread_) {
+    FAIL() << "unable to create btu message loop thread.";
+  }
+
+  thread_post(message_loop_thread_, message_loop_run, nullptr);
+  semaphore_wait(msg_loop_ready);
+  semaphore_free(msg_loop_ready);
 
   for (int i = 0; i < 100; i++) {
     const std::string alarm_name =
-        "alarm_test.test_callback_ordering_on_queue[" + std::to_string(i) + "]";
+        "alarm_test.test_callback_ordering_on_mloop[" + std::to_string(i) + "]";
     alarms[i] = alarm_new(alarm_name.c_str());
   }
 
   for (int i = 0; i < 100; i++) {
-    alarm_set_on_queue(alarms[i], 100, ordered_cb, INT_TO_PTR(i), queue);
+    alarm_set_on_mloop(alarms[i], 100, ordered_cb, INT_TO_PTR(i));
   }
 
   for (int i = 1; i <= 100; i++) {
@@ -316,128 +347,9 @@
 
   for (int i = 0; i < 100; i++) alarm_free(alarms[i]);
 
+  message_loop_->PostTask(FROM_HERE, run_loop_->QuitWhenIdleClosure());
+  thread_free(message_loop_thread_);
   EXPECT_FALSE(WakeLockHeld());
-
-  alarm_unregister_processing_queue(queue);
-  fixed_queue_free(queue, NULL);
-  thread_free(thread);
-}
-
-// Test whether unregistering a processing queue cancels all timers using
-// that queue.
-TEST_F(AlarmTest, test_unregister_processing_queue) {
-  alarm_t* alarms[100];
-  fixed_queue_t* queue = fixed_queue_new(SIZE_MAX);
-  thread_t* thread =
-      thread_new("timers.test_unregister_processing_queue.thread");
-
-  alarm_register_processing_queue(queue, thread);
-
-  for (int i = 0; i < 100; i++) {
-    const std::string alarm_name =
-        "alarm_test.test_unregister_processing_queue[" + std::to_string(i) +
-        "]";
-    alarms[i] = alarm_new(alarm_name.c_str());
-  }
-
-  // Schedule half of the timers to expire soon, and the rest far in the future
-  for (int i = 0; i < 50; i++) {
-    alarm_set_on_queue(alarms[i], 100, ordered_cb, INT_TO_PTR(i), queue);
-  }
-  for (int i = 50; i < 100; i++) {
-    alarm_set_on_queue(alarms[i], 1000 * 1000, ordered_cb, INT_TO_PTR(i),
-                       queue);
-  }
-
-  // Wait until half of the timers have expired
-  for (int i = 1; i <= 50; i++) {
-    semaphore_wait(semaphore);
-    EXPECT_GE(cb_counter, i);
-  }
-  EXPECT_EQ(cb_counter, 50);
-  EXPECT_EQ(cb_misordered_counter, 0);
-
-  // Test that only the expired timers are not scheduled
-  for (int i = 0; i < 50; i++) {
-    EXPECT_FALSE(alarm_is_scheduled(alarms[i]));
-  }
-  for (int i = 50; i < 100; i++) {
-    EXPECT_TRUE(alarm_is_scheduled(alarms[i]));
-  }
-
-  alarm_unregister_processing_queue(queue);
-
-  // Test that none of the timers are scheduled
-  for (int i = 0; i < 100; i++) {
-    EXPECT_FALSE(alarm_is_scheduled(alarms[i]));
-  }
-
-  for (int i = 0; i < 100; i++) {
-    alarm_free(alarms[i]);
-  }
-
-  EXPECT_FALSE(WakeLockHeld());
-
-  fixed_queue_free(queue, NULL);
-  thread_free(thread);
-}
-
-// Test whether unregistering a processing queue cancels all periodic timers
-// using that queue.
-TEST_F(AlarmTest, test_periodic_unregister_processing_queue) {
-  alarm_t* alarms[5];
-  fixed_queue_t* queue = fixed_queue_new(SIZE_MAX);
-  thread_t* thread =
-      thread_new("timers.test_periodic_unregister_processing_queue.thread");
-
-  alarm_register_processing_queue(queue, thread);
-
-  for (int i = 0; i < 5; i++) {
-    const std::string alarm_name =
-        "alarm_test.test_periodic_unregister_processing_queue[" +
-        std::to_string(i) + "]";
-    alarms[i] = alarm_new_periodic(alarm_name.c_str());
-  }
-
-  // Schedule each of the timers with different period
-  for (int i = 0; i < 5; i++) {
-    alarm_set_on_queue(alarms[i], 20 + i, cb, INT_TO_PTR(i), queue);
-  }
-  EXPECT_TRUE(WakeLockHeld());
-
-  for (int i = 1; i <= 20; i++) {
-    semaphore_wait(semaphore);
-
-    EXPECT_GE(cb_counter, i);
-    EXPECT_TRUE(WakeLockHeld());
-  }
-
-  // Test that all timers are still scheduled
-  for (int i = 0; i < 5; i++) {
-    EXPECT_TRUE(alarm_is_scheduled(alarms[i]));
-  }
-
-  alarm_unregister_processing_queue(queue);
-
-  int saved_cb_counter = cb_counter;
-
-  // Test that none of the timers are scheduled
-  for (int i = 0; i < 5; i++) {
-    EXPECT_FALSE(alarm_is_scheduled(alarms[i]));
-  }
-
-  // Sleep for 500ms and test again that the cb_counter hasn't been modified
-  usleep(500 * 1000);
-  EXPECT_TRUE(cb_counter == saved_cb_counter);
-
-  for (int i = 0; i < 5; i++) {
-    alarm_free(alarms[i]);
-  }
-
-  EXPECT_FALSE(WakeLockHeld());
-
-  fixed_queue_free(queue, NULL);
-  thread_free(thread);
 }
 
 // Try to catch any race conditions between the timer callback and |alarm_free|.
diff --git a/service/Android.bp b/service/Android.bp
index 83761c9..5c8cb6c 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -1,60 +1,17 @@
+subdirs = [
+    "common",
+]
+
 cc_defaults {
     name: "fluoride_service_defaults",
     defaults: ["fluoride_defaults"],
-    local_include_dirs: [
-        "common"
-    ],
     include_dirs: [
-        "system/bt"
+        "system/bt",
     ],
-    srcs: [
-        "common/bluetooth/adapter_state.cc",
-        "common/bluetooth/advertise_data.cc",
-        "common/bluetooth/advertise_settings.cc",
-        "common/bluetooth/descriptor.cc",
-        "common/bluetooth/characteristic.cc",
-        "common/bluetooth/scan_filter.cc",
-        "common/bluetooth/scan_result.cc",
-        "common/bluetooth/scan_settings.cc",
-        "common/bluetooth/service.cc",
-        "common/bluetooth/util/address_helper.cc",
-        "common/bluetooth/util/atomic_string.cc",
-        "common/bluetooth/uuid.cc",
-    ]
 }
 
 // Source variables
 // ========================================================
-btserviceCommonBinderSrc = [
-    "common/android/bluetooth/IBluetooth.aidl",
-    "common/android/bluetooth/IBluetoothCallback.aidl",
-    "common/android/bluetooth/IBluetoothGattClient.aidl",
-    "common/android/bluetooth/IBluetoothGattClientCallback.aidl",
-    "common/android/bluetooth/IBluetoothGattServer.aidl",
-    "common/android/bluetooth/IBluetoothGattServerCallback.aidl",
-    "common/android/bluetooth/IBluetoothLeAdvertiser.aidl",
-    "common/android/bluetooth/IBluetoothLeAdvertiserCallback.aidl",
-    "common/android/bluetooth/IBluetoothLeScanner.aidl",
-    "common/android/bluetooth/IBluetoothLeScannerCallback.aidl",
-    "common/android/bluetooth/IBluetoothLowEnergy.aidl",
-    "common/android/bluetooth/IBluetoothLowEnergyCallback.aidl",
-    "common/android/bluetooth/advertise_data.cc",
-    "common/android/bluetooth/advertise_settings.cc",
-    "common/android/bluetooth/bluetooth_gatt_characteristic.cc",
-    "common/android/bluetooth/bluetooth_gatt_descriptor.cc",
-    "common/android/bluetooth/bluetooth_gatt_included_service.cc",
-    "common/android/bluetooth/bluetooth_gatt_service.cc",
-    "common/android/bluetooth/scan_filter.cc",
-    "common/android/bluetooth/scan_result.cc",
-    "common/android/bluetooth/scan_settings.cc",
-    "common/android/bluetooth/uuid.cc",
-]
-
-btserviceCommonAidlInclude = [
-    "system/bt/service/common",
-    "frameworks/native/aidl/binder",
-]
-
 btserviceDaemonSrc = [
     "adapter.cc",
     "daemon.cc",
@@ -77,7 +34,7 @@
     "ipc/linux_ipc_host.cc",
 ]
 
-btserviceBinderDaemonImplSrc = [
+btserviceBinderDaemonSrc = [
     "ipc/binder/bluetooth_binder_server.cc",
     "ipc/binder/bluetooth_gatt_client_binder_server.cc",
     "ipc/binder/bluetooth_gatt_server_binder_server.cc",
@@ -88,8 +45,6 @@
     "ipc/binder/ipc_handler_binder.cc",
 ]
 
-btserviceBinderDaemonSrc = btserviceCommonBinderSrc + btserviceBinderDaemonImplSrc
-
 // Main unit test sources. These get built for host and target.
 // ========================================================
 btserviceBaseTestSrc = [
@@ -104,7 +59,6 @@
     "test/low_energy_client_unittest.cc",
     "test/low_energy_scanner_unittest.cc",
     "test/settings_unittest.cc",
-    "test/util_unittest.cc",
     "test/uuid_unittest.cc",
 ]
 
@@ -113,15 +67,15 @@
 cc_binary {
     name: "bluetoothtbd",
     defaults: ["fluoride_service_defaults"],
-    srcs: btserviceBinderDaemonSrc
-        + btserviceLinuxSrc
-        + btserviceDaemonSrc
-        + ["main.cc"],
-    aidl: {
-        include_dirs: btserviceCommonAidlInclude
-    },
+    srcs: btserviceBinderDaemonSrc +
+    btserviceLinuxSrc +
+    btserviceDaemonSrc +
+    ["main.cc"],
     required: ["bluetooth.default"],
-    static_libs: ["libbtcore"],
+    static_libs: [
+        "libbluetooth-binder-common",
+        "libbtcore",
+    ],
     shared_libs: [
         "libbinder",
         "libcutils",
@@ -139,14 +93,18 @@
     name: "bluetoothtbd_test",
     test_suites: ["device-tests"],
     defaults: ["fluoride_service_defaults"],
-    srcs: btserviceBaseTestSrc
-        + btserviceDaemonSrc + [
-        "test/main.cc"
+    srcs: btserviceBaseTestSrc +
+    btserviceDaemonSrc + [
+        "test/main.cc",
     ],
     aidl: {
-        include_dirs: btserviceCommonAidlInclude,
+        include_dirs: [
+            "system/bt/service/common",
+            "frameworks/native/aidl/binder",
+        ],
     },
     static_libs: [
+        "libbluetooth-common",
         "libgmock",
         "liblog",
     ],
@@ -159,6 +117,9 @@
                 "test/parcelable_unittest.cc",
                 "test/ParcelableTest.aidl",
             ],
+            static_libs: [
+                "libbluetooth-binder-common",
+            ],
             shared_libs: [
                 "libbinder",
                 "libutils",
@@ -184,31 +145,15 @@
     },
 }
 
-// Client library for interacting with Bluetooth daemon
-// This is a static library for target.
-// ========================================================
-cc_library_static {
-    name: "libbluetooth-client",
-    defaults: ["fluoride_service_defaults"],
-    srcs: btserviceCommonBinderSrc,
-    aidl: {
-        export_aidl_headers: true,
-        include_dirs: btserviceCommonAidlInclude
-    },
-    export_include_dirs: ["common"],
-    shared_libs: [
-        "libbinder",
-        "libutils",
-    ],
-}
-
 // Native system service CLI for target
 // ========================================================
 cc_binary {
     name: "bluetooth-cli",
     defaults: ["fluoride_defaults"],
     srcs: ["client/main.cc"],
-    static_libs: ["libbluetooth-client"],
+    static_libs: [
+        "libbluetooth-binder-common",
+    ],
     shared_libs: [
         "libbinder",
         "libutils",
@@ -225,7 +170,9 @@
         "example/heart_rate/heart_rate_server.cc",
         "example/heart_rate/server_main.cc",
     ],
-    static_libs: ["libbluetooth-client"],
+    static_libs: [
+        "libbluetooth-binder-common",
+    ],
     shared_libs: [
         "libbinder",
         "libutils",
@@ -236,9 +183,9 @@
     name: "libbluetoothtbd_hal",
     defaults: ["fluoride_defaults"],
     include_dirs: ["system/bt"],
-    srcs = [
+    srcs: [
         "hal/bluetooth_gatt_interface.cc",
         "hal/bluetooth_interface.cc",
         "logging_helpers.cc",
-    ]
+    ],
 }
diff --git a/service/BUILD.gn b/service/BUILD.gn
index ba49728..2ad2982 100644
--- a/service/BUILD.gn
+++ b/service/BUILD.gn
@@ -26,7 +26,6 @@
     "common/bluetooth/scan_result.cc",
     "common/bluetooth/scan_settings.cc",
     "common/bluetooth/service.cc",
-    "common/bluetooth/util/address_helper.cc",
     "common/bluetooth/util/atomic_string.cc",
     "common/bluetooth/uuid.cc",
     "daemon.cc",
@@ -58,7 +57,8 @@
   ]
 
   deps = [
-    "//third_party/libchrome:base"
+    "//types",
+    "//third_party/libchrome:base",
   ]
 }
 
diff --git a/service/adapter.cc b/service/adapter.cc
index 42f8d79..e059c80 100644
--- a/service/adapter.cc
+++ b/service/adapter.cc
@@ -265,7 +265,7 @@
       switch (property->type) {
         case BT_PROPERTY_BDADDR: {
           std::string address =
-              BtAddrString(reinterpret_cast<bt_bdaddr_t*>(property->val));
+              BtAddrString(reinterpret_cast<RawAddress*>(property->val));
           LOG(INFO) << "Adapter address changed: " << address;
           address_.Set(address);
           break;
@@ -300,13 +300,13 @@
     }
   }
 
-  void SSPRequestCallback(bt_bdaddr_t*, bt_bdname_t*, uint32_t,
-                          bt_ssp_variant_t, uint32_t pass_key) override {
+  void SSPRequestCallback(RawAddress*, bt_bdname_t*, uint32_t, bt_ssp_variant_t,
+                          uint32_t pass_key) override {
     LOG(INFO) << "Passkey is: " << pass_key;
   }
 
   void AclStateChangedCallback(bt_status_t status,
-                               const bt_bdaddr_t& remote_bdaddr,
+                               const RawAddress& remote_bdaddr,
                                bt_acl_state_t state) override {
     std::string device_address = BtAddrString(&remote_bdaddr);
     bool connected = (state == BT_ACL_STATE_CONNECTED);
diff --git a/service/common/Android.bp b/service/common/Android.bp
new file mode 100644
index 0000000..e85d353
--- /dev/null
+++ b/service/common/Android.bp
@@ -0,0 +1,75 @@
+// Bluetooth types
+cc_library_static {
+    name: "libbluetooth-common",
+    defaults: ["fluoride_defaults"],
+    cflags: [
+        /* we export all classes, so change default visibility, instead of having EXPORT_SYMBOL on each class*/
+        "-fvisibility=default",
+    ],
+    host_supported: true,
+    srcs: [
+        "bluetooth/adapter_state.cc",
+        "bluetooth/advertise_data.cc",
+        "bluetooth/advertise_settings.cc",
+        "bluetooth/characteristic.cc",
+        "bluetooth/descriptor.cc",
+        "bluetooth/scan_filter.cc",
+        "bluetooth/scan_result.cc",
+        "bluetooth/scan_settings.cc",
+        "bluetooth/service.cc",
+        "bluetooth/util/atomic_string.cc",
+        "bluetooth/uuid.cc",
+    ],
+    export_include_dirs: ["./"],
+    include_dirs: ["system/bt"],
+    shared_libs: [
+        "libbase",
+    ],
+}
+
+// Bluetooth Binder shared library
+cc_library_static {
+    name: "libbluetooth-binder-common",
+    defaults: ["fluoride_defaults"],
+    cflags: [
+        /* we export all classes, so change default visibility, instead of having EXPORT_SYMBOL on each class*/
+        "-fvisibility=default",
+    ],
+    srcs: [
+        "android/bluetooth/IBluetooth.aidl",
+        "android/bluetooth/IBluetoothCallback.aidl",
+        "android/bluetooth/IBluetoothGattClient.aidl",
+        "android/bluetooth/IBluetoothGattClientCallback.aidl",
+        "android/bluetooth/IBluetoothGattServer.aidl",
+        "android/bluetooth/IBluetoothGattServerCallback.aidl",
+        "android/bluetooth/IBluetoothLeAdvertiser.aidl",
+        "android/bluetooth/IBluetoothLeAdvertiserCallback.aidl",
+        "android/bluetooth/IBluetoothLeScanner.aidl",
+        "android/bluetooth/IBluetoothLeScannerCallback.aidl",
+        "android/bluetooth/IBluetoothLowEnergy.aidl",
+        "android/bluetooth/IBluetoothLowEnergyCallback.aidl",
+        "android/bluetooth/advertise_data.cc",
+        "android/bluetooth/advertise_settings.cc",
+        "android/bluetooth/bluetooth_gatt_characteristic.cc",
+        "android/bluetooth/bluetooth_gatt_descriptor.cc",
+        "android/bluetooth/bluetooth_gatt_included_service.cc",
+        "android/bluetooth/bluetooth_gatt_service.cc",
+        "android/bluetooth/scan_filter.cc",
+        "android/bluetooth/scan_result.cc",
+        "android/bluetooth/scan_settings.cc",
+        "android/bluetooth/uuid.cc",
+    ],
+    aidl: {
+        export_aidl_headers: true,
+        include_dirs: [
+            "frameworks/native/aidl/binder",
+            "system/bt/service/common",
+        ],
+    },
+    export_include_dirs: ["./"],
+    whole_static_libs: ["libbluetooth-common"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+    ],
+}
diff --git a/service/common/README b/service/common/README
index de9e914..55f95fa 100644
--- a/service/common/README
+++ b/service/common/README
@@ -10,9 +10,3 @@
 This is so that client applications that link against the client library have
 one common include path exported to them, and our headers can find eachother
 within that.
-
-It is however OK to include from the package root when including common headers
-from source files as these are pre-compiled. For example,
-common/bluetooth/adapter_state.cpp should do:
-
-#include "service/common/bluetooth/adapter_state.h"
diff --git a/service/common/android/bluetooth/advertise_data.cc b/service/common/android/bluetooth/advertise_data.cc
index 07eb50a..7fe3601 100644
--- a/service/common/android/bluetooth/advertise_data.cc
+++ b/service/common/android/bluetooth/advertise_data.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/advertise_data.h"
+#include "android/bluetooth/advertise_data.h"
 
 using android::OK;
 
diff --git a/service/common/android/bluetooth/bluetooth_gatt_characteristic.cc b/service/common/android/bluetooth/bluetooth_gatt_characteristic.cc
index cf1fb2f..6ed9e1a 100644
--- a/service/common/android/bluetooth/bluetooth_gatt_characteristic.cc
+++ b/service/common/android/bluetooth/bluetooth_gatt_characteristic.cc
@@ -14,9 +14,9 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/bluetooth_gatt_characteristic.h"
-#include "service/common/android/bluetooth/bluetooth_gatt_descriptor.h"
-#include "service/common/android/bluetooth/uuid.h"
+#include "android/bluetooth/bluetooth_gatt_characteristic.h"
+#include "android/bluetooth/bluetooth_gatt_descriptor.h"
+#include "android/bluetooth/uuid.h"
 
 #include <utils/String16.h>
 #include <utils/String8.h>
diff --git a/service/common/android/bluetooth/bluetooth_gatt_descriptor.cc b/service/common/android/bluetooth/bluetooth_gatt_descriptor.cc
index 7749404..ecec0e0 100644
--- a/service/common/android/bluetooth/bluetooth_gatt_descriptor.cc
+++ b/service/common/android/bluetooth/bluetooth_gatt_descriptor.cc
@@ -14,8 +14,8 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/bluetooth_gatt_descriptor.h"
-#include "service/common/android/bluetooth/uuid.h"
+#include "android/bluetooth/bluetooth_gatt_descriptor.h"
+#include "android/bluetooth/uuid.h"
 
 #include <utils/String16.h>
 #include <utils/String8.h>
diff --git a/service/common/android/bluetooth/bluetooth_gatt_included_service.cc b/service/common/android/bluetooth/bluetooth_gatt_included_service.cc
index 02dc546..c66e0d2 100644
--- a/service/common/android/bluetooth/bluetooth_gatt_included_service.cc
+++ b/service/common/android/bluetooth/bluetooth_gatt_included_service.cc
@@ -14,9 +14,9 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/bluetooth_gatt_characteristic.h"
-#include "service/common/android/bluetooth/bluetooth_gatt_service.h"
-#include "service/common/android/bluetooth/uuid.h"
+#include "android/bluetooth/bluetooth_gatt_characteristic.h"
+#include "android/bluetooth/bluetooth_gatt_service.h"
+#include "android/bluetooth/uuid.h"
 
 #include <utils/String16.h>
 #include <utils/String8.h>
diff --git a/service/common/android/bluetooth/bluetooth_gatt_service.cc b/service/common/android/bluetooth/bluetooth_gatt_service.cc
index f4915cb..0c0daeb 100644
--- a/service/common/android/bluetooth/bluetooth_gatt_service.cc
+++ b/service/common/android/bluetooth/bluetooth_gatt_service.cc
@@ -14,9 +14,9 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/bluetooth_gatt_service.h"
-#include "service/common/android/bluetooth/bluetooth_gatt_characteristic.h"
-#include "service/common/android/bluetooth/uuid.h"
+#include "android/bluetooth/bluetooth_gatt_service.h"
+#include "android/bluetooth/bluetooth_gatt_characteristic.h"
+#include "android/bluetooth/uuid.h"
 
 #include <utils/String16.h>
 #include <utils/String8.h>
diff --git a/service/common/android/bluetooth/scan_filter.cc b/service/common/android/bluetooth/scan_filter.cc
index bf9eaf2..6bb6119 100644
--- a/service/common/android/bluetooth/scan_filter.cc
+++ b/service/common/android/bluetooth/scan_filter.cc
@@ -14,8 +14,8 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/scan_filter.h"
-#include "service/common/android/bluetooth/uuid.h"
+#include "android/bluetooth/scan_filter.h"
+#include "android/bluetooth/uuid.h"
 
 #include <binder/Parcel.h>
 #include <utils/String16.h>
diff --git a/service/common/android/bluetooth/scan_result.cc b/service/common/android/bluetooth/scan_result.cc
index 17378df..32acae3 100644
--- a/service/common/android/bluetooth/scan_result.cc
+++ b/service/common/android/bluetooth/scan_result.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/scan_result.h"
+#include "android/bluetooth/scan_result.h"
 
 #include <base/logging.h>
 #include <binder/Parcel.h>
diff --git a/service/common/android/bluetooth/scan_settings.cc b/service/common/android/bluetooth/scan_settings.cc
index 0920cca..8c79cea 100644
--- a/service/common/android/bluetooth/scan_settings.cc
+++ b/service/common/android/bluetooth/scan_settings.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/scan_settings.h"
+#include "android/bluetooth/scan_settings.h"
 
 #include <binder/Parcel.h>
 
diff --git a/service/common/android/bluetooth/uuid.cc b/service/common/android/bluetooth/uuid.cc
index 6d03bb6..6cfc6db 100644
--- a/service/common/android/bluetooth/uuid.cc
+++ b/service/common/android/bluetooth/uuid.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/android/bluetooth/uuid.h"
+#include "android/bluetooth/uuid.h"
 
 #include <binder/Parcel.h>
 
diff --git a/service/common/bluetooth/adapter_state.cc b/service/common/bluetooth/adapter_state.cc
index 9ca5998..47c07af 100644
--- a/service/common/bluetooth/adapter_state.cc
+++ b/service/common/bluetooth/adapter_state.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/bluetooth/adapter_state.h"
+#include "bluetooth/adapter_state.h"
 
 namespace bluetooth {
 
diff --git a/service/common/bluetooth/advertise_data.cc b/service/common/bluetooth/advertise_data.cc
index 93bffa8..d9cac21 100644
--- a/service/common/bluetooth/advertise_data.cc
+++ b/service/common/bluetooth/advertise_data.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/bluetooth/advertise_data.h"
+#include "bluetooth/advertise_data.h"
 
 #include <base/logging.h>
 
diff --git a/service/common/bluetooth/advertise_settings.cc b/service/common/bluetooth/advertise_settings.cc
index ca3428c..4d2605b 100644
--- a/service/common/bluetooth/advertise_settings.cc
+++ b/service/common/bluetooth/advertise_settings.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/bluetooth/advertise_settings.h"
+#include "bluetooth/advertise_settings.h"
 
 namespace bluetooth {
 
diff --git a/service/common/bluetooth/scan_filter.cc b/service/common/bluetooth/scan_filter.cc
index c0b7375..3226c50 100644
--- a/service/common/bluetooth/scan_filter.cc
+++ b/service/common/bluetooth/scan_filter.cc
@@ -14,9 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/bluetooth/scan_filter.h"
-
-#include "service/common/bluetooth/util/address_helper.h"
+#include "bluetooth/scan_filter.h"
 
 namespace bluetooth {
 
@@ -48,7 +46,7 @@
 }
 
 bool ScanFilter::SetDeviceAddress(const std::string& device_address) {
-  if (!util::IsAddressValid(device_address)) return false;
+  if (!RawAddress::IsValidAddress(device_address)) return false;
 
   device_address_ = device_address;
   return true;
diff --git a/service/common/bluetooth/scan_filter.h b/service/common/bluetooth/scan_filter.h
index d4c87dd..a8c30ee 100644
--- a/service/common/bluetooth/scan_filter.h
+++ b/service/common/bluetooth/scan_filter.h
@@ -49,8 +49,8 @@
   // SetServiceUuidWithMask for what this mask does. The raw pointer returned
   // from these getters belongs to the ScanFilter object. nullptr will be
   // returned if these fields have not been set on this filter.
-  UUID* service_uuid() const { return service_uuid_.get(); }
-  UUID* service_uuid_mask() const { return service_uuid_mask_.get(); }
+  const UUID* service_uuid() const { return service_uuid_.get(); }
+  const UUID* service_uuid_mask() const { return service_uuid_mask_.get(); }
 
   // Sets the service UUID for this filter.
   void SetServiceUuid(const UUID& service_uuid);
diff --git a/service/common/bluetooth/scan_result.cc b/service/common/bluetooth/scan_result.cc
index 099cac7..007019e 100644
--- a/service/common/bluetooth/scan_result.cc
+++ b/service/common/bluetooth/scan_result.cc
@@ -14,19 +14,18 @@
 //  limitations under the License.
 //
 
-#include "service/common/bluetooth/scan_result.h"
+#include "bluetooth/scan_result.h"
+#include "raw_address.h"
 
 #include <base/logging.h>
 
-#include "service/common/bluetooth/util/address_helper.h"
-
 namespace bluetooth {
 
 ScanResult::ScanResult(const std::string& device_address,
                        const std::vector<uint8_t>& scan_record, int rssi)
     : device_address_(device_address), scan_record_(scan_record), rssi_(rssi) {
-  CHECK(util::IsAddressValid(device_address)) << "Invalid BD_ADDR given: "
-                                              << device_address;
+  CHECK(RawAddress::IsValidAddress(device_address)) << "Invalid BD_ADDR given: "
+                                                    << device_address;
 }
 
 bool ScanResult::operator==(const ScanResult& rhs) const {
diff --git a/service/common/bluetooth/scan_settings.cc b/service/common/bluetooth/scan_settings.cc
index a405a28..dac0391 100644
--- a/service/common/bluetooth/scan_settings.cc
+++ b/service/common/bluetooth/scan_settings.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/bluetooth/scan_settings.h"
+#include "bluetooth/scan_settings.h"
 
 namespace bluetooth {
 
diff --git a/service/common/bluetooth/util/address_helper.cc b/service/common/bluetooth/util/address_helper.cc
deleted file mode 100644
index 17aecce..0000000
--- a/service/common/bluetooth/util/address_helper.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-//  Copyright (C) 2015 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 "service/common/bluetooth/util/address_helper.h"
-
-#include <cstdlib>
-
-#include <base/logging.h>
-#include <base/strings/string_split.h>
-
-namespace util {
-
-bool IsAddressValid(const std::string& address) {
-  bt_bdaddr_t addr;
-  return BdAddrFromString(address, &addr);
-}
-
-bool BdAddrFromString(const std::string& address, bt_bdaddr_t* out_addr) {
-  CHECK(out_addr);
-
-  if (address.length() != 17) return false;
-
-  std::vector<std::string> byte_tokens = base::SplitString(
-      address, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-
-  if (byte_tokens.size() != 6) return false;
-
-  for (int i = 0; i < 6; i++) {
-    const auto& token = byte_tokens[i];
-
-    if (token.length() != 2) return false;
-
-    char* temp = nullptr;
-    out_addr->address[i] = strtol(token.c_str(), &temp, 16);
-    if (*temp != '\0') return false;
-  }
-
-  return true;
-}
-
-}  // namespace util
diff --git a/service/common/bluetooth/util/address_helper.h b/service/common/bluetooth/util/address_helper.h
deleted file mode 100644
index d71d907..0000000
--- a/service/common/bluetooth/util/address_helper.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-//  Copyright (C) 2015 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.
-//
-
-#pragma once
-
-#include <hardware/bluetooth.h>
-#include <string>
-
-namespace util {
-
-// Checks if the given string representing a Bluetooth device address (BD_ADDR)
-// is correctly formatted. The correct formatting is of the form
-//
-//   XX:XX:XX:XX:XX:XX
-//
-// where X is an alpha-numeric character.
-bool IsAddressValid(const std::string& address);
-
-// Populates a bt_bdaddr_t from a given string. Returns false if the data is
-// invalid.
-bool BdAddrFromString(const std::string& address, bt_bdaddr_t* out_addr);
-
-}  // namespace util
diff --git a/service/common/bluetooth/util/atomic_string.h b/service/common/bluetooth/util/atomic_string.h
index e1c2526..68d37ad 100644
--- a/service/common/bluetooth/util/atomic_string.h
+++ b/service/common/bluetooth/util/atomic_string.h
@@ -14,6 +14,8 @@
 //  limitations under the License.
 //
 
+#pragma once
+
 #include <mutex>
 #include <string>
 
diff --git a/service/common/bluetooth/uuid.cc b/service/common/bluetooth/uuid.cc
index b7ae9e5..16547ae 100644
--- a/service/common/bluetooth/uuid.cc
+++ b/service/common/bluetooth/uuid.cc
@@ -14,7 +14,7 @@
 //  limitations under the License.
 //
 
-#include "service/common/bluetooth/uuid.h"
+#include "bluetooth/uuid.h"
 
 #include <algorithm>
 #include <array>
diff --git a/service/daemon.cc b/service/daemon.cc
index 48d098c..7fd9b2b 100644
--- a/service/daemon.cc
+++ b/service/daemon.cc
@@ -25,6 +25,7 @@
 #include "service/hal/bluetooth_interface.h"
 #include "service/ipc/ipc_manager.h"
 #include "service/settings.h"
+#include "service/switches.h"
 
 namespace bluetooth {
 
@@ -33,7 +34,7 @@
 // The global Daemon instance.
 Daemon* g_daemon = nullptr;
 
-class DaemonImpl : public Daemon {
+class DaemonImpl : public Daemon, public ipc::IPCManager::Delegate {
  public:
   DaemonImpl() : initialized_(false) {}
 
@@ -52,6 +53,16 @@
   }
 
  private:
+  // ipc::IPCManager::Delegate implementation:
+  void OnIPCHandlerStarted(ipc::IPCManager::Type /* type */) override {
+    if (!settings_->EnableOnStart()) return;
+    adapter_->Enable(false /* start_restricted */);
+  }
+
+  void OnIPCHandlerStopped(ipc::IPCManager::Type /* type */) override {
+    // Do nothing.
+  }
+
   bool StartUpBluetoothInterfaces() {
     if (!hal::BluetoothInterface::Initialize()) goto failed;
 
@@ -82,7 +93,7 @@
     // If an IPC socket path was given, initialize IPC with it. Otherwise
     // initialize Binder IPC.
     if (settings_->UseSocketIPC()) {
-      if (!ipc_manager_->Start(ipc::IPCManager::TYPE_LINUX, nullptr)) {
+      if (!ipc_manager_->Start(ipc::IPCManager::TYPE_LINUX, this)) {
         LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager";
         return false;
       }
@@ -90,12 +101,12 @@
     }
 
 #if !defined(OS_GENERIC)
-    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, nullptr)) {
+    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, this)) {
       LOG(ERROR) << "Failed to set up Binder IPCManager";
       return false;
     }
 #else
-    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, nullptr)) {
+    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, this)) {
       LOG(ERROR) << "Failed to set up DBus IPCManager";
       return false;
     }
diff --git a/service/gatt_client.cc b/service/gatt_client.cc
index 0567dd7..80f5ebf 100644
--- a/service/gatt_client.cc
+++ b/service/gatt_client.cc
@@ -68,7 +68,7 @@
       hal::BluetoothGattInterface::Get()->GetClientHALInterface();
   bt_uuid_t app_uuid = uuid.GetBlueDroid();
 
-  if (hal_iface->register_client(&app_uuid) != BT_STATUS_SUCCESS) return false;
+  if (hal_iface->register_client(app_uuid) != BT_STATUS_SUCCESS) return false;
 
   pending_calls_[uuid] = callback;
 
diff --git a/service/gatt_server.cc b/service/gatt_server.cc
index 016c132..104afe1 100644
--- a/service/gatt_server.cc
+++ b/service/gatt_server.cc
@@ -17,26 +17,14 @@
 #include "service/gatt_server.h"
 
 #include "osi/include/log.h"
-#include "service/common/bluetooth/util/address_helper.h"
 #include "service/logging_helpers.h"
+#include "stack/include/bt_types.h"
 
 using std::lock_guard;
 using std::mutex;
 
 namespace bluetooth {
 
-namespace {
-
-bool operator==(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) {
-  return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
-}
-
-bool operator!=(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) {
-  return !(lhs == rhs);
-}
-
-}  // namespace
-
 // GattServer implementation
 // ========================================================
 
@@ -121,8 +109,8 @@
           << " offset: " << offset;
   lock_guard<mutex> lock(mutex_);
 
-  bt_bdaddr_t addr;
-  if (!util::BdAddrFromString(device_address, &addr)) {
+  RawAddress addr;
+  if (!RawAddress::FromString(device_address, addr)) {
     LOG(ERROR) << "Invalid device address given: " << device_address;
     return false;
   }
@@ -177,7 +165,7 @@
   bt_status_t result =
       hal::BluetoothGattInterface::Get()
           ->GetServerHALInterface()
-          ->send_response(connection->conn_id, request_id, error, &response);
+          ->send_response(connection->conn_id, request_id, error, response);
   if (result != BT_STATUS_SUCCESS) {
     LOG(ERROR) << "Failed to initiate call to send GATT response";
     return false;
@@ -196,8 +184,8 @@
           << " device_address: " << device_address << " confirm: " << confirm;
   lock_guard<mutex> lock(mutex_);
 
-  bt_bdaddr_t addr;
-  if (!util::BdAddrFromString(device_address, &addr)) {
+  RawAddress addr;
+  if (!RawAddress::FromString(device_address, addr)) {
     LOG(ERROR) << "Invalid device address given: " << device_address;
     return false;
   }
@@ -254,7 +242,7 @@
 
 void GattServer::ConnectionCallback(
     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int server_id,
-    int connected, const bt_bdaddr_t& bda) {
+    int connected, const RawAddress& bda) {
   lock_guard<mutex> lock(mutex_);
 
   if (server_id != server_id_) return;
@@ -346,7 +334,7 @@
 
 void GattServer::RequestReadCharacteristicCallback(
     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
-    const bt_bdaddr_t& bda, int attribute_handle, int offset, bool is_long) {
+    const RawAddress& bda, int attribute_handle, int offset, bool is_long) {
   lock_guard<mutex> lock(mutex_);
 
   // Check to see if we know about this connection. Otherwise ignore the
@@ -379,7 +367,7 @@
 }
 void GattServer::RequestReadDescriptorCallback(
     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
-    const bt_bdaddr_t& bda, int attribute_handle, int offset, bool is_long) {
+    const RawAddress& bda, int attribute_handle, int offset, bool is_long) {
   lock_guard<mutex> lock(mutex_);
 
   // Check to see if we know about this connection. Otherwise ignore the
@@ -413,7 +401,7 @@
 
 void GattServer::RequestWriteCharacteristicCallback(
     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
-    const bt_bdaddr_t& bda, int attr_handle, int offset, bool need_rsp,
+    const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
     bool is_prep, std::vector<uint8_t> value) {
   lock_guard<mutex> lock(mutex_);
 
@@ -452,7 +440,7 @@
 
 void GattServer::RequestWriteDescriptorCallback(
     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
-    const bt_bdaddr_t& bda, int attr_handle, int offset, bool need_rsp,
+    const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
     bool is_prep, std::vector<uint8_t> value) {
   lock_guard<mutex> lock(mutex_);
 
@@ -491,7 +479,7 @@
 
 void GattServer::RequestExecWriteCallback(
     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
-    const bt_bdaddr_t& bda, int exec_write) {
+    const RawAddress& bda, int exec_write) {
   lock_guard<mutex> lock(mutex_);
 
   // Check to see if we know about this connection. Otherwise ignore the
@@ -551,7 +539,7 @@
 }
 
 std::shared_ptr<GattServer::Connection> GattServer::GetConnection(
-    int conn_id, const bt_bdaddr_t& bda, int request_id) {
+    int conn_id, const RawAddress& bda, int request_id) {
   auto iter = conn_id_map_.find(conn_id);
   if (iter == conn_id_map_.end()) {
     VLOG(1) << "Connection doesn't belong to this server";
@@ -601,7 +589,7 @@
       hal::BluetoothGattInterface::Get()->GetServerHALInterface();
   bt_uuid_t app_uuid = uuid.GetBlueDroid();
 
-  if (hal_iface->register_server(&app_uuid) != BT_STATUS_SUCCESS) return false;
+  if (hal_iface->register_server(app_uuid) != BT_STATUS_SUCCESS) return false;
 
   pending_calls_[uuid] = callback;
 
diff --git a/service/gatt_server.h b/service/gatt_server.h
index 84ee165..e17e862 100644
--- a/service/gatt_server.h
+++ b/service/gatt_server.h
@@ -19,6 +19,7 @@
 #include <deque>
 #include <functional>
 #include <mutex>
+#include <string>
 #include <unordered_map>
 #include <unordered_set>
 #include <vector>
@@ -168,13 +169,13 @@
   // request ID and the device address for the connection. If |request_id| is -1
   // then no ATT read/write request is currently pending.
   struct Connection {
-    Connection(int conn_id, const bt_bdaddr_t& bdaddr)
+    Connection(int conn_id, const RawAddress& bdaddr)
         : conn_id(conn_id), bdaddr(bdaddr) {}
     Connection() : conn_id(-1) { memset(&bdaddr, 0, sizeof(bdaddr)); }
 
     int conn_id;
     std::unordered_map<int, int> request_id_to_handle;
-    bt_bdaddr_t bdaddr;
+    RawAddress bdaddr;
   };
 
   // Used to keep track of a pending Handle-Value indication.
@@ -193,7 +194,7 @@
   // hal::BluetoothGattInterface::ServerObserver overrides:
   void ConnectionCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
                           int server_id, int connected,
-                          const bt_bdaddr_t& bda) override;
+                          const RawAddress& bda) override;
   void ServiceAddedCallback(hal::BluetoothGattInterface* gatt_iface, int status,
                             int server_if,
                             std::vector<btgatt_db_element_t>) override;
@@ -202,26 +203,25 @@
                               int service_handle) override;
   void RequestReadCharacteristicCallback(
       hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
-      const bt_bdaddr_t& bda, int attribute_handle, int offset,
+      const RawAddress& bda, int attribute_handle, int offset,
       bool is_long) override;
   void RequestReadDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
                                      int conn_id, int trans_id,
-                                     const bt_bdaddr_t& bda,
+                                     const RawAddress& bda,
                                      int attribute_handle, int offset,
                                      bool is_long) override;
   void RequestWriteCharacteristicCallback(
       hal::BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
-      const bt_bdaddr_t& bda, int attr_handle, int offset, bool need_rsp,
+      const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
       bool is_prep, std::vector<uint8_t> value) override;
   void RequestWriteDescriptorCallback(hal::BluetoothGattInterface* gatt_iface,
                                       int conn_id, int trans_id,
-                                      const bt_bdaddr_t& bda, int attr_handle,
+                                      const RawAddress& bda, int attr_handle,
                                       int offset, bool need_rsp, bool is_prep,
                                       std::vector<uint8_t> value) override;
   void RequestExecWriteCallback(hal::BluetoothGattInterface* gatt_iface,
                                 int conn_id, int trans_id,
-                                const bt_bdaddr_t& bda,
-                                int exec_write) override;
+                                const RawAddress& bda, int exec_write) override;
   void IndicationSentCallback(hal::BluetoothGattInterface* gatt_iface,
                               int conn_id, int status) override;
 
@@ -233,7 +233,7 @@
 
   // Helper method that returns a pointer to an internal Connection instance
   // that matches the given parameters.
-  std::shared_ptr<Connection> GetConnection(int conn_id, const bt_bdaddr_t& bda,
+  std::shared_ptr<Connection> GetConnection(int conn_id, const RawAddress& bda,
                                             int request_id);
 
   // See getters for documentation.
diff --git a/service/gatt_server_old.cc b/service/gatt_server_old.cc
index d32ac8f..f6099ef 100644
--- a/service/gatt_server_old.cc
+++ b/service/gatt_server_old.cc
@@ -129,13 +129,14 @@
 namespace {
 
 /** Callback invoked in response to register_server */
-void RegisterServerCallback(int status, int server_if, bt_uuid_t* app_uuid) {
+void RegisterServerCallback(int status, int server_if,
+                            const bt_uuid_t& app_uuid) {
   LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d app_uuid:%p", __func__, status,
-           server_if, app_uuid);
+           server_if, &app_uuid);
 
   g_internal->server_if = server_if;
   pending_svc_decl.push_back(
-      {.type = BTGATT_DB_PRIMARY_SERVICE, .uuid = *app_uuid});
+      {.type = BTGATT_DB_PRIMARY_SERVICE, .uuid = app_uuid});
 }
 
 void ServiceAddedCallback(int status, int server_if,
@@ -197,13 +198,13 @@
   bt_uuid_t client_id = service[0].uuid;
   ++client_id.uu[15];
 
-  bt_status_t btstat = g_internal->gatt->client->register_client(&client_id);
+  bt_status_t btstat = g_internal->gatt->client->register_client(client_id);
   if (btstat != BT_STATUS_SUCCESS) {
     LOG_ERROR(LOG_TAG, "%s: Failed to register client", __func__);
   }
 }
 
-void RequestReadCallback(int conn_id, int trans_id, bt_bdaddr_t* bda,
+void RequestReadCallback(int conn_id, int trans_id, const RawAddress& bda,
                          int attr_handle, int attribute_offset_octets,
                          bool is_long) {
   std::lock_guard<std::mutex> lock(g_internal->lock);
@@ -223,7 +224,7 @@
   const size_t blob_remaining = ch.blob.size() - blob_offset_octets;
   const size_t attribute_size = std::min(kMaxGattAttributeSize, blob_remaining);
 
-  std::string addr(BtAddrString(bda));
+  std::string addr(BtAddrString(&bda));
   LOG_INFO(LOG_TAG,
            "%s: connection:%d (%s) reading attr:%d attribute_offset_octets:%d "
            "blob_section:%u (is_long:%u)",
@@ -243,13 +244,13 @@
   response.attr_value.handle = attr_handle;
   response.attr_value.offset = attribute_offset_octets;
   response.attr_value.auth_req = 0;
-  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, response);
 }
 
-void RequestWriteCallback(int conn_id, int trans_id, bt_bdaddr_t* bda,
+void RequestWriteCallback(int conn_id, int trans_id, const RawAddress& bda,
                           int attr_handle, int attribute_offset, bool need_rsp,
                           bool is_prep, std::vector<uint8_t> value) {
-  std::string addr(BtAddrString(bda));
+  std::string addr(BtAddrString(&bda));
   LOG_INFO(LOG_TAG,
            "%s: connection:%d (%s:trans:%d) write attr:%d attribute_offset:%d "
            "length:%zu "
@@ -299,19 +300,19 @@
   // Provide written data back to sender for the response.
   // Remote stacks use this to validate the success of the write.
   std::copy(value.begin(), value.end(), response.attr_value.value);
-  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, response);
 }
 
-void RequestExecWriteCallback(int conn_id, int trans_id, bt_bdaddr_t* bda,
+void RequestExecWriteCallback(int conn_id, int trans_id, const RawAddress& bda,
                               int exec_write) {
-  std::string addr(BtAddrString(bda));
+  std::string addr(BtAddrString(&bda));
   LOG_INFO(LOG_TAG, "%s: connection:%d (%s:trans:%d) exec_write:%d", __func__,
            conn_id, addr.c_str(), trans_id, exec_write);
 
   // This 'response' data is unused for ExecWriteResponses.
   // It is only used to pass BlueDroid argument validation.
   btgatt_response_t response = {};
-  g_internal->gatt->server->send_response(conn_id, trans_id, 0, &response);
+  g_internal->gatt->server->send_response(conn_id, trans_id, 0, response);
 
   if (!exec_write) return;
 
@@ -327,8 +328,8 @@
 }
 
 void ConnectionCallback(int conn_id, int server_if, int connected,
-                        bt_bdaddr_t* bda) {
-  std::string addr(BtAddrString(bda));
+                        const RawAddress& bda) {
+  std::string addr(BtAddrString(&bda));
   LOG_INFO(LOG_TAG, "%s: connection:%d server_if:%d connected:%d addr:%s",
            __func__, conn_id, server_if, connected, addr.c_str());
   if (connected == 1) {
@@ -345,9 +346,10 @@
   g_internal->api_synchronize.notify_one();
 }
 
-void RegisterClientCallback(int status, int client_if, bt_uuid_t* app_uuid) {
+void RegisterClientCallback(int status, int client_if,
+                            const bt_uuid_t& app_uuid) {
   LOG_INFO(LOG_TAG, "%s: status:%d client_if:%d uuid[0]:%u", __func__, status,
-           client_if, app_uuid->uu[0]);
+           client_if, app_uuid.uu[0]);
   g_internal->client_if = client_if;
 
   // Setup our advertisement. This has no callback.
@@ -370,7 +372,7 @@
 }
 
 void ScanResultCallback(uint16_t ble_evt_type, uint8_t addr_type,
-                        bt_bdaddr_t* bda, uint8_t ble_primary_phy,
+                        RawAddress* bda, uint8_t ble_primary_phy,
                         uint8_t ble_secondary_phy, uint8_t ble_advertising_sid,
                         int8_t ble_tx_power, int8_t rssi,
                         uint16_t ble_periodic_adv_int,
@@ -381,15 +383,15 @@
 }
 
 void ClientConnectCallback(int conn_id, int status, int client_if,
-                           bt_bdaddr_t* bda) {
-  std::string addr(BtAddrString(bda));
+                           const RawAddress& bda) {
+  std::string addr(BtAddrString(&bda));
   LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
            conn_id, status, client_if, addr.c_str());
 }
 
 void ClientDisconnectCallback(int conn_id, int status, int client_if,
-                              bt_bdaddr_t* bda) {
-  std::string addr(BtAddrString(bda));
+                              const RawAddress& bda) {
+  std::string addr(BtAddrString(&bda));
   LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
            conn_id, status, client_if, addr.c_str());
 }
@@ -547,7 +549,7 @@
 
   bt_uuid_t uuid = service_id.GetBlueDroid();
 
-  bt_status_t btstat = internal_->gatt->server->register_server(&uuid);
+  bt_status_t btstat = internal_->gatt->server->register_server(uuid);
   if (btstat != BT_STATUS_SUCCESS) {
     LOG_ERROR(LOG_TAG, "Failed to register server");
     return false;
diff --git a/service/hal/bluetooth_gatt_interface.cc b/service/hal/bluetooth_gatt_interface.cc
index 936a053..f33fdbc 100644
--- a/service/hal/bluetooth_gatt_interface.cc
+++ b/service/hal/bluetooth_gatt_interface.cc
@@ -78,18 +78,18 @@
     }                                                                  \
   } while (0)
 
-void RegisterClientCallback(int status, int client_if, bt_uuid_t* app_uuid) {
+void RegisterClientCallback(int status, int client_if,
+                            const bt_uuid_t& app_uuid) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - status: " << status << " client_if: " << client_if;
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(app_uuid);
 
   FOR_EACH_CLIENT_OBSERVER(
-      RegisterClientCallback(g_interface, status, client_if, *app_uuid));
+      RegisterClientCallback(g_interface, status, client_if, app_uuid));
 }
 
 void ScanResultCallback(
-    uint16_t ble_evt_type, uint8_t addr_type, bt_bdaddr_t* bda,
+    uint16_t ble_evt_type, uint8_t addr_type, RawAddress* bda,
     uint8_t ble_primary_phy, uint8_t ble_secondary_phy,
     uint8_t ble_advertising_sid, int8_t ble_tx_power, int8_t rssi,
     uint16_t ble_periodic_adv_int,
@@ -104,28 +104,28 @@
       ScanResultCallback(g_interface, *bda, rssi, adv_data));
 }
 
-void ConnectCallback(int conn_id, int status, int client_if, bt_bdaddr_t* bda) {
+void ConnectCallback(int conn_id, int status, int client_if,
+                     const RawAddress& bda) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(bda);
 
   VLOG(2) << __func__ << " - status: " << status << " client_if: " << client_if
-          << " - BD_ADDR: " << BtAddrString(bda) << " - conn_id: " << conn_id;
+          << " - BD_ADDR: " << BtAddrString(&bda) << " - conn_id: " << conn_id;
 
   FOR_EACH_CLIENT_OBSERVER(
-      ConnectCallback(g_interface, conn_id, status, client_if, *bda));
+      ConnectCallback(g_interface, conn_id, status, client_if, bda));
 }
 
 void DisconnectCallback(int conn_id, int status, int client_if,
-                        bt_bdaddr_t* bda) {
+                        const RawAddress& bda) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(bda);
 
   VLOG(2) << __func__ << " - conn_id: " << conn_id << " - status: " << status
-          << " client_if: " << client_if << " - BD_ADDR: " << BtAddrString(bda);
+          << " client_if: " << client_if
+          << " - BD_ADDR: " << BtAddrString(&bda);
   FOR_EACH_CLIENT_OBSERVER(
-      DisconnectCallback(g_interface, conn_id, status, client_if, *bda));
+      DisconnectCallback(g_interface, conn_id, status, client_if, bda));
 }
 
 void SearchCompleteCallback(int conn_id, int status) {
@@ -148,14 +148,14 @@
       g_interface, conn_id, status, registered, handle));
 }
 
-void NotifyCallback(int conn_id, btgatt_notify_params_t* p_data) {
+void NotifyCallback(int conn_id, const btgatt_notify_params_t& p_data) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VERIFY_INTERFACE_OR_RETURN();
 
   VLOG(2) << __func__ << " - conn_id: " << conn_id
-          << " - address: " << BtAddrString(&p_data->bda)
-          << " - handle: " << p_data->handle << " - len: " << p_data->len
-          << " - is_notify: " << p_data->is_notify;
+          << " - address: " << BtAddrString(&p_data.bda)
+          << " - handle: " << p_data.handle << " - len: " << p_data.len
+          << " - is_notify: " << p_data.is_notify;
 
   FOR_EACH_CLIENT_OBSERVER(NotifyCallback(g_interface, conn_id, p_data));
 }
@@ -191,7 +191,7 @@
       MtuChangedCallback(g_interface, conn_id, status, mtu));
 }
 
-void GetGattDbCallback(int conn_id, btgatt_db_element_t* db, int size) {
+void GetGattDbCallback(int conn_id, const btgatt_db_element_t* db, int size) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - conn_id: " << conn_id << " size: " << size;
   VERIFY_INTERFACE_OR_RETURN();
@@ -210,7 +210,7 @@
       ServicesRemovedCallback(g_interface, conn_id, start_handle, end_handle));
 }
 
-void ServicesAddedCallback(int conn_id, btgatt_db_element_t* added,
+void ServicesAddedCallback(int conn_id, const btgatt_db_element_t& added,
                            int added_count) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - conn_id: " << conn_id
@@ -221,26 +221,25 @@
       ServicesAddedCallback(g_interface, conn_id, added, added_count));
 }
 
-void RegisterServerCallback(int status, int server_if, bt_uuid_t* app_uuid) {
+void RegisterServerCallback(int status, int server_if,
+                            const bt_uuid_t& app_uuid) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - status: " << status << " server_if: " << server_if;
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(app_uuid);
 
   FOR_EACH_SERVER_OBSERVER(
-      RegisterServerCallback(g_interface, status, server_if, *app_uuid));
+      RegisterServerCallback(g_interface, status, server_if, app_uuid));
 }
 
 void ConnectionCallback(int conn_id, int server_if, int connected,
-                        bt_bdaddr_t* bda) {
+                        const RawAddress& bda) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - conn_id: " << conn_id
           << " server_if: " << server_if << " connected: " << connected;
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(bda);
 
   FOR_EACH_SERVER_OBSERVER(
-      ConnectionCallback(g_interface, conn_id, server_if, connected, *bda));
+      ConnectionCallback(g_interface, conn_id, server_if, connected, bda));
 }
 
 void ServiceAddedCallback(
@@ -277,34 +276,33 @@
 }
 
 void RequestReadCharacteristicCallback(int conn_id, int trans_id,
-                                       bt_bdaddr_t* bda, int attr_handle,
+                                       const RawAddress& bda, int attr_handle,
                                        int offset, bool is_long) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
           << " attr_handle: " << attr_handle << " offset: " << offset
           << " is_long: " << is_long;
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(bda);
 
   FOR_EACH_SERVER_OBSERVER(RequestReadCharacteristicCallback(
-      g_interface, conn_id, trans_id, *bda, attr_handle, offset, is_long));
+      g_interface, conn_id, trans_id, bda, attr_handle, offset, is_long));
 }
 
-void RequestReadDescriptorCallback(int conn_id, int trans_id, bt_bdaddr_t* bda,
-                                   int attr_handle, int offset, bool is_long) {
+void RequestReadDescriptorCallback(int conn_id, int trans_id,
+                                   const RawAddress& bda, int attr_handle,
+                                   int offset, bool is_long) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
           << " attr_handle: " << attr_handle << " offset: " << offset
           << " is_long: " << is_long;
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(bda);
 
   FOR_EACH_SERVER_OBSERVER(RequestReadDescriptorCallback(
-      g_interface, conn_id, trans_id, *bda, attr_handle, offset, is_long));
+      g_interface, conn_id, trans_id, bda, attr_handle, offset, is_long));
 }
 
 void RequestWriteCharacteristicCallback(int conn_id, int trans_id,
-                                        bt_bdaddr_t* bda, int attr_handle,
+                                        const RawAddress& bda, int attr_handle,
                                         int offset, bool need_rsp, bool is_prep,
                                         std::vector<uint8_t> value) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
@@ -313,16 +311,15 @@
           << " length: " << value.size() << " need_rsp: " << need_rsp
           << " is_prep: " << is_prep;
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(bda);
 
   FOR_EACH_SERVER_OBSERVER(RequestWriteCharacteristicCallback(
-      g_interface, conn_id, trans_id, *bda, attr_handle, offset, need_rsp,
+      g_interface, conn_id, trans_id, bda, attr_handle, offset, need_rsp,
       is_prep, value));
 }
 
 void RequestWriteDescriptorCallback(
-    int conn_id, int trans_id, bt_bdaddr_t* bda, int attr_handle, int offset,
-    bool need_rsp, bool is_prep,
+    int conn_id, int trans_id, const RawAddress& bda, int attr_handle,
+    int offset, bool need_rsp, bool is_prep,
     std::vector<uint8_t> value) {  // NOLINT(pass-by-value)
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
@@ -330,23 +327,21 @@
           << " length: " << value.size() << " need_rsp: " << need_rsp
           << " is_prep: " << is_prep;
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(bda);
 
   FOR_EACH_SERVER_OBSERVER(RequestWriteDescriptorCallback(
-      g_interface, conn_id, trans_id, *bda, attr_handle, offset, need_rsp,
+      g_interface, conn_id, trans_id, bda, attr_handle, offset, need_rsp,
       is_prep, value));
 }
 
-void RequestExecWriteCallback(int conn_id, int trans_id, bt_bdaddr_t* bda,
+void RequestExecWriteCallback(int conn_id, int trans_id, const RawAddress& bda,
                               int exec_write) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
           << " exec_write: " << exec_write;
   VERIFY_INTERFACE_OR_RETURN();
-  CHECK(bda);
 
-  FOR_EACH_SERVER_OBSERVER(RequestExecWriteCallback(
-      g_interface, conn_id, trans_id, *bda, exec_write));
+  FOR_EACH_SERVER_OBSERVER(RequestExecWriteCallback(g_interface, conn_id,
+                                                    trans_id, bda, exec_write));
 }
 
 void ResponseConfirmationCallback(int status, int handle) {
@@ -564,7 +559,7 @@
 // themselves are optional.
 
 void BluetoothGattInterface::ScannerObserver::ScanResultCallback(
-    BluetoothGattInterface* /* gatt_iface */, const bt_bdaddr_t& /* bda */,
+    BluetoothGattInterface* /* gatt_iface */, const RawAddress& /* bda */,
     int /* rssi */,
     std::vector<uint8_t> /* adv_data */) {  // NOLINT(pass-by-value)
   // Do Nothing.
@@ -578,13 +573,13 @@
 
 void BluetoothGattInterface::ClientObserver::ConnectCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    int /* status */, int /* client_if */, const bt_bdaddr_t& /* bda */) {
+    int /* status */, int /* client_if */, const RawAddress& /* bda */) {
   // Do nothing
 }
 
 void BluetoothGattInterface::ClientObserver::DisconnectCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    int /* status */, int /* client_if */, const bt_bdaddr_t& /* bda */) {
+    int /* status */, int /* client_if */, const RawAddress& /* bda */) {
   // Do nothing
 }
 
@@ -602,7 +597,7 @@
 
 void BluetoothGattInterface::ClientObserver::NotifyCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    btgatt_notify_params_t* /* p_data */) {
+    const btgatt_notify_params_t& /* p_data */) {
   // Do nothing
 }
 
@@ -626,7 +621,7 @@
 
 void BluetoothGattInterface::ClientObserver::GetGattDbCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    btgatt_db_element_t* /* gatt_db */, int /* size */) {
+    const btgatt_db_element_t* /* gatt_db */, int /* size */) {
   // Do nothing.
 }
 
@@ -638,7 +633,7 @@
 
 void BluetoothGattInterface::ClientObserver::ServicesAddedCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    btgatt_db_element_t* /* added */, int /* added_count */) {
+    const btgatt_db_element_t& /* added */, int /* added_count */) {
   // Do nothing.
 }
 
@@ -650,7 +645,7 @@
 
 void BluetoothGattInterface::ServerObserver::ConnectionCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    int /* server_if */, int /* connected */, const bt_bdaddr_t& /* bda */) {
+    int /* server_if */, int /* connected */, const RawAddress& /* bda */) {
   // Do nothing.
 }
 
@@ -675,21 +670,21 @@
 
 void BluetoothGattInterface::ServerObserver::RequestReadCharacteristicCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    int /* trans_id */, const bt_bdaddr_t& /* bda */, int /* attr_handle */,
+    int /* trans_id */, const RawAddress& /* bda */, int /* attr_handle */,
     int /* offset */, bool /* is_long */) {
   // Do nothing.
 }
 
 void BluetoothGattInterface::ServerObserver::RequestReadDescriptorCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    int /* trans_id */, const bt_bdaddr_t& /* bda */, int /* attr_handle */,
+    int /* trans_id */, const RawAddress& /* bda */, int /* attr_handle */,
     int /* offset */, bool /* is_long */) {
   // Do nothing.
 }
 
 void BluetoothGattInterface::ServerObserver::RequestWriteCharacteristicCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    int /* trans_id */, const bt_bdaddr_t& /* bda */, int /* attr_handle */,
+    int /* trans_id */, const RawAddress& /* bda */, int /* attr_handle */,
     int /* offset */, bool /* need_rsp */, bool /* is_prep */,
     std::vector<uint8_t> /* value */) {  // NOLINT(pass-by-value)
   // Do nothing.
@@ -697,7 +692,7 @@
 
 void BluetoothGattInterface::ServerObserver::RequestWriteDescriptorCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    int /* trans_id */, const bt_bdaddr_t& /* bda */, int /* attr_handle */,
+    int /* trans_id */, const RawAddress& /* bda */, int /* attr_handle */,
     int /* offset */, bool /* need_rsp */, bool /* is_prep */,
     std::vector<uint8_t> /* value */) {  // NOLINT(pass-by-value)
   // Do nothing.
@@ -705,7 +700,7 @@
 
 void BluetoothGattInterface::ServerObserver::RequestExecWriteCallback(
     BluetoothGattInterface* /* gatt_iface */, int /* conn_id */,
-    int /* trans_id */, const bt_bdaddr_t& /* bda */, int /* exec_write */) {
+    int /* trans_id */, const RawAddress& /* bda */, int /* exec_write */) {
   // Do nothing.
 }
 
diff --git a/service/hal/bluetooth_gatt_interface.h b/service/hal/bluetooth_gatt_interface.h
index 9627dc1..345ed88 100644
--- a/service/hal/bluetooth_gatt_interface.h
+++ b/service/hal/bluetooth_gatt_interface.h
@@ -53,7 +53,7 @@
     // "btgatt_scanner_callbacks_t" in the HAL API definitions.
 
     virtual void ScanResultCallback(
-        BluetoothGattInterface* gatt_iface, const bt_bdaddr_t& bda, int rssi,
+        BluetoothGattInterface* gatt_iface, const RawAddress& bda, int rssi,
         std::vector<uint8_t> adv_data);  // NOLINT(pass-by-value)
   };
 
@@ -71,11 +71,11 @@
 
     virtual void ConnectCallback(BluetoothGattInterface* gatt_iface,
                                  int conn_id, int status, int client_if,
-                                 const bt_bdaddr_t& bda);
+                                 const RawAddress& bda);
 
     virtual void DisconnectCallback(BluetoothGattInterface* gatt_iface,
                                     int conn_id, int status, int client_if,
-                                    const bt_bdaddr_t& bda);
+                                    const RawAddress& bda);
 
     virtual void SearchCompleteCallback(BluetoothGattInterface* gatt_iface,
                                         int conn_id, int status);
@@ -85,7 +85,7 @@
         int registered, uint16_t handle);
 
     virtual void NotifyCallback(BluetoothGattInterface* gatt_iface, int conn_id,
-                                btgatt_notify_params_t* p_data);
+                                const btgatt_notify_params_t& p_data);
 
     virtual void WriteCharacteristicCallback(BluetoothGattInterface* gatt_iface,
                                              int conn_id, int status,
@@ -99,7 +99,8 @@
                                     int conn_id, int status, int mtu);
 
     virtual void GetGattDbCallback(BluetoothGattInterface* gatt_iface,
-                                   int conn_id, btgatt_db_element_t* gatt_db,
+                                   int conn_id,
+                                   const btgatt_db_element_t* gatt_db,
                                    int size);
 
     virtual void ServicesRemovedCallback(BluetoothGattInterface* gatt_iface,
@@ -107,7 +108,8 @@
                                          uint16_t end_handle);
 
     virtual void ServicesAddedCallback(BluetoothGattInterface* gatt_iface,
-                                       int conn_id, btgatt_db_element_t* added,
+                                       int conn_id,
+                                       const btgatt_db_element_t& added,
                                        int added_count);
   };
 
@@ -122,7 +124,7 @@
 
     virtual void ConnectionCallback(BluetoothGattInterface* gatt_iface,
                                     int conn_id, int server_if, int connected,
-                                    const bt_bdaddr_t& bda);
+                                    const RawAddress& bda);
 
     virtual void ServiceAddedCallback(
         BluetoothGattInterface* gatt_iface, int status, int server_if,
@@ -138,27 +140,27 @@
 
     virtual void RequestReadCharacteristicCallback(
         BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
-        const bt_bdaddr_t& bda, int attr_handle, int offset, bool is_long);
+        const RawAddress& bda, int attr_handle, int offset, bool is_long);
 
     virtual void RequestReadDescriptorCallback(
         BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
-        const bt_bdaddr_t& bda, int attr_handle, int offset, bool is_long);
+        const RawAddress& bda, int attr_handle, int offset, bool is_long);
 
     virtual void RequestWriteCharacteristicCallback(
         BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
-        const bt_bdaddr_t& bda, int attr_handle, int offset, bool need_rsp,
+        const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
         bool is_prep,
         std::vector<uint8_t> value);  // NOLINT(pass-by-value)
 
     virtual void RequestWriteDescriptorCallback(
         BluetoothGattInterface* gatt_iface, int conn_id, int trans_id,
-        const bt_bdaddr_t& bda, int attr_handle, int offset, bool need_rsp,
+        const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
         bool is_prep,
         std::vector<uint8_t> value);  // NOLINT(pass-by-alue)
 
     virtual void RequestExecWriteCallback(BluetoothGattInterface* gatt_iface,
                                           int conn_id, int trans_id,
-                                          const bt_bdaddr_t& bda,
+                                          const RawAddress& bda,
                                           int exec_write);
 
     virtual void ResponseConfirmationCallback(
diff --git a/service/hal/bluetooth_interface.cc b/service/hal/bluetooth_interface.cc
index cf55afd..39816ef 100644
--- a/service/hal/bluetooth_interface.cc
+++ b/service/hal/bluetooth_interface.cc
@@ -83,7 +83,7 @@
 }
 
 void RemoteDevicePropertiesCallback(bt_status_t status,
-                                    bt_bdaddr_t* remote_bd_addr,
+                                    RawAddress* remote_bd_addr,
                                     int num_properties,
                                     bt_property_t* properties) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
@@ -103,7 +103,7 @@
   FOR_EACH_BLUETOOTH_OBSERVER(DiscoveryStateChangedCallback(state));
 }
 
-void PinRequestCallback(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name,
+void PinRequestCallback(RawAddress* remote_bd_addr, bt_bdname_t* bd_name,
                         uint32_t cod, bool min_16_digit) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VERIFY_INTERFACE_OR_RETURN();
@@ -114,7 +114,7 @@
       PinRequestCallback(remote_bd_addr, bd_name, cod, min_16_digit));
 }
 
-void SSPRequestCallback(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name,
+void SSPRequestCallback(RawAddress* remote_bd_addr, bt_bdname_t* bd_name,
                         uint32_t cod, bt_ssp_variant_t pairing_variant,
                         uint32_t pass_key) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
@@ -126,7 +126,7 @@
                                                  pairing_variant, pass_key));
 }
 
-void BondStateChangedCallback(bt_status_t status, bt_bdaddr_t* remote_bd_addr,
+void BondStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr,
                               bt_bond_state_t state) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VERIFY_INTERFACE_OR_RETURN();
@@ -136,7 +136,7 @@
       BondStateChangedCallback(status, remote_bd_addr, state));
 }
 
-void AclStateChangedCallback(bt_status_t status, bt_bdaddr_t* remote_bd_addr,
+void AclStateChangedCallback(bt_status_t status, RawAddress* remote_bd_addr,
                              bt_acl_state_t state) {
   shared_lock<shared_mutex_impl> lock(g_instance_lock);
   VERIFY_INTERFACE_OR_RETURN();
@@ -320,7 +320,7 @@
 }
 
 void BluetoothInterface::Observer::RemoteDevicePropertiesCallback(
-    bt_status_t /* status */, bt_bdaddr_t* /* remote_bd_addr */,
+    bt_status_t /* status */, RawAddress* /* remote_bd_addr */,
     int /* num_properties */, bt_property_t* /* properties */) {
   // Do nothing.
 }
@@ -331,24 +331,24 @@
 }
 
 void BluetoothInterface::Observer::PinRequestCallback(
-    bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
+    RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
     bool min_16_digit) {
   // Do nothing.
 }
 
 void BluetoothInterface::Observer::SSPRequestCallback(
-    bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
+    RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
     bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
   // Do nothing.
 }
 
 void BluetoothInterface::Observer::BondStateChangedCallback(
-    bt_status_t status, bt_bdaddr_t* remote_bd_addr, bt_bond_state_t state) {
+    bt_status_t status, RawAddress* remote_bd_addr, bt_bond_state_t state) {
   // Do nothing.
 }
 
 void BluetoothInterface::Observer::AclStateChangedCallback(
-    bt_status_t /* status */, const bt_bdaddr_t& /* remote_bdaddr */,
+    bt_status_t /* status */, const RawAddress& /* remote_bdaddr */,
     bt_acl_state_t /* state */) {
   // Do nothing.
 }
diff --git a/service/hal/bluetooth_interface.h b/service/hal/bluetooth_interface.h
index 92d94ba..49d621c 100644
--- a/service/hal/bluetooth_interface.h
+++ b/service/hal/bluetooth_interface.h
@@ -54,22 +54,22 @@
                                            int num_properties,
                                            bt_property_t* properties);
     virtual void RemoteDevicePropertiesCallback(bt_status_t status,
-                                                bt_bdaddr_t* remote_bd_addr,
+                                                RawAddress* remote_bd_addr,
                                                 int num_properties,
                                                 bt_property_t* properties);
     virtual void DiscoveryStateChangedCallback(bt_discovery_state_t state);
-    virtual void PinRequestCallback(bt_bdaddr_t* remote_bd_addr,
+    virtual void PinRequestCallback(RawAddress* remote_bd_addr,
                                     bt_bdname_t* bd_name, uint32_t cod,
                                     bool min_16_digit);
-    virtual void SSPRequestCallback(bt_bdaddr_t* remote_bd_addr,
+    virtual void SSPRequestCallback(RawAddress* remote_bd_addr,
                                     bt_bdname_t* bd_name, uint32_t cod,
                                     bt_ssp_variant_t pairing_variant,
                                     uint32_t pass_key);
     virtual void BondStateChangedCallback(bt_status_t status,
-                                          bt_bdaddr_t* remote_bd_addr,
+                                          RawAddress* remote_bd_addr,
                                           bt_bond_state_t state);
     virtual void AclStateChangedCallback(bt_status_t status,
-                                         const bt_bdaddr_t& remote_bdaddr,
+                                         const RawAddress& remote_bdaddr,
                                          bt_acl_state_t state);
 
     // TODO(armansito): Complete the list of callbacks.
diff --git a/service/hal/fake_bluetooth_gatt_interface.cc b/service/hal/fake_bluetooth_gatt_interface.cc
index dba1f57..42ccb51 100644
--- a/service/hal/fake_bluetooth_gatt_interface.cc
+++ b/service/hal/fake_bluetooth_gatt_interface.cc
@@ -28,7 +28,7 @@
 std::shared_ptr<FakeBluetoothGattInterface::TestClientHandler> g_client_handler;
 std::shared_ptr<FakeBluetoothGattInterface::TestServerHandler> g_server_handler;
 
-bt_status_t FakeRegisterClient(bt_uuid_t* app_uuid) {
+bt_status_t FakeRegisterClient(const bt_uuid_t& app_uuid) {
   if (g_client_handler) return g_client_handler->RegisterClient(app_uuid);
 
   return BT_STATUS_FAIL;
@@ -40,7 +40,7 @@
   return BT_STATUS_FAIL;
 }
 
-bt_status_t FakeConnect(int client_if, const bt_bdaddr_t* bd_addr,
+bt_status_t FakeConnect(int client_if, const RawAddress& bd_addr,
                         bool is_direct, int transport, bool opportunistic,
                         int phy) {
   if (g_client_handler)
@@ -49,7 +49,7 @@
   return BT_STATUS_FAIL;
 }
 
-bt_status_t FakeDisconnect(int client_if, const bt_bdaddr_t* bd_addr,
+bt_status_t FakeDisconnect(int client_if, const RawAddress& bd_addr,
                            int conn_id) {
   if (g_client_handler)
     return g_client_handler->Disconnect(client_if, bd_addr, conn_id);
@@ -57,7 +57,7 @@
   return BT_STATUS_FAIL;
 }
 
-bt_status_t FakeRegisterServer(bt_uuid_t* app_uuid) {
+bt_status_t FakeRegisterServer(const bt_uuid_t& app_uuid) {
   if (g_server_handler) return g_server_handler->RegisterServer(app_uuid);
 
   return BT_STATUS_FAIL;
@@ -94,7 +94,7 @@
 }
 
 bt_status_t FakeSendResponse(int conn_id, int trans_id, int status,
-                             btgatt_response_t* response) {
+                             const btgatt_response_t& response) {
   if (g_server_handler)
     return g_server_handler->SendResponse(conn_id, trans_id, status, response);
 
@@ -177,7 +177,7 @@
 // The methods below can be used to notify observers with certain events and
 // given parameters.
 void FakeBluetoothGattInterface::NotifyScanResultCallback(
-    const bt_bdaddr_t& bda, int rssi, std::vector<uint8_t> adv_data) {
+    const RawAddress& bda, int rssi, std::vector<uint8_t> adv_data) {
   FOR_EACH_OBSERVER(ScannerObserver, scanner_observers_,
                     ScanResultCallback(this, bda, rssi, adv_data));
 }
@@ -190,13 +190,13 @@
 
 void FakeBluetoothGattInterface::NotifyConnectCallback(int conn_id, int status,
                                                        int client_if,
-                                                       const bt_bdaddr_t& bda) {
+                                                       const RawAddress& bda) {
   FOR_EACH_OBSERVER(ClientObserver, client_observers_,
                     ConnectCallback(this, conn_id, status, client_if, bda));
 }
 
 void FakeBluetoothGattInterface::NotifyDisconnectCallback(
-    int conn_id, int status, int client_if, const bt_bdaddr_t& bda) {
+    int conn_id, int status, int client_if, const RawAddress& bda) {
   FOR_EACH_OBSERVER(ClientObserver, client_observers_,
                     DisconnectCallback(this, conn_id, status, client_if, bda));
 }
@@ -208,7 +208,7 @@
 }
 
 void FakeBluetoothGattInterface::NotifyServerConnectionCallback(
-    int conn_id, int server_if, int connected, const bt_bdaddr_t& bda) {
+    int conn_id, int server_if, int connected, const RawAddress& bda) {
   FOR_EACH_OBSERVER(
       ServerObserver, server_observers_,
       ConnectionCallback(this, conn_id, server_if, connected, bda));
@@ -221,7 +221,7 @@
 }
 
 void FakeBluetoothGattInterface::NotifyRequestReadCharacteristicCallback(
-    int conn_id, int trans_id, const bt_bdaddr_t& bda, int attr_handle,
+    int conn_id, int trans_id, const RawAddress& bda, int attr_handle,
     int offset, bool is_long) {
   FOR_EACH_OBSERVER(
       ServerObserver, server_observers_,
@@ -230,7 +230,7 @@
 }
 
 void FakeBluetoothGattInterface::NotifyRequestReadDescriptorCallback(
-    int conn_id, int trans_id, const bt_bdaddr_t& bda, int attr_handle,
+    int conn_id, int trans_id, const RawAddress& bda, int attr_handle,
     int offset, bool is_long) {
   FOR_EACH_OBSERVER(
       ServerObserver, server_observers_,
@@ -239,7 +239,7 @@
 }
 
 void FakeBluetoothGattInterface::NotifyRequestWriteCharacteristicCallback(
-    int conn_id, int trans_id, const bt_bdaddr_t& bda, int attr_handle,
+    int conn_id, int trans_id, const RawAddress& bda, int attr_handle,
     int offset, bool need_rsp, bool is_prep, std::vector<uint8_t> value) {
   FOR_EACH_OBSERVER(ServerObserver, server_observers_,
                     RequestWriteCharacteristicCallback(
@@ -248,7 +248,7 @@
 }
 
 void FakeBluetoothGattInterface::NotifyRequestWriteDescriptorCallback(
-    int conn_id, int trans_id, const bt_bdaddr_t& bda, int attr_handle,
+    int conn_id, int trans_id, const RawAddress& bda, int attr_handle,
     int offset, bool need_rsp, bool is_prep, std::vector<uint8_t> value) {
   FOR_EACH_OBSERVER(
       ServerObserver, server_observers_,
@@ -257,7 +257,7 @@
 }
 
 void FakeBluetoothGattInterface::NotifyRequestExecWriteCallback(
-    int conn_id, int trans_id, const bt_bdaddr_t& bda, int exec_write) {
+    int conn_id, int trans_id, const RawAddress& bda, int exec_write) {
   FOR_EACH_OBSERVER(
       ServerObserver, server_observers_,
       RequestExecWriteCallback(this, conn_id, trans_id, bda, exec_write));
diff --git a/service/hal/fake_bluetooth_gatt_interface.h b/service/hal/fake_bluetooth_gatt_interface.h
index c96f7f0..7ad3c89 100644
--- a/service/hal/fake_bluetooth_gatt_interface.h
+++ b/service/hal/fake_bluetooth_gatt_interface.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <vector>
+
 #include <base/macros.h>
 #include <base/observer_list.h>
 
@@ -33,12 +35,12 @@
    public:
     virtual ~TestClientHandler() = default;
 
-    virtual bt_status_t RegisterClient(bt_uuid_t* app_uuid) = 0;
+    virtual bt_status_t RegisterClient(const bt_uuid_t& app_uuid) = 0;
     virtual bt_status_t UnregisterClient(int client_if) = 0;
 
-    virtual bt_status_t Connect(int client_if, const bt_bdaddr_t* bd_addr,
+    virtual bt_status_t Connect(int client_if, const RawAddress& bd_addr,
                                 bool is_direct, int transport) = 0;
-    virtual bt_status_t Disconnect(int client_if, const bt_bdaddr_t* bd_addr,
+    virtual bt_status_t Disconnect(int client_if, const RawAddress& bd_addr,
                                    int conn_id) = 0;
   };
 
@@ -49,7 +51,7 @@
    public:
     virtual ~TestServerHandler() = default;
 
-    virtual bt_status_t RegisterServer(bt_uuid_t* app_uuid) = 0;
+    virtual bt_status_t RegisterServer(const bt_uuid_t& app_uuid) = 0;
     virtual bt_status_t UnregisterServer(int server_if) = 0;
     virtual bt_status_t AddService(
         int server_if, std::vector<btgatt_db_element_t> service) = 0;
@@ -58,7 +60,7 @@
                                        int conn_id, int confirm,
                                        std::vector<uint8_t> value) = 0;
     virtual bt_status_t SendResponse(int conn_id, int trans_id, int status,
-                                     btgatt_response_t* response) = 0;
+                                     const btgatt_response_t& response) = 0;
   };
 
   // Constructs the fake with the given handlers. Implementations can
@@ -76,22 +78,22 @@
 
   void NotifyRegisterScannerCallback(int status, int client_if,
                                      const bt_uuid_t& app_uuid);
-  void NotifyScanResultCallback(const bt_bdaddr_t& bda, int rssi,
+  void NotifyScanResultCallback(const RawAddress& bda, int rssi,
                                 std::vector<uint8_t> adv_data);
 
   // Client callbacks:
   void NotifyRegisterClientCallback(int status, int client_if,
                                     const bt_uuid_t& app_uuid);
   void NotifyConnectCallback(int conn_id, int status, int client_if,
-                             const bt_bdaddr_t& bda);
+                             const RawAddress& bda);
   void NotifyDisconnectCallback(int conn_id, int status, int client_if,
-                                const bt_bdaddr_t& bda);
+                                const RawAddress& bda);
 
   // Server callbacks:
   void NotifyRegisterServerCallback(int status, int server_if,
                                     const bt_uuid_t& app_uuid);
   void NotifyServerConnectionCallback(int conn_id, int server_if, int connected,
-                                      const bt_bdaddr_t& bda);
+                                      const RawAddress& bda);
   void NotifyServiceAddedCallback(int status, int server_if,
                                   std::vector<btgatt_db_element_t> srvc);
   void NotifyCharacteristicAddedCallback(int status, int server_if,
@@ -102,25 +104,25 @@
                                      int desc_handle);
   void NotifyServiceStartedCallback(int status, int server_if, int srvc_handle);
   void NotifyRequestReadCharacteristicCallback(int conn_id, int trans_id,
-                                               const bt_bdaddr_t& bda,
+                                               const RawAddress& bda,
                                                int attr_handle, int offset,
                                                bool is_long);
   void NotifyRequestReadDescriptorCallback(int conn_id, int trans_id,
-                                           const bt_bdaddr_t& bda,
+                                           const RawAddress& bda,
                                            int attr_handle, int offset,
                                            bool is_long);
   void NotifyRequestWriteCharacteristicCallback(int conn_id, int trans_id,
-                                                const bt_bdaddr_t& bda,
+                                                const RawAddress& bda,
                                                 int attr_handle, int offset,
                                                 bool need_rsp, bool is_prep,
                                                 std::vector<uint8_t> value);
   void NotifyRequestWriteDescriptorCallback(int conn_id, int trans_id,
-                                            const bt_bdaddr_t& bda,
+                                            const RawAddress& bda,
                                             int attr_handle, int offset,
                                             bool need_rsp, bool is_prep,
                                             std::vector<uint8_t> value);
   void NotifyRequestExecWriteCallback(int conn_id, int trans_id,
-                                      const bt_bdaddr_t& bda, int exec_write);
+                                      const RawAddress& bda, int exec_write);
   void NotifyIndicationSentCallback(int conn_id, int status);
 
   // BluetoothGattInterface overrides:
diff --git a/service/hal/fake_bluetooth_interface.cc b/service/hal/fake_bluetooth_interface.cc
index 95f1f98..45fdca0 100644
--- a/service/hal/fake_bluetooth_interface.cc
+++ b/service/hal/fake_bluetooth_interface.cc
@@ -113,10 +113,10 @@
 }
 
 void FakeBluetoothInterface::NotifyAdapterAddressPropertyChanged(
-    const bt_bdaddr_t* address) {
+    const RawAddress* address) {
   bt_property_t property;
-  property.len = sizeof(bt_bdaddr_t);
-  property.val = (void*)address;
+  property.len = RawAddress::kLength;
+  property.val = (void*)address->address;
   property.type = BT_PROPERTY_BDADDR;
 
   NotifyAdapterPropertiesChanged(1, &property);
@@ -133,8 +133,7 @@
 }
 
 void FakeBluetoothInterface::NotifyAclStateChangedCallback(
-    bt_status_t status, const bt_bdaddr_t& remote_bdaddr,
-    bt_acl_state_t state) {
+    bt_status_t status, const RawAddress& remote_bdaddr, bt_acl_state_t state) {
   FOR_EACH_OBSERVER(Observer, observers_,
                     AclStateChangedCallback(status, remote_bdaddr, state));
 }
diff --git a/service/hal/fake_bluetooth_interface.h b/service/hal/fake_bluetooth_interface.h
index 1b2e246..b0fd657 100644
--- a/service/hal/fake_bluetooth_interface.h
+++ b/service/hal/fake_bluetooth_interface.h
@@ -51,11 +51,11 @@
   void NotifyAdapterPropertiesChanged(int num_properties,
                                       bt_property_t* properties);
   void NotifyAdapterNamePropertyChanged(const std::string& name);
-  void NotifyAdapterAddressPropertyChanged(const bt_bdaddr_t* address);
+  void NotifyAdapterAddressPropertyChanged(const RawAddress* address);
   void NotifyAdapterLocalLeFeaturesPropertyChanged(
       const bt_local_le_features_t* features);
   void NotifyAclStateChangedCallback(bt_status_t status,
-                                     const bt_bdaddr_t& remote_bdaddr,
+                                     const RawAddress& remote_bdaddr,
                                      bt_acl_state_t state);
 
   // hal::BluetoothInterface overrides:
diff --git a/service/ipc/dbus/bluetooth_adapter.cc b/service/ipc/dbus/bluetooth_adapter.cc
index 171fef0..8619a35 100644
--- a/service/ipc/dbus/bluetooth_adapter.cc
+++ b/service/ipc/dbus/bluetooth_adapter.cc
@@ -17,7 +17,6 @@
 #include "service/ipc/dbus/bluetooth_adapter.h"
 #include <base/files/file_util.h>
 #include <base/logging.h>
-#include "service/common/bluetooth/util/address_helper.h"
 #include "service/hal/bluetooth_interface.h"
 
 using ::dbus::Bus;
diff --git a/service/logging_helpers.cc b/service/logging_helpers.cc
index 34e70e4..39706ec 100644
--- a/service/logging_helpers.cc
+++ b/service/logging_helpers.cc
@@ -140,7 +140,7 @@
   }
 }
 
-std::string BtAddrString(const bt_bdaddr_t* addr) {
+std::string BtAddrString(const RawAddress* addr) {
   char buffer[20];
   snprintf(buffer, sizeof(buffer), "%02X:%02X:%02X:%02X:%02X:%02X",
            addr->address[0], addr->address[1], addr->address[2],
diff --git a/service/logging_helpers.h b/service/logging_helpers.h
index 4462f3e..d3c58d1 100644
--- a/service/logging_helpers.h
+++ b/service/logging_helpers.h
@@ -44,4 +44,4 @@
 const char* BtAclText(const bt_acl_state_t state);
 
 // TODO(icoolidge): Address object.
-std::string BtAddrString(const bt_bdaddr_t* addr);
+std::string BtAddrString(const RawAddress* addr);
diff --git a/service/low_energy_advertiser.cc b/service/low_energy_advertiser.cc
index f25d4f9..3df55db 100644
--- a/service/low_energy_advertiser.cc
+++ b/service/low_energy_advertiser.cc
@@ -20,7 +20,6 @@
 #include <base/logging.h>
 
 #include "service/adapter.h"
-#include "service/common/bluetooth/util/address_helper.h"
 #include "service/logging_helpers.h"
 #include "stack/include/bt_types.h"
 #include "stack/include/hcidefs.h"
diff --git a/service/low_energy_client.cc b/service/low_energy_client.cc
index ed1cf46..acb1bf9 100644
--- a/service/low_energy_client.cc
+++ b/service/low_energy_client.cc
@@ -19,7 +19,6 @@
 #include <base/logging.h>
 
 #include "service/adapter.h"
-#include "service/common/bluetooth/util/address_helper.h"
 #include "service/logging_helpers.h"
 #include "stack/include/bt_types.h"
 #include "stack/include/hcidefs.h"
@@ -54,12 +53,12 @@
 bool LowEnergyClient::Connect(const std::string& address, bool is_direct) {
   VLOG(2) << __func__ << "Address: " << address << " is_direct: " << is_direct;
 
-  bt_bdaddr_t bda;
-  util::BdAddrFromString(address, &bda);
+  RawAddress bda;
+  RawAddress::FromString(address, bda);
 
   bt_status_t status =
       hal::BluetoothGattInterface::Get()->GetClientHALInterface()->connect(
-          client_id_, &bda, is_direct, BT_TRANSPORT_LE, false, PHY_LE_1M_MASK);
+          client_id_, bda, is_direct, BT_TRANSPORT_LE, false, PHY_LE_1M_MASK);
   if (status != BT_STATUS_SUCCESS) {
     LOG(ERROR) << "HAL call to connect failed";
     return false;
@@ -71,10 +70,10 @@
 bool LowEnergyClient::Disconnect(const std::string& address) {
   VLOG(2) << __func__ << "Address: " << address;
 
-  bt_bdaddr_t bda;
-  util::BdAddrFromString(address, &bda);
+  RawAddress bda;
+  RawAddress::FromString(address, bda);
 
-  std::map<const bt_bdaddr_t, int>::iterator conn_id;
+  std::map<const RawAddress, int>::iterator conn_id;
   {
     lock_guard<mutex> lock(connection_fields_lock_);
     conn_id = connection_ids_.find(bda);
@@ -86,7 +85,7 @@
 
   bt_status_t status =
       hal::BluetoothGattInterface::Get()->GetClientHALInterface()->disconnect(
-          client_id_, &bda, conn_id->second);
+          client_id_, bda, conn_id->second);
   if (status != BT_STATUS_SUCCESS) {
     LOG(ERROR) << "HAL call to disconnect failed";
     return false;
@@ -98,10 +97,10 @@
 bool LowEnergyClient::SetMtu(const std::string& address, int mtu) {
   VLOG(2) << __func__ << "Address: " << address << " MTU: " << mtu;
 
-  bt_bdaddr_t bda;
-  util::BdAddrFromString(address, &bda);
+  RawAddress bda;
+  RawAddress::FromString(address, bda);
 
-  std::map<const bt_bdaddr_t, int>::iterator conn_id;
+  std::map<const RawAddress, int>::iterator conn_id;
   {
     lock_guard<mutex> lock(connection_fields_lock_);
     conn_id = connection_ids_.find(bda);
@@ -135,7 +134,7 @@
 
 void LowEnergyClient::ConnectCallback(hal::BluetoothGattInterface* gatt_iface,
                                       int conn_id, int status, int client_id,
-                                      const bt_bdaddr_t& bda) {
+                                      const RawAddress& bda) {
   if (client_id != client_id_) return;
 
   VLOG(1) << __func__ << "client_id: " << client_id << " status: " << status;
@@ -155,7 +154,7 @@
 
 void LowEnergyClient::DisconnectCallback(
     hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
-    int client_id, const bt_bdaddr_t& bda) {
+    int client_id, const RawAddress& bda) {
   if (client_id != client_id_) return;
 
   VLOG(1) << __func__ << " client_id: " << client_id << " status: " << status;
@@ -176,7 +175,7 @@
   VLOG(1) << __func__ << " conn_id: " << conn_id << " status: " << status
           << " mtu: " << mtu;
 
-  const bt_bdaddr_t* bda = nullptr;
+  const RawAddress* bda = nullptr;
   {
     lock_guard<mutex> lock(connection_fields_lock_);
     for (auto& connection : connection_ids_) {
@@ -220,7 +219,7 @@
       hal::BluetoothGattInterface::Get()->GetClientHALInterface();
   bt_uuid_t app_uuid = uuid.GetBlueDroid();
 
-  if (hal_iface->register_client(&app_uuid) != BT_STATUS_SUCCESS) return false;
+  if (hal_iface->register_client(app_uuid) != BT_STATUS_SUCCESS) return false;
 
   pending_calls_[uuid] = callback;
 
diff --git a/service/low_energy_client.h b/service/low_energy_client.h
index d9b1d37..16ef4a5 100644
--- a/service/low_energy_client.h
+++ b/service/low_energy_client.h
@@ -34,8 +34,8 @@
 namespace bluetooth {
 
 struct ConnComparator {
-  bool operator()(const bt_bdaddr_t& a, const bt_bdaddr_t& b) const {
-    return memcmp(&a, &b, sizeof(bt_bdaddr_t)) < 0;
+  bool operator()(const RawAddress& a, const RawAddress& b) const {
+    return memcmp(a.address, b.address, RawAddress::kLength) < 0;
   }
 };
 
@@ -104,10 +104,10 @@
   // BluetoothGattInterface::ClientObserver overrides:
   void ConnectCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
                        int status, int client_id,
-                       const bt_bdaddr_t& bda) override;
+                       const RawAddress& bda) override;
   void DisconnectCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
                           int status, int client_id,
-                          const bt_bdaddr_t& bda) override;
+                          const RawAddress& bda) override;
   void MtuChangedCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
                           int status, int mtu) override;
 
@@ -132,7 +132,7 @@
 
   // Maps bluetooth address to connection id
   // TODO(jpawlowski): change type to bimap
-  std::map<const bt_bdaddr_t, int, ConnComparator> connection_ids_;
+  std::map<const RawAddress, int, ConnComparator> connection_ids_;
 
   DISALLOW_COPY_AND_ASSIGN(LowEnergyClient);
 };
diff --git a/service/low_energy_scanner.cc b/service/low_energy_scanner.cc
index 5220414..093a554 100644
--- a/service/low_energy_scanner.cc
+++ b/service/low_energy_scanner.cc
@@ -20,7 +20,6 @@
 #include <base/logging.h>
 
 #include "service/adapter.h"
-#include "service/common/bluetooth/util/address_helper.h"
 #include "service/logging_helpers.h"
 #include "stack/include/bt_types.h"
 #include "stack/include/hcidefs.h"
@@ -139,7 +138,7 @@
 int LowEnergyScanner::GetInstanceId() const { return scanner_id_; }
 
 void LowEnergyScanner::ScanResultCallback(
-    hal::BluetoothGattInterface* gatt_iface, const bt_bdaddr_t& bda, int rssi,
+    hal::BluetoothGattInterface* gatt_iface, const RawAddress& bda, int rssi,
     std::vector<uint8_t> adv_data) {
   // Ignore scan results if this client didn't start a scan.
   if (!scan_started_.load()) return;
diff --git a/service/low_energy_scanner.h b/service/low_energy_scanner.h
index e7f6584..279ea7b 100644
--- a/service/low_energy_scanner.h
+++ b/service/low_energy_scanner.h
@@ -85,7 +85,7 @@
   int GetInstanceId() const override;
 
   void ScanResultCallback(hal::BluetoothGattInterface* gatt_iface,
-                          const bt_bdaddr_t& bda, int rssi,
+                          const RawAddress& bda, int rssi,
                           std::vector<uint8_t> adv_data) override;
 
  private:
diff --git a/service/settings.cc b/service/settings.cc
index d4728d7..79ac030 100644
--- a/service/settings.cc
+++ b/service/settings.cc
@@ -24,7 +24,7 @@
 
 namespace bluetooth {
 
-Settings::Settings() : initialized_(false) {}
+Settings::Settings() : initialized_(false), enable_on_start_(false) {}
 
 Settings::~Settings() {}
 
@@ -54,6 +54,16 @@
       }
 
       android_ipc_socket_suffix_ = suffix;
+    } else if (iter.first == switches::kEnableOnStart) {
+      if (iter.second == "true") {
+        enable_on_start_ = true;
+      } else if (iter.second == "false") {
+        enable_on_start_ = false;
+      } else {
+        LOG(ERROR) << "Invalid value for " << switches::kEnableOnStart << ": "
+                   << iter.second << ". Expect 'true' or 'false'";
+        return false;
+      }
     }
     // Check for libbase logging switches. These get processed by
     // logging::InitLogging directly.
diff --git a/service/settings.h b/service/settings.h
index d68bda1..4e7a6b4 100644
--- a/service/settings.h
+++ b/service/settings.h
@@ -60,8 +60,11 @@
            !create_ipc_socket_path().empty();
   }
 
+  bool EnableOnStart() const { return enable_on_start_; }
+
  private:
   bool initialized_;
+  bool enable_on_start_;
   std::string android_ipc_socket_suffix_;
   base::FilePath create_ipc_socket_path_;
 
diff --git a/service/switches.h b/service/switches.h
index af23398..fe6056a 100644
--- a/service/switches.h
+++ b/service/switches.h
@@ -26,6 +26,7 @@
 const char kHelpShort[] = "h";
 const char kAndroidIPCSocketSuffix[] = "android-ipc-socket-suffix";
 const char kCreateIPCSocketPath[] = "create-ipc-socket";
+const char kEnableOnStart[] = "enable-on-start";
 
 const char kHelpMessage[] =
     "\nBluetooth System Service\n"
@@ -36,6 +37,8 @@
     "Mutually exclusive with --create-ipc-socket.\n"
     "\t--create-ipc-socket\t\tSocket path created for Unix domain socket based "
     "IPC. Mutually exclusive with --android-ipc-socket-suffix.\n"
+    "\t--enable-on-start (true|false)\tIf true, enable adapter as soon as the "
+    "daemon starts.\n"
     "\t--v\t\t\t\tLog verbosity level (e.g. -v=1)\n";
 
 }  // namespace switches
diff --git a/service/test/adapter_unittest.cc b/service/test/adapter_unittest.cc
index f7ee109..c3827dc 100644
--- a/service/test/adapter_unittest.cc
+++ b/service/test/adapter_unittest.cc
@@ -18,7 +18,6 @@
 #include <gtest/gtest.h>
 
 #include "service/adapter.h"
-#include "service/common/bluetooth/util/address_helper.h"
 #include "service/hal/fake_bluetooth_gatt_interface.h"
 #include "service/hal/fake_bluetooth_interface.h"
 
@@ -227,7 +226,7 @@
 TEST_F(AdapterTest, GetAddress) {
   EXPECT_EQ(bluetooth::Adapter::kDefaultAddress, adapter_->GetAddress());
 
-  const bt_bdaddr_t kTestAdapterInput = {{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}};
+  const RawAddress kTestAdapterInput = {{0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}};
   const char kTestAdapterAddressOutput[] = "12:34:56:78:9A:BC";
 
   fake_hal_iface_->NotifyAdapterAddressPropertyChanged(&kTestAdapterInput);
@@ -255,8 +254,8 @@
 
   EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr));
 
-  bt_bdaddr_t hal_addr;
-  ASSERT_TRUE(util::BdAddrFromString(kDeviceAddr, &hal_addr));
+  RawAddress hal_addr;
+  ASSERT_TRUE(RawAddress::FromString(kDeviceAddr, hal_addr));
 
   // status != BT_STATUS_SUCCESS should be ignored
   fake_hal_iface_->NotifyAclStateChangedCallback(BT_STATUS_FAIL, hal_addr,
diff --git a/service/test/gatt_client_unittest.cc b/service/test/gatt_client_unittest.cc
index 7527e8b..2d59106 100644
--- a/service/test/gatt_client_unittest.cc
+++ b/service/test/gatt_client_unittest.cc
@@ -33,11 +33,11 @@
   MockGattHandler() = default;
   ~MockGattHandler() override = default;
 
-  MOCK_METHOD1(RegisterClient, bt_status_t(bt_uuid_t*));
+  MOCK_METHOD1(RegisterClient, bt_status_t(const bt_uuid_t&));
   MOCK_METHOD1(UnregisterClient, bt_status_t(int));
   MOCK_METHOD1(Scan, bt_status_t(bool));
-  MOCK_METHOD4(Connect, bt_status_t(int, const bt_bdaddr_t*, bool, int));
-  MOCK_METHOD3(Disconnect, bt_status_t(int, const bt_bdaddr_t*, int));
+  MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int));
+  MOCK_METHOD3(Disconnect, bt_status_t(int, const RawAddress&, int));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
diff --git a/service/test/gatt_server_unittest.cc b/service/test/gatt_server_unittest.cc
index ee88b99..0e70ac9 100644
--- a/service/test/gatt_server_unittest.cc
+++ b/service/test/gatt_server_unittest.cc
@@ -17,7 +17,6 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
-#include "service/common/bluetooth/util/address_helper.h"
 #include "service/gatt_server.h"
 #include "service/hal/fake_bluetooth_gatt_interface.h"
 
@@ -33,7 +32,7 @@
   MockGattHandler() = default;
   ~MockGattHandler() override = default;
 
-  MOCK_METHOD1(RegisterServer, bt_status_t(bt_uuid_t*));
+  MOCK_METHOD1(RegisterServer, bt_status_t(const bt_uuid_t&));
   MOCK_METHOD1(UnregisterServer, bt_status_t(int));
   MOCK_METHOD2(AddService, bt_status_t(int, std::vector<btgatt_db_element_t>));
   MOCK_METHOD5(AddCharacteristic, bt_status_t(int, int, bt_uuid_t*, int, int));
@@ -42,7 +41,8 @@
   MOCK_METHOD2(DeleteService, bt_status_t(int, int));
   MOCK_METHOD5(SendIndication,
                bt_status_t(int, int, int, int, std::vector<uint8_t>));
-  MOCK_METHOD4(SendResponse, bt_status_t(int, int, int, btgatt_response_t*));
+  MOCK_METHOD4(SendResponse,
+               bt_status_t(int, int, int, const btgatt_response_t&));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
@@ -399,9 +399,9 @@
   EXPECT_FALSE(gatt_server_->SendResponse(kTestAddress0, kReqId0,
                                           GATT_ERROR_NONE, 0, kTestValue));
 
-  bt_bdaddr_t hal_addr0, hal_addr1;
-  ASSERT_TRUE(util::BdAddrFromString(kTestAddress0, &hal_addr0));
-  ASSERT_TRUE(util::BdAddrFromString(kTestAddress1, &hal_addr1));
+  RawAddress hal_addr0, hal_addr1;
+  ASSERT_TRUE(RawAddress::FromString(kTestAddress0, hal_addr0));
+  ASSERT_TRUE(RawAddress::FromString(kTestAddress1, hal_addr1));
 
   // Send a connection callback. The GattServer should store the connection
   // information and be able to process the incoming read requests for this
@@ -509,9 +509,9 @@
   EXPECT_FALSE(gatt_server_->SendResponse(kTestAddress0, kReqId0,
                                           GATT_ERROR_NONE, 0, kTestValue));
 
-  bt_bdaddr_t hal_addr0, hal_addr1;
-  ASSERT_TRUE(util::BdAddrFromString(kTestAddress0, &hal_addr0));
-  ASSERT_TRUE(util::BdAddrFromString(kTestAddress1, &hal_addr1));
+  RawAddress hal_addr0, hal_addr1;
+  ASSERT_TRUE(RawAddress::FromString(kTestAddress0, hal_addr0));
+  ASSERT_TRUE(RawAddress::FromString(kTestAddress1, hal_addr1));
 
   // Send a connection callback. The GattServer should store the connection
   // information and be able to process the incoming read requests for this
@@ -619,8 +619,8 @@
   const int kConnId0 = 0;
   const int kConnId1 = 1;
   std::vector<uint8_t> value;
-  bt_bdaddr_t hal_addr0;
-  ASSERT_TRUE(util::BdAddrFromString(kTestAddress0, &hal_addr0));
+  RawAddress hal_addr0;
+  ASSERT_TRUE(RawAddress::FromString(kTestAddress0, hal_addr0));
 
   // Set up two connections with the same address.
   fake_hal_gatt_iface_->NotifyServerConnectionCallback(
diff --git a/service/test/low_energy_client_unittest.cc b/service/test/low_energy_client_unittest.cc
index 99eb934..5870f2e 100644
--- a/service/test/low_energy_client_unittest.cc
+++ b/service/test/low_energy_client_unittest.cc
@@ -40,10 +40,10 @@
   MockGattHandler(){};
   ~MockGattHandler() override = default;
 
-  MOCK_METHOD1(RegisterClient, bt_status_t(bt_uuid_t*));
+  MOCK_METHOD1(RegisterClient, bt_status_t(const bt_uuid_t&));
   MOCK_METHOD1(UnregisterClient, bt_status_t(int));
-  MOCK_METHOD4(Connect, bt_status_t(int, const bt_bdaddr_t*, bool, int));
-  MOCK_METHOD3(Disconnect, bt_status_t(int, const bt_bdaddr_t*, int));
+  MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int));
+  MOCK_METHOD3(Disconnect, bt_status_t(int, const RawAddress&, int));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
@@ -256,7 +256,7 @@
 }
 
 TEST_F(LowEnergyClientPostRegisterTest, Connect) {
-  const bt_bdaddr_t kTestAddress = {{0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C}};
+  const RawAddress kTestAddress = {{0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C}};
   const char kTestAddressStr[] = "01:02:03:0A:0B:0C";
   const bool kTestDirect = false;
   const int connId = 12;
@@ -268,13 +268,13 @@
   // success, fix it when it becomes important.
   // These should succeed and result in a HAL call
   EXPECT_CALL(*mock_handler_,
-              Connect(le_client_->GetInstanceId(), Pointee(BitEq(kTestAddress)),
+              Connect(le_client_->GetInstanceId(), BitEq(kTestAddress),
                       kTestDirect, BT_TRANSPORT_LE))
       .Times(1)
-      .WillOnce(DoAll(Invoke([&](int client_id, const bt_bdaddr_t* bd_addr,
+      .WillOnce(DoAll(Invoke([&](int client_id, const RawAddress& bd_addr,
                                  bool is_direct, int transport) {
                         fake_hal_gatt_iface_->NotifyConnectCallback(
-                            connId, BT_STATUS_SUCCESS, client_id, *bd_addr);
+                            connId, BT_STATUS_SUCCESS, client_id, bd_addr);
                       }),
                       Return(BT_STATUS_SUCCESS)));
 
@@ -284,12 +284,12 @@
   // TODO(jpawlowski): same as above
   // These should succeed and result in a HAL call
   EXPECT_CALL(*mock_handler_, Disconnect(le_client_->GetInstanceId(),
-                                         Pointee(BitEq(kTestAddress)), connId))
+                                         BitEq(kTestAddress), connId))
       .Times(1)
       .WillOnce(DoAll(
-          Invoke([&](int client_id, const bt_bdaddr_t* bd_addr, int connId) {
+          Invoke([&](int client_id, const RawAddress& bd_addr, int connId) {
             fake_hal_gatt_iface_->NotifyDisconnectCallback(
-                connId, BT_STATUS_SUCCESS, client_id, *bd_addr);
+                connId, BT_STATUS_SUCCESS, client_id, bd_addr);
           }),
           Return(BT_STATUS_SUCCESS)));
 
diff --git a/service/test/low_energy_scanner_unittest.cc b/service/test/low_energy_scanner_unittest.cc
index dc20ecf..d723a50 100644
--- a/service/test/low_energy_scanner_unittest.cc
+++ b/service/test/low_energy_scanner_unittest.cc
@@ -67,7 +67,7 @@
 
   MOCK_METHOD2(BatchscanReadReports, void(int client_if, int scan_mode));
 
-  MOCK_METHOD7(StartSync, void(uint8_t, bt_bdaddr_t, uint16_t, uint16_t,
+  MOCK_METHOD7(StartSync, void(uint8_t, RawAddress, uint16_t, uint16_t,
                                StartSyncCb, SyncReportCb, SyncLostCb));
   MOCK_METHOD1(StopSync, void(uint16_t));
 
@@ -75,7 +75,7 @@
                            int company_id, int company_id_mask,
                            const bt_uuid_t* p_uuid,
                            const bt_uuid_t* p_uuid_mask,
-                           const bt_bdaddr_t* bd_addr, char addr_type,
+                           const RawAddress* bd_addr, char addr_type,
                            std::vector<uint8_t> data,
                            std::vector<uint8_t> p_mask,
                            FilterConfigCallback cb){};
@@ -307,7 +307,7 @@
        0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
        0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
        0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00});
-  const bt_bdaddr_t kTestAddress = {{0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C}};
+  const RawAddress kTestAddress = {{0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C}};
   const char kTestAddressStr[] = "01:02:03:0A:0B:0C";
   const int kTestRssi = 64;
 
diff --git a/service/test/util_unittest.cc b/service/test/util_unittest.cc
deleted file mode 100644
index 83e7fb7..0000000
--- a/service/test/util_unittest.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-//  Copyright (C) 2015 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 <gtest/gtest.h>
-
-#include "service/common/bluetooth/util/address_helper.h"
-
-namespace util {
-
-TEST(UtilTest, IsAddressValid) {
-  EXPECT_FALSE(IsAddressValid(""));
-  EXPECT_FALSE(IsAddressValid("000000000000"));
-  EXPECT_FALSE(IsAddressValid("00:00:00:00:0000"));
-  EXPECT_FALSE(IsAddressValid("00:00:00:00:00:0"));
-  EXPECT_FALSE(IsAddressValid("00:00:00:00:00:0;"));
-  EXPECT_TRUE(IsAddressValid("00:00:00:00:00:00"));
-  EXPECT_FALSE(IsAddressValid("aB:cD:eF:Gh:iJ:Kl"));
-}
-
-TEST(UtilTest, BdAddrFromString) {
-  bt_bdaddr_t addr;
-  memset(&addr, 0, sizeof(addr));
-
-  EXPECT_TRUE(BdAddrFromString("00:00:00:00:00:00", &addr));
-  const bt_bdaddr_t result0 = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
-  EXPECT_EQ(0, memcmp(&addr, &result0, sizeof(addr)));
-
-  EXPECT_TRUE(BdAddrFromString("ab:01:4C:d5:21:9f", &addr));
-  const bt_bdaddr_t result1 = {{0xab, 0x01, 0x4c, 0xd5, 0x21, 0x9f}};
-  EXPECT_EQ(0, memcmp(&addr, &result1, sizeof(addr)));
-}
-
-}  // namespace util
diff --git a/stack/Android.bp b/stack/Android.bp
index f5ec040..5cb5678 100644
--- a/stack/Android.bp
+++ b/stack/Android.bp
@@ -19,6 +19,9 @@
         "smp",
         "srvc",
     ],
+    header_libs: [
+        "libhardware_headers",
+    ],
     include_dirs: [
         "external/aac/libAACenc/include",
         "external/aac/libSYS/include",
@@ -267,6 +270,7 @@
         "libcutils",
     ],
     static_libs: [
+        "libbluetooth-types",
         "liblog",
         "libgmock",
     ],
@@ -284,6 +288,7 @@
         "test/ad_parser_unittest.cc",
     ],
     static_libs: [
+        "libbluetooth-types",
         "liblog",
         "libgmock",
     ],
@@ -314,6 +319,7 @@
         "libprotobuf-cpp-lite",
     ],
     static_libs: [
+        "libbluetooth-types",
         "libgmock",
         "libosi",
         "libbt-protos",
diff --git a/stack/BUILD.gn b/stack/BUILD.gn
index 0be4333..9e386ab 100644
--- a/stack/BUILD.gn
+++ b/stack/BUILD.gn
@@ -178,6 +178,7 @@
   ]
 
   deps = [
+    "//types",
     "//third_party/libchrome:base",
     "//third_party/libldac:libldacBT_enc",
     "//third_party/libldac:libldacBT_abr",
@@ -225,6 +226,7 @@
     "//device",
     "//embdrv/sbc",
     "//hci",
+    "//types",
     "//main:bluetooth.default",
     "//third_party/googletest:gmock_main",
     "//third_party/libchrome:base",
@@ -247,7 +249,7 @@
     "//stack/btm",
   ]
 
-libs = [
+  libs = [
     "-ldl",
     "-lpthread",
     "-lresolv",
@@ -257,6 +259,7 @@
   ]
 
   deps = [
+    "//types",
     "//third_party/googletest:gmock_main",
     "//third_party/libchrome:base",
   ]
diff --git a/stack/a2dp/a2dp_aac.cc b/stack/a2dp/a2dp_aac.cc
index 7027df7..730aee3 100644
--- a/stack/a2dp/a2dp_aac.cc
+++ b/stack/a2dp/a2dp_aac.cc
@@ -244,17 +244,17 @@
 
   /* verify that each parameter is in range */
 
-  LOG_DEBUG(LOG_TAG, "%s: Object Type peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.objectType, p_cap->objectType);
-  LOG_DEBUG(LOG_TAG, "%s: Sample Rate peer: %u, capability %u", __func__,
-            cfg_cie.sampleRate, p_cap->sampleRate);
-  LOG_DEBUG(LOG_TAG, "%s: Channel Mode peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.channelMode, p_cap->channelMode);
-  LOG_DEBUG(
+  LOG_VERBOSE(LOG_TAG, "%s: Object Type peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.objectType, p_cap->objectType);
+  LOG_VERBOSE(LOG_TAG, "%s: Sample Rate peer: %u, capability %u", __func__,
+              cfg_cie.sampleRate, p_cap->sampleRate);
+  LOG_VERBOSE(LOG_TAG, "%s: Channel Mode peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.channelMode, p_cap->channelMode);
+  LOG_VERBOSE(
       LOG_TAG, "%s: Variable Bit Rate Support peer: 0x%x, capability 0x%x",
       __func__, cfg_cie.variableBitRateSupport, p_cap->variableBitRateSupport);
-  LOG_DEBUG(LOG_TAG, "%s: Bit Rate peer: %u, capability %u", __func__,
-            cfg_cie.bitRate, p_cap->bitRate);
+  LOG_VERBOSE(LOG_TAG, "%s: Bit Rate peer: %u, capability %u", __func__,
+              cfg_cie.bitRate, p_cap->bitRate);
 
   /* Object Type */
   if ((cfg_cie.objectType & p_cap->objectType) == 0) return A2DP_BAD_OBJ_TYPE;
@@ -533,7 +533,7 @@
   tA2DP_STATUS a2dp_status;
   tA2DP_AAC_CIE aac_cie;
 
-  LOG_DEBUG(LOG_TAG, "%s", __func__);
+  LOG_VERBOSE(LOG_TAG, "%s", __func__);
 
   a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, true);
   if (a2dp_status != A2DP_SUCCESS) {
@@ -541,70 +541,70 @@
     return false;
   }
 
-  LOG_DEBUG(LOG_TAG, "\tobjectType: 0x%x", aac_cie.objectType);
+  LOG_VERBOSE(LOG_TAG, "\tobjectType: 0x%x", aac_cie.objectType);
   if (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG2_LC) {
-    LOG_DEBUG(LOG_TAG, "\tobjectType: (MPEG-2 AAC LC)");
+    LOG_VERBOSE(LOG_TAG, "\tobjectType: (MPEG-2 AAC LC)");
   }
   if (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_LC) {
-    LOG_DEBUG(LOG_TAG, "\tobjectType: (MPEG-4 AAC LC)");
+    LOG_VERBOSE(LOG_TAG, "\tobjectType: (MPEG-4 AAC LC)");
   }
   if (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_LTP) {
-    LOG_DEBUG(LOG_TAG, "\tobjectType: (MPEG-4 AAC LTP)");
+    LOG_VERBOSE(LOG_TAG, "\tobjectType: (MPEG-4 AAC LTP)");
   }
   if (aac_cie.objectType & A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE) {
-    LOG_DEBUG(LOG_TAG, "\tobjectType: (MPEG-4 AAC Scalable)");
+    LOG_VERBOSE(LOG_TAG, "\tobjectType: (MPEG-4 AAC Scalable)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tsamp_freq: 0x%x", aac_cie.sampleRate);
+  LOG_VERBOSE(LOG_TAG, "\tsamp_freq: 0x%x", aac_cie.sampleRate);
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_8000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (8000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (8000)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_11025) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (11025)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (11025)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_12000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (12000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (12000)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_16000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (16000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (16000)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_22050) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (22050)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (22050)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_24000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (24000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (24000)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_32000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (32000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (32000)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_44100) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (44100)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (44100)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_48000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (48000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (48000)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_64000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (64000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (64000)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_88200) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (88200)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (88200)");
   }
   if (aac_cie.sampleRate & A2DP_AAC_SAMPLING_FREQ_96000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (96000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (96000)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tch_mode: 0x%x", aac_cie.channelMode);
+  LOG_VERBOSE(LOG_TAG, "\tch_mode: 0x%x", aac_cie.channelMode);
   if (aac_cie.channelMode == A2DP_AAC_CHANNEL_MODE_MONO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Mono)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Mono)");
   }
   if (aac_cie.channelMode == A2DP_AAC_CHANNEL_MODE_STEREO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Stereo)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Stereo)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tvariableBitRateSupport: %s",
-            (aac_cie.variableBitRateSupport != 0) ? "true" : "false");
+  LOG_VERBOSE(LOG_TAG, "\tvariableBitRateSupport: %s",
+              (aac_cie.variableBitRateSupport != 0) ? "true" : "false");
 
-  LOG_DEBUG(LOG_TAG, "\tbitRate: %u", aac_cie.bitRate);
+  LOG_VERBOSE(LOG_TAG, "\tbitRate: %u", aac_cie.bitRate);
 
   return true;
 }
diff --git a/stack/a2dp/a2dp_api.cc b/stack/a2dp/a2dp_api.cc
index 11d3bf2..4be2bdd 100644
--- a/stack/a2dp/a2dp_api.cc
+++ b/stack/a2dp/a2dp_api.cc
@@ -39,6 +39,11 @@
  *  Global data
  ****************************************************************************/
 tA2DP_CB a2dp_cb;
+static uint16_t a2dp_attr_list[] = {
+    ATTR_ID_SERVICE_CLASS_ID_LIST, /* update A2DP_NUM_ATTR, if changed */
+    ATTR_ID_BT_PROFILE_DESC_LIST,  ATTR_ID_SUPPORTED_FEATURES,
+    ATTR_ID_SERVICE_NAME,          ATTR_ID_PROTOCOL_DESC_LIST,
+    ATTR_ID_PROVIDER_NAME};
 
 /******************************************************************************
  *
@@ -261,16 +266,11 @@
  *                  A2DP_FAIL if function execution failed.
  *
  *****************************************************************************/
-tA2DP_STATUS A2DP_FindService(uint16_t service_uuid, BD_ADDR bd_addr,
+tA2DP_STATUS A2DP_FindService(uint16_t service_uuid, const RawAddress& bd_addr,
                               tA2DP_SDP_DB_PARAMS* p_db,
                               tA2DP_FIND_CBACK* p_cback) {
   tSDP_UUID uuid_list;
   bool result = true;
-  uint16_t a2dp_attr_list[] = {
-      ATTR_ID_SERVICE_CLASS_ID_LIST, /* update A2DP_NUM_ATTR, if changed */
-      ATTR_ID_BT_PROFILE_DESC_LIST,  ATTR_ID_SUPPORTED_FEATURES,
-      ATTR_ID_SERVICE_NAME,          ATTR_ID_PROTOCOL_DESC_LIST,
-      ATTR_ID_PROVIDER_NAME};
 
   LOG_VERBOSE(LOG_TAG, "%s: uuid: 0x%x", __func__, service_uuid);
   if ((service_uuid != UUID_SERVCLASS_AUDIO_SOURCE &&
diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc
index ce3934a..cfdaad4 100644
--- a/stack/a2dp/a2dp_sbc.cc
+++ b/stack/a2dp/a2dp_sbc.cc
@@ -334,20 +334,20 @@
 
   /* verify that each parameter is in range */
 
-  LOG_DEBUG(LOG_TAG, "%s: FREQ peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.samp_freq, p_cap->samp_freq);
-  LOG_DEBUG(LOG_TAG, "%s: CH_MODE peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.ch_mode, p_cap->ch_mode);
-  LOG_DEBUG(LOG_TAG, "%s: BLOCK_LEN peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.block_len, p_cap->block_len);
-  LOG_DEBUG(LOG_TAG, "%s: SUB_BAND peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.num_subbands, p_cap->num_subbands);
-  LOG_DEBUG(LOG_TAG, "%s: ALLOC_METHOD peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.alloc_method, p_cap->alloc_method);
-  LOG_DEBUG(LOG_TAG, "%s: MIN_BitPool peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.min_bitpool, p_cap->min_bitpool);
-  LOG_DEBUG(LOG_TAG, "%s: MAX_BitPool peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.max_bitpool, p_cap->max_bitpool);
+  LOG_VERBOSE(LOG_TAG, "%s: FREQ peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.samp_freq, p_cap->samp_freq);
+  LOG_VERBOSE(LOG_TAG, "%s: CH_MODE peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.ch_mode, p_cap->ch_mode);
+  LOG_VERBOSE(LOG_TAG, "%s: BLOCK_LEN peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.block_len, p_cap->block_len);
+  LOG_VERBOSE(LOG_TAG, "%s: SUB_BAND peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.num_subbands, p_cap->num_subbands);
+  LOG_VERBOSE(LOG_TAG, "%s: ALLOC_METHOD peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.alloc_method, p_cap->alloc_method);
+  LOG_VERBOSE(LOG_TAG, "%s: MIN_BitPool peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.min_bitpool, p_cap->min_bitpool);
+  LOG_VERBOSE(LOG_TAG, "%s: MAX_BitPool peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.max_bitpool, p_cap->max_bitpool);
 
   /* sampling frequency */
   if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) return A2DP_NS_SAMP_FREQ;
@@ -871,7 +871,7 @@
   tA2DP_STATUS a2dp_status;
   tA2DP_SBC_CIE sbc_cie;
 
-  LOG_DEBUG(LOG_TAG, "%s", __func__);
+  LOG_VERBOSE(LOG_TAG, "%s", __func__);
 
   a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, true);
   if (a2dp_status != A2DP_SUCCESS) {
@@ -879,66 +879,66 @@
     return false;
   }
 
-  LOG_DEBUG(LOG_TAG, "\tsamp_freq: 0x%x", sbc_cie.samp_freq);
+  LOG_VERBOSE(LOG_TAG, "\tsamp_freq: 0x%x", sbc_cie.samp_freq);
   if (sbc_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_16) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (16000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (16000)");
   }
   if (sbc_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_32) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (32000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (32000)");
   }
   if (sbc_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_44) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (44100)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (44100)");
   }
   if (sbc_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_48) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (48000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (48000)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tch_mode: 0x%x", sbc_cie.ch_mode);
+  LOG_VERBOSE(LOG_TAG, "\tch_mode: 0x%x", sbc_cie.ch_mode);
   if (sbc_cie.ch_mode & A2DP_SBC_IE_CH_MD_MONO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Mono)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Mono)");
   }
   if (sbc_cie.ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Dual)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Dual)");
   }
   if (sbc_cie.ch_mode & A2DP_SBC_IE_CH_MD_STEREO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Stereo)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Stereo)");
   }
   if (sbc_cie.ch_mode & A2DP_SBC_IE_CH_MD_JOINT) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Joint)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Joint)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tblock_len: 0x%x", sbc_cie.block_len);
+  LOG_VERBOSE(LOG_TAG, "\tblock_len: 0x%x", sbc_cie.block_len);
   if (sbc_cie.block_len & A2DP_SBC_IE_BLOCKS_4) {
-    LOG_DEBUG(LOG_TAG, "\tblock_len: (4)");
+    LOG_VERBOSE(LOG_TAG, "\tblock_len: (4)");
   }
   if (sbc_cie.block_len & A2DP_SBC_IE_BLOCKS_8) {
-    LOG_DEBUG(LOG_TAG, "\tblock_len: (8)");
+    LOG_VERBOSE(LOG_TAG, "\tblock_len: (8)");
   }
   if (sbc_cie.block_len & A2DP_SBC_IE_BLOCKS_12) {
-    LOG_DEBUG(LOG_TAG, "\tblock_len: (12)");
+    LOG_VERBOSE(LOG_TAG, "\tblock_len: (12)");
   }
   if (sbc_cie.block_len & A2DP_SBC_IE_BLOCKS_16) {
-    LOG_DEBUG(LOG_TAG, "\tblock_len: (16)");
+    LOG_VERBOSE(LOG_TAG, "\tblock_len: (16)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tnum_subbands: 0x%x", sbc_cie.num_subbands);
+  LOG_VERBOSE(LOG_TAG, "\tnum_subbands: 0x%x", sbc_cie.num_subbands);
   if (sbc_cie.num_subbands & A2DP_SBC_IE_SUBBAND_4) {
-    LOG_DEBUG(LOG_TAG, "\tnum_subbands: (4)");
+    LOG_VERBOSE(LOG_TAG, "\tnum_subbands: (4)");
   }
   if (sbc_cie.num_subbands & A2DP_SBC_IE_SUBBAND_8) {
-    LOG_DEBUG(LOG_TAG, "\tnum_subbands: (8)");
+    LOG_VERBOSE(LOG_TAG, "\tnum_subbands: (8)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\talloc_method: 0x%x)", sbc_cie.alloc_method);
+  LOG_VERBOSE(LOG_TAG, "\talloc_method: 0x%x)", sbc_cie.alloc_method);
   if (sbc_cie.alloc_method & A2DP_SBC_IE_ALLOC_MD_S) {
-    LOG_DEBUG(LOG_TAG, "\talloc_method: (SNR)");
+    LOG_VERBOSE(LOG_TAG, "\talloc_method: (SNR)");
   }
   if (sbc_cie.alloc_method & A2DP_SBC_IE_ALLOC_MD_L) {
-    LOG_DEBUG(LOG_TAG, "\talloc_method: (Loundess)");
+    LOG_VERBOSE(LOG_TAG, "\talloc_method: (Loundess)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool,
-            sbc_cie.max_bitpool);
+  LOG_VERBOSE(LOG_TAG, "\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool,
+              sbc_cie.max_bitpool);
 
   return true;
 }
diff --git a/stack/a2dp/a2dp_vendor_aptx.cc b/stack/a2dp/a2dp_vendor_aptx.cc
index 9d4d0e1..92ff7c8 100644
--- a/stack/a2dp/a2dp_vendor_aptx.cc
+++ b/stack/a2dp/a2dp_vendor_aptx.cc
@@ -204,10 +204,10 @@
 
   /* verify that each parameter is in range */
 
-  LOG_DEBUG(LOG_TAG, "%s: FREQ peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.sampleRate, p_cap->sampleRate);
-  LOG_DEBUG(LOG_TAG, "%s: CH_MODE peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.channelMode, p_cap->channelMode);
+  LOG_VERBOSE(LOG_TAG, "%s: FREQ peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.sampleRate, p_cap->sampleRate);
+  LOG_VERBOSE(LOG_TAG, "%s: CH_MODE peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.channelMode, p_cap->channelMode);
 
   /* sampling frequency */
   if ((cfg_cie.sampleRate & p_cap->sampleRate) == 0) return A2DP_NS_SAMP_FREQ;
@@ -336,7 +336,7 @@
   tA2DP_STATUS a2dp_status;
   tA2DP_APTX_CIE aptx_cie;
 
-  LOG_DEBUG(LOG_TAG, "%s", __func__);
+  LOG_VERBOSE(LOG_TAG, "%s", __func__);
 
   a2dp_status = A2DP_ParseInfoAptx(&aptx_cie, p_codec_info, true);
   if (a2dp_status != A2DP_SUCCESS) {
@@ -344,20 +344,20 @@
     return false;
   }
 
-  LOG_DEBUG(LOG_TAG, "\tsamp_freq: 0x%x", aptx_cie.sampleRate);
+  LOG_VERBOSE(LOG_TAG, "\tsamp_freq: 0x%x", aptx_cie.sampleRate);
   if (aptx_cie.sampleRate & A2DP_APTX_SAMPLERATE_44100) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (44100)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (44100)");
   }
   if (aptx_cie.sampleRate & A2DP_APTX_SAMPLERATE_48000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (48000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (48000)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tch_mode: 0x%x", aptx_cie.channelMode);
+  LOG_VERBOSE(LOG_TAG, "\tch_mode: 0x%x", aptx_cie.channelMode);
   if (aptx_cie.channelMode & A2DP_APTX_CHANNELS_MONO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Mono)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Mono)");
   }
   if (aptx_cie.channelMode & A2DP_APTX_CHANNELS_STEREO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Stereo)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Stereo)");
   }
 
   return true;
diff --git a/stack/a2dp/a2dp_vendor_aptx_hd.cc b/stack/a2dp/a2dp_vendor_aptx_hd.cc
index 9002729..85f2365 100644
--- a/stack/a2dp/a2dp_vendor_aptx_hd.cc
+++ b/stack/a2dp/a2dp_vendor_aptx_hd.cc
@@ -222,10 +222,10 @@
 
   /* verify that each parameter is in range */
 
-  LOG_DEBUG(LOG_TAG, "%s: FREQ peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.sampleRate, p_cap->sampleRate);
-  LOG_DEBUG(LOG_TAG, "%s: CH_MODE peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.channelMode, p_cap->channelMode);
+  LOG_VERBOSE(LOG_TAG, "%s: FREQ peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.sampleRate, p_cap->sampleRate);
+  LOG_VERBOSE(LOG_TAG, "%s: CH_MODE peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.channelMode, p_cap->channelMode);
 
   /* sampling frequency */
   if ((cfg_cie.sampleRate & p_cap->sampleRate) == 0) return A2DP_NS_SAMP_FREQ;
@@ -352,7 +352,7 @@
   tA2DP_STATUS a2dp_status;
   tA2DP_APTX_HD_CIE aptx_hd_cie;
 
-  LOG_DEBUG(LOG_TAG, "%s", __func__);
+  LOG_VERBOSE(LOG_TAG, "%s", __func__);
 
   a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie, p_codec_info, true);
   if (a2dp_status != A2DP_SUCCESS) {
@@ -361,20 +361,20 @@
     return false;
   }
 
-  LOG_DEBUG(LOG_TAG, "\tsamp_freq: 0x%x", aptx_hd_cie.sampleRate);
+  LOG_VERBOSE(LOG_TAG, "\tsamp_freq: 0x%x", aptx_hd_cie.sampleRate);
   if (aptx_hd_cie.sampleRate & A2DP_APTX_HD_SAMPLERATE_44100) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (44100)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (44100)");
   }
   if (aptx_hd_cie.sampleRate & A2DP_APTX_HD_SAMPLERATE_48000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (48000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (48000)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tch_mode: 0x%x", aptx_hd_cie.channelMode);
+  LOG_VERBOSE(LOG_TAG, "\tch_mode: 0x%x", aptx_hd_cie.channelMode);
   if (aptx_hd_cie.channelMode & A2DP_APTX_HD_CHANNELS_MONO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Mono)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Mono)");
   }
   if (aptx_hd_cie.channelMode & A2DP_APTX_HD_CHANNELS_STEREO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Stereo)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Stereo)");
   }
 
   return true;
diff --git a/stack/a2dp/a2dp_vendor_ldac.cc b/stack/a2dp/a2dp_vendor_ldac.cc
index 08d4362..e38424f 100644
--- a/stack/a2dp/a2dp_vendor_ldac.cc
+++ b/stack/a2dp/a2dp_vendor_ldac.cc
@@ -230,10 +230,10 @@
 
   /* verify that each parameter is in range */
 
-  LOG_DEBUG(LOG_TAG, "%s: FREQ peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.sampleRate, p_cap->sampleRate);
-  LOG_DEBUG(LOG_TAG, "%s: CH_MODE peer: 0x%x, capability 0x%x", __func__,
-            cfg_cie.channelMode, p_cap->channelMode);
+  LOG_VERBOSE(LOG_TAG, "%s: FREQ peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.sampleRate, p_cap->sampleRate);
+  LOG_VERBOSE(LOG_TAG, "%s: CH_MODE peer: 0x%x, capability 0x%x", __func__,
+              cfg_cie.channelMode, p_cap->channelMode);
 
   /* sampling frequency */
   if ((cfg_cie.sampleRate & p_cap->sampleRate) == 0) return A2DP_NS_SAMP_FREQ;
@@ -402,7 +402,7 @@
   tA2DP_STATUS a2dp_status;
   tA2DP_LDAC_CIE ldac_cie;
 
-  LOG_DEBUG(LOG_TAG, "%s", __func__);
+  LOG_VERBOSE(LOG_TAG, "%s", __func__);
 
   a2dp_status = A2DP_ParseInfoLdac(&ldac_cie, p_codec_info, true);
   if (a2dp_status != A2DP_SUCCESS) {
@@ -410,35 +410,35 @@
     return false;
   }
 
-  LOG_DEBUG(LOG_TAG, "\tsamp_freq: 0x%x", ldac_cie.sampleRate);
+  LOG_VERBOSE(LOG_TAG, "\tsamp_freq: 0x%x", ldac_cie.sampleRate);
   if (ldac_cie.sampleRate & A2DP_LDAC_SAMPLING_FREQ_44100) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (44100)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (44100)");
   }
   if (ldac_cie.sampleRate & A2DP_LDAC_SAMPLING_FREQ_48000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (48000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (48000)");
   }
   if (ldac_cie.sampleRate & A2DP_LDAC_SAMPLING_FREQ_88200) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (88200)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (88200)");
   }
   if (ldac_cie.sampleRate & A2DP_LDAC_SAMPLING_FREQ_96000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (96000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (96000)");
   }
   if (ldac_cie.sampleRate & A2DP_LDAC_SAMPLING_FREQ_176400) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (176400)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (176400)");
   }
   if (ldac_cie.sampleRate & A2DP_LDAC_SAMPLING_FREQ_192000) {
-    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (192000)");
+    LOG_VERBOSE(LOG_TAG, "\tsamp_freq: (192000)");
   }
 
-  LOG_DEBUG(LOG_TAG, "\tch_mode: 0x%x", ldac_cie.channelMode);
+  LOG_VERBOSE(LOG_TAG, "\tch_mode: 0x%x", ldac_cie.channelMode);
   if (ldac_cie.channelMode & A2DP_LDAC_CHANNEL_MODE_MONO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Mono)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Mono)");
   }
   if (ldac_cie.channelMode & A2DP_LDAC_CHANNEL_MODE_DUAL) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Dual)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Dual)");
   }
   if (ldac_cie.channelMode & A2DP_LDAC_CHANNEL_MODE_STEREO) {
-    LOG_DEBUG(LOG_TAG, "\tch_mode: (Stereo)");
+    LOG_VERBOSE(LOG_TAG, "\tch_mode: (Stereo)");
   }
 
   return true;
diff --git a/stack/a2dp/a2dp_vendor_ldac_encoder.cc b/stack/a2dp/a2dp_vendor_ldac_encoder.cc
index 47f7764..4ca3cdf 100644
--- a/stack/a2dp/a2dp_vendor_ldac_encoder.cc
+++ b/stack/a2dp/a2dp_vendor_ldac_encoder.cc
@@ -19,7 +19,9 @@
 
 #include "a2dp_vendor_ldac_encoder.h"
 
+#ifndef OS_GENERIC
 #include <cutils/trace.h>
+#endif
 #include <dlfcn.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -547,7 +549,9 @@
                              a2dp_ldac_encoder_cb.TxQueueLength, flag_enable);
       if (prev_eqmid != a2dp_ldac_encoder_cb.last_ldac_abr_eqmid)
         a2dp_ldac_encoder_cb.ldac_abr_adjustments++;
+#ifndef OS_GENERIC
       ATRACE_INT("LDAC ABR level", a2dp_ldac_encoder_cb.last_ldac_abr_eqmid);
+#endif
     }
     // Transcode frame and enqueue
     a2dp_ldac_encode_frames(nb_frame);
diff --git a/stack/avct/avct_api.cc b/stack/avct/avct_api.cc
index 2a9a485..af789e3 100644
--- a/stack/avct/avct_api.cc
+++ b/stack/avct/avct_api.cc
@@ -129,7 +129,8 @@
  * Returns          AVCT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc, BD_ADDR peer_addr) {
+uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc,
+                         const RawAddress& peer_addr) {
   uint16_t result = AVCT_SUCCESS;
   tAVCT_CCB* p_ccb;
   tAVCT_LCB* p_lcb;
@@ -166,7 +167,9 @@
         /* bind lcb to ccb */
         p_ccb->p_lcb = p_lcb;
         AVCT_TRACE_DEBUG("ch_state: %d", p_lcb->ch_state);
-        avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT*)&p_ccb);
+        tAVCT_LCB_EVT avct_lcb_evt;
+        avct_lcb_evt.p_ccb = p_ccb;
+        avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
       }
     }
   }
@@ -203,8 +206,9 @@
   }
   /* send unbind event to lcb */
   else {
-    avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT,
-                   (tAVCT_LCB_EVT*)&p_ccb);
+    tAVCT_LCB_EVT avct_lcb_evt;
+    avct_lcb_evt.p_ccb = p_ccb;
+    avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
   }
   return result;
 }
@@ -265,9 +269,11 @@
     if (result == AVCT_SUCCESS) {
       /* bind bcb to ccb */
       p_ccb->p_bcb = p_bcb;
-      memcpy(p_bcb->peer_addr, p_ccb->p_lcb->peer_addr, BD_ADDR_LEN);
+      p_bcb->peer_addr = p_ccb->p_lcb->peer_addr;
       AVCT_TRACE_DEBUG("ch_state: %d", p_bcb->ch_state);
-      avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT*)&p_ccb);
+      tAVCT_LCB_EVT avct_lcb_evt;
+      avct_lcb_evt.p_ccb = p_ccb;
+      avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
     }
   }
 
@@ -300,8 +306,9 @@
   } else if (p_ccb->p_bcb != NULL)
   /* send unbind event to bcb */
   {
-    avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT,
-                   (tAVCT_LCB_EVT*)&p_ccb);
+    tAVCT_LCB_EVT avct_lcb_evt;
+    avct_lcb_evt.p_ccb = p_ccb;
+    avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
   }
 
   return result;
@@ -416,14 +423,16 @@
         osi_free(p_msg);
       } else {
         p_ccb->p_bcb = avct_bcb_by_lcb(p_ccb->p_lcb);
-        avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT,
-                       (tAVCT_LCB_EVT*)&ul_msg);
+        tAVCT_LCB_EVT avct_lcb_evt;
+        avct_lcb_evt.ul_msg = ul_msg;
+        avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
       }
     }
     /* send msg event to lcb */
     else {
-      avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT,
-                     (tAVCT_LCB_EVT*)&ul_msg);
+      tAVCT_LCB_EVT avct_lcb_evt;
+      avct_lcb_evt.ul_msg = ul_msg;
+      avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
     }
   }
   return result;
diff --git a/stack/avct/avct_bcb_act.cc b/stack/avct/avct_bcb_act.cc
index de20e40..011a52d 100644
--- a/stack/avct/avct_bcb_act.cc
+++ b/stack/avct/avct_bcb_act.cc
@@ -119,7 +119,9 @@
       L2CA_ErtmConnectReq(AVCT_BR_PSM, p_lcb->peer_addr, &ertm_info);
   if (p_bcb->ch_lcid == 0) {
     /* if connect req failed, send ourselves close event */
-    avct_bcb_event(p_bcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&result);
+    tAVCT_LCB_EVT avct_lcb_evt;
+    avct_lcb_evt.result = result;
+    avct_bcb_event(p_bcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
   }
 }
 
@@ -167,20 +169,19 @@
         bind = true;
         p_ccb_bind = p_ccb;
         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_CFM_EVT,
-                               0, p_ccb->p_lcb->peer_addr);
+                               0, &p_ccb->p_lcb->peer_addr);
       }
       /* if unbound acceptor and lcb allocated and bd_addr are the same for bcb
          and lcb */
       else if ((p_ccb->p_bcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
                (p_ccb->p_lcb != NULL) &&
-               (!memcmp(p_bcb->peer_addr, p_ccb->p_lcb->peer_addr,
-                        BD_ADDR_LEN))) {
+               p_bcb->peer_addr == p_ccb->p_lcb->peer_addr) {
         /* bind bcb to ccb and send connect ind event */
         bind = true;
         p_ccb_bind = p_ccb;
         p_ccb->p_bcb = p_bcb;
         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_IND_EVT,
-                               0, p_ccb->p_lcb->peer_addr);
+                               0, &p_ccb->p_lcb->peer_addr);
       }
     }
   }
@@ -203,7 +204,9 @@
   p_bcb->p_tx_msg = NULL;
 
   /* send msg event to bcb */
-  avct_bcb_event(p_bcb, AVCT_LCB_UL_MSG_EVT, (tAVCT_LCB_EVT*)&ul_msg);
+  tAVCT_LCB_EVT avct_lcb_evt;
+  avct_lcb_evt.ul_msg = ul_msg;
+  avct_bcb_event(p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
 }
 
 /*******************************************************************************
@@ -247,7 +250,7 @@
       if (p_ccb->cc.role == AVCT_INT) {
         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
                                   AVCT_BROWSE_DISCONN_CFM_EVT, 0,
-                                  p_lcb->peer_addr);
+                                  &p_lcb->peer_addr);
       } else {
         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
                                   AVCT_BROWSE_DISCONN_IND_EVT, 0, NULL);
@@ -290,7 +293,7 @@
       p_ccb->p_bcb = NULL;
       if (p_ccb->p_lcb == NULL) avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
       (*p_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result,
-                 p_bcb->peer_addr);
+                 &p_bcb->peer_addr);
     }
   }
 }
@@ -310,7 +313,7 @@
   p_data->p_ccb->p_bcb = p_bcb;
   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
                                     AVCT_BROWSE_CONN_CFM_EVT, 0,
-                                    p_lcb->peer_addr);
+                                    &p_lcb->peer_addr);
 }
 
 /*******************************************************************************
@@ -390,7 +393,7 @@
   for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
     if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
       (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0,
-                                p_lcb->peer_addr);
+                                &p_lcb->peer_addr);
     }
   }
 }
diff --git a/stack/avct/avct_ccb.cc b/stack/avct/avct_ccb.cc
index 2cdd85b..d15fff2 100644
--- a/stack/avct/avct_ccb.cc
+++ b/stack/avct/avct_ccb.cc
@@ -72,7 +72,7 @@
  *
  ******************************************************************************/
 void avct_ccb_dealloc(tAVCT_CCB* p_ccb, uint8_t event, uint16_t result,
-                      BD_ADDR bd_addr) {
+                      const RawAddress* bd_addr) {
   tAVCT_CTRL_CBACK* p_cback = p_ccb->cc.p_ctrl_cback;
 
   AVCT_TRACE_DEBUG("avct_ccb_dealloc %d", avct_ccb_to_idx(p_ccb));
diff --git a/stack/avct/avct_int.h b/stack/avct/avct_int.h
index 9674cbc..53b8b97 100644
--- a/stack/avct/avct_int.h
+++ b/stack/avct/avct_int.h
@@ -80,7 +80,7 @@
   uint8_t ch_flags;       /* L2CAP configuration flags */
   BT_HDR* p_rx_msg;       /* Message being reassembled */
   uint16_t conflict_lcid; /* L2CAP channel LCID */
-  BD_ADDR peer_addr;      /* BD address of peer */
+  RawAddress peer_addr;   /* BD address of peer */
   fixed_queue_t* tx_q;    /* Transmit data buffer queue       */
   bool cong;              /* true, if congested */
 } tAVCT_LCB;
@@ -97,7 +97,7 @@
   BT_HDR* p_tx_msg;  /* Message to be sent - in case the browsing channel is not
                         open when MsgReg is called */
   uint8_t ch_close;  /* CCB index+1, if CCB initiated channel close */
-  BD_ADDR peer_addr; /* BD address of peer */
+  RawAddress peer_addr; /* BD address of peer */
 } tAVCT_BCB;
 
 #define AVCT_ALOC_LCB 0x01
@@ -154,8 +154,8 @@
 extern uint8_t avct_bcb_get_last_ccb_index(tAVCT_BCB* p_bcb,
                                            tAVCT_CCB* p_ccb_last);
 extern tAVCT_BCB* avct_bcb_by_lcid(uint16_t lcid);
-extern tAVCT_LCB* avct_lcb_by_bd(BD_ADDR bd_addr);
-extern tAVCT_LCB* avct_lcb_alloc(BD_ADDR bd_addr);
+extern tAVCT_LCB* avct_lcb_by_bd(const RawAddress& bd_addr);
+extern tAVCT_LCB* avct_lcb_alloc(const RawAddress& bd_addr);
 extern void avct_lcb_dealloc(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data);
 extern tAVCT_LCB* avct_lcb_by_lcid(uint16_t lcid);
 extern tAVCT_CCB* avct_lcb_has_pid(tAVCT_LCB* p_lcb, uint16_t pid);
@@ -205,7 +205,7 @@
 /* CCB function declarations */
 extern tAVCT_CCB* avct_ccb_alloc(tAVCT_CC* p_cc);
 extern void avct_ccb_dealloc(tAVCT_CCB* p_ccb, uint8_t event, uint16_t result,
-                             BD_ADDR bd_addr);
+                             const RawAddress* bd_addr);
 extern uint8_t avct_ccb_to_idx(tAVCT_CCB* p_ccb);
 extern tAVCT_CCB* avct_ccb_by_idx(uint8_t idx);
 
diff --git a/stack/avct/avct_l2c.cc b/stack/avct/avct_l2c.cc
index 2ed077b..f81ed56 100644
--- a/stack/avct/avct_l2c.cc
+++ b/stack/avct/avct_l2c.cc
@@ -37,8 +37,8 @@
 #define AVCT_L2C_CFG_CFM_DONE (1 << 1)
 
 /* callback function declarations */
-void avct_l2c_connect_ind_cback(BD_ADDR bd_addr, uint16_t lcid, uint16_t psm,
-                                uint8_t id);
+void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
+                                uint16_t psm, uint8_t id);
 void avct_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result);
 void avct_l2c_config_cfm_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
 void avct_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
@@ -99,7 +99,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void avct_l2c_connect_ind_cback(BD_ADDR bd_addr, uint16_t lcid,
+void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
                                 UNUSED_ATTR uint16_t psm, uint8_t id) {
   tAVCT_LCB* p_lcb;
   uint16_t result = L2CAP_CONN_OK;
@@ -194,10 +194,13 @@
       else {
         AVCT_TRACE_DEBUG("avct_l2c_connect_cfm_cback conflict_lcid:0x%x",
                          p_lcb->conflict_lcid);
-        if (p_lcb->conflict_lcid == lcid)
+        if (p_lcb->conflict_lcid == lcid) {
           p_lcb->conflict_lcid = 0;
-        else
-          avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&result);
+        } else {
+          tAVCT_LCB_EVT avct_lcb_evt;
+          avct_lcb_evt.result = result;
+          avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
+        }
       }
     } else if (p_lcb->conflict_lcid == lcid) {
       /* we must be in AVCT_CH_CFG state for the ch_lcid channel */
@@ -331,7 +334,9 @@
       L2CA_DisconnectRsp(lcid);
     }
 
-    avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&result);
+    tAVCT_LCB_EVT avct_lcb_evt;
+    avct_lcb_evt.result = result;
+    avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
     AVCT_TRACE_DEBUG("ch_state di: %d ", p_lcb->ch_state);
   }
 }
@@ -360,7 +365,9 @@
     res = (p_lcb->ch_result != 0) ? p_lcb->ch_result : result;
     p_lcb->ch_result = 0;
 
-    avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&res);
+    tAVCT_LCB_EVT avct_lcb_evt;
+    avct_lcb_evt.result = res;
+    avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
     AVCT_TRACE_DEBUG("ch_state dc: %d ", p_lcb->ch_state);
   }
 }
@@ -382,7 +389,9 @@
   /* look up lcb for this channel */
   p_lcb = avct_lcb_by_lcid(lcid);
   if (p_lcb != NULL) {
-    avct_lcb_event(p_lcb, AVCT_LCB_LL_CONG_EVT, (tAVCT_LCB_EVT*)&is_congested);
+    tAVCT_LCB_EVT avct_lcb_evt;
+    avct_lcb_evt.cong = is_congested;
+    avct_lcb_event(p_lcb, AVCT_LCB_LL_CONG_EVT, &avct_lcb_evt);
   }
 }
 
diff --git a/stack/avct/avct_l2c_br.cc b/stack/avct/avct_l2c_br.cc
index 4538650..3b364cd 100644
--- a/stack/avct/avct_l2c_br.cc
+++ b/stack/avct/avct_l2c_br.cc
@@ -70,8 +70,8 @@
 #define AVCT_BR_FCR_OPT_MONITOR_TOUT 12000
 
 /* callback function declarations */
-void avct_l2c_br_connect_ind_cback(BD_ADDR bd_addr, uint16_t lcid, uint16_t psm,
-                                   uint8_t id);
+void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
+                                   uint16_t psm, uint8_t id);
 void avct_l2c_br_connect_cfm_cback(uint16_t lcid, uint16_t result);
 void avct_l2c_br_config_cfm_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
 void avct_l2c_br_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
@@ -116,7 +116,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void avct_l2c_br_connect_ind_cback(BD_ADDR bd_addr, uint16_t lcid,
+void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
                                    UNUSED_ATTR uint16_t psm, uint8_t id) {
   tAVCT_LCB* p_lcb;
   uint16_t result = L2CAP_CONN_NO_RESOURCES;
@@ -131,7 +131,7 @@
   if (p_lcb != NULL) {
     /* control channel exists */
     p_bcb = avct_bcb_by_lcb(p_lcb);
-    memcpy(p_bcb->peer_addr, bd_addr, BD_ADDR_LEN);
+    p_bcb->peer_addr = bd_addr;
 
     if (p_bcb->allocated == 0) {
       /* browsing channel does not exist yet and the browsing channel is
@@ -192,7 +192,9 @@
 
   if (result != L2CAP_CONN_OK) {
     /* failure */
-    avct_bcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&result);
+    tAVCT_LCB_EVT avct_lcb_evt;
+    avct_lcb_evt.result = result;
+    avct_bcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
     return;
   }
 
@@ -342,7 +344,9 @@
     L2CA_DisconnectRsp(lcid);
   }
 
-  avct_bcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&result);
+  tAVCT_LCB_EVT avct_lcb_evt;
+  avct_lcb_evt.result = result;
+  avct_bcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
 }
 
 /*******************************************************************************
@@ -367,7 +371,9 @@
   res = (p_lcb->ch_result != 0) ? p_lcb->ch_result : result;
   p_lcb->ch_result = 0;
 
-  avct_bcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&res);
+  tAVCT_LCB_EVT avct_lcb_evt;
+  avct_lcb_evt.result = res;
+  avct_bcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
 }
 
 /*******************************************************************************
@@ -387,7 +393,9 @@
   p_lcb = avct_bcb_by_lcid(lcid);
   if (p_lcb == NULL) return;
 
-  avct_bcb_event(p_lcb, AVCT_LCB_LL_CONG_EVT, (tAVCT_LCB_EVT*)&is_congested);
+  tAVCT_LCB_EVT avct_lcb_evt;
+  avct_lcb_evt.cong = is_congested;
+  avct_bcb_event(p_lcb, AVCT_LCB_LL_CONG_EVT, &avct_lcb_evt);
 }
 
 /*******************************************************************************
diff --git a/stack/avct/avct_lcb.cc b/stack/avct/avct_lcb.cc
index f13dc73..96156a2 100644
--- a/stack/avct/avct_lcb.cc
+++ b/stack/avct/avct_lcb.cc
@@ -23,6 +23,7 @@
  *
  ******************************************************************************/
 
+#include <base/logging.h>
 #include <string.h>
 #include "avct_api.h"
 #include "avct_int.h"
@@ -230,13 +231,13 @@
  * Returns          pointer to the lcb, or NULL if none found.
  *
  ******************************************************************************/
-tAVCT_LCB* avct_lcb_by_bd(BD_ADDR bd_addr) {
+tAVCT_LCB* avct_lcb_by_bd(const RawAddress& bd_addr) {
   tAVCT_LCB* p_lcb = &avct_cb.lcb[0];
   int i;
 
   for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++) {
     /* if allocated lcb has matching lcb */
-    if (p_lcb->allocated && (!memcmp(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN))) {
+    if (p_lcb->allocated && p_lcb->peer_addr == bd_addr) {
       break;
     }
   }
@@ -245,9 +246,7 @@
     /* if no lcb found */
     p_lcb = NULL;
 
-    AVCT_TRACE_DEBUG("No lcb for addr %02x-%02x-%02x-%02x-%02x-%02x",
-                     bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-                     bd_addr[5]);
+    VLOG(1) << "No lcb for addr " << bd_addr;
   }
   return p_lcb;
 }
@@ -262,14 +261,14 @@
  * Returns          pointer to the lcb, or NULL if none could be allocated.
  *
  ******************************************************************************/
-tAVCT_LCB* avct_lcb_alloc(BD_ADDR bd_addr) {
+tAVCT_LCB* avct_lcb_alloc(const RawAddress& bd_addr) {
   tAVCT_LCB* p_lcb = &avct_cb.lcb[0];
   int i;
 
   for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++) {
     if (!p_lcb->allocated) {
       p_lcb->allocated = (uint8_t)(i + 1);
-      memcpy(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN);
+      p_lcb->peer_addr = bd_addr;
       AVCT_TRACE_DEBUG("avct_lcb_alloc %d", p_lcb->allocated);
       p_lcb->tx_q = fixed_queue_new(SIZE_MAX);
       break;
diff --git a/stack/avct/avct_lcb_act.cc b/stack/avct/avct_lcb_act.cc
index 9731780..e2ce9db 100644
--- a/stack/avct/avct_lcb_act.cc
+++ b/stack/avct/avct_lcb_act.cc
@@ -173,7 +173,9 @@
   p_lcb->ch_lcid = L2CA_ConnectReq(AVCT_PSM, p_lcb->peer_addr);
   if (p_lcb->ch_lcid == 0) {
     /* if connect req failed, send ourselves close event */
-    avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT*)&result);
+    tAVCT_LCB_EVT avct_lcb_evt;
+    avct_lcb_evt.result = result;
+    avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
   }
 }
 
@@ -217,7 +219,7 @@
         bind = true;
         L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH);
         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_CFM_EVT, 0,
-                               p_lcb->peer_addr);
+                               &p_lcb->peer_addr);
       }
       /* if unbound acceptor and lcb doesn't already have a ccb for this PID */
       else if ((p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
@@ -227,7 +229,7 @@
         p_ccb->p_lcb = p_lcb;
         L2CA_SetTxPriority(p_lcb->ch_lcid, L2CAP_CHNL_PRIORITY_HIGH);
         p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_IND_EVT, 0,
-                               p_lcb->peer_addr);
+                               &p_lcb->peer_addr);
       }
     }
   }
@@ -256,7 +258,7 @@
   for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
     if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
       avct_ccb_dealloc(p_ccb, AVCT_CONNECT_CFM_EVT, p_data->result,
-                       p_lcb->peer_addr);
+                       &p_lcb->peer_addr);
     }
   }
 }
@@ -279,11 +281,12 @@
   for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
     if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
       if (p_ccb->cc.role == AVCT_INT) {
-        avct_ccb_dealloc(p_ccb, AVCT_DISCONNECT_IND_EVT, 0, p_lcb->peer_addr);
+        avct_ccb_dealloc(p_ccb, AVCT_DISCONNECT_IND_EVT, 0, &p_lcb->peer_addr);
       } else {
         p_ccb->p_lcb = NULL;
         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb),
-                                  AVCT_DISCONNECT_IND_EVT, 0, p_lcb->peer_addr);
+                                  AVCT_DISCONNECT_IND_EVT, 0,
+                                  &p_lcb->peer_addr);
       }
     }
   }
@@ -316,11 +319,11 @@
       }
 
       if (p_ccb->cc.role == AVCT_INT) {
-        avct_ccb_dealloc(p_ccb, event, p_data->result, p_lcb->peer_addr);
+        avct_ccb_dealloc(p_ccb, event, p_data->result, &p_lcb->peer_addr);
       } else {
         p_ccb->p_lcb = NULL;
         (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result,
-                                  p_lcb->peer_addr);
+                                  &p_lcb->peer_addr);
       }
     }
   }
@@ -339,7 +342,7 @@
 void avct_lcb_bind_conn(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
   p_data->p_ccb->p_lcb = p_lcb;
   (*p_data->p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_data->p_ccb),
-                                    AVCT_CONNECT_CFM_EVT, 0, p_lcb->peer_addr);
+                                    AVCT_CONNECT_CFM_EVT, 0, &p_lcb->peer_addr);
 }
 
 /*******************************************************************************
@@ -429,7 +432,7 @@
   for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
     if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
       (*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), event, 0,
-                                p_lcb->peer_addr);
+                                &p_lcb->peer_addr);
     }
   }
 }
diff --git a/stack/avdt/avdt_ad.cc b/stack/avdt/avdt_ad.cc
index 3012def..6143985 100644
--- a/stack/avdt/avdt_ad.cc
+++ b/stack/avdt/avdt_ad.cc
@@ -305,7 +305,9 @@
     if (p_scb != NULL) {
       close.tcid = p_tbl->tcid;
       close.type = avdt_ad_tcid_to_type(p_tbl->tcid);
-      avdt_scb_event(p_scb, AVDT_SCB_TC_CLOSE_EVT, (tAVDT_SCB_EVT*)&close);
+      tAVDT_SCB_EVT avdt_scb_evt;
+      avdt_scb_evt.close = close;
+      avdt_scb_event(p_scb, AVDT_SCB_TC_CLOSE_EVT, &avdt_scb_evt);
     }
   }
 }
@@ -343,7 +345,9 @@
     if (p_tbl->cfg_flags & AVDT_L2C_CFG_CONN_ACP) {
       evt.err_param = AVDT_ACP;
     }
-    avdt_ccb_event(p_ccb, AVDT_CCB_LL_OPEN_EVT, (tAVDT_CCB_EVT*)&evt);
+    tAVDT_CCB_EVT avdt_ccb_evt;
+    avdt_ccb_evt.msg.hdr = evt;
+    avdt_ccb_event(p_ccb, AVDT_CCB_LL_OPEN_EVT, &avdt_ccb_evt);
   }
   /* if media or other channel, notify scb that channel open */
   else {
@@ -356,7 +360,9 @@
       open.peer_mtu = p_tbl->peer_mtu;
       open.lcid = avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].lcid;
       open.hdr.err_code = avdt_ad_tcid_to_type(p_tbl->tcid);
-      avdt_scb_event(p_scb, AVDT_SCB_TC_OPEN_EVT, (tAVDT_SCB_EVT*)&open);
+      tAVDT_SCB_EVT avdt_scb_evt;
+      avdt_scb_evt.open = open;
+      avdt_scb_event(p_scb, AVDT_SCB_TC_OPEN_EVT, &avdt_scb_evt);
     }
   }
 }
@@ -382,7 +388,9 @@
   /* if signaling channel, notify ccb of congestion */
   if (p_tbl->tcid == 0) {
     p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
-    avdt_ccb_event(p_ccb, AVDT_CCB_LL_CONG_EVT, (tAVDT_CCB_EVT*)&is_congested);
+    tAVDT_CCB_EVT avdt_ccb_evt;
+    avdt_ccb_evt.llcong = is_congested;
+    avdt_ccb_event(p_ccb, AVDT_CCB_LL_CONG_EVT, &avdt_ccb_evt);
   }
   /* if media or other channel, notify scb that channel open */
   else {
@@ -390,8 +398,9 @@
     p_scb =
         avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
     if (p_scb != NULL) {
-      avdt_scb_event(p_scb, AVDT_SCB_TC_CONG_EVT,
-                     (tAVDT_SCB_EVT*)&is_congested);
+      tAVDT_SCB_EVT avdt_scb_evt;
+      avdt_scb_evt.llcong = is_congested;
+      avdt_scb_event(p_scb, AVDT_SCB_TC_CONG_EVT, &avdt_scb_evt);
     }
   }
 }
diff --git a/stack/avdt/avdt_api.cc b/stack/avdt/avdt_api.cc
index 5369f6e..a507841 100644
--- a/stack/avdt/avdt_api.cc
+++ b/stack/avdt/avdt_api.cc
@@ -42,7 +42,9 @@
   uint8_t avdt_event = AVDT_CCB_IDLE_TOUT_EVT;
   uint8_t err_code = AVDT_ERR_TIMEOUT;
 
-  avdt_ccb_event(p_ccb, avdt_event, (tAVDT_CCB_EVT*)&err_code);
+  tAVDT_CCB_EVT avdt_ccb_evt;
+  avdt_ccb_evt.err_code = err_code;
+  avdt_ccb_event(p_ccb, avdt_event, &avdt_ccb_evt);
 }
 
 void avdt_ccb_ret_ccb_timer_timeout(void* data) {
@@ -50,7 +52,9 @@
   uint8_t avdt_event = AVDT_CCB_RET_TOUT_EVT;
   uint8_t err_code = AVDT_ERR_TIMEOUT;
 
-  avdt_ccb_event(p_ccb, avdt_event, (tAVDT_CCB_EVT*)&err_code);
+  tAVDT_CCB_EVT avdt_ccb_evt;
+  avdt_ccb_evt.err_code = err_code;
+  avdt_ccb_event(p_ccb, avdt_event, &avdt_ccb_evt);
 }
 
 void avdt_ccb_rsp_ccb_timer_timeout(void* data) {
@@ -58,7 +62,9 @@
   uint8_t avdt_event = AVDT_CCB_RSP_TOUT_EVT;
   uint8_t err_code = AVDT_ERR_TIMEOUT;
 
-  avdt_ccb_event(p_ccb, avdt_event, (tAVDT_CCB_EVT*)&err_code);
+  tAVDT_CCB_EVT avdt_ccb_evt;
+  avdt_ccb_evt.err_code = err_code;
+  avdt_ccb_event(p_ccb, avdt_event, &avdt_ccb_evt);
 }
 
 void avdt_scb_transport_channel_timer_timeout(void* data) {
@@ -246,7 +252,7 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-uint16_t AVDT_DiscoverReq(BD_ADDR bd_addr, tAVDT_SEP_INFO* p_sep_info,
+uint16_t AVDT_DiscoverReq(const RawAddress& bd_addr, tAVDT_SEP_INFO* p_sep_info,
                           uint8_t max_seps, tAVDT_CTRL_CBACK* p_cback) {
   tAVDT_CCB* p_ccb;
   uint16_t result = AVDT_SUCCESS;
@@ -293,7 +299,8 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-static uint16_t avdt_get_cap_req(BD_ADDR bd_addr, tAVDT_CCB_API_GETCAP* p_evt) {
+static uint16_t avdt_get_cap_req(const RawAddress& bd_addr,
+                                 tAVDT_CCB_API_GETCAP* p_evt) {
   tAVDT_CCB* p_ccb = NULL;
   uint16_t result = AVDT_SUCCESS;
 
@@ -357,8 +364,8 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-uint16_t AVDT_GetCapReq(BD_ADDR bd_addr, uint8_t seid, tAVDT_CFG* p_cfg,
-                        tAVDT_CTRL_CBACK* p_cback) {
+uint16_t AVDT_GetCapReq(const RawAddress& bd_addr, uint8_t seid,
+                        tAVDT_CFG* p_cfg, tAVDT_CTRL_CBACK* p_cback) {
   tAVDT_CCB_API_GETCAP getcap;
   uint16_t result = AVDT_SUCCESS;
 
@@ -399,8 +406,8 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-uint16_t AVDT_GetAllCapReq(BD_ADDR bd_addr, uint8_t seid, tAVDT_CFG* p_cfg,
-                           tAVDT_CTRL_CBACK* p_cback) {
+uint16_t AVDT_GetAllCapReq(const RawAddress& bd_addr, uint8_t seid,
+                           tAVDT_CFG* p_cfg, tAVDT_CTRL_CBACK* p_cback) {
   tAVDT_CCB_API_GETCAP getcap;
   uint16_t result = AVDT_SUCCESS;
 
@@ -467,7 +474,7 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-uint16_t AVDT_OpenReq(uint8_t handle, BD_ADDR bd_addr, uint8_t seid,
+uint16_t AVDT_OpenReq(uint8_t handle, const RawAddress& bd_addr, uint8_t seid,
                       tAVDT_CFG* p_cfg) {
   tAVDT_CCB* p_ccb = NULL;
   tAVDT_SCB* p_scb = NULL;
@@ -983,7 +990,7 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-uint16_t AVDT_ConnectReq(BD_ADDR bd_addr, uint8_t sec_mask,
+uint16_t AVDT_ConnectReq(const RawAddress& bd_addr, uint8_t sec_mask,
                          tAVDT_CTRL_CBACK* p_cback) {
   tAVDT_CCB* p_ccb = NULL;
   uint16_t result = AVDT_SUCCESS;
@@ -1030,12 +1037,13 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-uint16_t AVDT_DisconnectReq(BD_ADDR bd_addr, tAVDT_CTRL_CBACK* p_cback) {
+uint16_t AVDT_DisconnectReq(const RawAddress& bd_addr,
+                            tAVDT_CTRL_CBACK* p_cback) {
   tAVDT_CCB* p_ccb = NULL;
   uint16_t result = AVDT_SUCCESS;
   tAVDT_CCB_EVT evt;
 
-  AVDT_TRACE_DEBUG("%s", __func__);
+  AVDT_TRACE_WARNING("%s: address=%s", __func__, bd_addr.ToString().c_str());
 
   /* find channel control block for this bd addr; if none, error */
   p_ccb = avdt_ccb_by_bd(bd_addr);
@@ -1049,7 +1057,8 @@
     avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCONNECT_REQ_EVT, &evt);
   }
 
-  AVDT_TRACE_DEBUG("%s: result=%d", __func__, result);
+  AVDT_TRACE_DEBUG("%s: address=%s result=%d", __func__,
+                   bd_addr.ToString().c_str(), result);
 
   return result;
 }
@@ -1091,7 +1100,7 @@
  * Returns          CID if successful, otherwise 0.
  *
  ******************************************************************************/
-uint16_t AVDT_GetSignalChannel(uint8_t handle, BD_ADDR bd_addr) {
+uint16_t AVDT_GetSignalChannel(uint8_t handle, const RawAddress& bd_addr) {
   tAVDT_SCB* p_scb;
   tAVDT_CCB* p_ccb;
   uint8_t tcid = 0; /* tcid is always 0 for signal channel */
diff --git a/stack/avdt/avdt_ccb.cc b/stack/avdt/avdt_ccb.cc
index a9ca128..87e2fd5 100644
--- a/stack/avdt/avdt_ccb.cc
+++ b/stack/avdt/avdt_ccb.cc
@@ -405,13 +405,13 @@
  * Returns          pointer to the ccb, or NULL if none found.
  *
  ******************************************************************************/
-tAVDT_CCB* avdt_ccb_by_bd(BD_ADDR bd_addr) {
+tAVDT_CCB* avdt_ccb_by_bd(const RawAddress& bd_addr) {
   tAVDT_CCB* p_ccb = &avdt_cb.ccb[0];
   int i;
 
   for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) {
     /* if allocated ccb has matching ccb */
-    if (p_ccb->allocated && (!memcmp(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN))) {
+    if (p_ccb->allocated && p_ccb->peer_addr == bd_addr) {
       break;
     }
   }
@@ -420,9 +420,7 @@
     /* if no ccb found */
     p_ccb = NULL;
 
-    AVDT_TRACE_DEBUG("No ccb for addr %02x-%02x-%02x-%02x-%02x-%02x",
-                     bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-                     bd_addr[5]);
+    VLOG(1) << "No ccb for addr " << bd_addr;
   }
   return p_ccb;
 }
@@ -437,14 +435,14 @@
  * Returns          pointer to the ccb, or NULL if none could be allocated.
  *
  ******************************************************************************/
-tAVDT_CCB* avdt_ccb_alloc(BD_ADDR bd_addr) {
+tAVDT_CCB* avdt_ccb_alloc(const RawAddress& bd_addr) {
   tAVDT_CCB* p_ccb = &avdt_cb.ccb[0];
   int i;
 
   for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) {
     if (!p_ccb->allocated) {
       p_ccb->allocated = true;
-      memcpy(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN);
+      p_ccb->peer_addr = bd_addr;
       p_ccb->cmd_q = fixed_queue_new(SIZE_MAX);
       p_ccb->rsp_q = fixed_queue_new(SIZE_MAX);
       p_ccb->idle_ccb_timer = alarm_new("avdt_ccb.idle_ccb_timer");
diff --git a/stack/avdt/avdt_ccb_act.cc b/stack/avdt/avdt_ccb_act.cc
index 9347646..f679dab 100644
--- a/stack/avdt/avdt_ccb_act.cc
+++ b/stack/avdt/avdt_ccb_act.cc
@@ -35,8 +35,6 @@
 #include "btu.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*******************************************************************************
  *
  * Function         avdt_ccb_clear_ccb
@@ -125,9 +123,8 @@
     alarm_cancel(p_ccb->ret_ccb_timer);
     alarm_cancel(p_ccb->rsp_ccb_timer);
     period_ms_t interval_ms = avdt_cb.rcb.idle_tout * 1000;
-    alarm_set_on_queue(p_ccb->idle_ccb_timer, interval_ms,
-                       avdt_ccb_idle_ccb_timer_timeout, p_ccb,
-                       btu_general_alarm_queue);
+    alarm_set_on_mloop(p_ccb->idle_ccb_timer, interval_ms,
+                       avdt_ccb_idle_ccb_timer_timeout, p_ccb);
   }
 }
 
@@ -187,7 +184,7 @@
   p_ccb->proc_busy = false;
 
   /* call app callback with results */
-  (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_DISCOVER_CFM_EVT,
+  (*p_ccb->proc_cback)(0, &p_ccb->peer_addr, AVDT_DISCOVER_CFM_EVT,
                        (tAVDT_CTRL*)(&p_data->msg.discover_rsp));
 }
 
@@ -232,7 +229,7 @@
   p_ccb->proc_busy = false;
 
   /* call app callback with results */
-  (*p_ccb->proc_cback)(0, p_ccb->peer_addr, AVDT_GETCAP_CFM_EVT,
+  (*p_ccb->proc_cback)(0, &p_ccb->peer_addr, AVDT_GETCAP_CFM_EVT,
                        (tAVDT_CTRL*)(&p_data->msg.svccap));
 }
 
@@ -509,8 +506,9 @@
       p_scb = avdt_scb_by_hdl(seid_list[i]);
       if (p_scb != NULL) {
         AVDT_TRACE_DEBUG("%s: AVDT_SCB_MSG_START_REJ_EVT: i=%d", __func__, i);
-        avdt_scb_event(p_scb, AVDT_SCB_MSG_START_REJ_EVT,
-                       (tAVDT_SCB_EVT*)&avdt_msg.hdr);
+        tAVDT_SCB_EVT avdt_scb_evt;
+        avdt_scb_evt.msg.hdr = avdt_msg.hdr;
+        avdt_scb_event(p_scb, AVDT_SCB_MSG_START_REJ_EVT, &avdt_scb_evt);
       }
     }
   }
@@ -583,8 +581,9 @@
     for (i = 0; i < p_data->msg.multi.num_seps; i++) {
       p_scb = avdt_scb_by_hdl(seid_list[i]);
       if (p_scb != NULL) {
-        avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_REJ_EVT,
-                       (tAVDT_SCB_EVT*)&avdt_msg.hdr);
+        tAVDT_SCB_EVT avdt_scb_evt;
+        avdt_scb_evt.msg.hdr = avdt_msg.hdr;
+        avdt_scb_event(p_scb, AVDT_SCB_MSG_SUSPEND_REJ_EVT, &avdt_scb_evt);
       }
     }
   }
@@ -647,7 +646,9 @@
   */
   do {
     /* we know p_curr_cmd = NULL after this */
-    avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT*)&err_code);
+    tAVDT_CCB_EVT avdt_ccb_evt;
+    avdt_ccb_evt.err_code = err_code;
+    avdt_ccb_cmd_fail(p_ccb, &avdt_ccb_evt);
 
     /* set up next message */
     p_ccb->p_curr_cmd = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->cmd_q);
@@ -689,13 +690,16 @@
     evt = avdt_msg_rej_2_evt[p_ccb->p_curr_cmd->event - 1];
 
     if (evt & AVDT_CCB_MKR) {
-      avdt_ccb_event(p_ccb, (uint8_t)(evt & ~AVDT_CCB_MKR),
-                     (tAVDT_CCB_EVT*)&msg);
+      tAVDT_CCB_EVT avdt_ccb_evt;
+      avdt_ccb_evt.msg = msg;
+      avdt_ccb_event(p_ccb, (uint8_t)(evt & ~AVDT_CCB_MKR), &avdt_ccb_evt);
     } else {
       /* we get the scb out of the current cmd */
       p_scb = avdt_scb_by_hdl(*((uint8_t*)(p_ccb->p_curr_cmd + 1)));
       if (p_scb != NULL) {
-        avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT*)&msg);
+        tAVDT_SCB_EVT avdt_scb_evt;
+        avdt_scb_evt.msg = msg;
+        avdt_scb_event(p_scb, evt, &avdt_scb_evt);
       }
     }
 
@@ -747,13 +751,13 @@
  *
  ******************************************************************************/
 void avdt_ccb_ret_cmd(tAVDT_CCB* p_ccb, tAVDT_CCB_EVT* p_data) {
-  uint8_t err_code = AVDT_ERR_TIMEOUT;
-
   p_ccb->ret_count++;
   if (p_ccb->ret_count == AVDT_RET_MAX) {
     /* command failed */
     p_ccb->ret_count = 0;
-    avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT*)&err_code);
+    tAVDT_CCB_EVT avdt_ccb_evt;
+    avdt_ccb_evt.err_code = AVDT_ERR_TIMEOUT;
+    avdt_ccb_cmd_fail(p_ccb, &avdt_ccb_evt);
 
     /* go to next queued command */
     avdt_ccb_snd_cmd(p_ccb, p_data);
@@ -773,9 +777,8 @@
     alarm_cancel(p_ccb->idle_ccb_timer);
     alarm_cancel(p_ccb->rsp_ccb_timer);
     period_ms_t interval_ms = avdt_cb.rcb.ret_tout * 1000;
-    alarm_set_on_queue(p_ccb->ret_ccb_timer, interval_ms,
-                       avdt_ccb_ret_ccb_timer_timeout, p_ccb,
-                       btu_general_alarm_queue);
+    alarm_set_on_mloop(p_ccb->ret_ccb_timer, interval_ms,
+                       avdt_ccb_ret_ccb_timer_timeout, p_ccb);
   }
 }
 
@@ -886,8 +889,6 @@
  *
  ******************************************************************************/
 void avdt_ccb_chk_reconn(tAVDT_CCB* p_ccb, UNUSED_ATTR tAVDT_CCB_EVT* p_data) {
-  uint8_t err_code = AVDT_ERR_CONNECT;
-
   if (p_ccb->reconn) {
     p_ccb->reconn = false;
 
@@ -895,7 +896,10 @@
     avdt_ccb_clear_ccb(p_ccb);
 
     /* clear out current command, if any */
-    avdt_ccb_cmd_fail(p_ccb, (tAVDT_CCB_EVT*)&err_code);
+    uint8_t err_code = AVDT_ERR_CONNECT;
+    tAVDT_CCB_EVT avdt_ccb_evt;
+    avdt_ccb_evt.err_code = err_code;
+    avdt_ccb_cmd_fail(p_ccb, &avdt_ccb_evt);
 
     /* reopen the signaling channel */
     avdt_ccb_event(p_ccb, AVDT_CCB_UL_OPEN_EVT, NULL);
@@ -989,7 +993,6 @@
  ******************************************************************************/
 void avdt_ccb_ll_closed(tAVDT_CCB* p_ccb, UNUSED_ATTR tAVDT_CCB_EVT* p_data) {
   tAVDT_CTRL_CBACK* p_cback;
-  BD_ADDR bd_addr;
   tAVDT_CTRL avdt_ctrl;
 
   /* clear any pending commands */
@@ -998,7 +1001,7 @@
   /* save callback pointer, bd addr */
   p_cback = p_ccb->p_conn_cback;
   if (!p_cback) p_cback = avdt_cb.p_conn_cback;
-  memcpy(bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
+  RawAddress bd_addr = p_ccb->peer_addr;
 
   /* dealloc ccb */
   avdt_ccb_dealloc(p_ccb, NULL);
@@ -1006,7 +1009,7 @@
   /* call callback */
   if (p_cback) {
     avdt_ctrl.hdr.err_code = 0;
-    (*p_cback)(0, bd_addr, AVDT_DISCONNECT_IND_EVT, &avdt_ctrl);
+    (*p_cback)(0, &bd_addr, AVDT_DISCONNECT_IND_EVT, &avdt_ctrl);
   }
 }
 
@@ -1031,7 +1034,7 @@
   if (p_ccb->p_conn_cback) {
     avdt_ctrl.hdr.err_code = 0;
     avdt_ctrl.hdr.err_param = p_data->msg.hdr.err_param;
-    (*p_ccb->p_conn_cback)(0, p_ccb->peer_addr, AVDT_CONNECT_IND_EVT,
+    (*p_ccb->p_conn_cback)(0, &p_ccb->peer_addr, AVDT_CONNECT_IND_EVT,
                            &avdt_ctrl);
   }
 }
diff --git a/stack/avdt/avdt_int.h b/stack/avdt/avdt_int.h
index 8d45418..1f593ef 100644
--- a/stack/avdt/avdt_int.h
+++ b/stack/avdt/avdt_int.h
@@ -400,7 +400,7 @@
 
 /* channel control block type */
 typedef struct {
-  BD_ADDR peer_addr; /* BD address of peer */
+  RawAddress peer_addr; /* BD address of peer */
   /*
    * NOTE: idle_ccb_timer, ret_ccb_timer and rsp_ccb_timer are mutually
    * exclusive - no more than one timer should be running at the same time.
@@ -530,8 +530,8 @@
 extern void avdt_ccb_init(void);
 extern void avdt_ccb_event(tAVDT_CCB* p_ccb, uint8_t event,
                            tAVDT_CCB_EVT* p_data);
-extern tAVDT_CCB* avdt_ccb_by_bd(BD_ADDR bd_addr);
-extern tAVDT_CCB* avdt_ccb_alloc(BD_ADDR bd_addr);
+extern tAVDT_CCB* avdt_ccb_by_bd(const RawAddress& bd_addr);
+extern tAVDT_CCB* avdt_ccb_alloc(const RawAddress& bd_addr);
 extern void avdt_ccb_dealloc(tAVDT_CCB* p_ccb, tAVDT_CCB_EVT* p_data);
 extern uint8_t avdt_ccb_to_idx(tAVDT_CCB* p_ccb);
 extern tAVDT_CCB* avdt_ccb_by_idx(uint8_t idx);
diff --git a/stack/avdt/avdt_l2c.cc b/stack/avdt/avdt_l2c.cc
index 35502f8..8ae1d43 100644
--- a/stack/avdt/avdt_l2c.cc
+++ b/stack/avdt/avdt_l2c.cc
@@ -37,8 +37,8 @@
 #include "osi/include/osi.h"
 
 /* callback function declarations */
-void avdt_l2c_connect_ind_cback(BD_ADDR bd_addr, uint16_t lcid, uint16_t psm,
-                                uint8_t id);
+void avdt_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
+                                uint16_t psm, uint8_t id);
 void avdt_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result);
 void avdt_l2c_config_cfm_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
 void avdt_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
@@ -72,7 +72,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void avdt_sec_check_complete_term(BD_ADDR bd_addr,
+static void avdt_sec_check_complete_term(const RawAddress* bd_addr,
                                          tBT_TRANSPORT transport,
                                          UNUSED_ATTR void* p_ref_data,
                                          uint8_t res) {
@@ -81,18 +81,14 @@
   tAVDT_TC_TBL* p_tbl;
 
   AVDT_TRACE_DEBUG("avdt_sec_check_complete_term res: %d", res);
-  if (!bd_addr) {
-    AVDT_TRACE_WARNING("avdt_sec_check_complete_term: NULL BD_ADDR");
-    return;
-  }
-  p_ccb = avdt_ccb_by_bd(bd_addr);
+  p_ccb = avdt_ccb_by_bd(*bd_addr);
 
   p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_SEC_ACP);
   if (p_tbl == NULL) return;
 
   if (res == BTM_SUCCESS) {
     /* Send response to the L2CAP layer. */
-    L2CA_ConnectRsp(bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK,
+    L2CA_ConnectRsp(*bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK,
                     L2CAP_CONN_OK);
 
     /* store idx in LCID table, store LCID in routing table */
@@ -111,7 +107,7 @@
     cfg.flush_to = p_tbl->my_flush_to;
     L2CA_ConfigReq(p_tbl->lcid, &cfg);
   } else {
-    L2CA_ConnectRsp(bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_SECURITY_BLOCK,
+    L2CA_ConnectRsp(*bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_SECURITY_BLOCK,
                     L2CAP_CONN_OK);
     avdt_ad_tc_close_ind(p_tbl, L2CAP_CONN_SECURITY_BLOCK);
   }
@@ -127,7 +123,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void avdt_sec_check_complete_orig(BD_ADDR bd_addr,
+static void avdt_sec_check_complete_orig(const RawAddress* bd_addr,
                                          tBT_TRANSPORT trasnport,
                                          UNUSED_ATTR void* p_ref_data,
                                          uint8_t res) {
@@ -136,7 +132,7 @@
   tAVDT_TC_TBL* p_tbl;
 
   AVDT_TRACE_DEBUG("avdt_sec_check_complete_orig res: %d", res);
-  if (bd_addr) p_ccb = avdt_ccb_by_bd(bd_addr);
+  if (bd_addr) p_ccb = avdt_ccb_by_bd(*bd_addr);
   p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_SEC_INT);
   if (p_tbl == NULL) return;
 
@@ -166,7 +162,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void avdt_l2c_connect_ind_cback(BD_ADDR bd_addr, uint16_t lcid,
+void avdt_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
                                 UNUSED_ATTR uint16_t psm, uint8_t id) {
   tAVDT_CCB* p_ccb;
   tAVDT_TC_TBL* p_tbl = NULL;
@@ -193,8 +189,7 @@
       p_tbl->state = AVDT_AD_ST_SEC_ACP;
       p_tbl->cfg_flags = AVDT_L2C_CFG_CONN_ACP;
 
-      if (interop_match_addr(INTEROP_2MBPS_LINK_ONLY,
-                             (const bt_bdaddr_t*)&bd_addr)) {
+      if (interop_match_addr(INTEROP_2MBPS_LINK_ONLY, &bd_addr)) {
         // Disable 3DH packets for AVDT ACL to improve sensitivity on HS
         tACL_CONN* p_acl_cb = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR);
         btm_set_packet_types(
@@ -318,7 +313,7 @@
             p_tbl->cfg_flags = AVDT_L2C_CFG_CONN_INT;
 
             if (interop_match_addr(INTEROP_2MBPS_LINK_ONLY,
-                                   (const bt_bdaddr_t*)&p_ccb->peer_addr)) {
+                                   (const RawAddress*)&p_ccb->peer_addr)) {
               // Disable 3DH packets for AVDT ACL to improve sensitivity on HS
               tACL_CONN* p_acl_cb =
                   btm_bda_to_acl(p_ccb->peer_addr, BT_TRANSPORT_BR_EDR);
diff --git a/stack/avdt/avdt_msg.cc b/stack/avdt/avdt_msg.cc
index fc1887e..52ce2e8 100644
--- a/stack/avdt/avdt_msg.cc
+++ b/stack/avdt/avdt_msg.cc
@@ -38,8 +38,6 @@
 #include "btu.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*****************************************************************************
  * constants
  ****************************************************************************/
@@ -1138,16 +1136,14 @@
           alarm_cancel(p_ccb->idle_ccb_timer);
           alarm_cancel(p_ccb->ret_ccb_timer);
           period_ms_t interval_ms = avdt_cb.rcb.sig_tout * 1000;
-          alarm_set_on_queue(p_ccb->rsp_ccb_timer, interval_ms,
-                             avdt_ccb_rsp_ccb_timer_timeout, p_ccb,
-                             btu_general_alarm_queue);
+          alarm_set_on_mloop(p_ccb->rsp_ccb_timer, interval_ms,
+                             avdt_ccb_rsp_ccb_timer_timeout, p_ccb);
         } else if (sig != AVDT_SIG_DELAY_RPT) {
           alarm_cancel(p_ccb->idle_ccb_timer);
           alarm_cancel(p_ccb->rsp_ccb_timer);
           period_ms_t interval_ms = avdt_cb.rcb.ret_tout * 1000;
-          alarm_set_on_queue(p_ccb->ret_ccb_timer, interval_ms,
-                             avdt_ccb_ret_ccb_timer_timeout, p_ccb,
-                             btu_general_alarm_queue);
+          alarm_set_on_mloop(p_ccb->ret_ccb_timer, interval_ms,
+                             avdt_ccb_ret_ccb_timer_timeout, p_ccb);
         }
       }
     } else {
@@ -1638,8 +1634,9 @@
   if (ok) {
     /* if it's a ccb event send to ccb */
     if (evt & AVDT_CCB_MKR) {
-      avdt_ccb_event(p_ccb, (uint8_t)(evt & ~AVDT_CCB_MKR),
-                     (tAVDT_CCB_EVT*)&msg);
+      tAVDT_CCB_EVT avdt_ccb_evt;
+      avdt_ccb_evt.msg = msg;
+      avdt_ccb_event(p_ccb, (uint8_t)(evt & ~AVDT_CCB_MKR), &avdt_ccb_evt);
     }
     /* if it's a scb event */
     else {
@@ -1658,7 +1655,9 @@
       if (evt) {
         p_scb = avdt_scb_by_hdl(scb_hdl);
         if (p_scb != NULL) {
-          avdt_scb_event(p_scb, evt, (tAVDT_SCB_EVT*)&msg);
+          tAVDT_SCB_EVT avdt_scb_evt;
+          avdt_scb_evt.msg = msg;
+          avdt_scb_event(p_scb, evt, &avdt_scb_evt);
         }
       }
     }
diff --git a/stack/avdt/avdt_scb_act.cc b/stack/avdt/avdt_scb_act.cc
index c44a5a2..9bb7ad2 100644
--- a/stack/avdt/avdt_scb_act.cc
+++ b/stack/avdt/avdt_scb_act.cc
@@ -23,6 +23,7 @@
  *
  ******************************************************************************/
 
+#include <cutils/log.h>
 #include <string.h>
 #include "a2dp_codec_api.h"
 #include "avdt_api.h"
@@ -35,8 +36,6 @@
 #include "btu.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /* This table is used to lookup the callback event that matches a particular
  * state machine API request event.  Note that state machine API request
  * events are at the beginning of the event list starting at zero, thus
@@ -209,9 +208,9 @@
   avdt_ad_open_req(AVDT_CHAN_MEDIA, p_scb->p_ccb, p_scb, AVDT_INT);
 
   /* start tc connect timer */
-  alarm_set_on_queue(
-      p_scb->transport_channel_timer, AVDT_SCB_TC_CONN_TIMEOUT_MS,
-      avdt_scb_transport_channel_timer_timeout, p_scb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_scb->transport_channel_timer,
+                     AVDT_SCB_TC_CONN_TIMEOUT_MS,
+                     avdt_scb_transport_channel_timer_timeout, p_scb);
 }
 
 /*******************************************************************************
@@ -233,10 +232,14 @@
   uint16_t offset;
   uint16_t ex_len;
   uint8_t pad_len = 0;
+  uint16_t len = p_data->p_pkt->len;
 
   p = p_start = (uint8_t*)(p_data->p_pkt + 1) + p_data->p_pkt->offset;
 
   /* parse media packet header */
+  offset = 12;
+  // AVDT_MSG_PRS_OCTET1(1) + AVDT_MSG_PRS_M_PT(1) + UINT16(2) + UINT32(4) + 4
+  if (offset > len) goto length_error;
   AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc);
   AVDT_MSG_PRS_M_PT(p, m_pt, marker);
   BE_STREAM_TO_UINT16(seq, p);
@@ -244,18 +247,19 @@
   p += 4;
 
   /* skip over any csrc's in packet */
+  offset += o_cc * 4;
   p += o_cc * 4;
 
   /* check for and skip over extension header */
   if (o_x) {
+    offset += 4;
+    if (offset > len) goto length_error;
     p += 2;
     BE_STREAM_TO_UINT16(ex_len, p);
+    offset += ex_len * 4;
     p += ex_len * 4;
   }
 
-  /* save our new offset */
-  offset = (uint16_t)(p - p_start);
-
   /* adjust length for any padding at end of packet */
   if (o_p) {
     /* padding length in last byte of packet */
@@ -283,6 +287,12 @@
       osi_free_and_reset((void**)&p_data->p_pkt);
     }
   }
+  return;
+length_error:
+  android_errorWriteLog(0x534e4554, "111450156");
+  AVDT_TRACE_WARNING("%s: hdl packet length %d too short: must be at least %d",
+                     __func__, len, offset);
+  osi_free_and_reset((void**)&p_data->p_pkt);
 }
 
 #if (AVDT_REPORTING == TRUE)
@@ -300,13 +310,21 @@
   uint8_t* p_start = p;
   uint32_t ssrc;
   uint8_t o_v, o_p, o_cc;
+  uint16_t min_len = 0;
   AVDT_REPORT_TYPE pt;
-  tAVDT_REPORT_DATA report, *p_rpt;
+  tAVDT_REPORT_DATA report;
 
   AVDT_TRACE_DEBUG("%s", __func__);
   if (p_scb->cs.p_report_cback) {
-    p_rpt = &report;
     /* parse report packet header */
+    min_len += 8;
+    if (min_len > len) {
+      android_errorWriteLog(0x534e4554, "111450156");
+      AVDT_TRACE_WARNING(
+          "%s: hdl packet length %d too short: must be at least %d", __func__,
+          len, min_len);
+      goto avdt_scb_hdl_report_exit;
+    }
     AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc);
     pt = *p++;
     p += 2;
@@ -314,6 +332,14 @@
 
     switch (pt) {
       case AVDT_RTCP_PT_SR: /* the packet type - SR (Sender Report) */
+        min_len += 20;
+        if (min_len > len) {
+          android_errorWriteLog(0x534e4554, "111450156");
+          AVDT_TRACE_WARNING(
+              "%s: hdl packet length %d too short: must be at least %d",
+              __func__, len, min_len);
+          goto avdt_scb_hdl_report_exit;
+        }
         BE_STREAM_TO_UINT32(report.sr.ntp_sec, p);
         BE_STREAM_TO_UINT32(report.sr.ntp_frac, p);
         BE_STREAM_TO_UINT32(report.sr.rtp_time, p);
@@ -322,6 +348,14 @@
         break;
 
       case AVDT_RTCP_PT_RR: /* the packet type - RR (Receiver Report) */
+        min_len += 20;
+        if (min_len > len) {
+          android_errorWriteLog(0x534e4554, "111450156");
+          AVDT_TRACE_WARNING(
+              "%s: hdl packet length %d too short: must be at least %d",
+              __func__, len, min_len);
+          goto avdt_scb_hdl_report_exit;
+        }
         report.rr.frag_lost = *p;
         BE_STREAM_TO_UINT32(report.rr.packet_lost, p);
         report.rr.packet_lost &= 0xFFFFFF;
@@ -332,9 +366,40 @@
         break;
 
       case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */
-        if (*p == AVDT_RTCP_SDES_CNAME) {
-          p_rpt = (tAVDT_REPORT_DATA*)(p + 2);
+        uint8_t sdes_type;
+        min_len += 1;
+        if (min_len > len) {
+          android_errorWriteLog(0x534e4554, "111450156");
+          AVDT_TRACE_WARNING(
+              "%s: hdl packet length %d too short: must be at least %d",
+              __func__, len, min_len);
+          goto avdt_scb_hdl_report_exit;
+        }
+        BE_STREAM_TO_UINT8(sdes_type, p);
+        if (sdes_type == AVDT_RTCP_SDES_CNAME) {
+          uint8_t name_length;
+          min_len += 1;
+          if (min_len > len) {
+            android_errorWriteLog(0x534e4554, "111450156");
+            AVDT_TRACE_WARNING(
+                "%s: hdl packet length %d too short: must be at least %d",
+                __func__, len, min_len);
+            goto avdt_scb_hdl_report_exit;
+          }
+          BE_STREAM_TO_UINT8(name_length, p);
+          if (name_length > len - 2 || name_length > AVDT_MAX_CNAME_SIZE) {
+            result = AVDT_BAD_PARAMS;
+          } else {
+            BE_STREAM_TO_ARRAY(p, &(report.cname[0]), name_length);
+          }
         } else {
+          if (min_len + 1 > len) {
+            android_errorWriteLog(0x534e4554, "111450156");
+            AVDT_TRACE_WARNING(
+                "%s: hdl packet length %d too short: must be at least %d",
+                __func__, len, min_len + 2);
+            goto avdt_scb_hdl_report_exit;
+          }
           AVDT_TRACE_WARNING(" - SDES SSRC=0x%08x sc=%d %d len=%d %s", ssrc,
                              o_cc, *p, *(p + 1), p + 2);
           result = AVDT_BUSY;
@@ -347,8 +412,9 @@
     }
 
     if (result == AVDT_SUCCESS)
-      (*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, p_rpt);
+      (*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, &report);
   }
+avdt_scb_hdl_report_exit:
   p_start += len;
   return p_start;
 }
@@ -520,9 +586,10 @@
       memcpy(&p_scb->req_cfg, p_cfg, sizeof(tAVDT_CFG));
       /* call app callback */
       /* handle of scb- which is same as sep handle of bta_av_cb.p_scb*/
-      (*p_scb->cs.p_ctrl_cback)(
-          avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
-          AVDT_CONFIG_IND_EVT, (tAVDT_CTRL*)&p_data->msg.config_cmd);
+      (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb),
+                                p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
+                                AVDT_CONFIG_IND_EVT,
+                                (tAVDT_CTRL*)&p_data->msg.config_cmd);
     } else {
       p_data->msg.hdr.err_code = AVDT_ERR_UNSUP_CFG;
       p_data->msg.hdr.err_param = 0;
@@ -579,7 +646,9 @@
 
     /* initiate open */
     single.seid = p_scb->peer_seid;
-    avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_REQ_EVT, (tAVDT_SCB_EVT*)&single);
+    tAVDT_SCB_EVT avdt_scb_evt;
+    avdt_scb_evt.msg.single = single;
+    avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_REQ_EVT, &avdt_scb_evt);
   }
 }
 
@@ -596,7 +665,7 @@
 void avdt_scb_hdl_start_cmd(tAVDT_SCB* p_scb,
                             UNUSED_ATTR tAVDT_SCB_EVT* p_data) {
   (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb),
-                            p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+                            p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
                             AVDT_START_IND_EVT, NULL);
 }
 
@@ -612,7 +681,7 @@
  ******************************************************************************/
 void avdt_scb_hdl_start_rsp(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) {
   (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb),
-                            p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+                            p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
                             AVDT_START_CFM_EVT, (tAVDT_CTRL*)&p_data->msg.hdr);
 }
 
@@ -629,7 +698,7 @@
 void avdt_scb_hdl_suspend_cmd(tAVDT_SCB* p_scb,
                               UNUSED_ATTR tAVDT_SCB_EVT* p_data) {
   (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb),
-                            p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+                            p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
                             AVDT_SUSPEND_IND_EVT, NULL);
 }
 
@@ -645,7 +714,7 @@
  ******************************************************************************/
 void avdt_scb_hdl_suspend_rsp(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) {
   (*p_scb->cs.p_ctrl_cback)(
-      avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+      avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
       AVDT_SUSPEND_CFM_EVT, (tAVDT_CTRL*)&p_data->msg.hdr);
 }
 
@@ -671,9 +740,7 @@
   tAVDT_CTRL avdt_ctrl;
   uint8_t event;
   tAVDT_CCB* p_ccb = p_scb->p_ccb;
-  BD_ADDR remote_addr;
-
-  memcpy(remote_addr, p_ccb->peer_addr, BD_ADDR_LEN);
+  RawAddress remote_addr = p_ccb->peer_addr;
 
   /* set up hdr */
   avdt_ctrl.hdr.err_code = p_scb->close_code;
@@ -701,7 +768,7 @@
   }
 
   /* call app callback */
-  (*p_ctrl_cback)(hdl, remote_addr, event, &avdt_ctrl);
+  (*p_ctrl_cback)(hdl, &remote_addr, event, &avdt_ctrl);
 }
 
 /*******************************************************************************
@@ -731,7 +798,7 @@
  ******************************************************************************/
 void avdt_scb_hdl_delay_rpt_cmd(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) {
   (*p_scb->cs.p_ctrl_cback)(
-      avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+      avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
       AVDT_DELAY_REPORT_EVT, (tAVDT_CTRL*)&p_data->msg.hdr);
 
   if (p_scb->p_ccb)
@@ -752,7 +819,7 @@
  ******************************************************************************/
 void avdt_scb_hdl_delay_rpt_rsp(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) {
   (*p_scb->cs.p_ctrl_cback)(
-      avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+      avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
       AVDT_DELAY_REPORT_CFM_EVT, (tAVDT_CTRL*)&p_data->msg.hdr);
 }
 
@@ -778,7 +845,7 @@
       avdt_ctrl.hdr.err_param = 0;
       /* call app callback */
       (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb),
-                                p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+                                p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
                                 AVDT_REPORT_DISCONN_EVT, &avdt_ctrl);
     }
   } else {
@@ -826,7 +893,7 @@
 
   /* call app callback */
   (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb),
-                            p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+                            p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
                             event, (tAVDT_CTRL*)&p_data->open);
 }
 
@@ -852,7 +919,7 @@
     avdt_ctrl.hdr.err_code = 0;
     avdt_ctrl.hdr.err_param = 1;
     (*p_scb->cs.p_ctrl_cback)(avdt_scb_to_hdl(p_scb),
-                              p_scb->p_ccb ? p_scb->p_ccb->peer_addr : NULL,
+                              p_scb->p_ccb ? &p_scb->p_ccb->peer_addr : NULL,
                               AVDT_REPORT_CONN_EVT, &avdt_ctrl);
   }
 }
@@ -928,7 +995,9 @@
 
     hdr.seid = p_scb->peer_seid;
 
-    avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_ABORT, (tAVDT_MSG*)&hdr);
+    tAVDT_MSG avdt_msg;
+    avdt_msg.hdr = hdr;
+    avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_ABORT, &avdt_msg);
   }
 }
 
@@ -964,7 +1033,9 @@
 
   hdr.seid = p_scb->peer_seid;
 
-  avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_CLOSE, (tAVDT_MSG*)&hdr);
+  tAVDT_MSG avdt_msg;
+  avdt_msg.hdr = hdr;
+  avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_CLOSE, &avdt_msg);
 }
 
 /*******************************************************************************
@@ -1009,7 +1080,9 @@
 
   hdr.seid = p_scb->peer_seid;
 
-  avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_GETCONFIG, (tAVDT_MSG*)&hdr);
+  tAVDT_MSG avdt_msg;
+  avdt_msg.hdr = hdr;
+  avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_GETCONFIG, &avdt_msg);
 }
 
 /*******************************************************************************
@@ -1040,7 +1113,9 @@
 
   hdr.seid = p_scb->peer_seid;
 
-  avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_OPEN, (tAVDT_MSG*)&hdr);
+  tAVDT_MSG avdt_msg;
+  avdt_msg.hdr = hdr;
+  avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_OPEN, &avdt_msg);
 }
 
 /*******************************************************************************
@@ -1062,9 +1137,9 @@
   /* send response */
   avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_OPEN, &p_data->msg);
 
-  alarm_set_on_queue(
-      p_scb->transport_channel_timer, AVDT_SCB_TC_CONN_TIMEOUT_MS,
-      avdt_scb_transport_channel_timer_timeout, p_scb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_scb->transport_channel_timer,
+                     AVDT_SCB_TC_CONN_TIMEOUT_MS,
+                     avdt_scb_transport_channel_timer_timeout, p_scb);
 }
 
 /*******************************************************************************
@@ -1447,9 +1522,9 @@
  ******************************************************************************/
 void avdt_scb_transport_channel_timer(tAVDT_SCB* p_scb,
                                       UNUSED_ATTR tAVDT_SCB_EVT* p_data) {
-  alarm_set_on_queue(
-      p_scb->transport_channel_timer, AVDT_SCB_TC_DISC_TIMEOUT_MS,
-      avdt_scb_transport_channel_timer_timeout, p_scb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_scb->transport_channel_timer,
+                     AVDT_SCB_TC_DISC_TIMEOUT_MS,
+                     avdt_scb_transport_channel_timer_timeout, p_scb);
 }
 
 /*******************************************************************************
diff --git a/stack/avrc/avrc_api.cc b/stack/avrc/avrc_api.cc
index 164ad78..10eb1a9 100644
--- a/stack/avrc/avrc_api.cc
+++ b/stack/avrc/avrc_api.cc
@@ -36,7 +36,6 @@
 /*****************************************************************************
  *  Global data
  ****************************************************************************/
-extern fixed_queue_t* btu_general_alarm_queue;
 
 #define AVRC_MAX_RCV_CTRL_EVT AVCT_BROWSE_UNCONG_IND_EVT
 
@@ -84,7 +83,7 @@
  *
  *****************************************************************************/
 static void avrc_ctrl_cback(uint8_t handle, uint8_t event, uint16_t result,
-                            BD_ADDR peer_addr) {
+                            const RawAddress* peer_addr) {
   uint8_t avrc_event;
 
   if (event <= AVRC_MAX_RCV_CTRL_EVT && avrc_cb.ccb[handle].p_ctrl_cback) {
@@ -207,8 +206,8 @@
   AVRC_TRACE_DEBUG("AVRC: starting timer (handle=0x%02x, label=0x%02x)", handle,
                    label);
 
-  alarm_set_on_queue(avrc_cb.ccb_int[handle].tle, AVRC_CMD_TOUT_MS,
-                     avrc_process_timeout, param, btu_general_alarm_queue);
+  alarm_set_on_mloop(avrc_cb.ccb_int[handle].tle, AVRC_CMD_TOUT_MS,
+                     avrc_process_timeout, param);
 }
 
 /******************************************************************************
@@ -598,7 +597,10 @@
     }
     avrc_cmd.status = AVRC_STS_NO_ERROR;
     avrc_cmd.target_pdu = p_rcb->rasm_pdu;
-    status = AVRC_BldCommand((tAVRC_COMMAND*)&avrc_cmd, &p_cmd);
+
+    tAVRC_COMMAND avrc_command;
+    avrc_command.continu = avrc_cmd;
+    status = AVRC_BldCommand(&avrc_command, &p_cmd);
     if (status == AVRC_STS_NO_ERROR) {
       AVRC_MsgReq(handle, (uint8_t)(label), AVRC_CMD_CTRL, p_cmd);
     }
@@ -1056,7 +1058,7 @@
  *
  *****************************************************************************/
 uint16_t AVRC_Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb,
-                   BD_ADDR_PTR peer_addr) {
+                   const RawAddress& peer_addr) {
   uint16_t status;
   tAVCT_CC cc;
 
diff --git a/stack/avrc/avrc_sdp.cc b/stack/avrc/avrc_sdp.cc
index dbb71fa..3a7ed96 100644
--- a/stack/avrc/avrc_sdp.cc
+++ b/stack/avrc/avrc_sdp.cc
@@ -31,6 +31,11 @@
  *  Global data
  ****************************************************************************/
 tAVRC_CB avrc_cb;
+static uint16_t a2dp_attr_list_sdp[] = {
+    ATTR_ID_SERVICE_CLASS_ID_LIST, /* update A2DP_NUM_ATTR, if changed */
+    ATTR_ID_BT_PROFILE_DESC_LIST,  ATTR_ID_SUPPORTED_FEATURES,
+    ATTR_ID_SERVICE_NAME,          ATTR_ID_PROTOCOL_DESC_LIST,
+    ATTR_ID_PROVIDER_NAME};
 
 /******************************************************************************
  *
@@ -98,16 +103,11 @@
  *                                    perform the service search.
  *
  *****************************************************************************/
-uint16_t AVRC_FindService(uint16_t service_uuid, BD_ADDR bd_addr,
+uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr,
                           tAVRC_SDP_DB_PARAMS* p_db,
                           tAVRC_FIND_CBACK* p_cback) {
   tSDP_UUID uuid_list;
   bool result = true;
-  uint16_t a2dp_attr_list[] = {
-      ATTR_ID_SERVICE_CLASS_ID_LIST, /* update AVRC_NUM_ATTR, if changed */
-      ATTR_ID_PROTOCOL_DESC_LIST,    ATTR_ID_BT_PROFILE_DESC_LIST,
-      ATTR_ID_SERVICE_NAME,          ATTR_ID_SUPPORTED_FEATURES,
-      ATTR_ID_PROVIDER_NAME};
 
   AVRC_TRACE_API("%s uuid: %x", __func__, service_uuid);
   if ((service_uuid != UUID_SERVCLASS_AV_REM_CTRL_TARGET &&
@@ -125,7 +125,7 @@
   uuid_list.uu.uuid16 = service_uuid;
 
   if (p_db->p_attrs == NULL || p_db->num_attr == 0) {
-    p_db->p_attrs = a2dp_attr_list;
+    p_db->p_attrs = a2dp_attr_list_sdp;
     p_db->num_attr = AVRC_NUM_ATTR;
   }
 
diff --git a/stack/bnep/bnep_api.cc b/stack/bnep/bnep_api.cc
index 12a5caa..e5d3c09 100644
--- a/stack/bnep/bnep_api.cc
+++ b/stack/bnep/bnep_api.cc
@@ -27,8 +27,6 @@
 #include <string.h>
 #include "bnep_int.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*******************************************************************************
  *
  * Function         BNEP_Init
@@ -126,14 +124,12 @@
  *                  BNEP_NO_RESOURCES           if no resources
  *
  ******************************************************************************/
-tBNEP_RESULT BNEP_Connect(BD_ADDR p_rem_bda, tBT_UUID* src_uuid,
+tBNEP_RESULT BNEP_Connect(const RawAddress& p_rem_bda, tBT_UUID* src_uuid,
                           tBT_UUID* dst_uuid, uint16_t* p_handle) {
   uint16_t cid;
   tBNEP_CONN* p_bcb = bnepu_find_bcb_by_bd_addr(p_rem_bda);
 
-  BNEP_TRACE_API("BNEP_Connect()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
-                 p_rem_bda[0], p_rem_bda[1], p_rem_bda[2], p_rem_bda[3],
-                 p_rem_bda[4], p_rem_bda[5]);
+  VLOG(0) << __func__ << " BDA:" << p_rem_bda;
 
   if (!bnep_cb.profile_registered) return BNEP_WRONG_STATE;
 
@@ -194,8 +190,8 @@
     }
 
     /* Start timer waiting for connect */
-    alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
-                       bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
+                       bnep_conn_timer_timeout, p_bcb);
   }
 
   *p_handle = p_bcb->handle;
@@ -336,9 +332,9 @@
  *                  BNEP_SUCCESS            - If written successfully
  *
  ******************************************************************************/
-tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, uint8_t* p_dest_addr, BT_HDR* p_buf,
-                           uint16_t protocol, uint8_t* p_src_addr,
-                           bool fw_ext_present) {
+tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr,
+                           BT_HDR* p_buf, uint16_t protocol,
+                           const RawAddress* p_src_addr, bool fw_ext_present) {
   tBNEP_CONN* p_bcb;
   uint8_t* p_data;
 
@@ -409,7 +405,7 @@
   }
 
   /* Build the BNEP header */
-  bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, p_dest_addr,
+  bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr,
                        fw_ext_present);
 
   /* Send the data or queue it up */
@@ -442,9 +438,9 @@
  *                  BNEP_SUCCESS            - If written successfully
  *
  ******************************************************************************/
-tBNEP_RESULT BNEP_Write(uint16_t handle, uint8_t* p_dest_addr, uint8_t* p_data,
-                        uint16_t len, uint16_t protocol, uint8_t* p_src_addr,
-                        bool fw_ext_present) {
+tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr,
+                        uint8_t* p_data, uint16_t len, uint16_t protocol,
+                        const RawAddress* p_src_addr, bool fw_ext_present) {
   tBNEP_CONN* p_bcb;
   uint8_t* p;
 
@@ -515,7 +511,7 @@
   memcpy(p, p_data, len);
 
   /* Build the BNEP header */
-  bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, p_dest_addr,
+  bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr,
                        fw_ext_present);
 
   /* Send the data or queue it up */
@@ -622,8 +618,9 @@
 
   /* Fill the multicast filter values in connnection block */
   for (xx = 0; xx < num_filters; xx++) {
-    memcpy(p_bcb->sent_mcast_filter_start[xx], p_start_array, BD_ADDR_LEN);
-    memcpy(p_bcb->sent_mcast_filter_end[xx], p_end_array, BD_ADDR_LEN);
+    memcpy(p_bcb->sent_mcast_filter_start[xx].address, p_start_array,
+           BD_ADDR_LEN);
+    memcpy(p_bcb->sent_mcast_filter_end[xx].address, p_end_array, BD_ADDR_LEN);
 
     p_start_array += BD_ADDR_LEN;
     p_end_array += BD_ADDR_LEN;
@@ -691,7 +688,7 @@
   p_status->rcvd_num_filters = p_bcb->rcvd_num_filters;
   p_status->rcvd_mcast_filters = p_bcb->rcvd_mcast_filters;
 
-  memcpy(p_status->rem_bda, p_bcb->rem_bda, BD_ADDR_LEN);
+  p_status->rem_bda = p_bcb->rem_bda;
   memcpy(&(p_status->src_uuid), &(p_bcb->src_uuid), sizeof(tBT_UUID));
   memcpy(&(p_status->dst_uuid), &(p_bcb->dst_uuid), sizeof(tBT_UUID));
 
diff --git a/stack/bnep/bnep_int.h b/stack/bnep/bnep_int.h
index 9703963..e25e7f8 100644
--- a/stack/bnep/bnep_int.h
+++ b/stack/bnep/bnep_int.h
@@ -125,7 +125,7 @@
   BT_HDR* p_pending_data;
 
   uint16_t l2cap_cid;
-  BD_ADDR rem_bda;
+  RawAddress rem_bda;
   uint16_t rem_mtu_size;
   alarm_t* conn_timer;
   fixed_queue_t* xmit_q;
@@ -135,16 +135,16 @@
   uint16_t sent_prot_filter_end[BNEP_MAX_PROT_FILTERS];
 
   uint16_t sent_mcast_filters;
-  BD_ADDR sent_mcast_filter_start[BNEP_MAX_MULTI_FILTERS];
-  BD_ADDR sent_mcast_filter_end[BNEP_MAX_MULTI_FILTERS];
+  RawAddress sent_mcast_filter_start[BNEP_MAX_MULTI_FILTERS];
+  RawAddress sent_mcast_filter_end[BNEP_MAX_MULTI_FILTERS];
 
   uint16_t rcvd_num_filters;
   uint16_t rcvd_prot_filter_start[BNEP_MAX_PROT_FILTERS];
   uint16_t rcvd_prot_filter_end[BNEP_MAX_PROT_FILTERS];
 
   uint16_t rcvd_mcast_filters;
-  BD_ADDR rcvd_mcast_filter_start[BNEP_MAX_MULTI_FILTERS];
-  BD_ADDR rcvd_mcast_filter_end[BNEP_MAX_MULTI_FILTERS];
+  RawAddress rcvd_mcast_filter_start[BNEP_MAX_MULTI_FILTERS];
+  RawAddress rcvd_mcast_filter_end[BNEP_MAX_MULTI_FILTERS];
 
   uint16_t bad_pkts_rcvd;
   uint8_t re_transmits;
@@ -192,15 +192,16 @@
 /* Functions provided by bnep_utils.cc
 */
 extern tBNEP_CONN* bnepu_find_bcb_by_cid(uint16_t cid);
-extern tBNEP_CONN* bnepu_find_bcb_by_bd_addr(uint8_t* p_bda);
-extern tBNEP_CONN* bnepu_allocate_bcb(BD_ADDR p_rem_bda);
+extern tBNEP_CONN* bnepu_find_bcb_by_bd_addr(const RawAddress& p_bda);
+extern tBNEP_CONN* bnepu_allocate_bcb(const RawAddress& p_rem_bda);
 extern void bnepu_release_bcb(tBNEP_CONN* p_bcb);
 extern void bnepu_send_peer_our_filters(tBNEP_CONN* p_bcb);
 extern void bnepu_send_peer_our_multi_filters(tBNEP_CONN* p_bcb);
 extern bool bnepu_does_dest_support_prot(tBNEP_CONN* p_bcb, uint16_t protocol);
 extern void bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf,
-                                 uint16_t protocol, uint8_t* p_src_addr,
-                                 uint8_t* p_dest_addr, bool ext_bit);
+                                 uint16_t protocol,
+                                 const RawAddress* p_src_addr,
+                                 const RawAddress* p_dest_addr, bool ext_bit);
 extern void test_bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf,
                                       uint16_t protocol, uint8_t* p_src_addr,
                                       uint8_t* p_dest_addr, uint8_t type);
@@ -222,10 +223,11 @@
                                              uint8_t* p_setup);
 extern uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
                                             uint16_t* len, bool is_ext);
-extern void bnep_sec_check_complete(BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
-                                    void* p_ref_data, uint8_t result);
+extern void bnep_sec_check_complete(const RawAddress* bd_addr,
+                                    tBT_TRANSPORT trasnport, void* p_ref_data,
+                                    uint8_t result);
 extern tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb,
-                                           BD_ADDR p_dest_addr,
+                                           const RawAddress& p_dest_addr,
                                            uint16_t protocol,
                                            bool fw_ext_present,
                                            uint8_t* p_data);
diff --git a/stack/bnep/bnep_main.cc b/stack/bnep/bnep_main.cc
index 9eae106..8772e57 100644
--- a/stack/bnep/bnep_main.cc
+++ b/stack/bnep/bnep_main.cc
@@ -46,8 +46,6 @@
 #include "device/include/controller.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /******************************************************************************/
 /*                     G L O B A L    B N E P       D A T A                   */
 /******************************************************************************/
@@ -58,8 +56,8 @@
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
-static void bnep_connect_ind(BD_ADDR bd_addr, uint16_t l2cap_cid, uint16_t psm,
-                             uint8_t l2cap_id);
+static void bnep_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid,
+                             uint16_t psm, uint8_t l2cap_id);
 static void bnep_connect_cfm(uint16_t l2cap_cid, uint16_t result);
 static void bnep_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
 static void bnep_config_cfm(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
@@ -115,7 +113,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void bnep_connect_ind(BD_ADDR bd_addr, uint16_t l2cap_cid,
+static void bnep_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid,
                              UNUSED_ATTR uint16_t psm, uint8_t l2cap_id) {
   tBNEP_CONN* p_bcb = bnepu_find_bcb_by_bd_addr(bd_addr);
 
@@ -140,8 +138,8 @@
   L2CA_ConfigReq(l2cap_cid, &bnep_cb.l2cap_my_cfg);
 
   /* Start timer waiting for config setup */
-  alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
-                     bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
+                     bnep_conn_timer_timeout, p_bcb);
 
   BNEP_TRACE_EVENT("BNEP - Rcvd L2CAP conn ind, CID: 0x%x", p_bcb->l2cap_cid);
 }
@@ -177,8 +175,8 @@
     L2CA_ConfigReq(l2cap_cid, &bnep_cb.l2cap_my_cfg);
 
     /* Start timer waiting for config results */
-    alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
-                       bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
+                       bnep_conn_timer_timeout, p_bcb);
 
     BNEP_TRACE_EVENT("BNEP - got conn cnf, sent cfg req, CID: 0x%x",
                      p_bcb->l2cap_cid);
@@ -253,8 +251,8 @@
     p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
 
     /* Start timer waiting for setup or response */
-    alarm_set_on_queue(p_bcb->conn_timer, BNEP_HOST_TIMEOUT_MS,
-                       bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_bcb->conn_timer, BNEP_HOST_TIMEOUT_MS,
+                       bnep_conn_timer_timeout, p_bcb);
 
     if (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) {
       btm_sec_mx_access_request(
@@ -296,9 +294,8 @@
       p_bcb->con_state = BNEP_STATE_SEC_CHECKING;
 
       /* Start timer waiting for setup or response */
-      alarm_set_on_queue(p_bcb->conn_timer, BNEP_HOST_TIMEOUT_MS,
-                         bnep_conn_timer_timeout, p_bcb,
-                         btu_general_alarm_queue);
+      alarm_set_on_mloop(p_bcb->conn_timer, BNEP_HOST_TIMEOUT_MS,
+                         bnep_conn_timer_timeout, p_bcb);
 
       if (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG) {
         btm_sec_mx_access_request(p_bcb->rem_bda, BT_PSM_BNEP, true,
@@ -442,7 +439,6 @@
   uint8_t type, ctrl_type, ext_type = 0;
   bool extension_present, fw_ext_present;
   uint16_t protocol = 0;
-  uint8_t *p_src_addr, *p_dst_addr;
 
   /* Find CCB based on CID */
   p_bcb = bnepu_find_bcb_by_cid(l2cap_cid);
@@ -531,13 +527,14 @@
                    p_buf->len, extension_present);
 
   /* Initialize addresses to 'not supplied' */
+  const RawAddress *p_src_addr, *p_dst_addr;
   p_src_addr = p_dst_addr = NULL;
 
   switch (type) {
     case BNEP_FRAME_GENERAL_ETHERNET:
-      p_dst_addr = p;
+      p_dst_addr = (RawAddress*)p;
       p += BD_ADDR_LEN;
-      p_src_addr = p;
+      p_src_addr = (RawAddress*)p;
       p += BD_ADDR_LEN;
       BE_STREAM_TO_UINT16(protocol, p);
       rem_len -= 14;
@@ -578,14 +575,14 @@
       break;
 
     case BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY:
-      p_src_addr = p;
+      p_src_addr = (RawAddress*)p;
       p += BD_ADDR_LEN;
       BE_STREAM_TO_UINT16(protocol, p);
       rem_len -= 8;
       break;
 
     case BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY:
-      p_dst_addr = p;
+      p_dst_addr = (RawAddress*)p;
       p += BD_ADDR_LEN;
       BE_STREAM_TO_UINT16(protocol, p);
       rem_len -= 8;
@@ -613,10 +610,9 @@
   p_buf->len = rem_len;
 
   /* Always give the upper layer MAC addresses */
-  if (!p_src_addr) p_src_addr = (uint8_t*)p_bcb->rem_bda;
+  if (!p_src_addr) p_src_addr = &p_bcb->rem_bda;
 
-  if (!p_dst_addr)
-    p_dst_addr = (uint8_t*)controller_get_interface()->get_address();
+  if (!p_dst_addr) p_dst_addr = controller_get_interface()->get_address();
 
   /* check whether there are any extensions to be forwarded */
   if (ext_type)
@@ -625,12 +621,12 @@
     fw_ext_present = false;
 
   if (bnep_cb.p_data_buf_cb) {
-    (*bnep_cb.p_data_buf_cb)(p_bcb->handle, p_src_addr, p_dst_addr, protocol,
+    (*bnep_cb.p_data_buf_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol,
                              p_buf, fw_ext_present);
     osi_free(p_buf);
   } else if (bnep_cb.p_data_ind_cb) {
-    (*bnep_cb.p_data_ind_cb)(p_bcb->handle, p_src_addr, p_dst_addr, protocol, p,
-                             rem_len, fw_ext_present);
+    (*bnep_cb.p_data_ind_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol,
+                             p, rem_len, fw_ext_present);
     osi_free(p_buf);
   }
 }
@@ -667,9 +663,8 @@
 
     if (p_bcb->re_transmits++ != BNEP_MAX_RETRANSMITS) {
       bnep_send_conn_req(p_bcb);
-      alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
-                         bnep_conn_timer_timeout, p_bcb,
-                         btu_general_alarm_queue);
+      alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
+                         bnep_conn_timer_timeout, p_bcb);
     } else {
       L2CA_DisconnectReq(p_bcb->l2cap_cid);
 
@@ -695,9 +690,8 @@
   } else if (p_bcb->con_flags & BNEP_FLAGS_FILTER_RESP_PEND) {
     if (p_bcb->re_transmits++ != BNEP_MAX_RETRANSMITS) {
       bnepu_send_peer_our_filters(p_bcb);
-      alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
-                         bnep_conn_timer_timeout, p_bcb,
-                         btu_general_alarm_queue);
+      alarm_set_on_mloop(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
+                         bnep_conn_timer_timeout, p_bcb);
     } else {
       L2CA_DisconnectReq(p_bcb->l2cap_cid);
 
@@ -712,9 +706,8 @@
   } else if (p_bcb->con_flags & BNEP_FLAGS_MULTI_RESP_PEND) {
     if (p_bcb->re_transmits++ != BNEP_MAX_RETRANSMITS) {
       bnepu_send_peer_our_multi_filters(p_bcb);
-      alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
-                         bnep_conn_timer_timeout, p_bcb,
-                         btu_general_alarm_queue);
+      alarm_set_on_mloop(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
+                         bnep_conn_timer_timeout, p_bcb);
     } else {
       L2CA_DisconnectReq(p_bcb->l2cap_cid);
 
diff --git a/stack/bnep/bnep_utils.cc b/stack/bnep/bnep_utils.cc
index 373b9c5..3bab9ee 100644
--- a/stack/bnep/bnep_utils.cc
+++ b/stack/bnep/bnep_utils.cc
@@ -35,8 +35,6 @@
 #include "device/include/controller.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
@@ -82,15 +80,14 @@
  * Returns          the BCB address, or NULL if not found.
  *
  ******************************************************************************/
-tBNEP_CONN* bnepu_find_bcb_by_bd_addr(uint8_t* p_bda) {
+tBNEP_CONN* bnepu_find_bcb_by_bd_addr(const RawAddress& p_bda) {
   uint16_t xx;
   tBNEP_CONN* p_bcb;
 
   /* Look through each connection control block */
   for (xx = 0, p_bcb = bnep_cb.bcb; xx < BNEP_MAX_CONNECTIONS; xx++, p_bcb++) {
     if (p_bcb->con_state != BNEP_STATE_IDLE) {
-      if (!memcmp((uint8_t*)(p_bcb->rem_bda), p_bda, BD_ADDR_LEN))
-        return (p_bcb);
+      if (p_bcb->rem_bda == p_bda) return (p_bcb);
     }
   }
 
@@ -107,7 +104,7 @@
  * Returns          BCB address, or NULL if none available.
  *
  ******************************************************************************/
-tBNEP_CONN* bnepu_allocate_bcb(BD_ADDR p_rem_bda) {
+tBNEP_CONN* bnepu_allocate_bcb(const RawAddress& p_rem_bda) {
   uint16_t xx;
   tBNEP_CONN* p_bcb;
 
@@ -118,7 +115,7 @@
       memset((uint8_t*)p_bcb, 0, sizeof(tBNEP_CONN));
       p_bcb->conn_timer = alarm_new("bnep.conn_timer");
 
-      memcpy((uint8_t*)(p_bcb->rem_bda), (uint8_t*)p_rem_bda, BD_ADDR_LEN);
+      p_bcb->rem_bda = p_rem_bda;
       p_bcb->handle = xx + 1;
       p_bcb->xmit_q = fixed_queue_new(SIZE_MAX);
 
@@ -274,8 +271,8 @@
   p_bcb->con_flags |= BNEP_FLAGS_FILTER_RESP_PEND;
 
   /* Start timer waiting for setup response */
-  alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
-                     bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
+                     bnep_conn_timer_timeout, p_bcb);
 }
 
 /*******************************************************************************
@@ -305,9 +302,9 @@
 
   UINT16_TO_BE_STREAM(p, (2 * BD_ADDR_LEN * p_bcb->sent_mcast_filters));
   for (xx = 0; xx < p_bcb->sent_mcast_filters; xx++) {
-    memcpy(p, p_bcb->sent_mcast_filter_start[xx], BD_ADDR_LEN);
+    memcpy(p, p_bcb->sent_mcast_filter_start[xx].address, BD_ADDR_LEN);
     p += BD_ADDR_LEN;
-    memcpy(p, p_bcb->sent_mcast_filter_end[xx], BD_ADDR_LEN);
+    memcpy(p, p_bcb->sent_mcast_filter_end[xx].address, BD_ADDR_LEN);
     p += BD_ADDR_LEN;
   }
 
@@ -318,8 +315,8 @@
   p_bcb->con_flags |= BNEP_FLAGS_MULTI_RESP_PEND;
 
   /* Start timer waiting for setup response */
-  alarm_set_on_queue(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
-                     bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_bcb->conn_timer, BNEP_FILTER_SET_TIMEOUT_MS,
+                     bnep_conn_timer_timeout, p_bcb);
 }
 
 /*******************************************************************************
@@ -426,34 +423,33 @@
  *
  ******************************************************************************/
 void bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf, uint16_t protocol,
-                          uint8_t* p_src_addr, uint8_t* p_dest_addr,
-                          bool fw_ext_present) {
+                          const RawAddress* p_src_addr,
+                          const RawAddress* p_dest_addr, bool fw_ext_present) {
   const controller_t* controller = controller_get_interface();
-  uint8_t ext_bit, *p = (uint8_t *)NULL;
+  uint8_t ext_bit, *p = (uint8_t*)NULL;
   uint8_t type = BNEP_FRAME_COMPRESSED_ETHERNET;
 
   ext_bit = fw_ext_present ? 0x80 : 0x00;
 
-  if ((p_src_addr) &&
-      (memcmp(p_src_addr, &controller->get_address()->address, BD_ADDR_LEN)))
+  if (p_src_addr && *p_src_addr != *controller->get_address())
     type = BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY;
 
-  if (memcmp(p_dest_addr, p_bcb->rem_bda, BD_ADDR_LEN))
+  if (*p_dest_addr != p_bcb->rem_bda)
     type = (type == BNEP_FRAME_COMPRESSED_ETHERNET)
                ? BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY
                : BNEP_FRAME_GENERAL_ETHERNET;
 
-  if (!p_src_addr) p_src_addr = (uint8_t*)controller->get_address();
+  if (!p_src_addr) p_src_addr = controller->get_address();
 
   switch (type) {
     case BNEP_FRAME_GENERAL_ETHERNET:
       p = bnepu_init_hdr(p_buf, 15,
                          (uint8_t)(ext_bit | BNEP_FRAME_GENERAL_ETHERNET));
 
-      memcpy(p, p_dest_addr, BD_ADDR_LEN);
+      memcpy(p, p_dest_addr->address, BD_ADDR_LEN);
       p += BD_ADDR_LEN;
 
-      memcpy(p, p_src_addr, BD_ADDR_LEN);
+      memcpy(p, p_src_addr->address, BD_ADDR_LEN);
       p += BD_ADDR_LEN;
       break;
 
@@ -467,7 +463,7 @@
           p_buf, 9,
           (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY));
 
-      memcpy(p, p_src_addr, BD_ADDR_LEN);
+      memcpy(p, p_src_addr->address, BD_ADDR_LEN);
       p += BD_ADDR_LEN;
       break;
 
@@ -476,7 +472,7 @@
           p_buf, 9,
           (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY));
 
-      memcpy(p, p_dest_addr, BD_ADDR_LEN);
+      memcpy(p, p_dest_addr->address, BD_ADDR_LEN);
       p += BD_ADDR_LEN;
       break;
   }
@@ -1085,17 +1081,17 @@
 
   p_bcb->rcvd_mcast_filters = num_filters;
   for (xx = 0; xx < num_filters; xx++) {
-    memcpy(p_bcb->rcvd_mcast_filter_start[xx], p_filters, BD_ADDR_LEN);
-    memcpy(p_bcb->rcvd_mcast_filter_end[xx], p_filters + BD_ADDR_LEN,
+    memcpy(p_bcb->rcvd_mcast_filter_start[xx].address, p_filters, BD_ADDR_LEN);
+    memcpy(p_bcb->rcvd_mcast_filter_end[xx].address, p_filters + BD_ADDR_LEN,
            BD_ADDR_LEN);
     p_filters += (BD_ADDR_LEN * 2);
 
     /* Check if any of the ranges have all zeros as both starting and ending
      * addresses */
-    if ((memcmp(null_bda, p_bcb->rcvd_mcast_filter_start[xx], BD_ADDR_LEN) ==
-         0) &&
-        (memcmp(null_bda, p_bcb->rcvd_mcast_filter_end[xx], BD_ADDR_LEN) ==
-         0)) {
+    if ((memcmp(null_bda, p_bcb->rcvd_mcast_filter_start[xx].address,
+                BD_ADDR_LEN) == 0) &&
+        (memcmp(null_bda, p_bcb->rcvd_mcast_filter_end[xx].address,
+                BD_ADDR_LEN) == 0)) {
       p_bcb->rcvd_mcast_filters = 0xFFFF;
       break;
     }
@@ -1150,7 +1146,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void bnep_sec_check_complete(UNUSED_ATTR BD_ADDR bd_addr,
+void bnep_sec_check_complete(UNUSED_ATTR const RawAddress* bd_addr,
                              UNUSED_ATTR tBT_TRANSPORT trasnport,
                              void* p_ref_data, uint8_t result) {
   tBNEP_CONN* p_bcb = (tBNEP_CONN*)p_ref_data;
@@ -1204,8 +1200,8 @@
     p_bcb->con_state = BNEP_STATE_CONN_SETUP;
 
     bnep_send_conn_req(p_bcb);
-    alarm_set_on_queue(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
-                       bnep_conn_timer_timeout, p_bcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS,
+                       bnep_conn_timer_timeout, p_bcb);
     return;
   }
 
@@ -1254,7 +1250,8 @@
  *                  BNEP_IGNORE_CMD       - if the protocol is filtered out
  *
  ******************************************************************************/
-tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb, BD_ADDR p_dest_addr,
+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) {
   if (p_bcb->rcvd_num_filters) {
@@ -1290,17 +1287,17 @@
   }
 
   /* Ckeck for multicast address filtering */
-  if ((p_dest_addr[0] & 0x01) && p_bcb->rcvd_mcast_filters) {
+  if ((p_dest_addr.address[0] & 0x01) && p_bcb->rcvd_mcast_filters) {
     uint16_t i;
 
     /* Check if every multicast should be filtered */
     if (p_bcb->rcvd_mcast_filters != 0xFFFF) {
       /* Check if the address is mentioned in the filter range */
       for (i = 0; i < p_bcb->rcvd_mcast_filters; i++) {
-        if ((memcmp(p_bcb->rcvd_mcast_filter_start[i], p_dest_addr,
-                    BD_ADDR_LEN) <= 0) &&
-            (memcmp(p_bcb->rcvd_mcast_filter_end[i], p_dest_addr,
-                    BD_ADDR_LEN) >= 0))
+        if ((memcmp(p_bcb->rcvd_mcast_filter_start[i].address,
+                    p_dest_addr.address, BD_ADDR_LEN) <= 0) &&
+            (memcmp(p_bcb->rcvd_mcast_filter_end[i].address,
+                    p_dest_addr.address, BD_ADDR_LEN) >= 0))
           break;
       }
     }
@@ -1312,10 +1309,8 @@
     */
     if ((p_bcb->rcvd_mcast_filters == 0xFFFF) ||
         (i == p_bcb->rcvd_mcast_filters)) {
-      BNEP_TRACE_DEBUG(
-          "Ignoring multicast address %x.%x.%x.%x.%x.%x in BNEP data write",
-          p_dest_addr[0], p_dest_addr[1], p_dest_addr[2], p_dest_addr[3],
-          p_dest_addr[4], p_dest_addr[5]);
+      VLOG(1) << "Ignoring multicast address " << p_dest_addr
+              << " in BNEP data write";
       return BNEP_IGNORE_CMD;
     }
   }
diff --git a/stack/btm/ble_advertiser_hci_interface.cc b/stack/btm/ble_advertiser_hci_interface.cc
index c72b48b..b3a2f02 100644
--- a/stack/btm/ble_advertiser_hci_interface.cc
+++ b/stack/btm/ble_advertiser_hci_interface.cc
@@ -113,8 +113,8 @@
 
   void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
                      uint32_t adv_int_max, uint8_t channel_map,
-                     uint8_t own_address_type, BD_ADDR own_address,
-                     uint8_t peer_address_type, BD_ADDR peer_address,
+                     uint8_t own_address_type, const RawAddress& own_address,
+                     uint8_t peer_address_type, const RawAddress& peer_address,
                      uint8_t filter_policy, int8_t tx_power,
                      uint8_t primary_phy, uint8_t secondary_max_skip,
                      uint8_t secondary_phy, uint8_t advertising_sid,
@@ -208,7 +208,7 @@
                command_complete);
   }
 
-  void SetRandomAddress(uint8_t handle, uint8_t random_address[6],
+  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
                         status_cb command_complete) override {
     VLOG(1) << __func__;
     uint8_t param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN];
@@ -223,12 +223,18 @@
                command_complete);
   }
 
-  void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
-              uint8_t max_extended_advertising_events,
+  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
               status_cb command_complete) override {
     VLOG(1) << __func__;
 
-    if (max_extended_advertising_events) {
+    if (sets.size() != 1) {
+      LOG(ERROR) << "Trying to enable multiple sets in VSC implemenetation!";
+      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
+      return;
+    }
+    SetEnableData& set = sets[0];
+
+    if (set.max_extended_advertising_events) {
       command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
       return;
     }
@@ -239,7 +245,7 @@
     uint8_t* pp = param;
     UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_ENB);
     UINT8_TO_STREAM(pp, enable);
-    UINT8_TO_STREAM(pp, handle);
+    UINT8_TO_STREAM(pp, set.handle);
 
     SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_ENB_LEN, param,
                command_complete);
@@ -333,8 +339,9 @@
 
   void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
                      uint32_t adv_int_max, uint8_t channel_map,
-                     uint8_t own_address_type, BD_ADDR /* own_address */,
-                     uint8_t peer_address_type, BD_ADDR peer_address,
+                     uint8_t own_address_type,
+                     const RawAddress& /* own_address */,
+                     uint8_t peer_address_type, const RawAddress& peer_address,
                      uint8_t filter_policy, int8_t tx_power,
                      uint8_t primary_phy, uint8_t secondary_max_skip,
                      uint8_t secondary_phy, uint8_t advertising_sid,
@@ -424,7 +431,7 @@
                HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1, command_complete);
   }
 
-  void SetRandomAddress(uint8_t handle, uint8_t random_address[6],
+  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
                         status_cb command_complete) override {
     VLOG(1) << __func__;
 
@@ -437,12 +444,18 @@
                HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD, command_complete);
   }
 
-  void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
-              uint8_t max_extended_advertising_events,
+  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
               status_cb command_complete) override {
     VLOG(1) << __func__;
 
-    if (max_extended_advertising_events) {
+    if (sets.size() != 1) {
+      LOG(ERROR) << "Trying to enable multiple sets in legacy implemenetation!";
+      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
+      return;
+    }
+
+    SetEnableData& set = sets[0];
+    if (set.max_extended_advertising_events) {
       command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
       return;
     }
@@ -503,8 +516,9 @@
 
   void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
                      uint32_t adv_int_max, uint8_t channel_map,
-                     uint8_t own_address_type, BD_ADDR /* own_address */,
-                     uint8_t peer_address_type, BD_ADDR peer_address,
+                     uint8_t own_address_type,
+                     const RawAddress& /* own_address */,
+                     uint8_t peer_address_type, const RawAddress& peer_address,
                      uint8_t filter_policy, int8_t tx_power,
                      uint8_t primary_phy, uint8_t secondary_max_skip,
                      uint8_t secondary_phy, uint8_t advertising_sid,
@@ -580,7 +594,7 @@
                cmd_length, command_complete);
   }
 
-  void SetRandomAddress(uint8_t handle, uint8_t random_address[6],
+  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
                         status_cb command_complete) override {
     VLOG(1) << __func__;
     const int LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN = 7;
@@ -596,23 +610,24 @@
                LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN, command_complete);
   }
 
-  void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
-              uint8_t max_extended_advertising_events,
+  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
               status_cb command_complete) override {
     VLOG(1) << __func__;
 
     /* cmd_length = header_size + num_of_of_advertiser * size_per_advertiser */
-    const uint16_t cmd_length = 2 + 1 * 4;
+    const uint16_t cmd_length = 2 + sets.size() * 4;
     uint8_t param[cmd_length];
     memset(param, 0, cmd_length);
 
     uint8_t* pp = param;
     UINT8_TO_STREAM(pp, enable);
-    UINT8_TO_STREAM(pp, 0x01);  // just one set
 
-    UINT8_TO_STREAM(pp, handle);
-    UINT16_TO_STREAM(pp, duration);
-    UINT8_TO_STREAM(pp, max_extended_advertising_events);
+    UINT8_TO_STREAM(pp, sets.size());
+    for (const SetEnableData& set : sets) {
+      UINT8_TO_STREAM(pp, set.handle);
+      UINT16_TO_STREAM(pp, set.duration);
+      UINT8_TO_STREAM(pp, set.max_extended_advertising_events);
+    }
 
     SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_ENABLE, param, cmd_length,
                command_complete);
diff --git a/stack/btm/ble_advertiser_hci_interface.h b/stack/btm/ble_advertiser_hci_interface.h
index 7797ce8..166c1f6 100644
--- a/stack/btm/ble_advertiser_hci_interface.h
+++ b/stack/btm/ble_advertiser_hci_interface.h
@@ -20,6 +20,7 @@
 #define BLE_ADVERTISER_HCI_INTERFACE_H
 
 #include <base/bind.h>
+#include <vector>
 #include "stack/include/bt_types.h"
 
 /* This class is an abstraction of HCI commands used for managing
@@ -50,16 +51,14 @@
       AdvertisingEventObserver* observer) = 0;
   virtual void ReadInstanceCount(
       base::Callback<void(uint8_t /* inst_cnt*/)> cb) = 0;
-  virtual void SetParameters(uint8_t handle, uint16_t properties,
-                             uint32_t adv_int_min, uint32_t adv_int_max,
-                             uint8_t channel_map, uint8_t own_address_type,
-                             BD_ADDR own_address, uint8_t peer_address_type,
-                             BD_ADDR peer_address, uint8_t filter_policy,
-                             int8_t tx_power, uint8_t primary_phy,
-                             uint8_t secondary_max_skip, uint8_t secondary_phy,
-                             uint8_t advertising_sid,
-                             uint8_t scan_request_notify_enable,
-                             parameters_cb command_complete) = 0;
+  virtual void SetParameters(
+      uint8_t handle, uint16_t properties, uint32_t adv_int_min,
+      uint32_t adv_int_max, uint8_t channel_map, uint8_t own_address_type,
+      const RawAddress& own_address, uint8_t peer_address_type,
+      const RawAddress& peer_address, uint8_t filter_policy, int8_t tx_power,
+      uint8_t primary_phy, uint8_t secondary_max_skip, uint8_t secondary_phy,
+      uint8_t advertising_sid, uint8_t scan_request_notify_enable,
+      parameters_cb command_complete) = 0;
   virtual void SetAdvertisingData(uint8_t handle, uint8_t operation,
                                   uint8_t fragment_preference,
                                   uint8_t data_length, uint8_t* data,
@@ -69,11 +68,28 @@
                                    uint8_t scan_response_data_length,
                                    uint8_t* scan_response_data,
                                    status_cb command_complete) = 0;
-  virtual void SetRandomAddress(uint8_t handle, BD_ADDR random_address,
+  virtual void SetRandomAddress(uint8_t handle,
+                                const RawAddress& random_address,
                                 status_cb command_complete) = 0;
-  virtual void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
-                      uint8_t max_extended_advertising_events,
+
+  struct SetEnableData {
+    uint8_t handle;
+    uint16_t duration;
+    uint8_t max_extended_advertising_events;
+  };
+  virtual void Enable(uint8_t enable, std::vector<SetEnableData> sets,
                       status_cb command_complete) = 0;
+
+  void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
+              uint8_t max_extended_advertising_events,
+              status_cb command_complete) {
+    std::vector<SetEnableData> enableData;
+    enableData.emplace_back(SetEnableData{
+        .handle = handle,
+        .duration = duration,
+        .max_extended_advertising_events = max_extended_advertising_events});
+    Enable(enable, enableData, command_complete);
+  };
   virtual void SetPeriodicAdvertisingParameters(uint8_t handle,
                                                 uint16_t periodic_adv_int_min,
                                                 uint16_t periodic_adv_int_max,
diff --git a/stack/btm/btm_acl.cc b/stack/btm/btm_acl.cc
index 34041d6..70e09b5 100644
--- a/stack/btm/btm_acl.cc
+++ b/stack/btm/btm_acl.cc
@@ -51,8 +51,6 @@
 #include "l2c_int.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 static void btm_read_remote_features(uint16_t handle);
 static void btm_read_remote_ext_features(uint16_t handle, uint8_t page_number);
 static void btm_process_remote_ext_features(tACL_CONN* p_acl_cb,
@@ -92,16 +90,13 @@
  *                 NULL if not found.
  *
  ******************************************************************************/
-tACL_CONN* btm_bda_to_acl(const BD_ADDR bda, tBT_TRANSPORT transport) {
+tACL_CONN* btm_bda_to_acl(const RawAddress& bda, tBT_TRANSPORT transport) {
   tACL_CONN* p = &btm_cb.acl_db[0];
   uint16_t xx;
-  if (bda) {
-    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) {
-      if ((p->in_use) && (!memcmp(p->remote_addr, bda, BD_ADDR_LEN)) &&
-          p->transport == transport) {
-        BTM_TRACE_DEBUG("btm_bda_to_acl found");
-        return (p);
-      }
+  for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) {
+    if ((p->in_use) && p->remote_addr == bda && p->transport == transport) {
+      BTM_TRACE_DEBUG("btm_bda_to_acl found");
+      return (p);
     }
   }
 
@@ -144,30 +139,29 @@
  * Returns          success return true, otherwise false.
  *
  ******************************************************************************/
-bool btm_ble_get_acl_remote_addr(tBTM_SEC_DEV_REC* p_dev_rec, BD_ADDR conn_addr,
+bool btm_ble_get_acl_remote_addr(tBTM_SEC_DEV_REC* p_dev_rec,
+                                 RawAddress& conn_addr,
                                  tBLE_ADDR_TYPE* p_addr_type) {
   bool st = true;
 
   if (p_dev_rec == NULL) {
-    BTM_TRACE_ERROR(
-        "btm_ble_get_acl_remote_addr can not find device with matching "
-        "address");
+    BTM_TRACE_ERROR("%s can not find device with matching address", __func__);
     return false;
   }
 
   switch (p_dev_rec->ble.active_addr_type) {
     case BTM_BLE_ADDR_PSEUDO:
-      memcpy(conn_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
+      conn_addr = p_dev_rec->bd_addr;
       *p_addr_type = p_dev_rec->ble.ble_addr_type;
       break;
 
     case BTM_BLE_ADDR_RRA:
-      memcpy(conn_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
+      conn_addr = p_dev_rec->ble.cur_rand_addr;
       *p_addr_type = BLE_ADDR_RANDOM;
       break;
 
     case BTM_BLE_ADDR_STATIC:
-      memcpy(conn_addr, p_dev_rec->ble.static_addr, BD_ADDR_LEN);
+      conn_addr = p_dev_rec->ble.static_addr;
       *p_addr_type = p_dev_rec->ble.static_addr_type;
       break;
 
@@ -191,7 +185,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_acl_created(BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
+void btm_acl_created(const RawAddress& bda, DEV_CLASS dc, BD_NAME bdn,
                      uint16_t hci_handle, uint8_t link_role,
                      tBT_TRANSPORT transport) {
   tBTM_SEC_DEV_REC* p_dev_rec = NULL;
@@ -206,9 +200,7 @@
     p->hci_handle = hci_handle;
     p->link_role = link_role;
     p->transport = transport;
-    BTM_TRACE_DEBUG(
-        "Duplicate btm_acl_created: RemBdAddr: %02x%02x%02x%02x%02x%02x",
-        bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+    VLOG(1) << "Duplicate btm_acl_created: RemBdAddr: " << bda;
     BTM_SetLinkPolicy(p->remote_addr, &btm_cb.btm_def_link_policy);
     return;
   }
@@ -220,7 +212,7 @@
       p->hci_handle = hci_handle;
       p->link_role = link_role;
       p->link_up_issued = false;
-      memcpy(p->remote_addr, bda, BD_ADDR_LEN);
+      p->remote_addr = bda;
 
       p->transport = transport;
 #if (BLE_PRIVACY_SPT == TRUE)
@@ -229,8 +221,7 @@
             bda, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr);
 #else
       p->conn_addr_type = BLE_ADDR_PUBLIC;
-      memcpy(p->conn_addr, &controller_get_interface()->get_address()->address,
-             BD_ADDR_LEN);
+      p->conn_addr = *controller_get_interface()->get_address();
 
 #endif
       p->switch_role_failed_attempts = 0;
@@ -270,7 +261,7 @@
           BTM_TRACE_API("%s: pend:%d", __func__, req_pend);
           if (req_pend) {
             /* Request for remaining Security Features (if any) */
-            l2cu_resubmit_pending_sec_req(p_dev_rec->bd_addr);
+            l2cu_resubmit_pending_sec_req(&p_dev_rec->bd_addr);
           }
           btm_establish_continue(p);
           return;
@@ -301,10 +292,10 @@
   }
 }
 
-void btm_acl_update_conn_addr(uint8_t conn_handle, BD_ADDR address) {
+void btm_acl_update_conn_addr(uint16_t conn_handle, const RawAddress& address) {
   uint8_t idx = btm_handle_to_acl_index(conn_handle);
   if (idx != MAX_L2CAP_LINKS) {
-    memcpy(btm_cb.acl_db[idx].conn_addr, address, BD_ADDR_LEN);
+    btm_cb.acl_db[idx].conn_addr = address;
   }
 }
 
@@ -318,12 +309,11 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_acl_report_role_change(uint8_t hci_status, BD_ADDR bda) {
+void btm_acl_report_role_change(uint8_t hci_status, const RawAddress* bda) {
   tBTM_ROLE_SWITCH_CMPL ref_data;
   BTM_TRACE_DEBUG("btm_acl_report_role_change");
   if (btm_cb.devcb.p_switch_role_cb &&
-      (bda && (0 == memcmp(btm_cb.devcb.switch_role_ref_data.remote_bd_addr,
-                           bda, BD_ADDR_LEN)))) {
+      (bda && btm_cb.devcb.switch_role_ref_data.remote_bd_addr == *bda)) {
     memcpy(&ref_data, &btm_cb.devcb.switch_role_ref_data,
            sizeof(tBTM_ROLE_SWITCH_CMPL));
     ref_data.hci_status = hci_status;
@@ -345,9 +335,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_acl_removed(BD_ADDR bda, tBT_TRANSPORT transport) {
+void btm_acl_removed(const RawAddress& bda, tBT_TRANSPORT transport) {
   tACL_CONN* p;
-  tBTM_BL_EVENT_DATA evt_data;
   tBTM_SEC_DEV_REC* p_dev_rec = NULL;
   BTM_TRACE_DEBUG("btm_acl_removed");
   p = btm_bda_to_acl(bda, transport);
@@ -355,7 +344,7 @@
     p->in_use = false;
 
     /* if the disconnected channel has a pending role switch, clear it now */
-    btm_acl_report_role_change(HCI_ERR_NO_CONNECTION, bda);
+    btm_acl_report_role_change(HCI_ERR_NO_CONNECTION, &bda);
 
     /* Only notify if link up has had a chance to be issued */
     if (p->link_up_issued) {
@@ -363,8 +352,9 @@
 
       /* If anyone cares, tell him database changed */
       if (btm_cb.p_bl_changed_cb) {
+        tBTM_BL_EVENT_DATA evt_data;
         evt_data.event = BTM_BL_DISCN_EVT;
-        evt_data.discn.p_bda = bda;
+        evt_data.discn.p_bda = &bda;
         evt_data.discn.handle = p->hci_handle;
         evt_data.discn.transport = p->transport;
         (*btm_cb.p_bl_changed_cb)(&evt_data);
@@ -490,7 +480,9 @@
     evt.busy_level = busy_level;
     btm_cb.busy_level = busy_level;
     if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_UPDATE_MASK)) {
-      (*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA*)&evt);
+      tBTM_BL_EVENT_DATA btm_bl_event_data;
+      btm_bl_event_data.update = evt;
+      (*btm_cb.p_bl_changed_cb)(&btm_bl_event_data);
     }
   }
 }
@@ -506,7 +498,7 @@
  *                  BTM_UNKNOWN_ADDR if no active link with bd addr specified
  *
  ******************************************************************************/
-tBTM_STATUS BTM_GetRole(BD_ADDR remote_bd_addr, uint8_t* p_role) {
+tBTM_STATUS BTM_GetRole(const RawAddress& remote_bd_addr, uint8_t* p_role) {
   tACL_CONN* p;
   BTM_TRACE_DEBUG("BTM_GetRole");
   p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR);
@@ -539,7 +531,7 @@
  *                  BTM_BUSY if the previous command is not completed
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SwitchRole(BD_ADDR remote_bd_addr, uint8_t new_role,
+tBTM_STATUS BTM_SwitchRole(const RawAddress& remote_bd_addr, uint8_t new_role,
                            tBTM_CMPL_CB* p_cb) {
   tACL_CONN* p;
   tBTM_SEC_DEV_REC* p_dev_rec = NULL;
@@ -549,20 +541,15 @@
   tBTM_STATUS status;
   tBTM_PM_MODE pwr_mode;
   tBTM_PM_PWR_MD settings;
-  BD_ADDR_PTR p_bda;
-  BTM_TRACE_API("BTM_SwitchRole BDA: %02x-%02x-%02x-%02x-%02x-%02x",
-                remote_bd_addr[0], remote_bd_addr[1], remote_bd_addr[2],
-                remote_bd_addr[3], remote_bd_addr[4], remote_bd_addr[5]);
+  VLOG(1) << __func__ << " BDA: " << remote_bd_addr;
 
   /* Make sure the local device supports switching */
   if (!controller_get_interface()->supports_master_slave_role_switch())
     return (BTM_MODE_UNSUPPORTED);
 
   if (btm_cb.devcb.p_switch_role_cb && p_cb) {
-    p_bda = btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
-    BTM_TRACE_DEBUG(
-        "Role switch on other device is in progress 0x%02x%02x%02x%02x%02x%02x",
-        p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
+    VLOG(2) << "Role switch on other device is in progress "
+            << btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
     return (BTM_BUSY);
   }
 
@@ -572,10 +559,8 @@
   /* Finished if already in desired role */
   if (p->link_role == new_role) return (BTM_SUCCESS);
 
-  if (interop_match_addr(INTEROP_DISABLE_ROLE_SWITCH,
-                         (const bt_bdaddr_t*)&remote_bd_addr)) {
+  if (interop_match_addr(INTEROP_DISABLE_ROLE_SWITCH, &remote_bd_addr))
     return BTM_DEV_BLACKLISTED;
-  }
 
 #if (BTM_SCO_INCLUDED == TRUE)
   /* Check if there is any SCO Active on this BD Address */
@@ -590,8 +575,7 @@
     return (BTM_BUSY);
   }
 
-  if (interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH,
-                         (const bt_bdaddr_t*)&remote_bd_addr)) {
+  if (interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH, &remote_bd_addr)) {
     BTM_TRACE_DEBUG("%s, Device blacklisted under INTEROP_DYNAMIC_ROLE_SWITCH.",
                     __func__);
     return BTM_DEV_BLACKLISTED;
@@ -634,8 +618,7 @@
 
   /* Initialize return structure in case request fails */
   if (p_cb) {
-    memcpy(btm_cb.devcb.switch_role_ref_data.remote_bd_addr, remote_bd_addr,
-           BD_ADDR_LEN);
+    btm_cb.devcb.switch_role_ref_data.remote_bd_addr = remote_bd_addr;
     btm_cb.devcb.switch_role_ref_data.role = new_role;
     /* initialized to an error code */
     btm_cb.devcb.switch_role_ref_data.hci_status = HCI_ERR_UNSUPPORTED_VALUE;
@@ -661,7 +644,6 @@
   tACL_CONN* p;
   uint8_t xx;
   tBTM_SEC_DEV_REC* p_dev_rec;
-  tBTM_BL_ROLE_CHG_DATA evt;
 
   BTM_TRACE_DEBUG("btm_acl_encrypt_change handle=%d status=%d encr_enabl=%d",
                   handle, status, encr_enable);
@@ -695,15 +677,18 @@
     p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
     p->encrypt_state = BTM_ACL_ENCRYPT_STATE_IDLE;
     btm_acl_report_role_change(btm_cb.devcb.switch_role_ref_data.hci_status,
-                               p->remote_addr);
+                               &p->remote_addr);
 
     /* if role change event is registered, report it now */
     if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_ROLE_CHG_MASK)) {
+      tBTM_BL_ROLE_CHG_DATA evt;
       evt.event = BTM_BL_ROLE_CHG_EVT;
       evt.new_role = btm_cb.devcb.switch_role_ref_data.role;
-      evt.p_bda = btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
+      evt.p_bda = &btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
       evt.hci_status = btm_cb.devcb.switch_role_ref_data.hci_status;
-      (*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA*)&evt);
+      tBTM_BL_EVENT_DATA btm_bl_event_data;
+      btm_bl_event_data.role_chg = evt;
+      (*btm_cb.p_bl_changed_cb)(&btm_bl_event_data);
 
       BTM_TRACE_DEBUG(
           "Role Switch Event: new_role 0x%02x, HCI Status 0x%02x, rs_st:%d",
@@ -737,7 +722,8 @@
  * Returns          status of the operation
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SetLinkPolicy(BD_ADDR remote_bda, uint16_t* settings) {
+tBTM_STATUS BTM_SetLinkPolicy(const RawAddress& remote_bda,
+                              uint16_t* settings) {
   tACL_CONN* p;
   uint8_t* localFeatures = BTM_ReadLocalFeatures();
   BTM_TRACE_DEBUG("%s", __func__);
@@ -832,7 +818,7 @@
   btsnd_hcic_write_def_policy_set(settings);
 }
 
-void btm_use_preferred_conn_params(BD_ADDR bda) {
+void btm_use_preferred_conn_params(const RawAddress& bda) {
   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda);
 
@@ -954,7 +940,7 @@
   BTM_TRACE_API("%s: pend:%d", __func__, req_pend);
   if (req_pend) {
     /* Request for remaining Security Features (if any) */
-    l2cu_resubmit_pending_sec_req(p_dev_rec->bd_addr);
+    l2cu_resubmit_pending_sec_req(&p_dev_rec->bd_addr);
   }
 }
 
@@ -1216,7 +1202,7 @@
   /* If anyone cares, tell him database changed */
   if (btm_cb.p_bl_changed_cb) {
     evt_data.event = BTM_BL_CONN_EVT;
-    evt_data.conn.p_bda = p_acl_cb->remote_addr;
+    evt_data.conn.p_bda = &p_acl_cb->remote_addr;
     evt_data.conn.p_bdn = p_acl_cb->remote_name;
     evt_data.conn.p_dc = p_acl_cb->remote_dc;
     evt_data.conn.p_features = p_acl_cb->peer_lmp_feature_pages[0];
@@ -1253,7 +1239,8 @@
  * Returns          status of the operation
  *
  ******************************************************************************/
-tBTM_STATUS BTM_GetLinkSuperTout(BD_ADDR remote_bda, uint16_t* p_timeout) {
+tBTM_STATUS BTM_GetLinkSuperTout(const RawAddress& remote_bda,
+                                 uint16_t* p_timeout) {
   tACL_CONN* p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
 
   BTM_TRACE_DEBUG("BTM_GetLinkSuperTout");
@@ -1274,7 +1261,8 @@
  * Returns          status of the operation
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SetLinkSuperTout(BD_ADDR remote_bda, uint16_t timeout) {
+tBTM_STATUS BTM_SetLinkSuperTout(const RawAddress& remote_bda,
+                                 uint16_t timeout) {
   tACL_CONN* p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
 
   BTM_TRACE_DEBUG("BTM_SetLinkSuperTout");
@@ -1286,8 +1274,9 @@
       btsnd_hcic_write_link_super_tout(LOCAL_BR_EDR_CONTROLLER_ID,
                                        p->hci_handle, timeout);
       return (BTM_CMD_STARTED);
-    } else
+    } else {
       return (BTM_SUCCESS);
+    }
   }
 
   /* If here, no BD Addr found */
@@ -1304,12 +1293,11 @@
  * Returns          true if connection is up, else false.
  *
  ******************************************************************************/
-bool BTM_IsAclConnectionUp(BD_ADDR remote_bda, tBT_TRANSPORT transport) {
+bool BTM_IsAclConnectionUp(const RawAddress& remote_bda,
+                           tBT_TRANSPORT transport) {
   tACL_CONN* p;
 
-  BTM_TRACE_API("BTM_IsAclConnectionUp: RemBdAddr: %02x%02x%02x%02x%02x%02x",
-                remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3],
-                remote_bda[4], remote_bda[5]);
+  VLOG(2) << __func__ << " RemBdAddr: " << remote_bda;
 
   p = btm_bda_to_acl(remote_bda, transport);
   if (p != (tACL_CONN*)NULL) {
@@ -1366,7 +1354,7 @@
  * Returns          the handle of the connection, or 0xFFFF if none.
  *
  ******************************************************************************/
-uint16_t BTM_GetHCIConnHandle(const BD_ADDR remote_bda,
+uint16_t BTM_GetHCIConnHandle(const RawAddress& remote_bda,
                               tBT_TRANSPORT transport) {
   tACL_CONN* p;
   BTM_TRACE_DEBUG("BTM_GetHCIConnHandle");
@@ -1413,7 +1401,8 @@
 * Returns          void
 *
 *******************************************************************************/
-void btm_blacklist_role_change_device(BD_ADDR bd_addr, uint8_t hci_status) {
+void btm_blacklist_role_change_device(const RawAddress& bd_addr,
+                                      uint8_t hci_status) {
   tACL_CONN* p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR);
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
 
@@ -1436,17 +1425,14 @@
       ((p->switch_role_state == BTM_ACL_SWKEY_STATE_SWITCHING) ||
        (p->switch_role_state == BTM_ACL_SWKEY_STATE_IN_PROGRESS)) &&
       ((cod & cod_audio_device) == cod_audio_device) &&
-      (!interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH,
-                           (const bt_bdaddr_t*)&bd_addr))) {
+      (!interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH, &bd_addr))) {
     p->switch_role_failed_attempts++;
     if (p->switch_role_failed_attempts == BTM_MAX_SW_ROLE_FAILED_ATTEMPTS) {
       BTM_TRACE_WARNING(
-          "%s: Device %02x:%02x:%02x:%02x:%02x:%02x blacklisted for role "
-          "switching - multiple role switch failed attempts: %u",
-          __func__, bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-          bd_addr[5], p->switch_role_failed_attempts);
-      interop_database_add(INTEROP_DYNAMIC_ROLE_SWITCH,
-                           (const bt_bdaddr_t*)&bd_addr, 3);
+          "%s: Device %s blacklisted for role switching - "
+          "multiple role switch failed attempts: %u",
+          __func__, bd_addr.ToString().c_str(), p->switch_role_failed_attempts);
+      interop_database_add(INTEROP_DYNAMIC_ROLE_SWITCH, &bd_addr, 3);
     }
   }
 }
@@ -1463,14 +1449,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_acl_role_changed(uint8_t hci_status, BD_ADDR bd_addr,
+void btm_acl_role_changed(uint8_t hci_status, const RawAddress* bd_addr,
                           uint8_t new_role) {
-  uint8_t* p_bda =
-      (bd_addr) ? bd_addr : btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
-  tACL_CONN* p = btm_bda_to_acl(p_bda, BT_TRANSPORT_BR_EDR);
+  const RawAddress* p_bda =
+      (bd_addr) ? bd_addr : &btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
+  tACL_CONN* p = btm_bda_to_acl(*p_bda, BT_TRANSPORT_BR_EDR);
   tBTM_ROLE_SWITCH_CMPL* p_data = &btm_cb.devcb.switch_role_ref_data;
   tBTM_SEC_DEV_REC* p_dev_rec;
-  tBTM_BL_ROLE_CHG_DATA evt;
 
   BTM_TRACE_DEBUG("btm_acl_role_changed");
   /* Ignore any stray events */
@@ -1485,7 +1470,7 @@
 
   if (hci_status == HCI_SUCCESS) {
     p_data->role = new_role;
-    memcpy(p_data->remote_bd_addr, p_bda, BD_ADDR_LEN);
+    p_data->remote_bd_addr = *p_bda;
 
     /* Update cached value */
     p->link_role = new_role;
@@ -1524,11 +1509,14 @@
 
   /* if role change event is registered, report it now */
   if (btm_cb.p_bl_changed_cb && (btm_cb.bl_evt_mask & BTM_BL_ROLE_CHG_MASK)) {
+    tBTM_BL_ROLE_CHG_DATA evt;
     evt.event = BTM_BL_ROLE_CHG_EVT;
     evt.new_role = new_role;
     evt.p_bda = p_bda;
     evt.hci_status = hci_status;
-    (*btm_cb.p_bl_changed_cb)((tBTM_BL_EVENT_DATA*)&evt);
+    tBTM_BL_EVENT_DATA btm_bl_event_data;
+    btm_bl_event_data.role_chg = evt;
+    (*btm_cb.p_bl_changed_cb)(&btm_bl_event_data);
   }
 
   BTM_TRACE_DEBUG(
@@ -1537,7 +1525,7 @@
 
 #if (BTM_DISC_DURING_RS == TRUE)
   /* If a disconnect is pending, issue it now that role switch has completed */
-  p_dev_rec = btm_find_dev(p_bda);
+  p_dev_rec = btm_find_dev(*p_bda);
   if (p_dev_rec != NULL) {
     if (p_dev_rec->rs_disc_pending == BTM_SEC_DISC_PENDING) {
       BTM_TRACE_WARNING(
@@ -1616,8 +1604,9 @@
   if (scn <= BTM_MAX_SCN) {
     btm_cb.btm_scn[scn - 1] = false;
     return (true);
-  } else
+  } else {
     return (false); /* Illegal SCN passed in */
+  }
 }
 
 /*******************************************************************************
@@ -1662,7 +1651,7 @@
  *                  connection, 0 if connection is not established
  *
  ******************************************************************************/
-uint16_t btm_get_max_packet_size(BD_ADDR addr) {
+uint16_t btm_get_max_packet_size(const RawAddress& addr) {
   tACL_CONN* p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
   uint16_t pkt_types = 0;
   uint16_t pkt_size = 0;
@@ -1671,8 +1660,7 @@
     pkt_types = p->pkt_types_mask;
   } else {
     /* Special case for when info for the local device is requested */
-    if (memcmp(controller_get_interface()->get_address(), addr, BD_ADDR_LEN) ==
-        0) {
+    if (addr == *controller_get_interface()->get_address()) {
       pkt_types = btm_cb.btm_acl_pkt_types_supported;
     }
   }
@@ -1714,7 +1702,7 @@
  * Returns          If connected report peer device info
  *
  ******************************************************************************/
-tBTM_STATUS BTM_ReadRemoteVersion(BD_ADDR addr, uint8_t* lmp_version,
+tBTM_STATUS BTM_ReadRemoteVersion(const RawAddress& addr, uint8_t* lmp_version,
                                   uint16_t* manufacturer,
                                   uint16_t* lmp_sub_version) {
   tACL_CONN* p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
@@ -1737,7 +1725,7 @@
  * Returns          pointer to the remote supported features mask (8 bytes)
  *
  ******************************************************************************/
-uint8_t* BTM_ReadRemoteFeatures(BD_ADDR addr) {
+uint8_t* BTM_ReadRemoteFeatures(const RawAddress& addr) {
   tACL_CONN* p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
   BTM_TRACE_DEBUG("BTM_ReadRemoteFeatures");
   if (p == NULL) {
@@ -1755,7 +1743,8 @@
  *                  or NULL if bad page
  *
  ******************************************************************************/
-uint8_t* BTM_ReadRemoteExtendedFeatures(BD_ADDR addr, uint8_t page_number) {
+uint8_t* BTM_ReadRemoteExtendedFeatures(const RawAddress& addr,
+                                        uint8_t page_number) {
   tACL_CONN* p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
   BTM_TRACE_DEBUG("BTM_ReadRemoteExtendedFeatures");
   if (p == NULL) {
@@ -1778,7 +1767,7 @@
  * Returns          number of features pages read from the remote device.
  *
  ******************************************************************************/
-uint8_t BTM_ReadNumberRemoteFeaturesPages(BD_ADDR addr) {
+uint8_t BTM_ReadNumberRemoteFeaturesPages(const RawAddress& addr) {
   tACL_CONN* p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
   BTM_TRACE_DEBUG("BTM_ReadNumberRemoteFeaturesPages");
   if (p == NULL) {
@@ -1795,7 +1784,7 @@
  * Returns          pointer to all features of the remote (24 bytes).
  *
  ******************************************************************************/
-uint8_t* BTM_ReadAllRemoteFeatures(BD_ADDR addr) {
+uint8_t* BTM_ReadAllRemoteFeatures(const RawAddress& addr) {
   tACL_CONN* p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
   BTM_TRACE_DEBUG("BTM_ReadAllRemoteFeatures");
   if (p == NULL) {
@@ -1841,11 +1830,11 @@
  * Returns          status of the operation
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SetQoS(BD_ADDR bd, FLOW_SPEC* p_flow, tBTM_CMPL_CB* p_cb) {
+tBTM_STATUS BTM_SetQoS(const RawAddress& bd, FLOW_SPEC* p_flow,
+                       tBTM_CMPL_CB* p_cb) {
   tACL_CONN* p = &btm_cb.acl_db[0];
 
-  BTM_TRACE_API("BTM_SetQoS: BdAddr: %02x%02x%02x%02x%02x%02x", bd[0], bd[1],
-                bd[2], bd[3], bd[4], bd[5]);
+  VLOG(2) << __func__ << " BdAddr: " << bd;
 
   /* If someone already waiting on the version, do not allow another */
   if (btm_cb.devcb.p_qos_setup_cmpl_cb) return (BTM_BUSY);
@@ -1853,8 +1842,8 @@
   p = btm_bda_to_acl(bd, BT_TRANSPORT_BR_EDR);
   if (p != NULL) {
     btm_cb.devcb.p_qos_setup_cmpl_cb = p_cb;
-    alarm_set_on_queue(btm_cb.devcb.qos_setup_timer, BTM_DEV_REPLY_TIMEOUT_MS,
-                       btm_qos_setup_timeout, NULL, btu_general_alarm_queue);
+    alarm_set_on_mloop(btm_cb.devcb.qos_setup_timer, BTM_DEV_REPLY_TIMEOUT_MS,
+                       btm_qos_setup_timeout, NULL);
 
     btsnd_hcic_qos_setup(p->hci_handle, p_flow->qos_flags, p_flow->service_type,
                          p_flow->token_rate, p_flow->peak_bandwidth,
@@ -1926,19 +1915,16 @@
  * Description      This function is called to read the link policy settings.
  *                  The address of link policy results are returned in the
  *                  callback.
- *                  (tBTM_RSSI_RESULTS)
+ *                  (tBTM_RSSI_RESULT)
  *
  * Returns          BTM_CMD_STARTED if successfully initiated or error code
  *
  ******************************************************************************/
-tBTM_STATUS BTM_ReadRSSI(const BD_ADDR remote_bda, tBTM_CMPL_CB* p_cb) {
+tBTM_STATUS BTM_ReadRSSI(const RawAddress& remote_bda, tBTM_CMPL_CB* p_cb) {
   tACL_CONN* p;
   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
   tBT_DEVICE_TYPE dev_type;
   tBLE_ADDR_TYPE addr_type;
-  BTM_TRACE_API("BTM_ReadRSSI: RemBdAddr: %02x%02x%02x%02x%02x%02x",
-                remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3],
-                remote_bda[4], remote_bda[5]);
 
   /* If someone already waiting on the version, do not allow another */
   if (btm_cb.devcb.p_rssi_cmpl_cb) return (BTM_BUSY);
@@ -1949,8 +1935,8 @@
   p = btm_bda_to_acl(remote_bda, transport);
   if (p != (tACL_CONN*)NULL) {
     btm_cb.devcb.p_rssi_cmpl_cb = p_cb;
-    alarm_set_on_queue(btm_cb.devcb.read_rssi_timer, BTM_DEV_REPLY_TIMEOUT_MS,
-                       btm_read_rssi_timeout, NULL, btu_general_alarm_queue);
+    alarm_set_on_mloop(btm_cb.devcb.read_rssi_timer, BTM_DEV_REPLY_TIMEOUT_MS,
+                       btm_read_rssi_timeout, NULL);
 
     btsnd_hcic_read_rssi(p->hci_handle);
     return (BTM_CMD_STARTED);
@@ -1962,31 +1948,103 @@
 
 /*******************************************************************************
  *
- * Function         BTM_ReadLinkQuality
+ * Function         BTM_ReadFailedContactCounter
  *
- * Description      This function is called to read the link qulaity.
- *                  The value of the link quality is returned in the callback.
- *                  (tBTM_LINK_QUALITY_RESULTS)
+ * Description      This function is called to read the failed contact counter.
+ *                  The result is returned in the callback.
+ *                  (tBTM_FAILED_CONTACT_COUNTER_RESULT)
  *
  * Returns          BTM_CMD_STARTED if successfully initiated or error code
  *
  ******************************************************************************/
-tBTM_STATUS BTM_ReadLinkQuality(BD_ADDR remote_bda, tBTM_CMPL_CB* p_cb) {
+tBTM_STATUS BTM_ReadFailedContactCounter(const RawAddress& remote_bda,
+                                         tBTM_CMPL_CB* p_cb) {
   tACL_CONN* p;
+  tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+  tBT_DEVICE_TYPE dev_type;
+  tBLE_ADDR_TYPE addr_type;
 
-  BTM_TRACE_API("BTM_ReadLinkQuality: RemBdAddr: %02x%02x%02x%02x%02x%02x",
-                remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3],
-                remote_bda[4], remote_bda[5]);
+  /* If someone already waiting on the result, do not allow another */
+  if (btm_cb.devcb.p_failed_contact_counter_cmpl_cb) return (BTM_BUSY);
+
+  BTM_ReadDevInfo(remote_bda, &dev_type, &addr_type);
+  if (dev_type == BT_DEVICE_TYPE_BLE) transport = BT_TRANSPORT_LE;
+
+  p = btm_bda_to_acl(remote_bda, transport);
+  if (p != (tACL_CONN*)NULL) {
+    btm_cb.devcb.p_failed_contact_counter_cmpl_cb = p_cb;
+    alarm_set_on_mloop(btm_cb.devcb.read_failed_contact_counter_timer,
+                       BTM_DEV_REPLY_TIMEOUT_MS,
+                       btm_read_failed_contact_counter_timeout, NULL);
+
+    btsnd_hcic_read_failed_contact_counter(p->hci_handle);
+    return (BTM_CMD_STARTED);
+  }
+
+  /* If here, no BD Addr found */
+  return (BTM_UNKNOWN_ADDR);
+}
+
+/*******************************************************************************
+ *
+ * Function         BTM_ReadAutomaticFlushTimeout
+ *
+ * Description      This function is called to read the automatic flush timeout.
+ *                  The result is returned in the callback.
+ *                  (tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT)
+ *
+ * Returns          BTM_CMD_STARTED if successfully initiated or error code
+ *
+ ******************************************************************************/
+tBTM_STATUS BTM_ReadAutomaticFlushTimeout(const RawAddress& remote_bda,
+                                          tBTM_CMPL_CB* p_cb) {
+  tACL_CONN* p;
+  tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+  tBT_DEVICE_TYPE dev_type;
+  tBLE_ADDR_TYPE addr_type;
+
+  /* If someone already waiting on the result, do not allow another */
+  if (btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb) return (BTM_BUSY);
+
+  BTM_ReadDevInfo(remote_bda, &dev_type, &addr_type);
+  if (dev_type == BT_DEVICE_TYPE_BLE) transport = BT_TRANSPORT_LE;
+
+  p = btm_bda_to_acl(remote_bda, transport);
+  if (!p) return BTM_UNKNOWN_ADDR;
+
+  btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb = p_cb;
+  alarm_set_on_mloop(btm_cb.devcb.read_automatic_flush_timeout_timer,
+                     BTM_DEV_REPLY_TIMEOUT_MS,
+                     btm_read_automatic_flush_timeout_timeout, nullptr);
+
+  btsnd_hcic_read_automatic_flush_timeout(p->hci_handle);
+  return BTM_CMD_STARTED;
+}
+
+/*******************************************************************************
+ *
+ * Function         BTM_ReadLinkQuality
+ *
+ * Description      This function is called to read the link qulaity.
+ *                  The value of the link quality is returned in the callback.
+ *                  (tBTM_LINK_QUALITY_RESULT)
+ *
+ * Returns          BTM_CMD_STARTED if successfully initiated or error code
+ *
+ ******************************************************************************/
+tBTM_STATUS BTM_ReadLinkQuality(const RawAddress& remote_bda,
+                                tBTM_CMPL_CB* p_cb) {
+  VLOG(2) << __func__ << ": RemBdAddr: " << remote_bda;
 
   /* If someone already waiting on the version, do not allow another */
   if (btm_cb.devcb.p_link_qual_cmpl_cb) return (BTM_BUSY);
 
-  p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
+  tACL_CONN* p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
   if (p != (tACL_CONN*)NULL) {
     btm_cb.devcb.p_link_qual_cmpl_cb = p_cb;
-    alarm_set_on_queue(btm_cb.devcb.read_link_quality_timer,
+    alarm_set_on_mloop(btm_cb.devcb.read_link_quality_timer,
                        BTM_DEV_REPLY_TIMEOUT_MS, btm_read_link_quality_timeout,
-                       NULL, btu_general_alarm_queue);
+                       NULL);
 
     btsnd_hcic_get_link_quality(p->hci_handle);
     return (BTM_CMD_STARTED);
@@ -2003,20 +2061,18 @@
  * Description      This function is called to read the current
  *                  TX power of the connection. The tx power level results
  *                  are returned in the callback.
- *                  (tBTM_RSSI_RESULTS)
+ *                  (tBTM_RSSI_RESULT)
  *
  * Returns          BTM_CMD_STARTED if successfully initiated or error code
  *
  ******************************************************************************/
-tBTM_STATUS BTM_ReadTxPower(BD_ADDR remote_bda, tBT_TRANSPORT transport,
-                            tBTM_CMPL_CB* p_cb) {
+tBTM_STATUS BTM_ReadTxPower(const RawAddress& remote_bda,
+                            tBT_TRANSPORT transport, tBTM_CMPL_CB* p_cb) {
   tACL_CONN* p;
 #define BTM_READ_RSSI_TYPE_CUR 0x00
 #define BTM_READ_RSSI_TYPE_MAX 0X01
 
-  BTM_TRACE_API("BTM_ReadTxPower: RemBdAddr: %02x%02x%02x%02x%02x%02x",
-                remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3],
-                remote_bda[4], remote_bda[5]);
+  VLOG(2) << __func__ << ": RemBdAddr: " << remote_bda;
 
   /* If someone already waiting on the version, do not allow another */
   if (btm_cb.devcb.p_tx_power_cmpl_cb) return (BTM_BUSY);
@@ -2024,12 +2080,12 @@
   p = btm_bda_to_acl(remote_bda, transport);
   if (p != (tACL_CONN*)NULL) {
     btm_cb.devcb.p_tx_power_cmpl_cb = p_cb;
-    alarm_set_on_queue(btm_cb.devcb.read_tx_power_timer,
+    alarm_set_on_mloop(btm_cb.devcb.read_tx_power_timer,
                        BTM_DEV_REPLY_TIMEOUT_MS, btm_read_tx_power_timeout,
-                       NULL, btu_general_alarm_queue);
+                       NULL);
 
     if (p->transport == BT_TRANSPORT_LE) {
-      memcpy(btm_cb.devcb.read_tx_pwr_addr, remote_bda, BD_ADDR_LEN);
+      btm_cb.devcb.read_tx_pwr_addr = remote_bda;
       btsnd_hcic_ble_read_adv_chnl_tx_power();
     } else {
       btsnd_hcic_read_tx_power(p->hci_handle, BTM_READ_RSSI_TYPE_CUR);
@@ -2069,10 +2125,8 @@
  ******************************************************************************/
 void btm_read_tx_power_complete(uint8_t* p, bool is_ble) {
   tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_tx_power_cmpl_cb;
-  tBTM_TX_POWER_RESULTS results;
-  uint16_t handle;
+  tBTM_TX_POWER_RESULT result;
   tACL_CONN* p_acl_cb = &btm_cb.acl_db[0];
-  uint16_t index;
 
   BTM_TRACE_DEBUG("%s", __func__);
   alarm_cancel(btm_cb.devcb.read_tx_power_timer);
@@ -2080,32 +2134,34 @@
 
   /* If there was a registered callback, call it */
   if (p_cb) {
-    STREAM_TO_UINT8(results.hci_status, p);
+    STREAM_TO_UINT8(result.hci_status, p);
 
-    if (results.hci_status == HCI_SUCCESS) {
-      results.status = BTM_SUCCESS;
+    if (result.hci_status == HCI_SUCCESS) {
+      result.status = BTM_SUCCESS;
 
       if (!is_ble) {
+        uint16_t handle;
         STREAM_TO_UINT16(handle, p);
-        STREAM_TO_UINT8(results.tx_power, p);
+        STREAM_TO_UINT8(result.tx_power, p);
 
         /* Search through the list of active channels for the correct BD Addr */
-        for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) {
+        for (uint16_t index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) {
           if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle)) {
-            memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
+            result.rem_bda = p_acl_cb->remote_addr;
             break;
           }
         }
       } else {
-        STREAM_TO_UINT8(results.tx_power, p);
-        memcpy(results.rem_bda, btm_cb.devcb.read_tx_pwr_addr, BD_ADDR_LEN);
+        STREAM_TO_UINT8(result.tx_power, p);
+        result.rem_bda = btm_cb.devcb.read_tx_pwr_addr;
       }
       BTM_TRACE_DEBUG("BTM TX power Complete: tx_power %d, hci status 0x%02x",
-                      results.tx_power, results.hci_status);
-    } else
-      results.status = BTM_ERR_PROCESSING;
+                      result.tx_power, result.hci_status);
+    } else {
+      result.status = BTM_ERR_PROCESSING;
+    }
 
-    (*p_cb)(&results);
+    (*p_cb)(&result);
   }
 }
 
@@ -2119,12 +2175,11 @@
  *
  ******************************************************************************/
 void btm_read_rssi_timeout(UNUSED_ATTR void* data) {
-  tBTM_RSSI_RESULTS  results;
+  tBTM_RSSI_RESULT result;
   tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_rssi_cmpl_cb;
   btm_cb.devcb.p_rssi_cmpl_cb = NULL;
-  results.status = BTM_DEVICE_TIMEOUT;
-  if (p_cb)
-      (*p_cb)(&results);
+  result.status = BTM_DEVICE_TIMEOUT;
+  if (p_cb) (*p_cb)(&result);
 }
 
 /*******************************************************************************
@@ -2139,10 +2194,8 @@
  ******************************************************************************/
 void btm_read_rssi_complete(uint8_t* p) {
   tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_rssi_cmpl_cb;
-  tBTM_RSSI_RESULTS results;
-  uint16_t handle;
+  tBTM_RSSI_RESULT result;
   tACL_CONN* p_acl_cb = &btm_cb.acl_db[0];
-  uint16_t index;
 
   BTM_TRACE_DEBUG("%s", __func__);
   alarm_cancel(btm_cb.devcb.read_rssi_timer);
@@ -2150,28 +2203,164 @@
 
   /* If there was a registered callback, call it */
   if (p_cb) {
-    STREAM_TO_UINT8(results.hci_status, p);
+    STREAM_TO_UINT8(result.hci_status, p);
 
-    if (results.hci_status == HCI_SUCCESS) {
-      results.status = BTM_SUCCESS;
+    if (result.hci_status == HCI_SUCCESS) {
+      uint16_t handle;
+      result.status = BTM_SUCCESS;
 
       STREAM_TO_UINT16(handle, p);
 
-      STREAM_TO_UINT8(results.rssi, p);
+      STREAM_TO_UINT8(result.rssi, p);
       BTM_TRACE_DEBUG("BTM RSSI Complete: rssi %d, hci status 0x%02x",
-                      results.rssi, results.hci_status);
+                      result.rssi, result.hci_status);
 
       /* Search through the list of active channels for the correct BD Addr */
-      for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) {
+      for (uint16_t index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) {
         if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle)) {
-          memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
+          result.rem_bda = p_acl_cb->remote_addr;
           break;
         }
       }
-    } else
-      results.status = BTM_ERR_PROCESSING;
+    } else {
+      result.status = BTM_ERR_PROCESSING;
+    }
 
-    (*p_cb)(&results);
+    (*p_cb)(&result);
+  }
+}
+
+/*******************************************************************************
+ *
+ * Function         btm_read_failed_contact_counter_timeout
+ *
+ * Description      Callback when reading the failed contact counter times out.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+void btm_read_failed_contact_counter_timeout(UNUSED_ATTR void* data) {
+  tBTM_FAILED_CONTACT_COUNTER_RESULT result;
+  tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_failed_contact_counter_cmpl_cb;
+  btm_cb.devcb.p_failed_contact_counter_cmpl_cb = NULL;
+  result.status = BTM_DEVICE_TIMEOUT;
+  if (p_cb) (*p_cb)(&result);
+}
+
+/*******************************************************************************
+ *
+ * Function         btm_read_failed_contact_counter_complete
+ *
+ * Description      This function is called when the command complete message
+ *                  is received from the HCI for the read failed contact
+ *                  counter request.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+void btm_read_failed_contact_counter_complete(uint8_t* p) {
+  tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_failed_contact_counter_cmpl_cb;
+  tBTM_FAILED_CONTACT_COUNTER_RESULT result;
+  tACL_CONN* p_acl_cb = &btm_cb.acl_db[0];
+
+  BTM_TRACE_DEBUG("%s", __func__);
+  alarm_cancel(btm_cb.devcb.read_failed_contact_counter_timer);
+  btm_cb.devcb.p_failed_contact_counter_cmpl_cb = NULL;
+
+  /* If there was a registered callback, call it */
+  if (p_cb) {
+    uint16_t handle;
+    STREAM_TO_UINT8(result.hci_status, p);
+
+    if (result.hci_status == HCI_SUCCESS) {
+      result.status = BTM_SUCCESS;
+
+      STREAM_TO_UINT16(handle, p);
+
+      STREAM_TO_UINT16(result.failed_contact_counter, p);
+      BTM_TRACE_DEBUG(
+          "BTM Failed Contact Counter Complete: counter %u, hci status 0x%02x",
+          result.failed_contact_counter, result.hci_status);
+
+      /* Search through the list of active channels for the correct BD Addr */
+      for (uint16_t index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) {
+        if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle)) {
+          result.rem_bda = p_acl_cb->remote_addr;
+          break;
+        }
+      }
+    } else {
+      result.status = BTM_ERR_PROCESSING;
+    }
+
+    (*p_cb)(&result);
+  }
+}
+
+/*******************************************************************************
+ *
+ * Function         btm_read_automatic_flush_timeout_timeout
+ *
+ * Description      Callback when reading the automatic flush timeout times out.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+void btm_read_automatic_flush_timeout_timeout(UNUSED_ATTR void* data) {
+  tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT result;
+  tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb;
+  btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb = nullptr;
+  result.status = BTM_DEVICE_TIMEOUT;
+  if (p_cb) (*p_cb)(&result);
+}
+
+/*******************************************************************************
+ *
+ * Function         btm_read_automatic_flush_timeout_complete
+ *
+ * Description      This function is called when the command complete message
+ *                  is received from the HCI for the read automatic flush
+ *                  timeout request.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+void btm_read_automatic_flush_timeout_complete(uint8_t* p) {
+  tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb;
+  tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT result;
+  tACL_CONN* p_acl_cb = &btm_cb.acl_db[0];
+
+  BTM_TRACE_DEBUG("%s", __func__);
+  alarm_cancel(btm_cb.devcb.read_automatic_flush_timeout_timer);
+  btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb = nullptr;
+
+  /* If there was a registered callback, call it */
+  if (p_cb) {
+    uint16_t handle;
+    STREAM_TO_UINT8(result.hci_status, p);
+
+    if (result.hci_status == HCI_SUCCESS) {
+      result.status = BTM_SUCCESS;
+
+      STREAM_TO_UINT16(handle, p);
+
+      STREAM_TO_UINT16(result.automatic_flush_timeout, p);
+      BTM_TRACE_DEBUG(
+          "BTM Automatic Flush Timeout Complete: timeout %u, hci status 0x%02x",
+          result.automatic_flush_timeout, result.hci_status);
+
+      /* Search through the list of active channels for the correct BD Addr */
+      for (uint16_t index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) {
+        if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle)) {
+          result.rem_bda = p_acl_cb->remote_addr;
+          break;
+        }
+      }
+    } else {
+      result.status = BTM_ERR_PROCESSING;
+    }
+
+    (*p_cb)(&result);
   }
 }
 
@@ -2202,10 +2391,8 @@
  ******************************************************************************/
 void btm_read_link_quality_complete(uint8_t* p) {
   tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_link_qual_cmpl_cb;
-  tBTM_LINK_QUALITY_RESULTS results;
-  uint16_t handle;
+  tBTM_LINK_QUALITY_RESULT result;
   tACL_CONN* p_acl_cb = &btm_cb.acl_db[0];
-  uint16_t index;
 
   BTM_TRACE_DEBUG("%s", __func__);
   alarm_cancel(btm_cb.devcb.read_link_quality_timer);
@@ -2213,29 +2400,31 @@
 
   /* If there was a registered callback, call it */
   if (p_cb) {
-    STREAM_TO_UINT8(results.hci_status, p);
+    STREAM_TO_UINT8(result.hci_status, p);
 
-    if (results.hci_status == HCI_SUCCESS) {
-      results.status = BTM_SUCCESS;
+    if (result.hci_status == HCI_SUCCESS) {
+      uint16_t handle;
+      result.status = BTM_SUCCESS;
 
       STREAM_TO_UINT16(handle, p);
 
-      STREAM_TO_UINT8(results.link_quality, p);
+      STREAM_TO_UINT8(result.link_quality, p);
       BTM_TRACE_DEBUG(
           "BTM Link Quality Complete: Link Quality %d, hci status 0x%02x",
-          results.link_quality, results.hci_status);
+          result.link_quality, result.hci_status);
 
       /* Search through the list of active channels for the correct BD Addr */
-      for (index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) {
+      for (uint16_t index = 0; index < MAX_L2CAP_LINKS; index++, p_acl_cb++) {
         if ((p_acl_cb->in_use) && (handle == p_acl_cb->hci_handle)) {
-          memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN);
+          result.rem_bda = p_acl_cb->remote_addr;
           break;
         }
       }
-    } else
-      results.status = BTM_ERR_PROCESSING;
+    } else {
+      result.status = BTM_ERR_PROCESSING;
+    }
 
-    (*p_cb)(&results);
+    (*p_cb)(&result);
   }
 }
 
@@ -2249,7 +2438,7 @@
  *                  BTM_NO_RESOURCES.
  *
  ******************************************************************************/
-tBTM_STATUS btm_remove_acl(BD_ADDR bd_addr, tBT_TRANSPORT transport) {
+tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
   uint16_t hci_handle = BTM_GetHCIConnHandle(bd_addr, transport);
   tBTM_STATUS status = BTM_SUCCESS;
 
@@ -2266,8 +2455,9 @@
     if (hci_handle != 0xFFFF && p_dev_rec &&
         p_dev_rec->sec_state != BTM_SEC_STATE_DISCONNECTING) {
       btsnd_hcic_disconnect(hci_handle, HCI_ERR_PEER_USER);
-    } else
+    } else {
       status = BTM_UNKNOWN_ADDR;
+    }
   }
 
   return status;
@@ -2342,7 +2532,6 @@
   tBTM_SEC_DEV_REC* p_dev_rec;
   BT_HDR* p_buf;
   uint8_t* pp;
-  BD_ADDR bda;
   BTM_TRACE_DEBUG("btm_acl_resubmit_page");
   /* If there were other page request schedule can start the next one */
   p_buf = (BT_HDR*)fixed_queue_try_dequeue(btm_cb.page_queue);
@@ -2351,16 +2540,18 @@
      * for both create_conn and rmt_name */
     pp = (uint8_t*)(p_buf + 1) + p_buf->offset + 3;
 
+    RawAddress bda;
     STREAM_TO_BDADDR(bda, pp);
 
     p_dev_rec = btm_find_or_alloc_dev(bda);
 
-    memcpy(btm_cb.connecting_bda, p_dev_rec->bd_addr, BD_ADDR_LEN);
+    btm_cb.connecting_bda = p_dev_rec->bd_addr;
     memcpy(btm_cb.connecting_dc, p_dev_rec->dev_class, DEV_CLASS_LEN);
 
     btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p_buf);
-  } else
+  } else {
     btm_cb.paging = false;
+  }
 }
 
 /*******************************************************************************
@@ -2388,30 +2579,23 @@
  * Description      send a paging command or queue it in btm_cb
  *
  ******************************************************************************/
-void btm_acl_paging(BT_HDR* p, BD_ADDR bda) {
+void btm_acl_paging(BT_HDR* p, const RawAddress& bda) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
-  BTM_TRACE_DEBUG("btm_acl_paging discing:%d, paging:%d BDA: %06x%06x",
-                  btm_cb.discing, btm_cb.paging,
-                  (bda[0] << 16) + (bda[1] << 8) + bda[2],
-                  (bda[3] << 16) + (bda[4] << 8) + bda[5]);
+  VLOG(2) << __func__ << ":" << btm_cb.discing << " , paging:" << btm_cb.paging
+          << " BDA: " << bda;
+
   if (btm_cb.discing) {
     btm_cb.paging = true;
     fixed_queue_enqueue(btm_cb.page_queue, p);
   } else {
     if (!BTM_ACL_IS_CONNECTED(bda)) {
-      BTM_TRACE_DEBUG(
-          "connecting_bda: %06x%06x",
-          (btm_cb.connecting_bda[0] << 16) + (btm_cb.connecting_bda[1] << 8) +
-              btm_cb.connecting_bda[2],
-          (btm_cb.connecting_bda[3] << 16) + (btm_cb.connecting_bda[4] << 8) +
-              btm_cb.connecting_bda[5]);
-      if (btm_cb.paging &&
-          memcmp(bda, btm_cb.connecting_bda, BD_ADDR_LEN) != 0) {
+      VLOG(1) << "connecting_bda: " << btm_cb.connecting_bda;
+      if (btm_cb.paging && bda != btm_cb.connecting_bda) {
         fixed_queue_enqueue(btm_cb.page_queue, p);
       } else {
         p_dev_rec = btm_find_or_alloc_dev(bda);
-        memcpy(btm_cb.connecting_bda, p_dev_rec->bd_addr, BD_ADDR_LEN);
+        btm_cb.connecting_bda = p_dev_rec->bd_addr;
         memcpy(btm_cb.connecting_dc, p_dev_rec->dev_class, DEV_CLASS_LEN);
 
         btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
@@ -2435,23 +2619,21 @@
  *                  false if no one needs the notification.
  *
  ******************************************************************************/
-bool btm_acl_notif_conn_collision(BD_ADDR bda) {
-  tBTM_BL_EVENT_DATA evt_data;
-
+bool btm_acl_notif_conn_collision(const RawAddress& bda) {
   /* Report possible collision to the upper layer. */
   if (btm_cb.p_bl_changed_cb) {
-    BTM_TRACE_DEBUG(
-        "btm_acl_notif_conn_collision: RemBdAddr: %02x%02x%02x%02x%02x%02x",
-        bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+    VLOG(1) << __func__ << " RemBdAddr: " << bda;
 
+    tBTM_BL_EVENT_DATA evt_data;
     evt_data.event = BTM_BL_COLLISION_EVT;
-    evt_data.conn.p_bda = bda;
+    evt_data.conn.p_bda = &bda;
     evt_data.conn.transport = BT_TRANSPORT_BR_EDR;
     evt_data.conn.handle = BTM_INVALID_HCI_HANDLE;
     (*btm_cb.p_bl_changed_cb)(&evt_data);
     return true;
-  } else
+  } else {
     return false;
+  }
 }
 
 /*******************************************************************************
diff --git a/stack/btm/btm_ble.cc b/stack/btm/btm_ble.cc
index c21af14..f3dcc98 100644
--- a/stack/btm/btm_ble.cc
+++ b/stack/btm/btm_ble.cc
@@ -68,7 +68,7 @@
  * Returns          true if added OK, else false
  *
  ******************************************************************************/
-bool BTM_SecAddBleDevice(const BD_ADDR bd_addr, BD_NAME bd_name,
+bool BTM_SecAddBleDevice(const RawAddress& bd_addr, BD_NAME bd_name,
                          tBT_DEVICE_TYPE dev_type, tBLE_ADDR_TYPE addr_type) {
   BTM_TRACE_DEBUG("%s: dev_type=0x%x", __func__, dev_type);
 
@@ -76,7 +76,7 @@
   if (!p_dev_rec) {
     p_dev_rec = btm_sec_allocate_dev_rec();
 
-    memcpy(p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
+    p_dev_rec->bd_addr = bd_addr;
     p_dev_rec->hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_BR_EDR);
     p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE);
 
@@ -100,7 +100,7 @@
   p_dev_rec->device_type |= dev_type;
   p_dev_rec->ble.ble_addr_type = addr_type;
 
-  memcpy(p_dev_rec->ble.pseudo_addr, bd_addr, BD_ADDR_LEN);
+  p_dev_rec->ble.pseudo_addr = bd_addr;
   /* sync up with the Inq Data base*/
   tBTM_INQ_INFO* p_info = BTM_InqDbRead(bd_addr);
   if (p_info) {
@@ -128,7 +128,7 @@
  * Returns          true if added OK, else false
  *
  ******************************************************************************/
-bool BTM_SecAddBleKey(BD_ADDR bd_addr, tBTM_LE_KEY_VALUE* p_le_key,
+bool BTM_SecAddBleKey(const RawAddress& bd_addr, tBTM_LE_KEY_VALUE* p_le_key,
                       tBTM_LE_KEY_TYPE key_type) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   BTM_TRACE_DEBUG("BTM_SecAddBleKey");
@@ -137,19 +137,13 @@
       (key_type != BTM_LE_KEY_PENC && key_type != BTM_LE_KEY_PID &&
        key_type != BTM_LE_KEY_PCSRK && key_type != BTM_LE_KEY_LENC &&
        key_type != BTM_LE_KEY_LCSRK && key_type != BTM_LE_KEY_LID)) {
-    BTM_TRACE_WARNING(
-        "BTM_SecAddBleKey()  Wrong Type, or No Device record \
-                        for bdaddr: %08x%04x, Type: %d",
-        (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) +
-            bd_addr[3],
-        (bd_addr[4] << 8) + bd_addr[5], key_type);
+    LOG(WARNING) << __func__
+                 << " Wrong Type, or No Device record for bdaddr: " << bd_addr
+                 << ", Type: " << key_type;
     return (false);
   }
 
-  BTM_TRACE_DEBUG(
-      "BTM_SecAddLeKey()  BDA: %08x%04x, Type: 0x%02x",
-      (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
-      (bd_addr[4] << 8) + bd_addr[5], key_type);
+  VLOG(1) << __func__ << " BDA: " << bd_addr << ", Type: " << key_type;
 
   btm_sec_save_le_key(bd_addr, key_type, p_le_key, false);
 
@@ -256,7 +250,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTM_ReadConnectionAddr(BD_ADDR remote_bda, BD_ADDR local_conn_addr,
+void BTM_ReadConnectionAddr(const RawAddress& remote_bda,
+                            RawAddress& local_conn_addr,
                             tBLE_ADDR_TYPE* p_addr_type) {
   tACL_CONN* p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE);
 
@@ -264,11 +259,11 @@
     BTM_TRACE_ERROR("No connection exist!");
     return;
   }
-  memcpy(local_conn_addr, p_acl->conn_addr, BD_ADDR_LEN);
+  local_conn_addr = p_acl->conn_addr;
   *p_addr_type = p_acl->conn_addr_type;
 
   BTM_TRACE_DEBUG("BTM_ReadConnectionAddr address type: %d addr: 0x%02x",
-                  p_acl->conn_addr_type, p_acl->conn_addr[0]);
+                  p_acl->conn_addr_type, p_acl->conn_addr.address[0]);
 }
 
 /*******************************************************************************
@@ -309,7 +304,8 @@
  * Returns        bool, true if connection to remote device exists, else false
  *
  ******************************************************************************/
-bool BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr,
+bool BTM_ReadRemoteConnectionAddr(const RawAddress& pseudo_addr,
+                                  RawAddress& conn_addr,
                                   tBLE_ADDR_TYPE* p_addr_type) {
   bool st = true;
 #if (BLE_PRIVACY_SPT == TRUE)
@@ -322,12 +318,12 @@
     return false;
   }
 
-  memcpy(conn_addr, p->active_remote_addr, BD_ADDR_LEN);
+  conn_addr = p->active_remote_addr;
   *p_addr_type = p->active_remote_addr_type;
 #else
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(pseudo_addr);
 
-  memcpy(conn_addr, pseudo_addr, BD_ADDR_LEN);
+  conn_addr = pseudo_addr;
   if (p_dev_rec != NULL) {
     *p_addr_type = p_dev_rec->ble.ble_addr_type;
   }
@@ -348,7 +344,7 @@
  * Returns          None
  *
  ******************************************************************************/
-void BTM_SecurityGrant(BD_ADDR bd_addr, uint8_t res) {
+void BTM_SecurityGrant(const RawAddress& bd_addr, uint8_t res) {
   tSMP_STATUS res_smp =
       (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_REPEATED_ATTEMPTS;
   BTM_TRACE_DEBUG("BTM_SecurityGrant");
@@ -371,7 +367,8 @@
  *                                 uint32_t)
  *
  ******************************************************************************/
-void BTM_BlePasskeyReply(BD_ADDR bd_addr, uint8_t res, uint32_t passkey) {
+void BTM_BlePasskeyReply(const RawAddress& bd_addr, uint8_t res,
+                         uint32_t passkey) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   tSMP_STATUS res_smp =
       (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_PASSKEY_ENTRY_FAIL;
@@ -398,7 +395,7 @@
  *                  res          - comparison result BTM_SUCCESS if success
  *
  ******************************************************************************/
-void BTM_BleConfirmReply(BD_ADDR bd_addr, uint8_t res) {
+void BTM_BleConfirmReply(const RawAddress& bd_addr, uint8_t res) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   tSMP_STATUS res_smp =
       (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_PASSKEY_ENTRY_FAIL;
@@ -428,7 +425,7 @@
  *                                "Security Manager TK Value".
  *
  ******************************************************************************/
-void BTM_BleOobDataReply(BD_ADDR bd_addr, uint8_t res, uint8_t len,
+void BTM_BleOobDataReply(const RawAddress& bd_addr, uint8_t res, uint8_t len,
                          uint8_t* p_data) {
   tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_OOB_FAIL;
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
@@ -457,8 +454,8 @@
  *                  p_r         - pointer to Randomizer
  *
  ******************************************************************************/
-void BTM_BleSecureConnectionOobDataReply(BD_ADDR bd_addr, uint8_t* p_c,
-                                         uint8_t* p_r) {
+void BTM_BleSecureConnectionOobDataReply(const RawAddress& bd_addr,
+                                         uint8_t* p_c, uint8_t* p_r) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
 
   BTM_TRACE_DEBUG("%s:", __func__);
@@ -477,7 +474,7 @@
   memcpy(&oob.peer_oob_data.randomizer, p_r, BT_OCTET16_LEN);
   memcpy(&oob.peer_oob_data.commitment, p_c, BT_OCTET16_LEN);
   oob.peer_oob_data.addr_rcvd_from.type = p_dev_rec->ble.ble_addr_type;
-  memcpy(&oob.peer_oob_data.addr_rcvd_from.bda, bd_addr, sizeof(BD_ADDR));
+  oob.peer_oob_data.addr_rcvd_from.bda = bd_addr;
 
   SMP_SecureConnectionOobDataReply((uint8_t*)&oob);
 }
@@ -537,7 +534,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTM_BleSetPrefConnParams(BD_ADDR bd_addr, uint16_t min_conn_int,
+void BTM_BleSetPrefConnParams(const RawAddress& bd_addr, uint16_t min_conn_int,
                               uint16_t max_conn_int, uint16_t slave_latency,
                               uint16_t supervision_tout) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
@@ -601,7 +598,7 @@
  *                  p_addr_type: output parameter to read the address type.
  *
  ******************************************************************************/
-void BTM_ReadDevInfo(const BD_ADDR remote_bda, tBT_DEVICE_TYPE* p_dev_type,
+void BTM_ReadDevInfo(const RawAddress& remote_bda, tBT_DEVICE_TYPE* p_dev_type,
                      tBLE_ADDR_TYPE* p_addr_type) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(remote_bda);
   tBTM_INQ_INFO* p_inq_info = BTM_InqDbRead(remote_bda);
@@ -625,12 +622,11 @@
       p_dev_rec->device_type = p_inq_info->results.device_type;
       p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type;
     }
-    if (memcmp(p_dev_rec->bd_addr, remote_bda, BD_ADDR_LEN) == 0 &&
-        memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0) {
+    if (p_dev_rec->bd_addr == remote_bda &&
+        p_dev_rec->ble.pseudo_addr == remote_bda) {
       *p_dev_type = p_dev_rec->device_type;
       *p_addr_type = p_dev_rec->ble.ble_addr_type;
-    } else if (memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) ==
-               0) {
+    } else if (p_dev_rec->ble.pseudo_addr == remote_bda) {
       *p_dev_type = BT_DEVICE_TYPE_BLE;
       *p_addr_type = p_dev_rec->ble.ble_addr_type;
     } else /* matching static adddress only */
@@ -658,26 +654,26 @@
  * Return           true if an active link is identified; false otherwise
  *
  ******************************************************************************/
-bool BTM_ReadConnectedTransportAddress(BD_ADDR remote_bda,
+bool BTM_ReadConnectedTransportAddress(RawAddress* remote_bda,
                                        tBT_TRANSPORT transport) {
-  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(remote_bda);
+  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(*remote_bda);
 
   /* if no device can be located, return */
   if (p_dev_rec == NULL) return false;
 
   if (transport == BT_TRANSPORT_BR_EDR) {
     if (btm_bda_to_acl(p_dev_rec->bd_addr, transport) != NULL) {
-      memcpy(remote_bda, p_dev_rec->bd_addr, BD_ADDR_LEN);
+      *remote_bda = p_dev_rec->bd_addr;
       return true;
     } else if (p_dev_rec->device_type & BT_DEVICE_TYPE_BREDR) {
-      memcpy(remote_bda, p_dev_rec->bd_addr, BD_ADDR_LEN);
+      *remote_bda = p_dev_rec->bd_addr;
     } else
-      memset(remote_bda, 0, BD_ADDR_LEN);
+      *remote_bda = RawAddress::kEmpty;
     return false;
   }
 
   if (transport == BT_TRANSPORT_LE) {
-    memcpy(remote_bda, p_dev_rec->ble.pseudo_addr, BD_ADDR_LEN);
+    *remote_bda = p_dev_rec->ble.pseudo_addr;
     if (btm_bda_to_acl(p_dev_rec->ble.pseudo_addr, transport) != NULL)
       return true;
     else
@@ -762,7 +758,7 @@
  * Returns          true to use LE, false use BR/EDR.
  *
  ******************************************************************************/
-bool BTM_UseLeLink(BD_ADDR bd_addr) {
+bool BTM_UseLeLink(const RawAddress& bd_addr) {
   tACL_CONN* p;
   tBT_DEVICE_TYPE dev_type;
   tBLE_ADDR_TYPE addr_type;
@@ -792,7 +788,8 @@
  * Returns          BTM_SUCCESS if success; otherwise failed.
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SetBleDataLength(BD_ADDR bd_addr, uint16_t tx_pdu_length) {
+tBTM_STATUS BTM_SetBleDataLength(const RawAddress& bd_addr,
+                                 uint16_t tx_pdu_length) {
   tACL_CONN* p_acl = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE);
 
   if (p_acl == NULL) {
@@ -825,6 +822,171 @@
   return BTM_SUCCESS;
 }
 
+void read_phy_cb(
+    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb,
+    uint8_t* data, uint16_t len) {
+  uint8_t status, tx_phy, rx_phy;
+  uint16_t handle;
+
+  LOG_ASSERT(len == 5) << "Received bad response length: " << len;
+  uint8_t* pp = data;
+  STREAM_TO_UINT8(status, pp);
+  STREAM_TO_UINT16(handle, pp);
+  handle = handle & 0x0FFF;
+  STREAM_TO_UINT8(tx_phy, pp);
+  STREAM_TO_UINT8(rx_phy, pp);
+
+  DVLOG(1) << __func__ << " Received read_phy_cb";
+  cb.Run(tx_phy, rx_phy, status);
+}
+
+/*******************************************************************************
+ *
+ * Function         BTM_BleReadPhy
+ *
+ * Description      To read the current PHYs for specified LE connection
+ *
+ *
+ * Returns          BTM_SUCCESS if command successfully sent to controller,
+ *                  BTM_MODE_UNSUPPORTED if local controller doesn't support LE
+ *                  2M or LE Coded PHY,
+ *                  BTM_WRONG_MODE if Device in wrong mode for request.
+ *
+ ******************************************************************************/
+void BTM_BleReadPhy(
+    const RawAddress& bd_addr,
+    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
+  BTM_TRACE_DEBUG("%s", __func__);
+
+  tACL_CONN* p_acl = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE);
+
+  if (p_acl == NULL) {
+    BTM_TRACE_ERROR("%s: Wrong mode: no LE link exist or LE not supported",
+                    __func__);
+    cb.Run(0, 0, HCI_ERR_NO_CONNECTION);
+    return;
+  }
+
+  // checking if local controller supports it!
+  if (!controller_get_interface()->supports_ble_2m_phy() &&
+      !controller_get_interface()->supports_ble_coded_phy()) {
+    BTM_TRACE_ERROR("%s failed, request not supported in local controller!",
+                    __func__);
+    cb.Run(0, 0, HCI_ERR_ILLEGAL_COMMAND);
+    return;
+  }
+
+  uint16_t handle = p_acl->hci_handle;
+
+  const uint8_t len = HCIC_PARAM_SIZE_BLE_READ_PHY;
+  uint8_t data[len];
+  uint8_t* pp = data;
+  UINT16_TO_STREAM(pp, handle);
+  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_READ_PHY, data, len,
+                            base::Bind(&read_phy_cb, std::move(cb)));
+  return;
+}
+
+void doNothing(uint8_t* data, uint16_t len) {}
+
+/*******************************************************************************
+ *
+ * Function         BTM_BleSetDefaultPhy
+ *
+ * Description      To set preferred PHY for ensuing LE connections
+ *
+ *
+ * Returns          BTM_SUCCESS if command successfully sent to controller,
+ *                  BTM_MODE_UNSUPPORTED if local controller doesn't support LE
+ *                  2M or LE Coded PHY
+ *
+ ******************************************************************************/
+tBTM_STATUS BTM_BleSetDefaultPhy(uint8_t all_phys, uint8_t tx_phys,
+                                 uint8_t rx_phys) {
+  BTM_TRACE_DEBUG("%s: all_phys = 0x%02x, tx_phys = 0x%02x, rx_phys = 0x%02x",
+                  __func__, all_phys, tx_phys, rx_phys);
+
+  // checking if local controller supports it!
+  if (!controller_get_interface()->supports_ble_2m_phy() &&
+      !controller_get_interface()->supports_ble_coded_phy()) {
+    BTM_TRACE_ERROR("%s failed, request not supported in local controller!",
+                    __func__);
+    return BTM_MODE_UNSUPPORTED;
+  }
+
+  const uint8_t len = HCIC_PARAM_SIZE_BLE_SET_DEFAULT_PHY;
+  uint8_t data[len];
+  uint8_t* pp = data;
+  UINT8_TO_STREAM(pp, all_phys);
+  UINT8_TO_STREAM(pp, tx_phys);
+  UINT8_TO_STREAM(pp, rx_phys);
+  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_SET_DEFAULT_PHY, data, len,
+                            base::Bind(doNothing));
+  return BTM_SUCCESS;
+}
+
+/*******************************************************************************
+ *
+ * Function         BTM_BleSetPhy
+ *
+ * Description      To set PHY preferences for specified LE connection
+ *
+ *
+ * Returns          BTM_SUCCESS if command successfully sent to controller,
+ *                  BTM_MODE_UNSUPPORTED if local controller doesn't support LE
+ *                  2M or LE Coded PHY,
+ *                  BTM_ILLEGAL_VALUE if specified remote doesn't support LE 2M
+ *                  or LE Coded PHY,
+ *                  BTM_WRONG_MODE if Device in wrong mode for request.
+ *
+ ******************************************************************************/
+void BTM_BleSetPhy(const RawAddress& bd_addr, uint8_t tx_phys, uint8_t rx_phys,
+                   uint16_t phy_options) {
+  tACL_CONN* p_acl = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE);
+
+  if (p_acl == NULL) {
+    BTM_TRACE_ERROR("%s: Wrong mode: no LE link exist or LE not supported",
+                    __func__);
+    return;
+  }
+
+  uint8_t all_phys = 0;
+  if (tx_phys == 0) all_phys &= 0x01;
+  if (rx_phys == 0) all_phys &= 0x02;
+
+  BTM_TRACE_DEBUG(
+      "%s: all_phys = 0x%02x, tx_phys = 0x%02x, rx_phys = 0x%02x, phy_options "
+      "= 0x%04x",
+      __func__, all_phys, tx_phys, rx_phys, phy_options);
+
+  // checking if local controller supports it!
+  if (!controller_get_interface()->supports_ble_2m_phy() &&
+      !controller_get_interface()->supports_ble_coded_phy()) {
+    BTM_TRACE_ERROR("%s failed, request not supported in local controller!",
+                    __func__);
+    return;
+  }
+
+  if (!HCI_LE_2M_PHY_SUPPORTED(p_acl->peer_le_features) &&
+      !HCI_LE_CODED_PHY_SUPPORTED(p_acl->peer_le_features)) {
+    BTM_TRACE_ERROR("%s failed, peer does not support request", __func__);
+    return;
+  }
+
+  uint16_t handle = p_acl->hci_handle;
+
+  const uint8_t len = HCIC_PARAM_SIZE_BLE_SET_PHY;
+  uint8_t data[len];
+  uint8_t* pp = data;
+  UINT16_TO_STREAM(pp, handle);
+  UINT8_TO_STREAM(pp, all_phys);
+  UINT8_TO_STREAM(pp, tx_phys);
+  UINT8_TO_STREAM(pp, rx_phys);
+  UINT16_TO_STREAM(pp, phy_options);
+  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_SET_PHY, data, len,
+                            base::Bind(doNothing));
+}
+
 /*******************************************************************************
  *
  * Function         btm_ble_determine_security_act
@@ -841,7 +1003,7 @@
  *
  ******************************************************************************/
 tBTM_SEC_ACTION btm_ble_determine_security_act(bool is_originator,
-                                               BD_ADDR bdaddr,
+                                               const RawAddress& bdaddr,
                                                uint16_t security_required) {
   tBTM_LE_AUTH_REQ auth_req = 0x00;
 
@@ -921,8 +1083,9 @@
  *                  false.
  *
  ******************************************************************************/
-bool btm_ble_start_sec_check(BD_ADDR bd_addr, uint16_t psm, bool is_originator,
-                             tBTM_SEC_CALLBACK* p_callback, void* p_ref_data) {
+bool btm_ble_start_sec_check(const RawAddress& bd_addr, uint16_t psm,
+                             bool is_originator, tBTM_SEC_CALLBACK* p_callback,
+                             void* p_ref_data) {
   /* Find the service record for the PSM */
   tBTM_SEC_SERV_REC* p_serv_rec = btm_sec_find_first_serv(is_originator, psm);
 
@@ -930,7 +1093,7 @@
    */
   if (!p_serv_rec) {
     BTM_TRACE_WARNING("%s PSM: %d no application registerd", __func__, psm);
-    (*p_callback)(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_MODE_UNSUPPORTED);
+    (*p_callback)(&bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_MODE_UNSUPPORTED);
     return false;
   }
 
@@ -943,7 +1106,7 @@
   switch (sec_act) {
     case BTM_SEC_OK:
       BTM_TRACE_DEBUG("%s Security met", __func__);
-      p_callback(bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_SUCCESS);
+      p_callback(&bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_SUCCESS);
       status = true;
       break;
 
@@ -1026,7 +1189,7 @@
  * Returns         None
  *
  ******************************************************************************/
-void btm_ble_increment_sign_ctr(BD_ADDR bd_addr, bool is_local) {
+void btm_ble_increment_sign_ctr(const RawAddress& bd_addr, bool is_local) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
   BTM_TRACE_DEBUG("btm_ble_increment_sign_ctr is_local=%d", is_local);
@@ -1053,7 +1216,7 @@
  * Returns          p_key_type: output parameter to carry the key type value.
  *
  ******************************************************************************/
-bool btm_ble_get_enc_key_type(BD_ADDR bd_addr, uint8_t* p_key_types) {
+bool btm_ble_get_enc_key_type(const RawAddress& bd_addr, uint8_t* p_key_types) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
   BTM_TRACE_DEBUG("btm_ble_get_enc_key_type");
@@ -1074,13 +1237,10 @@
  *
  * Returns          TURE - if a valid DIV is availavle
  ******************************************************************************/
-bool btm_get_local_div(BD_ADDR bd_addr, uint16_t* p_div) {
+bool btm_get_local_div(const RawAddress& bd_addr, uint16_t* p_div) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   bool status = false;
-  BTM_TRACE_DEBUG("btm_get_local_div");
-
-  BTM_TRACE_DEBUG("bd_addr:%02x-%02x-%02x-%02x-%02x-%02x", bd_addr[0],
-                  bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
+  VLOG(1) << __func__ << " bd_addr: " << bd_addr;
 
   *p_div = 0;
   p_dev_rec = btm_find_dev(bd_addr);
@@ -1108,7 +1268,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type,
+void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type,
                          tBTM_LE_KEY_VALUE* p_keys, bool pass_to_application) {
   tBTM_SEC_DEV_REC* p_rec;
   tBTM_LE_EVT_DATA cb_data;
@@ -1118,8 +1278,7 @@
                   key_type, pass_to_application);
   /* Store the updated key in the device database */
 
-  BTM_TRACE_DEBUG("bd_addr:%02x-%02x-%02x-%02x-%02x-%02x", bd_addr[0],
-                  bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
+  VLOG(1) << "bd_addr:" << bd_addr;
 
   if ((p_rec = btm_find_dev(bd_addr)) != NULL &&
       (p_keys || key_type == BTM_LE_KEY_LID)) {
@@ -1150,14 +1309,13 @@
 
         // memcpy( p_rec->ble.keys.irk, p_keys->pid_key, BT_OCTET16_LEN); todo
         // will crash the system
-        memcpy(p_rec->ble.static_addr, p_keys->pid_key.static_addr,
-               BD_ADDR_LEN);
+        p_rec->ble.static_addr = p_keys->pid_key.static_addr;
         p_rec->ble.static_addr_type = p_keys->pid_key.addr_type;
         p_rec->ble.key_type |= BTM_LE_KEY_PID;
         BTM_TRACE_DEBUG("BTM_LE_KEY_PID key_type=0x%x save peer IRK",
                         p_rec->ble.key_type);
         /* update device record address as static address */
-        memcpy(p_rec->bd_addr, p_keys->pid_key.static_addr, BD_ADDR_LEN);
+        p_rec->bd_addr = p_keys->pid_key.static_addr;
         /* combine DUMO device security record if needed */
         btm_consolidate_dev(p_rec);
         break;
@@ -1217,11 +1375,8 @@
         return;
     }
 
-    BTM_TRACE_DEBUG(
-        "BLE key type 0x%02x updated for BDA: %08x%04x (btm_sec_save_le_key)",
-        key_type, (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) +
-                      bd_addr[3],
-        (bd_addr[4] << 8) + bd_addr[5]);
+    VLOG(1) << "BLE key type 0x" << std::hex << key_type
+            << " updated for BDA: " << bd_addr << " (btm_sec_save_le_key)";
 
     /* Notify the application that one of the BLE keys has been updated
        If link key is in progress, it will get sent later.*/
@@ -1234,12 +1389,9 @@
     return;
   }
 
-  BTM_TRACE_WARNING(
-      "BLE key type 0x%02x called for Unknown BDA or type: %08x%04x !! "
-      "(btm_sec_save_le_key)",
-      key_type,
-      (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
-      (bd_addr[4] << 8) + bd_addr[5]);
+  LOG(WARNING) << "BLE key type 0x" << std::hex << key_type
+               << " called for Unknown BDA or type: " << bd_addr
+               << "(btm_sec_save_le_key)";
 
   if (p_rec) {
     BTM_TRACE_DEBUG("sec_flags=0x%x", p_rec->sec_flags);
@@ -1255,7 +1407,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_ble_update_sec_key_size(BD_ADDR bd_addr, uint8_t enc_key_size) {
+void btm_ble_update_sec_key_size(const RawAddress& bd_addr,
+                                 uint8_t enc_key_size) {
   tBTM_SEC_DEV_REC* p_rec;
 
   BTM_TRACE_DEBUG("btm_ble_update_sec_key_size enc_key_size = %d",
@@ -1276,7 +1429,7 @@
  * Returns          void
  *
  ******************************************************************************/
-uint8_t btm_ble_read_sec_key_size(BD_ADDR bd_addr) {
+uint8_t btm_ble_read_sec_key_size(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_rec;
 
   p_rec = btm_find_dev(bd_addr);
@@ -1295,7 +1448,8 @@
  * Returns          true: check is OK and the *p_sec_req_act contain the action
  *
  ******************************************************************************/
-void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req,
+void btm_ble_link_sec_check(const RawAddress& bd_addr,
+                            tBTM_LE_AUTH_REQ auth_req,
                             tBTM_BLE_SEC_REQ_ACT* p_sec_req_act) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   uint8_t req_sec_level = BTM_LE_SEC_NONE, cur_sec_level = BTM_LE_SEC_NONE;
@@ -1362,7 +1516,8 @@
  *                  the local device ER is copied into er
  *
  ******************************************************************************/
-tBTM_STATUS btm_ble_set_encryption(BD_ADDR bd_addr, tBTM_BLE_SEC_ACT sec_act,
+tBTM_STATUS btm_ble_set_encryption(const RawAddress& bd_addr,
+                                   tBTM_BLE_SEC_ACT sec_act,
                                    uint8_t link_role) {
   tBTM_STATUS cmd = BTM_NO_RESOURCES;
   tBTM_SEC_DEV_REC* p_rec = btm_find_dev(bd_addr);
@@ -1461,7 +1616,8 @@
  * Returns          BTM_SUCCESS if encryption was started successfully
  *
  ******************************************************************************/
-tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, bool use_stk, BT_OCTET16 stk) {
+tBTM_STATUS btm_ble_start_encrypt(const RawAddress& bda, bool use_stk,
+                                  BT_OCTET16 stk) {
   tBTM_CB* p_cb = &btm_cb;
   tBTM_SEC_DEV_REC* p_rec = btm_find_dev(bda);
   BT_OCTET8 dummy_rand = {0};
@@ -1506,7 +1662,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_ble_link_encrypted(BD_ADDR bd_addr, uint8_t encr_enable) {
+void btm_ble_link_encrypted(const RawAddress& bd_addr, uint8_t encr_enable) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   bool enc_cback;
 
@@ -1550,7 +1706,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_ble_ltk_request_reply(BD_ADDR bda, bool use_stk, BT_OCTET16 stk) {
+void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk,
+                               BT_OCTET16 stk) {
   tBTM_SEC_DEV_REC* p_rec = btm_find_dev(bda);
   tBTM_CB* p_cb = &btm_cb;
 
@@ -1692,7 +1849,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_ble_connected(uint8_t* bda, uint16_t handle, uint8_t enc_mode,
+void btm_ble_connected(const RawAddress& bda, uint16_t handle, uint8_t enc_mode,
                        uint8_t role, tBLE_ADDR_TYPE addr_type,
                        UNUSED_ATTR bool addr_matched) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda);
@@ -1703,20 +1860,14 @@
   /* Commenting out trace due to obf/compilation problems.
   */
   if (p_dev_rec) {
-    BTM_TRACE_EVENT(
-        "Security Manager: btm_ble_connected :  handle:%d  enc_mode:%d  bda:%x "
-        "RName:%s",
-        handle, enc_mode,
-        (bda[2] << 24) + (bda[3] << 16) + (bda[4] << 8) + bda[5],
-        p_dev_rec->sec_bd_name);
+    VLOG(1) << __func__ << " Security Manager: handle:" << handle
+            << " enc_mode:" << enc_mode << "  bda: " << bda
+            << " RName: " << p_dev_rec->sec_bd_name;
 
     BTM_TRACE_DEBUG("btm_ble_connected sec_flags=0x%x", p_dev_rec->sec_flags);
   } else {
-    BTM_TRACE_EVENT(
-        "Security Manager: btm_ble_connected:   handle:%d  enc_mode:%d  "
-        "bda:%x ",
-        handle, enc_mode,
-        (bda[2] << 24) + (bda[3] << 16) + (bda[4] << 8) + bda[5]);
+    VLOG(1) << __func__ << " Security Manager: handle:" << handle
+            << " enc_mode:" << enc_mode << "  bda: " << bda;
   }
 
   if (!p_dev_rec) {
@@ -1733,7 +1884,7 @@
   p_dev_rec->ble_hci_handle = handle;
   p_dev_rec->ble.ble_addr_type = addr_type;
   /* update pseudo address */
-  memcpy(p_dev_rec->ble.pseudo_addr, bda, BD_ADDR_LEN);
+  p_dev_rec->ble.pseudo_addr = bda;
 
   p_dev_rec->role_master = false;
   if (role == HCI_ROLE_MASTER) p_dev_rec->role_master = true;
@@ -1742,7 +1893,7 @@
   if (!addr_matched) p_dev_rec->ble.active_addr_type = BTM_BLE_ADDR_PSEUDO;
 
   if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_RANDOM && !addr_matched)
-    memcpy(p_dev_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
+    p_dev_rec->ble.cur_rand_addr = bda;
 #endif
 
   p_cb->inq_var.directed_conn = BTM_BLE_CONNECT_EVT;
@@ -1761,10 +1912,10 @@
 #if (BLE_PRIVACY_SPT == TRUE)
   uint8_t peer_addr_type;
 #endif
-  BD_ADDR local_rpa, peer_rpa;
+  RawAddress local_rpa, peer_rpa;
   uint8_t role, status, bda_type;
   uint16_t handle;
-  BD_ADDR bda;
+  RawAddress bda;
   uint16_t conn_interval, conn_latency, conn_timeout;
   bool match = false;
 
@@ -1787,7 +1938,7 @@
 
 #if (BLE_PRIVACY_SPT == TRUE)
     peer_addr_type = bda_type;
-    match = btm_identity_addr_to_random_pseudo(bda, &bda_type, true);
+    match = btm_identity_addr_to_random_pseudo(&bda, &bda_type, true);
 
     /* possiblly receive connection complete with resolvable random while
        the device has been paired */
@@ -1797,12 +1948,12 @@
         LOG_INFO(LOG_TAG, "%s matched and resolved random address", __func__);
         match = true;
         match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
-        memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
+        match_rec->ble.cur_rand_addr = bda;
         if (!btm_ble_init_pseudo_addr(match_rec, bda)) {
           /* assign the original address to be the current report address */
-          memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN);
+          bda = match_rec->ble.pseudo_addr;
         } else {
-          memcpy(bda, match_rec->bd_addr, BD_ADDR_LEN);
+          bda = match_rec->bd_addr;
         }
       } else {
         LOG_INFO(LOG_TAG, "%s unable to match and resolve random address",
@@ -1841,7 +1992,7 @@
     }
   }
 
-  btm_ble_update_mode_operation(role, bda, status);
+  btm_ble_update_mode_operation(role, &bda, status);
 }
 
 /*****************************************************************************
@@ -1862,7 +2013,7 @@
  *  Description     This function is the SMP callback handler.
  *
  *****************************************************************************/
-uint8_t btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr,
+uint8_t btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr,
                            tSMP_EVT_DATA* p_data) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   uint8_t res = 0;
@@ -1894,7 +2045,7 @@
           BTM_TRACE_DEBUG("%s: Ignoring SMP Security request", __func__);
           break;
         }
-        memcpy(btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN);
+        btm_cb.pairing_bda = bd_addr;
         p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
         btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
       /* fall through */
@@ -1953,15 +2104,12 @@
           BTM_TRACE_DEBUG(
               "btm_cb pairing_state=%x pairing_flags=%x pin_code_len=%x",
               btm_cb.pairing_state, btm_cb.pairing_flags, btm_cb.pin_code_len);
-          BTM_TRACE_DEBUG("btm_cb.pairing_bda %02x:%02x:%02x:%02x:%02x:%02x",
-                          btm_cb.pairing_bda[0], btm_cb.pairing_bda[1],
-                          btm_cb.pairing_bda[2], btm_cb.pairing_bda[3],
-                          btm_cb.pairing_bda[4], btm_cb.pairing_bda[5]);
+          VLOG(1) << "btm_cb.pairing_bda: " << btm_cb.pairing_bda;
 
           /* Reset btm state only if the callback address matches pairing
            * address*/
-          if (memcmp(bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) == 0) {
-            memset(btm_cb.pairing_bda, 0xff, BD_ADDR_LEN);
+          if (bd_addr == btm_cb.pairing_bda) {
+            btm_cb.pairing_bda = RawAddress::kAny;
             btm_cb.pairing_state = BTM_PAIR_STATE_IDLE;
             btm_cb.pairing_flags = 0;
           }
@@ -2005,8 +2153,8 @@
  * Returns          true if signing sucessul, otherwise false.
  *
  ******************************************************************************/
-bool BTM_BleDataSignature(BD_ADDR bd_addr, uint8_t* p_text, uint16_t len,
-                          BLE_SIGNATURE signature) {
+bool BTM_BleDataSignature(const RawAddress& bd_addr, uint8_t* p_text,
+                          uint16_t len, BLE_SIGNATURE signature) {
   tBTM_SEC_DEV_REC* p_rec = btm_find_dev(bd_addr);
 
   BTM_TRACE_DEBUG("%s", __func__);
@@ -2066,8 +2214,8 @@
  * Returns          true if signature verified correctly; otherwise false.
  *
  ******************************************************************************/
-bool BTM_BleVerifySignature(BD_ADDR bd_addr, uint8_t* p_orig, uint16_t len,
-                            uint32_t counter, uint8_t* p_comp) {
+bool BTM_BleVerifySignature(const RawAddress& bd_addr, uint8_t* p_orig,
+                            uint16_t len, uint32_t counter, uint8_t* p_comp) {
   bool verified = false;
   tBTM_SEC_DEV_REC* p_rec = btm_find_dev(bd_addr);
   uint8_t p_mac[BTM_CMAC_TLEN_SIZE];
@@ -2103,7 +2251,8 @@
  * Returns          bool    true if LE device is found, false otherwise.
  *
  ******************************************************************************/
-bool BTM_GetLeSecurityState(BD_ADDR bd_addr, uint8_t* p_le_dev_sec_flags,
+bool BTM_GetLeSecurityState(const RawAddress& bd_addr,
+                            uint8_t* p_le_dev_sec_flags,
                             uint8_t* p_le_key_size) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   uint16_t dev_rec_sec_flags;
@@ -2160,14 +2309,12 @@
  *                  otherwise.
  *
  ******************************************************************************/
-bool BTM_BleSecurityProcedureIsRunning(BD_ADDR bd_addr) {
+bool BTM_BleSecurityProcedureIsRunning(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
 
   if (p_dev_rec == NULL) {
-    BTM_TRACE_ERROR("%s device with BDA: %08x%04x is not found", __func__,
-                    (bd_addr[0] << 24) + (bd_addr[1] << 16) +
-                        (bd_addr[2] << 8) + bd_addr[3],
-                    (bd_addr[4] << 8) + bd_addr[5]);
+    LOG(ERROR) << __func__ << " device with BDA: " << bd_addr
+               << " is not found";
     return false;
   }
 
@@ -2186,17 +2333,15 @@
  * Returns          the key size or 0 if the size can't be retrieved.
  *
  ******************************************************************************/
-extern uint8_t BTM_BleGetSupportedKeySize(BD_ADDR bd_addr) {
+extern uint8_t BTM_BleGetSupportedKeySize(const RawAddress& bd_addr) {
 #if (L2CAP_LE_COC_INCLUDED == TRUE)
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   tBTM_LE_IO_REQ dev_io_cfg;
   uint8_t callback_rc;
 
   if (!p_dev_rec) {
-    BTM_TRACE_ERROR("%s device with BDA: %08x%04x is not found", __func__,
-                    (bd_addr[0] << 24) + (bd_addr[1] << 16) +
-                        (bd_addr[2] << 8) + bd_addr[3],
-                    (bd_addr[4] << 8) + bd_addr[5]);
+    LOG(ERROR) << __func__ << " device with BDA: " << bd_addr
+               << " is not found";
     return 0;
   }
 
@@ -2372,7 +2517,7 @@
 
 /* This function set a random address to local controller. It also temporarily
  * disable scans and adv before sending the command to the controller. */
-void btm_ble_set_random_address(BD_ADDR random_bda) {
+void btm_ble_set_random_address(const RawAddress& random_bda) {
   tBTM_LE_RANDOM_CB* p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
   tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb;
   bool adv_mode = btm_cb.ble_ctr_cb.inq_var.adv_mode;
@@ -2389,7 +2534,7 @@
   if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) btm_ble_stop_scan();
   btm_ble_suspend_bg_conn();
 
-  memcpy(p_cb->private_addr, random_bda, BD_ADDR_LEN);
+  p_cb->private_addr = random_bda;
   btsnd_hcic_ble_set_random_addr(p_cb->private_addr);
 
   if (adv_mode == BTM_BLE_ADV_ENABLE)
diff --git a/stack/btm/btm_ble_addr.cc b/stack/btm/btm_ble_addr.cc
index 4025df2..5459c53 100644
--- a/stack/btm/btm_ble_addr.cc
+++ b/stack/btm/btm_ble_addr.cc
@@ -35,8 +35,6 @@
 #include "btm_ble_int.h"
 #include "smp_api.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*******************************************************************************
  *
  * Function         btm_gen_resolve_paddr_cmpl
@@ -53,9 +51,9 @@
 
   if (p) {
     /* set hash to be LSB of rpAddress */
-    p_cb->private_addr[5] = p->param_buf[0];
-    p_cb->private_addr[4] = p->param_buf[1];
-    p_cb->private_addr[3] = p->param_buf[2];
+    p_cb->private_addr.address[5] = p->param_buf[0];
+    p_cb->private_addr.address[4] = p->param_buf[1];
+    p_cb->private_addr.address[3] = p->param_buf[2];
     /* set it to controller */
     btm_ble_set_random_address(p_cb->private_addr);
 
@@ -66,9 +64,8 @@
 #if (BTM_BLE_CONFORMANCE_TESTING == TRUE)
     interval_ms = btm_cb.ble_ctr_cb.rpa_tout * 1000;
 #endif
-    alarm_set_on_queue(p_cb->refresh_raddr_timer, interval_ms,
-                       btm_ble_refresh_raddr_timer_timeout, NULL,
-                       btu_general_alarm_queue);
+    alarm_set_on_mloop(p_cb->refresh_raddr_timer, interval_ms,
+                       btm_ble_refresh_raddr_timer_timeout, NULL);
   } else {
     /* random address set failure */
     BTM_TRACE_DEBUG("set random address failed");
@@ -92,9 +89,9 @@
   rand[2] &= (~BLE_RESOLVE_ADDR_MASK);
   rand[2] |= BLE_RESOLVE_ADDR_MSB;
 
-  p_cb->private_addr[2] = rand[0];
-  p_cb->private_addr[1] = rand[1];
-  p_cb->private_addr[0] = rand[2];
+  p_cb->private_addr.address[2] = rand[0];
+  p_cb->private_addr.address[1] = rand[1];
+  p_cb->private_addr.address[0] = rand[2];
 
   /* encrypt with ur IRK */
   if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, rand, 3,
@@ -133,7 +130,7 @@
   tBTM_BLE_ADDR_CBACK* p_cback = p_cb->p_generate_cback;
   void* p_data = p_cb->p;
   uint8_t* pp;
-  BD_ADDR static_random;
+  RawAddress static_random;
 
   BTM_TRACE_EVENT("btm_gen_non_resolve_paddr_cmpl");
 
@@ -141,7 +138,7 @@
   pp = rand;
   STREAM_TO_BDADDR(static_random, pp);
   /* mask off the 2 MSB */
-  static_random[0] &= BLE_STATIC_PRIVATE_MSB_MASK;
+  static_random.address[0] &= BLE_STATIC_PRIVATE_MSB_MASK;
 
   /* report complete */
   if (p_cback) (*p_cback)(static_random, p_data);
@@ -183,7 +180,7 @@
  *
  ******************************************************************************/
 static bool btm_ble_proc_resolve_x(const tSMP_ENC& encrypt_output,
-                                   const bt_bdaddr_t& random_bda) {
+                                   const RawAddress& random_bda) {
   BTM_TRACE_EVENT("btm_ble_proc_resolve_x");
 
   /* compare the hash with 3 LSB of bd address */
@@ -211,11 +208,9 @@
  *
  ******************************************************************************/
 bool btm_ble_init_pseudo_addr(tBTM_SEC_DEV_REC* p_dev_rec,
-                              BD_ADDR new_pseudo_addr) {
-  BD_ADDR dummy_bda = {0};
-
-  if (memcmp(p_dev_rec->ble.pseudo_addr, dummy_bda, BD_ADDR_LEN) == 0) {
-    memcpy(p_dev_rec->ble.pseudo_addr, new_pseudo_addr, BD_ADDR_LEN);
+                              const RawAddress& new_pseudo_addr) {
+  if (p_dev_rec->ble.pseudo_addr.IsEmpty()) {
+    p_dev_rec->ble.pseudo_addr = new_pseudo_addr;
     return true;
   }
 
@@ -232,7 +227,8 @@
  * Returns          true is resolvable; false otherwise.
  *
  ******************************************************************************/
-bool btm_ble_addr_resolvable(BD_ADDR rpa, tBTM_SEC_DEV_REC* p_dev_rec) {
+bool btm_ble_addr_resolvable(const RawAddress& rpa,
+                             tBTM_SEC_DEV_REC* p_dev_rec) {
   bool rt = false;
 
   if (!BTM_BLE_IS_RESOLVE_BDA(rpa)) return rt;
@@ -243,16 +239,16 @@
       (p_dev_rec->ble.key_type & BTM_LE_KEY_PID)) {
     BTM_TRACE_DEBUG("%s try to resolve", __func__);
     /* use the 3 MSB of bd address as prand */
-    rand[0] = rpa[2];
-    rand[1] = rpa[1];
-    rand[2] = rpa[0];
+    rand[0] = rpa.address[2];
+    rand[1] = rpa.address[1];
+    rand[2] = rpa.address[0];
 
     /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */
     SMP_Encrypt(p_dev_rec->ble.keys.irk, BT_OCTET16_LEN, &rand[0], 3, &output);
 
-    rand[0] = rpa[5];
-    rand[1] = rpa[4];
-    rand[2] = rpa[3];
+    rand[0] = rpa.address[5];
+    rand[1] = rpa.address[4];
+    rand[2] = rpa.address[3];
 
     if (!memcmp(output.param_buf, &rand[0], 3)) {
       btm_ble_init_pseudo_addr(p_dev_rec, rpa);
@@ -275,15 +271,13 @@
  *
  ******************************************************************************/
 static bool btm_ble_match_random_bda(void* data, void* context) {
-  bt_bdaddr_t random_bda;
-  bdcpy(random_bda.address, (uint8_t *)context);
-
+  RawAddress* random_bda = (RawAddress*)context;
   /* use the 3 MSB of bd address as prand */
 
   uint8_t rand[3];
-  rand[0] = random_bda.address[2];
-  rand[1] = random_bda.address[1];
-  rand[2] = random_bda.address[0];
+  rand[0] = random_bda->address[2];
+  rand[1] = random_bda->address[1];
+  rand[2] = random_bda->address[0];
 
   BTM_TRACE_EVENT("%s next iteration", __func__);
 
@@ -300,7 +294,7 @@
   /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */
   SMP_Encrypt(p_dev_rec->ble.keys.irk, BT_OCTET16_LEN, &rand[0], 3, &output);
   // if it was match, finish iteration, otherwise continue
-  return !btm_ble_proc_resolve_x(output, random_bda);
+  return !btm_ble_proc_resolve_x(output, *random_bda);
 }
 
 /*******************************************************************************
@@ -313,14 +307,14 @@
  *                  address is matched to.
  *
  ******************************************************************************/
-tBTM_SEC_DEV_REC* btm_ble_resolve_random_addr(BD_ADDR random_bda) {
+tBTM_SEC_DEV_REC* btm_ble_resolve_random_addr(const RawAddress& random_bda) {
   BTM_TRACE_EVENT("%s", __func__);
 
   /* start to resolve random address */
   /* check for next security record */
 
-  list_node_t* n =
-      list_foreach(btm_cb.sec_dev_rec, btm_ble_match_random_bda, random_bda);
+  list_node_t* n = list_foreach(btm_cb.sec_dev_rec, btm_ble_match_random_bda,
+                                (void*)&random_bda);
   tBTM_SEC_DEV_REC* p_dev_rec = nullptr;
   if (n != nullptr) p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(list_node(n));
 
@@ -339,7 +333,7 @@
  * Description      find the security record whose LE static address is matching
  *
  ******************************************************************************/
-tBTM_SEC_DEV_REC* btm_find_dev_by_identity_addr(BD_ADDR bd_addr,
+tBTM_SEC_DEV_REC* btm_find_dev_by_identity_addr(const RawAddress& bd_addr,
                                                 uint8_t addr_type) {
 #if (BLE_PRIVACY_SPT == TRUE)
   list_node_t* end = list_end(btm_cb.sec_dev_rec);
@@ -347,7 +341,7 @@
        node = list_next(node)) {
     tBTM_SEC_DEV_REC* p_dev_rec =
         static_cast<tBTM_SEC_DEV_REC*>(list_node(node));
-    if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) == 0) {
+    if (p_dev_rec->ble.static_addr == bd_addr) {
       if ((p_dev_rec->ble.static_addr_type & (~BLE_ADDR_TYPE_ID_BIT)) !=
           (addr_type & (~BLE_ADDR_TYPE_ID_BIT)))
         BTM_TRACE_WARNING(
@@ -371,11 +365,11 @@
  *                  address in security database.
  *
  ******************************************************************************/
-bool btm_identity_addr_to_random_pseudo(BD_ADDR bd_addr, uint8_t* p_addr_type,
-                                        bool refresh) {
+bool btm_identity_addr_to_random_pseudo(RawAddress* bd_addr,
+                                        uint8_t* p_addr_type, bool refresh) {
 #if (BLE_PRIVACY_SPT == TRUE)
   tBTM_SEC_DEV_REC* p_dev_rec =
-      btm_find_dev_by_identity_addr(bd_addr, *p_addr_type);
+      btm_find_dev_by_identity_addr(*bd_addr, *p_addr_type);
 
   BTM_TRACE_EVENT("%s", __func__);
   /* evt reported on static address, map static address to random pseudo */
@@ -386,8 +380,8 @@
       btm_ble_read_resolving_list_entry(p_dev_rec);
 
     /* assign the original address to be the current report address */
-    if (!btm_ble_init_pseudo_addr(p_dev_rec, bd_addr))
-      memcpy(bd_addr, p_dev_rec->ble.pseudo_addr, BD_ADDR_LEN);
+    if (!btm_ble_init_pseudo_addr(p_dev_rec, *bd_addr))
+      *bd_addr = p_dev_rec->ble.pseudo_addr;
 
     *p_addr_type = p_dev_rec->ble.ble_addr_type;
     return true;
@@ -404,15 +398,15 @@
  *                  address. random_pseudo is input and output parameter
  *
  ******************************************************************************/
-bool btm_random_pseudo_to_identity_addr(BD_ADDR random_pseudo,
+bool btm_random_pseudo_to_identity_addr(RawAddress* random_pseudo,
                                         uint8_t* p_static_addr_type) {
 #if (BLE_PRIVACY_SPT == TRUE)
-  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(random_pseudo);
+  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(*random_pseudo);
 
   if (p_dev_rec != NULL) {
     if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) {
       *p_static_addr_type = p_dev_rec->ble.static_addr_type;
-      memcpy(random_pseudo, p_dev_rec->ble.static_addr, BD_ADDR_LEN);
+      *random_pseudo = p_dev_rec->ble.static_addr;
       if (controller_get_interface()->supports_ble_privacy())
         *p_static_addr_type |= BLE_ADDR_TYPE_ID_BIT;
       return true;
@@ -431,19 +425,17 @@
  *                  connection address.
  *
  ******************************************************************************/
-void btm_ble_refresh_peer_resolvable_private_addr(BD_ADDR pseudo_bda,
-                                                  BD_ADDR rpa,
+void btm_ble_refresh_peer_resolvable_private_addr(const RawAddress& pseudo_bda,
+                                                  const RawAddress& rpa,
                                                   uint8_t rra_type) {
 #if (BLE_PRIVACY_SPT == TRUE)
   uint8_t rra_dummy = false;
-  BD_ADDR dummy_bda = {0};
-
-  if (memcmp(dummy_bda, rpa, BD_ADDR_LEN) == 0) rra_dummy = true;
+  if (rpa.IsEmpty()) rra_dummy = true;
 
   /* update security record here, in adv event or connection complete process */
   tBTM_SEC_DEV_REC* p_sec_rec = btm_find_dev(pseudo_bda);
   if (p_sec_rec != NULL) {
-    memcpy(p_sec_rec->ble.cur_rand_addr, rpa, BD_ADDR_LEN);
+    p_sec_rec->ble.cur_rand_addr = rpa;
 
     /* unknown, if dummy address, set to static */
     if (rra_type == BTM_BLE_ADDR_PSEUDO)
@@ -469,23 +461,19 @@
       /* use static address, resolvable_private_addr is empty */
       if (rra_dummy) {
         p_acl->active_remote_addr_type = p_sec_rec->ble.static_addr_type;
-        memcpy(p_acl->active_remote_addr, p_sec_rec->ble.static_addr,
-               BD_ADDR_LEN);
+        p_acl->active_remote_addr = p_sec_rec->ble.static_addr;
       } else {
         p_acl->active_remote_addr_type = BLE_ADDR_RANDOM;
-        memcpy(p_acl->active_remote_addr, rpa, BD_ADDR_LEN);
+        p_acl->active_remote_addr = rpa;
       }
     } else {
       p_acl->active_remote_addr_type = rra_type;
-      memcpy(p_acl->active_remote_addr, rpa, BD_ADDR_LEN);
+      p_acl->active_remote_addr = rpa;
     }
 
     BTM_TRACE_DEBUG("p_acl->active_remote_addr_type: %d ",
                     p_acl->active_remote_addr_type);
-    BTM_TRACE_DEBUG("%s conn_addr: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
-                    p_acl->active_remote_addr[0], p_acl->active_remote_addr[1],
-                    p_acl->active_remote_addr[2], p_acl->active_remote_addr[3],
-                    p_acl->active_remote_addr[4], p_acl->active_remote_addr[5]);
+    VLOG(1) << __func__ << " conn_addr: " << p_acl->active_remote_addr;
   }
 #endif
 }
@@ -498,24 +486,21 @@
  *                  address for the active link to the remote device
  *
  ******************************************************************************/
-void btm_ble_refresh_local_resolvable_private_addr(BD_ADDR pseudo_addr,
-                                                   BD_ADDR local_rpa) {
+void btm_ble_refresh_local_resolvable_private_addr(
+    const RawAddress& pseudo_addr, const RawAddress& local_rpa) {
 #if (BLE_PRIVACY_SPT == TRUE)
   tACL_CONN* p = btm_bda_to_acl(pseudo_addr, BT_TRANSPORT_LE);
-  BD_ADDR dummy_bda = {0};
 
   if (p != NULL) {
     if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
       p->conn_addr_type = BLE_ADDR_RANDOM;
-      if (memcmp(local_rpa, dummy_bda, BD_ADDR_LEN))
-        memcpy(p->conn_addr, local_rpa, BD_ADDR_LEN);
+      if (!local_rpa.IsEmpty())
+        p->conn_addr = local_rpa;
       else
-        memcpy(p->conn_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr,
-               BD_ADDR_LEN);
+        p->conn_addr = btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr;
     } else {
       p->conn_addr_type = BLE_ADDR_PUBLIC;
-      memcpy(p->conn_addr, &controller_get_interface()->get_address()->address,
-             BD_ADDR_LEN);
+      p->conn_addr = *controller_get_interface()->get_address();
     }
   }
 #endif
diff --git a/stack/btm/btm_ble_adv_filter.cc b/stack/btm/btm_ble_adv_filter.cc
index 5f264d0..eb3fc4d 100644
--- a/stack/btm/btm_ble_adv_filter.cc
+++ b/stack/btm/btm_ble_adv_filter.cc
@@ -52,7 +52,6 @@
 
 tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb;
 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
-static const BD_ADDR na_bda = {0};
 
 static uint8_t btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
                                             uint8_t cond_type,
@@ -213,8 +212,7 @@
   BTM_TRACE_DEBUG("%s: Recd: %d, %d, %d, %d, %d", __func__, op_subcode,
                   expected_ocf, action, status, num_avail);
   if (HCI_SUCCESS == status) {
-    if (memcmp(&btm_ble_adv_filt_cb.cur_filter_target.bda, &na_bda,
-               BD_ADDR_LEN) == 0)
+    if (btm_ble_adv_filt_cb.cur_filter_target.bda.IsEmpty())
       btm_ble_cs_update_pf_counter(action, cond_type, NULL, num_avail);
     else
       btm_ble_cs_update_pf_counter(
@@ -245,8 +243,7 @@
   if (p_le_bda == NULL) return &btm_ble_adv_filt_cb.p_addr_filter_count[0];
 
   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
-    if (p_addr_filter->in_use &&
-        memcmp(p_le_bda->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) {
+    if (p_addr_filter->in_use && p_le_bda->bda == p_addr_filter->bd_addr) {
       return p_addr_filter;
     }
   }
@@ -263,14 +260,15 @@
  *                  otherwise.
  *
  ******************************************************************************/
-tBTM_BLE_PF_COUNT* btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr) {
+tBTM_BLE_PF_COUNT* btm_ble_alloc_addr_filter_counter(
+    const RawAddress& bd_addr) {
   uint8_t i;
   tBTM_BLE_PF_COUNT* p_addr_filter =
       &btm_ble_adv_filt_cb.p_addr_filter_count[1];
 
   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
-    if (memcmp(na_bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) {
-      memcpy(p_addr_filter->bd_addr, bd_addr, BD_ADDR_LEN);
+    if (p_addr_filter->bd_addr.IsEmpty()) {
+      p_addr_filter->bd_addr = bd_addr;
       p_addr_filter->in_use = true;
       return p_addr_filter;
     }
@@ -298,14 +296,12 @@
            sizeof(tBTM_BLE_PF_COUNT));
 
   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
-    if ((p_addr_filter->in_use) &&
-        (NULL == p_bd_addr ||
-         (NULL != p_bd_addr &&
-          memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) {
+    if (p_addr_filter->in_use &&
+        (!p_bd_addr || p_bd_addr->bda == p_addr_filter->bd_addr)) {
       found = true;
       memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT));
 
-      if (NULL != p_bd_addr) break;
+      if (p_bd_addr) break;
     }
   }
   return found;
diff --git a/stack/btm/btm_ble_batchscan.cc b/stack/btm/btm_ble_batchscan.cc
index 21900e9..a0b159c 100644
--- a/stack/btm/btm_ble_batchscan.cc
+++ b/stack/btm/btm_ble_batchscan.cc
@@ -85,7 +85,7 @@
       STREAM_TO_UINT8(adv_data.filt_index, p);
       STREAM_TO_UINT8(adv_data.advertiser_state, p);
       STREAM_TO_UINT8(adv_data.advertiser_info_present, p);
-      STREAM_TO_BDADDR(adv_data.bd_addr.address, p);
+      STREAM_TO_BDADDR(adv_data.bd_addr, p);
       STREAM_TO_UINT8(adv_data.addr_type, p);
 
       /* Extract the adv info details */
@@ -112,7 +112,7 @@
       /* Based on L-release version */
       STREAM_TO_UINT8(adv_data.filt_index, p);
       STREAM_TO_UINT8(adv_data.addr_type, p);
-      STREAM_TO_BDADDR(adv_data.bd_addr.address, p);
+      STREAM_TO_BDADDR(adv_data.bd_addr, p);
       STREAM_TO_UINT8(adv_data.advertiser_state, p);
     }
 
@@ -121,7 +121,7 @@
                     adv_data.advertiser_state);
 
     // Make sure the device is known
-    BTM_SecAddBleDevice(adv_data.bd_addr.address, NULL, BT_DEVICE_TYPE_BLE,
+    BTM_SecAddBleDevice(adv_data.bd_addr, NULL, BT_DEVICE_TYPE_BLE,
                         adv_data.addr_type);
 
     ble_advtrack_cb.p_track_cback(&adv_data);
diff --git a/stack/btm/btm_ble_bgconn.cc b/stack/btm/btm_ble_bgconn.cc
index c3d8dbb..f2f8307 100644
--- a/stack/btm/btm_ble_bgconn.cc
+++ b/stack/btm/btm_ble_bgconn.cc
@@ -49,7 +49,7 @@
 // peripherals or not.
 // TODO: Move all of this to controller/le/background_list or similar?
 typedef struct background_connection_t {
-  bt_bdaddr_t address;
+  RawAddress address;
   uint8_t addr_type;
 
   bool in_controller_wl;
@@ -59,30 +59,22 @@
 } background_connection_t;
 
 struct BgConnHash {
-  bool operator()(const bt_bdaddr_t& x) const {
+  bool operator()(const RawAddress& x) const {
     const uint8_t* a = x.address;
     return a[0] ^ (a[1] << 8) ^ (a[2] << 16) ^ (a[3] << 24) ^ a[4] ^
            (a[5] << 8);
   }
 };
 
-struct BgConnKeyEqual {
-  bool operator()(const bt_bdaddr_t& x, const bt_bdaddr_t& y) const {
-    return bdaddr_equals(&x, &y);
-  }
-};
-
-static std::unordered_map<bt_bdaddr_t, background_connection_t, BgConnHash,
-                          BgConnKeyEqual>
+static std::unordered_map<RawAddress, background_connection_t, BgConnHash>
     background_connections;
 
-static void background_connection_add(uint8_t addr_type, bt_bdaddr_t* address) {
-  CHECK(address);
-
-  auto map_iter = background_connections.find(*address);
+static void background_connection_add(uint8_t addr_type,
+                                      const RawAddress& address) {
+  auto map_iter = background_connections.find(address);
   if (map_iter == background_connections.end()) {
-    background_connections[*address] =
-        background_connection_t{*address, addr_type, false, 0, false};
+    background_connections[address] =
+        background_connection_t{address, addr_type, false, 0, false};
   } else {
     background_connection_t* connection = &map_iter->second;
     connection->addr_type = addr_type;
@@ -90,8 +82,8 @@
   }
 }
 
-static void background_connection_remove(bt_bdaddr_t* address) {
-  auto map_iter = background_connections.find(*address);
+static void background_connection_remove(const RawAddress& address) {
+  auto map_iter = background_connections.find(address);
   if (map_iter != background_connections.end()) {
     if (map_iter->second.in_controller_wl) {
       map_iter->second.pending_removal = true;
@@ -108,7 +100,7 @@
     background_connection_t* connection = &map_el.second;
     if (connection->pending_removal) continue;
     const bool connected =
-        BTM_IsAclConnectionUp(connection->address.address, BT_TRANSPORT_LE);
+        BTM_IsAclConnectionUp(connection->address, BT_TRANSPORT_LE);
     if (!connected) {
       return true;
     }
@@ -162,12 +154,10 @@
  * Parameters       bd_addr: updated device
  *
  ******************************************************************************/
-void btm_ble_bgconn_cancel_if_disconnected(BD_ADDR bd_addr) {
+void btm_ble_bgconn_cancel_if_disconnected(const RawAddress& bd_addr) {
   if (btm_cb.ble_ctr_cb.conn_state != BLE_BG_CONN) return;
 
-  bt_bdaddr_t addr = *(bt_bdaddr_t*)bd_addr;
-
-  auto map_it = background_connections.find(addr);
+  auto map_it = background_connections.find(bd_addr);
   if (map_it != background_connections.end()) {
     background_connection_t* connection = &map_it->second;
     if (!connection->in_controller_wl && !connection->pending_removal &&
@@ -183,38 +173,34 @@
  *
  * Description      This function load the device into controller white list
  ******************************************************************************/
-bool btm_add_dev_to_controller(bool to_add, BD_ADDR bd_addr) {
+bool btm_add_dev_to_controller(bool to_add, const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   bool started = false;
-  BD_ADDR dummy_bda = {0};
 
   if (p_dev_rec != NULL && p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) {
     if (to_add) {
       if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC ||
           !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) {
-        background_connection_add(p_dev_rec->ble.ble_addr_type,
-                                  (bt_bdaddr_t*)bd_addr);
+        background_connection_add(p_dev_rec->ble.ble_addr_type, bd_addr);
         started = true;
         p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT;
-      } else if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) !=
-                     0 &&
-                 memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) !=
-                     0) {
+      } else if (p_dev_rec->ble.static_addr != bd_addr &&
+                 !p_dev_rec->ble.static_addr.IsEmpty()) {
         background_connection_add(p_dev_rec->ble.static_addr_type,
-                                  (bt_bdaddr_t*)p_dev_rec->ble.static_addr);
+                                  p_dev_rec->ble.static_addr);
         started = true;
         p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT;
       }
     } else {
       if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC ||
           !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) {
-        background_connection_remove((bt_bdaddr_t*)bd_addr);
+        background_connection_remove(bd_addr);
         started = true;
       }
 
-      if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0 &&
-          memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0) {
-        background_connection_remove((bt_bdaddr_t*)p_dev_rec->ble.static_addr);
+      if (!p_dev_rec->ble.static_addr.IsEmpty() &&
+          p_dev_rec->ble.static_addr != bd_addr) {
+        background_connection_remove(p_dev_rec->ble.static_addr);
         started = true;
       }
 
@@ -223,13 +209,11 @@
   } else {
     /* not a known device, i.e. attempt to connect to device never seen before
      */
-    uint8_t addr_type =
-        BTM_IS_PUBLIC_BDA(bd_addr) ? BLE_ADDR_PUBLIC : BLE_ADDR_RANDOM;
     started = true;
     if (to_add)
-      background_connection_add(addr_type, (bt_bdaddr_t*)bd_addr);
+      background_connection_add(BLE_ADDR_PUBLIC, bd_addr);
     else
-      background_connection_remove((bt_bdaddr_t*)bd_addr);
+      background_connection_remove(bd_addr);
   }
 
   return started;
@@ -248,7 +232,7 @@
     background_connection_t* connection = &map_it->second;
     if (connection->pending_removal) {
       btsnd_hcic_ble_remove_from_white_list(connection->addr_type_in_wl,
-                                            connection->address.address);
+                                            connection->address);
       map_it = background_connections.erase(map_it);
     } else
       ++map_it;
@@ -256,10 +240,9 @@
   for (auto& map_el : background_connections) {
     background_connection_t* connection = &map_el.second;
     const bool connected =
-        BTM_IsAclConnectionUp(connection->address.address, BT_TRANSPORT_LE);
+        BTM_IsAclConnectionUp(connection->address, BT_TRANSPORT_LE);
     if (!connection->in_controller_wl && !connected) {
-      btsnd_hcic_ble_add_white_list(connection->addr_type,
-                                    connection->address.address);
+      btsnd_hcic_ble_add_white_list(connection->addr_type, connection->address);
       connection->in_controller_wl = true;
       connection->addr_type_in_wl = connection->addr_type;
     } else if (connection->in_controller_wl && connected) {
@@ -268,7 +251,7 @@
          correctly, therefore we must make sure connected devices are not in
          the white list when bg connection attempt is active. */
       btsnd_hcic_ble_remove_from_white_list(connection->addr_type_in_wl,
-                                            connection->address.address);
+                                            connection->address);
       connection->in_controller_wl = false;
     }
   }
@@ -283,7 +266,7 @@
  *                  the white list.
  *
  ******************************************************************************/
-bool btm_update_dev_to_white_list(bool to_add, BD_ADDR bd_addr) {
+bool btm_update_dev_to_white_list(bool to_add, const RawAddress& bd_addr) {
   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
 
   if (to_add &&
@@ -363,7 +346,7 @@
 
 void btm_send_hci_create_connection(
     uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
-    uint8_t addr_type_peer, BD_ADDR bda_peer, uint8_t addr_type_own,
+    uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
     uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
     uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
     uint8_t initiating_phys) {
@@ -412,7 +395,6 @@
  ******************************************************************************/
 bool btm_ble_start_auto_conn(bool start) {
   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
-  BD_ADDR dummy_bda = {0};
   bool exec = true;
   uint16_t scan_int;
   uint16_t scan_win;
@@ -455,7 +437,7 @@
           scan_win,                       /* uint16_t scan_win      */
           0x01,                           /* uint8_t white_list     */
           peer_addr_type,                 /* uint8_t addr_type_peer */
-          dummy_bda,                      /* BD_ADDR bda_peer     */
+          RawAddress::kEmpty,             /* BD_ADDR bda_peer     */
           own_addr_type,                  /* uint8_t addr_type_own */
           BTM_BLE_CONN_INT_MIN_DEF,       /* uint16_t conn_int_min  */
           BTM_BLE_CONN_INT_MAX_DEF,       /* uint16_t conn_int_max  */
@@ -604,7 +586,7 @@
  * Returns          None.
  *
  ******************************************************************************/
-void btm_ble_dequeue_direct_conn_req(BD_ADDR rem_bda) {
+void btm_ble_dequeue_direct_conn_req(const RawAddress& rem_bda) {
   if (fixed_queue_is_empty(btm_cb.ble_ctr_cb.conn_pending_q)) return;
 
   list_t* list = fixed_queue_get_list(btm_cb.ble_ctr_cb.conn_pending_q);
@@ -616,7 +598,7 @@
       continue;
     }
     // If BD address matches
-    if (!memcmp(rem_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN)) {
+    if (rem_bda == p_lcb->remote_bd_addr) {
       fixed_queue_try_remove_from_queue(btm_cb.ble_ctr_cb.conn_pending_q,
                                         p_req);
       l2cu_release_lcb((tL2C_LCB*)p_req->p_param);
diff --git a/stack/btm/btm_ble_gap.cc b/stack/btm/btm_ble_gap.cc
index fe093e2..341d85d 100644
--- a/stack/btm/btm_ble_gap.cc
+++ b/stack/btm/btm_ble_gap.cc
@@ -60,14 +60,12 @@
 #define MIN_ADV_LENGTH 2
 #define BTM_VSC_CHIP_CAPABILITY_RSP_LEN_L_RELEASE 9
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 namespace {
 
 class AdvertisingCache {
  public:
   /* Set the data to |data| for device |addr_type, addr| */
-  const std::vector<uint8_t>& Set(uint8_t addr_type, BD_ADDR addr,
+  const std::vector<uint8_t>& Set(uint8_t addr_type, const RawAddress& addr,
                                   std::vector<uint8_t> data) {
     auto it = Find(addr_type, addr);
     if (it != items.end()) {
@@ -84,7 +82,7 @@
   }
 
   /* Append |data| for device |addr_type, addr| */
-  const std::vector<uint8_t>& Append(uint8_t addr_type, BD_ADDR addr,
+  const std::vector<uint8_t>& Append(uint8_t addr_type, const RawAddress& addr,
                                      std::vector<uint8_t> data) {
     auto it = Find(addr_type, addr);
     if (it != items.end()) {
@@ -101,7 +99,7 @@
   }
 
   /* Clear data for device |addr_type, addr| */
-  void Clear(uint8_t addr_type, BD_ADDR addr) {
+  void Clear(uint8_t addr_type, const RawAddress& addr) {
     auto it = Find(addr_type, addr);
     if (it != items.end()) {
       items.erase(it);
@@ -111,19 +109,16 @@
  private:
   struct Item {
     uint8_t addr_type;
-    BD_ADDR addr;
+    RawAddress addr;
     std::vector<uint8_t> data;
 
-    Item(uint8_t addr_type, BD_ADDR addr, std::vector<uint8_t> data)
-        : addr_type(addr_type), data(data) {
-      memcpy(this->addr, addr, BD_ADDR_LEN);
-    }
+    Item(uint8_t addr_type, const RawAddress& addr, std::vector<uint8_t> data)
+        : addr_type(addr_type), addr(addr), data(data) {}
   };
 
-  std::list<Item>::iterator Find(uint8_t addr_type, BD_ADDR addr) {
+  std::list<Item>::iterator Find(uint8_t addr_type, const RawAddress& addr) {
     for (auto it = items.begin(); it != items.end(); it++) {
-      if (it->addr_type == addr_type &&
-          memcmp(it->addr, addr, BD_ADDR_LEN) == 0) {
+      if (it->addr_type == addr_type && it->addr == addr) {
         return it;
       }
     }
@@ -150,11 +145,12 @@
  ******************************************************************************/
 static void btm_ble_update_adv_flag(uint8_t flag);
 static void btm_ble_process_adv_pkt_cont(
-    uint16_t evt_type, uint8_t addr_type, BD_ADDR bda, uint8_t primary_phy,
-    uint8_t secondary_phy, uint8_t advertising_sid, int8_t tx_power,
-    int8_t rssi, uint16_t periodic_adv_int, uint8_t data_len, uint8_t* data);
+    uint16_t evt_type, uint8_t addr_type, const RawAddress& bda,
+    uint8_t primary_phy, uint8_t secondary_phy, uint8_t advertising_sid,
+    int8_t tx_power, int8_t rssi, uint16_t periodic_adv_int, uint8_t data_len,
+    uint8_t* data);
 static uint8_t btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB* p_cb,
-                                               BD_ADDR_PTR p_peer_addr_ptr,
+                                               RawAddress& p_peer_addr_ptr,
                                                tBLE_ADDR_TYPE* p_peer_addr_type,
                                                tBLE_ADDR_TYPE* p_own_addr_type);
 static void btm_ble_stop_observe(void);
@@ -191,243 +187,163 @@
   return (evt_type >> 5) & 3;
 }
 
+constexpr uint8_t UNSUPPORTED = 255;
+
 /* LE states combo bit to check */
-const uint8_t btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] =
-    {{
-         /* single state support */
-         {HCI_SUPP_LE_STATES_CONN_ADV_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_OFF}, /* conn_adv */
-         {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* init */
-         {HCI_SUPP_LE_STATES_INIT_MASK,
-          HCI_SUPP_LE_STATES_INIT_OFF}, /* master */
-         {HCI_SUPP_LE_STATES_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_SLAVE_OFF}, /* slave */
-         {0, 0}, /* todo: lo du dir adv, not covered ? */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF}, /* hi duty dir adv */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF}, /* non connectable adv */
-         {HCI_SUPP_LE_STATES_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_PASS_SCAN_OFF}, /*  passive scan */
-         {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF}, /*   active scan */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_MASK,
-          HCI_SUPP_LE_STATESSCAN_ADV_OFF} /* scanable adv */
-     },
-     {
-         /* conn_adv =0 */
-         {0, 0}, /* conn_adv */
-         {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* init: 32 */
-         {HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF}, /* master: 35 */
-         {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* slave: 38,*/
-         {0, 0},                                  /* lo du dir adv */
-         {0, 0},                                  /* hi duty dir adv */
-         {0, 0},                                  /* non connectable adv */
-         {HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF}, /*  passive scan */
-         {HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF}, /*   active scan */
-         {0, 0}                                         /* scanable adv */
-     },
-     {
-         /* init */
-         {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* conn_adv: 32 */
-         {0, 0},                                 /* init */
-         {HCI_SUPP_LE_STATES_INIT_MASTER_MASK,
-          HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* master 28 */
-         {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* slave 41 */
-         {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF}, /* lo du dir adv 34 */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF}, /* hi duty dir adv 33 */
-         {HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF}, /*  non connectable adv */
-         {HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK,
-          HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF}, /* passive scan */
-         {HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK,
-          HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF}, /*  active scan */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF} /* scanable adv */
+const uint8_t btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX] = {
+    {
+        /* single state support */
+        HCI_LE_STATES_CONN_ADV_BIT, /* conn_adv */
+        HCI_LE_STATES_INIT_BIT,     /* init */
+        HCI_LE_STATES_INIT_BIT,     /* master */
+        HCI_LE_STATES_SLAVE_BIT,    /* slave */
+        UNSUPPORTED,                /* todo: lo du dir adv, not covered ? */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_BIT, /* hi duty dir adv */
+        HCI_LE_STATES_NON_CONN_ADV_BIT,    /* non connectable adv */
+        HCI_LE_STATES_PASS_SCAN_BIT,       /*  passive scan */
+        HCI_LE_STATES_ACTIVE_SCAN_BIT,     /*   active scan */
+        HCI_LE_STATES_SCAN_ADV_BIT         /* scanable adv */
+    },
+    {
+        /* conn_adv =0 */
+        UNSUPPORTED,                            /* conn_adv */
+        HCI_LE_STATES_CONN_ADV_INIT_BIT,        /* init: 32 */
+        HCI_LE_STATES_CONN_ADV_MASTER_BIT,      /* master: 35 */
+        HCI_LE_STATES_CONN_ADV_SLAVE_BIT,       /* slave: 38,*/
+        UNSUPPORTED,                            /* lo du dir adv */
+        UNSUPPORTED,                            /* hi duty dir adv */
+        UNSUPPORTED,                            /* non connectable adv */
+        HCI_LE_STATES_CONN_ADV_PASS_SCAN_BIT,   /*  passive scan */
+        HCI_LE_STATES_CONN_ADV_ACTIVE_SCAN_BIT, /*   active scan */
+        UNSUPPORTED                             /* scanable adv */
+    },
+    {
+        /* init */
+        HCI_LE_STATES_CONN_ADV_INIT_BIT,        /* conn_adv: 32 */
+        UNSUPPORTED,                            /* init */
+        HCI_LE_STATES_INIT_MASTER_BIT,          /* master 28 */
+        HCI_LE_STATES_INIT_MASTER_SLAVE_BIT,    /* slave 41 */
+        HCI_LE_STATES_LO_DUTY_DIR_ADV_INIT_BIT, /* lo du dir adv 34 */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_INIT_BIT, /* hi duty dir adv 33 */
+        HCI_LE_STATES_NON_CONN_INIT_BIT,        /*  non connectable adv */
+        HCI_LE_STATES_PASS_SCAN_INIT_BIT,       /* passive scan */
+        HCI_LE_STATES_ACTIVE_SCAN_INIT_BIT,     /*  active scan */
+        HCI_LE_STATES_SCAN_ADV_INIT_BIT         /* scanable adv */
 
-     },
-     {
-         /* master */
-         {HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF}, /* conn_adv: 35 */
-         {HCI_SUPP_LE_STATES_INIT_MASTER_MASK,
-          HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* init 28 */
-         {HCI_SUPP_LE_STATES_INIT_MASTER_MASK,
-          HCI_SUPP_LE_STATES_INIT_MASTER_OFF}, /* master 28 */
-         {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF}, /* slave: 32 */
-         {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF}, /* lo duty cycle adv
-                                                             37 */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF}, /* hi duty cycle adv
-                                                             36 */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF}, /*  non connectable adv
-                                                          */
-         {HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK,
-          HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF}, /*  passive scan */
-         {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK,
-          HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF}, /*   active scan */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF} /*  scanable adv */
+    },
+    {
+        /* master */
+        HCI_LE_STATES_CONN_ADV_MASTER_BIT,        /* conn_adv: 35 */
+        HCI_LE_STATES_INIT_MASTER_BIT,            /* init 28 */
+        HCI_LE_STATES_INIT_MASTER_BIT,            /* master 28 */
+        HCI_LE_STATES_CONN_ADV_INIT_BIT,          /* slave: 32 */
+        HCI_LE_STATES_LO_DUTY_DIR_ADV_MASTER_BIT, /* lo duty cycle adv 37 */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_MASTER_BIT, /* hi duty cycle adv 36 */
+        HCI_LE_STATES_NON_CONN_ADV_MASTER_BIT,    /*  non connectable adv*/
+        HCI_LE_STATES_PASS_SCAN_MASTER_BIT,       /*  passive scan */
+        HCI_LE_STATES_ACTIVE_SCAN_MASTER_BIT,     /*   active scan */
+        HCI_LE_STATES_SCAN_ADV_MASTER_BIT         /*  scanable adv */
 
-     },
-     {
-         /* slave */
-         {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* conn_adv: 38,*/
-         {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* init 41 */
-         {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* master 41 */
-         {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* slave: 38,*/
-         {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF}, /* lo duty cycle adv 40
-                                                            */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF}, /* hi duty cycle adv 39
-                                                            */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF}, /* non connectable adv */
-         {HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF}, /* passive scan */
-         {HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF}, /*  active scan */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF} /* scanable adv */
+    },
+    {
+        /* slave */
+        HCI_LE_STATES_CONN_ADV_SLAVE_BIT,        /* conn_adv: 38,*/
+        HCI_LE_STATES_INIT_MASTER_SLAVE_BIT,     /* init 41 */
+        HCI_LE_STATES_INIT_MASTER_SLAVE_BIT,     /* master 41 */
+        HCI_LE_STATES_CONN_ADV_SLAVE_BIT,        /* slave: 38,*/
+        HCI_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_BIT, /* lo duty cycle adv 40 */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_BIT, /* hi duty cycle adv 39 */
+        HCI_LE_STATES_NON_CONN_ADV_SLAVE_BIT,    /* non connectable adv */
+        HCI_LE_STATES_PASS_SCAN_SLAVE_BIT,       /* passive scan */
+        HCI_LE_STATES_ACTIVE_SCAN_SLAVE_BIT,     /*  active scan */
+        HCI_LE_STATES_SCAN_ADV_SLAVE_BIT         /* scanable adv */
 
-     },
-     {
-         /* lo duty cycle adv */
-         {0, 0}, /* conn_adv: 38,*/
-         {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF}, /* init 34 */
-         {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF}, /* master 37 */
-         {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF}, /* slave: 40 */
-         {0, 0}, /* lo duty cycle adv 40 */
-         {0, 0}, /* hi duty cycle adv 39 */
-         {0, 0}, /*  non connectable adv */
-         {0, 0}, /* TODO: passive scan, not covered? */
-         {0, 0}, /* TODO:  active scan, not covered? */
-         {0, 0}  /*  scanable adv */
-     },
-     {
-         /* hi duty cycle adv */
-         {0, 0}, /* conn_adv: 38,*/
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF}, /* init 33 */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF}, /* master 36 */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF}, /* slave: 39*/
-         {0, 0}, /* lo duty cycle adv 40 */
-         {0, 0}, /* hi duty cycle adv 39 */
-         {0, 0}, /* non connectable adv */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF}, /* passive scan */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF}, /* active scan */
-         {0, 0} /* scanable adv */
-     },
-     {
-         /* non connectable adv */
-         {0, 0}, /* conn_adv: */
-         {HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF}, /* init  */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF}, /* master  */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF}, /* slave: */
-         {0, 0},                                      /* lo duty cycle adv */
-         {0, 0},                                      /* hi duty cycle adv */
-         {0, 0},                                      /* non connectable adv */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF}, /* passive scan */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF}, /*  active scan */
-         {0, 0}                                             /* scanable adv */
-     },
-     {
-         /* passive scan */
-         {HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF}, /* conn_adv: */
-         {HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK,
-          HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF}, /* init  */
-         {HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK,
-          HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF}, /* master  */
-         {HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF}, /* slave: */
-         {0, 0},                                   /* lo duty cycle adv */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF}, /* hi duty cycle
-                                                                adv */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF}, /*  non connectable
-                                                             adv */
-         {0, 0},                                          /* passive scan */
-         {0, 0},                                          /* active scan */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF} /* scanable adv */
-     },
-     {
-         /* active scan */
-         {HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF}, /* conn_adv: */
-         {HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK,
-          HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF}, /* init  */
-         {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK,
-          HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF}, /* master  */
-         {HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF}, /* slave: */
-         {0, 0},                                     /* lo duty cycle adv */
-         {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF}, /* hi duty
-                                                                  cycle adv
-                                                                  */
-         {HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF}, /*  non
-                                                               connectable
-                                                               adv */
-         {0, 0}, /* TODO: passive scan */
-         {0, 0}, /* TODO:  active scan */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF} /*  scanable adv */
-     },
-     {
-         /* scanable adv */
-         {0, 0}, /* conn_adv: */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF}, /* init  */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF}, /* master  */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF}, /* slave: */
-         {0, 0},                                  /* lo duty cycle adv */
-         {0, 0},                                  /* hi duty cycle adv */
-         {0, 0},                                  /* non connectable adv */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF}, /*  passive scan */
-         {HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK,
-          HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF}, /*  active scan */
-         {0, 0}                                         /* scanable adv */
-     }
+    },
+    {
+        /* lo duty cycle adv */
+        UNSUPPORTED,                              /* conn_adv: 38,*/
+        HCI_LE_STATES_LO_DUTY_DIR_ADV_INIT_BIT,   /* init 34 */
+        HCI_LE_STATES_LO_DUTY_DIR_ADV_MASTER_BIT, /* master 37 */
+        HCI_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_BIT,  /* slave: 40 */
+        UNSUPPORTED,                              /* lo duty cycle adv 40 */
+        UNSUPPORTED,                              /* hi duty cycle adv 39 */
+        UNSUPPORTED,                              /*  non connectable adv */
+        UNSUPPORTED, /* TODO: passive scan, not covered? */
+        UNSUPPORTED, /* TODO:  active scan, not covered? */
+        UNSUPPORTED  /*  scanable adv */
+    },
+    {
+        /* hi duty cycle adv */
+        UNSUPPORTED,                                 /* conn_adv: 38,*/
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_INIT_BIT,      /* init 33 */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_MASTER_BIT,    /* master 36 */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_BIT,     /* slave: 39*/
+        UNSUPPORTED,                                 /* lo duty cycle adv 40 */
+        UNSUPPORTED,                                 /* hi duty cycle adv 39 */
+        UNSUPPORTED,                                 /* non connectable adv */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_BIT, /* passive scan */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_BIT, /* active scan */
+        UNSUPPORTED                                    /* scanable adv */
+    },
+    {
+        /* non connectable adv */
+        UNSUPPORTED,                                /* conn_adv: */
+        HCI_LE_STATES_NON_CONN_INIT_BIT,            /* init  */
+        HCI_LE_STATES_NON_CONN_ADV_MASTER_BIT,      /* master  */
+        HCI_LE_STATES_NON_CONN_ADV_SLAVE_BIT,       /* slave: */
+        UNSUPPORTED,                                /* lo duty cycle adv */
+        UNSUPPORTED,                                /* hi duty cycle adv */
+        UNSUPPORTED,                                /* non connectable adv */
+        HCI_LE_STATES_NON_CONN_ADV_PASS_SCAN_BIT,   /* passive scan */
+        HCI_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_BIT, /* active scan */
+        UNSUPPORTED                                 /* scanable adv */
+    },
+    {
+        /* passive scan */
+        HCI_LE_STATES_CONN_ADV_PASS_SCAN_BIT,        /* conn_adv: */
+        HCI_LE_STATES_PASS_SCAN_INIT_BIT,            /* init  */
+        HCI_LE_STATES_PASS_SCAN_MASTER_BIT,          /* master  */
+        HCI_LE_STATES_PASS_SCAN_SLAVE_BIT,           /* slave: */
+        UNSUPPORTED,                                 /* lo duty cycle adv */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_BIT, /* hi duty cycle adv */
+        HCI_LE_STATES_NON_CONN_ADV_PASS_SCAN_BIT,    /* non connectable adv */
+        UNSUPPORTED,                                 /* passive scan */
+        UNSUPPORTED,                                 /* active scan */
+        HCI_LE_STATES_SCAN_ADV_PASS_SCAN_BIT         /* scanable adv */
+    },
+    {
+        /* active scan */
+        HCI_LE_STATES_CONN_ADV_ACTIVE_SCAN_BIT,        /* conn_adv: */
+        HCI_LE_STATES_ACTIVE_SCAN_INIT_BIT,            /* init  */
+        HCI_LE_STATES_ACTIVE_SCAN_MASTER_BIT,          /* master  */
+        HCI_LE_STATES_ACTIVE_SCAN_SLAVE_BIT,           /* slave: */
+        UNSUPPORTED,                                   /* lo duty cycle adv */
+        HCI_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_BIT, /* hi duty cycle adv */
+        HCI_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_BIT, /*  non connectable adv */
+        UNSUPPORTED,                                /* TODO: passive scan */
+        UNSUPPORTED,                                /* TODO:  active scan */
+        HCI_LE_STATES_SCAN_ADV_ACTIVE_SCAN_BIT      /*  scanable adv */
+    },
+    {
+        /* scanable adv */
+        UNSUPPORTED,                            /* conn_adv: */
+        HCI_LE_STATES_SCAN_ADV_INIT_BIT,        /* init  */
+        HCI_LE_STATES_SCAN_ADV_MASTER_BIT,      /* master  */
+        HCI_LE_STATES_SCAN_ADV_SLAVE_BIT,       /* slave: */
+        UNSUPPORTED,                            /* lo duty cycle adv */
+        UNSUPPORTED,                            /* hi duty cycle adv */
+        UNSUPPORTED,                            /* non connectable adv */
+        HCI_LE_STATES_SCAN_ADV_PASS_SCAN_BIT,   /*  passive scan */
+        HCI_LE_STATES_SCAN_ADV_ACTIVE_SCAN_BIT, /*  active scan */
+        UNSUPPORTED                             /* scanable adv */
+    }};
 
-};
 /* check LE combo state supported */
-#define BTM_LE_STATES_SUPPORTED(x, y, z) ((x)[(z)] & (y))
+inline bool BTM_LE_STATES_SUPPORTED(const uint8_t* x, uint8_t bit_num) {
+  uint8_t mask = 1 << (bit_num % 8);
+  uint8_t offset = bit_num / 8;
+  return ((x)[offset] & mask);
+}
 
 /*******************************************************************************
  *
@@ -442,7 +358,7 @@
 void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) {
   tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var;
   tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC;
-  BD_ADDR p_addr_ptr = {0};
+  RawAddress adv_address = RawAddress::kEmpty;
   uint8_t adv_mode = p_cb->adv_mode;
 
   BTM_TRACE_EVENT("BTM_BleUpdateAdvFilterPolicy");
@@ -457,14 +373,14 @@
 
     if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE)
       p_cb->evt_type = btm_set_conn_mode_adv_init_addr(
-          p_cb, p_addr_ptr, &init_addr_type, &p_cb->adv_addr_type);
+          p_cb, adv_address, &init_addr_type, &p_cb->adv_addr_type);
 
     btsnd_hcic_ble_write_adv_params(
         (uint16_t)(p_cb->adv_interval_min ? p_cb->adv_interval_min
                                           : BTM_BLE_GAP_ADV_SLOW_INT),
         (uint16_t)(p_cb->adv_interval_max ? p_cb->adv_interval_max
                                           : BTM_BLE_GAP_ADV_SLOW_INT),
-        p_cb->evt_type, p_cb->adv_addr_type, init_addr_type, p_addr_ptr,
+        p_cb->evt_type, p_cb->adv_addr_type, init_addr_type, adv_address,
         p_cb->adv_chnl_map, p_cb->afp);
 
     if (adv_mode == BTM_BLE_ADV_ENABLE) btm_ble_start_adv();
@@ -537,9 +453,8 @@
       if (duration != 0) {
         /* start observer timer */
         period_ms_t duration_ms = duration * 1000;
-        alarm_set_on_queue(btm_cb.ble_ctr_cb.observer_timer, duration_ms,
-                           btm_ble_observer_timer_timeout, NULL,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(btm_cb.ble_ctr_cb.observer_timer, duration_ms,
+                           btm_ble_observer_timer_timeout, NULL);
       }
     }
   } else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) {
@@ -799,7 +714,7 @@
  *
  * Description      This function is called to clear the whitelist,
  *                  end any pending whitelist connections,
-*                   and reset the local bg device list.
+ *                  and reset the local bg device list.
  *
  * Parameters       void
  *
@@ -818,9 +733,8 @@
  *
  * Description      This function is called to add or remove a device into/from
  *                  background connection procedure. The background connection
-*                   procedure is decided by the background connection type, it
-*can be
-*                   auto connection, or selective connection.
+ *                  procedure is decided by the background connection type, it
+ *                  can be auto connection, or selective connection.
  *
  * Parameters       add_remove: true to add; false to remove.
  *                  remote_bda: device address to add/remove.
@@ -828,7 +742,7 @@
  * Returns          void
  *
  ******************************************************************************/
-bool BTM_BleUpdateBgConnDev(bool add_remove, BD_ADDR remote_bda) {
+bool BTM_BleUpdateBgConnDev(bool add_remove, const RawAddress& remote_bda) {
   BTM_TRACE_EVENT("%s() add=%d", __func__, add_remove);
   return btm_update_dev_to_white_list(add_remove, remote_bda);
 }
@@ -880,7 +794,7 @@
  *
  ******************************************************************************/
 static uint8_t btm_set_conn_mode_adv_init_addr(
-    tBTM_BLE_INQ_CB* p_cb, BD_ADDR_PTR p_peer_addr_ptr,
+    tBTM_BLE_INQ_CB* p_cb, RawAddress& p_peer_addr_ptr,
     tBLE_ADDR_TYPE* p_peer_addr_type, tBLE_ADDR_TYPE* p_own_addr_type) {
   uint8_t evt_type;
 #if (BLE_PRIVACY_SPT == TRUE)
@@ -906,7 +820,7 @@
         if ((p_dev_rec = btm_find_or_alloc_dev(p_cb->direct_bda.bda)) != NULL &&
             p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) {
           btm_ble_enable_resolving_list(BTM_BLE_RL_ADV);
-          memcpy(p_peer_addr_ptr, p_dev_rec->ble.static_addr, BD_ADDR_LEN);
+          p_peer_addr_ptr = p_dev_rec->ble.static_addr;
           *p_peer_addr_type = p_dev_rec->ble.static_addr_type;
           *p_own_addr_type = BLE_ADDR_RANDOM_ID;
           return evt_type;
@@ -919,7 +833,7 @@
 #endif
       /* direct adv mode does not have privacy, if privacy is not enabled  */
       *p_peer_addr_type = p_cb->direct_bda.type;
-      memcpy(p_peer_addr_ptr, p_cb->direct_bda.bda, BD_ADDR_LEN);
+      p_peer_addr_ptr = p_cb->direct_bda.bda;
       return evt_type;
     }
   }
@@ -937,7 +851,7 @@
        * peer */
       tBTM_SEC_DEV_REC* p_dev_rec =
           static_cast<tBTM_SEC_DEV_REC*>(list_node(n));
-      memcpy(p_peer_addr_ptr, p_dev_rec->ble.static_addr, BD_ADDR_LEN);
+      p_peer_addr_ptr = p_dev_rec->ble.static_addr;
       *p_peer_addr_type = p_dev_rec->ble.static_addr_type;
 
       *p_own_addr_type = BLE_ADDR_RANDOM_ID;
@@ -974,12 +888,12 @@
  *
  ******************************************************************************/
 tBTM_STATUS BTM_BleSetAdvParams(uint16_t adv_int_min, uint16_t adv_int_max,
-                                tBLE_BD_ADDR* p_dir_bda,
+                                const RawAddress& p_dir_bda,
                                 tBTM_BLE_ADV_CHNL_MAP chnl_map) {
   tBTM_LE_RANDOM_CB* p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
   tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var;
   tBTM_STATUS status = BTM_SUCCESS;
-  BD_ADDR p_addr_ptr = {0};
+  RawAddress address = RawAddress::kEmpty;
   tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC;
   tBLE_ADDR_TYPE own_addr_type = p_addr_cb->own_addr_type;
   uint8_t adv_mode = p_cb->adv_mode;
@@ -998,22 +912,19 @@
   p_cb->adv_interval_min = adv_int_min;
   p_cb->adv_interval_max = adv_int_max;
   p_cb->adv_chnl_map = chnl_map;
-
-  if (p_dir_bda) {
-    memcpy(&p_cb->direct_bda, p_dir_bda, sizeof(tBLE_BD_ADDR));
-  }
+  p_cb->direct_bda.bda = p_dir_bda;
 
   BTM_TRACE_EVENT("update params for an active adv");
 
   btm_ble_stop_adv();
 
   p_cb->evt_type = btm_set_conn_mode_adv_init_addr(
-      p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
+      p_cb, address, &init_addr_type, &own_addr_type);
 
   /* update adv params */
   btsnd_hcic_ble_write_adv_params(
       p_cb->adv_interval_min, p_cb->adv_interval_max, p_cb->evt_type,
-      own_addr_type, init_addr_type, p_addr_ptr, p_cb->adv_chnl_map, p_cb->afp);
+      own_addr_type, init_addr_type, address, p_cb->adv_chnl_map, p_cb->afp);
 
   if (adv_mode == BTM_BLE_ADV_ENABLE) btm_ble_start_adv();
 
@@ -1257,7 +1168,7 @@
   uint8_t new_mode = BTM_BLE_ADV_ENABLE;
   uint8_t evt_type;
   tBTM_STATUS status = BTM_SUCCESS;
-  BD_ADDR p_addr_ptr = {0};
+  RawAddress address = RawAddress::kEmpty;
   tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC,
                  own_addr_type = p_addr_cb->own_addr_type;
   uint16_t adv_int_min, adv_int_max;
@@ -1270,7 +1181,7 @@
 
   p_cb->discoverable_mode = mode;
 
-  evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type,
+  evt_type = btm_set_conn_mode_adv_init_addr(p_cb, address, &init_addr_type,
                                              &own_addr_type);
 
   if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE &&
@@ -1294,7 +1205,7 @@
 
       /* update adv params */
       btsnd_hcic_ble_write_adv_params(adv_int_min, adv_int_max, evt_type,
-                                      own_addr_type, init_addr_type, p_addr_ptr,
+                                      own_addr_type, init_addr_type, address,
                                       p_cb->adv_chnl_map, p_cb->afp);
       p_cb->evt_type = evt_type;
       p_cb->adv_addr_type = own_addr_type;
@@ -1311,9 +1222,8 @@
   if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
     p_cb->fast_adv_on = true;
     /* start initial GAP mode adv timer */
-    alarm_set_on_queue(p_cb->fast_adv_timer, BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS,
-                       btm_ble_fast_adv_timer_timeout, NULL,
-                       btu_general_alarm_queue);
+    alarm_set_on_mloop(p_cb->fast_adv_timer, BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS,
+                       btm_ble_fast_adv_timer_timeout, NULL);
   } else {
 #if (BLE_PRIVACY_SPT == TRUE)
     btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true);
@@ -1325,9 +1235,9 @@
     BTM_TRACE_EVENT("start timer for limited disc mode duration=%d ms",
                     BTM_BLE_GAP_LIM_TIMEOUT_MS);
     /* start Tgap(lim_timeout) */
-    alarm_set_on_queue(p_cb->inquiry_timer, BTM_BLE_GAP_LIM_TIMEOUT_MS,
+    alarm_set_on_mloop(p_cb->inquiry_timer, BTM_BLE_GAP_LIM_TIMEOUT_MS,
                        btm_ble_inquiry_timer_gap_limited_discovery_timeout,
-                       NULL, btu_general_alarm_queue);
+                       NULL);
   }
   return status;
 }
@@ -1350,7 +1260,7 @@
   uint8_t new_mode = BTM_BLE_ADV_ENABLE;
   uint8_t evt_type;
   tBTM_STATUS status = BTM_SUCCESS;
-  BD_ADDR p_addr_ptr = {0};
+  RawAddress address = RawAddress::kEmpty;
   tBLE_ADDR_TYPE peer_addr_type = BLE_ADDR_PUBLIC,
                  own_addr_type = p_addr_cb->own_addr_type;
   uint16_t adv_int_min, adv_int_max;
@@ -1363,7 +1273,7 @@
 
   p_cb->connectable_mode = mode;
 
-  evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &peer_addr_type,
+  evt_type = btm_set_conn_mode_adv_init_addr(p_cb, address, &peer_addr_type,
                                              &own_addr_type);
 
   if (mode == BTM_BLE_NON_CONNECTABLE &&
@@ -1381,7 +1291,7 @@
       btm_ble_stop_adv();
 
       btsnd_hcic_ble_write_adv_params(adv_int_min, adv_int_max, evt_type,
-                                      own_addr_type, peer_addr_type, p_addr_ptr,
+                                      own_addr_type, peer_addr_type, address,
                                       p_cb->adv_chnl_map, p_cb->afp);
       p_cb->evt_type = evt_type;
       p_cb->adv_addr_type = own_addr_type;
@@ -1399,9 +1309,8 @@
   if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
     p_cb->fast_adv_on = true;
     /* start initial GAP mode adv timer */
-    alarm_set_on_queue(p_cb->fast_adv_timer, BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS,
-                       btm_ble_fast_adv_timer_timeout, NULL,
-                       btu_general_alarm_queue);
+    alarm_set_on_mloop(p_cb->fast_adv_timer, BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS,
+                       btm_ble_fast_adv_timer_timeout, NULL);
   } else {
 #if (BLE_PRIVACY_SPT == TRUE)
     btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true);
@@ -1506,9 +1415,8 @@
     if (duration != 0) {
       /* start inquiry timer */
       period_ms_t duration_ms = duration * 1000;
-      alarm_set_on_queue(p_ble_cb->inq_var.inquiry_timer, duration_ms,
-                         btm_ble_inquiry_timer_timeout, NULL,
-                         btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ble_cb->inq_var.inquiry_timer, duration_ms,
+                         btm_ble_inquiry_timer_timeout, NULL);
     }
   }
 
@@ -1524,8 +1432,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_ble_read_remote_name_cmpl(bool status, BD_ADDR bda, uint16_t length,
-                                   char* p_name) {
+void btm_ble_read_remote_name_cmpl(bool status, const RawAddress& bda,
+                                   uint16_t length, char* p_name) {
   uint8_t hci_status = HCI_SUCCESS;
   BD_NAME bd_name;
 
@@ -1539,8 +1447,8 @@
     hci_status = HCI_ERR_HOST_TIMEOUT;
   }
 
-  btm_process_remote_name(bda, bd_name, length + 1, hci_status);
-  btm_sec_rmt_name_request_complete(bda, (uint8_t*)p_name, hci_status);
+  btm_process_remote_name(&bda, bd_name, length + 1, hci_status);
+  btm_sec_rmt_name_request_complete(&bda, (uint8_t*)p_name, hci_status);
 }
 
 /*******************************************************************************
@@ -1555,7 +1463,8 @@
  * Returns          void
  *
  ******************************************************************************/
-tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda, tBTM_CMPL_CB* p_cb) {
+tBTM_STATUS btm_ble_read_remote_name(const RawAddress& remote_bda,
+                                     tBTM_CMPL_CB* p_cb) {
   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
 
   if (!controller_get_interface()->supports_ble()) return BTM_ERR_PROCESSING;
@@ -1574,12 +1483,10 @@
 
   p_inq->p_remname_cmpl_cb = p_cb;
   p_inq->remname_active = true;
+  p_inq->remname_bda = remote_bda;
 
-  memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
-
-  alarm_set_on_queue(p_inq->remote_name_timer, BTM_EXT_BLE_RMT_NAME_TIMEOUT_MS,
-                     btm_inq_remote_name_timer_timeout, NULL,
-                     btu_general_alarm_queue);
+  alarm_set_on_mloop(p_inq->remote_name_timer, BTM_EXT_BLE_RMT_NAME_TIMEOUT_MS,
+                     btm_inq_remote_name_timer_timeout, NULL);
 
   return BTM_CMD_STARTED;
 }
@@ -1595,14 +1502,14 @@
  * Returns          void
  *
  ******************************************************************************/
-bool btm_ble_cancel_remote_name(BD_ADDR remote_bda) {
+bool btm_ble_cancel_remote_name(const RawAddress& remote_bda) {
   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
   bool status;
 
   status = GAP_BleCancelReadPeerDevName(remote_bda);
 
   p_inq->remname_active = false;
-  memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
+  p_inq->remname_bda = RawAddress::kEmpty;
   alarm_cancel(p_inq->remote_name_timer);
 
   return status;
@@ -1655,7 +1562,7 @@
  * Check ADV flag to make sure device is discoverable and match the search
  * condition
  */
-uint8_t btm_ble_is_discoverable(BD_ADDR bda,
+uint8_t btm_ble_is_discoverable(const RawAddress& bda,
                                 std::vector<uint8_t> const& adv_data) {
   uint8_t flag = 0, rt = 0;
   uint8_t data_len;
@@ -1667,7 +1574,7 @@
 
   /* does not match filter condition */
   if (p_cond->filter_cond_type == BTM_FILTER_COND_BD_ADDR &&
-      memcmp(bda, p_cond->filter_cond.bdaddr_cond, BD_ADDR_LEN) != 0) {
+      bda != p_cond->filter_cond.bdaddr_cond) {
     BTM_TRACE_DEBUG("BD ADDR does not meet filter condition");
     return rt;
   }
@@ -1822,11 +1729,11 @@
 /**
  * Update adv packet information into inquiry result.
  */
-void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type, BD_ADDR bda,
-                               uint16_t evt_type, uint8_t primary_phy,
-                               uint8_t secondary_phy, uint8_t advertising_sid,
-                               int8_t tx_power, int8_t rssi,
-                               uint16_t periodic_adv_int,
+void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type,
+                               const RawAddress& bda, uint16_t evt_type,
+                               uint8_t primary_phy, uint8_t secondary_phy,
+                               uint8_t advertising_sid, int8_t tx_power,
+                               int8_t rssi, uint16_t periodic_adv_int,
                                std::vector<uint8_t> const& data) {
   tBTM_INQ_RESULTS* p_cur = &p_i->inq_info.results;
   uint8_t len;
@@ -1934,25 +1841,24 @@
   }
 }
 
-void btm_ble_process_adv_addr(BD_ADDR bda, uint8_t addr_type) {
+void btm_ble_process_adv_addr(RawAddress& bda, uint8_t addr_type) {
 #if (BLE_PRIVACY_SPT == TRUE)
   /* map address to security record */
-  bool match = btm_identity_addr_to_random_pseudo(bda, &addr_type, false);
+  bool match = btm_identity_addr_to_random_pseudo(&bda, &addr_type, false);
 
-  BTM_TRACE_DEBUG("%s: bda= %0x:%0x:%0x:%0x:%0x:%0x", __func__, bda[0], bda[1],
-                  bda[2], bda[3], bda[4], bda[5]);
+  VLOG(1) << __func__ << ": bda=" << bda;
   /* always do RRA resolution on host */
   if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) {
     tBTM_SEC_DEV_REC* match_rec = btm_ble_resolve_random_addr(bda);
     if (match_rec) {
       match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
-      memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
+      match_rec->ble.cur_rand_addr = bda;
 
       if (btm_ble_init_pseudo_addr(match_rec, bda)) {
-        memcpy(bda, match_rec->bd_addr, BD_ADDR_LEN);
+        bda = match_rec->bd_addr;
       } else {
         // Assign the original address to be the current report address
-        memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN);
+        bda = match_rec->ble.pseudo_addr;
       }
     }
   }
@@ -1965,7 +1871,7 @@
  * entry is discarded.
  */
 void btm_ble_process_ext_adv_pkt(uint8_t data_len, uint8_t* data) {
-  BD_ADDR bda, direct_address;
+  RawAddress bda, direct_address;
   uint8_t* p = data;
   uint8_t addr_type, num_reports, pkt_data_len, primary_phy, secondary_phy,
       advertising_sid;
@@ -2022,7 +1928,7 @@
  * discarded.
  */
 void btm_ble_process_adv_pkt(uint8_t data_len, uint8_t* data) {
-  BD_ADDR bda;
+  RawAddress bda;
   uint8_t* p = data;
   uint8_t legacy_evt_type, addr_type, num_reports, pkt_data_len;
   int8_t rssi;
@@ -2091,9 +1997,10 @@
  * to process adv packet.
  */
 static void btm_ble_process_adv_pkt_cont(
-    uint16_t evt_type, uint8_t addr_type, BD_ADDR bda, uint8_t primary_phy,
-    uint8_t secondary_phy, uint8_t advertising_sid, int8_t tx_power,
-    int8_t rssi, uint16_t periodic_adv_int, uint8_t data_len, uint8_t* data) {
+    uint16_t evt_type, uint8_t addr_type, const RawAddress& bda,
+    uint8_t primary_phy, uint8_t secondary_phy, uint8_t advertising_sid,
+    int8_t tx_power, int8_t rssi, uint16_t periodic_adv_int, uint8_t data_len,
+    uint8_t* data) {
   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
   bool update = true;
 
@@ -2119,8 +2026,7 @@
 
   if (!data_complete) {
     // If we didn't receive whole adv data yet, don't report the device.
-    DVLOG(1) << "Data not complete yet, waiting for more "
-             << base::HexEncode(bda, BD_ADDR_LEN);
+    DVLOG(1) << "Data not complete yet, waiting for more " << bda;
     return;
   }
 
@@ -2128,8 +2034,7 @@
       btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_ACTI;
   if (is_active_scan && is_scannable && !is_scan_resp) {
     // If we didn't receive scan response yet, don't report the device.
-    DVLOG(1) << " Waiting for scan response "
-             << base::HexEncode(bda, BD_ADDR_LEN);
+    DVLOG(1) << " Waiting for scan response " << bda;
     return;
   }
 
@@ -2470,20 +2375,19 @@
 
   if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
     tBTM_LE_RANDOM_CB* p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
-    BD_ADDR p_addr_ptr = {0};
+    RawAddress address = RawAddress::kEmpty;
     tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC;
     tBLE_ADDR_TYPE own_addr_type = p_addr_cb->own_addr_type;
 
     btm_ble_stop_adv();
 
     p_cb->evt_type = btm_set_conn_mode_adv_init_addr(
-        p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
+        p_cb, address, &init_addr_type, &own_addr_type);
 
     /* slow adv mode never goes into directed adv */
-    btsnd_hcic_ble_write_adv_params(BTM_BLE_GAP_ADV_SLOW_INT,
-                                    BTM_BLE_GAP_ADV_SLOW_INT, p_cb->evt_type,
-                                    own_addr_type, init_addr_type, p_addr_ptr,
-                                    p_cb->adv_chnl_map, p_cb->afp);
+    btsnd_hcic_ble_write_adv_params(
+        BTM_BLE_GAP_ADV_SLOW_INT, BTM_BLE_GAP_ADV_SLOW_INT, p_cb->evt_type,
+        own_addr_type, init_addr_type, address, p_cb->adv_chnl_map, p_cb->afp);
 
     btm_ble_start_adv();
   }
@@ -2658,7 +2562,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_ble_update_mode_operation(uint8_t link_role, BD_ADDR bd_addr,
+void btm_ble_update_mode_operation(uint8_t link_role, const RawAddress* bd_addr,
                                    uint8_t status) {
   if (status == HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT) {
     btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
@@ -2675,7 +2579,7 @@
 
   /* in case of disconnected, we must cancel bgconn and restart
      in order to add back device to white list in order to reconnect */
-  btm_ble_bgconn_cancel_if_disconnected(bd_addr);
+  btm_ble_bgconn_cancel_if_disconnected(*bd_addr);
 
   /* when no connection is attempted, and controller is not rejecting last
      request
@@ -2752,7 +2656,6 @@
 
   uint8_t state_offset = 0;
   uint16_t cur_states = btm_cb.ble_ctr_cb.cur_states;
-  uint8_t mask, offset;
   uint8_t request_state = 0;
 
   /* check only one bit is set and within valid range */
@@ -2769,28 +2672,24 @@
   }
 
   /* check if the requested state is supported or not */
-  mask = btm_le_state_combo_tbl[0][request_state - 1][0];
-  offset = btm_le_state_combo_tbl[0][request_state - 1][1];
-
+  uint8_t bit_num = btm_le_state_combo_tbl[0][request_state - 1];
   const uint8_t* ble_supported_states =
       controller_get_interface()->get_ble_supported_states();
 
-  if (!BTM_LE_STATES_SUPPORTED(ble_supported_states, mask, offset)) {
+  if (!BTM_LE_STATES_SUPPORTED(ble_supported_states, bit_num)) {
     BTM_TRACE_ERROR("state requested not supported: %d", request_state);
     return rt;
   }
 
   rt = true;
   /* make sure currently active states are all supported in conjunction with the
-     requested
-     state. If the bit in table is not set, the combination is not supported */
+     requested state. If the bit in table is UNSUPPORTED, the combination is not
+     supported */
   while (cur_states != 0) {
     if (cur_states & 0x01) {
-      mask = btm_le_state_combo_tbl[request_state][state_offset][0];
-      offset = btm_le_state_combo_tbl[request_state][state_offset][1];
-
-      if (mask != 0 && offset != 0) {
-        if (!BTM_LE_STATES_SUPPORTED(ble_supported_states, mask, offset)) {
+      uint8_t bit_num = btm_le_state_combo_tbl[request_state][state_offset];
+      if (bit_num != UNSUPPORTED) {
+        if (!BTM_LE_STATES_SUPPORTED(ble_supported_states, bit_num)) {
           rt = false;
           break;
         }
diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h
index f7da237..895d6ba 100644
--- a/stack/btm/btm_ble_int.h
+++ b/stack/btm/btm_ble_int.h
@@ -41,9 +41,9 @@
 extern void btm_ble_process_phy_update_pkt(uint8_t len, uint8_t* p);
 extern void btm_ble_process_ext_adv_pkt(uint8_t len, uint8_t* p);
 extern void btm_ble_proc_scan_rsp_rpt(uint8_t* p);
-extern tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda,
+extern tBTM_STATUS btm_ble_read_remote_name(const RawAddress& remote_bda,
                                             tBTM_CMPL_CB* p_cb);
-extern bool btm_ble_cancel_remote_name(BD_ADDR remote_bda);
+extern bool btm_ble_cancel_remote_name(const RawAddress& remote_bda);
 
 extern tBTM_STATUS btm_ble_set_discoverability(uint16_t combined_mode);
 extern tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode);
@@ -59,9 +59,9 @@
 extern void btm_ble_stop_scan();
 extern void btm_ble_stop_inquiry(void);
 extern void btm_ble_init(void);
-extern void btm_ble_connected(uint8_t* bda, uint16_t handle, uint8_t enc_mode,
-                              uint8_t role, tBLE_ADDR_TYPE addr_type,
-                              bool addr_matched);
+extern void btm_ble_connected(const RawAddress& bda, uint16_t handle,
+                              uint8_t enc_mode, uint8_t role,
+                              tBLE_ADDR_TYPE addr_type, bool addr_matched);
 extern void btm_ble_read_remote_features_complete(uint8_t* p);
 extern void btm_ble_write_adv_enable_complete(uint8_t* p);
 extern void btm_ble_conn_complete(uint8_t* p, uint16_t evt_len, bool enhanced);
@@ -76,41 +76,48 @@
 extern void btm_ble_create_ll_conn_complete(uint8_t status);
 
 /* LE security function from btm_sec.cc */
-extern void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req,
+extern void btm_ble_link_sec_check(const RawAddress& bd_addr,
+                                   tBTM_LE_AUTH_REQ auth_req,
                                    tBTM_BLE_SEC_REQ_ACT* p_sec_req_act);
-extern void btm_ble_ltk_request_reply(BD_ADDR bda, bool use_stk,
+extern void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk,
                                       BT_OCTET16 stk);
-extern uint8_t btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr,
+extern uint8_t btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr,
                                   tSMP_EVT_DATA* p_data);
-extern tBTM_STATUS btm_ble_set_encryption(BD_ADDR bd_addr,
+extern tBTM_STATUS btm_ble_set_encryption(const RawAddress& bd_addr,
                                           tBTM_BLE_SEC_ACT sec_act,
                                           uint8_t link_role);
 extern void btm_ble_ltk_request(uint16_t handle, uint8_t rand[8],
                                 uint16_t ediv);
-extern tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, bool use_stk,
+extern tBTM_STATUS btm_ble_start_encrypt(const RawAddress& bda, bool use_stk,
                                          BT_OCTET16 stk);
-extern void btm_ble_link_encrypted(BD_ADDR bd_addr, uint8_t encr_enable);
+extern void btm_ble_link_encrypted(const RawAddress& bd_addr,
+                                   uint8_t encr_enable);
 
 /* LE device management functions */
 extern void btm_ble_reset_id(void);
 
 /* security related functions */
-extern void btm_ble_increment_sign_ctr(BD_ADDR bd_addr, bool is_local);
-extern bool btm_get_local_div(BD_ADDR bd_addr, uint16_t* p_div);
-extern bool btm_ble_get_enc_key_type(BD_ADDR bd_addr, uint8_t* p_key_types);
+extern void btm_ble_increment_sign_ctr(const RawAddress& bd_addr,
+                                       bool is_local);
+extern bool btm_get_local_div(const RawAddress& bd_addr, uint16_t* p_div);
+extern bool btm_ble_get_enc_key_type(const RawAddress& bd_addr,
+                                     uint8_t* p_key_types);
 
 extern void btm_ble_test_command_complete(uint8_t* p);
 extern void btm_ble_rand_enc_complete(uint8_t* p, uint16_t op_code,
                                       tBTM_RAND_ENC_CB* p_enc_cplt_cback);
 
-extern void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type,
+extern void btm_sec_save_le_key(const RawAddress& bd_addr,
+                                tBTM_LE_KEY_TYPE key_type,
                                 tBTM_LE_KEY_VALUE* p_keys,
                                 bool pass_to_application);
-extern void btm_ble_update_sec_key_size(BD_ADDR bd_addr, uint8_t enc_key_size);
-extern uint8_t btm_ble_read_sec_key_size(BD_ADDR bd_addr);
+extern void btm_ble_update_sec_key_size(const RawAddress& bd_addr,
+                                        uint8_t enc_key_size);
+extern uint8_t btm_ble_read_sec_key_size(const RawAddress& bd_addr);
 
 /* white list function */
-extern bool btm_update_dev_to_white_list(bool to_add, BD_ADDR bd_addr);
+extern bool btm_update_dev_to_white_list(bool to_add,
+                                         const RawAddress& bd_addr);
 extern void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy);
 extern void btm_update_adv_filter_policy(tBTM_BLE_AFP adv_policy);
 extern void btm_ble_clear_white_list(void);
@@ -126,45 +133,46 @@
 extern bool btm_ble_resume_bg_conn(void);
 extern void btm_send_hci_create_connection(
     uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
-    uint8_t addr_type_peer, BD_ADDR bda_peer, uint8_t addr_type_own,
+    uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
     uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
     uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
     uint8_t phy);
 extern bool btm_ble_start_auto_conn(bool start);
 extern bool btm_ble_start_select_conn(bool start);
-extern bool btm_ble_renew_bg_conn_params(bool add, BD_ADDR bd_addr);
-extern void btm_write_dir_conn_wl(BD_ADDR target_addr);
-extern void btm_ble_update_mode_operation(uint8_t link_role, BD_ADDR bda,
+extern bool btm_ble_renew_bg_conn_params(bool add, const RawAddress& bd_addr);
+extern void btm_write_dir_conn_wl(const RawAddress& target_addr);
+extern void btm_ble_update_mode_operation(uint8_t link_role,
+                                          const RawAddress* bda,
                                           uint8_t status);
 extern bool btm_execute_wl_dev_operation(void);
 extern void btm_ble_update_link_topology_mask(uint8_t role, bool increase);
-extern void btm_ble_bgconn_cancel_if_disconnected(BD_ADDR bd_addr);
+extern void btm_ble_bgconn_cancel_if_disconnected(const RawAddress& bd_addr);
 
 /* direct connection utility */
 extern bool btm_send_pending_direct_conn(void);
 extern void btm_ble_enqueue_direct_conn_req(void* p_param);
-extern void btm_ble_dequeue_direct_conn_req(BD_ADDR rem_bda);
+extern void btm_ble_dequeue_direct_conn_req(const RawAddress& rem_bda);
 
 /* BLE address management */
 extern void btm_gen_resolvable_private_addr(base::Callback<void(BT_OCTET8)> cb);
 extern void btm_gen_non_resolvable_private_addr(tBTM_BLE_ADDR_CBACK* p_cback,
                                                 void* p);
-extern tBTM_SEC_DEV_REC* btm_ble_resolve_random_addr(BD_ADDR random_bda);
+extern tBTM_SEC_DEV_REC* btm_ble_resolve_random_addr(
+    const RawAddress& random_bda);
 extern void btm_gen_resolve_paddr_low(BT_OCTET8 rand);
 
 /*  privacy function */
 #if (BLE_PRIVACY_SPT == TRUE)
 /* BLE address mapping with CS feature */
-extern bool btm_identity_addr_to_random_pseudo(BD_ADDR bd_addr,
+extern bool btm_identity_addr_to_random_pseudo(RawAddress* bd_addr,
                                                uint8_t* p_addr_type,
                                                bool refresh);
-extern bool btm_random_pseudo_to_identity_addr(BD_ADDR random_pseudo,
+extern bool btm_random_pseudo_to_identity_addr(RawAddress* random_pseudo,
                                                uint8_t* p_static_addr_type);
-extern void btm_ble_refresh_peer_resolvable_private_addr(BD_ADDR pseudo_bda,
-                                                         BD_ADDR rra,
-                                                         uint8_t rra_type);
-extern void btm_ble_refresh_local_resolvable_private_addr(BD_ADDR pseudo_addr,
-                                                          BD_ADDR local_rpa);
+extern void btm_ble_refresh_peer_resolvable_private_addr(
+    const RawAddress& pseudo_bda, const RawAddress& rra, uint8_t rra_type);
+extern void btm_ble_refresh_local_resolvable_private_addr(
+    const RawAddress& pseudo_addr, const RawAddress& local_rpa);
 extern void btm_ble_read_resolving_list_entry_complete(uint8_t* p,
                                                        uint16_t evt_len);
 extern void btm_ble_remove_resolving_list_entry_complete(uint8_t* p,
@@ -191,7 +199,7 @@
 extern bool btm_ble_topology_check(tBTM_BLE_STATE_MASK request);
 extern bool btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state);
 extern bool btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state);
-extern void btm_ble_set_random_address(BD_ADDR random_bda);
+extern void btm_ble_set_random_address(const RawAddress& random_bda);
 
 #if (BTM_BLE_CONFORMANCE_TESTING == TRUE)
 extern void btm_ble_set_no_disc_if_pair_fail(bool disble_disc);
diff --git a/stack/btm/btm_ble_int_types.h b/stack/btm/btm_ble_int_types.h
index 3e16fea..b539211 100644
--- a/stack/btm/btm_ble_int_types.h
+++ b/stack/btm/btm_ble_int_types.h
@@ -81,14 +81,9 @@
 #define BLE_RESOLVE_ADDR_MSB 0x40
 /* bit 6, and bit7 */
 #define BLE_RESOLVE_ADDR_MASK 0xc0
-#define BTM_BLE_IS_RESOLVE_BDA(x) \
-  (((x)[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
-
-#define BLE_PUBLIC_ADDR_MSB_MASK 0xC0
-/*  most significant bit, bit7, bit6 is 10 to be public address*/
-#define BLE_PUBLIC_ADDR_MSB 0x80
-#define BTM_IS_PUBLIC_BDA(x) \
-  (((x)[0] & BLE_PUBLIC_ADDR_MSB_MASK) == BLE_PUBLIC_ADDR_MSB)
+inline bool BTM_BLE_IS_RESOLVE_BDA(const RawAddress& x) {
+  return ((x.address)[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB;
+}
 
 /* LE scan activity bit mask, continue with LE inquiry bits */
 /* observe is in progress */
@@ -162,13 +157,13 @@
 /* random address resolving complete callback */
 typedef void(tBTM_BLE_RESOLVE_CBACK)(void* match_rec, void* p);
 
-typedef void(tBTM_BLE_ADDR_CBACK)(BD_ADDR_PTR static_random, void* p);
+typedef void(tBTM_BLE_ADDR_CBACK)(const RawAddress& static_random, void* p);
 
 /* random address management control block */
 typedef struct {
   tBLE_ADDR_TYPE own_addr_type; /* local device LE address type */
-  BD_ADDR private_addr;
-  BD_ADDR random_bda;
+  RawAddress private_addr;
+  RawAddress random_bda;
   tBTM_BLE_ADDR_CBACK* p_generate_cback;
   void* p;
   alarm_t* refresh_raddr_timer;
@@ -183,7 +178,7 @@
 } tBTM_LE_CONN_PRAMS;
 
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t attr;
   bool is_connected;
   bool in_use;
@@ -251,7 +246,7 @@
 #endif
 
 typedef struct {
-  BD_ADDR* resolve_q_random_pseudo;
+  RawAddress* resolve_q_random_pseudo;
   uint8_t* resolve_q_action;
   uint8_t q_next;
   uint8_t q_pending;
@@ -260,7 +255,7 @@
 typedef struct {
   bool in_use;
   bool to_add;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t attr;
 } tBTM_BLE_WL_OP;
 
diff --git a/stack/btm/btm_ble_multi_adv.cc b/stack/btm/btm_ble_multi_adv.cc
index e64766c..99b8cb5 100644
--- a/stack/btm/btm_ble_multi_adv.cc
+++ b/stack/btm/btm_ble_multi_adv.cc
@@ -20,6 +20,7 @@
 #include <base/bind.h>
 #include <base/logging.h>
 #include <base/strings/string_number_conversions.h>
+#include <base/time/time.h>
 #include <string.h>
 #include <queue>
 #include <vector>
@@ -33,13 +34,15 @@
 #include "btm_int_types.h"
 
 using base::Bind;
+using base::TimeDelta;
+using base::TimeTicks;
 using RegisterCb =
     base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>;
 using IdTxPowerStatusCb = base::Callback<void(
     uint8_t /* inst_id */, int8_t /* tx_power */, uint8_t /* status */)>;
+using SetEnableData = BleAdvertiserHciInterface::SetEnableData;
 extern void btm_gen_resolvable_private_addr(
     base::Callback<void(uint8_t[8])> cb);
-extern fixed_queue_t* btu_general_alarm_queue;
 
 constexpr int ADV_DATA_LEN_MAX = 251;
 
@@ -55,13 +58,15 @@
   uint8_t advertising_event_properties;
   alarm_t* adv_raddr_timer;
   int8_t tx_power;
-  uint16_t duration;
+  uint16_t duration;  // 1 unit is 10ms
   uint8_t maxExtAdvEvents;
   alarm_t* timeout_timer;
   uint8_t own_address_type;
-  BD_ADDR own_address;
+  RawAddress own_address;
   MultiAdvCb timeout_cb;
   bool address_update_required;
+  bool periodic_enabled;
+  uint32_t advertising_interval;  // 1 unit is 0.625 ms
 
   /* When true, advertising set is enabled, or last scheduled call to "LE Set
    * Extended Advertising Set Enable" is to enable this advertising set. Any
@@ -73,6 +78,7 @@
    * command scheduled when in this state will execute when the set is disabled.
    */
   bool enable_status;
+  TimeTicks enable_time;
 
   bool IsEnabled() { return enable_status; }
 
@@ -86,8 +92,9 @@
         duration(0),
         timeout_timer(nullptr),
         own_address_type(0),
-        own_address{0},
+        own_address(RawAddress::kEmpty),
         address_update_required(false),
+        periodic_enabled(false),
         enable_status(false) {
     adv_raddr_timer = alarm_new_periodic("btm_ble.adv_raddr_timer");
   }
@@ -116,14 +123,14 @@
 }
 
 // Periodic alarms are not supported, because we clean up data in callback
-void alarm_set_closure_on_queue(const tracked_objects::Location& posted_from,
-                                alarm_t* alarm, period_ms_t interval_ms,
-                                base::Closure user_task, fixed_queue_t* queue) {
+void alarm_set_closure(const tracked_objects::Location& posted_from,
+                       alarm_t* alarm, period_ms_t interval_ms,
+                       base::Closure user_task) {
   closure_data* data = new closure_data;
   data->posted_from = posted_from;
   data->user_task = std::move(user_task);
   VLOG(1) << "scheduling timer %s" << data->posted_from.ToString();
-  alarm_set_on_queue(alarm, interval_ms, alarm_closure_cb, data, queue);
+  alarm_set_on_mloop(alarm, interval_ms, alarm_closure_cb, data);
 }
 
 class BleAdvertisingManagerImpl;
@@ -159,9 +166,7 @@
   ~BleAdvertisingManagerImpl() { adv_inst.clear(); }
 
   void GetOwnAddress(uint8_t inst_id, GetAddressCallback cb) override {
-    bt_bdaddr_t addr;
-    memcpy(addr.address, adv_inst[inst_id].own_address, BD_ADDR_LEN);
-    cb.Run(adv_inst[inst_id].own_address_type, addr);
+    cb.Run(adv_inst[inst_id].own_address_type, adv_inst[inst_id].own_address);
   }
 
   void ReadInstanceCountCb(uint8_t instance_count) {
@@ -173,11 +178,11 @@
     }
   }
 
-  void OnRpaGenerationComplete(base::Callback<void(bt_bdaddr_t)> cb,
+  void OnRpaGenerationComplete(base::Callback<void(RawAddress)> cb,
                                uint8_t rand[8]) {
     VLOG(1) << __func__;
 
-    bt_bdaddr_t bda;
+    RawAddress bda;
 
     rand[2] &= (~BLE_RESOLVE_ADDR_MASK);
     rand[2] |= BLE_RESOLVE_ADDR_MSB;
@@ -201,7 +206,7 @@
     cb.Run(bda);
   }
 
-  void GenerateRpa(base::Callback<void(bt_bdaddr_t)> cb) {
+  void GenerateRpa(base::Callback<void(RawAddress)> cb) {
     btm_gen_resolvable_private_addr(
         Bind(&BleAdvertisingManagerImpl::OnRpaGenerationComplete,
              base::Unretained(this), std::move(cb)));
@@ -222,7 +227,7 @@
 
     GenerateRpa(Bind(
         [](AdvertisingInstance* p_inst, MultiAdvCb configuredCb,
-           bt_bdaddr_t bda) {
+           RawAddress bda) {
           /* Connectable advertising set must be disabled when updating RPA */
           bool restart = p_inst->IsEnabled() && p_inst->IsConnectable();
 
@@ -240,9 +245,9 @@
           hci_interface->SetRandomAddress(
               p_inst->inst_id, p_inst->own_address,
               Bind(
-                  [](AdvertisingInstance* p_inst, bt_bdaddr_t bda,
+                  [](AdvertisingInstance* p_inst, RawAddress bda,
                      MultiAdvCb configuredCb, uint8_t status) {
-                    memcpy(p_inst->own_address, &bda, BD_ADDR_LEN);
+                    p_inst->own_address = bda;
                     configuredCb.Run(0x00);
                   },
                   p_inst, bda, configuredCb));
@@ -272,20 +277,18 @@
             [](AdvertisingInstance* p_inst,
                base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>
                    cb,
-               bt_bdaddr_t bda) {
-              memcpy(p_inst->own_address, &bda, BD_ADDR_LEN);
+               RawAddress bda) {
+              p_inst->own_address = bda;
 
-              alarm_set_on_queue(p_inst->adv_raddr_timer,
+              alarm_set_on_mloop(p_inst->adv_raddr_timer,
                                  BTM_BLE_PRIVATE_ADDR_INT_MS,
-                                 btm_ble_adv_raddr_timer_timeout, p_inst,
-                                 btu_general_alarm_queue);
+                                 btm_ble_adv_raddr_timer_timeout, p_inst);
               cb.Run(p_inst->inst_id, BTM_BLE_MULTI_ADV_SUCCESS);
             },
             p_inst, cb));
       } else {
         p_inst->own_address_type = BLE_ADDR_PUBLIC;
-        memcpy(p_inst->own_address,
-               controller_get_interface()->get_address()->address, BD_ADDR_LEN);
+        p_inst->own_address = *controller_get_interface()->get_address();
 
         cb.Run(p_inst->inst_id, BTM_BLE_MULTI_ADV_SUCCESS);
       }
@@ -340,8 +343,8 @@
 
         c->self->adv_inst[c->inst_id].tx_power = tx_power;
 
-        BD_ADDR *rpa = &c->self->adv_inst[c->inst_id].own_address;
-        c->self->GetHciInterface()->SetRandomAddress(c->inst_id, *rpa, Bind(
+        const RawAddress& rpa = c->self->adv_inst[c->inst_id].own_address;
+        c->self->GetHciInterface()->SetRandomAddress(c->inst_id, rpa, Bind(
           [](c_type c, uint8_t status) {
             if (status != 0) {
               LOG(ERROR) << "setting random address failed, status: " << +status;
@@ -395,7 +398,6 @@
     c->maxExtAdvEvents = maxExtAdvEvents;
     c->timeout_cb = std::move(timeout_cb);
 
-
     // this code is intentionally left formatted this way to highlight the
     // asynchronous flow
     // clang-format off
@@ -420,8 +422,8 @@
 
             c->self->adv_inst[c->inst_id].tx_power = tx_power;
 
-            BD_ADDR *rpa = &c->self->adv_inst[c->inst_id].own_address;
-            c->self->GetHciInterface()->SetRandomAddress(c->inst_id, *rpa, Bind(
+            const RawAddress& rpa = c->self->adv_inst[c->inst_id].own_address;
+            c->self->GetHciInterface()->SetRandomAddress(c->inst_id, rpa, Bind(
               [](c_type c, uint8_t status) {
                 if (status != 0) {
                   c->self->Unregister(c->inst_id);
@@ -538,8 +540,8 @@
                             std::move(timeout_cb), 0, 0, base::Bind(DoNothing));
 
     // schedule disable when the timeout passes
-    alarm_set_closure_on_queue(FROM_HERE, p_inst->timeout_timer, duration * 10,
-                               std::move(cb), btu_general_alarm_queue);
+    alarm_set_closure(FROM_HERE, p_inst->timeout_timer, duration * 10,
+                      std::move(cb));
   }
 
   void Enable(uint8_t inst_id, bool enable, MultiAdvCb cb, uint16_t duration,
@@ -578,27 +580,27 @@
 
   void EnableFinish(AdvertisingInstance* p_inst, bool enable, MultiAdvCb cb,
                     uint8_t status) {
+    MultiAdvCb myCb;
     if (enable && p_inst->duration) {
-      p_inst->enable_status = enable;
       // TODO(jpawlowski): HCI implementation that can't do duration should
       // emulate it, not EnableWithTimerCb.
-      GetHciInterface()->Enable(
-          enable, p_inst->inst_id, p_inst->duration, p_inst->maxExtAdvEvents,
-          Bind(&BleAdvertisingManagerImpl::EnableWithTimerCb,
-               base::Unretained(this), p_inst->inst_id, std::move(cb),
-               p_inst->duration, p_inst->timeout_cb));
-
+      myCb = Bind(&BleAdvertisingManagerImpl::EnableWithTimerCb,
+                  base::Unretained(this), p_inst->inst_id, std::move(cb),
+                  p_inst->duration, p_inst->timeout_cb);
     } else {
+      myCb = std::move(cb);
+
       if (p_inst->timeout_timer) {
         alarm_cancel(p_inst->timeout_timer);
         alarm_free(p_inst->timeout_timer);
         p_inst->timeout_timer = nullptr;
       }
-
-      p_inst->enable_status = enable;
-      GetHciInterface()->Enable(enable, p_inst->inst_id, p_inst->duration,
-                                p_inst->maxExtAdvEvents, std::move(cb));
     }
+
+    if (enable) p_inst->enable_time = TimeTicks::Now();
+    p_inst->enable_status = enable;
+    GetHciInterface()->Enable(enable, p_inst->inst_id, p_inst->duration,
+                              p_inst->maxExtAdvEvents, std::move(myCb));
   }
 
   void SetParameters(uint8_t inst_id, tBTM_BLE_ADV_PARAMS* p_params,
@@ -616,13 +618,15 @@
       return;
     }
 
-    // TODO: disable only if was enabled, currently no use scenario needs that,
+    // TODO: disable only if was enabled, currently no use scenario needs
+    // that,
     // we always set parameters before enabling
     // GetHciInterface()->Enable(false, inst_id, Bind(DoNothing));
     p_inst->advertising_event_properties =
         p_params->advertising_event_properties;
     p_inst->tx_power = p_params->tx_power;
-    BD_ADDR peer_address = {0, 0, 0, 0, 0, 0};
+    p_inst->advertising_interval = p_params->adv_int_min;
+    const RawAddress& peer_address = RawAddress::kEmpty;
 
     GetHciInterface()->SetParameters(
         p_inst->inst_id, p_params->advertising_event_properties,
@@ -758,7 +762,27 @@
                                     MultiAdvCb cb) override {
     VLOG(1) << __func__ << " inst_id: " << +inst_id << ", enable: " << +enable;
 
-    GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id, cb);
+    AdvertisingInstance* p_inst = &adv_inst[inst_id];
+    if (!p_inst->in_use) {
+      LOG(ERROR) << "Invalid or not active instance";
+      cb.Run(BTM_BLE_MULTI_ADV_FAILURE);
+      return;
+    }
+
+    MultiAdvCb enable_cb = Bind(
+        [](AdvertisingInstance* p_inst, uint8_t enable, MultiAdvCb cb,
+           uint8_t status) {
+          VLOG(1) << "periodc adv enable cb: inst_id: " << +p_inst->inst_id
+                  << ", enable: " << +enable << ", status: " << std::hex
+                  << +status;
+          if (!status) p_inst->periodic_enabled = enable;
+
+          cb.Run(status);
+        },
+        p_inst, enable, std::move(cb));
+
+    GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id,
+                                                    std::move(enable_cb));
   }
 
   void Unregister(uint8_t inst_id) override {
@@ -775,12 +799,75 @@
       GetHciInterface()->Enable(false, inst_id, 0x00, 0x00, Bind(DoNothing));
     }
 
+    if (p_inst->periodic_enabled) {
+      p_inst->periodic_enabled = false;
+      GetHciInterface()->SetPeriodicAdvertisingEnable(false, inst_id,
+                                                      Bind(DoNothing));
+    }
+
     alarm_cancel(p_inst->adv_raddr_timer);
     p_inst->in_use = false;
     GetHciInterface()->RemoveAdvertisingSet(inst_id, Bind(DoNothing));
     p_inst->address_update_required = false;
   }
 
+  void RecomputeTimeout(AdvertisingInstance* inst, TimeTicks now) {
+    TimeDelta duration = now - inst->enable_time;
+    bool cb_fired = false;
+    if (inst->duration) {
+      int durationDone = (duration.InMilliseconds() / 10);
+      if (durationDone + 1 >= inst->duration) {
+        inst->enable_status = false;
+        inst->timeout_cb.Run(0 /* TODO: STATUS HERE?*/);
+        cb_fired = true;
+      } else {
+        inst->duration = inst->duration - durationDone;
+      }
+    }
+
+    if (inst->maxExtAdvEvents && !cb_fired) {
+      int eventsDone =
+          (duration.InMilliseconds() / (inst->advertising_interval * 5 / 8));
+
+      if (eventsDone + 1 >= inst->maxExtAdvEvents) {
+        inst->enable_status = false;
+        inst->timeout_cb.Run(0 /* TODO: STATUS HERE?*/);
+      } else {
+        inst->maxExtAdvEvents = inst->maxExtAdvEvents - eventsDone;
+      }
+    }
+  }
+
+  void Suspend() {
+    std::vector<SetEnableData> sets;
+
+    for (AdvertisingInstance& inst : adv_inst) {
+      if (!inst.in_use || !inst.enable_status) continue;
+
+      if (inst.duration || inst.maxExtAdvEvents)
+        RecomputeTimeout(&inst, TimeTicks::Now());
+
+      sets.emplace_back(SetEnableData{.handle = inst.inst_id});
+    }
+
+    if (!sets.empty()) GetHciInterface()->Enable(false, sets, Bind(DoNothing));
+  }
+
+  void Resume() override {
+    std::vector<SetEnableData> sets;
+
+    for (const AdvertisingInstance& inst : adv_inst) {
+      if (inst.in_use && inst.enable_status) {
+        sets.emplace_back(SetEnableData{
+            .handle = inst.inst_id,
+            .duration = inst.duration,
+            .max_extended_advertising_events = inst.maxExtAdvEvents});
+      }
+    }
+
+    if (!sets.empty()) GetHciInterface()->Enable(true, sets, Bind(DoNothing));
+  }
+
   void OnAdvertisingSetTerminated(
       uint8_t status, uint8_t advertising_handle, uint16_t connection_handle,
       uint8_t num_completed_extended_adv_events) override {
@@ -812,10 +899,15 @@
     if (p_inst->in_use == true) {
       // TODO(jpawlowski): we don't really allow to do directed advertising
       // right now. This should probably be removed, check with Andre.
-      if ((p_inst->advertising_event_properties & 0x0C) ==
-          0 /* directed advertising bits not set */) {
-        GetHciInterface()->Enable(true, advertising_handle, 0x00, 0x00,
-                                  Bind(DoNothing));
+      if ((p_inst->advertising_event_properties & 0x0C) == 0) {
+        /* directed advertising bits not set */
+
+        RecomputeTimeout(p_inst, TimeTicks::Now());
+        if (p_inst->enable_status) {
+          GetHciInterface()->Enable(true, advertising_handle, p_inst->duration,
+                                    p_inst->maxExtAdvEvents, Bind(DoNothing));
+        }
+
       } else {
         /* mark directed adv as disabled if adv has been stopped */
         p_inst->in_use = false;
@@ -884,3 +976,72 @@
   BleAdvertisingManager::CleanUp();
   BleAdvertiserHciInterface::CleanUp();
 }
+
+// TODO(jpawlowski): Find a nicer way to test RecomputeTimeout without exposing
+// AdvertisingInstance
+bool timeout_triggered = false;
+void test_timeout_cb(uint8_t status) { timeout_triggered = true; }
+
+// verify that if duration passed, or is about to pass, recomputation will shut
+// down the advertiser completly
+void testRecomputeTimeout1() {
+  auto manager = (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get();
+
+  TimeTicks start = TimeTicks::Now();
+  TimeTicks end = start + TimeDelta::FromMilliseconds(111);
+  AdvertisingInstance test1(0);
+  test1.enable_status = true;
+  test1.enable_time = start;
+  test1.duration = 12 /*120ms*/;
+  test1.timeout_cb = Bind(&test_timeout_cb);
+
+  manager->RecomputeTimeout(&test1, end);
+
+  CHECK(timeout_triggered == true);
+  timeout_triggered = false;
+  CHECK(test1.enable_status == false);
+}
+
+// verify that duration and maxExtAdvEvents are properly adjusted when
+// recomputing.
+void testRecomputeTimeout2() {
+  auto manager = (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get();
+
+  TimeTicks start = TimeTicks::Now();
+  TimeTicks end = start + TimeDelta::FromMilliseconds(250);
+  AdvertisingInstance test1(0);
+  test1.enable_status = true;
+  test1.enable_time = start;
+  test1.duration = 50 /*500ms*/;
+  test1.maxExtAdvEvents = 50;
+  test1.advertising_interval = 16 /* 10 ms */;
+  test1.timeout_cb = Bind(&test_timeout_cb);
+
+  manager->RecomputeTimeout(&test1, end);
+
+  CHECK(timeout_triggered == false);
+  CHECK(test1.enable_status == true);
+  CHECK(test1.duration == 25);
+  CHECK(test1.maxExtAdvEvents == 25);
+}
+
+// verify that if maxExtAdvEvents were sent, or are close to end, recomputation
+// wil shut down the advertiser completly
+void testRecomputeTimeout3() {
+  auto manager = (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get();
+
+  TimeTicks start = TimeTicks::Now();
+  TimeTicks end = start + TimeDelta::FromMilliseconds(495);
+  AdvertisingInstance test1(0);
+  test1.enable_status = true;
+  test1.enable_time = start;
+  test1.maxExtAdvEvents = 50;
+  test1.advertising_interval = 16 /* 10 ms */;
+  test1.timeout_cb = Bind(&test_timeout_cb);
+
+  manager->RecomputeTimeout(&test1, end);
+
+  CHECK(timeout_triggered == true);
+  timeout_triggered = false;
+  CHECK(test1.enable_status == false);
+}
diff --git a/stack/btm/btm_ble_privacy.cc b/stack/btm/btm_ble_privacy.cc
index a00b2df..f1aa509 100644
--- a/stack/btm/btm_ble_privacy.cc
+++ b/stack/btm/btm_ble_privacy.cc
@@ -25,6 +25,7 @@
 #include "bt_target.h"
 
 #if (BLE_PRIVACY_SPT == TRUE)
+#include "ble_advertiser.h"
 #include "bt_types.h"
 #include "btm_int.h"
 #include "btu.h"
@@ -62,10 +63,11 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, uint8_t op_code) {
+void btm_ble_enq_resolving_list_pending(const RawAddress& pseudo_bda,
+                                        uint8_t op_code) {
   tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
 
-  memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN);
+  p_q->resolve_q_random_pseudo[p_q->q_next] = pseudo_bda;
   p_q->resolve_q_action[p_q->q_next] = op_code;
   p_q->q_next++;
   p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size();
@@ -83,13 +85,12 @@
  * Returns          void
  *
  ******************************************************************************/
-bool btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr,
+bool btm_ble_brcm_find_resolving_pending_entry(const RawAddress& pseudo_addr,
                                                uint8_t action) {
   tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
 
   for (uint8_t i = p_q->q_pending; i != p_q->q_next;) {
-    if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) ==
-            0 &&
+    if (p_q->resolve_q_random_pseudo[i] == pseudo_addr &&
         action == p_q->resolve_q_action[i])
       return true;
 
@@ -111,13 +112,12 @@
  * Returns          void
  *
  ******************************************************************************/
-bool btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr) {
+bool btm_ble_deq_resolving_pending(RawAddress& pseudo_addr) {
   tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
 
   if (p_q->q_next != p_q->q_pending) {
-    memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending],
-           BD_ADDR_LEN);
-    memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN);
+    pseudo_addr = p_q->resolve_q_random_pseudo[p_q->q_pending];
+    p_q->resolve_q_random_pseudo[p_q->q_pending] = RawAddress::kEmpty;
     p_q->q_pending++;
     p_q->q_pending %=
         controller_get_interface()->get_ble_resolving_list_max_size();
@@ -185,7 +185,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, bool add) {
+void btm_ble_update_resolving_list(const RawAddress& pseudo_bda, bool add) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(pseudo_bda);
   if (p_dev_rec == NULL) return;
 
@@ -269,7 +269,7 @@
 
   BTM_TRACE_DEBUG("%s status = %d", __func__, status);
 
-  BD_ADDR pseudo_bda;
+  RawAddress pseudo_bda;
   if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
     BTM_TRACE_DEBUG("no pending resolving list operation");
     return;
@@ -303,7 +303,7 @@
  ******************************************************************************/
 void btm_ble_remove_resolving_list_entry_complete(uint8_t* p,
                                                   uint16_t evt_len) {
-  BD_ADDR pseudo_bda;
+  RawAddress pseudo_bda;
   uint8_t status;
 
   STREAM_TO_UINT8(status, p);
@@ -337,7 +337,7 @@
  ******************************************************************************/
 void btm_ble_read_resolving_list_entry_complete(uint8_t* p, uint16_t evt_len) {
   uint8_t status, rra_type = BTM_BLE_ADDR_PSEUDO;
-  BD_ADDR rra, pseudo_bda;
+  RawAddress rra, pseudo_bda;
 
   STREAM_TO_UINT8(status, p);
 
@@ -355,8 +355,7 @@
       p += (2 + 16 + 1 + 6);
       STREAM_TO_BDADDR(rra, p);
 
-      BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
-                      rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]);
+      VLOG(2) << __func__ << " peer_addr: " << rra;
     } else {
       STREAM_TO_BDADDR(rra, p);
     }
@@ -528,6 +527,13 @@
     p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
   }
 
+  // If it's non-VSC implementation, suspend
+  if (BleAdvertisingManager::IsInitialized() &&
+      (controller_get_interface()->supports_ble_extended_advertising() ||
+       BTM_BleMaxMultiAdvInstanceCount() == 0)) {
+    BleAdvertisingManager::Get()->Suspend();
+  }
+
   if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
     btm_ble_stop_scan();
     p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
@@ -555,6 +561,13 @@
 
   if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) btm_ble_start_adv();
 
+  // If it's non-VSC implementation, resume
+  if (BleAdvertisingManager::IsInitialized() &&
+      (controller_get_interface()->supports_ble_extended_advertising() ||
+       BTM_BleMaxMultiAdvInstanceCount() == 0)) {
+    BleAdvertisingManager::Get()->Resume();
+  }
+
   if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) btm_ble_start_scan();
 
   if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) btm_ble_resume_bg_conn();
@@ -695,12 +708,11 @@
 
         btm_ble_update_resolving_list(p_dev_rec->bd_addr, true);
         if (controller_get_interface()->supports_ble_privacy()) {
-          BD_ADDR dummy_bda = {0};
           uint8_t* peer_irk = p_dev_rec->ble.keys.irk;
           uint8_t* local_irk = btm_cb.devcb.id_keys.irk;
 
-          if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0) {
-            memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
+          if (p_dev_rec->ble.static_addr.IsEmpty()) {
+            p_dev_rec->ble.static_addr = p_dev_rec->bd_addr;
             p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
           }
 
@@ -711,7 +723,7 @@
               p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr,
               peer_irk, local_irk);
 
-          if (controller_get_interface()->supports_ble_privacy()) {
+          if (controller_get_interface()->supports_ble_set_privacy_mode()) {
             BTM_TRACE_DEBUG("%s: adding device privacy mode", __func__);
             btsnd_hcic_ble_set_privacy_mode(p_dev_rec->ble.static_addr_type,
                                             p_dev_rec->ble.static_addr, 0x01);
@@ -876,7 +888,7 @@
 
   if (max_irk_list_sz > 0) {
     p_q->resolve_q_random_pseudo =
-        (BD_ADDR*)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz);
+        (RawAddress*)osi_malloc(sizeof(RawAddress) * max_irk_list_sz);
     p_q->resolve_q_action = (uint8_t*)osi_malloc(max_irk_list_sz);
 
     /* RPA offloading feature */
diff --git a/stack/btm/btm_dev.cc b/stack/btm/btm_dev.cc
index 808f1cd..0fe5c20 100644
--- a/stack/btm/btm_dev.cc
+++ b/stack/btm/btm_dev.cc
@@ -58,9 +58,10 @@
  * Returns          true if added OK, else false
  *
  ******************************************************************************/
-bool BTM_SecAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
-                      uint8_t* features, uint32_t trusted_mask[],
-                      LINK_KEY link_key, uint8_t key_type, tBTM_IO_CAP io_cap,
+bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class,
+                      BD_NAME bd_name, uint8_t* features,
+                      uint32_t trusted_mask[], LINK_KEY link_key,
+                      uint8_t key_type, tBTM_IO_CAP io_cap,
                       uint8_t pin_length) {
   BTM_TRACE_API("%s: link key type:%x", __func__, key_type);
 
@@ -68,7 +69,7 @@
   if (!p_dev_rec) {
     p_dev_rec = btm_sec_allocate_dev_rec();
 
-    memcpy(p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
+    p_dev_rec->bd_addr = bd_addr;
     p_dev_rec->hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_BR_EDR);
 
     /* use default value for background connection params */
@@ -118,9 +119,7 @@
   BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
 
   if (link_key) {
-    BTM_TRACE_EVENT("%s: BDA: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
-                    bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-                    bd_addr[5]);
+    VLOG(2) << __func__ << ": BDA: " << bd_addr;
     p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
     memcpy(p_dev_rec->link_key, link_key, LINK_KEY_LEN);
     p_dev_rec->link_key_type = key_type;
@@ -148,18 +147,17 @@
   return true;
 }
 
-/*******************************************************************************
+/** Free resources associated with the device associated with |bd_addr| address.
  *
- * Function         BTM_SecDeleteDevice
+ * *** WARNING ***
+ * tBTM_SEC_DEV_REC associated with bd_addr becomes invalid after this function
+ * is called, also any of it's fields. i.e. if you use p_dev_rec->bd_addr, it is
+ * no longer valid!
+ * *** WARNING ***
  *
- * Description      Free resources associated with the device.
- *
- * Parameters:      bd_addr          - BD address of the peer
- *
- * Returns          true if removed OK, false if not found or ACL link is active
- *
- ******************************************************************************/
-bool BTM_SecDeleteDevice(BD_ADDR bd_addr) {
+ * Returns true if removed OK, false if not found or ACL link is active.
+ */
+bool BTM_SecDeleteDevice(const RawAddress& bd_addr) {
   if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
       BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR)) {
     BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active",
@@ -169,9 +167,10 @@
 
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   if (p_dev_rec != NULL) {
+    RawAddress bda = p_dev_rec->bd_addr;
     btm_sec_free_dev(p_dev_rec);
     /* Tell controller to get rid of the link key, if it has one stored */
-    BTM_DeleteStoredLinkKey(p_dev_rec->bd_addr, NULL);
+    BTM_DeleteStoredLinkKey(&bda, NULL);
   }
 
   return true;
@@ -185,7 +184,7 @@
  *                  remove device.
  *
  ******************************************************************************/
-extern void BTM_SecClearSecurityFlags(BD_ADDR bd_addr) {
+extern void BTM_SecClearSecurityFlags(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   if (p_dev_rec == NULL) return;
 
@@ -204,7 +203,7 @@
  * Returns          Pointer to the name or NULL
  *
  ******************************************************************************/
-char* BTM_SecReadDevName(BD_ADDR bd_addr) {
+char* BTM_SecReadDevName(const RawAddress& bd_addr) {
   char* p_name = NULL;
   tBTM_SEC_DEV_REC* p_srec;
 
@@ -214,15 +213,6 @@
   return (p_name);
 }
 
-bool is_bd_addr_equal(void* data, void* context) {
-  tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data);
-  BD_ADDR* bd_addr = static_cast<BD_ADDR*>(context);
-
-  if (!memcmp(p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN)) return false;
-
-  return true;
-}
-
 /*******************************************************************************
  *
  * Function         btm_sec_alloc_dev
@@ -233,7 +223,7 @@
  * Returns          Pointer to the record or NULL
  *
  ******************************************************************************/
-tBTM_SEC_DEV_REC* btm_sec_alloc_dev(BD_ADDR bd_addr) {
+tBTM_SEC_DEV_REC* btm_sec_alloc_dev(const RawAddress& bd_addr) {
   tBTM_INQ_INFO* p_inq_info;
   BTM_TRACE_EVENT("btm_sec_alloc_dev");
 
@@ -247,13 +237,13 @@
 
     p_dev_rec->device_type = p_inq_info->results.device_type;
     p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type;
-  } else if (!memcmp(bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
+  } else if (bd_addr == btm_cb.connecting_bda)
     memcpy(p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
 
   /* update conn params, use default value for background connection params */
   memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
 
-  memcpy(p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
+  p_dev_rec->bd_addr = bd_addr;
 
   p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE);
   p_dev_rec->hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_BR_EDR);
@@ -286,7 +276,7 @@
  * Returns          true if device is known and role switch is supported
  *
  ******************************************************************************/
-bool btm_dev_support_switch(BD_ADDR bd_addr) {
+bool btm_dev_support_switch(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   uint8_t xx;
   bool feature_empty = true;
@@ -351,11 +341,11 @@
 
 bool is_address_equal(void* data, void* context) {
   tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data);
-  BD_ADDR* bd_addr = static_cast<BD_ADDR*>(context);
+  const RawAddress* bd_addr = ((RawAddress*)context);
 
-  if (!memcmp(p_dev_rec->bd_addr, *bd_addr, BD_ADDR_LEN)) return false;
+  if (p_dev_rec->bd_addr == *bd_addr) return false;
   // If a LE random address is looking for device record
-  if (!memcmp(p_dev_rec->ble.pseudo_addr, *bd_addr, BD_ADDR_LEN)) return false;
+  if (p_dev_rec->ble.pseudo_addr == *bd_addr) return false;
 
   if (btm_ble_addr_resolvable(*bd_addr, p_dev_rec)) return false;
   return true;
@@ -371,11 +361,9 @@
  * Returns          Pointer to the record or NULL
  *
  ******************************************************************************/
-tBTM_SEC_DEV_REC* btm_find_dev(const BD_ADDR bd_addr) {
-  if (!bd_addr) return NULL;
-
+tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr) {
   list_node_t* n =
-      list_foreach(btm_cb.sec_dev_rec, is_address_equal, (void*)bd_addr);
+      list_foreach(btm_cb.sec_dev_rec, is_address_equal, (void*)&bd_addr);
   if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n));
 
   return NULL;
@@ -396,14 +384,17 @@
   BTM_TRACE_DEBUG("%s", __func__);
 
   list_node_t* end = list_end(btm_cb.sec_dev_rec);
-  for (list_node_t* node = list_begin(btm_cb.sec_dev_rec); node != end;
-       node = list_next(node)) {
+  list_node_t* node = list_begin(btm_cb.sec_dev_rec);
+  while (node != end) {
     tBTM_SEC_DEV_REC* p_dev_rec =
         static_cast<tBTM_SEC_DEV_REC*>(list_node(node));
 
+    // we do list_remove in some cases, must grab next before removing
+    node = list_next(node);
+
     if (p_target_rec == p_dev_rec) continue;
 
-    if (!memcmp(p_dev_rec->bd_addr, p_target_rec->bd_addr, BD_ADDR_LEN)) {
+    if (p_dev_rec->bd_addr == p_target_rec->bd_addr) {
       memcpy(p_target_rec, p_dev_rec, sizeof(tBTM_SEC_DEV_REC));
       p_target_rec->ble = temp_rec.ble;
       p_target_rec->ble_hci_handle = temp_rec.ble_hci_handle;
@@ -419,20 +410,17 @@
 
       /* remove the combined record */
       list_remove(btm_cb.sec_dev_rec, p_dev_rec);
-      break;
     }
 
     /* an RPA device entry is a duplicate of the target record */
     if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec)) {
-      if (memcmp(p_target_rec->ble.pseudo_addr, p_dev_rec->bd_addr,
-                 BD_ADDR_LEN) == 0) {
+      if (p_target_rec->ble.pseudo_addr == p_dev_rec->bd_addr) {
         p_target_rec->ble.ble_addr_type = p_dev_rec->ble.ble_addr_type;
         p_target_rec->device_type |= p_dev_rec->device_type;
 
         /* remove the combined record */
         list_remove(btm_cb.sec_dev_rec, p_dev_rec);
       }
-      break;
     }
   }
 }
@@ -447,7 +435,7 @@
  * Returns          Pointer to the record or NULL
  *
  ******************************************************************************/
-tBTM_SEC_DEV_REC* btm_find_or_alloc_dev(BD_ADDR bd_addr) {
+tBTM_SEC_DEV_REC* btm_find_or_alloc_dev(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   BTM_TRACE_EVENT("btm_find_or_alloc_dev");
   p_dev_rec = btm_find_dev(bd_addr);
@@ -546,7 +534,7 @@
  * Returns          The device bond type if known, otherwise BOND_TYPE_UNKNOWN
  *
  ******************************************************************************/
-tBTM_BOND_TYPE btm_get_bond_type_dev(BD_ADDR bd_addr) {
+tBTM_BOND_TYPE btm_get_bond_type_dev(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
 
   if (p_dev_rec == NULL) return BOND_TYPE_UNKNOWN;
@@ -564,7 +552,8 @@
  * Returns          true on success, otherwise false
  *
  ******************************************************************************/
-bool btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type) {
+bool btm_set_bond_type_dev(const RawAddress& bd_addr,
+                           tBTM_BOND_TYPE bond_type) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
 
   if (p_dev_rec == NULL) return false;
diff --git a/stack/btm/btm_devctl.cc b/stack/btm/btm_devctl.cc
index 15b17f3..4910315 100644
--- a/stack/btm/btm_devctl.cc
+++ b/stack/btm/btm_devctl.cc
@@ -43,7 +43,6 @@
 
 #include "gatt_int.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
 extern thread_t* bt_workqueue_thread;
 
 /******************************************************************************/
@@ -83,6 +82,10 @@
 
   btm_cb.devcb.read_local_name_timer = alarm_new("btm.read_local_name_timer");
   btm_cb.devcb.read_rssi_timer = alarm_new("btm.read_rssi_timer");
+  btm_cb.devcb.read_failed_contact_counter_timer =
+      alarm_new("btm.read_failed_contact_counter_timer");
+  btm_cb.devcb.read_automatic_flush_timeout_timer =
+      alarm_new("btm.read_automatic_flush_timeout_timer");
   btm_cb.devcb.read_link_quality_timer =
       alarm_new("btm.read_link_quality_timer");
   btm_cb.devcb.read_inq_tx_power_timer =
@@ -129,7 +132,21 @@
     p_cb = btm_cb.devcb.p_rssi_cmpl_cb;
     btm_cb.devcb.p_rssi_cmpl_cb = NULL;
 
-    if (p_cb) (*p_cb)((tBTM_RSSI_RESULTS*)&status);
+    if (p_cb) (*p_cb)((tBTM_RSSI_RESULT*)&status);
+  }
+
+  if (btm_cb.devcb.p_failed_contact_counter_cmpl_cb) {
+    p_cb = btm_cb.devcb.p_failed_contact_counter_cmpl_cb;
+    btm_cb.devcb.p_failed_contact_counter_cmpl_cb = NULL;
+
+    if (p_cb) (*p_cb)((tBTM_FAILED_CONTACT_COUNTER_RESULT*)&status);
+  }
+
+  if (btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb) {
+    p_cb = btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb;
+    btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb = NULL;
+
+    if (p_cb) (*p_cb)((tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT*)&status);
   }
 }
 
@@ -446,9 +463,9 @@
   btm_cb.devcb.p_rln_cmpl_cb = p_rln_cmpl_cback;
 
   btsnd_hcic_read_name();
-  alarm_set_on_queue(btm_cb.devcb.read_local_name_timer,
+  alarm_set_on_mloop(btm_cb.devcb.read_local_name_timer,
                      BTM_DEV_NAME_REPLY_TIMEOUT_MS, btm_read_local_name_timeout,
-                     NULL, btu_general_alarm_queue);
+                     NULL);
 
   return BTM_CMD_STARTED;
 }
@@ -768,27 +785,26 @@
  *                                 the results
  *
  ******************************************************************************/
-tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB* p_cb) {
-  BD_ADDR local_bd_addr;
-  bool delete_all_flag = false;
-
+tBTM_STATUS BTM_DeleteStoredLinkKey(const RawAddress* bd_addr,
+                                    tBTM_CMPL_CB* p_cb) {
   /* Check if the previous command is completed */
   if (btm_cb.devcb.p_stored_link_key_cmpl_cb) return (BTM_BUSY);
 
-  if (!bd_addr) {
-    /* This is to delete all link keys */
-    delete_all_flag = true;
-
-    /* We don't care the BD address. Just pass a non zero pointer */
-    bd_addr = local_bd_addr;
-  }
+  bool delete_all_flag = !bd_addr;
 
   BTM_TRACE_EVENT("BTM: BTM_DeleteStoredLinkKey: delete_all_flag: %s",
                   delete_all_flag ? "true" : "false");
 
-  /* Send the HCI command */
   btm_cb.devcb.p_stored_link_key_cmpl_cb = p_cb;
-  btsnd_hcic_delete_stored_key(bd_addr, delete_all_flag);
+  if (!bd_addr) {
+    /* This is to delete all link keys */
+    /* We don't care the BD address. Just pass a non zero pointer */
+    RawAddress local_bd_addr = RawAddress::kEmpty;
+    btsnd_hcic_delete_stored_key(local_bd_addr, delete_all_flag);
+  } else {
+    btsnd_hcic_delete_stored_key(*bd_addr, delete_all_flag);
+  }
+
   return (BTM_SUCCESS);
 }
 
diff --git a/stack/btm/btm_inq.cc b/stack/btm/btm_inq.cc
index 687e89d..213683c 100644
--- a/stack/btm/btm_inq.cc
+++ b/stack/btm/btm_inq.cc
@@ -51,8 +51,6 @@
 #define BTM_INQ_DEBUG FALSE
 #endif
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /******************************************************************************/
 /*               L O C A L    D A T A    D E F I N I T I O N S                */
 /******************************************************************************/
@@ -954,11 +952,10 @@
  *                  BTM_WRONG_MODE if the device is not up.
  *
  ******************************************************************************/
-tBTM_STATUS BTM_ReadRemoteDeviceName(BD_ADDR remote_bda, tBTM_CMPL_CB* p_cb,
+tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
+                                     tBTM_CMPL_CB* p_cb,
                                      tBT_TRANSPORT transport) {
-  BTM_TRACE_API("%s: bd addr [%02x%02x%02x%02x%02x%02x]", __func__,
-                remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3],
-                remote_bda[4], remote_bda[5]);
+  VLOG(1) << __func__ << ": bd addr " << remote_bda;
   /* Use LE transport when LE is the only available option */
   if (transport == BT_TRANSPORT_LE) {
     return btm_ble_read_remote_name(remote_bda, p_cb);
@@ -1017,9 +1014,8 @@
  * Returns          pointer to entry, or NULL if not found
  *
  ******************************************************************************/
-tBTM_INQ_INFO* BTM_InqDbRead(const BD_ADDR p_bda) {
-  BTM_TRACE_API("BTM_InqDbRead: bd addr [%02x%02x%02x%02x%02x%02x]", p_bda[0],
-                p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
+tBTM_INQ_INFO* BTM_InqDbRead(const RawAddress& p_bda) {
+  VLOG(1) << __func__ << ": bd addr " << p_bda;
 
   tINQ_DB_ENT* p_ent = btm_inq_db_find(p_bda);
   if (!p_ent) return NULL;
@@ -1096,7 +1092,7 @@
  *                          is active, otherwise BTM_SUCCESS
  *
  ******************************************************************************/
-tBTM_STATUS BTM_ClearInqDb(BD_ADDR p_bda) {
+tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda) {
   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
 
   /* If an inquiry or remote name is in progress return busy */
@@ -1123,9 +1119,9 @@
   if (btm_cb.devcb.p_inq_tx_power_cmpl_cb) return (BTM_BUSY);
 
   btm_cb.devcb.p_inq_tx_power_cmpl_cb = p_cb;
-  alarm_set_on_queue(btm_cb.devcb.read_inq_tx_power_timer,
+  alarm_set_on_mloop(btm_cb.devcb.read_inq_tx_power_timer,
                      BTM_INQ_REPLY_TIMEOUT_MS, btm_read_inq_tx_power_timeout,
-                     NULL, btu_general_alarm_queue);
+                     NULL);
 
   btsnd_hcic_read_inq_tx_power();
   return (BTM_CMD_STARTED);
@@ -1177,7 +1173,7 @@
   if (p_inq->remname_active) {
     alarm_cancel(p_inq->remote_name_timer);
     p_inq->remname_active = false;
-    memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
+    p_inq->remname_bda = RawAddress::kEmpty;
 
     if (p_inq->p_remname_cmpl_cb) {
       rem_name.status = BTM_DEV_RESET;
@@ -1292,7 +1288,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_clr_inq_db(BD_ADDR p_bda) {
+void btm_clr_inq_db(const RawAddress* p_bda) {
   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
   tINQ_DB_ENT* p_ent = p_inq->inq_db;
   uint16_t xx;
@@ -1304,8 +1300,7 @@
   for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
     if (p_ent->in_use) {
       /* If this is the specified BD_ADDR or clearing all devices */
-      if (p_bda == NULL || (!memcmp(p_ent->inq_info.results.remote_bd_addr,
-                                    p_bda, BD_ADDR_LEN))) {
+      if (p_bda == NULL || (p_ent->inq_info.results.remote_bd_addr == *p_bda)) {
         p_ent->in_use = false;
       }
     }
@@ -1344,7 +1339,7 @@
  * Returns          true if found, else false (new entry)
  *
  ******************************************************************************/
-bool btm_inq_find_bdaddr(BD_ADDR p_bda) {
+bool btm_inq_find_bdaddr(const RawAddress& p_bda) {
   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
   tINQ_BDADDR* p_db = &p_inq->p_bd_db[0];
   uint16_t xx;
@@ -1354,14 +1349,13 @@
     return (false);
 
   for (xx = 0; xx < p_inq->num_bd_entries; xx++, p_db++) {
-    if (!memcmp(p_db->bd_addr, p_bda, BD_ADDR_LEN) &&
-        p_db->inq_count == p_inq->inq_counter)
+    if (p_db->bd_addr == p_bda && p_db->inq_count == p_inq->inq_counter)
       return (true);
   }
 
   if (xx < p_inq->max_bd_entries) {
     p_db->inq_count = p_inq->inq_counter;
-    memcpy(p_db->bd_addr, p_bda, BD_ADDR_LEN);
+    p_db->bd_addr = p_bda;
     p_inq->num_bd_entries++;
   }
 
@@ -1379,13 +1373,12 @@
  * Returns          pointer to entry, or NULL if not found
  *
  ******************************************************************************/
-tINQ_DB_ENT* btm_inq_db_find(const BD_ADDR p_bda) {
+tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda) {
   uint16_t xx;
   tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
 
   for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
-    if ((p_ent->in_use) &&
-        (!memcmp(p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
+    if (p_ent->in_use && p_ent->inq_info.results.remote_bd_addr == p_bda)
       return (p_ent);
   }
 
@@ -1404,7 +1397,7 @@
  * Returns          pointer to entry
  *
  ******************************************************************************/
-tINQ_DB_ENT* btm_inq_db_new(BD_ADDR p_bda) {
+tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda) {
   uint16_t xx;
   tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
   tINQ_DB_ENT* p_old = btm_cb.btm_inq_vars.inq_db;
@@ -1413,7 +1406,7 @@
   for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
     if (!p_ent->in_use) {
       memset(p_ent, 0, sizeof(tINQ_DB_ENT));
-      memcpy(p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN);
+      p_ent->inq_info.results.remote_bd_addr = p_bda;
       p_ent->in_use = true;
 
       return (p_ent);
@@ -1428,7 +1421,7 @@
   /* If here, no free entry found. Return the oldest. */
 
   memset(p_old, 0, sizeof(tINQ_DB_ENT));
-  memcpy(p_old->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN);
+  p_old->inq_info.results.remote_bd_addr = p_bda;
   p_old->in_use = true;
 
   return (p_old);
@@ -1469,11 +1462,7 @@
   BTM_TRACE_DEBUG(
       "btm_set_inq_event_filter: filter type %d [Clear-0, COD-1, BDADDR-2]",
       filter_cond_type);
-  BTM_TRACE_DEBUG(
-      "                       condition [%02x%02x%02x %02x%02x%02x]",
-      p_filt_cond->bdaddr_cond[0], p_filt_cond->bdaddr_cond[1],
-      p_filt_cond->bdaddr_cond[2], p_filt_cond->bdaddr_cond[3],
-      p_filt_cond->bdaddr_cond[4], p_filt_cond->bdaddr_cond[5]);
+  VLOG(2) << "condition " << p_filt_cond->bdaddr_cond;
 #endif
 
   /* Load the correct filter condition to pass to the lower layer */
@@ -1489,7 +1478,7 @@
       break;
 
     case BTM_FILTER_COND_BD_ADDR:
-      p_cond = p_filt_cond->bdaddr_cond;
+      p_cond = (uint8_t*)&p_filt_cond->bdaddr_cond;
 
       /* condition length should already be set as the default */
       break;
@@ -1692,7 +1681,7 @@
  ******************************************************************************/
 void btm_process_inq_results(uint8_t* p, uint8_t inq_res_mode) {
   uint8_t num_resp, xx;
-  BD_ADDR bda;
+  RawAddress bda;
   tINQ_DB_ENT* p_i;
   tBTM_INQ_RESULTS* p_cur = NULL;
   bool is_new = true;
@@ -2062,7 +2051,7 @@
  *                  BTM_WRONG_MODE if the device is not up.
  *
  ******************************************************************************/
-tBTM_STATUS btm_initiate_rem_name(BD_ADDR remote_bda, uint8_t origin,
+tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
                                   period_ms_t timeout_ms, tBTM_CMPL_CB* p_cb) {
   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
 
@@ -2083,11 +2072,10 @@
       /* If there is no remote name request running,call the callback function
        * and start timer */
       p_inq->p_remname_cmpl_cb = p_cb;
-      memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
+      p_inq->remname_bda = remote_bda;
 
-      alarm_set_on_queue(p_inq->remote_name_timer, timeout_ms,
-                         btm_inq_remote_name_timer_timeout, NULL,
-                         btu_general_alarm_queue);
+      alarm_set_on_mloop(p_inq->remote_name_timer, timeout_ms,
+                         btm_inq_remote_name_timer_timeout, NULL);
 
       /* If the database entry exists for the device, use its clock offset */
       tINQ_DB_ENT* p_i = btm_inq_db_find(remote_bda);
@@ -2122,8 +2110,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_process_remote_name(BD_ADDR bda, BD_NAME bdn, uint16_t evt_len,
-                             uint8_t hci_status) {
+void btm_process_remote_name(const RawAddress* bda, BD_NAME bdn,
+                             uint16_t evt_len, uint8_t hci_status) {
   tBTM_REMOTE_DEV_NAME rem_name;
   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
   tBTM_CMPL_CB* p_cb = p_inq->p_remname_cmpl_cb;
@@ -2131,23 +2119,16 @@
 
   uint16_t temp_evt_len;
 
-  if (bda != NULL) {
-    BTM_TRACE_EVENT("BDA %02x:%02x:%02x:%02x:%02x:%02x", bda[0], bda[1], bda[2],
-                    bda[3], bda[4], bda[5]);
+  if (bda) {
+    VLOG(2) << "BDA " << *bda;
   }
 
-  BTM_TRACE_EVENT("Inquire BDA %02x:%02x:%02x:%02x:%02x:%02x",
-                  p_inq->remname_bda[0], p_inq->remname_bda[1],
-                  p_inq->remname_bda[2], p_inq->remname_bda[3],
-                  p_inq->remname_bda[4], p_inq->remname_bda[5]);
+  VLOG(2) << "Inquire BDA " << p_inq->remname_bda;
 
   /* If the inquire BDA and remote DBA are the same, then stop the timer and set
    * the active to false */
   if ((p_inq->remname_active == true) &&
-      (((bda != NULL) && (memcmp(bda, p_inq->remname_bda, BD_ADDR_LEN) == 0)) ||
-       bda == NULL))
-
-  {
+      (!bda || (*bda == p_inq->remname_bda))) {
     if (BTM_UseLeLink(p_inq->remname_bda)) {
       if (hci_status == HCI_ERR_UNSPECIFIED)
         btm_ble_cancel_remote_name(p_inq->remname_bda);
@@ -2183,7 +2164,7 @@
       rem_name.remote_bd_name[0] = 0;
     }
     /* Reset the remote BAD to zero and call callback if possible */
-    memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
+    p_inq->remname_bda = RawAddress::kEmpty;
 
     p_inq->p_remname_cmpl_cb = NULL;
     if (p_cb) (p_cb)((tBTM_REMOTE_DEV_NAME*)&rem_name);
@@ -2210,7 +2191,7 @@
                   btm_cb.btm_inq_vars.remname_active);
 
   if (btm_cb.btm_inq_vars.remname_active)
-    btm_process_remote_name(btm_cb.btm_inq_vars.remname_bda, NULL, 0,
+    btm_process_remote_name(&btm_cb.btm_inq_vars.remname_bda, NULL, 0,
                             HCI_ERR_UNSPECIFIED);
   else
     btm_process_remote_name(NULL, NULL, 0, HCI_ERR_UNSPECIFIED);
@@ -2244,7 +2225,7 @@
  ******************************************************************************/
 void btm_read_inq_tx_power_complete(uint8_t* p) {
   tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_inq_tx_power_cmpl_cb;
-  tBTM_INQ_TXPWR_RESULTS results;
+  tBTM_INQ_TXPWR_RESULT result;
 
   BTM_TRACE_DEBUG("%s", __func__);
   alarm_cancel(btm_cb.devcb.read_inq_tx_power_timer);
@@ -2252,19 +2233,20 @@
 
   /* If there was a registered callback, call it */
   if (p_cb) {
-    STREAM_TO_UINT8(results.hci_status, p);
+    STREAM_TO_UINT8(result.hci_status, p);
 
-    if (results.hci_status == HCI_SUCCESS) {
-      results.status = BTM_SUCCESS;
+    if (result.hci_status == HCI_SUCCESS) {
+      result.status = BTM_SUCCESS;
 
-      STREAM_TO_UINT8(results.tx_power, p);
+      STREAM_TO_UINT8(result.tx_power, p);
       BTM_TRACE_EVENT(
           "BTM INQ TX POWER Complete: tx_power %d, hci status 0x%02x",
-          results.tx_power, results.hci_status);
-    } else
-      results.status = BTM_ERR_PROCESSING;
+          result.tx_power, result.hci_status);
+    } else {
+      result.status = BTM_ERR_PROCESSING;
+    }
 
-    (*p_cb)(&results);
+    (*p_cb)(&result);
   }
 }
 /*******************************************************************************
diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h
index 1abb2be..76b05ef 100644
--- a/stack/btm/btm_int.h
+++ b/stack/btm/btm_int.h
@@ -51,17 +51,17 @@
 /* Internal functions provided by btm_inq.cc
  ******************************************
 */
-extern tBTM_STATUS btm_initiate_rem_name(BD_ADDR remote_bda, uint8_t origin,
-                                         period_ms_t timeout_ms,
+extern tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda,
+                                         uint8_t origin, period_ms_t timeout_ms,
                                          tBTM_CMPL_CB* p_cb);
 
-extern void btm_process_remote_name(BD_ADDR bda, BD_NAME name, uint16_t evt_len,
-                                    uint8_t hci_status);
+extern void btm_process_remote_name(const RawAddress* bda, BD_NAME name,
+                                    uint16_t evt_len, uint8_t hci_status);
 extern void btm_inq_rmt_name_failed(void);
 extern void btm_inq_remote_name_timer_timeout(void* data);
 
 /* Inquiry related functions */
-extern void btm_clr_inq_db(BD_ADDR p_bda);
+extern void btm_clr_inq_db(const RawAddress* p_bda);
 extern void btm_inq_db_init(void);
 extern void btm_process_inq_results(uint8_t* p, uint8_t inq_res_mode);
 extern void btm_process_inq_complete(uint8_t status, uint8_t mode);
@@ -69,19 +69,17 @@
 extern void btm_event_filter_complete(uint8_t* p);
 extern void btm_inq_stop_on_ssp(void);
 extern void btm_inq_clear_ssp(void);
-extern tINQ_DB_ENT* btm_inq_db_find(const BD_ADDR p_bda);
-extern bool btm_inq_find_bdaddr(BD_ADDR p_bda);
-
-extern bool btm_lookup_eir(BD_ADDR_PTR p_rem_addr);
+extern tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda);
+extern bool btm_inq_find_bdaddr(const RawAddress& p_bda);
 
 /* Internal functions provided by btm_acl.cc
  *******************************************
 */
 extern void btm_acl_init(void);
-extern void btm_acl_created(BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
+extern void btm_acl_created(const RawAddress& bda, DEV_CLASS dc, BD_NAME bdn,
                             uint16_t hci_handle, uint8_t link_role,
                             tBT_TRANSPORT transport);
-extern void btm_acl_removed(BD_ADDR bda, tBT_TRANSPORT transport);
+extern void btm_acl_removed(const RawAddress& bda, tBT_TRANSPORT transport);
 extern void btm_acl_device_down(void);
 extern void btm_acl_update_busy_level(tBTM_BLI_EVENT event);
 
@@ -94,6 +92,12 @@
 extern void btm_read_rssi_timeout(void* data);
 extern void btm_read_rssi_complete(uint8_t* p);
 
+extern void btm_read_failed_contact_counter_timeout(void* data);
+extern void btm_read_failed_contact_counter_complete(uint8_t* p);
+
+extern void btm_read_automatic_flush_timeout_timeout(void* data);
+extern void btm_read_automatic_flush_timeout_complete(uint8_t* p);
+
 extern void btm_read_tx_power_timeout(void* data);
 extern void btm_read_tx_power_complete(uint8_t* p, bool is_ble);
 
@@ -103,14 +107,15 @@
 extern tBTM_STATUS btm_set_packet_types(tACL_CONN* p, uint16_t pkt_types);
 extern void btm_process_clk_off_comp_evt(uint16_t hci_handle,
                                          uint16_t clock_offset);
-extern void btm_acl_role_changed(uint8_t hci_status, BD_ADDR bd_addr,
+extern void btm_acl_role_changed(uint8_t hci_status, const RawAddress* bd_addr,
                                  uint8_t new_role);
-extern void btm_blacklist_role_change_device(BD_ADDR bd_addr,
+extern void btm_blacklist_role_change_device(const RawAddress& bd_addr,
                                              uint8_t hci_status);
 extern void btm_acl_encrypt_change(uint16_t handle, uint8_t status,
                                    uint8_t encr_enable);
 extern uint16_t btm_get_acl_disc_reason_code(void);
-extern tBTM_STATUS btm_remove_acl(BD_ADDR bd_addr, tBT_TRANSPORT transport);
+extern tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr,
+                                  tBT_TRANSPORT transport);
 extern void btm_read_remote_features_complete(uint8_t* p);
 extern void btm_read_remote_ext_features_complete(uint8_t* p, uint8_t evt_len);
 extern void btm_read_remote_ext_features_failed(uint8_t status,
@@ -121,10 +126,12 @@
 extern void btm_acl_chk_peer_pkt_type_support(tACL_CONN* p,
                                               uint16_t* p_pkt_type);
 /* Read maximum data packet that can be sent over current connection */
-extern uint16_t btm_get_max_packet_size(BD_ADDR addr);
-extern tACL_CONN* btm_bda_to_acl(const BD_ADDR bda, tBT_TRANSPORT transport);
-extern bool btm_acl_notif_conn_collision(BD_ADDR bda);
-extern void btm_acl_update_conn_addr(uint8_t conn_handle, BD_ADDR address);
+extern uint16_t btm_get_max_packet_size(const RawAddress& addr);
+extern tACL_CONN* btm_bda_to_acl(const RawAddress& bda,
+                                 tBT_TRANSPORT transport);
+extern bool btm_acl_notif_conn_collision(const RawAddress& bda);
+extern void btm_acl_update_conn_addr(uint16_t conn_handle,
+                                     const RawAddress& address);
 
 extern void btm_pm_reset(void);
 extern void btm_pm_sm_alloc(uint8_t ind);
@@ -132,7 +139,7 @@
 extern void btm_pm_proc_mode_change(uint8_t hci_status, uint16_t hci_handle,
                                     uint8_t mode, uint16_t interval);
 extern void btm_pm_proc_ssr_evt(uint8_t* p, uint16_t evt_len);
-extern tBTM_STATUS btm_read_power_mode_state(BD_ADDR remote_bda,
+extern tBTM_STATUS btm_read_power_mode_state(const RawAddress& remote_bda,
                                              tBTM_PM_STATE* pmState);
 #if (BTM_SCO_INCLUDED == TRUE)
 extern void btm_sco_chk_pend_unpark(uint8_t hci_status, uint16_t hci_handle);
@@ -148,19 +155,19 @@
  *******************************************
 */
 extern void btm_sco_init(void);
-extern void btm_sco_connected(uint8_t hci_status, BD_ADDR bda,
+extern void btm_sco_connected(uint8_t hci_status, const RawAddress* bda,
                               uint16_t hci_handle, tBTM_ESCO_DATA* p_esco_data);
 extern void btm_esco_proc_conn_chg(uint8_t status, uint16_t handle,
                                    uint8_t tx_interval, uint8_t retrans_window,
                                    uint16_t rx_pkt_len, uint16_t tx_pkt_len);
-extern void btm_sco_conn_req(BD_ADDR bda, DEV_CLASS dev_class,
+extern void btm_sco_conn_req(const RawAddress& bda, DEV_CLASS dev_class,
                              uint8_t link_type);
 extern void btm_sco_removed(uint16_t hci_handle, uint8_t reason);
-extern void btm_sco_acl_removed(BD_ADDR bda);
+extern void btm_sco_acl_removed(const RawAddress* bda);
 extern void btm_route_sco_data(BT_HDR* p_msg);
 extern bool btm_is_sco_active(uint16_t handle);
-extern void btm_remove_sco_links(BD_ADDR bda);
-extern bool btm_is_sco_active_by_bdaddr(BD_ADDR remote_bda);
+extern void btm_remove_sco_links(const RawAddress& bda);
+extern bool btm_is_sco_active_by_bdaddr(const RawAddress& remote_bda);
 
 extern void btm_read_def_esco_mode(enh_esco_params_t* p_parms);
 extern uint16_t btm_find_scb_by_handle(uint16_t handle);
@@ -177,7 +184,8 @@
 extern void btm_ble_remove_from_white_list_complete(uint8_t* p,
                                                     uint16_t evt_len);
 extern void btm_ble_clear_white_list_complete(uint8_t* p, uint16_t evt_len);
-extern bool btm_ble_addr_resolvable(BD_ADDR rpa, tBTM_SEC_DEV_REC* p_dev_rec);
+extern bool btm_ble_addr_resolvable(const RawAddress& rpa,
+                                    tBTM_SEC_DEV_REC* p_dev_rec);
 extern tBTM_STATUS btm_ble_read_resolving_list_entry(
     tBTM_SEC_DEV_REC* p_dev_rec);
 extern bool btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC* p_dev_rec);
@@ -194,30 +202,34 @@
 /* Internal functions provided by btm_dev.cc
  *********************************************
 */
-extern bool btm_dev_support_switch(BD_ADDR bd_addr);
+extern bool btm_dev_support_switch(const RawAddress& bd_addr);
 
 extern tBTM_SEC_DEV_REC* btm_sec_allocate_dev_rec(void);
-extern tBTM_SEC_DEV_REC* btm_sec_alloc_dev(BD_ADDR bd_addr);
+extern tBTM_SEC_DEV_REC* btm_sec_alloc_dev(const RawAddress& bd_addr);
 extern void btm_sec_free_dev(tBTM_SEC_DEV_REC* p_dev_rec);
-extern tBTM_SEC_DEV_REC* btm_find_dev(const BD_ADDR bd_addr);
-extern tBTM_SEC_DEV_REC* btm_find_or_alloc_dev(BD_ADDR bd_addr);
+extern tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr);
+extern tBTM_SEC_DEV_REC* btm_find_or_alloc_dev(const RawAddress& bd_addr);
 extern tBTM_SEC_DEV_REC* btm_find_dev_by_handle(uint16_t handle);
-extern tBTM_BOND_TYPE btm_get_bond_type_dev(BD_ADDR bd_addr);
-extern bool btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type);
+extern tBTM_BOND_TYPE btm_get_bond_type_dev(const RawAddress& bd_addr);
+extern bool btm_set_bond_type_dev(const RawAddress& bd_addr,
+                                  tBTM_BOND_TYPE bond_type);
 
 /* Internal functions provided by btm_sec.cc
  *********************************************
 */
-extern bool btm_dev_support_switch(BD_ADDR bd_addr);
-extern tBTM_STATUS btm_sec_l2cap_access_req(BD_ADDR bd_addr, uint16_t psm,
-                                            uint16_t handle,
+extern bool btm_dev_support_switch(const RawAddress& bd_addr);
+extern tBTM_STATUS btm_sec_l2cap_access_req(const RawAddress& bd_addr,
+                                            uint16_t psm, uint16_t handle,
                                             CONNECTION_TYPE conn_type,
                                             tBTM_SEC_CALLBACK* p_callback,
                                             void* p_ref_data);
-extern tBTM_STATUS btm_sec_mx_access_request(
-    BD_ADDR bd_addr, uint16_t psm, bool is_originator, uint32_t mx_proto_id,
-    uint32_t mx_chan_id, tBTM_SEC_CALLBACK* p_callback, void* p_ref_data);
-extern void btm_sec_conn_req(uint8_t* bda, uint8_t* dc);
+extern tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr,
+                                             uint16_t psm, bool is_originator,
+                                             uint32_t mx_proto_id,
+                                             uint32_t mx_chan_id,
+                                             tBTM_SEC_CALLBACK* p_callback,
+                                             void* p_ref_data);
+extern void btm_sec_conn_req(const RawAddress& bda, uint8_t* dc);
 extern void btm_create_conn_cancel_complete(uint8_t* p);
 
 extern void btm_read_inq_tx_power_timeout(void* data);
@@ -225,26 +237,27 @@
 
 extern void btm_sec_init(uint8_t sec_mode);
 extern void btm_sec_dev_reset(void);
-extern void btm_sec_abort_access_req(BD_ADDR bd_addr);
+extern void btm_sec_abort_access_req(const RawAddress& bd_addr);
 extern void btm_sec_auth_complete(uint16_t handle, uint8_t status);
 extern void btm_sec_encrypt_change(uint16_t handle, uint8_t status,
                                    uint8_t encr_enable);
-extern void btm_sec_connected(uint8_t* bda, uint16_t handle, uint8_t status,
-                              uint8_t enc_mode);
+extern void btm_sec_connected(const RawAddress& bda, uint16_t handle,
+                              uint8_t status, uint8_t enc_mode);
 extern tBTM_STATUS btm_sec_disconnect(uint16_t handle, uint8_t reason);
 extern void btm_sec_disconnected(uint16_t handle, uint8_t reason);
-extern void btm_sec_rmt_name_request_complete(uint8_t* bd_addr,
+extern void btm_sec_rmt_name_request_complete(const RawAddress* bd_addr,
                                               uint8_t* bd_name, uint8_t status);
 extern void btm_sec_rmt_host_support_feat_evt(uint8_t* p);
-extern void btm_io_capabilities_req(uint8_t* p);
+extern void btm_io_capabilities_req(const RawAddress& p);
 extern void btm_io_capabilities_rsp(uint8_t* p);
 extern void btm_proc_sp_req_evt(tBTM_SP_EVT event, uint8_t* p);
 extern void btm_keypress_notif_evt(uint8_t* p);
 extern void btm_simple_pair_complete(uint8_t* p);
-extern void btm_sec_link_key_notification(uint8_t* p_bda, uint8_t* p_link_key,
+extern void btm_sec_link_key_notification(const RawAddress& p_bda,
+                                          uint8_t* p_link_key,
                                           uint8_t key_type);
-extern void btm_sec_link_key_request(uint8_t* p_bda);
-extern void btm_sec_pin_code_request(uint8_t* p_bda);
+extern void btm_sec_link_key_request(const RawAddress& p_bda);
+extern void btm_sec_pin_code_request(const RawAddress& p_bda);
 extern void btm_sec_update_clock_offset(uint16_t handle, uint16_t clock_offset);
 extern void btm_sec_dev_rec_cback_event(tBTM_SEC_DEV_REC* p_dev_rec,
                                         uint8_t res, bool is_le_trasnport);
@@ -252,27 +265,27 @@
                                       tBTM_SEC_DEV_REC* p_dev_rec);
 
 extern void btm_sec_clear_ble_keys(tBTM_SEC_DEV_REC* p_dev_rec);
-extern bool btm_sec_is_a_bonded_dev(BD_ADDR bda);
+extern bool btm_sec_is_a_bonded_dev(const RawAddress& bda);
 extern void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec);
-extern bool btm_sec_is_le_capable_dev(BD_ADDR bda);
+extern bool btm_sec_is_le_capable_dev(const RawAddress& bda);
 extern bool btm_ble_init_pseudo_addr(tBTM_SEC_DEV_REC* p_dev_rec,
-                                     BD_ADDR new_pseudo_addr);
+                                     const RawAddress& new_pseudo_addr);
 extern tBTM_SEC_SERV_REC* btm_sec_find_first_serv(CONNECTION_TYPE conn_type,
                                                   uint16_t psm);
-extern bool btm_ble_start_sec_check(BD_ADDR bd_addr, uint16_t psm,
+extern bool btm_ble_start_sec_check(const RawAddress& bd_addr, uint16_t psm,
                                     bool is_originator,
                                     tBTM_SEC_CALLBACK* p_callback,
                                     void* p_ref_data);
 
-extern tINQ_DB_ENT* btm_inq_db_new(BD_ADDR p_bda);
+extern tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda);
 
 extern void btm_rem_oob_req(uint8_t* p);
 extern void btm_read_local_oob_complete(uint8_t* p);
 
 extern void btm_acl_resubmit_page(void);
 extern void btm_acl_reset_paging(void);
-extern void btm_acl_paging(BT_HDR* p, BD_ADDR dest);
+extern void btm_acl_paging(BT_HDR* p, const RawAddress& dest);
 extern uint8_t btm_sec_clr_service_by_psm(uint16_t psm);
-extern void btm_sec_clr_temp_auth_service(BD_ADDR bda);
+extern void btm_sec_clr_temp_auth_service(const RawAddress& bda);
 
 #endif
diff --git a/stack/btm/btm_int_types.h b/stack/btm/btm_int_types.h
index b36eaab..c633cf0 100644
--- a/stack/btm/btm_int_types.h
+++ b/stack/btm/btm_int_types.h
@@ -63,7 +63,7 @@
   uint16_t hci_handle;
   uint16_t pkt_types_mask;
   uint16_t clock_offset;
-  BD_ADDR remote_addr;
+  RawAddress remote_addr;
   DEV_CLASS remote_dc;
   BD_NAME remote_name;
 
@@ -100,9 +100,9 @@
   uint8_t encrypt_state;                   /* overall BTM encryption state */
 
   tBT_TRANSPORT transport;
-  BD_ADDR conn_addr;      /* local device address used for this connection */
+  RawAddress conn_addr;   /* local device address used for this connection */
   uint8_t conn_addr_type; /* local device address type for this connection */
-  BD_ADDR active_remote_addr;      /* remote address used on this connection */
+  RawAddress active_remote_addr;   /* remote address used on this connection */
   uint8_t active_remote_addr_type; /* local device address type for this
                                       connection */
   BD_FEATURES peer_le_features; /* Peer LE Used features mask for the device */
@@ -122,9 +122,22 @@
   alarm_t* read_local_name_timer; /* Read local name timer */
   tBTM_CMPL_CB* p_rln_cmpl_cb;    /* Callback function to be called when  */
                                   /* read local name function complete    */
+
   alarm_t* read_rssi_timer;       /* Read RSSI timer */
   tBTM_CMPL_CB* p_rssi_cmpl_cb;   /* Callback function to be called when  */
                                   /* read RSSI function completes */
+
+  alarm_t* read_failed_contact_counter_timer; /* Read Failed Contact Counter */
+                                              /* timer */
+  tBTM_CMPL_CB* p_failed_contact_counter_cmpl_cb; /* Callback function to be */
+  /* called when read Failed Contact Counter function completes */
+
+  alarm_t*
+      read_automatic_flush_timeout_timer; /* Read Automatic Flush Timeout */
+                                          /* timer */
+  tBTM_CMPL_CB* p_automatic_flush_timeout_cmpl_cb; /* Callback function to be */
+  /* called when read Automatic Flush Timeout function completes */
+
   alarm_t* read_link_quality_timer;
   tBTM_CMPL_CB* p_link_qual_cmpl_cb; /* Callback function to be called when  */
                                      /* read link quality function completes */
@@ -151,7 +164,7 @@
       p_le_test_cmd_cmpl_cb; /* Callback function to be called when
                              LE test mode command has been sent successfully */
 
-  BD_ADDR read_tx_pwr_addr; /* read TX power target address     */
+  RawAddress read_tx_pwr_addr; /* read TX power target address     */
 
 #define BTM_LE_SUPPORT_STATE_SIZE 8
   uint8_t le_supported_states[BTM_LE_SUPPORT_STATE_SIZE];
@@ -193,7 +206,7 @@
   /* received for the current inquiry operation. (We do not   */
   /* want to flood the caller with multiple responses from    */
   /* the same device.                                         */
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
 } tINQ_BDADDR;
 
 typedef struct {
@@ -229,7 +242,7 @@
   uint16_t page_scan_type; /* current page scan type */
   tBTM_INQ_TYPE scan_type;
 
-  BD_ADDR remname_bda; /* Name of bd addr for active remote name request */
+  RawAddress remname_bda; /* Name of bd addr for active remote name request */
 #define BTM_RMT_NAME_INACTIVE 0
 #define BTM_RMT_NAME_EXT 0x1 /* Initiated through API */
 #define BTM_RMT_NAME_SEC 0x2 /* Initiated internally by security manager */
@@ -438,18 +451,18 @@
 } tBTM_SEC_BLE_KEYS;
 
 typedef struct {
-  BD_ADDR pseudo_addr; /* LE pseudo address of the device if different from
+  RawAddress pseudo_addr; /* LE pseudo address of the device if different from
                           device address  */
   tBLE_ADDR_TYPE ble_addr_type; /* LE device type: public or random address */
   tBLE_ADDR_TYPE static_addr_type; /* static address type */
-  BD_ADDR static_addr;             /* static address */
+  RawAddress static_addr;          /* static address */
 
 #define BTM_WHITE_LIST_BIT 0x01
 #define BTM_RESOLVING_LIST_BIT 0x02
   uint8_t in_controller_list; /* in controller resolving list or not */
   uint8_t resolving_list_index;
 #if (BLE_PRIVACY_SPT == TRUE)
-  BD_ADDR cur_rand_addr; /* current random address */
+  RawAddress cur_rand_addr; /* current random address */
 
 #define BTM_BLE_ADDR_PSEUDO 0 /* address index device record */
 #define BTM_BLE_ADDR_RRA 1    /* cur_rand_addr */
@@ -478,7 +491,7 @@
                                                         services     */
   uint16_t hci_handle;     /* Handle to connection when exists   */
   uint16_t clock_offset;   /* Latest known clock offset          */
-  BD_ADDR bd_addr;         /* BD_ADDR of the device              */
+  RawAddress bd_addr;      /* BD_ADDR of the device              */
   DEV_CLASS dev_class;     /* DEV_CLASS of the device            */
   LINK_KEY link_key;       /* Device link key                    */
   uint8_t pin_code_length; /* Length of the pin_code used for paring */
@@ -722,7 +735,7 @@
 
 typedef struct {
   bool is_mux;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t psm;
   bool is_orig;
   tBTM_SEC_CALLBACK* p_callback;
@@ -836,7 +849,7 @@
   PIN_CODE pin_code;                /* for legacy devices */
   tBTM_PAIRING_STATE pairing_state; /* The current pairing state    */
   uint8_t pairing_flags;            /* The current pairing flags    */
-  BD_ADDR pairing_bda;              /* The device currently pairing */
+  RawAddress pairing_bda;           /* The device currently pairing */
   alarm_t* pairing_timer;           /* Timer for pairing process    */
   uint16_t disc_handle;             /* for legacy devices */
   uint8_t disc_reason;              /* for legacy devices */
@@ -845,7 +858,7 @@
   tBTM_SEC_SERV_REC* p_out_serv;
   tBTM_MKEY_CALLBACK* mkey_cback;
 
-  BD_ADDR connecting_bda;
+  RawAddress connecting_bda;
   DEV_CLASS connecting_dc;
 
   uint8_t acl_disc_reason;
diff --git a/stack/btm/btm_pm.cc b/stack/btm/btm_pm.cc
index 0df4667..aeb5170 100644
--- a/stack/btm/btm_pm.cc
+++ b/stack/btm/btm_pm.cc
@@ -72,7 +72,7 @@
         BTM_PM_GET_MD1,  BTM_PM_GET_MD2,  BTM_PM_GET_COMP};
 
 /* function prototype */
-static int btm_pm_find_acl_ind(BD_ADDR remote_bda);
+static int btm_pm_find_acl_ind(const RawAddress& remote_bda);
 static tBTM_STATUS btm_pm_snd_md_req(uint8_t pm_id, int link_ind,
                                      tBTM_PM_PWR_MD* p_mode);
 static const char* mode_to_string(tBTM_PM_MODE mode);
@@ -143,7 +143,7 @@
  *                  BTM_UNKNOWN_ADDR if bd addr is not active or bad
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, BD_ADDR remote_bda,
+tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda,
                              tBTM_PM_PWR_MD* p_mode) {
   uint8_t* p_features;
   int ind, acl_ind;
@@ -155,10 +155,8 @@
 
   if (p_mode == NULL) return BTM_ILLEGAL_VALUE;
 
-  BTM_TRACE_API("BTM_SetPowerMode: pm_id %d BDA: %08x mode:0x%x", pm_id,
-                (remote_bda[2] << 24) + (remote_bda[3] << 16) +
-                    (remote_bda[4] << 8) + remote_bda[5],
-                p_mode->mode);
+  VLOG(2) << __func__ << " pm_id " << pm_id << " BDA: " << remote_bda
+          << " mode:0x" << std::hex << p_mode->mode;
 
   /* take out the force bit */
   mode = p_mode->mode & ~BTM_PM_MD_FORCE;
@@ -248,7 +246,8 @@
  *                  BTM_UNKNOWN_ADDR if bd addr is not active or bad
  *
  ******************************************************************************/
-tBTM_STATUS BTM_ReadPowerMode(BD_ADDR remote_bda, tBTM_PM_MODE* p_mode) {
+tBTM_STATUS BTM_ReadPowerMode(const RawAddress& remote_bda,
+                              tBTM_PM_MODE* p_mode) {
   int acl_ind;
 
   acl_ind = btm_pm_find_acl_ind(remote_bda);
@@ -279,7 +278,7 @@
  *                  BTM_UNKNOWN_ADDR if bd addr is not active or bad
  *
  ******************************************************************************/
-tBTM_STATUS btm_read_power_mode_state(BD_ADDR remote_bda,
+tBTM_STATUS btm_read_power_mode_state(const RawAddress& remote_bda,
                                       tBTM_PM_STATE* pmState) {
   int acl_ind = btm_pm_find_acl_ind(remote_bda);
 
@@ -307,7 +306,7 @@
  *                  BTM_CMD_STORED if the command is stored
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SetSsrParams(BD_ADDR remote_bda, uint16_t max_lat,
+tBTM_STATUS BTM_SetSsrParams(const RawAddress& remote_bda, uint16_t max_lat,
                              uint16_t min_rmt_to, uint16_t min_loc_to) {
 #if (BTM_SSR_INCLUDED == TRUE)
   int acl_ind;
@@ -393,12 +392,12 @@
  * Returns          void
  *
  ******************************************************************************/
-static int btm_pm_find_acl_ind(BD_ADDR remote_bda) {
+static int btm_pm_find_acl_ind(const RawAddress& remote_bda) {
   tACL_CONN* p = &btm_cb.acl_db[0];
   uint8_t xx;
 
   for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++) {
-    if ((p->in_use) && (!memcmp(p->remote_addr, remote_bda, BD_ADDR_LEN)) &&
+    if (p->in_use && p->remote_addr == remote_bda &&
         p->transport == BT_TRANSPORT_BR_EDR) {
 #if (BTM_PM_DEBUG == TRUE)
       BTM_TRACE_DEBUG("btm_pm_find_acl_ind ind:%d, st:%d", xx,
diff --git a/stack/btm/btm_sco.cc b/stack/btm/btm_sco.cc
index 477b773..dea830f 100644
--- a/stack/btm/btm_sco.cc
+++ b/stack/btm/btm_sco.cc
@@ -121,7 +121,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status, BD_ADDR bda,
+static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status,
+                              const RawAddress& bda,
                               enh_esco_params_t* p_parms) {
 #if (BTM_MAX_SCO_LINKS > 0)
   tSCO_CONN* p_sco = NULL;
@@ -540,9 +541,9 @@
  *                                   with the sco index used for the connection.
  *
  ******************************************************************************/
-tBTM_STATUS BTM_CreateSco(BD_ADDR remote_bda, bool is_orig, uint16_t pkt_types,
-                          uint16_t* p_sco_inx, tBTM_SCO_CB* p_conn_cb,
-                          tBTM_SCO_CB* p_disc_cb) {
+tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig,
+                          uint16_t pkt_types, uint16_t* p_sco_inx,
+                          tBTM_SCO_CB* p_conn_cb, tBTM_SCO_CB* p_disc_cb) {
 #if (BTM_MAX_SCO_LINKS > 0)
   enh_esco_params_t* p_setup;
   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
@@ -566,13 +567,10 @@
       BTM_TRACE_ERROR("%s: remote_bda is null", __func__);
       return BTM_ILLEGAL_VALUE;
     }
-    acl_handle = BTM_GetHCIConnHandle(remote_bda, BT_TRANSPORT_BR_EDR);
+    acl_handle = BTM_GetHCIConnHandle(*remote_bda, BT_TRANSPORT_BR_EDR);
     if (acl_handle == 0xFFFF) {
-      BTM_TRACE_ERROR(
-          "%s: cannot find ACL handle for remote device "
-          "%02x:%02x:%02x:%02x:%02x:%02x",
-          __func__, remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3],
-          remote_bda[4], remote_bda[5]);
+      VLOG(2) << __func__ << ": cannot find ACL handle for remote device "
+              << remote_bda;
       return BTM_UNKNOWN_ADDR;
     }
   }
@@ -582,7 +580,7 @@
     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
       if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
            (p->state == SCO_ST_PEND_UNPARK)) &&
-          (!memcmp(p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN))) {
+          (p->esco.data.bd_addr == *remote_bda)) {
         return BTM_BUSY;
       }
     }
@@ -609,17 +607,17 @@
                               state);
               memset((void*)&pm, 0, sizeof(pm));
               pm.mode = BTM_PM_MD_ACTIVE;
-              BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm);
+              BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, *remote_bda, &pm);
               p->state = SCO_ST_PEND_UNPARK;
             }
           }
 #else   // BTM_SCO_WAKE_PARKED_LINK
-          if ((BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) &&
+          if ((BTM_ReadPowerMode(*remote_bda, &mode) == BTM_SUCCESS) &&
               (mode == BTM_PM_MD_PARK))
             return (BTM_WRONG_MODE);
 #endif  // BTM_SCO_WAKE_PARKED_LINK
         }
-        memcpy(p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN);
+        p->esco.data.bd_addr = *remote_bda;
         p->rem_bd_known = true;
       } else
         p->rem_bd_known = false;
@@ -647,7 +645,7 @@
         if (is_orig) {
           /* If role change is in progress, do not proceed with SCO setup
            * Wait till role change is complete */
-          p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
+          p_acl = btm_bda_to_acl(*remote_bda, BT_TRANSPORT_BR_EDR);
           if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE) {
             BTM_TRACE_API("Role Change is in progress for ACL handle 0x%04x",
                           acl_handle);
@@ -796,7 +794,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_sco_conn_req(BD_ADDR bda, DEV_CLASS dev_class, uint8_t link_type) {
+void btm_sco_conn_req(const RawAddress& bda, DEV_CLASS dev_class,
+                      uint8_t link_type) {
 #if (BTM_MAX_SCO_LINKS > 0)
   tSCO_CB* p_sco = &btm_cb.sco_cb;
   tSCO_CONN* p = &p_sco->sco_db[0];
@@ -808,8 +807,7 @@
      * If the sco state is in the SCO_ST_CONNECTING state, we still need
      * to return accept sco to avoid race conditon for sco creation
      */
-    int rem_bd_matches =
-        p->rem_bd_known && !memcmp(p->esco.data.bd_addr, bda, BD_ADDR_LEN);
+    int rem_bd_matches = p->rem_bd_known && p->esco.data.bd_addr == bda;
     if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
         ((p->state == SCO_ST_LISTENING) &&
          (rem_bd_matches || !p->rem_bd_known))) {
@@ -817,7 +815,7 @@
       p->rem_bd_known = true;
       p->esco.data.link_type = link_type;
       p->state = SCO_ST_W4_CONN_RSP;
-      memcpy(p->esco.data.bd_addr, bda, BD_ADDR_LEN);
+      p->esco.data.bd_addr = bda;
 
       /* If no callback, auto-accept the connection if packet types match */
       if (!p->esco.p_esco_cback) {
@@ -838,12 +836,13 @@
         }
       } else /* Notify upper layer of connect indication */
       {
-        memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN);
+        evt_data.bd_addr = bda;
         memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
         evt_data.link_type = link_type;
         evt_data.sco_inx = xx;
-        p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT,
-                             (tBTM_ESCO_EVT_DATA*)&evt_data);
+        tBTM_ESCO_EVT_DATA btm_esco_evt_data;
+        btm_esco_evt_data.conn_evt = evt_data;
+        p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, &btm_esco_evt_data);
       }
 
       return;
@@ -860,7 +859,7 @@
         p->state = SCO_ST_LISTENING;
 
         p->esco.data.link_type = link_type;
-        memcpy(p->esco.data.bd_addr, bda, BD_ADDR_LEN);
+        p->esco.data.bd_addr = bda;
         p->rem_bd_known = true;
         break;
       }
@@ -889,8 +888,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_sco_connected(uint8_t hci_status, BD_ADDR bda, uint16_t hci_handle,
-                       tBTM_ESCO_DATA* p_esco_data) {
+void btm_sco_connected(uint8_t hci_status, const RawAddress* bda,
+                       uint16_t hci_handle, tBTM_ESCO_DATA* p_esco_data) {
 #if (BTM_MAX_SCO_LINKS > 0)
   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
   uint16_t xx;
@@ -904,8 +903,7 @@
   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
     if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
          (p->state == SCO_ST_W4_CONN_RSP)) &&
-        (p->rem_bd_known) &&
-        (!bda || !memcmp(p->esco.data.bd_addr, bda, BD_ADDR_LEN))) {
+        (p->rem_bd_known) && (!bda || p->esco.data.bd_addr == *bda)) {
       if (hci_status != HCI_SUCCESS) {
         /* Report the error if originator, otherwise remain in Listen mode */
         if (p->is_orig) {
@@ -1045,13 +1043,13 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_remove_sco_links(BD_ADDR bda) {
+void btm_remove_sco_links(const RawAddress& bda) {
 #if (BTM_MAX_SCO_LINKS > 0)
   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
   uint16_t xx;
 
   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
-    if (p->rem_bd_known && (!memcmp(p->esco.data.bd_addr, bda, BD_ADDR_LEN))) {
+    if (p->rem_bd_known && p->esco.data.bd_addr == bda) {
       BTM_RemoveSco(xx);
     }
   }
@@ -1108,15 +1106,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_sco_acl_removed(BD_ADDR bda) {
+void btm_sco_acl_removed(const RawAddress* bda) {
 #if (BTM_MAX_SCO_LINKS > 0)
   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
   uint16_t xx;
 
   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
     if (p->state != SCO_ST_UNUSED) {
-      if ((!bda) || (!memcmp(p->esco.data.bd_addr, bda, BD_ADDR_LEN) &&
-                     p->rem_bd_known)) {
+      if ((!bda) || (p->esco.data.bd_addr == *bda && p->rem_bd_known)) {
         btm_sco_flush_sco_data(xx);
 
         p->state = SCO_ST_UNUSED;
@@ -1284,13 +1281,13 @@
  * Returns          pointer to BD address or NULL if not known
  *
  ******************************************************************************/
-uint8_t* BTM_ReadScoBdAddr(uint16_t sco_inx) {
+const RawAddress* BTM_ReadScoBdAddr(uint16_t sco_inx) {
 #if (BTM_MAX_SCO_LINKS > 0)
   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
 
   /* Validity check */
   if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
-    return (p->esco.data.bd_addr);
+    return &(p->esco.data.bd_addr);
   else
     return (NULL);
 #else
@@ -1592,7 +1589,7 @@
     if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle) {
       /* If upper layer wants notification */
       if (p->esco.p_esco_cback) {
-        memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN);
+        data.bd_addr = p->esco.data.bd_addr;
         data.hci_status = status;
         data.sco_inx = xx;
         data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len;
@@ -1600,7 +1597,9 @@
         data.tx_interval = p->esco.data.tx_interval = tx_interval;
         data.retrans_window = p->esco.data.retrans_window = retrans_window;
 
-        (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT, (tBTM_ESCO_EVT_DATA*)&data);
+        tBTM_ESCO_EVT_DATA btm_esco_evt_data;
+        btm_esco_evt_data.chg_evt = data;
+        (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT, &btm_esco_evt_data);
       }
       return;
     }
@@ -1671,15 +1670,14 @@
  * Returns          bool
  *
  ******************************************************************************/
-bool btm_is_sco_active_by_bdaddr(BD_ADDR remote_bda) {
+bool btm_is_sco_active_by_bdaddr(const RawAddress& remote_bda) {
 #if (BTM_MAX_SCO_LINKS > 0)
   uint8_t xx;
   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
 
   /* If any SCO is being established to the remote BD address, refuse this */
   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
-    if ((!memcmp(p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) &&
-        (p->state == SCO_ST_CONNECTED)) {
+    if (p->esco.data.bd_addr == remote_bda && p->state == SCO_ST_CONNECTED) {
       return (true);
     }
   }
@@ -1796,9 +1794,9 @@
 
 #else /* SCO_EXCLUDED == TRUE (Link in stubs) */
 
-tBTM_STATUS BTM_CreateSco(BD_ADDR remote_bda, bool is_orig, uint16_t pkt_types,
-                          uint16_t* p_sco_inx, tBTM_SCO_CB* p_conn_cb,
-                          tBTM_SCO_CB* p_disc_cb) {
+tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig,
+                          uint16_t pkt_types, uint16_t* p_sco_inx,
+                          tBTM_SCO_CB* p_conn_cb, tBTM_SCO_CB* p_disc_cb) {
   return (BTM_NO_RESOURCES);
 }
 tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) { return (BTM_NO_RESOURCES); }
@@ -1810,7 +1808,9 @@
 uint16_t BTM_ReadScoHandle(uint16_t sco_inx) {
   return (BTM_INVALID_HCI_HANDLE);
 }
-uint8_t* BTM_ReadScoBdAddr(uint16_t sco_inx) { return ((uint8_t*)NULL); }
+const RawAddress* BTM_ReadScoBdAddr(uint16_t sco_inx) {
+  return ((uint8_t*)NULL);
+}
 uint16_t BTM_ReadScoDiscReason(void) { return (BTM_INVALID_SCO_DISC_REASON); }
 tBTM_STATUS BTM_SetEScoMode(enh_esco_params_t* p_parms) {
   return (BTM_MODE_UNSUPPORTED);
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 3d68c0e..e66ef9d 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -24,6 +24,7 @@
 
 #define LOG_TAG "bt_btm_sec"
 
+#include <log/log.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
@@ -42,15 +43,15 @@
 
 #include "gatt_int.h"
 
+#include "bta/dm/bta_dm_int.h"
+
 #define BTM_SEC_MAX_COLLISION_DELAY (5000)
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 #ifdef APPL_AUTH_WRITE_EXCEPTION
-bool(APPL_AUTH_WRITE_EXCEPTION)(BD_ADDR bd_addr);
+bool(APPL_AUTH_WRITE_EXCEPTION)(const RawAddress& bd_addr);
 #endif
 
-extern void bta_dm_process_remove_device(BD_ADDR bd_addr);
+extern void bta_dm_process_remove_device(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *             L O C A L    F U N C T I O N     P R O T O T Y P E S            *
@@ -75,7 +76,7 @@
 static const char* btm_pair_state_descr(tBTM_PAIRING_STATE state);
 
 static void btm_sec_check_pending_reqs(void);
-static bool btm_sec_queue_mx_request(BD_ADDR bd_addr, uint16_t psm,
+static bool btm_sec_queue_mx_request(const RawAddress& bd_addr, uint16_t psm,
                                      bool is_orig, uint32_t mx_proto_id,
                                      uint32_t mx_chan_id,
                                      tBTM_SEC_CALLBACK* p_callback,
@@ -108,7 +109,7 @@
 static uint16_t btm_sec_set_serv_level4_flags(uint16_t cur_security,
                                               bool is_originator);
 
-static bool btm_sec_queue_encrypt_request(BD_ADDR bd_addr,
+static bool btm_sec_queue_encrypt_request(const RawAddress& bd_addr,
                                           tBT_TRANSPORT transport,
                                           tBTM_SEC_CALLBACK* p_callback,
                                           void* p_ref_data,
@@ -324,7 +325,7 @@
  * Returns          bool    true or false is device found
  *
  ******************************************************************************/
-bool BTM_GetSecurityFlags(BD_ADDR bd_addr, uint8_t* p_sec_flags) {
+bool BTM_GetSecurityFlags(const RawAddress& bd_addr, uint8_t* p_sec_flags) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
   p_dev_rec = btm_find_dev(bd_addr);
@@ -345,7 +346,8 @@
  * Returns          bool    true or false is device found
  *
  ******************************************************************************/
-bool BTM_GetSecurityFlagsByTransport(BD_ADDR bd_addr, uint8_t* p_sec_flags,
+bool BTM_GetSecurityFlagsByTransport(const RawAddress& bd_addr,
+                                     uint8_t* p_sec_flags,
                                      tBT_TRANSPORT transport) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
@@ -783,7 +785,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-void btm_sec_clr_temp_auth_service(BD_ADDR bda) {
+void btm_sec_clr_temp_auth_service(const RawAddress& bda) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
   p_dev_rec = btm_find_dev(bda);
@@ -796,10 +798,7 @@
    * is accessed autorization will take place */
   if (p_dev_rec->last_author_service_id != BTM_SEC_NO_LAST_SERVICE_ID &&
       p_dev_rec->p_cur_service) {
-    BTM_TRACE_DEBUG(
-        "btm_sec_clr_auth_service_by_psm [clearing device: "
-        "%02x:%02x:%02x:%02x:%02x:%02x]",
-        bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+    VLOG(1) << __func__ << " clearing device: " << bda;
 
     p_dev_rec->last_author_service_id = BTM_SEC_NO_LAST_SERVICE_ID;
   }
@@ -822,7 +821,7 @@
  *                                 (array of uint32_t)
  *
  ******************************************************************************/
-void BTM_PINCodeReply(BD_ADDR bd_addr, uint8_t res, uint8_t pin_len,
+void BTM_PINCodeReply(const RawAddress& bd_addr, uint8_t res, uint8_t pin_len,
                       uint8_t* p_pin, uint32_t trusted_mask[]) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
@@ -839,7 +838,7 @@
     return;
   }
 
-  if (memcmp(bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) != 0) {
+  if (bd_addr != btm_cb.pairing_bda) {
     BTM_TRACE_ERROR("BTM_PINCodeReply() - Wrong BD Addr");
     return;
   }
@@ -944,17 +943,15 @@
  *
  *  Note: After 2.1 parameters are not used and preserved here not to change API
  ******************************************************************************/
-tBTM_STATUS btm_sec_bond_by_transport(BD_ADDR bd_addr, tBT_TRANSPORT transport,
-                                      uint8_t pin_len, uint8_t* p_pin,
-                                      uint32_t trusted_mask[]) {
+tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr,
+                                      tBT_TRANSPORT transport, uint8_t pin_len,
+                                      uint8_t* p_pin, uint32_t trusted_mask[]) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   tBTM_STATUS status;
   uint8_t* p_features;
   uint8_t ii;
   tACL_CONN* p = btm_bda_to_acl(bd_addr, transport);
-  BTM_TRACE_API("btm_sec_bond_by_transport BDA: %02x:%02x:%02x:%02x:%02x:%02x",
-                bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-                bd_addr[5]);
+  VLOG(1) << __func__ << " BDA: " << bd_addr;
 
   BTM_TRACE_DEBUG("btm_sec_bond_by_transport: Transport used %d", transport);
 
@@ -989,7 +986,7 @@
   }
 
   /* Tell controller to get rid of the link key if it has one stored */
-  if ((BTM_DeleteStoredLinkKey(bd_addr, NULL)) != BTM_SUCCESS)
+  if ((BTM_DeleteStoredLinkKey(&bd_addr, NULL)) != BTM_SUCCESS)
     return (BTM_NO_RESOURCES);
 
   /* Save the PIN code if we got a valid one */
@@ -999,7 +996,7 @@
     memcpy(btm_cb.pin_code, p_pin, PIN_CODE_LEN);
   }
 
-  memcpy(btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN);
+  btm_cb.pairing_bda = bd_addr;
 
   btm_cb.pairing_flags = BTM_PAIR_FLAGS_WE_STARTED_DD;
 
@@ -1123,9 +1120,9 @@
  *
  *  Note: After 2.1 parameters are not used and preserved here not to change API
  ******************************************************************************/
-tBTM_STATUS BTM_SecBondByTransport(BD_ADDR bd_addr, tBT_TRANSPORT transport,
-                                   uint8_t pin_len, uint8_t* p_pin,
-                                   uint32_t trusted_mask[]) {
+tBTM_STATUS BTM_SecBondByTransport(const RawAddress& bd_addr,
+                                   tBT_TRANSPORT transport, uint8_t pin_len,
+                                   uint8_t* p_pin, uint32_t trusted_mask[]) {
   tBT_DEVICE_TYPE dev_type;
   tBLE_ADDR_TYPE addr_type;
 
@@ -1156,8 +1153,8 @@
  *
  *  Note: After 2.1 parameters are not used and preserved here not to change API
  ******************************************************************************/
-tBTM_STATUS BTM_SecBond(BD_ADDR bd_addr, uint8_t pin_len, uint8_t* p_pin,
-                        uint32_t trusted_mask[]) {
+tBTM_STATUS BTM_SecBond(const RawAddress& bd_addr, uint8_t pin_len,
+                        uint8_t* p_pin, uint32_t trusted_mask[]) {
   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
   if (BTM_UseLeLink(bd_addr)) transport = BT_TRANSPORT_LE;
   return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin,
@@ -1174,15 +1171,14 @@
  *                  transport    - false for BR/EDR link; true for LE link
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SecBondCancel(BD_ADDR bd_addr) {
+tBTM_STATUS BTM_SecBondCancel(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
   BTM_TRACE_API("BTM_SecBondCancel()  State: %s flags:0x%x",
                 btm_pair_state_descr(btm_cb.pairing_state),
                 btm_cb.pairing_flags);
   p_dev_rec = btm_find_dev(bd_addr);
-  if ((p_dev_rec == NULL) ||
-      (memcmp(btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0)) {
+  if (!p_dev_rec || btm_cb.pairing_bda != bd_addr) {
     return BTM_UNKNOWN_ADDR;
   }
 
@@ -1255,7 +1251,8 @@
  *                  link_key     - Link Key is copied into this array
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SecGetDeviceLinkKey(BD_ADDR bd_addr, LINK_KEY link_key) {
+tBTM_STATUS BTM_SecGetDeviceLinkKey(const RawAddress& bd_addr,
+                                    LINK_KEY link_key) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   p_dev_rec = btm_find_dev(bd_addr);
   if ((p_dev_rec != NULL) && (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)) {
@@ -1279,7 +1276,7 @@
  *                  otherwise.
  *
  ******************************************************************************/
-tBTM_LINK_KEY_TYPE BTM_SecGetDeviceLinkKeyType(BD_ADDR bd_addr) {
+tBTM_LINK_KEY_TYPE BTM_SecGetDeviceLinkKeyType(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
 
   if ((p_dev_rec != NULL) && (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)) {
@@ -1315,7 +1312,8 @@
  *                  BTM_MODE_UNSUPPORTED - if security manager not linked in.
  *
  ******************************************************************************/
-tBTM_STATUS BTM_SetEncryption(BD_ADDR bd_addr, tBT_TRANSPORT transport,
+tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr,
+                              tBT_TRANSPORT transport,
                               tBTM_SEC_CBACK* p_callback, void* p_ref_data,
                               tBTM_BLE_SEC_ACT sec_act) {
   tBTM_STATUS rc = 0;
@@ -1329,7 +1327,7 @@
     BTM_TRACE_WARNING("Security Manager: BTM_SetEncryption not connected");
 
     if (p_callback)
-      (*p_callback)(bd_addr, transport, p_ref_data, BTM_WRONG_MODE);
+      (*p_callback)(&bd_addr, transport, p_ref_data, BTM_WRONG_MODE);
 
     return (BTM_WRONG_MODE);
   }
@@ -1338,7 +1336,8 @@
       (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)) {
     BTM_TRACE_EVENT("Security Manager: BTM_SetEncryption already encrypted");
 
-    if (p_callback) (*p_callback)(bd_addr, transport, p_ref_data, BTM_SUCCESS);
+    if (*p_callback)
+      (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS);
 
     return (BTM_SUCCESS);
   }
@@ -1353,7 +1352,7 @@
       return BTM_CMD_STARTED;
     } else {
       if (p_callback)
-        (*p_callback)(bd_addr, transport, p_ref_data, BTM_NO_RESOURCES);
+        (*p_callback)(&bd_addr, transport, p_ref_data, BTM_NO_RESOURCES);
       return BTM_NO_RESOURCES;
     }
   }
@@ -1386,7 +1385,7 @@
   if (rc != BTM_CMD_STARTED && rc != BTM_BUSY) {
     if (p_callback) {
       p_dev_rec->p_callback = NULL;
-      (*p_callback)(bd_addr, transport, p_dev_rec->p_ref_data, rc);
+      (*p_callback)(&bd_addr, transport, p_dev_rec->p_ref_data, rc);
     }
   }
 
@@ -1460,7 +1459,7 @@
  *                  bd_addr       - Address of the peer device
  *
  ******************************************************************************/
-void BTM_ConfirmReqReply(tBTM_STATUS res, BD_ADDR bd_addr) {
+void BTM_ConfirmReqReply(tBTM_STATUS res, const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
   BTM_TRACE_EVENT("BTM_ConfirmReqReply() State: %s  Res: %u",
@@ -1468,7 +1467,7 @@
 
   /* If timeout already expired or has been canceled, ignore the reply */
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM) ||
-      (memcmp(btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0))
+      (btm_cb.pairing_bda != bd_addr))
     return;
 
   btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
@@ -1508,12 +1507,13 @@
  *
  ******************************************************************************/
 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
-void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, uint32_t passkey) {
+void BTM_PasskeyReqReply(tBTM_STATUS res, const RawAddress& bd_addr,
+                         uint32_t passkey) {
   BTM_TRACE_API("BTM_PasskeyReqReply: State: %s  res:%d",
                 btm_pair_state_descr(btm_cb.pairing_state), res);
 
   if ((btm_cb.pairing_state == BTM_PAIR_STATE_IDLE) ||
-      (memcmp(btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0)) {
+      (btm_cb.pairing_bda != bd_addr)) {
     return;
   }
 
@@ -1570,7 +1570,7 @@
  *
  ******************************************************************************/
 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
-void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type) {
+void BTM_SendKeypressNotif(const RawAddress& bd_addr, tBTM_SP_KEY_TYPE type) {
   /* This API only make sense between PASSKEY_REQ and SP complete */
   if (btm_cb.pairing_state == BTM_PAIR_STATE_KEY_ENTRY)
     btsnd_hcic_send_keypress_notif(bd_addr, type);
@@ -1592,13 +1592,13 @@
  *                  auth_req- MITM protection required or not.
  *
  ******************************************************************************/
-void BTM_IoCapRsp(BD_ADDR bd_addr, tBTM_IO_CAP io_cap, tBTM_OOB_DATA oob,
-                  tBTM_AUTH_REQ auth_req) {
+void BTM_IoCapRsp(const RawAddress& bd_addr, tBTM_IO_CAP io_cap,
+                  tBTM_OOB_DATA oob, tBTM_AUTH_REQ auth_req) {
   BTM_TRACE_EVENT("BTM_IoCapRsp: state: %s  oob: %d io_cap: %d",
                   btm_pair_state_descr(btm_cb.pairing_state), oob, io_cap);
 
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS) ||
-      (memcmp(btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0))
+      (btm_cb.pairing_bda != bd_addr))
     return;
 
   if (oob < BTM_OOB_UNKNOWN && io_cap < BTM_IO_CAP_MAX) {
@@ -1634,8 +1634,8 @@
  *                  r           - simple pairing Randomizer  C.
  *
  ******************************************************************************/
-void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, BT_OCTET16 c,
-                            BT_OCTET16 r) {
+void BTM_RemoteOobDataReply(tBTM_STATUS res, const RawAddress& bd_addr,
+                            BT_OCTET16 c, BT_OCTET16 r) {
   BTM_TRACE_EVENT("%s() - State: %s res: %d", __func__,
                   btm_pair_state_descr(btm_cb.pairing_state), res);
 
@@ -1683,7 +1683,7 @@
   if (p_data && max_len >= BTM_OOB_MANDATORY_SIZE) {
     /* add mandatory part */
     UINT16_TO_STREAM(p, len);
-    BDADDR_TO_STREAM(p, controller_get_interface()->get_address()->address);
+    BDADDR_TO_STREAM(p, *controller_get_interface()->get_address());
 
     len = BTM_OOB_MANDATORY_SIZE;
     max_len -= len;
@@ -1753,7 +1753,7 @@
  *                  local and the remote device, else false.
  *
  ******************************************************************************/
-bool BTM_BothEndsSupportSecureConnections(BD_ADDR bd_addr) {
+bool BTM_BothEndsSupportSecureConnections(const RawAddress& bd_addr) {
   return ((controller_get_interface()->supports_secure_connections()) &&
           (BTM_PeerSupportsSecureConnections(bd_addr)));
 }
@@ -1771,15 +1771,12 @@
  *                  else false.
  *
  ******************************************************************************/
-bool BTM_PeerSupportsSecureConnections(BD_ADDR bd_addr) {
+bool BTM_PeerSupportsSecureConnections(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec;
 
   p_dev_rec = btm_find_dev(bd_addr);
   if (p_dev_rec == NULL) {
-    BTM_TRACE_WARNING("%s: unknown BDA: %08x%04x", __func__,
-                      (bd_addr[0] << 24) + (bd_addr[1] << 16) +
-                          (bd_addr[2] << 8) + bd_addr[3],
-                      (bd_addr[4] << 8) + bd_addr[5]);
+    LOG(WARNING) << __func__ << ": unknown BDA: " << bd_addr;
     return false;
   }
 
@@ -1858,7 +1855,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void BTM_SetOutService(BD_ADDR bd_addr, uint8_t service_id,
+void BTM_SetOutService(const RawAddress& bd_addr, uint8_t service_id,
                        uint32_t mx_chan_id) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   tBTM_SEC_SERV_REC* p_serv_rec = &btm_cb.sec_serv_rec[0];
@@ -1915,9 +1912,9 @@
           p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps, mtm_check);
     }
     /* Already have a link key to the connected peer. Is the link key secure
-    *enough?
-    ** Is a link key upgrade even possible?
-    */
+     *enough?
+     ** Is a link key upgrade even possible?
+     */
     if ((p_dev_rec->security_required & mtm_check) /* needs MITM */
         && ((p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB) ||
             (p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256))
@@ -1964,7 +1961,7 @@
      * it probably would not want to upgrade the link key based on the security
      * level database */
     tBTM_SP_UPGRADE evt_data;
-    memcpy(evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
+    evt_data.bd_addr = p_dev_rec->bd_addr;
     evt_data.upgrade = true;
     if (btm_cb.api.p_sp_callback)
       (*btm_cb.api.p_sp_callback)(BTM_SP_UPGRADE_EVT,
@@ -2002,7 +1999,7 @@
  * Returns          tBTM_STATUS
  *
  ******************************************************************************/
-tBTM_STATUS btm_sec_l2cap_access_req(BD_ADDR bd_addr, uint16_t psm,
+tBTM_STATUS btm_sec_l2cap_access_req(const RawAddress& bd_addr, uint16_t psm,
                                      uint16_t handle, CONNECTION_TYPE conn_type,
                                      tBTM_SEC_CALLBACK* p_callback,
                                      void* p_ref_data) {
@@ -2045,14 +2042,14 @@
    */
   if (!p_serv_rec) {
     BTM_TRACE_WARNING("%s() PSM: %d no application registerd", __func__, psm);
-    (*p_callback)(bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
+    (*p_callback)(&bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
     return (BTM_MODE_UNSUPPORTED);
   }
 
   /* Services level0 by default have no security */
   if ((btm_sec_is_serv_level0(psm)) &&
       (!btm_cb.devcb.secure_connections_only)) {
-    (*p_callback)(bd_addr, transport, p_ref_data, BTM_SUCCESS_NO_SECURITY);
+    (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS_NO_SECURITY);
     return (BTM_SUCCESS);
   }
 #if (L2CAP_UCD_INCLUDED == TRUE)
@@ -2104,7 +2101,7 @@
 
     if (rc == BTM_SUCCESS) {
       if (p_callback)
-        (*p_callback)(bd_addr, transport, (void*)p_ref_data, BTM_SUCCESS);
+        (*p_callback)(&bd_addr, transport, (void*)p_ref_data, BTM_SUCCESS);
 
       return (BTM_SUCCESS);
     }
@@ -2135,7 +2132,7 @@
                       local_supports_sc,
                       p_dev_rec->remote_supports_secure_connections);
       if (p_callback)
-        (*p_callback)(bd_addr, transport, (void*)p_ref_data,
+        (*p_callback)(&bd_addr, transport, (void*)p_ref_data,
                       BTM_MODE4_LEVEL4_NOT_SUPPORTED);
 
       return (BTM_MODE4_LEVEL4_NOT_SUPPORTED);
@@ -2216,7 +2213,7 @@
 
       if (rc == BTM_SUCCESS) {
         if (p_callback)
-          (*p_callback)(bd_addr, transport, (void*)p_ref_data, BTM_SUCCESS);
+          (*p_callback)(&bd_addr, transport, (void*)p_ref_data, BTM_SUCCESS);
         return (BTM_SUCCESS);
       }
     }
@@ -2292,7 +2289,7 @@
       p_dev_rec->security_required = old_security_required;
       p_dev_rec->is_originator = old_is_originator;
 
-      (*p_callback)(bd_addr, transport, p_ref_data, BTM_SUCCESS);
+      (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS);
 
       return (BTM_SUCCESS);
     }
@@ -2315,7 +2312,7 @@
     p_dev_rec->security_required = old_security_required;
     p_dev_rec->is_originator = old_is_originator;
 
-    (*p_callback)(bd_addr, transport, p_ref_data, BTM_SUCCESS);
+    (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS);
 
     return (BTM_SUCCESS);
   }
@@ -2342,7 +2339,7 @@
           __func__);
       p_dev_rec->p_callback = p_callback;
       p_dev_rec->sec_state = BTM_SEC_STATE_DELAY_FOR_ENC;
-      (*p_callback)(bd_addr, transport, p_ref_data, rc);
+      (*p_callback)(&bd_addr, transport, p_ref_data, rc);
 
       return BTM_SUCCESS;
     }
@@ -2388,7 +2385,7 @@
   rc = btm_sec_execute_procedure(p_dev_rec);
   if (rc != BTM_CMD_STARTED) {
     p_dev_rec->p_callback = NULL;
-    (*p_callback)(bd_addr, transport, p_dev_rec->p_ref_data, (uint8_t)rc);
+    (*p_callback)(&bd_addr, transport, p_dev_rec->p_ref_data, (uint8_t)rc);
   }
 
   return (rc);
@@ -2417,7 +2414,7 @@
  * Returns          BTM_CMD_STARTED
  *
  ******************************************************************************/
-tBTM_STATUS btm_sec_mx_access_request(BD_ADDR bd_addr, uint16_t psm,
+tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, uint16_t psm,
                                       bool is_originator, uint32_t mx_proto_id,
                                       uint32_t mx_chan_id,
                                       tBTM_SEC_CALLBACK* p_callback,
@@ -2441,7 +2438,7 @@
    */
   if (!p_serv_rec) {
     if (p_callback)
-      (*p_callback)(bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
+      (*p_callback)(&bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
 
     BTM_TRACE_ERROR(
         "Security Manager: MX service not found PSM:%d Proto:%d SCN:%d", psm,
@@ -2552,7 +2549,7 @@
     {
       /* access granted */
       if (p_callback) {
-        (*p_callback)(bd_addr, transport, p_ref_data, (uint8_t)rc);
+        (*p_callback)(&bd_addr, transport, p_ref_data, (uint8_t)rc);
       }
     }
 
@@ -2575,7 +2572,7 @@
                       p_dev_rec->remote_supports_secure_connections);
 
       if (p_callback)
-        (*p_callback)(bd_addr, transport, (void*)p_ref_data,
+        (*p_callback)(&bd_addr, transport, (void*)p_ref_data,
                       BTM_MODE4_LEVEL4_NOT_SUPPORTED);
 
       return (BTM_MODE4_LEVEL4_NOT_SUPPORTED);
@@ -2630,7 +2627,7 @@
   if (rc != BTM_CMD_STARTED) {
     if (p_callback) {
       p_dev_rec->p_callback = NULL;
-      (*p_callback)(bd_addr, transport, p_ref_data, (uint8_t)rc);
+      (*p_callback)(&bd_addr, transport, p_ref_data, (uint8_t)rc);
     }
   }
 
@@ -2647,7 +2644,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_sec_conn_req(uint8_t* bda, uint8_t* dc) {
+void btm_sec_conn_req(const RawAddress& bda, uint8_t* dc) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda);
 
   /* Some device may request a connection before we are done with the HCI_Reset
@@ -2684,7 +2681,7 @@
 
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
       (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) &&
-      (!memcmp(btm_cb.pairing_bda, bda, BD_ADDR_LEN))) {
+      (btm_cb.pairing_bda == bda)) {
     BTM_TRACE_EVENT(
         "Security Manager: reject connect request from bonding device");
 
@@ -2696,7 +2693,7 @@
 
   /* Host is not interested or approved connection.  Save BDA and DC and */
   /* pass request to L2CAP */
-  memcpy(btm_cb.connecting_bda, bda, BD_ADDR_LEN);
+  btm_cb.connecting_bda = bda;
   memcpy(btm_cb.connecting_dc, dc, DEV_CLASS_LEN);
 
   if (l2c_link_hci_conn_req(bda)) {
@@ -2798,7 +2795,7 @@
     /* First, resubmit L2CAP requests */
     if (btm_cb.sec_req_pending) {
       btm_cb.sec_req_pending = false;
-      l2cu_resubmit_pending_sec_req(NULL);
+      l2cu_resubmit_pending_sec_req(nullptr);
     }
 
     /* Now, re-submit anything in the mux queue */
@@ -2841,7 +2838,7 @@
  ******************************************************************************/
 void btm_sec_init(uint8_t sec_mode) {
   btm_cb.security_mode = sec_mode;
-  memset(btm_cb.pairing_bda, 0xff, BD_ADDR_LEN);
+  btm_cb.pairing_bda = RawAddress::kAny;
   btm_cb.max_collision_delay = BTM_SEC_MAX_COLLISION_DELAY;
 }
 
@@ -2896,7 +2893,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_sec_abort_access_req(BD_ADDR bd_addr) {
+void btm_sec_abort_access_req(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
 
   if (!p_dev_rec) return;
@@ -2933,10 +2930,8 @@
   if (!p_lcb &&
       (p_lcb = l2cu_allocate_lcb(p_dev_rec->bd_addr, true,
                                  BT_TRANSPORT_BR_EDR)) == NULL) {
-    BTM_TRACE_WARNING(
-        "Security Manager: failed allocate LCB [%02x%02x%02x%02x%02x%02x]",
-        p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
-        p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
+    LOG(WARNING) << "Security Manager: failed allocate LCB "
+                 << p_dev_rec->bd_addr;
 
     return (BTM_NO_RESOURCES);
   }
@@ -2945,10 +2940,8 @@
   btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE;
 
   if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == false) {
-    BTM_TRACE_WARNING(
-        "Security Manager: failed create  [%02x%02x%02x%02x%02x%02x]",
-        p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
-        p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
+    LOG(WARNING) << "Security Manager: failed create allocate LCB "
+                 << p_dev_rec->bd_addr;
 
     l2cu_release_lcb(p_lcb);
     return (BTM_NO_RESOURCES);
@@ -2956,10 +2949,7 @@
 
   btm_acl_update_busy_level(BTM_BLI_PAGE_EVT);
 
-  BTM_TRACE_DEBUG(
-      "Security Manager: btm_sec_dd_create_conn [%02x%02x%02x%02x%02x%02x]",
-      p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
-      p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
+  VLOG(1) << "Security Manager: " << p_dev_rec->bd_addr;
 
   btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_PIN_REQ);
 
@@ -2978,43 +2968,43 @@
 /*******************************************************************************
  *
  * Function         btm_sec_rmt_name_request_complete
-*
+ *
  * Description      This function is called when remote name was obtained from
  *                  the peer device
  *
  * Returns          void
  *
  ******************************************************************************/
-void btm_sec_rmt_name_request_complete(uint8_t* p_bd_addr, uint8_t* p_bd_name,
-                                       uint8_t status) {
+void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr,
+                                       uint8_t* p_bd_name, uint8_t status) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   int i;
   DEV_CLASS dev_class;
   uint8_t old_sec_state;
 
   BTM_TRACE_EVENT("btm_sec_rmt_name_request_complete");
-  if (((p_bd_addr == NULL) && !BTM_ACL_IS_CONNECTED(btm_cb.connecting_bda)) ||
-      ((p_bd_addr != NULL) && !BTM_ACL_IS_CONNECTED(p_bd_addr))) {
+  if ((!p_bd_addr && !BTM_ACL_IS_CONNECTED(btm_cb.connecting_bda)) ||
+      (p_bd_addr && !BTM_ACL_IS_CONNECTED(*p_bd_addr))) {
     btm_acl_resubmit_page();
   }
 
   /* If remote name request failed, p_bd_addr is null and we need to search */
   /* based on state assuming that we are doing 1 at a time */
   if (p_bd_addr)
-    p_dev_rec = btm_find_dev(p_bd_addr);
+    p_dev_rec = btm_find_dev(*p_bd_addr);
   else {
     list_node_t* node =
         list_foreach(btm_cb.sec_dev_rec, is_state_getting_name, NULL);
     if (node != NULL) {
       p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(list_node(node));
-      p_bd_addr = p_dev_rec->bd_addr;
+      p_bd_addr = &p_dev_rec->bd_addr;
     } else {
       p_dev_rec = NULL;
     }
   }
 
   /* Commenting out trace due to obf/compilation problems.
-  */
+   */
   if (!p_bd_name) p_bd_name = (uint8_t*)"";
 
   if (p_dev_rec) {
@@ -3049,7 +3039,7 @@
     /* Notify all clients waiting for name to be resolved */
     for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
       if (btm_cb.p_rmt_name_callback[i] && p_bd_addr)
-        (*btm_cb.p_rmt_name_callback[i])(p_bd_addr, p_dev_rec->dev_class,
+        (*btm_cb.p_rmt_name_callback[i])(*p_bd_addr, p_dev_rec->dev_class,
                                          p_dev_rec->sec_bd_name);
     }
   } else {
@@ -3061,7 +3051,7 @@
      * clients can continue */
     for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) {
       if (btm_cb.p_rmt_name_callback[i] && p_bd_addr)
-        (*btm_cb.p_rmt_name_callback[i])(p_bd_addr, dev_class, (uint8_t*)"");
+        (*btm_cb.p_rmt_name_callback[i])(*p_bd_addr, dev_class, (uint8_t*)"");
     }
 
     return;
@@ -3070,7 +3060,7 @@
   /* If we were delaying asking UI for a PIN because name was not resolved, ask
    * now */
   if ((btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_LOCAL_PIN) && p_bd_addr &&
-      (memcmp(btm_cb.pairing_bda, p_bd_addr, BD_ADDR_LEN) == 0)) {
+      (btm_cb.pairing_bda == *p_bd_addr)) {
     BTM_TRACE_EVENT(
         "%s() delayed pin now being requested flags:0x%x, "
         "(p_pin_callback=0x%p)",
@@ -3095,7 +3085,7 @@
 
   /* Check if we were delaying bonding because name was not resolved */
   if (btm_cb.pairing_state == BTM_PAIR_STATE_GET_REM_NAME) {
-    if (p_bd_addr && memcmp(btm_cb.pairing_bda, p_bd_addr, BD_ADDR_LEN) == 0) {
+    if (p_bd_addr && btm_cb.pairing_bda == *p_bd_addr) {
       BTM_TRACE_EVENT("%s() continue bonding sm4: 0x%04x, status:0x%x",
                       __func__, p_dev_rec->sm4, status);
       if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_CANCEL_DD) {
@@ -3132,10 +3122,10 @@
                       BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4));
 
       /* BT 2.1 or carkit, bring up the connection to force the peer to request
-      *PIN.
-      ** Else prefetch (btm_sec_check_prefetch_pin will do the prefetching if
-      *needed)
-      */
+       *PIN.
+       ** Else prefetch (btm_sec_check_prefetch_pin will do the prefetching if
+       *needed)
+       */
       if ((p_dev_rec->sm4 != BTM_SM4_KNOWN) ||
           !btm_sec_check_prefetch_pin(p_dev_rec)) {
         /* if we rejected incoming connection request, we have to wait
@@ -3241,7 +3231,7 @@
  ******************************************************************************/
 void btm_sec_rmt_host_support_feat_evt(uint8_t* p) {
   tBTM_SEC_DEV_REC* p_dev_rec;
-  BD_ADDR bd_addr; /* peer address */
+  RawAddress bd_addr; /* peer address */
   BD_FEATURES features;
 
   STREAM_TO_BDADDR(bd_addr, p);
@@ -3273,14 +3263,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_io_capabilities_req(uint8_t* p) {
+void btm_io_capabilities_req(const RawAddress& p) {
   tBTM_SP_IO_REQ evt_data;
   uint8_t err_code = 0;
   tBTM_SEC_DEV_REC* p_dev_rec;
   bool is_orig = true;
   uint8_t callback_rc = BTM_SUCCESS;
 
-  STREAM_TO_BDADDR(evt_data.bd_addr, p);
+  evt_data.bd_addr = p;
 
   /* setup the default response according to compile options */
   /* assume that the local IO capability does not change
@@ -3292,11 +3282,11 @@
   BTM_TRACE_EVENT("%s: State: %s", __func__,
                   btm_pair_state_descr(btm_cb.pairing_state));
 
-  if (btm_sec_is_a_bonded_dev(evt_data.bd_addr)) {
+  if (btm_sec_is_a_bonded_dev(p)) {
     BTM_TRACE_WARNING(
-        "%s: Incoming bond request, but device is already bonded (removing)",
-        __func__);
-    bta_dm_process_remove_device(evt_data.bd_addr);
+        "%s: Incoming bond request, but %s is already bonded (removing)",
+        __func__, p.ToString().c_str());
+    bta_dm_process_remove_device(p);
   }
 
   p_dev_rec = btm_find_or_alloc_dev(evt_data.bd_addr);
@@ -3345,7 +3335,7 @@
     /* initiator, at this point it is expected to be dedicated bonding
     initiated by local device */
     case BTM_PAIR_STATE_WAIT_PIN_REQ:
-      if (!memcmp(evt_data.bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN)) {
+      if (evt_data.bd_addr == btm_cb.pairing_bda) {
         evt_data.auth_req = BTM_DEFAULT_DD_AUTH_REQ;
       } else {
         err_code = HCI_ERR_HOST_BUSY_PAIRING;
@@ -3406,9 +3396,9 @@
   /* Notify L2CAP to increase timeout */
   l2c_pin_code_request(evt_data.bd_addr);
 
-  memcpy(btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN);
+  btm_cb.pairing_bda = evt_data.bd_addr;
 
-  if (!memcmp(evt_data.bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
+  if (evt_data.bd_addr == btm_cb.connecting_bda)
     memcpy(p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
 
   btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS);
@@ -3481,7 +3471,7 @@
 
   /* If no security is in progress, this indicates incoming security */
   if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE) {
-    memcpy(btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN);
+    btm_cb.pairing_bda = evt_data.bd_addr;
 
     btm_sec_change_pairing_state(BTM_PAIR_STATE_INCOMING_SSP);
 
@@ -3497,7 +3487,7 @@
 
   /* We must have a device record here.
    * Use the connecting device's CoD for the connection */
-  if (!memcmp(evt_data.bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
+  if (evt_data.bd_addr == btm_cb.connecting_bda)
     memcpy(p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
 
   /* peer sets dedicated bonding bit and we did not initiate dedicated bonding
@@ -3534,22 +3524,19 @@
 void btm_proc_sp_req_evt(tBTM_SP_EVT event, uint8_t* p) {
   tBTM_STATUS status = BTM_ERR_PROCESSING;
   tBTM_SP_EVT_DATA evt_data;
-  uint8_t* p_bda = evt_data.cfm_req.bd_addr;
+  RawAddress& p_bda = evt_data.cfm_req.bd_addr;
   tBTM_SEC_DEV_REC* p_dev_rec;
 
   /* All events start with bd_addr */
   STREAM_TO_BDADDR(p_bda, p);
 
-  BTM_TRACE_EVENT(
-      "btm_proc_sp_req_evt() BDA: %08x%04x event: 0x%x, State: %s",
-      (p_bda[0] << 24) + (p_bda[1] << 16) + (p_bda[2] << 8) + p_bda[3],
-      (p_bda[4] << 8) + p_bda[5], event,
-      btm_pair_state_descr(btm_cb.pairing_state));
+  VLOG(2) << " BDA: " << p_bda << " event: 0x" << std::hex << +event
+          << " State: " << btm_pair_state_descr(btm_cb.pairing_state);
 
   p_dev_rec = btm_find_dev(p_bda);
   if ((p_dev_rec != NULL) && (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
-      (memcmp(btm_cb.pairing_bda, p_bda, BD_ADDR_LEN) == 0)) {
-    memcpy(evt_data.cfm_req.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
+      (btm_cb.pairing_bda == p_bda)) {
+    evt_data.cfm_req.bd_addr = p_dev_rec->bd_addr;
     memcpy(evt_data.cfm_req.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
 
     strlcpy((char*)evt_data.cfm_req.bd_name, (char*)p_dev_rec->sec_bd_name,
@@ -3618,7 +3605,7 @@
     }
 
     if (btm_cb.api.p_sp_callback) {
-      status = (*btm_cb.api.p_sp_callback)(event, (tBTM_SP_EVT_DATA*)&evt_data);
+      status = (*btm_cb.api.p_sp_callback)(event, &evt_data);
       if (status != BTM_NOT_AUTHORIZED) {
         return;
       }
@@ -3679,11 +3666,10 @@
  ******************************************************************************/
 void btm_keypress_notif_evt(uint8_t* p) {
   tBTM_SP_KEYPRESS evt_data;
-  uint8_t* p_bda;
 
   /* parse & report BTM_SP_KEYPRESS_EVT */
   if (btm_cb.api.p_sp_callback) {
-    p_bda = evt_data.bd_addr;
+    RawAddress& p_bda = evt_data.bd_addr;
 
     STREAM_TO_BDADDR(p_bda, p);
     evt_data.notif_type = *p;
@@ -3714,10 +3700,7 @@
 
   p_dev_rec = btm_find_dev(evt_data.bd_addr);
   if (p_dev_rec == NULL) {
-    BTM_TRACE_ERROR("btm_simple_pair_complete() with unknown BDA: %08x%04x",
-                    (evt_data.bd_addr[0] << 24) + (evt_data.bd_addr[1] << 16) +
-                        (evt_data.bd_addr[2] << 8) + evt_data.bd_addr[3],
-                    (evt_data.bd_addr[4] << 8) + evt_data.bd_addr[5]);
+    LOG(ERROR) << __func__ << " with unknown BDA: " << evt_data.bd_addr;
     return;
   }
 
@@ -3735,10 +3718,9 @@
       btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_DISCONNECT);
 
       /* Change the timer to 1 second */
-      alarm_set_on_queue(btm_cb.pairing_timer, BT_1SEC_TIMEOUT_MS,
-                         btm_sec_pairing_timeout, NULL,
-                         btu_general_alarm_queue);
-    } else if (memcmp(btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN) == 0) {
+      alarm_set_on_mloop(btm_cb.pairing_timer, BT_1SEC_TIMEOUT_MS,
+                         btm_sec_pairing_timeout, NULL);
+    } else if (btm_cb.pairing_bda == evt_data.bd_addr) {
       /* stop the timer */
       alarm_cancel(btm_cb.pairing_timer);
 
@@ -3753,7 +3735,7 @@
 
   /* Let the pairing state stay active, p_auth_complete_callback will report the
    * failure */
-  memcpy(evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
+  evt_data.bd_addr = p_dev_rec->bd_addr;
   memcpy(evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
 
   if (btm_cb.api.p_sp_callback)
@@ -3782,21 +3764,19 @@
  *
  ******************************************************************************/
 void btm_rem_oob_req(uint8_t* p) {
-  uint8_t* p_bda;
   tBTM_SP_RMT_OOB evt_data;
   tBTM_SEC_DEV_REC* p_dev_rec;
   BT_OCTET16 c;
   BT_OCTET16 r;
 
-  p_bda = evt_data.bd_addr;
+  RawAddress& p_bda = evt_data.bd_addr;
 
   STREAM_TO_BDADDR(p_bda, p);
 
-  BTM_TRACE_EVENT("btm_rem_oob_req() BDA: %02x:%02x:%02x:%02x:%02x:%02x",
-                  p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
+  VLOG(2) << __func__ << " BDA: " << p_bda;
   p_dev_rec = btm_find_dev(p_bda);
   if ((p_dev_rec != NULL) && btm_cb.api.p_sp_callback) {
-    memcpy(evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
+    evt_data.bd_addr = p_dev_rec->bd_addr;
     memcpy(evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
     strlcpy((char*)evt_data.bd_name, (char*)p_dev_rec->sec_bd_name,
             BTM_MAX_REM_BD_NAME_LEN);
@@ -3837,9 +3817,11 @@
   } else
     evt_data.status = BTM_ERR_PROCESSING;
 
-  if (btm_cb.api.p_sp_callback)
-    (*btm_cb.api.p_sp_callback)(BTM_SP_LOC_OOB_EVT,
-                                (tBTM_SP_EVT_DATA*)&evt_data);
+  if (btm_cb.api.p_sp_callback) {
+    tBTM_SP_EVT_DATA btm_sp_evt_data;
+    btm_sp_evt_data.loc_oob = evt_data;
+    (*btm_cb.api.p_sp_callback)(BTM_SP_LOC_OOB_EVT, &btm_sp_evt_data);
+  }
 }
 
 /*******************************************************************************
@@ -3877,9 +3859,8 @@
         p_dev_rec->sec_state = 0;
 
       btm_cb.p_collided_dev_rec = p_dev_rec;
-      alarm_set_on_queue(btm_cb.sec_collision_timer, BT_1SEC_TIMEOUT_MS,
-                         btm_sec_collision_timeout, NULL,
-                         btu_general_alarm_queue);
+      alarm_set_on_mloop(btm_cb.sec_collision_timer, BT_1SEC_TIMEOUT_MS,
+                         btm_sec_collision_timeout, NULL);
     }
   }
 }
@@ -3944,18 +3925,16 @@
   bool are_bonding = false;
 
   if (p_dev_rec) {
-    BTM_TRACE_EVENT(
-        "Security Manager: auth_complete PairState: %s  handle:%u  status:%d  "
-        "dev->sec_state: %u  Bda:%08x, RName:%s",
-        btm_pair_state_descr(btm_cb.pairing_state), handle, status,
-        p_dev_rec->sec_state,
-        (p_dev_rec->bd_addr[2] << 24) + (p_dev_rec->bd_addr[3] << 16) +
-            (p_dev_rec->bd_addr[4] << 8) + p_dev_rec->bd_addr[5],
-        p_dev_rec->sec_bd_name);
+    VLOG(2) << __func__ << "Security Manager: in state: "
+            << btm_pair_state_descr(btm_cb.pairing_state)
+            << " handle:" << handle << " status:" << status
+            << "dev->sec_state:" << p_dev_rec->sec_state
+            << " bda:" << p_dev_rec->bd_addr
+            << "RName:" << p_dev_rec->sec_bd_name;
   } else {
-    BTM_TRACE_EVENT(
-        "Security Manager: auth_complete PairState: %s  handle:%u  status:%d",
-        btm_pair_state_descr(btm_cb.pairing_state), handle, status);
+    VLOG(2) << __func__ << "Security Manager: in state: "
+            << btm_pair_state_descr(btm_cb.pairing_state)
+            << " handle:" << handle << " status:" << status;
   }
 
   /* For transaction collision we need to wait and repeat.  There is no need */
@@ -3986,11 +3965,11 @@
 
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
       (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) &&
-      (memcmp(p_dev_rec->bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) == 0))
+      (p_dev_rec->bd_addr == btm_cb.pairing_bda))
     are_bonding = true;
 
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
-      (memcmp(p_dev_rec->bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) == 0))
+      (p_dev_rec->bd_addr == btm_cb.pairing_bda))
     btm_sec_change_pairing_state(BTM_PAIR_STATE_IDLE);
 
   if (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHENTICATING) {
@@ -4221,7 +4200,7 @@
     if (BTM_SEC_STATE_DELAY_FOR_ENC == p_dev_rec->sec_state) {
       p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
       p_dev_rec->p_callback = NULL;
-      l2cu_resubmit_pending_sec_req(p_dev_rec->bd_addr);
+      l2cu_resubmit_pending_sec_req(&p_dev_rec->bd_addr);
     }
     return;
   }
@@ -4280,7 +4259,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void btm_sec_connected(uint8_t* bda, uint16_t handle, uint8_t status,
+void btm_sec_connected(const RawAddress& bda, uint16_t handle, uint8_t status,
                        uint8_t enc_mode) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda);
   uint8_t res;
@@ -4291,18 +4270,16 @@
   btm_acl_resubmit_page();
 
   if (p_dev_rec) {
-    BTM_TRACE_EVENT(
-        "Security Manager: btm_sec_connected in state: %s  handle:%d status:%d "
-        "enc_mode:%d  bda:%x RName:%s",
-        btm_pair_state_descr(btm_cb.pairing_state), handle, status, enc_mode,
-        (bda[2] << 24) + (bda[3] << 16) + (bda[4] << 8) + bda[5],
-        p_dev_rec->sec_bd_name);
+    VLOG(2) << __func__ << "Security Manager: in state: "
+            << btm_pair_state_descr(btm_cb.pairing_state)
+            << " handle:" << handle << " status:" << status
+            << "enc_mode:" << enc_mode << " bda:" << bda
+            << "RName:" << p_dev_rec->sec_bd_name;
   } else {
-    BTM_TRACE_EVENT(
-        "Security Manager: btm_sec_connected in state: %s  handle:%d status:%d "
-        "enc_mode:%d  bda:%x ",
-        btm_pair_state_descr(btm_cb.pairing_state), handle, status, enc_mode,
-        (bda[2] << 24) + (bda[3] << 16) + (bda[4] << 8) + bda[5]);
+    VLOG(2) << __func__ << "Security Manager: in state: "
+            << btm_pair_state_descr(btm_cb.pairing_state)
+            << " handle:" << handle << " status:" << status
+            << "enc_mode:" << enc_mode << " bda:" << bda;
   }
 
   if (!p_dev_rec) {
@@ -4313,7 +4290,7 @@
       /* If the device matches with stored paring address
        * reset the paring state to idle */
       if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
-          (memcmp(btm_cb.pairing_bda, bda, BD_ADDR_LEN) == 0)) {
+          btm_cb.pairing_bda == bda) {
         btm_sec_change_pairing_state(BTM_PAIR_STATE_IDLE);
       }
 
@@ -4328,7 +4305,7 @@
     if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND) {
       /* tell L2CAP it's a bonding connection. */
       if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
-          (memcmp(btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0) &&
+          (btm_cb.pairing_bda == p_dev_rec->bd_addr) &&
           (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)) {
         /* if incoming connection failed while pairing, then try to connect and
          * continue */
@@ -4344,9 +4321,8 @@
             /* Start timer with 0 to initiate connection with new LCB */
             /* because L2CAP will delete current LCB with this event  */
             btm_cb.p_collided_dev_rec = p_dev_rec;
-            alarm_set_on_queue(btm_cb.sec_collision_timer, 0,
-                               btm_sec_connect_after_reject_timeout, NULL,
-                               btu_general_alarm_queue);
+            alarm_set_on_mloop(btm_cb.sec_collision_timer, 0,
+                               btm_sec_connect_after_reject_timeout, NULL);
           } else {
             btm_sec_change_pairing_state(BTM_PAIR_STATE_GET_REM_NAME);
             if (BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL,
@@ -4378,7 +4354,7 @@
   p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
 
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
-      (memcmp(btm_cb.pairing_bda, bda, BD_ADDR_LEN) == 0)) {
+      (btm_cb.pairing_bda == bda)) {
     /* if we rejected incoming connection from bonding device */
     if ((status == HCI_ERR_HOST_REJECT_DEVICE) &&
         (btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT)) {
@@ -4404,9 +4380,8 @@
         /* Start timer with 0 to initiate connection with new LCB */
         /* because L2CAP will delete current LCB with this event  */
         btm_cb.p_collided_dev_rec = p_dev_rec;
-        alarm_set_on_queue(btm_cb.sec_collision_timer, 0,
-                           btm_sec_connect_after_reject_timeout, NULL,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(btm_cb.sec_collision_timer, 0,
+                           btm_sec_connect_after_reject_timeout, NULL);
       }
 
       return;
@@ -4596,7 +4571,7 @@
   /* If we are in the process of bonding we need to tell client that auth failed
    */
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
-      (memcmp(btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0) &&
+      (btm_cb.pairing_bda == p_dev_rec->bd_addr) &&
       (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)) {
     /* we are currently doing bonding.  Link will be disconnected when done */
     btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE;
@@ -4644,14 +4619,11 @@
   /* clear unused flags */
   p_dev_rec->sm4 &= BTM_SM4_TRUE;
 
-  uint8_t* bd_addr = (uint8_t*)p_dev_rec->bd_addr;
-  BTM_TRACE_EVENT(
-      "%s sec_req:x%x state:%s reason:%d bd_addr:%02x:%02x:%02x:%02x:%02x:%02x"
-      "  remote_name:%s",
-      __func__, p_dev_rec->security_required,
-      btm_pair_state_descr(btm_cb.pairing_state), reason, bd_addr[0],
-      bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5],
-      p_dev_rec->sec_bd_name);
+  VLOG(2) << __func__ << " bd_addr: " << p_dev_rec->bd_addr
+          << " name: " << p_dev_rec->sec_bd_name
+          << " state: " << btm_pair_state_descr(btm_cb.pairing_state)
+          << " reason: " << reason << " sec_req: " << std::hex
+          << p_dev_rec->security_required;
 
   BTM_TRACE_EVENT("%s before update sec_flags=0x%x", __func__,
                   p_dev_rec->sec_flags);
@@ -4659,7 +4631,7 @@
   /* If we are in the process of bonding we need to tell client that auth failed
    */
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
-      (memcmp(btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)) {
+      (btm_cb.pairing_bda == p_dev_rec->bd_addr)) {
     btm_sec_change_pairing_state(BTM_PAIR_STATE_IDLE);
     p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
     if (btm_cb.api.p_auth_complete_callback) {
@@ -4678,7 +4650,7 @@
     }
   }
 
-  btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, p_dev_rec->bd_addr,
+  btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, &p_dev_rec->bd_addr,
                                 HCI_SUCCESS);
   /* see sec_flags processing in btm_acl_removed */
 
@@ -4691,6 +4663,26 @@
     p_dev_rec->sec_flags &=
         ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED |
           BTM_SEC_ROLE_SWITCHED | BTM_SEC_16_DIGIT_PIN_AUTHED);
+
+    // Remove temporary key.
+    if (p_dev_rec->bond_type == BOND_TYPE_TEMPORARY)
+      p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN);
+  }
+
+  BTM_TRACE_EVENT("%s after update sec_flags=0x%x", __func__,
+                  p_dev_rec->sec_flags);
+
+  /* Some devices hardcode sample LTK value from spec, instead of generating
+   * one. Treat such devices as insecure, and remove such bonds on
+   * disconnection.
+   */
+  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";
+
+    tBTA_DM_MSG p_data;
+    p_data.remove_dev.bd_addr = p_dev_rec->bd_addr;
+    bta_dm_remove_device(&p_data);
   }
 
   if (p_dev_rec->sec_state == BTM_SEC_STATE_DISCONNECTING_BOTH) {
@@ -4709,12 +4701,9 @@
     p_dev_rec->p_callback =
         NULL; /* when the peer device time out the authentication before
                  we do, this call back must be reset here */
-    (*p_callback)(p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data,
+    (*p_callback)(&p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data,
                   BTM_ERR_PROCESSING);
   }
-
-  BTM_TRACE_EVENT("%s after update sec_flags=0x%x", __func__,
-                  p_dev_rec->sec_flags);
 }
 
 /*******************************************************************************
@@ -4727,17 +4716,13 @@
  * Returns          Pointer to the record or NULL
  *
  ******************************************************************************/
-void btm_sec_link_key_notification(uint8_t* p_bda, uint8_t* p_link_key,
+void btm_sec_link_key_notification(const RawAddress& p_bda, uint8_t* p_link_key,
                                    uint8_t key_type) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(p_bda);
   bool we_are_bonding = false;
   bool ltk_derived_lk = false;
 
-  BTM_TRACE_EVENT(
-      "btm_sec_link_key_notification()  BDA:%04x%08x, TYPE: %d",
-      (p_bda[0] << 8) + p_bda[1],
-      (p_bda[2] << 24) + (p_bda[3] << 16) + (p_bda[4] << 8) + p_bda[5],
-      key_type);
+  VLOG(2) << __func__ << " BDA: " << p_bda << ", TYPE: " << +key_type;
 
   if ((key_type >= BTM_LTK_DERIVED_LKEY_OFFSET + BTM_LKEY_TYPE_COMBINATION) &&
       (key_type <=
@@ -4768,7 +4753,7 @@
   memcpy(p_dev_rec->link_key, p_link_key, LINK_KEY_LEN);
 
   if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) &&
-      (memcmp(btm_cb.pairing_bda, p_bda, BD_ADDR_LEN) == 0)) {
+      (btm_cb.pairing_bda == p_bda)) {
     if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
       we_are_bonding = true;
     else
@@ -4801,10 +4786,7 @@
        ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) !=
         BTM_COD_MAJOR_PERIPHERAL)) &&
       !ltk_derived_lk) {
-    BTM_TRACE_EVENT(
-        "btm_sec_link_key_notification()  Delayed BDA: %08x%04x Type:%d",
-        (p_bda[0] << 24) + (p_bda[1] << 16) + (p_bda[2] << 8) + p_bda[3],
-        (p_bda[4] << 8) + p_bda[5], key_type);
+    VLOG(2) << __func__ << " Delayed BDA: " << p_bda << " Type:" << +key_type;
 
     p_dev_rec->link_key_not_sent = true;
 
@@ -4864,33 +4846,31 @@
  * Returns          Pointer to the record or NULL
  *
  ******************************************************************************/
-void btm_sec_link_key_request(uint8_t* p_bda) {
-  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(p_bda);
+void btm_sec_link_key_request(const RawAddress& bda) {
+  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda);
 
-  BTM_TRACE_EVENT(
-      "btm_sec_link_key_request()  BDA: %02x:%02x:%02x:%02x:%02x:%02x",
-      p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
+  VLOG(2) << __func__ << " bda: " << bda;
 
   if ((btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ) &&
       (btm_cb.collision_start_time != 0) &&
-      (memcmp(btm_cb.p_collided_dev_rec->bd_addr, p_bda, BD_ADDR_LEN) == 0)) {
+      (btm_cb.p_collided_dev_rec->bd_addr == bda)) {
     BTM_TRACE_EVENT(
         "btm_sec_link_key_request() rejecting link key req "
         "State: %d START_TIMEOUT : %d",
         btm_cb.pairing_state, btm_cb.collision_start_time);
-    btsnd_hcic_link_key_neg_reply(p_bda);
+    btsnd_hcic_link_key_neg_reply(bda);
     return;
   }
   if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) {
-    btsnd_hcic_link_key_req_reply(p_bda, p_dev_rec->link_key);
+    btsnd_hcic_link_key_req_reply(bda, p_dev_rec->link_key);
     return;
   }
 
   /* Notify L2CAP to increase timeout */
-  l2c_pin_code_request(p_bda);
+  l2c_pin_code_request(bda);
 
   /* The link key is not in the database and it is not known to the manager */
-  btsnd_hcic_link_key_neg_reply(p_bda);
+  btsnd_hcic_link_key_neg_reply(bda);
 }
 
 /*******************************************************************************
@@ -4972,11 +4952,9 @@
        * complete.
        * now it's time to tear down the ACL link*/
       if (p_dev_rec == NULL) {
-        BTM_TRACE_ERROR(
-            "%s BTM_PAIR_STATE_WAIT_DISCONNECT unknown BDA: %08x%04x", __func__,
-            (p_cb->pairing_bda[0] << 24) + (p_cb->pairing_bda[1] << 16) +
-                (p_cb->pairing_bda[2] << 8) + p_cb->pairing_bda[3],
-            (p_cb->pairing_bda[4] << 8) + p_cb->pairing_bda[5]);
+        LOG(ERROR) << __func__
+                   << " BTM_PAIR_STATE_WAIT_DISCONNECT unknown BDA: "
+                   << p_cb->pairing_bda;
         break;
       }
       btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_AUTH_FAILURE,
@@ -5018,22 +4996,20 @@
  * Returns          Pointer to the record or NULL
  *
  ******************************************************************************/
-void btm_sec_pin_code_request(uint8_t* p_bda) {
+void btm_sec_pin_code_request(const RawAddress& p_bda) {
   tBTM_SEC_DEV_REC* p_dev_rec;
   tBTM_CB* p_cb = &btm_cb;
 
-  BTM_TRACE_EVENT(
-      "btm_sec_pin_code_request()  State: %s, BDA:%04x%08x",
-      btm_pair_state_descr(btm_cb.pairing_state), (p_bda[0] << 8) + p_bda[1],
-      (p_bda[2] << 24) + (p_bda[3] << 16) + (p_bda[4] << 8) + p_bda[5]);
+  VLOG(2) << __func__ << " BDA: " << p_bda
+          << " state: " << btm_pair_state_descr(btm_cb.pairing_state);
 
   if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) {
-    if ((memcmp(p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) == 0) &&
+    if ((p_bda == btm_cb.pairing_bda) &&
         (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_AUTH_COMPLETE)) {
       btsnd_hcic_pin_code_neg_reply(p_bda);
       return;
     } else if ((btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_PIN_REQ) ||
-               memcmp(p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) != 0) {
+               p_bda != btm_cb.pairing_bda) {
       BTM_TRACE_WARNING("btm_sec_pin_code_request() rejected - state: %s",
                         btm_pair_state_descr(btm_cb.pairing_state));
       btsnd_hcic_pin_code_neg_reply(p_bda);
@@ -5046,7 +5022,7 @@
   p_dev_rec->sm4 = BTM_SM4_KNOWN;
 
   if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE) {
-    memcpy(btm_cb.pairing_bda, p_bda, BD_ADDR_LEN);
+    btm_cb.pairing_bda = p_bda;
 
     btm_cb.pairing_flags = BTM_PAIR_FLAGS_PEER_STARTED_DD;
     /* Make sure we reset the trusted mask to help against attacks */
@@ -5062,7 +5038,7 @@
   }
 
   /* Use the connecting device's CoD for the connection */
-  if ((!memcmp(p_bda, p_cb->connecting_bda, BD_ADDR_LEN)) &&
+  if ((p_bda == p_cb->connecting_bda) &&
       (p_cb->connecting_dc[0] || p_cb->connecting_dc[1] ||
        p_cb->connecting_dc[2]))
     memcpy(p_dev_rec->dev_class, p_cb->connecting_dc, DEV_CLASS_LEN);
@@ -5089,7 +5065,7 @@
       p_cb->pairing_disabled || (p_cb->api.p_pin_callback == NULL)
 
       /* OR Microsoft keyboard can for some reason try to establish connection
-         */
+       */
       /*  the only thing we can do here is to shut it up.  Normally we will be
          originator */
       /*  for keyboard bonding */
@@ -5108,7 +5084,7 @@
   else {
     btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_LOCAL_PIN);
     /* Pin code request can not come at the same time as connection request */
-    memcpy(p_cb->connecting_bda, p_bda, BD_ADDR_LEN);
+    p_cb->connecting_bda = p_bda;
     memcpy(p_cb->connecting_dc, p_dev_rec->dev_class, DEV_CLASS_LEN);
 
     /* Check if the name is known */
@@ -5605,7 +5581,7 @@
  *                  otherwise, the trusted mask
  *
  ******************************************************************************/
-uint32_t* BTM_ReadTrustedMask(BD_ADDR bd_addr) {
+uint32_t* BTM_ReadTrustedMask(const RawAddress& bd_addr) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
   if (p_dev_rec != NULL) return (p_dev_rec->trusted_mask);
   return NULL;
@@ -5693,14 +5669,14 @@
     btm_sec_check_pending_reqs();
     btm_inq_clear_ssp();
 
-    memset(btm_cb.pairing_bda, 0xFF, BD_ADDR_LEN);
+    btm_cb.pairing_bda = RawAddress::kAny;
   } else {
     /* If transitioning out of idle, mark the lcb as bonding */
     if (old_state == BTM_PAIR_STATE_IDLE)
       l2cu_update_lcb_4_bonding(btm_cb.pairing_bda, true);
 
-    alarm_set_on_queue(btm_cb.pairing_timer, BTM_SEC_TIMEOUT_VALUE * 1000,
-                       btm_sec_pairing_timeout, NULL, btu_general_alarm_queue);
+    alarm_set_on_mloop(btm_cb.pairing_timer, BTM_SEC_TIMEOUT_VALUE * 1000,
+                       btm_sec_pairing_timeout, NULL);
   }
 }
 
@@ -5758,10 +5734,10 @@
     p_dev_rec->p_callback = NULL;
 
     if (is_le_transport)
-      (*p_callback)(p_dev_rec->ble.pseudo_addr, BT_TRANSPORT_LE,
+      (*p_callback)(&p_dev_rec->ble.pseudo_addr, BT_TRANSPORT_LE,
                     p_dev_rec->p_ref_data, res);
     else
-      (*p_callback)(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR,
+      (*p_callback)(&p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR,
                     p_dev_rec->p_ref_data, res);
   }
 
@@ -5775,7 +5751,7 @@
  * Description      Return state description for tracing
  *
  ******************************************************************************/
-static bool btm_sec_queue_mx_request(BD_ADDR bd_addr, uint16_t psm,
+static bool btm_sec_queue_mx_request(const RawAddress& bd_addr, uint16_t psm,
                                      bool is_orig, uint32_t mx_proto_id,
                                      uint32_t mx_chan_id,
                                      tBTM_SEC_CALLBACK* p_callback,
@@ -5791,8 +5767,7 @@
   p_e->mx_chan_id = mx_chan_id;
   p_e->transport = BT_TRANSPORT_BR_EDR;
   p_e->sec_act = 0;
-
-  memcpy(p_e->bd_addr, bd_addr, BD_ADDR_LEN);
+  p_e->bd_addr = bd_addr;
 
   BTM_TRACE_EVENT(
       "%s() PSM: 0x%04x  Is_Orig: %u  mx_proto_id: %u  mx_chan_id: %u",
@@ -5882,7 +5857,7 @@
  *                  process pending.
  *
  ******************************************************************************/
-static bool btm_sec_queue_encrypt_request(BD_ADDR bd_addr,
+static bool btm_sec_queue_encrypt_request(const RawAddress& bd_addr,
                                           tBT_TRANSPORT transport,
                                           tBTM_SEC_CALLBACK* p_callback,
                                           void* p_ref_data,
@@ -5895,7 +5870,7 @@
   p_e->p_ref_data = p_ref_data;
   p_e->transport = transport;
   p_e->sec_act = sec_act;
-  memcpy(p_e->bd_addr, bd_addr, BD_ADDR_LEN);
+  p_e->bd_addr = bd_addr;
   fixed_queue_enqueue(btm_cb.sec_pending_q, p_e);
 
   return true;
@@ -5913,9 +5888,6 @@
  ******************************************************************************/
 void btm_sec_set_peer_sec_caps(tACL_CONN* p_acl_cb,
                                tBTM_SEC_DEV_REC* p_dev_rec) {
-  BD_ADDR rem_bd_addr;
-  uint8_t* p_rem_bd_addr;
-
   if ((btm_cb.security_mode == BTM_SEC_MODE_SP ||
        btm_cb.security_mode == BTM_SEC_MODE_SP_DEBUG ||
        btm_cb.security_mode == BTM_SEC_MODE_SC) &&
@@ -5936,10 +5908,7 @@
     BTM_TRACE_EVENT(
         "%s: Now device in SC Only mode, waiting for peer remote features!",
         __func__);
-    p_rem_bd_addr = (uint8_t*)rem_bd_addr;
-    BDADDR_TO_STREAM(p_rem_bd_addr, p_dev_rec->bd_addr);
-    p_rem_bd_addr = (uint8_t*)rem_bd_addr;
-    btm_io_capabilities_req(p_rem_bd_addr);
+    btm_io_capabilities_req(p_dev_rec->bd_addr);
     p_dev_rec->remote_features_needed = false;
   }
 }
@@ -5983,15 +5952,15 @@
     tBTM_SEC_QUEUE_ENTRY* p_e = (tBTM_SEC_QUEUE_ENTRY*)list_node(node);
     node = list_next(node);
 
-    if (memcmp(p_e->bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0 &&
-        p_e->psm == 0 && p_e->transport == transport) {
+    if (p_e->bd_addr == p_dev_rec->bd_addr && p_e->psm == 0 &&
+        p_e->transport == transport) {
       if (encr_enable == 0 || transport == BT_TRANSPORT_BR_EDR ||
           p_e->sec_act == BTM_BLE_SEC_ENCRYPT ||
           p_e->sec_act == BTM_BLE_SEC_ENCRYPT_NO_MITM ||
           (p_e->sec_act == BTM_BLE_SEC_ENCRYPT_MITM &&
            p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED)) {
         if (p_e->p_callback)
-          (*p_e->p_callback)(p_dev_rec->bd_addr, transport, p_e->p_ref_data,
+          (*p_e->p_callback)(&p_dev_rec->bd_addr, transport, p_e->p_ref_data,
                              res);
         fixed_queue_try_remove_from_queue(btm_cb.sec_pending_q, (void*)p_e);
       }
@@ -6048,7 +6017,7 @@
  * Returns          true - dev is bonded
  *
  ******************************************************************************/
-bool btm_sec_is_a_bonded_dev(BD_ADDR bda) {
+bool btm_sec_is_a_bonded_dev(const RawAddress& bda) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda);
   bool is_bonded = false;
 
@@ -6070,7 +6039,7 @@
  * Returns          true - dev is a dual mode
  *
  ******************************************************************************/
-bool btm_sec_is_le_capable_dev(BD_ADDR bda) {
+bool btm_sec_is_le_capable_dev(const RawAddress& bda) {
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda);
   bool le_capable = false;
 
diff --git a/stack/btu/btu_hcif.cc b/stack/btu/btu_hcif.cc
index 1456228..15227cb 100644
--- a/stack/btu/btu_hcif.cc
+++ b/stack/btu/btu_hcif.cc
@@ -32,6 +32,7 @@
 #include <base/location.h>
 #include <base/logging.h>
 #include <base/threading/thread.h>
+#include <log/log.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -344,7 +345,7 @@
           btu_ble_data_length_change_evt(p, hci_evt_len);
           break;
 
-        case HCI_LE_PHY_UPDATE_COMPLETE_EVT:
+        case HCI_BLE_PHY_UPDATE_COMPLETE_EVT:
           btm_ble_process_phy_update_pkt(ble_evt_len, p);
           break;
 
@@ -574,7 +575,7 @@
 static void btu_hcif_connection_comp_evt(uint8_t* p) {
   uint8_t status;
   uint16_t handle;
-  BD_ADDR bda;
+  RawAddress bda;
   uint8_t link_type;
   uint8_t enc_mode;
 #if (BTM_SCO_INCLUDED == TRUE)
@@ -598,8 +599,8 @@
   else {
     memset(&esco_data, 0, sizeof(tBTM_ESCO_DATA));
     /* esco_data.link_type = HCI_LINK_TYPE_SCO; already zero */
-    memcpy(esco_data.bd_addr, bda, BD_ADDR_LEN);
-    btm_sco_connected(status, bda, handle, &esco_data);
+    esco_data.bd_addr = bda;
+    btm_sco_connected(status, &bda, handle, &esco_data);
   }
 #endif /* BTM_SCO_INCLUDED */
 }
@@ -614,7 +615,7 @@
  *
  ******************************************************************************/
 static void btu_hcif_connection_request_evt(uint8_t* p) {
-  BD_ADDR bda;
+  RawAddress bda;
   DEV_CLASS dc;
   uint8_t link_type;
 
@@ -694,18 +695,52 @@
  ******************************************************************************/
 static void btu_hcif_rmt_name_request_comp_evt(uint8_t* p, uint16_t evt_len) {
   uint8_t status;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
 
   STREAM_TO_UINT8(status, p);
   STREAM_TO_BDADDR(bd_addr, p);
 
   evt_len -= (1 + BD_ADDR_LEN);
 
-  btm_process_remote_name(bd_addr, p, evt_len, status);
+  btm_process_remote_name(&bd_addr, p, evt_len, status);
 
-  btm_sec_rmt_name_request_complete(bd_addr, p, status);
+  btm_sec_rmt_name_request_complete(&bd_addr, p, status);
 }
 
+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) {
+  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. */
+    HCI_TRACE_WARNING("%s encryption stopped on link: 0x%02x", __func__,
+                      handle);
+    return;
+  }
+
+  if (status != HCI_SUCCESS) {
+    HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status);
+    btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
+    return;
+  }
+
+  if (key_size < MIN_KEY_SIZE) {
+    android_errorWriteLog(0x534e4554, "124301137");
+    HCI_TRACE_ERROR(
+        "%s encryption key too short, disconnecting. handle: 0x%02x, key_size: "
+        "%d",
+        __func__, handle, key_size);
+
+    btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
+    return;
+  }
+
+  // good key size - succeed
+  btm_acl_encrypt_change(handle, status, 1 /* enable */);
+  btm_sec_encrypt_change(handle, status, 1 /* enable */);
+}
 /*******************************************************************************
  *
  * Function         btu_hcif_encryption_change_evt
@@ -724,8 +759,15 @@
   STREAM_TO_UINT16(handle, p);
   STREAM_TO_UINT8(encr_enable, p);
 
-  btm_acl_encrypt_change(handle, status, encr_enable);
-  btm_sec_encrypt_change(handle, status, encr_enable);
+  if (status != HCI_SUCCESS || encr_enable == 0 ||
+      BTM_IsBleConnection(handle)) {
+    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));
+  }
 }
 
 /*******************************************************************************
@@ -818,7 +860,7 @@
 #if (BTM_SCO_INCLUDED == TRUE)
   tBTM_ESCO_DATA data;
   uint16_t handle;
-  BD_ADDR bda;
+  RawAddress bda;
   uint8_t status;
 
   STREAM_TO_UINT8(status, p);
@@ -832,8 +874,8 @@
   STREAM_TO_UINT16(data.tx_pkt_len, p);
   STREAM_TO_UINT8(data.air_mode, p);
 
-  memcpy(data.bd_addr, bda, BD_ADDR_LEN);
-  btm_sco_connected(status, bda, handle, &data);
+  data.bd_addr = bda;
+  btm_sco_connected(status, &bda, handle, &data);
 #endif
 }
 
@@ -905,6 +947,14 @@
       btm_read_rssi_complete(p);
       break;
 
+    case HCI_READ_FAILED_CONTACT_COUNTER:
+      btm_read_failed_contact_counter_complete(p);
+      break;
+
+    case HCI_READ_AUTOMATIC_FLUSH_TIMEOUT:
+      btm_read_automatic_flush_timeout_complete(p);
+      break;
+
     case HCI_READ_TRANSMIT_POWER_LEVEL:
       btm_read_tx_power_complete(p, false);
       break;
@@ -1029,7 +1079,7 @@
 static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
                                         uint8_t* p_cmd,
                                         void* p_vsc_status_cback) {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t handle;
 #if (BTM_SCO_INCLUDED == TRUE)
   tBTM_ESCO_DATA esco_data;
@@ -1083,10 +1133,10 @@
             if (p_cmd != NULL) {
               p_cmd++;
               STREAM_TO_BDADDR(bd_addr, p_cmd);
-              btm_acl_role_changed(status, bd_addr, BTM_ROLE_UNDEFINED);
+              btm_acl_role_changed(status, &bd_addr, BTM_ROLE_UNDEFINED);
             } else
               btm_acl_role_changed(status, NULL, BTM_ROLE_UNDEFINED);
-            l2c_link_role_changed(NULL, BTM_ROLE_UNDEFINED,
+            l2c_link_role_changed(nullptr, BTM_ROLE_UNDEFINED,
                                   HCI_ERR_COMMAND_DISALLOWED);
             break;
 
@@ -1232,7 +1282,7 @@
  ******************************************************************************/
 static void btu_hcif_role_change_evt(uint8_t* p) {
   uint8_t status;
-  BD_ADDR bda;
+  RawAddress bda;
   uint8_t role;
 
   STREAM_TO_UINT8(status, p);
@@ -1240,8 +1290,8 @@
   STREAM_TO_UINT8(role, p);
 
   btm_blacklist_role_change_device(bda, status);
-  l2c_link_role_changed(bda, role, status);
-  btm_acl_role_changed(status, bda, role);
+  l2c_link_role_changed(&bda, role, status);
+  btm_acl_role_changed(status, &bda, role);
 }
 
 /*******************************************************************************
@@ -1316,7 +1366,7 @@
  *
  ******************************************************************************/
 static void btu_hcif_pin_code_request_evt(uint8_t* p) {
-  BD_ADDR bda;
+  RawAddress bda;
 
   STREAM_TO_BDADDR(bda, p);
 
@@ -1337,7 +1387,7 @@
  *
  ******************************************************************************/
 static void btu_hcif_link_key_request_evt(uint8_t* p) {
-  BD_ADDR bda;
+  RawAddress bda;
 
   STREAM_TO_BDADDR(bda, p);
   btm_sec_link_key_request(bda);
@@ -1353,7 +1403,7 @@
  *
  ******************************************************************************/
 static void btu_hcif_link_key_notification_evt(uint8_t* p) {
-  BD_ADDR bda;
+  RawAddress bda;
   LINK_KEY key;
   uint8_t key_type;
 
@@ -1504,7 +1554,9 @@
  *
  ******************************************************************************/
 static void btu_hcif_io_cap_request_evt(uint8_t* p) {
-  btm_io_capabilities_req(p);
+  RawAddress bda;
+  STREAM_TO_BDADDR(bda, p);
+  btm_io_capabilities_req(bda);
 }
 
 /*******************************************************************************
@@ -1614,22 +1666,57 @@
  * End of Simple Pairing Events
  **********************************************/
 
-/**********************************************
- * BLE Events
- **********************************************/
+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. */
+    HCI_TRACE_WARNING("%s encryption stopped on link: 0x%02x", __func__,
+                      handle);
+    return;
+  }
+
+  if (status != HCI_SUCCESS) {
+    HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status);
+    btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
+    return;
+  }
+
+  if (key_size < MIN_KEY_SIZE) {
+    android_errorWriteLog(0x534e4554, "124301137");
+    HCI_TRACE_WARNING(
+        "%s encryption key too short, disconnecting. handle: 0x%02x, key_size: "
+        "%d",
+        __func__, handle, key_size);
+
+    btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
+    return;
+  }
+
+  btm_sec_encrypt_change(handle, status, 1 /* enc_enable */);
+}
+
 static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p) {
   uint8_t status;
-  uint8_t enc_enable = 0;
   uint16_t handle;
 
   STREAM_TO_UINT8(status, p);
   STREAM_TO_UINT16(handle, p);
 
-  if (status == HCI_SUCCESS) enc_enable = 1;
-
-  btm_sec_encrypt_change(handle, status, enc_enable);
+  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));
+  }
 }
 
+/**********************************************
+ * BLE Events
+ **********************************************/
+
 static void btu_ble_ll_conn_complete_evt(uint8_t* p, uint16_t evt_len) {
   btm_ble_conn_complete(p, evt_len, false);
 }
diff --git a/stack/btu/btu_init.cc b/stack/btu/btu_init.cc
index 16b9d61..e383fd3 100644
--- a/stack/btu/btu_init.cc
+++ b/stack/btu/btu_init.cc
@@ -39,26 +39,13 @@
 // RT priority for audio-related tasks
 #define BTU_TASK_RT_PRIORITY 1
 
-extern fixed_queue_t* btif_msg_queue;
-
-// Communication queue from bta thread to bt_workqueue.
-fixed_queue_t* btu_bta_msg_queue;
-
 // Communication queue from hci thread to bt_workqueue.
 extern fixed_queue_t* btu_hci_msg_queue;
 
-// General timer queue.
-fixed_queue_t* btu_general_alarm_queue;
-
 thread_t* bt_workqueue_thread;
 static const char* BT_WORKQUEUE_NAME = "bt_workqueue";
 
 extern void PLATFORM_DisableHciTransport(uint8_t bDisable);
-/*****************************************************************************
- *                          V A R I A B L E S                                *
- *****************************************************************************/
-// TODO(cmanton) Move this out of this file
-const BD_ADDR BT_BD_ANY = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
 void btu_task_start_up(void* context);
 void btu_task_shut_down(void* context);
@@ -122,12 +109,6 @@
 void BTU_StartUp(void) {
   btu_trace_level = HCI_INITIAL_TRACE_LEVEL;
 
-  btu_bta_msg_queue = fixed_queue_new(SIZE_MAX);
-  if (btu_bta_msg_queue == NULL) goto error_exit;
-
-  btu_general_alarm_queue = fixed_queue_new(SIZE_MAX);
-  if (btu_general_alarm_queue == NULL) goto error_exit;
-
   bt_workqueue_thread = thread_new(BT_WORKQUEUE_NAME);
   if (bt_workqueue_thread == NULL) goto error_exit;
 
@@ -146,11 +127,6 @@
 void BTU_ShutDown(void) {
   btu_task_shut_down(NULL);
 
-  fixed_queue_free(btu_bta_msg_queue, NULL);
-  btu_bta_msg_queue = NULL;
-
-  fixed_queue_free(btu_general_alarm_queue, NULL);
-  btu_general_alarm_queue = NULL;
 
   thread_free(bt_workqueue_thread);
 
diff --git a/stack/btu/btu_task.cc b/stack/btu/btu_task.cc
index 103990e..c0f374d 100644
--- a/stack/btu/btu_task.cc
+++ b/stack/btu/btu_task.cc
@@ -38,12 +38,11 @@
 #include "stack/include/btu.h"
 #include "stack/l2cap/l2c_int.h"
 
+static const int THREAD_RT_PRIORITY = 1;
+
 /* Define BTU storage area */
 uint8_t btu_trace_level = HCI_INITIAL_TRACE_LEVEL;
 
-// General timer queue.
-extern fixed_queue_t* btu_general_alarm_queue;
-
 extern thread_t* bt_workqueue_thread;
 
 static base::MessageLoop* message_loop_ = NULL;
@@ -125,9 +124,13 @@
   module_init(get_module(BTE_LOGMSG_MODULE));
 
   message_loop_thread_ = thread_new("btu message loop");
+  if (!message_loop_thread_) {
+    LOG(FATAL) << __func__ << " unable to create btu message loop thread.";
+  }
+
+  thread_set_rt_priority(message_loop_thread_, THREAD_RT_PRIORITY);
   thread_post(message_loop_thread_, btu_message_loop_run, nullptr);
 
-  alarm_register_processing_queue(btu_general_alarm_queue, bt_workqueue_thread);
 }
 
 void btu_task_shut_down(UNUSED_ATTR void* context) {
@@ -136,8 +139,6 @@
     message_loop_->task_runner()->PostTask(FROM_HERE, run_loop_->QuitClosure());
   }
 
-  alarm_unregister_processing_queue(btu_general_alarm_queue);
-
   module_clean_up(get_module(BTE_LOGMSG_MODULE));
 
   bta_sys_free();
diff --git a/stack/gap/gap_ble.cc b/stack/gap/gap_ble.cc
index 37c91f5..2247a14 100644
--- a/stack/gap/gap_ble.cc
+++ b/stack/gap/gap_ble.cc
@@ -35,7 +35,7 @@
 } tGAP_REQUEST;
 
 typedef struct {
-  BD_ADDR bda;
+  RawAddress bda;
   tGAP_BLE_CMPL_CBACK* p_cback;
   uint16_t conn_id;
   uint16_t cl_op_uuid;
@@ -51,7 +51,7 @@
 
 void server_attr_request_cback(uint16_t, uint32_t, tGATTS_REQ_TYPE,
                                tGATTS_DATA*);
-void client_connect_cback(tGATT_IF, BD_ADDR, uint16_t, bool,
+void client_connect_cback(tGATT_IF, const RawAddress&, uint16_t, bool,
                           tGATT_DISCONN_REASON, tGATT_TRANSPORT);
 void client_cmpl_cback(uint16_t, tGATTC_OPTYPE, tGATT_STATUS,
                        tGATT_CL_COMPLETE*);
@@ -75,9 +75,9 @@
 tGATT_IF gatt_if;
 
 /** returns LCB with macthing bd address, or nullptr */
-tGAP_CLCB* find_clcb_by_bd_addr(BD_ADDR bda) {
+tGAP_CLCB* find_clcb_by_bd_addr(const RawAddress& bda) {
   for (auto& cb : gap_clcbs)
-    if (!memcmp(cb.bda, bda, BD_ADDR_LEN)) return &cb;
+    if (cb.bda == bda) return &cb;
 
   return nullptr;
 }
@@ -91,11 +91,10 @@
 }
 
 /** allocates a GAP connection link control block */
-tGAP_CLCB* clcb_alloc(BD_ADDR bda) {
+tGAP_CLCB* clcb_alloc(const RawAddress& bda) {
   gap_clcbs.emplace_back();
   tGAP_CLCB& cb = gap_clcbs.back();
-
-  memcpy(cb.bda, bda, BD_ADDR_LEN);
+  cb.bda = bda;
   return &cb;
 }
 
@@ -223,7 +222,7 @@
 
     default:
       DVLOG(1) << StringPrintf("Unknown/unexpected LE GAP ATT request: 0x%02x",
-                              type);
+                               type);
       break;
   }
 
@@ -285,7 +284,7 @@
 }
 
 /** Client connection callback */
-void client_connect_cback(tGATT_IF, BD_ADDR bda, uint16_t conn_id,
+void client_connect_cback(tGATT_IF, const RawAddress& bda, uint16_t conn_id,
                           bool connected, tGATT_DISCONN_REASON reason,
                           tGATT_TRANSPORT) {
   tGAP_CLCB* p_clcb = find_clcb_by_bd_addr(bda);
@@ -354,7 +353,7 @@
   }
 }
 
-bool accept_client_operation(BD_ADDR peer_bda, uint16_t uuid,
+bool accept_client_operation(const RawAddress& peer_bda, uint16_t uuid,
                              tGAP_BLE_CMPL_CBACK* p_cback) {
   if (p_cback == NULL && uuid != GATT_UUID_GAP_PREF_CONN_PARAM) return false;
 
@@ -363,10 +362,8 @@
     p_clcb = clcb_alloc(peer_bda);
   }
 
-  DVLOG(1) << StringPrintf("%s() - BDA: %08x%04x  cl_op_uuid: 0x%04x", __func__,
-                          (peer_bda[0] << 24) + (peer_bda[1] << 16) +
-                              (peer_bda[2] << 8) + peer_bda[3],
-                          (peer_bda[4] << 8) + peer_bda[5], uuid);
+  DVLOG(1) << __func__ << ": BDA: " << peer_bda
+           << StringPrintf(" cl_op_uuid: 0x%04x", uuid);
 
   if (GATT_GetConnIdIfConnected(gatt_if, peer_bda, &p_clcb->conn_id,
                                 BT_TRANSPORT_LE))
@@ -516,7 +513,7 @@
  * Returns          true if read started, else false if GAP is busy
  *
  ******************************************************************************/
-bool GAP_BleReadPeerPrefConnParams(BD_ADDR peer_bda) {
+bool GAP_BleReadPeerPrefConnParams(const RawAddress& peer_bda) {
   return accept_client_operation(peer_bda, GATT_UUID_GAP_PREF_CONN_PARAM, NULL);
 }
 
@@ -530,7 +527,8 @@
  * Returns          true if request accepted
  *
  ******************************************************************************/
-bool GAP_BleReadPeerDevName(BD_ADDR peer_bda, tGAP_BLE_CMPL_CBACK* p_cback) {
+bool GAP_BleReadPeerDevName(const RawAddress& peer_bda,
+                            tGAP_BLE_CMPL_CBACK* p_cback) {
   return accept_client_operation(peer_bda, GATT_UUID_GAP_DEVICE_NAME, p_cback);
 }
 
@@ -543,7 +541,7 @@
  * Returns          true if request accepted
  *
  ******************************************************************************/
-bool GAP_BleReadPeerAddressResolutionCap(BD_ADDR peer_bda,
+bool GAP_BleReadPeerAddressResolutionCap(const RawAddress& peer_bda,
                                          tGAP_BLE_CMPL_CBACK* p_cback) {
   return accept_client_operation(peer_bda, GATT_UUID_GAP_CENTRAL_ADDR_RESOL,
                                  p_cback);
@@ -558,14 +556,12 @@
  * Returns          true if request accepted
  *
  ******************************************************************************/
-bool GAP_BleCancelReadPeerDevName(BD_ADDR peer_bda) {
+bool GAP_BleCancelReadPeerDevName(const RawAddress& peer_bda) {
   tGAP_CLCB* p_clcb = find_clcb_by_bd_addr(peer_bda);
 
-  DVLOG(1) << StringPrintf("%s: BDA: %08x%04x  cl_op_uuid: 0x%04x", __func__,
-                          (peer_bda[0] << 24) + (peer_bda[1] << 16) +
-                              (peer_bda[2] << 8) + peer_bda[3],
-                          (peer_bda[4] << 8) + peer_bda[5],
-                          (p_clcb == NULL) ? 0 : p_clcb->cl_op_uuid);
+  DVLOG(1) << __func__ << ": BDA: " << peer_bda
+           << StringPrintf(" cl_op_uuid: 0x%04x",
+                           (p_clcb == NULL) ? 0 : p_clcb->cl_op_uuid);
 
   if (p_clcb == NULL) {
     LOG(ERROR) << "Cannot cancel current op is not get dev name";
diff --git a/stack/gap/gap_conn.cc b/stack/gap/gap_conn.cc
index b05a7b2..7d75986 100644
--- a/stack/gap/gap_conn.cc
+++ b/stack/gap/gap_conn.cc
@@ -52,7 +52,7 @@
   uint16_t connection_id; /* L2CAP CID */
   bool rem_addr_specified;
   uint8_t chan_mode_mask; /* Supported channel modes (FCR) */
-  BD_ADDR rem_dev_address;
+  RawAddress rem_dev_address;
   uint16_t psm;
   uint16_t rem_mtu_size;
 
@@ -83,8 +83,8 @@
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
-static void gap_connect_ind(BD_ADDR bd_addr, uint16_t l2cap_cid, uint16_t psm,
-                            uint8_t l2cap_id);
+static void gap_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid,
+                            uint16_t psm, uint8_t l2cap_id);
 static void gap_connect_cfm(uint16_t l2cap_cid, uint16_t result);
 static void gap_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
 static void gap_config_cfm(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
@@ -160,7 +160,7 @@
  *
  ******************************************************************************/
 uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id,
-                      bool is_server, BD_ADDR p_rem_bda, uint16_t psm,
+                      bool is_server, const RawAddress* p_rem_bda, uint16_t psm,
                       tL2CAP_CFG_INFO* p_cfg, tL2CAP_ERTM_INFO* ertm_info,
                       uint16_t security, uint8_t chan_mode_mask,
                       tGAP_CONN_CALLBACK* p_cb, tBT_TRANSPORT transport) {
@@ -181,11 +181,10 @@
 
   /* If caller specified a BD address, save it */
   if (p_rem_bda) {
-    /* the bd addr is not BT_BD_ANY, then a bd address was specified */
-    if (memcmp(p_rem_bda, BT_BD_ANY, BD_ADDR_LEN))
-      p_ccb->rem_addr_specified = true;
+    /* the bd addr is not RawAddress::kAny, then a bd address was specified */
+    if (*p_rem_bda != RawAddress::kAny) p_ccb->rem_addr_specified = true;
 
-    memcpy(&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
+    p_ccb->rem_dev_address = *p_rem_bda;
   } else if (!is_server) {
     /* remore addr is not specified and is not a server -> bad */
     return (GAP_INVALID_HANDLE);
@@ -287,7 +286,7 @@
 
     /* Check if L2CAP started the connection process */
     if (p_rem_bda && (transport == BT_TRANSPORT_BR_EDR)) {
-      cid = L2CA_CONNECT_REQ(p_ccb->psm, p_rem_bda, &p_ccb->ertm_info);
+      cid = L2CA_CONNECT_REQ(p_ccb->psm, *p_rem_bda, &p_ccb->ertm_info);
       if (cid != 0) {
         p_ccb->connection_id = cid;
         return (p_ccb->gap_handle);
@@ -295,7 +294,7 @@
     }
 
     if (p_rem_bda && (transport == BT_TRANSPORT_LE)) {
-      cid = L2CA_CONNECT_COC_REQ(p_ccb->psm, p_rem_bda, &p_ccb->local_coc_cfg);
+      cid = L2CA_CONNECT_COC_REQ(p_ccb->psm, *p_rem_bda, &p_ccb->local_coc_cfg);
       if (cid != 0) {
         p_ccb->connection_id = cid;
         return (p_ccb->gap_handle);
@@ -607,22 +606,17 @@
  *                  GAP_ERR_BAD_HANDLE  - invalid handle
  *
  ******************************************************************************/
-uint8_t* GAP_ConnGetRemoteAddr(uint16_t gap_handle) {
+const RawAddress* GAP_ConnGetRemoteAddr(uint16_t gap_handle) {
   tGAP_CCB* p_ccb = gap_find_ccb_by_handle(gap_handle);
 
-  DVLOG(1) << StringPrintf("GAP_ConnGetRemoteAddr gap_handle = %d", gap_handle);
+  DVLOG(1) << __func__ << " gap_handle = " << gap_handle;
 
   if ((p_ccb) && (p_ccb->con_state > GAP_CCB_STATE_LISTENING)) {
-    DVLOG(1) << StringPrintf(
-        "GAP_ConnGetRemoteAddr bda "
-        ":0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
-        p_ccb->rem_dev_address[0], p_ccb->rem_dev_address[1],
-        p_ccb->rem_dev_address[2], p_ccb->rem_dev_address[3],
-        p_ccb->rem_dev_address[4], p_ccb->rem_dev_address[5]);
-    return (p_ccb->rem_dev_address);
+    DVLOG(1) << __func__ << " BDA: " << p_ccb->rem_dev_address;
+    return &p_ccb->rem_dev_address;
   } else {
-    DVLOG(1) << StringPrintf("GAP_ConnGetRemoteAddr return Error ");
-    return (NULL);
+    DVLOG(1) << __func__ << " return Error ";
+    return nullptr;
   }
 }
 
@@ -699,8 +693,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void gap_connect_ind(BD_ADDR bd_addr, uint16_t l2cap_cid, uint16_t psm,
-                            uint8_t l2cap_id) {
+static void gap_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid,
+                            uint16_t psm, uint8_t l2cap_id) {
   uint16_t xx;
   tGAP_CCB* p_ccb;
 
@@ -708,7 +702,7 @@
   for (xx = 0, p_ccb = conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) {
     if ((p_ccb->con_state == GAP_CCB_STATE_LISTENING) && (p_ccb->psm == psm) &&
         ((p_ccb->rem_addr_specified == false) ||
-         (!memcmp(bd_addr, p_ccb->rem_dev_address, BD_ADDR_LEN))))
+         (bd_addr == p_ccb->rem_dev_address)))
       break;
   }
 
@@ -728,7 +722,7 @@
     p_ccb->con_state = GAP_CCB_STATE_CFG_SETUP;
 
   /* Save the BD Address and Channel ID. */
-  memcpy(&p_ccb->rem_dev_address[0], bd_addr, BD_ADDR_LEN);
+  p_ccb->rem_dev_address = bd_addr;
   p_ccb->connection_id = l2cap_cid;
 
   /* Send response to the L2CAP layer. */
@@ -788,8 +782,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void gap_sec_check_complete(BD_ADDR, tBT_TRANSPORT, void* p_ref_data,
-                                   uint8_t res) {
+static void gap_sec_check_complete(const RawAddress*, tBT_TRANSPORT,
+                                   void* p_ref_data, uint8_t res) {
   tGAP_CCB* p_ccb = (tGAP_CCB*)p_ref_data;
 
   DVLOG(1) << StringPrintf(
diff --git a/stack/gatt/att_protocol.cc b/stack/gatt/att_protocol.cc
index e215547..82fa5a3 100644
--- a/stack/gatt/att_protocol.cc
+++ b/stack/gatt/att_protocol.cc
@@ -31,6 +31,7 @@
 #define GATT_OP_CODE_SIZE 1
 #define GATT_START_END_HANDLE_SIZE 4
 
+using base::StringPrintf;
 /**********************************************************************
  *   ATT protocl message building utility                              *
  **********************************************************************/
@@ -302,8 +303,8 @@
       /* update handle value pair length */
       if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2);
 
-      GATT_TRACE_WARNING("attribute value too long, to be truncated to %d",
-                         len);
+      LOG(WARNING) << StringPrintf(
+          "attribute value too long, to be truncated to %d", len);
     }
 
     ARRAY_TO_STREAM(p, p_data, len);
@@ -326,35 +327,27 @@
   if (tcb.att_lcid == L2CAP_ATT_CID)
     l2cap_ret = L2CA_SendFixedChnlData(L2CAP_ATT_CID, tcb.peer_bda, p_toL2CAP);
   else
-
     l2cap_ret = (uint16_t)L2CA_DataWrite(tcb.att_lcid, p_toL2CAP);
 
   if (l2cap_ret == L2CAP_DW_FAILED) {
-    GATT_TRACE_ERROR("ATT failed to pass msg to L2CAP");
+    LOG(ERROR) << __func__ << ": failed to write data to L2CAP";
     return GATT_INTERNAL_ERROR;
   } else if (l2cap_ret == L2CAP_DW_CONGESTED) {
-    GATT_TRACE_DEBUG("ATT congested, message accepted");
+    VLOG(1) << StringPrintf("ATT congested, message accepted");
     return GATT_CONGESTED;
   }
   return GATT_SUCCESS;
 }
 
-/*******************************************************************************
- *
- * Function         attp_build_sr_msg
- *
- * Description      Build ATT Server PDUs.
- *
- ******************************************************************************/
+/** Build ATT Server PDUs */
 BT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code,
                           tGATT_SR_MSG* p_msg) {
-  BT_HDR* p_cmd = NULL;
   uint16_t offset = 0;
 
   switch (op_code) {
     case GATT_RSP_READ_BLOB:
     case GATT_RSP_PREPARE_WRITE:
-      GATT_TRACE_EVENT(
+      VLOG(1) << StringPrintf(
           "ATT_RSP_READ_BLOB/GATT_RSP_PREPARE_WRITE: len = %d offset = %d",
           p_msg->attr_value.len, p_msg->attr_value.offset);
       offset = p_msg->attr_value.offset;
@@ -365,36 +358,27 @@
     case GATT_RSP_READ:
     case GATT_HANDLE_VALUE_NOTIF:
     case GATT_HANDLE_VALUE_IND:
-      p_cmd = attp_build_value_cmd(
+      return attp_build_value_cmd(
           tcb.payload_size, op_code, p_msg->attr_value.handle, offset,
           p_msg->attr_value.len, p_msg->attr_value.value);
-      break;
 
     case GATT_RSP_WRITE:
-      p_cmd = attp_build_opcode_cmd(op_code);
-      break;
+      return attp_build_opcode_cmd(op_code);
 
     case GATT_RSP_ERROR:
-      p_cmd = attp_build_err_cmd(p_msg->error.cmd_code, p_msg->error.handle,
-                                 p_msg->error.reason);
-      break;
+      return attp_build_err_cmd(p_msg->error.cmd_code, p_msg->error.handle,
+                                p_msg->error.reason);
 
     case GATT_RSP_EXEC_WRITE:
-      p_cmd = attp_build_exec_write_cmd(op_code, 0);
-      break;
+      return attp_build_exec_write_cmd(op_code, 0);
 
     case GATT_RSP_MTU:
-      p_cmd = attp_build_mtu_cmd(op_code, p_msg->mtu);
-      break;
+      return attp_build_mtu_cmd(op_code, p_msg->mtu);
 
     default:
-      GATT_TRACE_DEBUG("attp_build_sr_msg: unknown op code = %d", op_code);
-      break;
+      LOG(FATAL) << "attp_build_sr_msg: unknown op code = " << +op_code;
+      return nullptr;
   }
-
-  if (!p_cmd) GATT_TRACE_ERROR("No resources");
-
-  return p_cmd;
 }
 
 /*******************************************************************************
diff --git a/stack/gatt/gatt_api.cc b/stack/gatt/gatt_api.cc
index 1c4d2cc..c77a4c5 100644
--- a/stack/gatt/gatt_api.cc
+++ b/stack/gatt/gatt_api.cc
@@ -23,42 +23,17 @@
  ******************************************************************************/
 #include "bt_target.h"
 
-#include <base/bind.h>
+#include <base/strings/stringprintf.h>
 #include <stdio.h>
 #include <string.h>
 #include "bt_common.h"
 #include "btm_int.h"
-#include "btu.h"
 #include "device/include/controller.h"
 #include "gatt_api.h"
 #include "gatt_int.h"
 #include "l2c_api.h"
 
-/*******************************************************************************
- *
- * Function         GATT_SetTraceLevel
- *
- * Description      This function sets the trace level.  If called with
- *                  a value of 0xFF, it simply returns the current trace level.
- *
- *                  Input Parameters:
- *                      level:  The level to set the GATT tracing to:
- *                      0xff-returns the current setting.
- *                      0-turns off tracing.
- *                      >= 1-Errors.
- *                      >= 2-Warnings.
- *                      >= 3-APIs.
- *                      >= 4-Events.
- *                      >= 5-Debug.
- *
- * Returns          The new or current trace level
- *
- ******************************************************************************/
-uint8_t GATT_SetTraceLevel(uint8_t new_level) {
-  if (new_level != 0xFF) gatt_cb.trace_level = new_level;
-
-  return (gatt_cb.trace_level);
-}
+using base::StringPrintf;
 
 /**
  * Add an service handle range to the list in decending order of the start
@@ -155,7 +130,7 @@
       break;
 
     default:
-      GATT_TRACE_ERROR("%s: Unknown UUID length %d!", __func__, p_dest->len);
+      LOG(ERROR) << __func__ << ": Unknown UUID length %d!" << +p_dest->len;
       break;
   }
 }
@@ -180,7 +155,7 @@
     else if (el->type == BTGATT_DB_CHARACTERISTIC)
       db_size += 2;
     else
-      GATT_TRACE_ERROR("%s: Unknown element type: %d", __func__, el->type);
+      LOG(ERROR) << __func__ << ": Unknown element type: " << el->type;
 
   return db_size;
 }
@@ -229,10 +204,10 @@
   tBT_UUID svc_uuid;
   btif_to_bta_uuid(&svc_uuid, &service->uuid);
 
-  GATT_TRACE_API("%s", __func__);
+  LOG(INFO) << __func__;
 
   if (p_reg == NULL) {
-    GATT_TRACE_ERROR("Inavlid gatt_if=%d", gatt_if);
+    LOG(ERROR) << "Inavlid gatt_if=" << +gatt_if;
     return GATT_INTERNAL_ERROR;
   }
 
@@ -259,8 +234,9 @@
 
   /* check for space */
   if (num_handles > (0xFFFF - s_hdl + 1)) {
-    GATT_TRACE_ERROR("GATTS_ReserveHandles: no handles, s_hdl: %u  needed: %u",
-                     s_hdl, num_handles);
+    LOG(ERROR) << StringPrintf(
+        "GATTS_ReserveHandles: no handles, s_hdl: %u  needed: %u", s_hdl,
+        num_handles);
     return GATT_INTERNAL_ERROR;
   }
 
@@ -278,8 +254,8 @@
 
   gatts_init_service_db(list.svc_db, &svc_uuid, is_pri, s_hdl, num_handles);
 
-  GATT_TRACE_DEBUG(
-      "%d: handles needed:%u s_hdl=%u e_hdl=%u %s[%x] is_primary=%d", __func__,
+  VLOG(1) << StringPrintf(
+      "%s: handles needed:%u s_hdl=%u e_hdl=%u %s[%x] is_primary=%d", __func__,
       num_handles, list.asgn_range.s_handle, list.asgn_range.e_handle,
       ((list.asgn_range.svc_uuid.len == 2) ? "uuid16" : "uuid128"),
       list.asgn_range.svc_uuid.uu.uuid16, list.asgn_range.is_primary);
@@ -297,13 +273,14 @@
            !(el->permissions & GATT_WRITE_SIGNED_PERM)) ||
           ((el->permissions & GATT_WRITE_SIGNED_PERM) &&
            !(el->properties & GATT_CHAR_PROP_BIT_AUTH))) {
-        GATT_TRACE_DEBUG("Invalid configuration property=0x%02x perm=0x%04x ",
-                         el->properties, el->permissions);
+        VLOG(1) << StringPrintf(
+            "Invalid configuration property=0x%02x perm=0x%04x ",
+            el->properties, el->permissions);
         return GATT_INTERNAL_ERROR;
       }
 
       if (is_gatt_attr_type(uuid)) {
-        GATT_TRACE_ERROR(
+        LOG(ERROR) << StringPrintf(
             "%s: attept to add characteristic with UUID equal to GATT "
             "Attribute Type 0x%04x ",
             __func__, uuid.uu.uuid16);
@@ -314,7 +291,7 @@
           list.svc_db, el->permissions, el->properties, uuid);
     } else if (el->type == BTGATT_DB_DESCRIPTOR) {
       if (is_gatt_attr_type(uuid)) {
-        GATT_TRACE_ERROR(
+        LOG(ERROR) << StringPrintf(
             "%s: attept to add descriptor with UUID equal to GATT "
             "Attribute Type 0x%04x ",
             __func__, uuid.uu.uuid16);
@@ -327,7 +304,7 @@
       tGATT_HDL_LIST_ELEM* p_incl_decl;
       p_incl_decl = gatt_find_hdl_buffer_by_handle(el->attribute_handle);
       if (p_incl_decl == nullptr) {
-        GATT_TRACE_DEBUG("Included Service not created");
+        VLOG(1) << "Included Service not created";
         return GATT_INTERNAL_ERROR;
       }
 
@@ -337,7 +314,7 @@
     }
   }
 
-  GATT_TRACE_API("%s: service parsed correctly, now starting", __func__);
+  LOG(INFO) << __func__ << ": service parsed correctly, now starting";
 
   /*this is a new application service start */
 
@@ -369,9 +346,9 @@
 
   gatt_update_last_pri_srv_info();
 
-  GATT_TRACE_DEBUG("%s: allocated el: s_hdl=%d e_hdl=%d type=0x%x sdp_hdl=0x%x",
-                   __func__, elem.s_hdl, elem.e_hdl, elem.type,
-                   elem.sdp_handle);
+  VLOG(1) << StringPrintf(
+      "%s: allocated el: s_hdl=%d e_hdl=%d type=0x%x sdp_hdl=0x%x", __func__,
+      elem.s_hdl, elem.e_hdl, elem.type, elem.sdp_handle);
 
   gatt_proc_srv_chg();
 
@@ -386,7 +363,7 @@
     if (p_this_uuid && gatt_uuid_compare(*p_app_uuid128, info.app_uuid) &&
         gatt_uuid_compare(*p_svc_uuid, *p_this_uuid) &&
         (start_handle == info.s_hdl)) {
-      GATT_TRACE_ERROR("Active Service Found ");
+      LOG(ERROR) << "Active Service Found";
       gatt_dbg_display_uuid(*p_svc_uuid);
 
       return true;
@@ -411,18 +388,18 @@
  ******************************************************************************/
 bool GATTS_DeleteService(tGATT_IF gatt_if, tBT_UUID* p_svc_uuid,
                          uint16_t svc_inst) {
-  GATT_TRACE_DEBUG("GATTS_DeleteService");
+  VLOG(1) << __func__;
 
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
   if (p_reg == NULL) {
-    GATT_TRACE_ERROR("Applicaiton not foud");
+    LOG(ERROR) << "Applicaiton not foud";
     return false;
   }
 
   tBT_UUID* p_app_uuid128 = &p_reg->app_uuid128;
   auto it = gatt_find_hdl_buffer_by_app_id(p_app_uuid128, p_svc_uuid, svc_inst);
   if (it == gatt_cb.hdl_list_info->end()) {
-    GATT_TRACE_ERROR("No Service found");
+    LOG(ERROR) << "No Service found";
     return false;
   }
 
@@ -432,8 +409,8 @@
     GATTS_StopService(it->asgn_range.s_handle);
   }
 
-  GATT_TRACE_DEBUG("released handles s_hdl=%u e_hdl=%u",
-                   it->asgn_range.s_handle, it->asgn_range.e_handle);
+  VLOG(1) << StringPrintf("released handles s_hdl=%u e_hdl=%u",
+                          it->asgn_range.s_handle, it->asgn_range.e_handle);
 
   if ((it->asgn_range.s_handle >= gatt_cb.hdl_cfg.app_start_hdl) &&
       gatt_cb.cb_info.p_nv_save_callback)
@@ -455,12 +432,12 @@
  *
  ******************************************************************************/
 void GATTS_StopService(uint16_t service_handle) {
-  GATT_TRACE_API("%s: %u", __func__, service_handle);
+  LOG(INFO) << __func__ << ": 0x" << std::hex << +service_handle;
 
   auto it = gatt_sr_find_i_rcb_by_handle(service_handle);
   if (it == gatt_cb.srv_list_info->end()) {
-    GATT_TRACE_ERROR("%s: service_handle: %u is not in use", __func__,
-                     service_handle);
+    LOG(ERROR) << StringPrintf("%s: service_handle: %u is not in use", __func__,
+                               service_handle);
   }
 
   if (it->sdp_handle) {
@@ -498,10 +475,9 @@
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
 
-  GATT_TRACE_API("GATTS_HandleValueIndication");
+  VLOG(1) << __func__;
   if ((p_reg == NULL) || (p_tcb == NULL)) {
-    GATT_TRACE_ERROR("GATTS_HandleValueIndication Unknown  conn_id: %u ",
-                     conn_id);
+    LOG(ERROR) << __func__ << ": Unknown  conn_id: " << +conn_id;
     return (tGATT_STATUS)GATT_INVALID_CONN_ID;
   }
 
@@ -514,7 +490,7 @@
   indication.auth_req = GATT_AUTH_REQ_NONE;
 
   if (GATT_HANDLE_IS_VALID(p_tcb->indicate_handle)) {
-    GATT_TRACE_DEBUG("Add a pending indication");
+    VLOG(1) << "Add a pending indication";
     p_buf = gatt_add_pending_ind(p_tcb, &indication);
     if (p_buf != NULL) {
       cmd_status = GATT_SUCCESS;
@@ -522,8 +498,9 @@
       cmd_status = GATT_NO_RESOURCES;
     }
   } else {
-    p_msg = attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_IND,
-                              (tGATT_SR_MSG*)&indication);
+    tGATT_SR_MSG gatt_sr_msg;
+    gatt_sr_msg.attr_value = indication;
+    p_msg = attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_IND, &gatt_sr_msg);
     if (p_msg != NULL) {
       cmd_status = attp_send_sr_msg(*p_tcb, p_msg);
 
@@ -560,11 +537,10 @@
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
 
-  GATT_TRACE_API("GATTS_HandleValueNotification");
+  VLOG(1) << __func__;
 
   if ((p_reg == NULL) || (p_tcb == NULL)) {
-    GATT_TRACE_ERROR("GATTS_HandleValueNotification Unknown  conn_id: %u ",
-                     conn_id);
+    LOG(ERROR) << __func__ << "Unknown  conn_id: " << conn_id;
     return (tGATT_STATUS)GATT_INVALID_CONN_ID;
   }
 
@@ -578,8 +554,10 @@
   notif.auth_req = GATT_AUTH_REQ_NONE;
 
   tGATT_STATUS cmd_sent;
+  tGATT_SR_MSG gatt_sr_msg;
+  gatt_sr_msg.attr_value = notif;
   BT_HDR* p_buf =
-      attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_NOTIF, (tGATT_SR_MSG*)&notif);
+      attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_NOTIF, &gatt_sr_msg);
   if (p_buf != NULL) {
     cmd_sent = attp_send_sr_msg(*p_tcb, p_buf);
   } else
@@ -609,17 +587,18 @@
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
 
-  GATT_TRACE_API("GATTS_SendRsp: conn_id: %u  trans_id: %u  Status: 0x%04x",
-                 conn_id, trans_id, status);
+  VLOG(1) << __func__
+          << StringPrintf(": conn_id: %u  trans_id: %u  Status: 0x%04x",
+                          conn_id, trans_id, status);
 
   if ((p_reg == NULL) || (p_tcb == NULL)) {
-    GATT_TRACE_ERROR("GATTS_SendRsp Unknown  conn_id: %u ", conn_id);
+    LOG(ERROR) << StringPrintf("Unknown  conn_id: %u ", conn_id);
     return (tGATT_STATUS)GATT_INVALID_CONN_ID;
   }
 
   if (p_tcb->sr_cmd.trans_id != trans_id) {
-    GATT_TRACE_ERROR("GATTS_SendRsp conn_id: %u  waiting for op_code = %02x",
-                     conn_id, p_tcb->sr_cmd.op_code);
+    LOG(ERROR) << StringPrintf("conn_id: %u  waiting for op_code = %02x",
+                               conn_id, p_tcb->sr_cmd.op_code);
 
     return (GATT_WRONG_STATE);
   }
@@ -653,15 +632,12 @@
  *
  ******************************************************************************/
 tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) {
-  uint8_t ret = GATT_NO_RESOURCES;
   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
   uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
 
-  tGATT_CLCB* p_clcb;
-
-  GATT_TRACE_API("GATTC_ConfigureMTU conn_id=%d mtu=%d", conn_id, mtu);
+  VLOG(1) << __func__ << StringPrintf("conn_id=%d mtu=%d", conn_id, mtu);
 
   if ((p_tcb == NULL) || (p_reg == NULL) || (mtu < GATT_DEF_BLE_MTU_SIZE) ||
       (mtu > GATT_MAX_MTU_SIZE)) {
@@ -674,100 +650,20 @@
   }
 
   if (gatt_is_clcb_allocated(conn_id)) {
-    GATT_TRACE_ERROR("GATTC_ConfigureMTU GATT_BUSY conn_id = %d", conn_id);
+    LOG(ERROR) << "GATT_BUSY conn_id = " << +conn_id;
     return GATT_BUSY;
   }
 
-  p_clcb = gatt_clcb_alloc(conn_id);
-  if (p_clcb != NULL) {
-    p_clcb->p_tcb->payload_size = mtu;
-    p_clcb->operation = GATTC_OPTYPE_CONFIG;
+  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
+  if (!p_clcb) return GATT_NO_RESOURCES;
 
-    ret = attp_send_cl_msg(*p_clcb->p_tcb, p_clcb, GATT_REQ_MTU,
-                           (tGATT_CL_MSG*)&mtu);
-  }
-
-  return ret;
+  p_clcb->p_tcb->payload_size = mtu;
+  p_clcb->operation = GATTC_OPTYPE_CONFIG;
+  tGATT_CL_MSG gatt_cl_msg;
+  gatt_cl_msg.mtu = mtu;
+  return attp_send_cl_msg(*p_clcb->p_tcb, p_clcb, GATT_REQ_MTU, &gatt_cl_msg);
 }
 
-void read_phy_cb(
-    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb,
-    uint8_t* data, uint16_t len) {
-  uint8_t status, tx_phy, rx_phy;
-  uint16_t handle;
-
-  LOG_ASSERT(len == 5) << "Received bad response length: " << len;
-  uint8_t* pp = data;
-  STREAM_TO_UINT8(status, pp);
-  STREAM_TO_UINT16(handle, pp);
-  handle = handle & 0x0FFF;
-  STREAM_TO_UINT8(tx_phy, pp);
-  STREAM_TO_UINT8(rx_phy, pp);
-
-  DVLOG(1) << __func__ << " Received read_phy_cb";
-  cb.Run(tx_phy, rx_phy, status);
-}
-
-void GATTC_ReadPHY(
-    uint16_t conn_id,
-    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb) {
-  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
-  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
-  if (p_tcb == NULL) {
-    GATT_TRACE_ERROR("%s: no p_tcb for conn_id %d", __func__, conn_id);
-    cb.Run(0, 0, GATT_INVALID_HANDLE);
-    return;
-  }
-
-  tACL_CONN* p_lcb = btm_bda_to_acl(p_tcb->peer_bda, BT_TRANSPORT_LE);
-  if (p_lcb == NULL) {
-    GATT_TRACE_ERROR("%s: no p_lcb for conn_id %d", __func__, conn_id);
-    cb.Run(0, 0, GATT_INVALID_HANDLE);
-    return;
-  }
-  uint16_t handle = p_lcb->hci_handle;
-
-  const uint8_t len = 2;
-  uint8_t data[len];
-  uint8_t* pp = data;
-  UINT16_TO_STREAM(pp, handle);
-  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_LE_READ_PHY, data, len,
-                            base::Bind(&read_phy_cb, std::move(cb)));
-}
-
-void doNothing(uint8_t* data, uint16_t len) {}
-
-void GATTC_SetPreferredPHY(uint16_t conn_id, uint8_t tx_phy, uint8_t rx_phy,
-                           uint16_t phy_options) {
-  uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
-  tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
-  if (p_tcb == NULL) {
-    GATT_TRACE_ERROR("%s: no p_tcb for conn_id %d", __func__, conn_id);
-    return;
-  }
-
-  tACL_CONN* p_lcb = btm_bda_to_acl(p_tcb->peer_bda, BT_TRANSPORT_LE);
-  if (p_lcb == NULL) {
-    GATT_TRACE_ERROR("%s: no p_lcb for conn_id %d", __func__, conn_id);
-    return;
-  }
-  uint16_t handle = p_lcb->hci_handle;
-
-  uint8_t all_phys = 0;
-  if (tx_phy == 0) all_phys &= 0x01;
-  if (rx_phy == 0) all_phys &= 0x02;
-
-  const uint8_t len = 7;
-  uint8_t data[len];
-  uint8_t* pp = data;
-  UINT16_TO_STREAM(pp, handle);
-  UINT8_TO_STREAM(pp, all_phys);
-  UINT8_TO_STREAM(pp, tx_phy);
-  UINT8_TO_STREAM(pp, rx_phy);
-  UINT16_TO_STREAM(pp, phy_options);
-  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_LE_SET_PHY, data, len,
-                            base::Bind(doNothing));
-}
 
 /*******************************************************************************
  *
@@ -785,48 +681,44 @@
  ******************************************************************************/
 tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                             tGATT_DISC_PARAM* p_param) {
-  tGATT_STATUS status = GATT_SUCCESS;
-  tGATT_CLCB* p_clcb;
   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
   uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
 
-  GATT_TRACE_API("GATTC_Discover conn_id=%d disc_type=%d", conn_id, disc_type);
+  LOG(INFO) << __func__
+            << StringPrintf(" conn_id=%d disc_type=%d", conn_id, disc_type);
 
   if ((p_tcb == NULL) || (p_reg == NULL) || (p_param == NULL) ||
       (disc_type >= GATT_DISC_MAX)) {
-    GATT_TRACE_ERROR("GATTC_Discover Illegal param: disc_type %d conn_id = %d",
-                     disc_type, conn_id);
+    LOG(ERROR) << StringPrintf("Illegal param: disc_type %d conn_id = %d",
+                               disc_type, conn_id);
+    return GATT_ILLEGAL_PARAMETER;
+  }
+
+  if (!GATT_HANDLE_IS_VALID(p_param->s_handle) ||
+      !GATT_HANDLE_IS_VALID(p_param->e_handle) ||
+      /* search by type does not have a valid UUID param */
+      (disc_type == GATT_DISC_SRVC_BY_UUID && p_param->service.len == 0)) {
     return GATT_ILLEGAL_PARAMETER;
   }
 
   if (gatt_is_clcb_allocated(conn_id)) {
-    GATT_TRACE_ERROR("GATTC_Discover GATT_BUSY conn_id = %d", conn_id);
+    LOG(ERROR) << __func__ << "GATT_BUSY conn_id = " << +conn_id;
     return GATT_BUSY;
   }
 
-  p_clcb = gatt_clcb_alloc(conn_id);
-  if (p_clcb != NULL) {
-    if (!GATT_HANDLE_IS_VALID(p_param->s_handle) ||
-        !GATT_HANDLE_IS_VALID(p_param->e_handle) ||
-        /* search by type does not have a valid UUID param */
-        (disc_type == GATT_DISC_SRVC_BY_UUID && p_param->service.len == 0)) {
-      gatt_clcb_dealloc(p_clcb);
-      return GATT_ILLEGAL_PARAMETER;
-    }
+  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
+  if (!p_clcb) return GATT_NO_RESOURCES;
 
-    p_clcb->operation = GATTC_OPTYPE_DISCOVERY;
-    p_clcb->op_subtype = disc_type;
-    p_clcb->s_handle = p_param->s_handle;
-    p_clcb->e_handle = p_param->e_handle;
-    p_clcb->uuid = p_param->service;
+  p_clcb->operation = GATTC_OPTYPE_DISCOVERY;
+  p_clcb->op_subtype = disc_type;
+  p_clcb->s_handle = p_param->s_handle;
+  p_clcb->e_handle = p_param->e_handle;
+  p_clcb->uuid = p_param->service;
 
-    gatt_act_discovery(p_clcb);
-  } else {
-    status = GATT_NO_RESOURCES;
-  }
-  return status;
+  gatt_act_discovery(p_clcb);
+  return GATT_SUCCESS;
 }
 
 /*******************************************************************************
@@ -845,72 +737,66 @@
  ******************************************************************************/
 tGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type,
                         tGATT_READ_PARAM* p_read) {
-  tGATT_STATUS status = GATT_SUCCESS;
-  tGATT_CLCB* p_clcb;
   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
   uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
 
-  GATT_TRACE_API("GATTC_Read conn_id=%d type=%d", conn_id, type);
+  VLOG(1) << __func__ << StringPrintf(" conn_id=%d type=%d", conn_id, type);
 
   if ((p_tcb == NULL) || (p_reg == NULL) || (p_read == NULL) ||
       ((type >= GATT_READ_MAX) || (type == 0))) {
-    GATT_TRACE_ERROR("GATT_Read Illegal param: conn_id %d, type 0%d,", conn_id,
-                     type);
+    LOG(ERROR) << StringPrintf(" Illegal param: conn_id %d, type 0%d,", conn_id,
+                               type);
     return GATT_ILLEGAL_PARAMETER;
   }
 
   if (gatt_is_clcb_allocated(conn_id)) {
-    GATT_TRACE_ERROR("GATTC_Read GATT_BUSY conn_id = %d", conn_id);
+    LOG(ERROR) << StringPrintf(" GATT_BUSY conn_id = %d", conn_id);
     return GATT_BUSY;
   }
 
-  p_clcb = gatt_clcb_alloc(conn_id);
-  if (p_clcb != NULL) {
-    p_clcb->operation = GATTC_OPTYPE_READ;
-    p_clcb->op_subtype = type;
-    p_clcb->auth_req = p_read->by_handle.auth_req;
-    p_clcb->counter = 0;
+  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
+  if (!p_clcb) return GATT_NO_RESOURCES;
 
-    switch (type) {
-      case GATT_READ_BY_TYPE:
-      case GATT_READ_CHAR_VALUE:
-        p_clcb->s_handle = p_read->service.s_handle;
-        p_clcb->e_handle = p_read->service.e_handle;
-        memcpy(&p_clcb->uuid, &p_read->service.uuid, sizeof(tBT_UUID));
-        break;
-      case GATT_READ_MULTIPLE: {
-        p_clcb->s_handle = 0;
-        /* copy multiple handles in CB */
-        tGATT_READ_MULTI* p_read_multi =
-            (tGATT_READ_MULTI*)osi_malloc(sizeof(tGATT_READ_MULTI));
-        p_clcb->p_attr_buf = (uint8_t*)p_read_multi;
-        memcpy(p_read_multi, &p_read->read_multiple, sizeof(tGATT_READ_MULTI));
-        break;
+  p_clcb->operation = GATTC_OPTYPE_READ;
+  p_clcb->op_subtype = type;
+  p_clcb->auth_req = p_read->by_handle.auth_req;
+  p_clcb->counter = 0;
+
+  switch (type) {
+    case GATT_READ_BY_TYPE:
+    case GATT_READ_CHAR_VALUE:
+      p_clcb->s_handle = p_read->service.s_handle;
+      p_clcb->e_handle = p_read->service.e_handle;
+      memcpy(&p_clcb->uuid, &p_read->service.uuid, sizeof(tBT_UUID));
+      break;
+    case GATT_READ_MULTIPLE: {
+      p_clcb->s_handle = 0;
+      /* copy multiple handles in CB */
+      tGATT_READ_MULTI* p_read_multi =
+          (tGATT_READ_MULTI*)osi_malloc(sizeof(tGATT_READ_MULTI));
+      p_clcb->p_attr_buf = (uint8_t*)p_read_multi;
+      memcpy(p_read_multi, &p_read->read_multiple, sizeof(tGATT_READ_MULTI));
+      break;
+    }
+    case GATT_READ_BY_HANDLE:
+    case GATT_READ_PARTIAL:
+      memset(&p_clcb->uuid, 0, sizeof(tBT_UUID));
+      p_clcb->s_handle = p_read->by_handle.handle;
+
+      if (type == GATT_READ_PARTIAL) {
+        p_clcb->counter = p_read->partial.offset;
       }
-      case GATT_READ_BY_HANDLE:
-      case GATT_READ_PARTIAL:
-        memset(&p_clcb->uuid, 0, sizeof(tBT_UUID));
-        p_clcb->s_handle = p_read->by_handle.handle;
 
-        if (type == GATT_READ_PARTIAL) {
-          p_clcb->counter = p_read->partial.offset;
-        }
-
-        break;
-      default:
-        break;
-    }
-    /* start security check */
-    if (gatt_security_check_start(p_clcb) == false) {
-      status = GATT_NO_RESOURCES;
-      gatt_clcb_dealloc(p_clcb);
-    }
-  } else {
-    status = GATT_NO_RESOURCES;
+      break;
+    default:
+      break;
   }
-  return status;
+
+  /* start security check */
+  gatt_security_check_start(p_clcb);
+  return GATT_SUCCESS;
 }
 
 /*******************************************************************************
@@ -929,9 +815,6 @@
  ******************************************************************************/
 tGATT_STATUS GATTC_Write(uint16_t conn_id, tGATT_WRITE_TYPE type,
                          tGATT_VALUE* p_write) {
-  tGATT_STATUS status = GATT_SUCCESS;
-  tGATT_CLCB* p_clcb;
-  tGATT_VALUE* p;
   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
   uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
@@ -940,40 +823,35 @@
   if ((p_tcb == NULL) || (p_reg == NULL) || (p_write == NULL) ||
       ((type != GATT_WRITE) && (type != GATT_WRITE_PREPARE) &&
        (type != GATT_WRITE_NO_RSP))) {
-    GATT_TRACE_ERROR("GATT_Write Illegal param: conn_id %d, type 0%d,", conn_id,
-                     type);
+    LOG(ERROR) << __func__
+               << StringPrintf(" Illegal param: conn_id %d, type 0%d,", conn_id,
+                               type);
     return GATT_ILLEGAL_PARAMETER;
   }
 
   if (gatt_is_clcb_allocated(conn_id)) {
-    GATT_TRACE_ERROR("GATTC_Write GATT_BUSY conn_id = %d", conn_id);
+    LOG(ERROR) << StringPrintf("GATT_BUSY conn_id = %d", conn_id);
     return GATT_BUSY;
   }
 
-  p_clcb = gatt_clcb_alloc(conn_id);
-  if (p_clcb != NULL) {
-    p_clcb->operation = GATTC_OPTYPE_WRITE;
-    p_clcb->op_subtype = type;
-    p_clcb->auth_req = p_write->auth_req;
+  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
+  if (!p_clcb) return GATT_NO_RESOURCES;
 
-    p_clcb->p_attr_buf = (uint8_t*)osi_malloc(sizeof(tGATT_VALUE));
-    memcpy(p_clcb->p_attr_buf, (void*)p_write, sizeof(tGATT_VALUE));
+  p_clcb->operation = GATTC_OPTYPE_WRITE;
+  p_clcb->op_subtype = type;
+  p_clcb->auth_req = p_write->auth_req;
 
-    p = (tGATT_VALUE*)p_clcb->p_attr_buf;
-    if (type == GATT_WRITE_PREPARE) {
-      p_clcb->start_offset = p_write->offset;
-      p->offset = 0;
-    }
+  p_clcb->p_attr_buf = (uint8_t*)osi_malloc(sizeof(tGATT_VALUE));
+  memcpy(p_clcb->p_attr_buf, (void*)p_write, sizeof(tGATT_VALUE));
 
-    if (gatt_security_check_start(p_clcb) == false) {
-      status = GATT_NO_RESOURCES;
-    }
-
-    if (status == GATT_NO_RESOURCES) gatt_clcb_dealloc(p_clcb);
-  } else {
-    status = GATT_NO_RESOURCES;
+  tGATT_VALUE* p = (tGATT_VALUE*)p_clcb->p_attr_buf;
+  if (type == GATT_WRITE_PREPARE) {
+    p_clcb->start_offset = p_write->offset;
+    p->offset = 0;
   }
-  return status;
+
+  gatt_security_check_start(p_clcb);
+  return GATT_SUCCESS;
 }
 
 /*******************************************************************************
@@ -991,37 +869,32 @@
  *
  ******************************************************************************/
 tGATT_STATUS GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) {
-  tGATT_STATUS status = GATT_SUCCESS;
-  tGATT_CLCB* p_clcb;
-  tGATT_EXEC_FLAG flag;
   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
   uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
 
-  GATT_TRACE_API("GATTC_ExecuteWrite conn_id=%d is_execute=%d", conn_id,
-                 is_execute);
+  VLOG(1) << __func__
+          << StringPrintf(": conn_id=%d is_execute=%d", conn_id, is_execute);
 
   if ((p_tcb == NULL) || (p_reg == NULL)) {
-    GATT_TRACE_ERROR("GATTC_ExecuteWrite Illegal param: conn_id %d", conn_id);
+    LOG(ERROR) << StringPrintf(" Illegal param: conn_id %d", conn_id);
     return GATT_ILLEGAL_PARAMETER;
   }
 
   if (gatt_is_clcb_allocated(conn_id)) {
-    GATT_TRACE_ERROR("GATTC_Write GATT_BUSY conn_id = %d", conn_id);
+    LOG(ERROR) << StringPrintf(" GATT_BUSY conn_id = %d", conn_id);
     return GATT_BUSY;
   }
 
-  p_clcb = gatt_clcb_alloc(conn_id);
-  if (p_clcb != NULL) {
-    p_clcb->operation = GATTC_OPTYPE_EXE_WRITE;
-    flag = is_execute ? GATT_PREP_WRITE_EXEC : GATT_PREP_WRITE_CANCEL;
-    gatt_send_queue_write_cancel(*p_clcb->p_tcb, p_clcb, flag);
-  } else {
-    GATT_TRACE_ERROR("Unable to allocate client CB for conn_id %d ", conn_id);
-    status = GATT_NO_RESOURCES;
-  }
-  return status;
+  tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id);
+  if (!p_clcb) return GATT_NO_RESOURCES;
+
+  p_clcb->operation = GATTC_OPTYPE_EXE_WRITE;
+  tGATT_EXEC_FLAG flag =
+      is_execute ? GATT_PREP_WRITE_EXEC : GATT_PREP_WRITE_CANCEL;
+  gatt_send_queue_write_cancel(*p_clcb->p_tcb, p_clcb, flag);
+  return GATT_SUCCESS;
 }
 
 /*******************************************************************************
@@ -1038,27 +911,29 @@
  *
  ******************************************************************************/
 tGATT_STATUS GATTC_SendHandleValueConfirm(uint16_t conn_id, uint16_t handle) {
-  GATT_TRACE_API("%s conn_id=%d handle=0x%x", __func__, conn_id, handle);
+  VLOG(1) << __func__
+          << StringPrintf(" conn_id=%d handle=0x%x", conn_id, handle);
 
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(GATT_GET_TCB_IDX(conn_id));
   if (!p_tcb) {
-    GATT_TRACE_ERROR("%s - Unknown conn_id: %u", __func__, conn_id);
+    LOG(ERROR) << StringPrintf(" Unknown conn_id: %u", conn_id);
     return GATT_ILLEGAL_PARAMETER;
   }
 
   if (p_tcb->ind_count == 0) {
-    GATT_TRACE_DEBUG(
-        "%s - conn_id: %u - ignored not waiting for indicaiton ack", __func__,
-        conn_id);
+    VLOG(1) << " conn_id: " << +conn_id
+            << " ignored not waiting for indicaiton ack";
     return GATT_SUCCESS;
   }
 
   alarm_cancel(p_tcb->ind_ack_timer);
 
-  GATT_TRACE_DEBUG("notif_count=%d ", p_tcb->ind_count);
+  VLOG(1) << "notif_count= " << p_tcb->ind_count;
   /* send confirmation now */
-  tGATT_STATUS ret = attp_send_cl_msg(*p_tcb, nullptr, GATT_HANDLE_VALUE_CONF,
-                                      (tGATT_CL_MSG*)&handle);
+  tGATT_CL_MSG gatt_cl_msg;
+  gatt_cl_msg.handle = handle;
+  tGATT_STATUS ret =
+      attp_send_cl_msg(*p_tcb, nullptr, GATT_HANDLE_VALUE_CONF, &gatt_cl_msg);
 
   p_tcb->ind_count = 0;
 
@@ -1083,7 +958,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void GATT_SetIdleTimeout(BD_ADDR bd_addr, uint16_t idle_tout,
+void GATT_SetIdleTimeout(const RawAddress& bd_addr, uint16_t idle_tout,
                          tBT_TRANSPORT transport) {
   tGATT_TCB* p_tcb;
   bool status = false;
@@ -1102,9 +977,9 @@
     }
   }
 
-  GATT_TRACE_API(
-      "GATT_SetIdleTimeout idle_tout=%d status=%d(1-OK 0-not performed)",
-      idle_tout, status);
+  VLOG(1) << __func__
+          << StringPrintf(" idle_tout=%d status=%d(1-OK 0-not performed)",
+                          idle_tout, status);
 }
 
 /*******************************************************************************
@@ -1126,7 +1001,7 @@
   uint8_t i_gatt_if = 0;
   tGATT_IF gatt_if = 0;
 
-  GATT_TRACE_API("%s", __func__);
+  LOG(INFO) << __func__;
   gatt_dbg_display_uuid(*p_app_uuid128);
 
   for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS;
@@ -1134,7 +1009,7 @@
     if (p_reg->in_use &&
         !memcmp(p_app_uuid128->uu.uuid128, p_reg->app_uuid128.uu.uuid128,
                 LEN_UUID_128)) {
-      GATT_TRACE_ERROR("application already registered.");
+      LOG(ERROR) << "application already registered.";
       return 0;
     }
   }
@@ -1149,13 +1024,13 @@
       p_reg->app_cb = *p_cb_info;
       p_reg->in_use = true;
 
-      GATT_TRACE_API("%s: allocated gatt_if=%d", __func__, gatt_if);
+      LOG(INFO) << "allocated gatt_if=" << +gatt_if;
       return gatt_if;
     }
   }
 
-  GATT_TRACE_ERROR("%s: can't Register GATT client, MAX client %d reached!",
-                   __func__, GATT_MAX_APPS);
+  LOG(ERROR) << "can't Register GATT client, MAX client reached: "
+             << GATT_MAX_APPS;
   return 0;
 }
 
@@ -1171,12 +1046,12 @@
  *
  ******************************************************************************/
 void GATT_Deregister(tGATT_IF gatt_if) {
-  GATT_TRACE_API("GATT_Deregister gatt_if=%d", gatt_if);
+  VLOG(1) << __func__ << " gatt_if=" << +gatt_if;
 
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
   /* Index 0 is GAP and is never deregistered */
   if ((gatt_if == 0) || (p_reg == NULL)) {
-    GATT_TRACE_ERROR("GATT_Deregister with invalid gatt_if: %u", gatt_if);
+    LOG(ERROR) << "invalid gatt_if: " << +gatt_if;
     return;
   }
 
@@ -1185,9 +1060,11 @@
     other application
     deregisteration need to bed performed in an orderly fashion
     no check for now */
-  for (auto& el : *gatt_cb.srv_list_info) {
-    if (el.gatt_if == gatt_if) {
-      GATTS_StopService(el.s_hdl);
+  for (auto it = gatt_cb.srv_list_info->begin(); it != gatt_cb.srv_list_info->end(); ) {
+    if (it->gatt_if == gatt_if) {
+      GATTS_StopService(it++->s_hdl);
+    } else {
+      ++it;
     }
   }
 
@@ -1238,12 +1115,12 @@
 void GATT_StartIf(tGATT_IF gatt_if) {
   tGATT_REG* p_reg;
   tGATT_TCB* p_tcb;
-  BD_ADDR bda;
+  RawAddress bda;
   uint8_t start_idx, found_idx;
   uint16_t conn_id;
   tGATT_TRANSPORT transport;
 
-  GATT_TRACE_API("GATT_StartIf gatt_if=%d", gatt_if);
+  VLOG(1) << __func__ << " gatt_if=" << gatt_if;
   p_reg = gatt_get_regcb(gatt_if);
   if (p_reg != NULL) {
     start_idx = 0;
@@ -1275,25 +1152,25 @@
  *                  failure.
  *
  ******************************************************************************/
-bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
+bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, bool is_direct,
                   tBT_TRANSPORT transport, bool opportunistic) {
   uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
   return GATT_Connect(gatt_if, bd_addr, is_direct, transport, opportunistic,
                       phy);
 }
 
-bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
+bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, bool is_direct,
                   tBT_TRANSPORT transport, bool opportunistic,
                   uint8_t initiating_phys) {
   tGATT_REG* p_reg;
   bool status = false;
 
-  GATT_TRACE_API("GATT_Connect gatt_if=%d", gatt_if);
+  LOG(INFO) << __func__ << "gatt_if=" << +gatt_if << " " << bd_addr;
 
   /* Make sure app is registered */
   p_reg = gatt_get_regcb(gatt_if);
   if (p_reg == NULL) {
-    GATT_TRACE_ERROR("GATT_Connect - gatt_if =%d is not registered", gatt_if);
+    LOG(ERROR) << "gatt_if = " << gatt_if << " is not registered";
     return (false);
   }
 
@@ -1304,7 +1181,7 @@
     if (transport == BT_TRANSPORT_LE)
       status = gatt_update_auto_connect_dev(gatt_if, true, bd_addr);
     else {
-      GATT_TRACE_ERROR("Unsupported transport for background connection");
+      LOG(ERROR) << "Unsupported transport for background connection";
     }
   }
 
@@ -1326,11 +1203,12 @@
  * Returns          true if the connection started; false otherwise.
  *
  ******************************************************************************/
-bool GATT_CancelConnect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct) {
-  GATT_TRACE_API("%s: gatt_if=%d", __func__, gatt_if);
+bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr,
+                        bool is_direct) {
+  LOG(INFO) << __func__ << ": gatt_if=" << +gatt_if;
 
   if (gatt_if && !gatt_get_regcb(gatt_if)) {
-    GATT_TRACE_ERROR("%s: gatt_if =%d is not registered", __func__, gatt_if);
+    LOG(ERROR) << "gatt_if =" << +gatt_if << " is not registered";
     return false;
   }
 
@@ -1339,11 +1217,11 @@
       return gatt_cancel_open(gatt_if, bd_addr);
     }
 
-    GATT_TRACE_DEBUG("%s: unconditional", __func__);
+    VLOG(1) << " unconditional";
     /* only LE connection can be cancelled */
     tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
     if (!p_tcb || p_tcb->app_hold_link.empty()) {
-      GATT_TRACE_ERROR("%s: no app found", __func__);
+      LOG(ERROR) << __func__ << " no app found";
       return false;
     }
 
@@ -1363,9 +1241,9 @@
   if (gatt_if) return gatt_remove_bg_dev_for_app(gatt_if, bd_addr);
 
   if (!gatt_clear_bg_dev_for_addr(bd_addr)) {
-    GATT_TRACE_ERROR(
-        "%s: no app associated with the bg device for unconditional removal",
-        __func__);
+    LOG(ERROR)
+        << __func__
+        << ": no app associated with the bg device for unconditional removal";
     return false;
   }
 
@@ -1390,7 +1268,7 @@
   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
   uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
 
-  GATT_TRACE_API("GATT_Disconnect conn_id=%d ", conn_id);
+  LOG(INFO) << __func__ << " conn_id=" << +conn_id;
 
   p_tcb = gatt_get_tcb_by_idx(tcb_idx);
 
@@ -1416,17 +1294,17 @@
  *
  ******************************************************************************/
 bool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if,
-                             BD_ADDR bd_addr, tBT_TRANSPORT* p_transport) {
+                             RawAddress& bd_addr, tBT_TRANSPORT* p_transport) {
   tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id);
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
   uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id);
   tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx);
   bool status = false;
 
-  GATT_TRACE_API("GATT_GetConnectionInfor conn_id=%d", conn_id);
+  VLOG(1) << __func__ << " conn_id=" << +conn_id;
 
   if (p_tcb && p_reg) {
-    memcpy(bd_addr, p_tcb->peer_bda, BD_ADDR_LEN);
+    bd_addr = p_tcb->peer_bda;
     *p_gatt_if = gatt_if;
     *p_transport = p_tcb->transport;
     status = true;
@@ -1449,7 +1327,7 @@
  * Returns          true the logical link is connected
  *
  ******************************************************************************/
-bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr,
+bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, const RawAddress& bd_addr,
                                uint16_t* p_conn_id, tBT_TRANSPORT transport) {
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
@@ -1460,6 +1338,6 @@
     status = true;
   }
 
-  GATT_TRACE_API("GATT_GetConnIdIfConnected status=%d", status);
+  VLOG(1) << __func__ << " status= " << +status;
   return status;
 }
diff --git a/stack/gatt/gatt_attr.cc b/stack/gatt/gatt_attr.cc
index 3730ee6..f4e028a 100644
--- a/stack/gatt/gatt_attr.cc
+++ b/stack/gatt/gatt_attr.cc
@@ -31,6 +31,8 @@
 #include "gatt_int.h"
 #include "osi/include/osi.h"
 
+using base::StringPrintf;
+
 #define GATTP_MAX_NUM_INC_SVR 0
 #define GATTP_MAX_CHAR_NUM 2
 #define GATTP_MAX_ATTR_NUM (GATTP_MAX_CHAR_NUM * 2 + GATTP_MAX_NUM_INC_SVR + 1)
@@ -44,9 +46,9 @@
 
 static void gatt_request_cback(uint16_t conn_id, uint32_t trans_id,
                                uint8_t op_code, tGATTS_DATA* p_data);
-static void gatt_connect_cback(UNUSED_ATTR tGATT_IF gatt_if, BD_ADDR bda,
-                               uint16_t conn_id, bool connected,
-                               tGATT_DISCONN_REASON reason,
+static void gatt_connect_cback(UNUSED_ATTR tGATT_IF gatt_if,
+                               const RawAddress& bda, uint16_t conn_id,
+                               bool connected, tGATT_DISCONN_REASON reason,
                                tBT_TRANSPORT transport);
 static void gatt_disc_res_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                                 tGATT_DISC_RES* p_data);
@@ -78,7 +80,7 @@
  * Returns          Connection ID
  *
  ******************************************************************************/
-uint16_t gatt_profile_find_conn_id_by_bd_addr(BD_ADDR remote_bda) {
+uint16_t gatt_profile_find_conn_id_by_bd_addr(const RawAddress& remote_bda) {
   uint16_t conn_id = GATT_INVALID_CONN_ID;
   GATT_GetConnIdIfConnected(gatt_cb.gatt_if, remote_bda, &conn_id,
                             BT_TRANSPORT_LE);
@@ -116,14 +118,14 @@
  *
  ******************************************************************************/
 static tGATT_PROFILE_CLCB* gatt_profile_find_clcb_by_bd_addr(
-    BD_ADDR bda, tBT_TRANSPORT transport) {
+    const RawAddress& bda, tBT_TRANSPORT transport) {
   uint8_t i_clcb;
   tGATT_PROFILE_CLCB* p_clcb = NULL;
 
   for (i_clcb = 0, p_clcb = gatt_cb.profile_clcb; i_clcb < GATT_MAX_APPS;
        i_clcb++, p_clcb++) {
     if (p_clcb->in_use && p_clcb->transport == transport && p_clcb->connected &&
-        !memcmp(p_clcb->bda, bda, BD_ADDR_LEN))
+        p_clcb->bda == bda)
       return p_clcb;
   }
 
@@ -141,7 +143,8 @@
  *                  block.
  *
  ******************************************************************************/
-tGATT_PROFILE_CLCB* gatt_profile_clcb_alloc(uint16_t conn_id, BD_ADDR bda,
+tGATT_PROFILE_CLCB* gatt_profile_clcb_alloc(uint16_t conn_id,
+                                            const RawAddress& bda,
                                             tBT_TRANSPORT tranport) {
   uint8_t i_clcb = 0;
   tGATT_PROFILE_CLCB* p_clcb = NULL;
@@ -153,7 +156,7 @@
       p_clcb->conn_id = conn_id;
       p_clcb->connected = true;
       p_clcb->transport = tranport;
-      memcpy(p_clcb->bda, bda, BD_ADDR_LEN);
+      p_clcb->bda = bda;
       break;
     }
   }
@@ -207,16 +210,17 @@
     case GATTS_REQ_TYPE_WRITE_EXEC:
     case GATT_CMD_WRITE:
       ignore = true;
-      GATT_TRACE_EVENT("Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD");
+      VLOG(1) << StringPrintf("Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD");
       break;
 
     case GATTS_REQ_TYPE_MTU:
-      GATT_TRACE_EVENT("Get MTU exchange new mtu size: %d", p_data->mtu);
+      VLOG(1) << StringPrintf("Get MTU exchange new mtu size: %d", p_data->mtu);
       ignore = true;
       break;
 
     default:
-      GATT_TRACE_EVENT("Unknown/unexpected LE GAP ATT request: 0x%02x", type);
+      VLOG(1) << StringPrintf("Unknown/unexpected LE GAP ATT request: 0x%02x",
+                              type);
       break;
   }
 
@@ -232,14 +236,13 @@
  * Returns          void
  *
  ******************************************************************************/
-static void gatt_connect_cback(UNUSED_ATTR tGATT_IF gatt_if, BD_ADDR bda,
-                               uint16_t conn_id, bool connected,
-                               tGATT_DISCONN_REASON reason,
+static void gatt_connect_cback(UNUSED_ATTR tGATT_IF gatt_if,
+                               const RawAddress& bda, uint16_t conn_id,
+                               bool connected, tGATT_DISCONN_REASON reason,
                                tBT_TRANSPORT transport) {
-  GATT_TRACE_EVENT("%s: from %08x%04x connected:%d conn_id=%d reason = 0x%04x",
-                   __func__,
-                   (bda[0] << 24) + (bda[1] << 16) + (bda[2] << 8) + bda[3],
-                   (bda[4] << 8) + bda[5], connected, conn_id, reason);
+  VLOG(1) << __func__ << ": from " << bda
+          << StringPrintf(" connected:%d conn_id=%d reason = 0x%04x", connected,
+                          conn_id, reason);
 
   tGATT_PROFILE_CLCB* p_clcb =
       gatt_profile_find_clcb_by_bd_addr(bda, transport);
@@ -295,7 +298,8 @@
   service_handle = service[0].attribute_handle;
   gatt_cb.handle_of_h_r = service[1].attribute_handle;
 
-  GATT_TRACE_ERROR("gatt_profile_db_init:  gatt_if=%d", gatt_cb.gatt_if);
+  LOG(ERROR) << StringPrintf("gatt_profile_db_init:  gatt_if=%d",
+                             gatt_cb.gatt_if);
 }
 
 /*******************************************************************************
@@ -353,8 +357,8 @@
     p_clcb->ccc_stage++;
     gatt_cl_start_config_ccc(p_clcb);
   } else {
-    GATT_TRACE_ERROR("%s() - Unable to register for service changed indication",
-                     __func__);
+    LOG(ERROR) << StringPrintf(
+        "%s() - Unable to register for service changed indication", __func__);
   }
 }
 
@@ -385,7 +389,7 @@
   tGATT_DISC_PARAM srvc_disc_param;
   tGATT_VALUE ccc_value;
 
-  GATT_TRACE_DEBUG("%s() - stage: %d", __func__, p_clcb->ccc_stage);
+  VLOG(1) << StringPrintf("%s() - stage: %d", __func__, p_clcb->ccc_stage);
 
   memset(&srvc_disc_param, 0, sizeof(tGATT_DISC_PARAM));
   memset(&ccc_value, 0, sizeof(tGATT_VALUE));
@@ -431,7 +435,7 @@
  * Returns          none
  *
  ******************************************************************************/
-void GATT_ConfigServiceChangeCCC(BD_ADDR remote_bda, bool enable,
+void GATT_ConfigServiceChangeCCC(const RawAddress& remote_bda, bool enable,
                                  tBT_TRANSPORT transport) {
   tGATT_PROFILE_CLCB* p_clcb =
       gatt_profile_find_clcb_by_bd_addr(remote_bda, transport);
diff --git a/stack/gatt/gatt_auth.cc b/stack/gatt/gatt_auth.cc
index ae7cb30..b91b56c 100644
--- a/stack/gatt/gatt_auth.cc
+++ b/stack/gatt/gatt_auth.cc
@@ -32,6 +32,8 @@
 #include "gatt_int.h"
 #include "osi/include/osi.h"
 
+using base::StringPrintf;
+
 /*******************************************************************************
  *
  * Function         gatt_sign_data
@@ -98,8 +100,8 @@
   uint32_t counter;
 
   if (p_buf->len < GATT_AUTH_SIGN_LEN + 4) {
-    GATT_TRACE_ERROR("%s: Data length %u less than expected %u", __func__,
-                     p_buf->len, GATT_AUTH_SIGN_LEN + 4);
+    LOG(ERROR) << StringPrintf("%s: Data length %u less than expected %u",
+                               __func__, p_buf->len, GATT_AUTH_SIGN_LEN + 4);
     return;
   }
   cmd_len = p_buf->len - GATT_AUTH_SIGN_LEN + 4;
@@ -108,7 +110,7 @@
 
   if (!BTM_BleVerifySignature(tcb.peer_bda, p_orig, cmd_len, counter, p)) {
     /* if this is a bad signature, assume from attacker, ignore it  */
-    GATT_TRACE_ERROR("Signature Verification Failed, data ignored");
+    LOG(ERROR) << StringPrintf("Signature Verification Failed, data ignored");
     return;
   }
 
@@ -148,19 +150,21 @@
  * Returns
  *
  ******************************************************************************/
-void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport,
+void gatt_enc_cmpl_cback(const RawAddress* bd_addr, tBT_TRANSPORT transport,
                          UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) {
-  GATT_TRACE_DEBUG("gatt_enc_cmpl_cback");
-  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
+  VLOG(1) << StringPrintf("gatt_enc_cmpl_cback");
+  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(*bd_addr, transport);
   if (!p_tcb) {
-    GATT_TRACE_ERROR("%s: enc callback for unknown bd_addr", __func__);
+    LOG(ERROR) << StringPrintf("%s: enc callback for unknown bd_addr",
+                               __func__);
     return;
   }
 
   if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) return;
 
   if (p_tcb->pending_enc_clcb.empty()) {
-    GATT_TRACE_ERROR("%s: no operation waiting for encrypting", __func__);
+    LOG(ERROR) << StringPrintf("%s: no operation waiting for encrypting",
+                               __func__);
     return;
   }
 
@@ -171,7 +175,7 @@
   if (result == BTM_SUCCESS) {
     if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM) {
       uint8_t sec_flag = 0;
-      BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);
+      BTM_GetSecurityFlagsByTransport(*bd_addr, &sec_flag, transport);
 
       if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED) {
         status = true;
@@ -201,10 +205,11 @@
  * Returns
  *
  ******************************************************************************/
-void gatt_notify_enc_cmpl(BD_ADDR bd_addr) {
+void gatt_notify_enc_cmpl(const RawAddress& bd_addr) {
   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
   if (!p_tcb) {
-    GATT_TRACE_DEBUG("notify GATT for encryption completion of unknown device");
+    VLOG(1) << StringPrintf(
+        "notify GATT for encryption completion of unknown device");
     return;
   }
 
@@ -356,7 +361,8 @@
       encrypt_status = GATT_ENCRYPED_MITM;
   }
 
-  GATT_TRACE_DEBUG("gatt_get_link_encrypt_status status=0x%x", encrypt_status);
+  VLOG(1) << StringPrintf("gatt_get_link_encrypt_status status=0x%x",
+                          encrypt_status);
   return encrypt_status;
 }
 
@@ -390,51 +396,44 @@
 
   return status;
 }
-/*******************************************************************************
- *
- * Function         gatt_check_enc_req
- *
- * Description      check link security.
- *
- * Returns          true if encrypted, otherwise false.
- *
- ******************************************************************************/
-bool gatt_security_check_start(tGATT_CLCB* p_clcb) {
+
+/** check link security */
+void gatt_security_check_start(tGATT_CLCB* p_clcb) {
   tGATT_TCB* p_tcb = p_clcb->p_tcb;
-  tGATT_SEC_ACTION gatt_sec_act;
-  tBTM_BLE_SEC_ACT btm_ble_sec_act;
-  bool status = true;
-  tBTM_STATUS btm_status;
   tGATT_SEC_ACTION sec_act_old = gatt_get_sec_act(p_tcb);
 
-  gatt_sec_act = gatt_determine_sec_act(p_clcb);
+  tGATT_SEC_ACTION gatt_sec_act = gatt_determine_sec_act(p_clcb);
 
   if (sec_act_old == GATT_SEC_NONE) gatt_set_sec_act(p_tcb, gatt_sec_act);
 
   switch (gatt_sec_act) {
     case GATT_SEC_SIGN_DATA:
-      GATT_TRACE_DEBUG("gatt_security_check_start: Do data signing");
+      VLOG(1) << StringPrintf("%s: Do data signing", __func__);
       gatt_sign_data(p_clcb);
       break;
     case GATT_SEC_ENCRYPT:
     case GATT_SEC_ENCRYPT_NO_MITM:
     case GATT_SEC_ENCRYPT_MITM:
       if (sec_act_old < GATT_SEC_ENCRYPT) {
-        GATT_TRACE_DEBUG(
-            "gatt_security_check_start: Encrypt now or key upgreade first");
+        VLOG(1) << StringPrintf("%s: Encrypt now or key upgreade first",
+                                __func__);
+        tBTM_BLE_SEC_ACT btm_ble_sec_act;
         gatt_convert_sec_action(gatt_sec_act, &btm_ble_sec_act);
-        btm_status =
+        tBTM_STATUS btm_status =
             BTM_SetEncryption(p_tcb->peer_bda, p_tcb->transport,
                               gatt_enc_cmpl_cback, NULL, btm_ble_sec_act);
         if ((btm_status != BTM_SUCCESS) && (btm_status != BTM_CMD_STARTED)) {
-          GATT_TRACE_ERROR(
-              "gatt_security_check_start BTM_SetEncryption failed "
-              "btm_status=%d",
+          LOG(ERROR) << StringPrintf(
+              "%s BTM_SetEncryption failed btm_status=%d", __func__,
               btm_status);
-          status = false;
+          gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
+          gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
+
+          gatt_end_operation(p_clcb, GATT_INSUF_ENCRYPTION, NULL);
+          return;
         }
       }
-      if (status) p_tcb->pending_enc_clcb.push(p_clcb);
+      p_tcb->pending_enc_clcb.push(p_clcb);
       break;
     case GATT_SEC_ENC_PENDING:
       p_tcb->pending_enc_clcb.push(p_clcb);
@@ -444,11 +443,4 @@
       gatt_sec_check_complete(true, p_clcb, gatt_sec_act);
       break;
   }
-
-  if (status == false) {
-    gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
-    gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
-  }
-
-  return status;
 }
diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc
index a3ed6dc..9e77e15 100644
--- a/stack/gatt/gatt_cl.cc
+++ b/stack/gatt/gatt_cl.cc
@@ -43,6 +43,7 @@
 #define GATT_MTU_RSP_MIN_LEN 2
 #define GATT_READ_BY_TYPE_RSP_MIN_LEN 1
 
+using base::StringPrintf;
 /*******************************************************************************
  *                      G L O B A L      G A T T       D A T A                 *
  ******************************************************************************/
@@ -161,8 +162,8 @@
         else
           p_clcb->first_read_blob_after_read = false;
 
-        GATT_TRACE_DEBUG("gatt_act_read first_read_blob_after_read=%d",
-                         p_clcb->first_read_blob_after_read);
+        VLOG(1) << __func__ << ": first_read_blob_after_read="
+                << p_clcb->first_read_blob_after_read;
         op_code = GATT_REQ_READ_BLOB;
         msg.read_blob.offset = offset;
         msg.read_blob.handle = p_clcb->s_handle;
@@ -188,7 +189,7 @@
       break;
 
     default:
-      GATT_TRACE_ERROR("Unknown read type: %d", p_clcb->op_subtype);
+      LOG(ERROR) << "Unknown read type:" << +p_clcb->op_subtype;
       break;
   }
 
@@ -199,61 +200,60 @@
   }
 }
 
-/*******************************************************************************
- *
- * Function         gatt_act_write
- *
- * Description      GATT write operation.
- *
- * Returns          void.
- *
- ******************************************************************************/
+/** GATT write operation */
 void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act) {
   tGATT_TCB& tcb = *p_clcb->p_tcb;
-  uint8_t rt = GATT_SUCCESS, op_code = 0;
-  tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
 
-  if (p_attr) {
-    switch (p_clcb->op_subtype) {
-      case GATT_WRITE_NO_RSP:
-        p_clcb->s_handle = p_attr->handle;
-        op_code = (sec_act == GATT_SEC_SIGN_DATA) ? GATT_SIGN_CMD_WRITE
-                                                  : GATT_CMD_WRITE;
-        rt = gatt_send_write_msg(tcb, p_clcb, op_code, p_attr->handle,
-                                 p_attr->len, 0, p_attr->value);
-        break;
+  CHECK(p_clcb->p_attr_buf);
+  tGATT_VALUE& attr = *((tGATT_VALUE*)p_clcb->p_attr_buf);
 
-      case GATT_WRITE:
-        if (p_attr->len <= (tcb.payload_size - GATT_HDR_SIZE)) {
-          p_clcb->s_handle = p_attr->handle;
-
-          rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_WRITE, p_attr->handle,
-                                   p_attr->len, 0, p_attr->value);
-        } else /* prepare write for long attribute */
-        {
-          gatt_send_prepare_write(tcb, p_clcb);
+  switch (p_clcb->op_subtype) {
+    case GATT_WRITE_NO_RSP: {
+      p_clcb->s_handle = attr.handle;
+      uint8_t op_code = (sec_act == GATT_SEC_SIGN_DATA) ? GATT_SIGN_CMD_WRITE
+                                                        : GATT_CMD_WRITE;
+      uint8_t rt = gatt_send_write_msg(tcb, p_clcb, op_code, attr.handle,
+                                       attr.len, 0, attr.value);
+      if (rt != GATT_CMD_STARTED) {
+        if (rt != GATT_SUCCESS) {
+          LOG(ERROR) << StringPrintf(
+              "gatt_act_write() failed op_code=0x%x rt=%d", op_code, rt);
         }
-        break;
+        gatt_end_operation(p_clcb, rt, NULL);
+      }
+      return;
+    }
 
-      case GATT_WRITE_PREPARE:
+    case GATT_WRITE: {
+      if (attr.len <= (tcb.payload_size - GATT_HDR_SIZE)) {
+        p_clcb->s_handle = attr.handle;
+
+        uint8_t rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_WRITE,
+                                         attr.handle, attr.len, 0, attr.value);
+        if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED &&
+            rt != GATT_CONGESTED) {
+          if (rt != GATT_SUCCESS) {
+            LOG(ERROR) << StringPrintf(
+                "gatt_act_write() failed op_code=0x%x rt=%d", GATT_REQ_WRITE,
+                rt);
+          }
+          gatt_end_operation(p_clcb, rt, NULL);
+        }
+
+      } else {
+        /* prepare write for long attribute */
         gatt_send_prepare_write(tcb, p_clcb);
-        break;
-
-      default:
-        rt = GATT_INTERNAL_ERROR;
-        GATT_TRACE_ERROR("Unknown write type: %d", p_clcb->op_subtype);
-        break;
+      }
+      return;
     }
-  } else
-    rt = GATT_INTERNAL_ERROR;
 
-  if ((rt != GATT_SUCCESS && rt != GATT_CMD_STARTED && rt != GATT_CONGESTED) ||
-      (rt != GATT_CMD_STARTED && p_clcb->op_subtype == GATT_WRITE_NO_RSP)) {
-    if (rt != GATT_SUCCESS) {
-      GATT_TRACE_ERROR("gatt_act_write() failed op_code=0x%x rt=%d", op_code,
-                       rt);
-    }
-    gatt_end_operation(p_clcb, rt, NULL);
+    case GATT_WRITE_PREPARE:
+      gatt_send_prepare_write(tcb, p_clcb);
+      return;
+
+    default:
+      CHECK(false) << "Unknown write type" << p_clcb->op_subtype;
+      return;
   }
 }
 /*******************************************************************************
@@ -269,9 +269,11 @@
                                   tGATT_EXEC_FLAG flag) {
   uint8_t rt;
 
-  GATT_TRACE_DEBUG("gatt_send_queue_write_cancel ");
+  VLOG(1) << __func__;
 
-  rt = attp_send_cl_msg(tcb, p_clcb, GATT_REQ_EXEC_WRITE, (tGATT_CL_MSG*)&flag);
+  tGATT_CL_MSG gatt_cl_msg;
+  gatt_cl_msg.exec_write = flag;
+  rt = attp_send_cl_msg(tcb, p_clcb, GATT_REQ_EXEC_WRITE, &gatt_cl_msg);
 
   if (rt != GATT_SUCCESS) {
     gatt_end_operation(p_clcb, rt, NULL);
@@ -292,7 +294,7 @@
   bool exec = false;
   tGATT_EXEC_FLAG flag = GATT_PREP_WRITE_EXEC;
 
-  GATT_TRACE_DEBUG("gatt_check_write_long_terminate ");
+  VLOG(1) << __func__;
   /* check the first write response status */
   if (p_rsp_value != NULL) {
     if (p_rsp_value->handle != p_attr->handle ||
@@ -316,23 +318,14 @@
   }
   return false;
 }
-/*******************************************************************************
- *
- * Function         gatt_send_prepare_write
- *
- * Description      Send prepare write.
- *
- * Returns          void.
- *
- ******************************************************************************/
+
+/** Send prepare write */
 void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb) {
   tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
-  uint16_t to_send, offset;
-  uint8_t rt = GATT_SUCCESS;
   uint8_t type = p_clcb->op_subtype;
 
-  GATT_TRACE_DEBUG("gatt_send_prepare_write type=0x%x", type);
-  to_send = p_attr->len - p_attr->offset;
+  VLOG(1) << __func__ << StringPrintf(" type=0x%x", type);
+  uint16_t to_send = p_attr->len - p_attr->offset;
 
   if (to_send > (tcb.payload_size -
                  GATT_WRITE_LONG_HDR_SIZE)) /* 2 = uint16_t offset bytes  */
@@ -340,22 +333,22 @@
 
   p_clcb->s_handle = p_attr->handle;
 
-  offset = p_attr->offset;
+  uint16_t offset = p_attr->offset;
   if (type == GATT_WRITE_PREPARE) {
     offset += p_clcb->start_offset;
   }
 
-  GATT_TRACE_DEBUG("offset =0x%x len=%d", offset, to_send);
+  VLOG(1) << StringPrintf("offset =0x%x len=%d", offset, to_send);
 
-  rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_PREPARE_WRITE, p_attr->handle,
-                           to_send,                         /* length */
-                           offset,                          /* used as offset */
-                           p_attr->value + p_attr->offset); /* data */
+  uint8_t rt = gatt_send_write_msg(tcb, p_clcb, GATT_REQ_PREPARE_WRITE,
+                                   p_attr->handle, to_send, /* length */
+                                   offset,                  /* used as offset */
+                                   p_attr->value + p_attr->offset); /* data */
 
   /* remember the write long attribute length */
   p_clcb->counter = to_send;
 
-  if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED) {
+  if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED && rt != GATT_CONGESTED) {
     gatt_end_operation(p_clcb, rt, NULL);
   }
 }
@@ -376,7 +369,7 @@
   tGATT_DISC_RES result;
   uint8_t* p = p_data;
 
-  GATT_TRACE_DEBUG("gatt_process_find_type_value_rsp ");
+  VLOG(1) << __func__;
   /* unexpected response */
   if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY ||
       p_clcb->op_subtype != GATT_DISC_SRVC_BY_UUID)
@@ -425,7 +418,7 @@
   uint8_t *p = p_data, uuid_len = 0, type;
 
   if (len < GATT_INFO_RSP_MIN_LEN) {
-    GATT_TRACE_ERROR("invalid Info Response PDU received, discard.");
+    LOG(ERROR) << "invalid Info Response PDU received, discard.";
     gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
     return;
   }
@@ -476,8 +469,8 @@
                               uint8_t reason) {
   tGATT_STATUS status = (tGATT_STATUS)reason;
 
-  GATT_TRACE_DEBUG("gatt_proc_disc_error_rsp reason: %02x cmd_code %04x",
-                   reason, opcode);
+  VLOG(1) << __func__
+          << StringPrintf("reason: %02x cmd_code %04x", reason, opcode);
 
   switch (opcode) {
     case GATT_REQ_READ_BY_GRP_TYPE:
@@ -486,11 +479,11 @@
     case GATT_REQ_FIND_INFO:
       if (reason == GATT_NOT_FOUND) {
         status = GATT_SUCCESS;
-        GATT_TRACE_DEBUG("Discovery completed");
+        VLOG(1) << "Discovery completed";
       }
       break;
     default:
-      GATT_TRACE_ERROR("Incorrect discovery opcode %04x", opcode);
+      LOG(ERROR) << StringPrintf("Incorrect discovery opcode %04x", opcode);
       break;
   }
 
@@ -514,11 +507,11 @@
   uint16_t handle;
   tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf;
 
-  GATT_TRACE_DEBUG("gatt_process_error_rsp ");
+  VLOG(1) << __func__;
 
   if (len < 4) {
     android_errorWriteLog(0x534e4554, "79591688");
-    GATT_TRACE_ERROR("Error response too short");
+    LOG(ERROR) << "Error response too short";
     // Specification does not clearly define what should happen if error
     // response is too short. General rule in BT Spec 5.0 Vol 3, Part F 3.4.1.1
     // is: "If an error code is received in the Error Response that is not
@@ -573,11 +566,11 @@
       .conn_id = p_clcb->conn_id, .auth_req = GATT_AUTH_REQ_NONE,
   };
 
-  GATT_TRACE_ERROR("value resp op_code = %s len = %d",
-                   gatt_dbg_op_name(op_code), len);
+  LOG(ERROR) << StringPrintf("value resp op_code = %s len = %d",
+                             gatt_dbg_op_name(op_code), len);
 
   if (len < GATT_PREP_WRITE_RSP_MIN_LEN) {
-    GATT_TRACE_ERROR("illegal prepare write response length, discard");
+    LOG(ERROR) << "illegal prepare write response length, discard";
     gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
     return;
   }
@@ -619,10 +612,10 @@
                                       ? GATTC_OPTYPE_NOTIFICATION
                                       : GATTC_OPTYPE_INDICATION;
 
-  GATT_TRACE_DEBUG("gatt_process_notification ");
+  VLOG(1) << __func__;
 
   if (len < GATT_NOTIFICATION_MIN_LEN) {
-    GATT_TRACE_ERROR("illegal notification PDU length, discard");
+    LOG(ERROR) << "illegal notification PDU length, discard";
     return;
   }
 
@@ -645,10 +638,8 @@
          For now, just log the error reset the counter.
          Later we need to disconnect the link unconditionally.
       */
-      GATT_TRACE_ERROR(
-          "gatt_process_notification rcv Ind. but ind_count=%d (will reset "
-          "ind_count)",
-          tcb.ind_count);
+      LOG(ERROR) << __func__ << " rcv Ind. but ind_count=" << tcb.ind_count
+                 << " (will reset ind_count)";
     }
     tcb.ind_count = 0;
   }
@@ -674,11 +665,13 @@
   }
 
   encrypt_status = gatt_get_link_encrypt_status(tcb);
+  tGATT_CL_COMPLETE gatt_cl_complete;
+  gatt_cl_complete.att_value = value;
   for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
     if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
       conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
       (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status,
-                                 (tGATT_CL_COMPLETE*)&value);
+                                 &gatt_cl_complete);
     }
   }
 }
@@ -708,8 +701,7 @@
     return;
 
   if (len < GATT_READ_BY_TYPE_RSP_MIN_LEN) {
-    GATT_TRACE_ERROR(
-        "Illegal ReadByType/ReadByGroupType Response length, discard");
+    LOG(ERROR) << "Illegal ReadByType/ReadByGroupType Response length, discard";
     gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL);
     return;
   }
@@ -720,10 +712,11 @@
     /* this is an error case that server's response containing a value length
        which is larger than MTU-2
        or value_len > message total length -1 */
-    GATT_TRACE_ERROR(
-        "gatt_process_read_by_type_rsp: Discard response op_code=%d "
-        "vale_len=%d > (MTU-2=%d or msg_len-1=%d)",
-        op_code, value_len, (tcb.payload_size - 2), (len - 1));
+    LOG(ERROR) << __func__
+               << StringPrintf(
+                      ": Discard response op_code=%d "
+                      "vale_len=%d > (MTU-2=%d or msg_len-1=%d)",
+                      op_code, value_len, (tcb.payload_size - 2), (len - 1));
     gatt_end_operation(p_clcb, GATT_ERROR, NULL);
     return;
   }
@@ -761,7 +754,7 @@
         record_value.group_value.e_handle = handle;
         if (!gatt_parse_uuid_from_cmd(&record_value.group_value.service_type,
                                       value_len, &p)) {
-          GATT_TRACE_ERROR("discover all service response parsing failure");
+          LOG(ERROR) << "discover all service response parsing failure";
           break;
         }
       }
@@ -792,10 +785,9 @@
         gatt_act_read(p_clcb, 0);
         return;
       } else {
-        GATT_TRACE_ERROR(
-            "gatt_process_read_by_type_rsp INCL_SRVC failed with invalid data "
-            "value_len=%d",
-            value_len);
+        LOG(ERROR) << __func__
+                   << ": INCL_SRVC failed with invalid data value_len="
+                   << +value_len;
         gatt_end_operation(p_clcb, GATT_INVALID_PDU, (void*)p);
         return;
       }
@@ -911,7 +903,7 @@
         if (len == (tcb.payload_size -
                     1) && /* full packet for read or read blob rsp */
             len + offset < GATT_MAX_ATTR_LEN) {
-          GATT_TRACE_DEBUG(
+          VLOG(1) << StringPrintf(
               "full pkt issue read blob for remianing bytes old offset=%d "
               "len=%d new offset=%d",
               offset, len, p_clcb->counter);
@@ -922,8 +914,8 @@
         }
       } else /* exception, should not happen */
       {
-        GATT_TRACE_ERROR("attr offset = %d p_attr_buf = %d ", offset,
-                         p_clcb->p_attr_buf);
+        LOG(ERROR) << "attr offset = " << +offset
+                   << " p_attr_buf = " << p_clcb->p_attr_buf;
         gatt_end_operation(p_clcb, GATT_NO_RESOURCES,
                            (void*)p_clcb->p_attr_buf);
       }
@@ -981,7 +973,7 @@
   tGATT_STATUS status = GATT_SUCCESS;
 
   if (len < GATT_MTU_RSP_MIN_LEN) {
-    GATT_TRACE_ERROR("invalid MTU response PDU received, discard.");
+    LOG(ERROR) << "invalid MTU response PDU received, discard.";
     status = GATT_INVALID_PDU;
   } else {
     STREAM_TO_UINT16(mtu, p_data);
@@ -1021,7 +1013,7 @@
 
     tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, cmd.p_cmd);
     if (att_ret != GATT_SUCCESS && att_ret != GATT_CONGESTED) {
-      GATT_TRACE_ERROR("%s: L2CAP sent error", __func__);
+      LOG(ERROR) << __func__ << ": L2CAP sent error";
       tcb.cl_cmd_q.pop();
       continue;
     }
@@ -1050,45 +1042,48 @@
   return false;
 }
 
-/*******************************************************************************
- *
- * Function         gatt_client_handle_server_rsp
- *
- * Description      This function is called to handle the server response to
- *                  client.
- *
- *
- * Returns          void
- *
- ******************************************************************************/
+/** This function is called to handle the server response to client */
 void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint8_t op_code,
                                    uint16_t len, uint8_t* p_data) {
-  tGATT_CLCB* p_clcb = NULL;
-
-  if (op_code != GATT_HANDLE_VALUE_IND && op_code != GATT_HANDLE_VALUE_NOTIF) {
-    uint8_t rsp_code;
-    p_clcb = gatt_cmd_dequeue(tcb, &rsp_code);
-
-    rsp_code = gatt_cmd_to_rsp_code(rsp_code);
-
-    if (p_clcb == NULL || (rsp_code != op_code && op_code != GATT_RSP_ERROR)) {
-      GATT_TRACE_WARNING(
-          "ATT - Ignore wrong response. Receives (%02x) Request(%02x) Ignored",
-          op_code, rsp_code);
+  if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF) {
+    if (len >= tcb.payload_size) {
+      LOG(ERROR) << StringPrintf(
+          "%s: invalid indicate pkt size: %d, PDU size: %d", __func__, len + 1,
+          tcb.payload_size);
       return;
     }
 
-    alarm_cancel(p_clcb->gatt_rsp_timer_ent);
-    p_clcb->retry_count = 0;
+    gatt_process_notification(tcb, op_code, len, p_data);
+    return;
   }
+
+  uint8_t cmd_code = 0;
+  tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, &cmd_code);
+  uint8_t rsp_code = gatt_cmd_to_rsp_code(cmd_code);
+  if (!p_clcb || (rsp_code != op_code && op_code != GATT_RSP_ERROR)) {
+    LOG(WARNING) << StringPrintf(
+        "ATT - Ignore wrong response. Receives (%02x) Request(%02x) Ignored",
+        op_code, rsp_code);
+    return;
+  }
+
+  if (!p_clcb->in_use) {
+    LOG(WARNING) << "ATT - clcb already not in use, ignoring response";
+    gatt_cl_send_next_cmd_inq(tcb);
+    return;
+  }
+
+  alarm_cancel(p_clcb->gatt_rsp_timer_ent);
+  p_clcb->retry_count = 0;
+
   /* the size of the message may not be bigger than the local max PDU size*/
   /* The message has to be smaller than the agreed MTU, len does not count
    * op_code */
   if (len >= tcb.payload_size) {
-    GATT_TRACE_ERROR("invalid response/indicate pkt size: %d, PDU size: %d",
-                     len + 1, tcb.payload_size);
-    if (op_code != GATT_HANDLE_VALUE_NOTIF && op_code != GATT_HANDLE_VALUE_IND)
-      gatt_end_operation(p_clcb, GATT_ERROR, NULL);
+    LOG(ERROR) << StringPrintf(
+        "%s: invalid response pkt size: %d, PDU size: %d", __func__, len + 1,
+        tcb.payload_size);
+    gatt_end_operation(p_clcb, GATT_ERROR, NULL);
   } else {
     switch (op_code) {
       case GATT_RSP_ERROR:
@@ -1130,20 +1125,11 @@
         gatt_end_operation(p_clcb, p_clcb->status, NULL);
         break;
 
-      case GATT_HANDLE_VALUE_NOTIF:
-      case GATT_HANDLE_VALUE_IND:
-        gatt_process_notification(tcb, op_code, len, p_data);
-        break;
-
       default:
-        GATT_TRACE_ERROR("Unknown opcode = %d", op_code);
+        LOG(ERROR) << __func__ << ": Unknown opcode = " << std::hex << op_code;
         break;
     }
   }
 
-  if (op_code != GATT_HANDLE_VALUE_IND && op_code != GATT_HANDLE_VALUE_NOTIF) {
-    gatt_cl_send_next_cmd_inq(tcb);
-  }
-
-  return;
+  gatt_cl_send_next_cmd_inq(tcb);
 }
diff --git a/stack/gatt/gatt_db.cc b/stack/gatt/gatt_db.cc
index 2819b0d..ac3d959 100644
--- a/stack/gatt/gatt_db.cc
+++ b/stack/gatt/gatt_db.cc
@@ -34,6 +34,7 @@
 #include "l2c_api.h"
 #include "osi/include/osi.h"
 
+using base::StringPrintf;
 /*******************************************************************************
  *             L O C A L    F U N C T I O N     P R O T O T Y P E S            *
  ******************************************************************************/
@@ -50,7 +51,8 @@
                            uint16_t s_hdl, uint16_t num_handle) {
   db.attr_list.reserve(num_handle);
 
-  GATT_TRACE_DEBUG("%s: s_hdl= %d num_handle= %d", __func__, s_hdl, num_handle);
+  VLOG(1) << StringPrintf("%s: s_hdl= %d num_handle= %d", __func__, s_hdl,
+                          num_handle);
 
   /* update service database information */
   db.next_handle = s_hdl;
@@ -66,7 +68,7 @@
 
 tBT_UUID* gatts_get_service_uuid(tGATT_SVC_DB* p_db) {
   if (!p_db || p_db->attr_list.empty()) {
-    GATT_TRACE_ERROR("service DB empty");
+    LOG(ERROR) << "service DB empty";
     return NULL;
   } else {
     return &p_db->attr_list[0].p_value->uuid;
@@ -88,32 +90,32 @@
   }
 
   if (!(perm & GATT_READ_ALLOWED)) {
-    GATT_TRACE_ERROR("%s: GATT_READ_NOT_PERMIT", __func__);
+    LOG(ERROR) << __func__ << ": GATT_READ_NOT_PERMIT";
     return GATT_READ_NOT_PERMIT;
   }
 
   if ((perm & GATT_READ_AUTH_REQUIRED) &&
       !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED) &&
       !(sec_flag & BTM_SEC_FLAG_ENCRYPTED)) {
-    GATT_TRACE_ERROR("%s: GATT_INSUF_AUTHENTICATION", __func__);
+    LOG(ERROR) << __func__ << ": GATT_INSUF_AUTHENTICATION";
     return GATT_INSUF_AUTHENTICATION;
   }
 
   if ((perm & GATT_READ_MITM_REQUIRED) &&
       !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) {
-    GATT_TRACE_ERROR("%s: GATT_INSUF_AUTHENTICATION: MITM Required", __func__);
+    LOG(ERROR) << __func__ << ": GATT_INSUF_AUTHENTICATION: MITM Required";
     return GATT_INSUF_AUTHENTICATION;
   }
 
   if ((perm & GATT_READ_ENCRYPTED_REQUIRED) &&
       !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
-    GATT_TRACE_ERROR("%s: GATT_INSUF_ENCRYPTION", __func__);
+    LOG(ERROR) << __func__ << ": GATT_INSUF_ENCRYPTION";
     return GATT_INSUF_ENCRYPTION;
   }
 
   if ((perm & GATT_READ_ENCRYPTED_REQUIRED) &&
       (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) {
-    GATT_TRACE_ERROR("%s: GATT_INSUF_KEY_SIZE", __func__);
+    LOG(ERROR) << __func__ << ": GATT_INSUF_KEY_SIZE";
     return GATT_INSUF_KEY_SIZE;
   }
 
@@ -127,7 +129,7 @@
       case GATT_UUID_CHAR_CLIENT_CONFIG:
       case GATT_UUID_CHAR_SRVR_CONFIG:
       case GATT_UUID_CHAR_PRESENT_FORMAT:
-        GATT_TRACE_ERROR("%s: GATT_NOT_LONG", __func__);
+        LOG(ERROR) << __func__ << ": GATT_NOT_LONG";
         return GATT_NOT_LONG;
 
       default:
@@ -163,9 +165,12 @@
   uint16_t len = 0, uuid16 = 0;
   uint8_t* p = *p_data;
 
-  GATT_TRACE_DEBUG(
-      "%s: uuid=0x%04x perm=0x%02x sec_flag=0x%x offset=%d read_long=%d",
-      __func__, attr16.uuid, attr16.permission, sec_flag, offset, read_long);
+  VLOG(1)
+      << __func__
+      << StringPrintf(
+             " uuid=0x%04x perm=0x%02x sec_flag=0x%x offset=%d read_long=%d",
+             attr16.uuid.uu.uuid16, attr16.permission, sec_flag, offset,
+             read_long);
 
   tGATT_STATUS status = gatts_check_attr_readability(attr16, offset, read_long,
                                                      sec_flag, key_size);
@@ -283,7 +288,7 @@
             p_rsp->len += (len + 2);
             *p_len -= (len + 2);
           } else {
-            GATT_TRACE_ERROR("format mismatch");
+            LOG(ERROR) << "format mismatch";
             status = GATT_NO_RESOURCES;
             break;
           }
@@ -326,11 +331,11 @@
                                     uint16_t e_handle, tBT_UUID service) {
   tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_INCLUDE_SERVICE}};
 
-  GATT_TRACE_DEBUG("%s: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x", __func__,
-                   s_handle, e_handle, service.uu.uuid16);
+  VLOG(1) << StringPrintf("%s: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x",
+                          __func__, s_handle, e_handle, service.uu.uuid16);
 
   if (service.len == 0 || s_handle == 0 || e_handle == 0) {
-    GATT_TRACE_ERROR("%s: Illegal Params.", __func__);
+    LOG(ERROR) << __func__ << ": Illegal Params.";
     return 0;
   }
 
@@ -364,7 +369,8 @@
                                   tBT_UUID& char_uuid) {
   tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
 
-  GATT_TRACE_DEBUG("%s: perm=0x%0x property=0x%0x", __func__, perm, property);
+  VLOG(1) << StringPrintf("%s: perm=0x%0x property=0x%0x", __func__, perm,
+                          property);
 
   tGATT_ATTR& char_decl = allocate_attr_in_db(db, uuid, GATT_PERM_READ);
   tGATT_ATTR& char_val = allocate_attr_in_db(db, char_uuid, perm);
@@ -432,7 +438,8 @@
  ******************************************************************************/
 uint16_t gatts_add_char_descr(tGATT_SVC_DB& db, tGATT_PERM perm,
                               tBT_UUID& descr_uuid) {
-  GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x", descr_uuid.uu.uuid16);
+  VLOG(1) << StringPrintf("gatts_add_char_descr uuid=0x%04x",
+                          descr_uuid.uu.uuid16);
 
   /* Add characteristic descriptors */
   tGATT_ATTR& char_dscptr = allocate_attr_in_db(db, descr_uuid, perm);
@@ -544,7 +551,7 @@
                                          uint8_t* p_data, uint16_t len,
                                          tGATT_SEC_FLAG sec_flag,
                                          uint8_t key_size) {
-  GATT_TRACE_DEBUG(
+  VLOG(1) << StringPrintf(
       "%s: op_code=0x%0x handle=0x%04x offset=%d len=%d sec_flag=0x%0x "
       "key_size=%d",
       __func__, op_code, handle, offset, len, sec_flag, key_size);
@@ -557,8 +564,8 @@
   if (min_key_size != 0) {
     min_key_size += 6;
   }
-  GATT_TRACE_DEBUG("%s: p_attr->permission =0x%04x min_key_size==0x%04x",
-                   __func__, p_attr->permission, min_key_size);
+  VLOG(1) << StringPrintf("%s: p_attr->permission =0x%04x min_key_size==0x%04x",
+                          __func__, p_attr->permission, min_key_size);
 
   if ((op_code == GATT_CMD_WRITE || op_code == GATT_REQ_WRITE) &&
       (perm & GATT_WRITE_SIGNED_PERM)) {
@@ -582,43 +589,43 @@
   tGATT_STATUS status = GATT_NOT_FOUND;
   if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM)) {
     status = GATT_WRITE_NOT_PERMIT;
-    GATT_TRACE_DEBUG("%s: sign cmd write not allowed", __func__);
+    VLOG(1) << __func__ << ": sign cmd write not allowed";
   }
   if ((op_code == GATT_SIGN_CMD_WRITE) &&
       (sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
     status = GATT_INVALID_PDU;
-    GATT_TRACE_ERROR("%s: Error!! sign cmd write sent on a encypted link",
-                     __func__);
+    LOG(ERROR) << __func__
+               << ": Error!! sign cmd write sent on a encypted link";
   } else if (!(perm & GATT_WRITE_ALLOWED)) {
     status = GATT_WRITE_NOT_PERMIT;
-    GATT_TRACE_ERROR("%s: GATT_WRITE_NOT_PERMIT", __func__);
+    LOG(ERROR) << __func__ << ": GATT_WRITE_NOT_PERMIT";
   }
   /* require authentication, but not been authenticated */
   else if ((perm & GATT_WRITE_AUTH_REQUIRED) &&
            !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED)) {
     status = GATT_INSUF_AUTHENTICATION;
-    GATT_TRACE_ERROR("%s: GATT_INSUF_AUTHENTICATION", __func__);
+    LOG(ERROR) << __func__ << ": GATT_INSUF_AUTHENTICATION";
   } else if ((perm & GATT_WRITE_MITM_REQUIRED) &&
              !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) {
     status = GATT_INSUF_AUTHENTICATION;
-    GATT_TRACE_ERROR("%s: GATT_INSUF_AUTHENTICATION: MITM required", __func__);
+    LOG(ERROR) << __func__ << ": GATT_INSUF_AUTHENTICATION: MITM required";
   } else if ((perm & GATT_WRITE_ENCRYPTED_PERM) &&
              !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) {
     status = GATT_INSUF_ENCRYPTION;
-    GATT_TRACE_ERROR("%s: GATT_INSUF_ENCRYPTION", __func__);
+    LOG(ERROR) << __func__ << ": GATT_INSUF_ENCRYPTION";
   } else if ((perm & GATT_WRITE_ENCRYPTED_PERM) &&
              (sec_flag & GATT_SEC_FLAG_ENCRYPTED) &&
              (key_size < min_key_size)) {
     status = GATT_INSUF_KEY_SIZE;
-    GATT_TRACE_ERROR("%s: GATT_INSUF_KEY_SIZE", __func__);
+    LOG(ERROR) << __func__ << ": GATT_INSUF_KEY_SIZE";
   }
   /* LE security mode 2 attribute  */
   else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE &&
            !(sec_flag & GATT_SEC_FLAG_ENCRYPTED) &&
            (perm & GATT_WRITE_ALLOWED) == 0) {
     status = GATT_INSUF_AUTHENTICATION;
-    GATT_TRACE_ERROR(
-        "%s: GATT_INSUF_AUTHENTICATION: LE security mode 2 required", __func__);
+    LOG(ERROR) << __func__
+               << ": GATT_INSUF_AUTHENTICATION: LE security mode 2 required";
   } else /* writable: must be char value declaration or char descritpors
             */
   {
@@ -661,11 +668,11 @@
           offset != 0) /* does not allow write blob */
       {
         status = GATT_NOT_LONG;
-        GATT_TRACE_ERROR("%s: GATT_NOT_LONG", __func__);
+        LOG(ERROR) << __func__ << ": GATT_NOT_LONG";
       } else if (len != max_size) /* data does not match the required format */
       {
         status = GATT_INVALID_ATTR_LEN;
-        GATT_TRACE_ERROR("%s: GATT_INVALID_PDU", __func__);
+        LOG(ERROR) << __func__ << ": GATT_INVALID_PDU";
       } else {
         status = GATT_SUCCESS;
       }
@@ -760,10 +767,9 @@
     } else if (gatt_type == BTGATT_DB_CHARACTERISTIC) {
       opcode = GATTS_REQ_TYPE_READ_CHARACTERISTIC;
     } else {
-      GATT_TRACE_ERROR(
-          "%s: Attempt to read attribute that's not tied with"
-          " characteristic or descriptor value.",
-          __func__);
+      LOG(ERROR) << __func__
+                 << ": Attempt to read attribute that's not tied with "
+                    "characteristic or descriptor value.";
       return GATT_ERROR;
     }
 
diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h
index bb9186f..cb0ad3e 100644
--- a/stack/gatt/gatt_int.h
+++ b/stack/gatt/gatt_int.h
@@ -21,12 +21,12 @@
 
 #include "bt_target.h"
 
-#include "bt_trace.h"
 #include "btm_ble_api.h"
 #include "btu.h"
 #include "gatt_api.h"
 #include "osi/include/fixed_queue.h"
 
+#include <base/strings/stringprintf.h>
 #include <string.h>
 #include <list>
 #include <unordered_set>
@@ -266,7 +266,7 @@
 typedef struct {
   std::queue<tGATT_CLCB*> pending_enc_clcb; /* pending encryption channel q */
   tGATT_SEC_ACTION sec_act;
-  BD_ADDR peer_bda;
+  RawAddress peer_bda;
   tBT_TRANSPORT transport;
   uint32_t trans_id;
 
@@ -333,7 +333,7 @@
 
 typedef struct {
   std::unordered_set<tGATT_IF> gatt_if;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
 } tGATT_BG_CONN_DEV;
 
 #define GATT_SVC_CHANGED_CONNECTING 1     /* wait for connection */
@@ -346,7 +346,7 @@
   uint16_t conn_id;
   bool in_use;
   bool connected;
-  BD_ADDR bda;
+  RawAddress bda;
   tBT_TRANSPORT transport;
 
   /* GATT service change CCC related variables */
@@ -370,7 +370,6 @@
   fixed_queue_t* srv_chg_clt_q; /* service change clients queue */
   tGATT_REG cl_rcb[GATT_MAX_APPS];
   tGATT_CLCB clcb[GATT_CL_MAX_LCB]; /* connection link control block*/
-  uint8_t trace_level;
   uint16_t def_mtu_size;
 
 #if (GATT_CONFORMANCE_TESTING == TRUE)
@@ -402,10 +401,10 @@
 
 /* from gatt_main.cc */
 extern bool gatt_disconnect(tGATT_TCB* p_tcb);
-extern bool gatt_act_connect(tGATT_REG* p_reg, BD_ADDR bd_addr,
+extern bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr,
                              tBT_TRANSPORT transport, bool opportunistic,
                              int8_t initiating_phys);
-extern bool gatt_connect(BD_ADDR rem_bda, tGATT_TCB* p_tcb,
+extern bool gatt_connect(const RawAddress& rem_bda, tGATT_TCB* p_tcb,
                          tBT_TRANSPORT transport, uint8_t initiating_phys);
 extern void gatt_data_process(tGATT_TCB& p_tcb, BT_HDR* p_buf);
 extern void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
@@ -416,12 +415,12 @@
 extern tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb);
 extern void gatt_init_srv_chg(void);
 extern void gatt_proc_srv_chg(void);
-extern void gatt_send_srv_chg_ind(BD_ADDR peer_bda);
+extern void gatt_send_srv_chg_ind(const RawAddress& peer_bda);
 extern void gatt_chk_srv_chg(tGATTS_SRV_CHG* p_srv_chg_clt);
-extern void gatt_add_a_bonded_dev_for_srv_chg(BD_ADDR bda);
+extern void gatt_add_a_bonded_dev_for_srv_chg(const RawAddress& bda);
 
 /* from gatt_attr.cc */
-extern uint16_t gatt_profile_find_conn_id_by_bd_addr(BD_ADDR bda);
+extern uint16_t gatt_profile_find_conn_id_by_bd_addr(const RawAddress& bda);
 
 /* Functions provided by att_protocol.cc */
 extern tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
@@ -441,8 +440,9 @@
 extern bool gatt_uuid_compare(tBT_UUID src, tBT_UUID tar);
 extern void gatt_convert_uuid32_to_uuid128(uint8_t uuid_128[LEN_UUID_128],
                                            uint32_t uuid_32);
-extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport,
-                                 uint8_t* p_sec_flag, uint8_t* p_key_size);
+extern void gatt_sr_get_sec_info(const RawAddress& rem_bda,
+                                 tBT_TRANSPORT transport, uint8_t* p_sec_flag,
+                                 uint8_t* p_key_size);
 extern void gatt_start_rsp_timer(tGATT_CLCB* p_clcb);
 extern void gatt_start_conf_timer(tGATT_TCB* p_tcb);
 extern void gatt_rsp_timeout(void* data);
@@ -455,13 +455,14 @@
 extern void gatt_dbg_display_uuid(tBT_UUID bt_uuid);
 
 extern bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb);
-extern tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(BD_ADDR bda);
+extern tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(
+    const RawAddress& bda);
 
-extern bool gatt_find_the_connected_bda(uint8_t start_idx, BD_ADDR bda,
+extern bool gatt_find_the_connected_bda(uint8_t start_idx, RawAddress& bda,
                                         uint8_t* p_found_idx,
                                         tBT_TRANSPORT* p_transport);
 extern void gatt_set_srv_chg(void);
-extern void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr);
+extern void gatt_delete_dev_from_srv_chg_clt_list(const RawAddress& bd_addr);
 extern tGATT_VALUE* gatt_add_pending_ind(tGATT_TCB* p_tcb, tGATT_VALUE* p_ind);
 extern void gatt_free_srvc_db_buffer_app_id(tBT_UUID* p_app_id);
 extern bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb);
@@ -474,11 +475,12 @@
 
 /* for background connection */
 extern bool gatt_update_auto_connect_dev(tGATT_IF gatt_if, bool add,
-                                         BD_ADDR bd_addr);
+                                         const RawAddress& bd_addr);
 extern bool gatt_is_bg_dev_for_app(tGATT_BG_CONN_DEV* p_dev, tGATT_IF gatt_if);
-extern bool gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr);
-extern uint8_t gatt_clear_bg_dev_for_addr(BD_ADDR bd_addr);
-extern tGATT_BG_CONN_DEV* gatt_find_bg_dev(BD_ADDR remote_bda);
+extern bool gatt_remove_bg_dev_for_app(tGATT_IF gatt_if,
+                                       const RawAddress& bd_addr);
+extern uint8_t gatt_clear_bg_dev_for_addr(const RawAddress& bd_addr);
+extern tGATT_BG_CONN_DEV* gatt_find_bg_dev(const RawAddress& remote_bda);
 extern void gatt_deregister_bgdev_list(tGATT_IF gatt_if);
 
 /* server function */
@@ -497,7 +499,7 @@
                                       uint8_t op_code, tGATTS_DATA* p_req_data);
 extern uint32_t gatt_sr_enqueue_cmd(tGATT_TCB& tcb, uint8_t op_code,
                                     uint16_t handle);
-extern bool gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda);
+extern bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda);
 extern void gatt_notify_phy_updated(tGATT_TCB* p_tcb, uint8_t tx_phy,
                                     uint8_t rx_phy, uint8_t status);
 
@@ -518,13 +520,15 @@
 extern void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if,
                                     bool is_inc, bool is_reset_first);
 
-extern uint8_t gatt_num_clcb_by_bd_addr(BD_ADDR bda);
+extern uint8_t gatt_num_clcb_by_bd_addr(const RawAddress& bda);
 extern tGATT_TCB* gatt_find_tcb_by_cid(uint16_t lcid);
-extern tGATT_TCB* gatt_allocate_tcb_by_bdaddr(BD_ADDR bda,
+extern tGATT_TCB* gatt_allocate_tcb_by_bdaddr(const RawAddress& bda,
                                               tBT_TRANSPORT transport);
 extern tGATT_TCB* gatt_get_tcb_by_idx(uint8_t tcb_idx);
-extern tGATT_TCB* gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport);
-extern bool gatt_send_ble_burst_data(BD_ADDR remote_bda, BT_HDR* p_buf);
+extern tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda,
+                                        tBT_TRANSPORT transport);
+extern bool gatt_send_ble_burst_data(const RawAddress& remote_bda,
+                                     BT_HDR* p_buf);
 
 /* GATT client functions */
 extern void gatt_dequeue_sr_cmd(tGATT_TCB& tcb);
@@ -532,7 +536,7 @@
                                    uint8_t op_code, uint16_t handle,
                                    uint16_t len, uint16_t offset,
                                    uint8_t* p_data);
-extern void gatt_cleanup_upon_disc(BD_ADDR bda, uint16_t reason,
+extern void gatt_cleanup_upon_disc(const RawAddress& bda, uint16_t reason,
                                    tBT_TRANSPORT transport);
 extern void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status,
                                void* p_data);
@@ -549,9 +553,8 @@
                                          tGATT_EXEC_FLAG flag);
 
 /* gatt_auth.cc */
-extern bool gatt_security_check_start(tGATT_CLCB* p_clcb);
+extern void gatt_security_check_start(tGATT_CLCB* p_clcb);
 extern void gatt_verify_signature(tGATT_TCB& tcb, BT_HDR* p_buf);
-extern tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB* p_clcb);
 extern tGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB& tcb);
 extern tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB* p_tcb);
 extern void gatt_set_sec_act(tGATT_TCB* p_tcb, tGATT_SEC_ACTION sec_act);
diff --git a/stack/gatt/gatt_main.cc b/stack/gatt/gatt_main.cc
index 3f5e639..3556b43 100644
--- a/stack/gatt/gatt_main.cc
+++ b/stack/gatt/gatt_main.cc
@@ -34,6 +34,8 @@
 #include "l2c_api.h"
 #include "osi/include/osi.h"
 
+using base::StringPrintf;
+
 /* Configuration flags. */
 #define GATT_L2C_CFG_IND_DONE (1 << 0)
 #define GATT_L2C_CFG_CFM_DONE (1 << 1)
@@ -45,14 +47,16 @@
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
-static void gatt_le_connect_cback(uint16_t chan, BD_ADDR bd_addr,
+static void gatt_le_connect_cback(uint16_t chan, const RawAddress& bd_addr,
                                   bool connected, uint16_t reason,
                                   tBT_TRANSPORT transport);
-static void gatt_le_data_ind(uint16_t chan, BD_ADDR bd_addr, BT_HDR* p_buf);
-static void gatt_le_cong_cback(BD_ADDR remote_bda, bool congest);
+static void gatt_le_data_ind(uint16_t chan, const RawAddress& bd_addr,
+                             BT_HDR* p_buf);
+static void gatt_le_cong_cback(const RawAddress& remote_bda, bool congest);
 
-static void gatt_l2cif_connect_ind_cback(BD_ADDR bd_addr, uint16_t l2cap_cid,
-                                         uint16_t psm, uint8_t l2cap_id);
+static void gatt_l2cif_connect_ind_cback(const RawAddress& bd_addr,
+                                         uint16_t l2cap_cid, uint16_t psm,
+                                         uint8_t l2cap_id);
 static void gatt_l2cif_connect_cfm_cback(uint16_t l2cap_cid, uint16_t result);
 static void gatt_l2cif_config_ind_cback(uint16_t l2cap_cid,
                                         tL2CAP_CFG_INFO* p_cfg);
@@ -93,16 +97,11 @@
 void gatt_init(void) {
   tL2CAP_FIXED_CHNL_REG fixed_reg;
 
-  GATT_TRACE_DEBUG("gatt_init()");
+  VLOG(1) << __func__;
 
   gatt_cb = tGATT_CB();
   memset(&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));
 
-#if defined(GATT_INITIAL_TRACE_LEVEL)
-  gatt_cb.trace_level = GATT_INITIAL_TRACE_LEVEL;
-#else
-  gatt_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
-#endif
   gatt_cb.def_mtu_size = GATT_DEF_BLE_MTU_SIZE;
   gatt_cb.sign_op_queue = fixed_queue_new(SIZE_MAX);
   gatt_cb.srv_chg_clt_q = fixed_queue_new(SIZE_MAX);
@@ -123,7 +122,7 @@
 
   /* Now, register with L2CAP for ATT PSM over BR/EDR */
   if (!L2CA_Register(BT_PSM_ATT, (tL2CAP_APPL_INFO*)&dyn_info)) {
-    GATT_TRACE_ERROR("ATT Dynamic Registration failed");
+    LOG(ERROR) << "ATT Dynamic Registration failed";
   }
 
   BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_ATT, BTM_SEC_NONE, BT_PSM_ATT,
@@ -151,7 +150,7 @@
  ******************************************************************************/
 void gatt_free(void) {
   int i;
-  GATT_TRACE_DEBUG("gatt_free()");
+  VLOG(1) << __func__;
 
   fixed_queue_free(gatt_cb.sign_op_queue, NULL);
   gatt_cb.sign_op_queue = NULL;
@@ -191,8 +190,8 @@
  * Returns          true if connection is started, otherwise return false.
  *
  ******************************************************************************/
-bool gatt_connect(BD_ADDR rem_bda, tGATT_TCB* p_tcb, tBT_TRANSPORT transport,
-                  uint8_t initiating_phys) {
+bool gatt_connect(const RawAddress& rem_bda, tGATT_TCB* p_tcb,
+                  tBT_TRANSPORT transport, uint8_t initiating_phys) {
   bool gatt_ret = false;
 
   if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
@@ -225,7 +224,7 @@
   bool ret = false;
   tGATT_CH_STATE ch_state;
 
-  GATT_TRACE_EVENT("%s", __func__);
+  VLOG(1) << __func__;
 
   if (p_tcb != NULL) {
     ret = true;
@@ -244,10 +243,10 @@
         if ((ch_state == GATT_CH_OPEN) || (ch_state == GATT_CH_CFG))
           ret = L2CA_DisconnectReq(p_tcb->att_lcid);
         else
-          GATT_TRACE_DEBUG("%s gatt_disconnect channel not opened", __func__);
+          VLOG(1) << __func__ << " gatt_disconnect channel not opened";
       }
     } else {
-      GATT_TRACE_DEBUG("%s already in closing state", __func__);
+      VLOG(1) << __func__ << " already in closing state";
     }
   }
 
@@ -268,25 +267,24 @@
                                       bool is_add) {
   auto& holders = p_tcb->app_hold_link;
 
+  VLOG(1) << __func__;
   if (is_add) {
     auto ret = holders.insert(gatt_if);
     if (ret.second) {
-      GATT_TRACE_DEBUG("%s: added gatt_if=%d", __func__, gatt_if);
+      VLOG(1) << "added gatt_if=" << +gatt_if;
     } else {
-      GATT_TRACE_DEBUG("%s: attempt to add already existing gatt_if=%d",
-                       __func__, gatt_if);
+      VLOG(1) << "attempt to add already existing gatt_if=" << +gatt_if;
     }
     return true;
   }
 
   //! is_add
   if (!holders.erase(gatt_if)) {
-    GATT_TRACE_DEBUG("%s: attempt to remove nonexisting gatt_if=%d", __func__,
-                     gatt_if);
+    VLOG(1) << "attempt to remove nonexisting gatt_if=" << +gatt_if;
     return false;
   }
 
-  GATT_TRACE_DEBUG("%s: removed gatt_if=%d", __func__, gatt_if);
+  VLOG(1) << "removed gatt_if=" << +gatt_if;
   return true;
 }
 
@@ -303,8 +301,8 @@
  ******************************************************************************/
 void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb,
                                    bool is_add, bool check_acl_link) {
-  GATT_TRACE_DEBUG("%s: is_add=%d chk_link=%d", __func__, is_add,
-                   check_acl_link);
+  VLOG(1) << StringPrintf("%s: is_add=%d chk_link=%d", __func__, is_add,
+                          check_acl_link);
 
   if (!p_tcb) return;
 
@@ -321,7 +319,7 @@
   }
 
   if (is_add) {
-    GATT_TRACE_DEBUG("%s: disable link idle timer", __func__);
+    VLOG(1) << "disable link idle timer";
     /* acl link is connected disable the idle timeout */
     GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT,
                         p_tcb->transport);
@@ -330,8 +328,8 @@
       /* acl link is connected but no application needs to use the link
          so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds
          */
-      GATT_TRACE_DEBUG("%s: start link idle timer =%d sec", __func__,
-                       GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
+      VLOG(1) << " start link idle timer = "
+              << GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP << " sec";
       GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP,
                           p_tcb->transport);
     }
@@ -347,7 +345,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-bool gatt_act_connect(tGATT_REG* p_reg, BD_ADDR bd_addr,
+bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr,
                       tBT_TRANSPORT transport, bool opportunistic,
                       int8_t initiating_phys) {
   bool ret = false;
@@ -372,14 +370,14 @@
     p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport);
     if (p_tcb != NULL) {
       if (!gatt_connect(bd_addr, p_tcb, transport, initiating_phys)) {
-        GATT_TRACE_ERROR("gatt_connect failed");
+        LOG(ERROR) << "gatt_connect failed";
         fixed_queue_free(p_tcb->pending_ind_q, NULL);
         *p_tcb = tGATT_TCB();
       } else
         ret = true;
     } else {
       ret = 0;
-      GATT_TRACE_ERROR("Max TCB for gatt_if [%d] reached.", p_reg->gatt_if);
+      LOG(ERROR) << "Max TCB for gatt_if [ " << +p_reg->gatt_if << "] reached.";
     }
   }
 
@@ -387,8 +385,8 @@
     if (!opportunistic)
       gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, false);
     else
-      GATT_TRACE_DEBUG(
-          "%s: connection is opportunistic, not updating app usage", __func__);
+      VLOG(1) << __func__
+              << ": connection is opportunistic, not updating app usage";
   }
 
   return ret;
@@ -403,7 +401,7 @@
  *                      connected (conn = true)/disconnected (conn = false).
  *
  ******************************************************************************/
-static void gatt_le_connect_cback(uint16_t chan, BD_ADDR bd_addr,
+static void gatt_le_connect_cback(uint16_t chan, const RawAddress& bd_addr,
                                   bool connected, uint16_t reason,
                                   tBT_TRANSPORT transport) {
   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
@@ -413,11 +411,8 @@
   /* ignore all fixed channel connect/disconnect on BR/EDR link for GATT */
   if (transport == BT_TRANSPORT_BR_EDR) return;
 
-  GATT_TRACE_DEBUG(
-      "GATT   ATT protocol channel with BDA: %08x%04x is %s",
-      (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
-      (bd_addr[4] << 8) + bd_addr[5],
-      (connected) ? "connected" : "disconnected");
+  VLOG(1) << "GATT   ATT protocol channel with BDA: " << bd_addr << " is "
+          << ((connected) ? "connected" : "disconnected");
 
   p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr);
   if (p_srv_chg_clt != NULL) {
@@ -456,12 +451,12 @@
           gatt_chk_srv_chg(p_srv_chg_clt);
         }
       } else {
-        GATT_TRACE_ERROR("CCB max out, no rsources");
+        LOG(ERROR) << "CCB max out, no rsources";
       }
     }
   } else {
     gatt_cleanup_upon_disc(bd_addr, reason, transport);
-    GATT_TRACE_DEBUG("ATT disconnected");
+    VLOG(1) << "ATT disconnected";
   }
 }
 
@@ -539,7 +534,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void gatt_le_cong_cback(BD_ADDR remote_bda, bool congested) {
+static void gatt_le_cong_cback(const RawAddress& remote_bda, bool congested) {
   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote_bda, BT_TRANSPORT_LE);
 
   /* if uncongested, check to see if there is any more pending data */
@@ -564,14 +559,15 @@
  * Returns          void
  *
  ******************************************************************************/
-static void gatt_le_data_ind(uint16_t chan, BD_ADDR bd_addr, BT_HDR* p_buf) {
+static void gatt_le_data_ind(uint16_t chan, const RawAddress& bd_addr,
+                             BT_HDR* p_buf) {
   tGATT_TCB* p_tcb;
 
   /* Find CCB based on bd addr */
   if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE)) != NULL) {
     if (gatt_get_ch_state(p_tcb) < GATT_CH_OPEN) {
-      GATT_TRACE_WARNING("ATT - Ignored L2CAP data while in state: %d",
-                         gatt_get_ch_state(p_tcb));
+      LOG(WARNING) << "ATT - Ignored L2CAP data while in state: "
+                   << +gatt_get_ch_state(p_tcb);
     } else
       gatt_data_process(*p_tcb, p_buf);
   }
@@ -590,14 +586,15 @@
  * Returns          void
  *
  ******************************************************************************/
-static void gatt_l2cif_connect_ind_cback(BD_ADDR bd_addr, uint16_t lcid,
+static void gatt_l2cif_connect_ind_cback(const RawAddress& bd_addr,
+                                         uint16_t lcid,
                                          UNUSED_ATTR uint16_t psm, uint8_t id) {
   /* do we already have a control channel for this peer? */
   uint8_t result = L2CAP_CONN_OK;
   tL2CAP_CFG_INFO cfg;
   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR);
 
-  GATT_TRACE_ERROR("Connection indication cid = %d", lcid);
+  LOG(ERROR) << "Connection indication cid = " << +lcid;
   /* new connection ? */
   if (p_tcb == NULL) {
     /* allocate tcb */
@@ -647,9 +644,9 @@
   /* look up clcb for this channel */
   p_tcb = gatt_find_tcb_by_cid(lcid);
   if (p_tcb != NULL) {
-    GATT_TRACE_DEBUG(
-        "gatt_l2c_connect_cfm_cback result: %d ch_state: %d, lcid:0x%x", result,
-        gatt_get_ch_state(p_tcb), p_tcb->att_lcid);
+    VLOG(1) << __func__
+            << StringPrintf(" result: %d ch_state: %d, lcid:0x%x", result,
+                            gatt_get_ch_state(p_tcb), p_tcb->att_lcid);
 
     /* if in correct state */
     if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN) {
@@ -948,7 +945,7 @@
   uint8_t op_code, pseudo_op_code;
 
   if (p_buf->len <= 0) {
-    GATT_TRACE_ERROR("invalid data length, ignore");
+    LOG(ERROR) << "invalid data length, ignore";
     return;
   }
 
@@ -959,7 +956,8 @@
   pseudo_op_code = op_code & (~GATT_WRITE_CMD_MASK);
 
   if (pseudo_op_code >= GATT_OP_CODE_MAX) {
-    GATT_TRACE_ERROR("ATT - Rcvd L2CAP data, unknown cmd: 0x%x", op_code);
+    LOG(ERROR) << "ATT - Rcvd L2CAP data, unknown cmd: 0x" << std::hex
+               << op_code;
     return;
   }
 
@@ -983,14 +981,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void gatt_add_a_bonded_dev_for_srv_chg(BD_ADDR bda) {
+void gatt_add_a_bonded_dev_for_srv_chg(const RawAddress& bda) {
   tGATTS_SRV_CHG_REQ req;
   tGATTS_SRV_CHG srv_chg_clt;
 
-  memcpy(srv_chg_clt.bda, bda, BD_ADDR_LEN);
+  srv_chg_clt.bda = bda;
   srv_chg_clt.srv_changed = false;
   if (gatt_add_srv_chg_clt(&srv_chg_clt) != NULL) {
-    memcpy(req.srv_chg.bda, bda, BD_ADDR_LEN);
+    req.srv_chg.bda = bda;
     req.srv_chg.srv_changed = false;
     if (gatt_cb.cb_info.p_srv_chg_callback)
       (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_ADD_CLIENT, &req,
@@ -1008,12 +1006,12 @@
  * Returns          void
  *
  ******************************************************************************/
-void gatt_send_srv_chg_ind(BD_ADDR peer_bda) {
+void gatt_send_srv_chg_ind(const RawAddress& peer_bda) {
   uint8_t handle_range[GATT_SIZE_OF_SRV_CHG_HNDL_RANGE];
   uint8_t* p = handle_range;
   uint16_t conn_id;
 
-  GATT_TRACE_DEBUG("gatt_send_srv_chg_ind");
+  VLOG(1) << "gatt_send_srv_chg_ind";
 
   if (gatt_cb.handle_of_h_r) {
     conn_id = gatt_profile_find_conn_id_by_bd_addr(peer_bda);
@@ -1024,10 +1022,7 @@
                                   GATT_SIZE_OF_SRV_CHG_HNDL_RANGE,
                                   handle_range);
     } else {
-      GATT_TRACE_ERROR("Unable to find conn_id for  %08x%04x ",
-                       (peer_bda[0] << 24) + (peer_bda[1] << 16) +
-                           (peer_bda[2] << 8) + peer_bda[3],
-                       (peer_bda[4] << 8) + peer_bda[5]);
+      LOG(ERROR) << "Unable to find conn_id for " << peer_bda;
     }
   }
 }
@@ -1043,8 +1038,7 @@
  *
  ******************************************************************************/
 void gatt_chk_srv_chg(tGATTS_SRV_CHG* p_srv_chg_clt) {
-  GATT_TRACE_DEBUG("gatt_chk_srv_chg srv_changed=%d",
-                   p_srv_chg_clt->srv_changed);
+  VLOG(1) << __func__ << " srv_changed=" << +p_srv_chg_clt->srv_changed;
 
   if (p_srv_chg_clt->srv_changed) {
     gatt_send_srv_chg_ind(p_srv_chg_clt->bda);
@@ -1068,14 +1062,13 @@
   uint8_t num_clients, i;
   tGATTS_SRV_CHG srv_chg_clt;
 
-  GATT_TRACE_DEBUG("gatt_init_srv_chg");
+  VLOG(1) << __func__;
   if (gatt_cb.cb_info.p_srv_chg_callback) {
     status = (*gatt_cb.cb_info.p_srv_chg_callback)(
         GATTS_SRV_CHG_CMD_READ_NUM_CLENTS, NULL, &rsp);
 
     if (status && rsp.num_clients) {
-      GATT_TRACE_DEBUG("gatt_init_srv_chg num_srv_chg_clt_clients=%d",
-                       rsp.num_clients);
+      VLOG(1) << "num_srv_chg_clt_clients=" << +rsp.num_clients;
       num_clients = rsp.num_clients;
       i = 1; /* use one based index */
       while ((i <= num_clients) && status) {
@@ -1085,7 +1078,7 @@
         if (status == true) {
           memcpy(&srv_chg_clt, &rsp.srv_chg, sizeof(tGATTS_SRV_CHG));
           if (gatt_add_srv_chg_clt(&srv_chg_clt) == NULL) {
-            GATT_TRACE_ERROR("Unable to add a service change client");
+            LOG(ERROR) << "Unable to add a service change client";
             status = false;
           }
         }
@@ -1093,7 +1086,7 @@
       }
     }
   } else {
-    GATT_TRACE_DEBUG("gatt_init_srv_chg callback not registered yet");
+    VLOG(1) << __func__ << " callback not registered yet";
   }
 }
 
@@ -1108,11 +1101,11 @@
  ******************************************************************************/
 void gatt_proc_srv_chg(void) {
   uint8_t start_idx, found_idx;
-  BD_ADDR bda;
+  RawAddress bda;
   tGATT_TCB* p_tcb;
   tBT_TRANSPORT transport;
 
-  GATT_TRACE_DEBUG("gatt_proc_srv_chg");
+  VLOG(1) << __func__;
 
   if (gatt_cb.cb_info.p_srv_chg_callback && gatt_cb.handle_of_h_r) {
     gatt_set_srv_chg();
@@ -1125,18 +1118,16 @@
 
       if (gatt_is_srv_chg_ind_pending(p_tcb)) {
         send_indication = false;
-        GATT_TRACE_DEBUG("discard srv chg - already has one in the queue");
+        VLOG(1) << "discard srv chg - already has one in the queue";
       }
 
       // Some LE GATT clients don't respond to service changed indications.
       char remote_name[BTM_MAX_REM_BD_NAME_LEN] = "";
-      bt_bdaddr_t bd_addr;
-      for (int i = 0; i < 6; i++) bd_addr.address[i] = bda[i];
       if (send_indication &&
-          btif_storage_get_stored_remote_name(bd_addr, remote_name)) {
+          btif_storage_get_stored_remote_name(bda, remote_name)) {
         if (interop_match_name(INTEROP_GATTC_NO_SERVICE_CHANGED_IND,
                                remote_name)) {
-          GATT_TRACE_DEBUG("discard srv chg - interop matched %s", remote_name);
+          VLOG(1) << "discard srv chg - interop matched " << remote_name;
           send_indication = false;
         }
       }
@@ -1159,8 +1150,7 @@
  ******************************************************************************/
 void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) {
   if (p_tcb) {
-    GATT_TRACE_DEBUG("gatt_set_ch_state: old=%d new=%d", p_tcb->ch_state,
-                     ch_state);
+    VLOG(1) << __func__ << ": old=" << +p_tcb->ch_state << " new=" << ch_state;
     p_tcb->ch_state = ch_state;
   }
 }
@@ -1177,7 +1167,7 @@
 tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) {
   tGATT_CH_STATE ch_state = GATT_CH_CLOSE;
   if (p_tcb) {
-    GATT_TRACE_DEBUG("gatt_get_ch_state: ch_state=%d", p_tcb->ch_state);
+    VLOG(1) << "gatt_get_ch_state: ch_state=" << +p_tcb->ch_state;
     ch_state = p_tcb->ch_state;
   }
   return ch_state;
diff --git a/stack/gatt/gatt_sr.cc b/stack/gatt/gatt_sr.cc
index 2b332d9..f9e8f53 100644
--- a/stack/gatt/gatt_sr.cc
+++ b/stack/gatt/gatt_sr.cc
@@ -22,6 +22,7 @@
  *
  ******************************************************************************/
 
+#include <log/log.h>
 #include "bt_target.h"
 #include "bt_utils.h"
 #include "osi/include/osi.h"
@@ -32,6 +33,7 @@
 #include "l2c_int.h"
 #define GATT_MTU_REQ_MIN_LEN 2
 
+using base::StringPrintf;
 /*******************************************************************************
  *
  * Function         gatt_sr_enqueue_cmd
@@ -87,9 +89,9 @@
  ******************************************************************************/
 void gatt_dequeue_sr_cmd(tGATT_TCB& tcb) {
   /* Double check in case any buffers are queued */
-  GATT_TRACE_DEBUG("gatt_dequeue_sr_cmd");
+  VLOG(1) << "gatt_dequeue_sr_cmd";
   if (tcb.sr_cmd.p_rsp_msg)
-    GATT_TRACE_ERROR("free tcb.sr_cmd.p_rsp_msg = %d", tcb.sr_cmd.p_rsp_msg);
+    LOG(ERROR) << "free tcb.sr_cmd.p_rsp_msg = " << tcb.sr_cmd.p_rsp_msg;
   osi_free_and_reset((void**)&tcb.sr_cmd.p_rsp_msg);
 
   while (!fixed_queue_is_empty(tcb.sr_cmd.multi_rsp_q))
@@ -113,7 +115,7 @@
   uint8_t* p;
   bool is_overflow = false;
 
-  GATT_TRACE_DEBUG("%s status=%d mtu=%d", __func__, status, mtu);
+  VLOG(1) << StringPrintf("%s status=%d mtu=%d", __func__, status, mtu);
 
   if (p_cmd->multi_rsp_q == NULL)
     p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX);
@@ -125,9 +127,8 @@
 
   p_cmd->status = status;
   if (status == GATT_SUCCESS) {
-    GATT_TRACE_DEBUG("Multi read count=%d num_hdls=%d",
-                     fixed_queue_length(p_cmd->multi_rsp_q),
-                     p_cmd->multi_req.num_handles);
+    VLOG(1) << "Multi read count=" << fixed_queue_length(p_cmd->multi_rsp_q)
+            << " num_hdls=" << p_cmd->multi_req.num_handles;
     /* Wait till we get all the responses */
     if (fixed_queue_length(p_cmd->multi_rsp_q) ==
         p_cmd->multi_req.num_handles) {
@@ -164,8 +165,9 @@
             /* just send the partial response for the overflow case */
             len = p_rsp->attr_value.len - (total_len - mtu);
             is_overflow = true;
-            GATT_TRACE_DEBUG("multi read overflow available len=%d val_len=%d",
-                             len, p_rsp->attr_value.len);
+            VLOG(1) << StringPrintf(
+                "multi read overflow available len=%d val_len=%d", len,
+                p_rsp->attr_value.len);
           } else {
             len = p_rsp->attr_value.len;
           }
@@ -190,10 +192,10 @@
 
       /* Sanity check on the buffer length */
       if (p_buf->len == 0) {
-        GATT_TRACE_ERROR("process_read_multi_rsp - nothing found!!");
+        LOG(ERROR) << __func__ << " nothing found!!";
         p_cmd->status = GATT_NOT_FOUND;
         osi_free(p_buf);
-        GATT_TRACE_DEBUG("osi_free(p_buf)");
+        VLOG(1) << __func__ << "osi_free(p_buf)";
       } else if (p_cmd->p_rsp_msg != NULL) {
         osi_free(p_buf);
       } else {
@@ -227,7 +229,7 @@
                                      tGATTS_RSP* p_msg) {
   tGATT_STATUS ret_code = GATT_SUCCESS;
 
-  GATT_TRACE_DEBUG("%s gatt_if=%d", __func__, gatt_if);
+  VLOG(1) << __func__ << " gatt_if=" << +gatt_if;
 
   gatt_sr_update_cback_cnt(tcb, gatt_if, false, false);
 
@@ -249,7 +251,7 @@
         tcb.sr_cmd.p_rsp_msg = attp_build_sr_msg(tcb, (uint8_t)(op_code + 1),
                                                  (tGATT_SR_MSG*)p_msg);
       } else {
-        GATT_TRACE_ERROR("Exception!!! already has respond message");
+        LOG(ERROR) << "Exception!!! already has respond message";
       }
     }
   }
@@ -265,7 +267,7 @@
     gatt_dequeue_sr_cmd(tcb);
   }
 
-  GATT_TRACE_DEBUG("%s ret_code=%d", __func__, ret_code);
+  VLOG(1) << __func__ << " ret_code=" << +ret_code;
 
   return ret_code;
 }
@@ -280,8 +282,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void gatt_process_exec_write_req(tGATT_TCB& tcb, uint8_t op_code,
-                                 UNUSED_ATTR uint16_t len, uint8_t* p_data) {
+void gatt_process_exec_write_req(tGATT_TCB& tcb, uint8_t op_code, uint16_t len,
+                                 uint8_t* p_data) {
   uint8_t *p = p_data, flag, i = 0;
   uint32_t trans_id = 0;
   tGATT_IF gatt_if;
@@ -289,9 +291,9 @@
 
 #if (GATT_CONFORMANCE_TESTING == TRUE)
   if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
-    GATT_TRACE_DEBUG(
-        "Conformance tst: forced err rspv for Execute Write: error status=%d",
-        gatt_cb.err_status);
+    VLOG(1)
+        << "Conformance tst: forced err rspv for Execute Write: error status="
+        << +gatt_cb.err_status;
 
     gatt_send_error_rsp(tcb, gatt_cb.err_status, gatt_cb.req_op_code,
                         gatt_cb.handle, false);
@@ -300,6 +302,13 @@
   }
 #endif
 
+  if (len < sizeof(flag)) {
+    android_errorWriteLog(0x534e4554, "73172115");
+    LOG(ERROR) << __func__ << "invalid length";
+    gatt_send_error_rsp(tcb, GATT_INVALID_PDU, GATT_REQ_EXEC_WRITE, 0, false);
+    return;
+  }
+
   STREAM_TO_UINT8(flag, p);
 
   /* mask the flag */
@@ -314,14 +323,16 @@
       if (tcb.prep_cnt[i]) {
         gatt_if = (tGATT_IF)(i + 1);
         conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, gatt_if);
+        tGATTS_DATA gatts_data;
+        gatts_data.exec_write = flag;
         gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_WRITE_EXEC,
-                                  (tGATTS_DATA*)&flag);
+                                  &gatts_data);
         tcb.prep_cnt[i] = 0;
       }
     }
   } else /* nothing needs to be executed , send response now */
   {
-    GATT_TRACE_ERROR("gatt_process_exec_write_req: no prepare write pending");
+    LOG(ERROR) << "gatt_process_exec_write_req: no prepare write pending";
     gatt_send_error_rsp(tcb, GATT_ERROR, GATT_REQ_EXEC_WRITE, 0, false);
   }
 }
@@ -344,16 +355,15 @@
   tGATT_STATUS err = GATT_SUCCESS;
   uint8_t sec_flag, key_size;
 
-  GATT_TRACE_DEBUG("gatt_process_read_multi_req");
+  VLOG(1) << __func__;
   tcb.sr_cmd.multi_req.num_handles = 0;
 
   gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
 
 #if (GATT_CONFORMANCE_TESTING == TRUE)
   if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
-    GATT_TRACE_DEBUG(
-        "Conformance tst: forced err rspvofr ReadMultiple: error status=%d",
-        gatt_cb.err_status);
+    VLOG(1) << "Conformance tst: forced err rspvofr ReadMultiple: error status="
+            << +gatt_cb.err_status;
 
     STREAM_TO_UINT16(handle, p);
 
@@ -376,7 +386,7 @@
       err = gatts_read_attr_perm_check(it->p_db, false, handle, sec_flag,
                                        key_size);
       if (err != GATT_SUCCESS) {
-        GATT_TRACE_DEBUG("read permission denied : 0x%02x", err);
+        VLOG(1) << StringPrintf("read permission denied : 0x%02x", err);
         break;
       }
     } else {
@@ -388,7 +398,7 @@
   }
 
   if (ll != 0) {
-    GATT_TRACE_ERROR("max attribute handle reached in ReadMultiple Request.");
+    LOG(ERROR) << "max attribute handle reached in ReadMultiple Request.";
   }
 
   if (tcb.sr_cmd.multi_req.num_handles == 0) err = GATT_INVALID_HANDLE;
@@ -473,7 +483,7 @@
 
             if (gatt_cb.last_primary_s_handle &&
                 gatt_cb.last_primary_s_handle == el.s_hdl) {
-              GATT_TRACE_DEBUG("Use 0xFFFF for the last primary attribute");
+              VLOG(1) << "Use 0xFFFF for the last primary attribute";
               /* see GATT ERRATA 4065, 4063, ATT ERRATA 4062 */
               UINT16_TO_STREAM(p, 0xFFFF);
             } else {
@@ -503,119 +513,89 @@
  *                  false: packet full, or format mismatch.
  */
 static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SRV_LIST_ELEM& el,
-                                             BT_HDR* p_msg, uint16_t* p_len,
+                                             BT_HDR* p_msg, uint16_t& len,
                                              uint16_t s_hdl, uint16_t e_hdl) {
-  tGATT_STATUS status = GATT_NOT_FOUND;
-  uint8_t* p;
-  uint16_t len = *p_len;
   uint8_t info_pair_len[2] = {4, 18};
 
-  if (!el.p_db) return status;
+  if (!el.p_db) return GATT_NOT_FOUND;
 
   /* check the attribute database */
 
-  p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET + p_msg->len;
+  uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET + p_msg->len;
 
   for (auto& attr : el.p_db->attr_list) {
-    if (attr.handle > e_hdl) {
-      break;
+    if (attr.handle > e_hdl) break;
+
+    if (attr.handle < s_hdl) continue;
+
+    if (p_msg->offset == 0)
+      p_msg->offset = (attr.uuid.len == LEN_UUID_16) ? GATT_INFO_TYPE_PAIR_16
+                                                     : GATT_INFO_TYPE_PAIR_128;
+
+    if (len < info_pair_len[p_msg->offset - 1]) return GATT_NO_RESOURCES;
+
+    if (p_msg->offset == GATT_INFO_TYPE_PAIR_16 &&
+        attr.uuid.len == LEN_UUID_16) {
+      UINT16_TO_STREAM(p, attr.handle);
+      UINT16_TO_STREAM(p, attr.uuid.uu.uuid16);
+    } else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 &&
+               attr.uuid.len == LEN_UUID_128) {
+      UINT16_TO_STREAM(p, attr.handle);
+      ARRAY_TO_STREAM(p, attr.uuid.uu.uuid128, LEN_UUID_128);
+    } else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 &&
+               attr.uuid.len == LEN_UUID_32) {
+      UINT16_TO_STREAM(p, attr.handle);
+      gatt_convert_uuid32_to_uuid128(p, attr.uuid.uu.uuid32);
+      p += LEN_UUID_128;
+    } else {
+      LOG(ERROR) << "format mismatch";
+      return GATT_NO_RESOURCES;
+      /* format mismatch */
     }
-
-    if (attr.handle >= s_hdl) {
-      if (p_msg->offset == 0)
-        p_msg->offset = (attr.uuid.len == LEN_UUID_16)
-                            ? GATT_INFO_TYPE_PAIR_16
-                            : GATT_INFO_TYPE_PAIR_128;
-
-      if (len >= info_pair_len[p_msg->offset - 1]) {
-        if (p_msg->offset == GATT_INFO_TYPE_PAIR_16 &&
-            attr.uuid.len == LEN_UUID_16) {
-          UINT16_TO_STREAM(p, attr.handle);
-          UINT16_TO_STREAM(p, attr.uuid.uu.uuid16);
-        } else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 &&
-                   attr.uuid.len == LEN_UUID_128) {
-          UINT16_TO_STREAM(p, attr.handle);
-          ARRAY_TO_STREAM(p, attr.uuid.uu.uuid128, LEN_UUID_128);
-        } else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 &&
-                   attr.uuid.len == LEN_UUID_32) {
-          UINT16_TO_STREAM(p, attr.handle);
-          gatt_convert_uuid32_to_uuid128(p, attr.uuid.uu.uuid32);
-          p += LEN_UUID_128;
-        } else {
-          GATT_TRACE_ERROR("format mismatch");
-          status = GATT_NO_RESOURCES;
-          break;
-          /* format mismatch */
-        }
-        p_msg->len += info_pair_len[p_msg->offset - 1];
-        len -= info_pair_len[p_msg->offset - 1];
-        status = GATT_SUCCESS;
-
-      } else {
-        status = GATT_NO_RESOURCES;
-        break;
-      }
-    }
+    p_msg->len += info_pair_len[p_msg->offset - 1];
+    len -= info_pair_len[p_msg->offset - 1];
+    return GATT_SUCCESS;
   }
 
-  *p_len = len;
-  return status;
+  return GATT_NOT_FOUND;
 }
 
-/*******************************************************************************
- *
- * Function         gatts_internal_read_by_type_req
- *
- * Description      Check to see if the ReadByType request can be handled
- *                  internally.
- *
- * Returns          void
- *
- ******************************************************************************/
-static tGATT_STATUS gatts_validate_packet_format(
-    uint8_t op_code, uint16_t* p_len, uint8_t** p_data, tBT_UUID* p_uuid_filter,
-    uint16_t* p_s_hdl, uint16_t* p_e_hdl) {
-  tGATT_STATUS reason = GATT_SUCCESS;
-  uint16_t uuid_len, s_hdl = 0, e_hdl = 0;
-  uint16_t len = *p_len;
-  uint8_t* p = *p_data;
+static tGATT_STATUS read_handles(uint16_t& len, uint8_t*& p, uint16_t& s_hdl,
+                                 uint16_t& e_hdl) {
+  if (len < 4) return GATT_INVALID_PDU;
 
-  if (len >= 4) {
-    /* obtain starting handle, and ending handle */
-    STREAM_TO_UINT16(s_hdl, p);
-    STREAM_TO_UINT16(e_hdl, p);
-    len -= 4;
+  /* obtain starting handle, and ending handle */
+  STREAM_TO_UINT16(s_hdl, p);
+  STREAM_TO_UINT16(e_hdl, p);
+  len -= 4;
 
-    if (s_hdl > e_hdl || !GATT_HANDLE_IS_VALID(s_hdl) ||
-        !GATT_HANDLE_IS_VALID(e_hdl)) {
-      reason = GATT_INVALID_HANDLE;
-    }
-    /* for these PDUs, uuid filter must present */
-    else if (op_code == GATT_REQ_READ_BY_GRP_TYPE ||
-             op_code == GATT_REQ_FIND_TYPE_VALUE ||
-             op_code == GATT_REQ_READ_BY_TYPE) {
-      if (len >= 2 && p_uuid_filter != NULL) {
-        uuid_len = (op_code == GATT_REQ_FIND_TYPE_VALUE) ? 2 : len;
+  if (s_hdl > e_hdl || !GATT_HANDLE_IS_VALID(s_hdl) ||
+      !GATT_HANDLE_IS_VALID(e_hdl)) {
+    return GATT_INVALID_PDU;
+  }
 
-        /* parse uuid now */
-        if (gatt_parse_uuid_from_cmd(p_uuid_filter, uuid_len, &p) == false ||
-            p_uuid_filter->len == 0) {
-          GATT_TRACE_DEBUG("UUID filter does not exsit");
-          reason = GATT_INVALID_PDU;
-        } else
-          len -= p_uuid_filter->len;
-      } else
-        reason = GATT_INVALID_PDU;
-    }
-  } else
-    reason = GATT_INVALID_PDU;
+  return GATT_SUCCESS;
+}
 
-  *p_data = p;
-  *p_len = len;
-  *p_s_hdl = s_hdl;
-  *p_e_hdl = e_hdl;
+static tGATT_STATUS gatts_validate_packet_format(uint8_t op_code, uint16_t& len,
+                                                 uint8_t*& p, tBT_UUID* p_uuid,
+                                                 uint16_t& s_hdl,
+                                                 uint16_t& e_hdl) {
+  tGATT_STATUS ret = read_handles(len, p, s_hdl, e_hdl);
+  if (ret != GATT_SUCCESS) return ret;
 
-  return reason;
+  if (len < 2) return GATT_INVALID_PDU;
+
+  /* parse uuid now */
+  CHECK(p_uuid);
+  uint16_t uuid_len = (op_code == GATT_REQ_FIND_TYPE_VALUE) ? 2 : len;
+  if (!gatt_parse_uuid_from_cmd(p_uuid, uuid_len, &p)) {
+    VLOG(1) << "Bad UUID";
+    return GATT_INVALID_PDU;
+  }
+
+  len -= uuid_len;
+  return GATT_SUCCESS;
 }
 
 /*******************************************************************************
@@ -631,50 +611,53 @@
  ******************************************************************************/
 void gatts_process_primary_service_req(tGATT_TCB& tcb, uint8_t op_code,
                                        uint16_t len, uint8_t* p_data) {
-  uint8_t reason = GATT_INVALID_PDU;
   uint16_t s_hdl = 0, e_hdl = 0;
-  tBT_UUID uuid, value,
-      primary_service = {LEN_UUID_16, {GATT_UUID_PRI_SERVICE}};
-  BT_HDR* p_msg = NULL;
-  uint16_t msg_len =
-      (uint16_t)(sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET);
+  tBT_UUID uuid;
 
+  uint8_t reason =
+      gatts_validate_packet_format(op_code, len, p_data, &uuid, s_hdl, e_hdl);
+  if (reason != GATT_SUCCESS) {
+    gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
+    return;
+  }
+
+  tBT_UUID primary_service = {LEN_UUID_16, {GATT_UUID_PRI_SERVICE}};
+  if (!gatt_uuid_compare(uuid, primary_service)) {
+    if (op_code == GATT_REQ_READ_BY_GRP_TYPE) {
+      gatt_send_error_rsp(tcb, GATT_UNSUPPORT_GRP_TYPE, op_code, s_hdl, false);
+      VLOG(1) << StringPrintf("unexpected ReadByGrpType Group: 0x%04x",
+                              uuid.uu.uuid16);
+      return;
+    }
+
+    // we do not support ReadByTypeValue with any non-primamry_service type
+    gatt_send_error_rsp(tcb, GATT_NOT_FOUND, op_code, s_hdl, false);
+    VLOG(1) << StringPrintf("unexpected ReadByTypeValue type: 0x%04x",
+                            uuid.uu.uuid16);
+    return;
+  }
+
+  // TODO: we assume theh value is UUID, there is no such requirement in spec
+  tBT_UUID value;
   memset(&value, 0, sizeof(tBT_UUID));
-  reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl,
-                                        &e_hdl);
-
-  if (reason == GATT_SUCCESS) {
-    if (gatt_uuid_compare(uuid, primary_service)) {
-      if (op_code == GATT_REQ_FIND_TYPE_VALUE) {
-        if (gatt_parse_uuid_from_cmd(&value, len, &p_data) == false)
-          reason = GATT_INVALID_PDU;
-      }
-
-      if (reason == GATT_SUCCESS) {
-        p_msg = (BT_HDR*)osi_calloc(msg_len);
-        reason = gatt_build_primary_service_rsp(p_msg, tcb, op_code, s_hdl,
-                                                e_hdl, p_data, value);
-      }
-    } else {
-      if (op_code == GATT_REQ_READ_BY_GRP_TYPE) {
-        reason = GATT_UNSUPPORT_GRP_TYPE;
-        GATT_TRACE_DEBUG("unexpected ReadByGrpType Group: 0x%04x",
-                         uuid.uu.uuid16);
-      } else {
-        /* we do not support ReadByTypeValue with any non-primamry_service type
-         */
-        reason = GATT_NOT_FOUND;
-        GATT_TRACE_DEBUG("unexpected ReadByTypeValue type: 0x%04x",
-                         uuid.uu.uuid16);
-      }
+  if (op_code == GATT_REQ_FIND_TYPE_VALUE) {
+    if (gatt_parse_uuid_from_cmd(&value, len, &p_data) == false) {
+      gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, s_hdl, false);
     }
   }
 
+  uint16_t msg_len =
+      (uint16_t)(sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET);
+  BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
+  reason = gatt_build_primary_service_rsp(p_msg, tcb, op_code, s_hdl, e_hdl,
+                                          p_data, value);
   if (reason != GATT_SUCCESS) {
     osi_free(p_msg);
     gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
-  } else
-    attp_send_sr_msg(tcb, p_msg);
+    return;
+  }
+
+  attp_send_sr_msg(tcb, p_msg);
 }
 
 /*******************************************************************************
@@ -690,9 +673,7 @@
 static void gatts_process_find_info(tGATT_TCB& tcb, uint8_t op_code,
                                     uint16_t len, uint8_t* p_data) {
   uint16_t s_hdl = 0, e_hdl = 0;
-
-  uint8_t reason = gatts_validate_packet_format(op_code, &len, &p_data, NULL,
-                                                &s_hdl, &e_hdl);
+  uint8_t reason = read_handles(len, p_data, s_hdl, e_hdl);
   if (reason != GATT_SUCCESS) {
     gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
     return;
@@ -712,7 +693,7 @@
 
   for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
     if (el.s_hdl <= e_hdl && el.e_hdl >= s_hdl) {
-      reason = gatt_build_find_info_rsp(el, p_msg, &buf_len, s_hdl, e_hdl);
+      reason = gatt_build_find_info_rsp(el, p_msg, buf_len, s_hdl, e_hdl);
       if (reason == GATT_NO_RESOURCES) {
         reason = GATT_SUCCESS;
         break;
@@ -743,48 +724,48 @@
  ******************************************************************************/
 static void gatts_process_mtu_req(tGATT_TCB& tcb, uint16_t len,
                                   uint8_t* p_data) {
-  uint16_t mtu = 0;
-  uint8_t *p = p_data, i;
-  BT_HDR* p_buf;
-  uint16_t conn_id;
-
   /* BR/EDR conenction, send error response */
   if (tcb.att_lcid != L2CAP_ATT_CID) {
     gatt_send_error_rsp(tcb, GATT_REQ_NOT_SUPPORTED, GATT_REQ_MTU, 0, false);
-  } else if (len < GATT_MTU_REQ_MIN_LEN) {
-    GATT_TRACE_ERROR("invalid MTU request PDU received.");
+    return;
+  }
+
+  if (len < GATT_MTU_REQ_MIN_LEN) {
+    LOG(ERROR) << "invalid MTU request PDU received.";
     gatt_send_error_rsp(tcb, GATT_INVALID_PDU, GATT_REQ_MTU, 0, false);
-  } else {
-    STREAM_TO_UINT16(mtu, p);
-    /* mtu must be greater than default MTU which is 23/48 */
-    if (mtu < GATT_DEF_BLE_MTU_SIZE)
-      tcb.payload_size = GATT_DEF_BLE_MTU_SIZE;
-    else if (mtu > GATT_MAX_MTU_SIZE)
-      tcb.payload_size = GATT_MAX_MTU_SIZE;
-    else
-      tcb.payload_size = mtu;
+    return;
+  }
 
-    GATT_TRACE_ERROR("MTU request PDU with MTU size %d", tcb.payload_size);
+  uint16_t mtu = 0;
+  uint8_t* p = p_data;
+  STREAM_TO_UINT16(mtu, p);
+  /* mtu must be greater than default MTU which is 23/48 */
+  if (mtu < GATT_DEF_BLE_MTU_SIZE)
+    tcb.payload_size = GATT_DEF_BLE_MTU_SIZE;
+  else if (mtu > GATT_MAX_MTU_SIZE)
+    tcb.payload_size = GATT_MAX_MTU_SIZE;
+  else
+    tcb.payload_size = mtu;
 
-    l2cble_set_fixed_channel_tx_data_length(tcb.peer_bda, L2CAP_ATT_CID,
-                                            tcb.payload_size);
+  LOG(ERROR) << "MTU request PDU with MTU size " << +tcb.payload_size;
 
-    p_buf =
-        attp_build_sr_msg(tcb, GATT_RSP_MTU, (tGATT_SR_MSG*)&tcb.payload_size);
-    if (p_buf != NULL) {
-      attp_send_sr_msg(tcb, p_buf);
+  l2cble_set_fixed_channel_tx_data_length(tcb.peer_bda, L2CAP_ATT_CID,
+                                          tcb.payload_size);
 
-      /* Notify all registered applicaiton with new MTU size. Us a transaction
-       * ID */
-      /* of 0, as no response is allowed from applcations                    */
+  tGATT_SR_MSG gatt_sr_msg;
+  gatt_sr_msg.mtu = tcb.payload_size;
+  BT_HDR* p_buf = attp_build_sr_msg(tcb, GATT_RSP_MTU, &gatt_sr_msg);
+  attp_send_sr_msg(tcb, p_buf);
 
-      for (i = 0; i < GATT_MAX_APPS; i++) {
-        if (gatt_cb.cl_rcb[i].in_use) {
-          conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, gatt_cb.cl_rcb[i].gatt_if);
-          gatt_sr_send_req_callback(conn_id, 0, GATTS_REQ_TYPE_MTU,
-                                    (tGATTS_DATA*)&tcb.payload_size);
-        }
-      }
+  tGATTS_DATA gatts_data;
+  gatts_data.mtu = tcb.payload_size;
+  /* Notify all registered applicaiton with new MTU size. Us a transaction ID */
+  /* of 0, as no response is allowed from applcations                    */
+  for (int i = 0; i < GATT_MAX_APPS; i++) {
+    if (gatt_cb.cl_rcb[i].in_use) {
+      uint16_t conn_id =
+          GATT_CREATE_CONN_ID(tcb.tcb_idx, gatt_cb.cl_rcb[i].gatt_if);
+      gatt_sr_send_req_callback(conn_id, 0, GATTS_REQ_TYPE_MTU, &gatts_data);
     }
   }
 }
@@ -807,21 +788,15 @@
 void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint8_t op_code,
                                     uint16_t len, uint8_t* p_data) {
   tBT_UUID uuid;
-  size_t msg_len = sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET;
-  uint16_t buf_len, s_hdl, e_hdl, err_hdl = 0;
-  BT_HDR* p_msg = NULL;
-  tGATT_STATUS reason, ret;
-  uint8_t* p;
-  uint8_t sec_flag, key_size;
-
-  reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl,
-                                        &e_hdl);
+  uint16_t s_hdl = 0, e_hdl = 0, err_hdl = 0;
+  if (len < 4) android_errorWriteLog(0x534e4554, "73125709");
+  tGATT_STATUS reason =
+      gatts_validate_packet_format(op_code, len, p_data, &uuid, s_hdl, e_hdl);
 
 #if (GATT_CONFORMANCE_TESTING == TRUE)
   if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
-    GATT_TRACE_DEBUG(
-        "Conformance tst: forced err rsp for ReadByType: error status=%d",
-        gatt_cb.err_status);
+    VLOG(1) << "Conformance tst: forced err rsp for ReadByType: error status="
+            << +gatt_cb.err_status;
 
     gatt_send_error_rsp(tcb, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl,
                         false);
@@ -830,38 +805,43 @@
   }
 #endif
 
-  if (reason == GATT_SUCCESS) {
-    p_msg = (BT_HDR*)osi_calloc(msg_len);
-    p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
+  if (reason != GATT_SUCCESS) {
+    gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
+    return;
+  }
 
-    *p++ = op_code + 1;
-    /* reserve length byte */
-    p_msg->len = 2;
-    buf_len = tcb.payload_size - 2;
+  size_t msg_len = sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET;
+  BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
+  uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
 
-    reason = GATT_NOT_FOUND;
+  *p++ = op_code + 1;
+  /* reserve length byte */
+  p_msg->len = 2;
+  uint16_t buf_len = tcb.payload_size - 2;
 
-    for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
-      if (el.s_hdl <= e_hdl && el.e_hdl >= s_hdl) {
-        gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
+  reason = GATT_NOT_FOUND;
+  for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
+    if (el.s_hdl <= e_hdl && el.e_hdl >= s_hdl) {
+      uint8_t sec_flag, key_size;
+      gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
 
-        ret = gatts_db_read_attr_value_by_type(tcb, el.p_db, op_code, p_msg,
-                                               s_hdl, e_hdl, uuid, &buf_len,
-                                               sec_flag, key_size, 0, &err_hdl);
-        if (ret != GATT_NOT_FOUND) {
-          reason = ret;
+      tGATT_STATUS ret = gatts_db_read_attr_value_by_type(
+          tcb, el.p_db, op_code, p_msg, s_hdl, e_hdl, uuid, &buf_len, sec_flag,
+          key_size, 0, &err_hdl);
+      if (ret != GATT_NOT_FOUND) {
+        reason = ret;
+        if (ret == GATT_NO_RESOURCES) reason = GATT_SUCCESS;
+      }
 
-          if (ret == GATT_NO_RESOURCES) reason = GATT_SUCCESS;
-        }
-        if (ret != GATT_SUCCESS && ret != GATT_NOT_FOUND) {
-          s_hdl = err_hdl;
-          break;
-        }
+      if (ret != GATT_SUCCESS && ret != GATT_NOT_FOUND) {
+        s_hdl = err_hdl;
+        break;
       }
     }
-    *p = (uint8_t)p_msg->offset;
-    p_msg->offset = L2CAP_MIN_OFFSET;
   }
+  *p = (uint8_t)p_msg->offset;
+  p_msg->offset = L2CAP_MIN_OFFSET;
+
   if (reason != GATT_SUCCESS) {
     osi_free(p_msg);
 
@@ -869,8 +849,11 @@
      * check */
     if (reason != GATT_PENDING && reason != GATT_BUSY)
       gatt_send_error_rsp(tcb, reason, op_code, s_hdl, false);
-  } else
-    attp_send_sr_msg(tcb, p_msg);
+
+    return;
+  }
+
+  attp_send_sr_msg(tcb, p_msg);
 }
 
 /**
@@ -891,10 +874,9 @@
   switch (op_code) {
     case GATT_REQ_PREPARE_WRITE:
       if (len < 2) {
-        GATT_TRACE_ERROR(
-            "%s: Prepare write request was invalid - missing offset, sending "
-            "error response",
-            __func__);
+        LOG(ERROR) << __func__
+                   << ": Prepare write request was invalid - missing offset, "
+                      "sending error response";
         gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, handle, false);
         return;
       }
@@ -904,7 +886,7 @@
     /* fall through */
     case GATT_SIGN_CMD_WRITE:
       if (op_code == GATT_SIGN_CMD_WRITE) {
-        GATT_TRACE_DEBUG("Write CMD with data sigining");
+        VLOG(1) << "Write CMD with data sigining";
         len -= GATT_AUTH_SIGN_LEN;
       }
     /* fall through */
@@ -937,10 +919,9 @@
       } else if (gatt_type == BTGATT_DB_CHARACTERISTIC) {
         opcode = GATTS_REQ_TYPE_WRITE_CHARACTERISTIC;
       } else {
-        GATT_TRACE_ERROR(
-            "%s: Attempt to write attribute that's not tied with"
-            " characteristic or descriptor value.",
-            __func__);
+        LOG(ERROR) << __func__
+                   << "%s: Attempt to write attribute that's not tied with"
+                      " characteristic or descriptor value.";
         status = GATT_ERROR;
       }
 
@@ -949,7 +930,7 @@
         status = GATT_PENDING;
       }
     } else {
-      GATT_TRACE_ERROR("max pending command, send error");
+      LOG(ERROR) << "max pending command, send error";
       status = GATT_BUSY; /* max pending command, application error */
     }
   }
@@ -968,37 +949,49 @@
  */
 static void gatts_process_read_req(tGATT_TCB& tcb, tGATT_SRV_LIST_ELEM& el,
                                    uint8_t op_code, uint16_t handle,
-                                   UNUSED_ATTR uint16_t len, uint8_t* p_data) {
+                                   uint16_t len, uint8_t* p_data) {
   size_t buf_len = sizeof(BT_HDR) + tcb.payload_size + L2CAP_MIN_OFFSET;
-  tGATT_STATUS reason;
-  uint8_t sec_flag, key_size, *p;
-  uint16_t offset = 0, value_len = 0;
+  uint16_t offset = 0;
+
+  if (op_code == GATT_REQ_READ_BLOB && len < sizeof(uint16_t)) {
+    /* Error: packet length is too short */
+    LOG(ERROR) << __func__ << ": packet length=" << len
+               << " too short. min=" << sizeof(uint16_t);
+    android_errorWriteWithInfoLog(0x534e4554, "73172115", -1, NULL, 0);
+    gatt_send_error_rsp(tcb, GATT_INVALID_PDU, op_code, 0, false);
+    return;
+  }
+
   BT_HDR* p_msg = (BT_HDR*)osi_calloc(buf_len);
 
   if (op_code == GATT_REQ_READ_BLOB) STREAM_TO_UINT16(offset, p_data);
 
-  p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
+  uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
   *p++ = op_code + 1;
   p_msg->len = 1;
   buf_len = tcb.payload_size - 1;
 
+  uint8_t sec_flag, key_size;
   gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size);
 
-  reason = gatts_read_attr_value_by_handle(
+  uint16_t value_len = 0;
+  tGATT_STATUS reason = gatts_read_attr_value_by_handle(
       tcb, el.p_db, op_code, handle, offset, p, &value_len, (uint16_t)buf_len,
       sec_flag, key_size, 0);
-
   p_msg->len += value_len;
 
   if (reason != GATT_SUCCESS) {
     osi_free(p_msg);
 
-    /* in theroy BUSY is not possible(should already been checked), protected
+    /* in theory BUSY is not possible(should already been checked), protected
      * check */
     if (reason != GATT_PENDING && reason != GATT_BUSY)
       gatt_send_error_rsp(tcb, reason, op_code, handle, false);
-  } else
-    attp_send_sr_msg(tcb, p_msg);
+
+    return;
+  }
+
+  attp_send_sr_msg(tcb, p_msg);
 }
 
 /*******************************************************************************
@@ -1018,7 +1011,7 @@
   tGATT_STATUS status = GATT_INVALID_HANDLE;
 
   if (len < 2) {
-    GATT_TRACE_ERROR("Illegal PDU length, discard request");
+    LOG(ERROR) << "Illegal PDU length, discard request";
     status = GATT_INVALID_PDU;
   } else {
     STREAM_TO_UINT16(handle, p);
@@ -1028,8 +1021,8 @@
 #if (GATT_CONFORMANCE_TESTING == TRUE)
   gatt_cb.handle = handle;
   if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) {
-    GATT_TRACE_DEBUG("Conformance tst: forced err rsp: error status=%d",
-                     gatt_cb.err_status);
+    VLOG(1) << "Conformance tst: forced err rsp: error status="
+            << +gatt_cb.err_status;
 
     gatt_send_error_rsp(tcb, gatt_cb.err_status, gatt_cb.req_op_code, handle,
                         false);
@@ -1086,11 +1079,11 @@
   tGATTS_SRV_CHG_REQ req;
   tGATTS_SRV_CHG* p_buf = NULL;
 
-  GATT_TRACE_DEBUG("%s", __func__);
+  VLOG(1) << __func__;
 
   p_buf = gatt_is_bda_in_the_srv_chg_clt_list(tcb.peer_bda);
   if (p_buf != NULL) {
-    GATT_TRACE_DEBUG("NV update set srv chg = false");
+    VLOG(1) << "NV update set srv chg = false";
     p_buf->srv_changed = false;
     memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG));
     if (gatt_cb.cb_info.p_srv_chg_callback)
@@ -1110,7 +1103,7 @@
  *
  ******************************************************************************/
 static void gatts_chk_pending_ind(tGATT_TCB& tcb) {
-  GATT_TRACE_DEBUG("%s", __func__);
+  VLOG(1) << __func__;
 
   tGATT_VALUE* p_buf =
       (tGATT_VALUE*)fixed_queue_try_peek_first(tcb.pending_ind_q);
@@ -1134,7 +1127,7 @@
 static bool gatts_proc_ind_ack(tGATT_TCB& tcb, uint16_t ack_handle) {
   bool continue_processing = true;
 
-  GATT_TRACE_DEBUG("gatts_proc_ind_ack ack handle=%d", ack_handle);
+  VLOG(1) << __func__ << " ack handle=%d" << ack_handle;
 
   if (ack_handle == gatt_cb.handle_of_h_r) {
     gatts_proc_srv_chg_ind_ack(tcb);
@@ -1162,7 +1155,7 @@
 
   alarm_cancel(tcb.conf_timer);
   if (!GATT_HANDLE_IS_VALID(handle)) {
-    GATT_TRACE_ERROR("unexpected handle value confirmation");
+    LOG(ERROR) << "unexpected handle value confirmation";
     return;
   }
 
@@ -1170,12 +1163,14 @@
   bool continue_processing = gatts_proc_ind_ack(tcb, handle);
 
   if (continue_processing) {
+    tGATTS_DATA gatts_data;
+    gatts_data.handle = handle;
     for (auto& el : *gatt_cb.srv_list_info) {
       if (el.s_hdl <= handle && el.e_hdl >= handle) {
         uint32_t trans_id = gatt_sr_enqueue_cmd(tcb, op_code, handle);
         uint16_t conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, el.gatt_if);
         gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_CONF,
-                                  (tGATTS_DATA*)&handle);
+                                  &gatts_data);
       }
     }
   }
@@ -1191,8 +1186,8 @@
   /* The message has to be smaller than the agreed MTU, len does not include op
    * code */
   if (len >= tcb.payload_size) {
-    GATT_TRACE_ERROR("server receive invalid PDU size:%d pdu size:%d", len + 1,
-                     tcb.payload_size);
+    LOG(ERROR) << StringPrintf("server receive invalid PDU size:%d pdu size:%d",
+                               len + 1, tcb.payload_size);
     /* for invalid request expecting response, send it now */
     if (op_code != GATT_CMD_WRITE && op_code != GATT_SIGN_CMD_WRITE &&
         op_code != GATT_HANDLE_VALUE_CONF) {
diff --git a/stack/gatt/gatt_utils.cc b/stack/gatt/gatt_utils.cc
index 8cb2745..e7cc762 100644
--- a/stack/gatt/gatt_utils.cc
+++ b/stack/gatt/gatt_utils.cc
@@ -35,6 +35,9 @@
 #include "gattdefs.h"
 #include "l2cdefs.h"
 #include "sdp_api.h"
+
+using base::StringPrintf;
+
 /* check if [x, y] and [a, b] have overlapping range */
 #define GATT_VALIDATE_HANDLE_RANGE(x, y, a, b) ((y) >= (a) && (x) <= (b))
 
@@ -77,8 +80,6 @@
     0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
     0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*******************************************************************************
  *
  * Function         gatt_free_pending_ind
@@ -89,7 +90,7 @@
  *
  ******************************************************************************/
 void gatt_free_pending_ind(tGATT_TCB* p_tcb) {
-  GATT_TRACE_DEBUG("%s", __func__);
+  VLOG(1) << __func__;
 
   if (p_tcb->pending_ind_q == NULL) return;
 
@@ -109,15 +110,15 @@
  * Returns       None
  *
  ******************************************************************************/
-void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr) {
-  GATT_TRACE_DEBUG("gatt_delete_dev_from_srv_chg_clt_list");
+void gatt_delete_dev_from_srv_chg_clt_list(const RawAddress& bd_addr) {
+  VLOG(1) << __func__;
 
   tGATTS_SRV_CHG* p_buf = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr);
   if (p_buf != NULL) {
     if (gatt_cb.cb_info.p_srv_chg_callback) {
       /* delete from NV */
       tGATTS_SRV_CHG_REQ req;
-      memcpy(req.srv_chg.bda, bd_addr, BD_ADDR_LEN);
+      req.srv_chg.bda = bd_addr;
       (*gatt_cb.cb_info.p_srv_chg_callback)(GATTS_SRV_CHG_CMD_REMOVE_CLIENT,
                                             &req, NULL);
     }
@@ -135,18 +136,18 @@
  *
  ******************************************************************************/
 void gatt_set_srv_chg(void) {
-  GATT_TRACE_DEBUG("gatt_set_srv_chg");
+  VLOG(1) << __func__;
 
   if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return;
 
   list_t* list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q);
   for (const list_node_t* node = list_begin(list); node != list_end(list);
        node = list_next(node)) {
-    GATT_TRACE_DEBUG("found a srv_chg clt");
+    VLOG(1) << "found a srv_chg clt";
 
     tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node);
     if (!p_buf->srv_changed) {
-      GATT_TRACE_DEBUG("set srv_changed to true");
+      VLOG(1) << "set srv_changed to true";
       p_buf->srv_changed = true;
       tGATTS_SRV_CHG_REQ req;
       memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG));
@@ -170,8 +171,7 @@
 tGATT_VALUE* gatt_add_pending_ind(tGATT_TCB* p_tcb, tGATT_VALUE* p_ind) {
   tGATT_VALUE* p_buf = (tGATT_VALUE*)osi_malloc(sizeof(tGATT_VALUE));
 
-  GATT_TRACE_DEBUG("%s", __func__);
-  GATT_TRACE_DEBUG("enqueue a pending indication");
+  VLOG(1) << __func__ << "enqueue a pending indication";
 
   memcpy(p_buf, p_ind, sizeof(tGATT_VALUE));
   fixed_queue_enqueue(p_tcb->pending_ind_q, p_buf);
@@ -191,9 +191,7 @@
  ******************************************************************************/
 tGATTS_SRV_CHG* gatt_add_srv_chg_clt(tGATTS_SRV_CHG* p_srv_chg) {
   tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)osi_malloc(sizeof(tGATTS_SRV_CHG));
-
-  GATT_TRACE_DEBUG("%s", __func__);
-  GATT_TRACE_DEBUG("enqueue a srv chg client");
+  VLOG(1) << __func__ << "enqueue a srv chg client";
 
   memcpy(p_buf, p_srv_chg, sizeof(tGATTS_SRV_CHG));
   fixed_queue_enqueue(gatt_cb.srv_chg_clt_q, p_buf);
@@ -261,27 +259,24 @@
  * Returns           true if found
  *
  ******************************************************************************/
-bool gatt_find_the_connected_bda(uint8_t start_idx, BD_ADDR bda,
+bool gatt_find_the_connected_bda(uint8_t start_idx, RawAddress& bda,
                                  uint8_t* p_found_idx,
                                  tBT_TRANSPORT* p_transport) {
   uint8_t i;
   bool found = false;
-  GATT_TRACE_DEBUG("gatt_find_the_connected_bda start_idx=%d", start_idx);
+  VLOG(1) << __func__ << " start_idx=" << +start_idx;
 
   for (i = start_idx; i < GATT_MAX_PHY_CHANNEL; i++) {
     if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN) {
-      memcpy(bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN);
+      bda = gatt_cb.tcb[i].peer_bda;
       *p_found_idx = i;
       *p_transport = gatt_cb.tcb[i].transport;
       found = true;
-      GATT_TRACE_DEBUG(
-          "gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x",
-          bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+      VLOG(1) << " bda :" << bda;
       break;
     }
   }
-  GATT_TRACE_DEBUG("gatt_find_the_connected_bda found=%d found_idx=%d", found,
-                   i);
+  VLOG(1) << StringPrintf(" found=%d found_idx=%d", found, i);
   return found;
 }
 
@@ -298,8 +293,8 @@
 bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb) {
   bool srv_chg_ind_pending = false;
 
-  GATT_TRACE_DEBUG("gatt_is_srv_chg_ind_pending is_queue_empty=%d",
-                   fixed_queue_is_empty(p_tcb->pending_ind_q));
+  VLOG(1) << __func__
+          << " is_queue_empty=" << fixed_queue_is_empty(p_tcb->pending_ind_q);
 
   if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) {
     srv_chg_ind_pending = true;
@@ -315,7 +310,7 @@
     }
   }
 
-  GATT_TRACE_DEBUG("srv_chg_ind_pending = %d", srv_chg_ind_pending);
+  VLOG(1) << __func__ << "srv_chg_ind_pending = %d", srv_chg_ind_pending;
   return srv_chg_ind_pending;
 }
 
@@ -329,12 +324,10 @@
  * Returns         pointer to the found elemenet otherwise NULL
  *
  ******************************************************************************/
-tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(BD_ADDR bda) {
+tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(const RawAddress& bda) {
   tGATTS_SRV_CHG* p_buf = NULL;
 
-  GATT_TRACE_DEBUG(
-      "gatt_is_bda_in_the_srv_chg_clt_list :%02x-%02x-%02x-%02x-%02x-%02x",
-      bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
+  VLOG(1) << __func__ << ": " << bda;
 
   if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return NULL;
 
@@ -342,8 +335,8 @@
   for (const list_node_t* node = list_begin(list); node != list_end(list);
        node = list_next(node)) {
     tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node);
-    if (!memcmp(bda, p_buf->bda, BD_ADDR_LEN)) {
-      GATT_TRACE_DEBUG("bda is in the srv chg clt list");
+    if (bda == p_buf->bda) {
+      VLOG(1) << "bda is in the srv chg clt list";
       break;
     }
   }
@@ -360,13 +353,12 @@
  * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
  *
  ******************************************************************************/
-bool gatt_is_bda_connected(BD_ADDR bda) {
+bool gatt_is_bda_connected(const RawAddress& bda) {
   uint8_t i = 0;
   bool connected = false;
 
   for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) {
-    if (gatt_cb.tcb[i].in_use &&
-        !memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN)) {
+    if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].peer_bda == bda) {
       connected = true;
       break;
     }
@@ -383,11 +375,12 @@
  * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
  *
  ******************************************************************************/
-uint8_t gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) {
+uint8_t gatt_find_i_tcb_by_addr(const RawAddress& bda,
+                                tBT_TRANSPORT transport) {
   uint8_t i = 0;
 
   for (; i < GATT_MAX_PHY_CHANNEL; i++) {
-    if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) &&
+    if (gatt_cb.tcb[i].peer_bda == bda &&
         gatt_cb.tcb[i].transport == transport) {
       return i;
     }
@@ -422,7 +415,8 @@
  * Returns          NULL if not found. Otherwise index to the tcb.
  *
  ******************************************************************************/
-tGATT_TCB* gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport) {
+tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda,
+                                 tBT_TRANSPORT transport) {
   tGATT_TCB* p_tcb = NULL;
   uint8_t i = 0;
 
@@ -441,7 +435,8 @@
  * Returns          GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
  *
  ******************************************************************************/
-tGATT_TCB* gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) {
+tGATT_TCB* gatt_allocate_tcb_by_bdaddr(const RawAddress& bda,
+                                       tBT_TRANSPORT transport) {
   /* search for existing tcb with matching bda    */
   uint8_t j = gatt_find_i_tcb_by_addr(bda, transport);
   if (j != GATT_INDEX_INVALID) return &gatt_cb.tcb[j];
@@ -459,7 +454,7 @@
     p_tcb->in_use = true;
     p_tcb->tcb_idx = i;
     p_tcb->transport = transport;
-    memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
+    p_tcb->peer_bda = bda;
     return p_tcb;
   }
 
@@ -639,12 +634,12 @@
 
     /* do not allow 32 bits UUID in ATT PDU now */
     case LEN_UUID_32:
-      GATT_TRACE_ERROR("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
+      LOG(ERROR) << "DO NOT ALLOW 32 BITS UUID IN ATT PDU";
       return false;
     case 0:
     default:
       if (uuid_size != 0) ret = false;
-      GATT_TRACE_WARNING("gatt_parse_uuid_from_cmd invalid uuid size");
+      LOG(WARNING) << __func__ << ": invalid uuid size";
       break;
   }
 
@@ -673,8 +668,8 @@
   if (p_clcb->gatt_rsp_timer_ent == NULL) {
     p_clcb->gatt_rsp_timer_ent = alarm_new("gatt.gatt_rsp_timer_ent");
   }
-  alarm_set_on_queue(p_clcb->gatt_rsp_timer_ent, timeout_ms, gatt_rsp_timeout,
-                     p_clcb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_clcb->gatt_rsp_timer_ent, timeout_ms, gatt_rsp_timeout,
+                     p_clcb);
 }
 
 /*******************************************************************************
@@ -687,9 +682,8 @@
  *
  ******************************************************************************/
 void gatt_start_conf_timer(tGATT_TCB* p_tcb) {
-  alarm_set_on_queue(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
-                     gatt_indication_confirmation_timeout, p_tcb,
-                     btu_general_alarm_queue);
+  alarm_set_on_mloop(p_tcb->conf_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
+                     gatt_indication_confirmation_timeout, p_tcb);
 }
 
 /*******************************************************************************
@@ -703,8 +697,8 @@
  ******************************************************************************/
 void gatt_start_ind_ack_timer(tGATT_TCB& tcb) {
   /* start notification cache timer */
-  alarm_set_on_queue(tcb.ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
-                     gatt_ind_ack_timeout, &tcb, btu_general_alarm_queue);
+  alarm_set_on_mloop(tcb.ind_ack_timer, GATT_WAIT_FOR_RSP_TIMEOUT_MS,
+                     gatt_ind_ack_timeout, &tcb);
 }
 
 /*******************************************************************************
@@ -720,16 +714,16 @@
   tGATT_CLCB* p_clcb = (tGATT_CLCB*)data;
 
   if (p_clcb == NULL || p_clcb->p_tcb == NULL) {
-    GATT_TRACE_WARNING("%s clcb is already deleted", __func__);
+    LOG(WARNING) << __func__ << " clcb is already deleted";
     return;
   }
   if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
       p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
       p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) {
     uint8_t rsp_code;
-    GATT_TRACE_WARNING("%s retry discovery primary service", __func__);
+    LOG(WARNING) << __func__ << " retry discovery primary service";
     if (p_clcb != gatt_cmd_dequeue(*p_clcb->p_tcb, &rsp_code)) {
-      GATT_TRACE_ERROR("%s command queue out of sync, disconnect", __func__);
+      LOG(ERROR) << __func__ << " command queue out of sync, disconnect";
     } else {
       p_clcb->retry_count++;
       gatt_act_discovery(p_clcb);
@@ -737,7 +731,7 @@
     }
   }
 
-  GATT_TRACE_WARNING("%s disconnecting...", __func__);
+  LOG(WARNING) << __func__ << " disconnecting...";
   gatt_disconnect(p_clcb->p_tcb);
 }
 
@@ -753,7 +747,7 @@
 void gatt_indication_confirmation_timeout(void* data) {
   tGATT_TCB* p_tcb = (tGATT_TCB*)data;
 
-  GATT_TRACE_WARNING("%s disconnecting...", __func__);
+  LOG(WARNING) << __func__ << " disconnecting...";
   gatt_disconnect(p_tcb);
 }
 
@@ -770,7 +764,7 @@
   tGATT_TCB* p_tcb = (tGATT_TCB*)data;
   CHECK(p_tcb);
 
-  GATT_TRACE_WARNING("%s send ack now", __func__);
+  LOG(WARNING) << __func__ << ": send ack now";
   p_tcb->ind_count = 0;
   attp_send_cl_msg(*p_tcb, nullptr, GATT_HANDLE_VALUE_CONF, NULL);
 }
@@ -805,7 +799,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport,
+void gatt_sr_get_sec_info(const RawAddress& rem_bda, tBT_TRANSPORT transport,
                           uint8_t* p_sec_flag, uint8_t* p_key_size) {
   uint8_t sec_flag = 0;
 
@@ -833,15 +827,14 @@
   tGATT_REG* p_reg = gatt_get_regcb(gatt_if);
 
   if (!p_reg) {
-    GATT_TRACE_ERROR("p_reg not found discard request");
+    LOG(ERROR) << "p_reg not found discard request";
     return;
   }
 
   if (p_reg->in_use && p_reg->app_cb.p_req_cb) {
     (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data);
   } else {
-    GATT_TRACE_WARNING("Call back not found for application conn_id=%d",
-                       conn_id);
+    LOG(WARNING) << "Call back not found for application conn_id=" << conn_id;
   }
 }
 
@@ -856,15 +849,15 @@
  ******************************************************************************/
 tGATT_STATUS gatt_send_error_rsp(tGATT_TCB& tcb, uint8_t err_code,
                                  uint8_t op_code, uint16_t handle, bool deq) {
-  tGATT_ERROR error;
   tGATT_STATUS status;
   BT_HDR* p_buf;
 
-  error.cmd_code = op_code;
-  error.reason = err_code;
-  error.handle = handle;
+  tGATT_SR_MSG msg;
+  msg.error.cmd_code = op_code;
+  msg.error.reason = err_code;
+  msg.error.handle = handle;
 
-  p_buf = attp_build_sr_msg(tcb, GATT_RSP_ERROR, (tGATT_SR_MSG*)&error);
+  p_buf = attp_build_sr_msg(tcb, GATT_RSP_ERROR, &msg);
   if (p_buf != NULL) {
     status = attp_send_sr_msg(tcb, p_buf);
   } else
@@ -892,8 +885,8 @@
   uint8_t buff[60];
   uint8_t* p = buff;
 
-  GATT_TRACE_DEBUG("gatt_add_sdp_record s_hdl=0x%x  s_hdl=0x%x", start_hdl,
-                   end_hdl);
+  VLOG(1) << __func__
+          << StringPrintf(" s_hdl=0x%x  s_hdl=0x%x", start_hdl, end_hdl);
 
   sdp_handle = SDP_CreateRecord();
   if (sdp_handle == 0) return 0;
@@ -918,7 +911,7 @@
       break;
 
     default:
-      GATT_TRACE_ERROR("inavlid UUID len=%d", p_uuid->len);
+      LOG(ERROR) << "inavlid UUID len=" << +p_uuid->len;
       SDP_DeleteRecord(sdp_handle);
       return 0;
       break;
@@ -952,8 +945,8 @@
  *
  ******************************************************************************/
 void gatt_set_err_rsp(bool enable, uint8_t req_op_code, uint8_t err_status) {
-  GATT_TRACE_DEBUG("gatt_set_err_rsp enable=%d op_code=%d, err_status=%d",
-                   enable, req_op_code, err_status);
+  VLOG(1) << __func__ << StringPrintf(" enable=%d op_code=%d, err_status=%d",
+                                      enable, req_op_code, err_status);
   gatt_cb.enable_err_rsp = enable;
   gatt_cb.req_op_code = req_op_code;
   gatt_cb.err_status = err_status;
@@ -974,7 +967,7 @@
   tGATT_REG* p_reg = NULL;
 
   if (ii < 1 || ii > GATT_MAX_APPS) {
-    GATT_TRACE_WARNING("gatt_if out of range [ = %d]", ii);
+    LOG(WARNING) << "gatt_if out of range = " << +ii;
     return NULL;
   }
 
@@ -982,7 +975,7 @@
   p_reg = &gatt_cb.cl_rcb[ii - 1];
 
   if (!p_reg->in_use) {
-    GATT_TRACE_WARNING("gatt_if found but not in use.");
+    LOG(WARNING) << "gatt_if found but not in use.";
     return NULL;
   }
 
@@ -1042,6 +1035,7 @@
       break;
     }
   }
+
   return p_clcb;
 }
 
@@ -1094,13 +1088,11 @@
  * Returns          total number of clcb found.
  *
  ******************************************************************************/
-uint8_t gatt_num_clcb_by_bd_addr(BD_ADDR bda) {
+uint8_t gatt_num_clcb_by_bd_addr(const RawAddress& bda) {
   uint8_t i, num = 0;
 
   for (i = 0; i < GATT_CL_MAX_LCB; i++) {
-    if (gatt_cb.clcb[i].in_use &&
-        memcmp(gatt_cb.clcb[i].p_tcb->peer_bda, bda, BD_ADDR_LEN) == 0)
-      num++;
+    if (gatt_cb.clcb[i].in_use && gatt_cb.clcb[i].p_tcb->peer_bda == bda) num++;
   }
   return num;
 }
@@ -1217,8 +1209,9 @@
                              bool is_reset_first) {
   uint8_t idx = ((uint8_t)gatt_if) - 1;
 
-  GATT_TRACE_DEBUG("%s tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d",
-                   __func__, tcb.tcb_idx, gatt_if, is_inc, is_reset_first);
+  VLOG(1) << StringPrintf(
+      "%s tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d", __func__,
+      tcb.tcb_idx, gatt_if, is_inc, is_reset_first);
 
   if (is_reset_first) {
     gatt_sr_reset_prep_cnt(tcb);
@@ -1240,7 +1233,7 @@
  * Returns         Boolean
  *
  ******************************************************************************/
-bool gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda) {
+bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) {
   tGATT_TCB* p_tcb = NULL;
   bool status = true;
 
@@ -1248,8 +1241,7 @@
 
   if (p_tcb) {
     if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) {
-      GATT_TRACE_ERROR(
-          "GATT_CancelConnect - link connected Too late to cancel");
+      LOG(ERROR) << __func__ << ": link connected Too late to cancel";
       status = false;
     } else {
       gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false);
@@ -1291,24 +1283,14 @@
   return p_clcb;
 }
 
-/*******************************************************************************
- *
- * Function         gatt_send_write_msg
- *
- * Description      This real function send out the ATT message for write.
- *
- * Returns          status code
- *
- ******************************************************************************/
+/** Send out the ATT message for write */
 uint8_t gatt_send_write_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint8_t op_code,
                             uint16_t handle, uint16_t len, uint16_t offset,
                             uint8_t* p_data) {
   tGATT_CL_MSG msg;
-
   msg.attr_value.handle = handle;
   msg.attr_value.len = len;
   msg.attr_value.offset = offset;
-
   memcpy(msg.attr_value.value, p_data, len);
 
   /* write by handle */
@@ -1335,8 +1317,8 @@
   uint16_t conn_id;
   uint8_t operation;
 
-  GATT_TRACE_DEBUG("gatt_end_operation status=%d op=%d subtype=%d", status,
-                   p_clcb->operation, p_clcb->op_subtype);
+  VLOG(1) << __func__ << StringPrintf(" status=%d op=%d subtype=%d", status,
+                                      p_clcb->operation, p_clcb->op_subtype);
   memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE));
 
   if (p_cmpl_cb != NULL && p_clcb->operation != 0) {
@@ -1355,7 +1337,7 @@
         if (p_data) {
           cb_data.att_value = *((tGATT_VALUE*)p_data);
         } else {
-          GATT_TRACE_DEBUG("Rcv Prepare write rsp but no data");
+          VLOG(1) << "Rcv Prepare write rsp but no data";
         }
       }
     }
@@ -1381,68 +1363,56 @@
   else if (p_cmpl_cb && op)
     (*p_cmpl_cb)(conn_id, op, status, &cb_data);
   else
-    GATT_TRACE_WARNING(
-        "gatt_end_operation not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
-        operation, p_disc_cmpl_cb, p_cmpl_cb);
+    LOG(WARNING) << __func__
+                 << StringPrintf(
+                        ": not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p",
+                        operation, p_disc_cmpl_cb, p_cmpl_cb);
 }
 
-/*******************************************************************************
- *
- * Function         gatt_cleanup_upon_disc
- *
- * Description      This function cleans up the control blocks when L2CAP
- *                  channel disconnect.
- *
- * Returns          16 bits uuid.
- *
- ******************************************************************************/
-void gatt_cleanup_upon_disc(BD_ADDR bda, uint16_t reason,
+/** This function cleans up the control blocks when L2CAP channel disconnect */
+void gatt_cleanup_upon_disc(const RawAddress& bda, uint16_t reason,
                             tBT_TRANSPORT transport) {
-  tGATT_TCB* p_tcb = NULL;
-  tGATT_CLCB* p_clcb;
-  uint8_t i;
-  uint16_t conn_id;
-  tGATT_REG* p_reg = NULL;
+  VLOG(1) << __func__;
 
-  GATT_TRACE_DEBUG("gatt_cleanup_upon_disc ");
+  tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, transport);
+  if (!p_tcb) return;
 
-  p_tcb = gatt_find_tcb_by_addr(bda, transport);
-  if (p_tcb != NULL) {
-    GATT_TRACE_DEBUG("found p_tcb ");
-    gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
-    for (i = 0; i < GATT_CL_MAX_LCB; i++) {
-      p_clcb = &gatt_cb.clcb[i];
-      if (p_clcb->in_use && p_clcb->p_tcb == p_tcb) {
-        alarm_cancel(p_clcb->gatt_rsp_timer_ent);
-        GATT_TRACE_DEBUG("found p_clcb conn_id=%d", p_clcb->conn_id);
-        if (p_clcb->operation != GATTC_OPTYPE_NONE)
-          gatt_end_operation(p_clcb, GATT_ERROR, NULL);
+  gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
+  for (uint8_t i = 0; i < GATT_CL_MAX_LCB; i++) {
+    tGATT_CLCB* p_clcb = &gatt_cb.clcb[i];
+    if (!p_clcb->in_use || p_clcb->p_tcb != p_tcb) continue;
 
-        gatt_clcb_dealloc(p_clcb);
-      }
+    alarm_cancel(p_clcb->gatt_rsp_timer_ent);
+    VLOG(1) << "found p_clcb conn_id=" << +p_clcb->conn_id;
+    if (p_clcb->operation == GATTC_OPTYPE_NONE) {
+      gatt_clcb_dealloc(p_clcb);
+      continue;
     }
 
-    alarm_free(p_tcb->ind_ack_timer);
-    p_tcb->ind_ack_timer = NULL;
-    alarm_free(p_tcb->conf_timer);
-    p_tcb->conf_timer = NULL;
-    gatt_free_pending_ind(p_tcb);
-    fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
-    p_tcb->sr_cmd.multi_rsp_q = NULL;
-
-    for (i = 0; i < GATT_MAX_APPS; i++) {
-      p_reg = &gatt_cb.cl_rcb[i];
-      if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
-        conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
-        GATT_TRACE_DEBUG("found p_reg tcb_idx=%d gatt_if=%d  conn_id=0x%x",
-                         p_tcb->tcb_idx, p_reg->gatt_if, conn_id);
-        (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, false, reason,
-                                   transport);
-      }
-    }
-    *p_tcb = tGATT_TCB();
+    gatt_end_operation(p_clcb, GATT_ERROR, NULL);
   }
-  GATT_TRACE_DEBUG("exit gatt_cleanup_upon_disc ");
+
+  alarm_free(p_tcb->ind_ack_timer);
+  p_tcb->ind_ack_timer = NULL;
+  alarm_free(p_tcb->conf_timer);
+  p_tcb->conf_timer = NULL;
+  gatt_free_pending_ind(p_tcb);
+  fixed_queue_free(p_tcb->sr_cmd.multi_rsp_q, NULL);
+  p_tcb->sr_cmd.multi_rsp_q = NULL;
+
+  for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+    tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
+    if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
+      uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+      VLOG(1) << StringPrintf("found p_reg tcb_idx=%d gatt_if=%d  conn_id=0x%x",
+                              p_tcb->tcb_idx, p_reg->gatt_if, conn_id);
+      (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, false, reason,
+                                 transport);
+    }
+  }
+
+  *p_tcb = tGATT_TCB();
+  VLOG(1) << __func__ << ": exit";
 }
 /*******************************************************************************
  *
@@ -1501,7 +1471,7 @@
   } else
     strlcpy(str_buf, "Unknown UUID 0", sizeof(str_buf));
 
-  GATT_TRACE_DEBUG("UUID=[%s]", str_buf);
+  VLOG(1) << StringPrintf("UUID=[%s]", str_buf);
 }
 
 /** Returns true if this is one of the background devices for the application,
@@ -1512,19 +1482,20 @@
 
 /** background connection device from the list. Returns pointer to the device
  * record, or nullptr if not found */
-tGATT_BG_CONN_DEV* gatt_find_bg_dev(BD_ADDR remote_bda) {
+tGATT_BG_CONN_DEV* gatt_find_bg_dev(const RawAddress& remote_bda) {
   for (tGATT_BG_CONN_DEV& dev : gatt_cb.bgconn_dev) {
-    if (!memcmp(dev.remote_bda, remote_bda, BD_ADDR_LEN)) {
+    if (dev.remote_bda == remote_bda) {
       return &dev;
     }
   }
   return nullptr;
 }
 
-std::list<tGATT_BG_CONN_DEV>::iterator gatt_find_bg_dev_it(BD_ADDR remote_bda) {
+std::list<tGATT_BG_CONN_DEV>::iterator gatt_find_bg_dev_it(
+    const RawAddress& remote_bda) {
   auto& list = gatt_cb.bgconn_dev;
   for (auto it = list.begin(); it != list.end(); it++) {
-    if (!memcmp(it->remote_bda, remote_bda, BD_ADDR_LEN)) {
+    if (it->remote_bda == remote_bda) {
       return it;
     }
   }
@@ -1533,14 +1504,14 @@
 
 /** Add a device from the background connection list.  Returns true if device
  * added to the list, or already in list, false otherwise */
-bool gatt_add_bg_dev_list(tGATT_REG* p_reg, BD_ADDR bd_addr) {
+bool gatt_add_bg_dev_list(tGATT_REG* p_reg, const RawAddress& bd_addr) {
   tGATT_IF gatt_if = p_reg->gatt_if;
 
   tGATT_BG_CONN_DEV* p_dev = gatt_find_bg_dev(bd_addr);
   if (p_dev) {
     // device already in the whitelist, just add interested app to the list
     if (!p_dev->gatt_if.insert(gatt_if).second) {
-      GATT_TRACE_ERROR("device already in iniator white list");
+      LOG(ERROR) << "device already in iniator white list";
     }
 
     return true;
@@ -1551,13 +1522,13 @@
 
   gatt_cb.bgconn_dev.emplace_back();
   tGATT_BG_CONN_DEV& dev = gatt_cb.bgconn_dev.back();
-  memcpy(dev.remote_bda, bd_addr, BD_ADDR_LEN);
+  dev.remote_bda = bd_addr;
   dev.gatt_if.insert(gatt_if);
   return true;
 }
 
 /** Remove the application interface for the specified background device */
-bool gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr) {
+bool gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, const RawAddress& bd_addr) {
   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
   bool status;
 
@@ -1568,7 +1539,7 @@
 
 /** Removes all registrations for background connection for given device.
  * Returns true if anything was removed, false otherwise */
-uint8_t gatt_clear_bg_dev_for_addr(BD_ADDR bd_addr) {
+uint8_t gatt_clear_bg_dev_for_addr(const RawAddress& bd_addr) {
   auto dev_it = gatt_find_bg_dev_it(bd_addr);
   if (dev_it == gatt_cb.bgconn_dev.end()) return false;
 
@@ -1580,7 +1551,7 @@
 /** Remove device from the background connection device list or listening to
  * advertising list.  Returns true if device was on the list and was succesfully
  * removed */
-bool gatt_remove_bg_dev_from_list(tGATT_REG* p_reg, BD_ADDR bd_addr) {
+bool gatt_remove_bg_dev_from_list(tGATT_REG* p_reg, const RawAddress& bd_addr) {
   tGATT_IF gatt_if = p_reg->gatt_if;
   auto dev_it = gatt_find_bg_dev_it(bd_addr);
   if (dev_it == gatt_cb.bgconn_dev.end()) return false;
@@ -1635,17 +1606,18 @@
  * Returns          true if connection started; false otherwise.
  *
  ******************************************************************************/
-bool gatt_update_auto_connect_dev(tGATT_IF gatt_if, bool add, BD_ADDR bd_addr) {
+bool gatt_update_auto_connect_dev(tGATT_IF gatt_if, bool add,
+                                  const RawAddress& bd_addr) {
   bool ret = false;
   tGATT_REG* p_reg;
   tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
 
-  GATT_TRACE_API("%s:", __func__);
+  VLOG(1) << __func__;
   /* Make sure app is registered */
   p_reg = gatt_get_regcb(gatt_if);
   if (p_reg == NULL) {
-    GATT_TRACE_ERROR("%s - gatt_if is not registered", __func__, gatt_if);
-    return (false);
+    LOG(ERROR) << __func__ << " gatt_if is not registered " << +gatt_if;
+    return false;
   }
 
   if (add) {
diff --git a/stack/hcic/hciblecmds.cc b/stack/hcic/hciblecmds.cc
index 330764b..041d1e0 100644
--- a/stack/hcic/hciblecmds.cc
+++ b/stack/hcic/hciblecmds.cc
@@ -46,7 +46,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_ble_set_random_addr(BD_ADDR random_bda) {
+void btsnd_hcic_ble_set_random_addr(const RawAddress& random_bda) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -63,7 +63,8 @@
 
 void btsnd_hcic_ble_write_adv_params(uint16_t adv_int_min, uint16_t adv_int_max,
                                      uint8_t adv_type, uint8_t addr_type_own,
-                                     uint8_t addr_type_dir, BD_ADDR direct_bda,
+                                     uint8_t addr_type_dir,
+                                     const RawAddress& direct_bda,
                                      uint8_t channel_map,
                                      uint8_t adv_filter_policy) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
@@ -197,13 +198,11 @@
 }
 
 /* link layer connection management commands */
-void btsnd_hcic_ble_create_ll_conn(uint16_t scan_int, uint16_t scan_win,
-                                   uint8_t init_filter_policy,
-                                   uint8_t addr_type_peer, BD_ADDR bda_peer,
-                                   uint8_t addr_type_own, uint16_t conn_int_min,
-                                   uint16_t conn_int_max, uint16_t conn_latency,
-                                   uint16_t conn_timeout, uint16_t min_ce_len,
-                                   uint16_t max_ce_len) {
+void btsnd_hcic_ble_create_ll_conn(
+    uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
+    uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
+    uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
+    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -258,7 +257,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_ble_add_white_list(uint8_t addr_type, BD_ADDR bda) {
+void btsnd_hcic_ble_add_white_list(uint8_t addr_type, const RawAddress& bda) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -274,7 +273,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_ble_remove_from_white_list(uint8_t addr_type, BD_ADDR bda) {
+void btsnd_hcic_ble_remove_from_white_list(uint8_t addr_type,
+                                           const RawAddress& bda) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -561,7 +561,7 @@
 #endif
 
 void btsnd_hcic_ble_add_device_resolving_list(
-    uint8_t addr_type_peer, BD_ADDR bda_peer,
+    uint8_t addr_type_peer, const RawAddress& bda_peer,
     uint8_t irk_peer[HCIC_BLE_IRK_SIZE], uint8_t irk_local[HCIC_BLE_IRK_SIZE]) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
@@ -580,7 +580,7 @@
 }
 
 void btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer,
-                                             BD_ADDR bda_peer) {
+                                             const RawAddress& bda_peer) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -595,7 +595,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_ble_set_privacy_mode(uint8_t addr_type_peer, BD_ADDR bda_peer,
+void btsnd_hcic_ble_set_privacy_mode(uint8_t addr_type_peer,
+                                     const RawAddress& bda_peer,
                                      uint8_t privacy_type) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
@@ -626,7 +627,7 @@
 }
 
 void btsnd_hcic_ble_read_resolvable_addr_peer(uint8_t addr_type_peer,
-                                              BD_ADDR bda_peer) {
+                                              const RawAddress& bda_peer) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -642,7 +643,7 @@
 }
 
 void btsnd_hcic_ble_read_resolvable_addr_local(uint8_t addr_type_peer,
-                                               BD_ADDR bda_peer) {
+                                               const RawAddress& bda_peer) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -703,6 +704,42 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
+void btsnd_hcic_ble_enh_rx_test(uint8_t rx_chan, uint8_t phy,
+                                uint8_t mod_index) {
+  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
+  uint8_t* pp = (uint8_t*)(p + 1);
+
+  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENH_RX_TEST;
+  p->offset = 0;
+
+  UINT16_TO_STREAM(pp, HCI_BLE_ENH_RECEIVER_TEST);
+  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENH_RX_TEST);
+
+  UINT8_TO_STREAM(pp, rx_chan);
+  UINT8_TO_STREAM(pp, phy);
+  UINT8_TO_STREAM(pp, mod_index);
+
+  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+void btsnd_hcic_ble_enh_tx_test(uint8_t tx_chan, uint8_t data_len,
+                                uint8_t payload, uint8_t phy) {
+  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
+  uint8_t* pp = (uint8_t*)(p + 1);
+
+  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENH_TX_TEST;
+  p->offset = 0;
+
+  UINT16_TO_STREAM(pp, HCI_BLE_ENH_TRANSMITTER_TEST);
+  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENH_TX_TEST);
+  UINT8_TO_STREAM(pp, tx_chan);
+  UINT8_TO_STREAM(pp, data_len);
+  UINT8_TO_STREAM(pp, payload);
+  UINT8_TO_STREAM(pp, phy);
+
+  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
 void btsnd_hcic_ble_set_extended_scan_params(uint8_t own_address_type,
                                              uint8_t scanning_filter_policy,
                                              uint8_t scanning_phys,
@@ -757,7 +794,8 @@
 
 void btsnd_hcic_ble_ext_create_conn(uint8_t init_filter_policy,
                                     uint8_t addr_type_own,
-                                    uint8_t addr_type_peer, BD_ADDR bda_peer,
+                                    uint8_t addr_type_peer,
+                                    const RawAddress& bda_peer,
                                     uint8_t initiating_phys,
                                     EXT_CONN_PHY_CFG* phy_cfg) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
diff --git a/stack/hcic/hcicmds.cc b/stack/hcic/hcicmds.cc
index 6292baa..f3277e1 100644
--- a/stack/hcic/hcicmds.cc
+++ b/stack/hcic/hcicmds.cc
@@ -1,20 +1,20 @@
 /******************************************************************************
- *
- *  Copyright (C) 1999-2012 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
+*
+*  Copyright (C) 1999-2012 Broadcom Corporation
+*
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at:
+*
+*  http://www.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*
+******************************************************************************/
 
 /******************************************************************************
  *
@@ -29,6 +29,7 @@
 #include "hcidefs.h"
 #include "hcimsgs.h"
 
+#include <base/bind.h>
 #include <stddef.h>
 #include <string.h>
 
@@ -97,7 +98,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_create_conn(BD_ADDR dest, uint16_t packet_types,
+void btsnd_hcic_create_conn(const RawAddress& dest, uint16_t packet_types,
                             uint8_t page_scan_rep_mode, uint8_t page_scan_mode,
                             uint16_t clock_offset, uint8_t allow_switch) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
@@ -160,7 +161,7 @@
 }
 #endif /* BTM_SCO_INCLUDED */
 
-void btsnd_hcic_create_conn_cancel(BD_ADDR dest) {
+void btsnd_hcic_create_conn_cancel(const RawAddress& dest) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -175,7 +176,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_accept_conn(BD_ADDR dest, uint8_t role) {
+void btsnd_hcic_accept_conn(const RawAddress& dest, uint8_t role) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -190,7 +191,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_reject_conn(BD_ADDR dest, uint8_t reason) {
+void btsnd_hcic_reject_conn(const RawAddress& dest, uint8_t reason) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -206,7 +207,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_link_key_req_reply(BD_ADDR bd_addr, LINK_KEY link_key) {
+void btsnd_hcic_link_key_req_reply(const RawAddress& bd_addr,
+                                   LINK_KEY link_key) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -222,7 +224,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_link_key_neg_reply(BD_ADDR bd_addr) {
+void btsnd_hcic_link_key_neg_reply(const RawAddress& bd_addr) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -237,8 +239,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_pin_code_req_reply(BD_ADDR bd_addr, uint8_t pin_code_len,
-                                   PIN_CODE pin_code) {
+void btsnd_hcic_pin_code_req_reply(const RawAddress& bd_addr,
+                                   uint8_t pin_code_len, PIN_CODE pin_code) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
   int i;
@@ -259,7 +261,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_pin_code_neg_reply(BD_ADDR bd_addr) {
+void btsnd_hcic_pin_code_neg_reply(const RawAddress& bd_addr) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -321,8 +323,9 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_rmt_name_req(BD_ADDR bd_addr, uint8_t page_scan_rep_mode,
-                             uint8_t page_scan_mode, uint16_t clock_offset) {
+void btsnd_hcic_rmt_name_req(const RawAddress& bd_addr,
+                             uint8_t page_scan_rep_mode, uint8_t page_scan_mode,
+                             uint16_t clock_offset) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -340,7 +343,7 @@
   btm_acl_paging(p, bd_addr);
 }
 
-void btsnd_hcic_rmt_name_req_cancel(BD_ADDR bd_addr) {
+void btsnd_hcic_rmt_name_req_cancel(const RawAddress& bd_addr) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -455,7 +458,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_accept_esco_conn(BD_ADDR bd_addr, uint32_t transmit_bandwidth,
+void btsnd_hcic_accept_esco_conn(const RawAddress& bd_addr,
+                                 uint32_t transmit_bandwidth,
                                  uint32_t receive_bandwidth,
                                  uint16_t max_latency, uint16_t content_fmt,
                                  uint8_t retrans_effort,
@@ -480,7 +484,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_reject_esco_conn(BD_ADDR bd_addr, uint8_t reason) {
+void btsnd_hcic_reject_esco_conn(const RawAddress& bd_addr, uint8_t reason) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -606,7 +610,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_switch_role(BD_ADDR bd_addr, uint8_t role) {
+void btsnd_hcic_switch_role(const RawAddress& bd_addr, uint8_t role) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -675,7 +679,7 @@
 
       filt_cond_len -= (2 * DEV_CLASS_LEN);
     } else if (filt_cond_type == HCI_FILTER_COND_BD_ADDR) {
-      BDADDR_TO_STREAM(pp, filt_cond);
+      BDADDR_TO_STREAM(pp, *((RawAddress*)filt_cond));
       filt_cond += BD_ADDR_LEN;
 
       filt_cond_len -= BD_ADDR_LEN;
@@ -707,7 +711,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_delete_stored_key(BD_ADDR bd_addr, bool delete_all_flag) {
+void btsnd_hcic_delete_stored_key(const RawAddress& bd_addr,
+                                  bool delete_all_flag) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -867,11 +872,11 @@
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
-  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT;
+  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_AUTOMATIC_FLUSH_TIMEOUT;
   p->offset = 0;
 
-  UINT16_TO_STREAM(pp, HCI_WRITE_AUTO_FLUSH_TOUT);
-  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT);
+  UINT16_TO_STREAM(pp, HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT);
+  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_AUTOMATIC_FLUSH_TIMEOUT);
 
   UINT16_TO_STREAM(pp, handle);
   UINT16_TO_STREAM(pp, tout);
@@ -992,7 +997,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_io_cap_req_reply(BD_ADDR bd_addr, uint8_t capability,
+void btsnd_hcic_io_cap_req_reply(const RawAddress& bd_addr, uint8_t capability,
                                  uint8_t oob_present, uint8_t auth_req) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
@@ -1061,7 +1066,7 @@
 }
 
 void btsnd_hcic_enhanced_accept_synchronous_connection(
-    BD_ADDR bd_addr, enh_esco_params_t* p_params) {
+    const RawAddress& bd_addr, enh_esco_params_t* p_params) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -1109,7 +1114,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_io_cap_req_neg_reply(BD_ADDR bd_addr, uint8_t err_code) {
+void btsnd_hcic_io_cap_req_neg_reply(const RawAddress& bd_addr,
+                                     uint8_t err_code) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -1138,7 +1144,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_user_conf_reply(BD_ADDR bd_addr, bool is_yes) {
+void btsnd_hcic_user_conf_reply(const RawAddress& bd_addr, bool is_yes) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -1160,7 +1166,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_user_passkey_reply(BD_ADDR bd_addr, uint32_t value) {
+void btsnd_hcic_user_passkey_reply(const RawAddress& bd_addr, uint32_t value) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -1176,7 +1182,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_user_passkey_neg_reply(BD_ADDR bd_addr) {
+void btsnd_hcic_user_passkey_neg_reply(const RawAddress& bd_addr) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -1191,7 +1197,8 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_rem_oob_reply(BD_ADDR bd_addr, uint8_t* p_c, uint8_t* p_r) {
+void btsnd_hcic_rem_oob_reply(const RawAddress& bd_addr, uint8_t* p_c,
+                              uint8_t* p_r) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -1208,7 +1215,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_rem_oob_neg_reply(BD_ADDR bd_addr) {
+void btsnd_hcic_rem_oob_neg_reply(const RawAddress& bd_addr) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -1236,7 +1243,7 @@
   btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
 }
 
-void btsnd_hcic_send_keypress_notif(BD_ADDR bd_addr, uint8_t notif) {
+void btsnd_hcic_send_keypress_notif(const RawAddress& bd_addr, uint8_t notif) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
 
@@ -1305,6 +1312,62 @@
   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) {
+  uint8_t status;
+  uint16_t handle;
+  uint8_t key_size;
+  STREAM_TO_UINT8(status, return_parameters);
+  STREAM_TO_UINT16(handle, return_parameters);
+  STREAM_TO_UINT8(key_size, return_parameters);
+
+  std::move(cb).Run(status, handle, key_size);
+}
+
+void btsnd_hcic_read_encryption_key_size(uint16_t handle, ReadEncKeySizeCb cb) {
+  constexpr uint8_t len = 2;
+  uint8_t param[len];
+  memset(param, 0, len);
+
+  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)));
+}
+
+void btsnd_hcic_read_failed_contact_counter(uint16_t handle) {
+  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
+  uint8_t* pp = (uint8_t*)(p + 1);
+
+  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE;
+  p->offset = 0;
+
+  UINT16_TO_STREAM(pp, HCI_READ_FAILED_CONTACT_COUNTER);
+  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE);
+
+  UINT16_TO_STREAM(pp, handle);
+
+  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
+void btsnd_hcic_read_automatic_flush_timeout(uint16_t handle) {
+  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
+  uint8_t* pp = (uint8_t*)(p + 1);
+
+  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CMD_HANDLE;
+  p->offset = 0;
+
+  UINT16_TO_STREAM(pp, HCI_READ_AUTOMATIC_FLUSH_TIMEOUT);
+  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CMD_HANDLE);
+
+  UINT16_TO_STREAM(pp, handle);
+
+  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
+}
+
 void btsnd_hcic_enable_test_mode(void) {
   BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
   uint8_t* pp = (uint8_t*)(p + 1);
diff --git a/stack/hid/hidd_api.cc b/stack/hid/hidd_api.cc
index 9879095..8ae70c3 100644
--- a/stack/hid/hidd_api.cc
+++ b/stack/hid/hidd_api.cc
@@ -424,9 +424,9 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-tHID_STATUS HID_DevPlugDevice(BD_ADDR addr) {
+tHID_STATUS HID_DevPlugDevice(const RawAddress& addr) {
   hd_cb.device.in_use = TRUE;
-  memcpy(hd_cb.device.addr, addr, sizeof(BD_ADDR));
+  hd_cb.device.addr = addr;
 
   return HID_SUCCESS;
 }
@@ -440,8 +440,8 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-tHID_STATUS HID_DevUnplugDevice(BD_ADDR addr) {
-  if (!memcmp(hd_cb.device.addr, addr, sizeof(BD_ADDR))) {
+tHID_STATUS HID_DevUnplugDevice(const RawAddress& addr) {
+  if (hd_cb.device.addr == addr) {
     hd_cb.device.in_use = FALSE;
     hd_cb.device.conn.conn_state = HID_CONN_STATE_UNUSED;
     hd_cb.device.conn.ctrl_cid = 0;
@@ -566,11 +566,11 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-tHID_STATUS HID_DevGetDevice(BD_ADDR* addr) {
+tHID_STATUS HID_DevGetDevice(RawAddress* addr) {
   HIDD_TRACE_API("%s", __func__);
 
   if (hd_cb.device.in_use) {
-    memcpy(addr, hd_cb.device.addr, sizeof(BD_ADDR));
+    *addr = hd_cb.device.addr;
   } else {
     return HID_ERR_NOT_REGISTERED;
   }
diff --git a/stack/hid/hidd_conn.cc b/stack/hid/hidd_conn.cc
index c76e545..cb08715 100644
--- a/stack/hid/hidd_conn.cc
+++ b/stack/hid/hidd_conn.cc
@@ -44,8 +44,8 @@
 
 #include "osi/include/osi.h"
 
-static void hidd_l2cif_connect_ind(BD_ADDR bd_addr, uint16_t cid, uint16_t psm,
-                                   uint8_t id);
+static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid,
+                                   uint16_t psm, uint8_t id);
 static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result);
 static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO* p_cfg);
 static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO* p_cfg);
@@ -107,7 +107,7 @@
  *                  send security block L2C connection response.
  *
  ******************************************************************************/
-static void hidd_sec_check_complete(UNUSED_ATTR BD_ADDR bd_addr,
+static void hidd_sec_check_complete(UNUSED_ATTR const RawAddress* bd_addr,
                                     UNUSED_ATTR tBT_TRANSPORT transport,
                                     void* p_ref_data, uint8_t res) {
   tHID_DEV_DEV_CTB* p_dev = (tHID_DEV_DEV_CTB*)p_ref_data;
@@ -140,7 +140,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void hidd_sec_check_complete_orig(UNUSED_ATTR BD_ADDR bd_addr,
+void hidd_sec_check_complete_orig(UNUSED_ATTR const RawAddress* bd_addr,
                                   UNUSED_ATTR tBT_TRANSPORT transport,
                                   void* p_ref_data, uint8_t res) {
   tHID_DEV_DEV_CTB* p_dev = (tHID_DEV_DEV_CTB*)p_ref_data;
@@ -173,8 +173,8 @@
  * Returns          void
  *
  ******************************************************************************/
-static void hidd_l2cif_connect_ind(BD_ADDR bd_addr, uint16_t cid, uint16_t psm,
-                                   uint8_t id) {
+static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid,
+                                   uint16_t psm, uint8_t id) {
   tHID_CONN* p_hcon;
   tHID_DEV_DEV_CTB* p_dev;
   bool accept = TRUE;  // accept by default
@@ -190,14 +190,14 @@
     return;
   }
 
-  if (p_dev->in_use && memcmp(bd_addr, p_dev->addr, sizeof(BD_ADDR))) {
+  if (p_dev->in_use && bd_addr != p_dev->addr) {
     HIDD_TRACE_WARNING(
         "%s: incoming connections from different device, rejecting", __func__);
     L2CA_ConnectRsp(bd_addr, id, cid, L2CAP_CONN_NO_RESOURCES, 0);
     return;
   } else if (!p_dev->in_use) {
     p_dev->in_use = TRUE;
-    memcpy(p_dev->addr, bd_addr, sizeof(BD_ADDR));
+    p_dev->addr = bd_addr;
     p_dev->state = HIDD_DEV_NO_CONN;
   }
 
diff --git a/stack/hid/hidd_int.h b/stack/hid/hidd_int.h
index cce1302..81e60ca 100644
--- a/stack/hid/hidd_int.h
+++ b/stack/hid/hidd_int.h
@@ -34,7 +34,7 @@
 
 typedef struct device_ctb {
   bool in_use;
-  BD_ADDR addr;
+  RawAddress addr;
 
   uint8_t state;
 
diff --git a/stack/hid/hidh_api.cc b/stack/hid/hidh_api.cc
index a290b77..adbc931 100644
--- a/stack/hid/hidh_api.cc
+++ b/stack/hid/hidh_api.cc
@@ -48,8 +48,8 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-tHID_STATUS HID_HostGetSDPRecord(BD_ADDR addr, tSDP_DISCOVERY_DB* p_db,
-                                 uint32_t db_len,
+tHID_STATUS HID_HostGetSDPRecord(const RawAddress& addr,
+                                 tSDP_DISCOVERY_DB* p_db, uint32_t db_len,
                                  tHID_HOST_SDP_CALLBACK* sdp_cback) {
   tSDP_UUID uuid_list;
 
@@ -233,11 +233,6 @@
   uint8_t log_level = hh_cb.trace_level;
   memset(&hh_cb, 0, sizeof(tHID_HOST_CTB));
   hh_cb.trace_level = log_level;
-
-  for (size_t i = 0; i < HID_HOST_MAX_DEVICES; i++) {
-    hh_cb.devices[i].conn.process_repage_timer =
-        alarm_new("hid_devices_conn.process_repage_timer");
-  }
 }
 
 /*******************************************************************************
@@ -281,6 +276,10 @@
   hh_cb.callback = dev_cback;
   hh_cb.reg_flag = true;
 
+  for (size_t i = 0; i < HID_HOST_MAX_DEVICES; i++) {
+    hh_cb.devices[i].conn.process_repage_timer =
+        alarm_new("hid_devices_conn.process_repage_timer");
+  }
   return (HID_SUCCESS);
 }
 
@@ -299,6 +298,7 @@
   if (!hh_cb.reg_flag) return (HID_ERR_NOT_REGISTERED);
 
   for (i = 0; i < HID_HOST_MAX_DEVICES; i++) {
+    alarm_free(hh_cb.devices[i].conn.process_repage_timer);
     HID_HostRemoveDev(i);
   }
 
@@ -317,15 +317,14 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-tHID_STATUS HID_HostAddDev(BD_ADDR addr, uint16_t attr_mask, uint8_t* handle) {
+tHID_STATUS HID_HostAddDev(const RawAddress& addr, uint16_t attr_mask,
+                           uint8_t* handle) {
   int i;
   /* Find an entry for this device in hh_cb.devices array */
   if (!hh_cb.reg_flag) return (HID_ERR_NOT_REGISTERED);
 
   for (i = 0; i < HID_HOST_MAX_DEVICES; i++) {
-    if ((hh_cb.devices[i].in_use) &&
-        (!memcmp(addr, hh_cb.devices[i].addr, BD_ADDR_LEN)))
-      break;
+    if ((hh_cb.devices[i].in_use) && addr == hh_cb.devices[i].addr) break;
   }
 
   if (i == HID_HOST_MAX_DEVICES) {
@@ -338,7 +337,7 @@
 
   if (!hh_cb.devices[i].in_use) {
     hh_cb.devices[i].in_use = true;
-    memcpy(hh_cb.devices[i].addr, addr, sizeof(BD_ADDR));
+    hh_cb.devices[i].addr = addr;
     hh_cb.devices[i].state = HID_DEV_NO_CONN;
     hh_cb.devices[i].conn_tries = 0;
   }
@@ -520,7 +519,7 @@
  * Returns          true if device is HID Device else false
  *
  ******************************************************************************/
-bool hid_known_hid_device(BD_ADDR bd_addr) {
+bool hid_known_hid_device(const RawAddress& bd_addr) {
   uint8_t i;
   tBTM_INQ_INFO* p_inq_info = BTM_InqDbRead(bd_addr);
 
@@ -550,8 +549,7 @@
 
   /* Find an entry for this device in hh_cb.devices array */
   for (i = 0; i < HID_HOST_MAX_DEVICES; i++) {
-    if ((hh_cb.devices[i].in_use) &&
-        (memcmp(bd_addr, hh_cb.devices[i].addr, BD_ADDR_LEN) == 0))
+    if ((hh_cb.devices[i].in_use) && bd_addr == hh_cb.devices[i].addr)
       return true;
   }
   /* Check if this device is marked as HID Device in IOP Dev */
diff --git a/stack/hid/hidh_conn.cc b/stack/hid/hidh_conn.cc
index 9abe679..a41aa90 100644
--- a/stack/hid/hidh_conn.cc
+++ b/stack/hid/hidh_conn.cc
@@ -45,16 +45,15 @@
 #include "log/log.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 static uint8_t find_conn_by_cid(uint16_t cid);
 static void hidh_conn_retry(uint8_t dhandle);
 
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
-static void hidh_l2cif_connect_ind(BD_ADDR bd_addr, uint16_t l2cap_cid,
-                                   uint16_t psm, uint8_t l2cap_id);
+static void hidh_l2cif_connect_ind(const RawAddress& bd_addr,
+                                   uint16_t l2cap_cid, uint16_t psm,
+                                   uint8_t l2cap_id);
 static void hidh_l2cif_connect_cfm(uint16_t l2cap_cid, uint16_t result);
 static void hidh_l2cif_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
 static void hidh_l2cif_config_cfm(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
@@ -159,7 +158,7 @@
  *                  send security block L2C connection response.
  *
  ******************************************************************************/
-void hidh_sec_check_complete_term(UNUSED_ATTR BD_ADDR bd_addr,
+void hidh_sec_check_complete_term(UNUSED_ATTR const RawAddress* bd_addr,
                                   UNUSED_ATTR tBT_TRANSPORT transport,
                                   void* p_ref_data, uint8_t res) {
   tHID_HOST_DEV_CTB* p_dev = (tHID_HOST_DEV_CTB*)p_ref_data;
@@ -200,8 +199,9 @@
  * Returns          void
  *
  ******************************************************************************/
-static void hidh_l2cif_connect_ind(BD_ADDR bd_addr, uint16_t l2cap_cid,
-                                   uint16_t psm, uint8_t l2cap_id) {
+static void hidh_l2cif_connect_ind(const RawAddress& bd_addr,
+                                   uint16_t l2cap_cid, uint16_t psm,
+                                   uint8_t l2cap_id) {
   tHID_CONN* p_hcon;
   bool bAccept = true;
   uint8_t i = HID_HOST_MAX_DEVICES;
@@ -322,7 +322,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void hidh_sec_check_complete_orig(UNUSED_ATTR BD_ADDR bd_addr,
+void hidh_sec_check_complete_orig(UNUSED_ATTR const RawAddress* bd_addr,
                                   UNUSED_ATTR tBT_TRANSPORT transport,
                                   void* p_ref_data, uint8_t res) {
   tHID_HOST_DEV_CTB* p_dev = (tHID_HOST_DEV_CTB*)p_ref_data;
@@ -657,9 +657,9 @@
         (hh_cb.devices[dhandle].attr_mask & HID_NORMALLY_CONNECTABLE)) {
       hh_cb.devices[dhandle].conn_tries = 0;
       period_ms_t interval_ms = HID_HOST_REPAGE_WIN * 1000;
-      alarm_set_on_queue(hh_cb.devices[dhandle].conn.process_repage_timer,
+      alarm_set_on_mloop(hh_cb.devices[dhandle].conn.process_repage_timer,
                          interval_ms, hidh_process_repage_timer_timeout,
-                         UINT_TO_PTR(dhandle), btu_general_alarm_queue);
+                         UINT_TO_PTR(dhandle));
       hh_cb.callback(dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE,
                      disc_res, NULL);
     } else
@@ -1074,9 +1074,8 @@
   p_dev->conn.conn_state = HID_CONN_STATE_UNUSED;
 #if (HID_HOST_REPAGE_WIN > 0)
   period_ms_t interval_ms = HID_HOST_REPAGE_WIN * 1000;
-  alarm_set_on_queue(p_dev->conn.process_repage_timer, interval_ms,
-                     hidh_process_repage_timer_timeout, UINT_TO_PTR(dhandle),
-                     btu_general_alarm_queue);
+  alarm_set_on_mloop(p_dev->conn.process_repage_timer, interval_ms,
+                     hidh_process_repage_timer_timeout, UINT_TO_PTR(dhandle));
 #else
   hidh_try_repage(dhandle);
 #endif
diff --git a/stack/hid/hidh_int.h b/stack/hid/hidh_int.h
index e584320..c332403 100644
--- a/stack/hid/hidh_int.h
+++ b/stack/hid/hidh_int.h
@@ -33,7 +33,7 @@
 
 typedef struct per_device_ctb {
   bool in_use;
-  BD_ADDR addr;       /* BD-Addr of the host device */
+  RawAddress addr;    /* BD-Addr of the host device */
   uint16_t attr_mask; /* 0x01- virtual_cable; 0x02- normally_connectable; 0x03-
                          reconn_initiate;
                                  0x04- sdp_disable; */
diff --git a/stack/include/a2dp_api.h b/stack/include/a2dp_api.h
index 15d30d8..ee215a9 100644
--- a/stack/include/a2dp_api.h
+++ b/stack/include/a2dp_api.h
@@ -156,7 +156,8 @@
  *                  A2DP_FAIL if function execution failed.
  *
  *****************************************************************************/
-extern tA2DP_STATUS A2DP_FindService(uint16_t service_uuid, BD_ADDR bd_addr,
+extern tA2DP_STATUS A2DP_FindService(uint16_t service_uuid,
+                                     const RawAddress& bd_addr,
                                      tA2DP_SDP_DB_PARAMS* p_db,
                                      tA2DP_FIND_CBACK* p_cback);
 
diff --git a/stack/include/a2dp_codec_api.h b/stack/include/a2dp_codec_api.h
index 94871ce..cdc4721 100644
--- a/stack/include/a2dp_codec_api.h
+++ b/stack/include/a2dp_codec_api.h
@@ -409,8 +409,8 @@
 
  private:
   struct CompareBtBdaddr
-      : public std::binary_function<bt_bdaddr_t, bt_bdaddr_t, bool> {
-    bool operator()(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) const {
+      : public std::binary_function<RawAddress, RawAddress, bool> {
+    bool operator()(const RawAddress& lhs, const RawAddress& rhs) const {
       return (memcmp(&lhs, &rhs, sizeof(lhs)) < 0);
     }
   };
@@ -430,7 +430,7 @@
   // A2DP Sink codecs ordered by priority
   std::list<A2dpCodecConfig*> ordered_sink_codecs_;
 
-  std::map<bt_bdaddr_t, IndexedCodecs*, CompareBtBdaddr> peer_codecs_;
+  std::map<RawAddress, IndexedCodecs*, CompareBtBdaddr> peer_codecs_;
 };
 
 /**
diff --git a/stack/include/advertise_data_parser.h b/stack/include/advertise_data_parser.h
index 0efac4f..473b979 100644
--- a/stack/include/advertise_data_parser.h
+++ b/stack/include/advertise_data_parser.h
@@ -18,9 +18,31 @@
 
 #pragma once
 
+#include <array>
 #include <vector>
 
+// Scan Response data from Traxxas
+static constexpr std::array<uint8_t, 18> trx_quirk{
+    {0x14, 0x09, 0x54, 0xFF, 0xFF, 0x20, 0x42, 0x4C, 0x45, 0x05, 0x12, 0xFF,
+     0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00}};
+
 class AdvertiseDataParser {
+  // Return true if the packet is malformed, but should be considered valid for
+  // compatibility with already existing devices
+  static bool MalformedPacketQuirk(const std::vector<uint8_t>& ad,
+                                   size_t position) {
+    auto data_start = ad.begin() + position;
+
+    // Traxxas - bad name length
+    if (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;
+    }
+
+    return false;
+  }
+
  public:
   static void RemoveTrailingZeros(std::vector<uint8_t>& ad) {
     size_t position = 0;
@@ -75,6 +97,8 @@
       // If the length of the current field would exceed the total data length,
       // then the data is badly formatted.
       if (position + len >= ad_len) {
+        if (MalformedPacketQuirk(ad, position)) return true;
+
         return false;
       }
 
diff --git a/stack/include/avct_api.h b/stack/include/avct_api.h
index 6c6914c..a0380b3 100644
--- a/stack/include/avct_api.h
+++ b/stack/include/avct_api.h
@@ -102,7 +102,7 @@
 
 /* Control callback function. */
 typedef void(tAVCT_CTRL_CBACK)(uint8_t handle, uint8_t event, uint16_t result,
-                               BD_ADDR peer_addr);
+                               const RawAddress* peer_addr);
 
 /* Message callback function */
 /* p_pkt->layer_specific is AVCT_DATA_CTRL or AVCT_DATA_BROWSE */
@@ -172,7 +172,7 @@
  *
  ******************************************************************************/
 extern uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc,
-                                BD_ADDR peer_addr);
+                                const RawAddress& peer_addr);
 
 /*******************************************************************************
  *
diff --git a/stack/include/avdt_api.h b/stack/include/avdt_api.h
index aaee2da..6fb1441 100644
--- a/stack/include/avdt_api.h
+++ b/stack/include/avdt_api.h
@@ -384,8 +384,8 @@
  * endpoints and for the AVDT_DiscoverReq() and AVDT_GetCapReq() functions.
  *
 */
-typedef void(tAVDT_CTRL_CBACK)(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                               tAVDT_CTRL* p_data);
+typedef void(tAVDT_CTRL_CBACK)(uint8_t handle, const RawAddress* bd_addr,
+                               uint8_t event, tAVDT_CTRL* p_data);
 
 /* This is the data callback function.  It is executed when AVDTP has a media
  * packet ready for the application.  This function is required for SNK
@@ -403,7 +403,7 @@
                                  tAVDT_REPORT_DATA* p_data);
 #endif
 
-typedef uint16_t(tAVDT_GETCAP_REQ)(BD_ADDR bd_addr, uint8_t seid,
+typedef uint16_t(tAVDT_GETCAP_REQ)(const RawAddress& bd_addr, uint8_t seid,
                                    tAVDT_CFG* p_cfg, tAVDT_CTRL_CBACK* p_cback);
 
 /* This structure contains information required when a stream is created.
@@ -533,8 +533,9 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-extern uint16_t AVDT_DiscoverReq(BD_ADDR bd_addr, tAVDT_SEP_INFO* p_sep_info,
-                                 uint8_t max_seps, tAVDT_CTRL_CBACK* p_cback);
+extern uint16_t AVDT_DiscoverReq(const RawAddress& bd_addr,
+                                 tAVDT_SEP_INFO* p_sep_info, uint8_t max_seps,
+                                 tAVDT_CTRL_CBACK* p_cback);
 
 /*******************************************************************************
  *
@@ -560,8 +561,8 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-extern uint16_t AVDT_GetCapReq(BD_ADDR bd_addr, uint8_t seid, tAVDT_CFG* p_cfg,
-                               tAVDT_CTRL_CBACK* p_cback);
+extern uint16_t AVDT_GetCapReq(const RawAddress& bd_addr, uint8_t seid,
+                               tAVDT_CFG* p_cfg, tAVDT_CTRL_CBACK* p_cback);
 
 /*******************************************************************************
  *
@@ -587,7 +588,7 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-extern uint16_t AVDT_GetAllCapReq(BD_ADDR bd_addr, uint8_t seid,
+extern uint16_t AVDT_GetAllCapReq(const RawAddress& bd_addr, uint8_t seid,
                                   tAVDT_CFG* p_cfg, tAVDT_CTRL_CBACK* p_cback);
 
 /*******************************************************************************
@@ -617,8 +618,8 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-extern uint16_t AVDT_OpenReq(uint8_t handle, BD_ADDR bd_addr, uint8_t seid,
-                             tAVDT_CFG* p_cfg);
+extern uint16_t AVDT_OpenReq(uint8_t handle, const RawAddress& bd_addr,
+                             uint8_t seid, tAVDT_CFG* p_cfg);
 
 /*******************************************************************************
  *
@@ -844,7 +845,7 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-extern uint16_t AVDT_ConnectReq(BD_ADDR bd_addr, uint8_t sec_mask,
+extern uint16_t AVDT_ConnectReq(const RawAddress& bd_addr, uint8_t sec_mask,
                                 tAVDT_CTRL_CBACK* p_cback);
 
 /*******************************************************************************
@@ -859,7 +860,8 @@
  * Returns          AVDT_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-extern uint16_t AVDT_DisconnectReq(BD_ADDR bd_addr, tAVDT_CTRL_CBACK* p_cback);
+extern uint16_t AVDT_DisconnectReq(const RawAddress& bd_addr,
+                                   tAVDT_CTRL_CBACK* p_cback);
 
 /*******************************************************************************
  *
@@ -882,7 +884,8 @@
  * Returns          CID if successful, otherwise 0.
  *
  ******************************************************************************/
-extern uint16_t AVDT_GetSignalChannel(uint8_t handle, BD_ADDR bd_addr);
+extern uint16_t AVDT_GetSignalChannel(uint8_t handle,
+                                      const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
diff --git a/stack/include/avdtc_api.h b/stack/include/avdtc_api.h
index 6009a8c..60a7c5f 100644
--- a/stack/include/avdtc_api.h
+++ b/stack/include/avdtc_api.h
@@ -69,8 +69,8 @@
   tAVDT_MULTI suspend_ind;
 } tAVDTC_CTRL;
 
-typedef void tAVDTC_CTRL_CBACK(uint8_t handle, BD_ADDR bd_addr, uint8_t event,
-                               tAVDTC_CTRL* p_data);
+typedef void tAVDTC_CTRL_CBACK(uint8_t handle, const RawAddress& bd_addr,
+                               uint8_t event, tAVDTC_CTRL* p_data);
 
 /*******************************************************************************
  *
@@ -94,7 +94,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void AVDTC_DiscoverRsp(BD_ADDR bd_addr, uint8_t label,
+extern void AVDTC_DiscoverRsp(const RawAddress& bd_addr, uint8_t label,
                               tAVDT_SEP_INFO sep_info[], uint8_t num_seps);
 
 /*******************************************************************************
@@ -106,7 +106,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void AVDTC_GetCapRsp(BD_ADDR bd_addr, uint8_t label, tAVDT_CFG* p_cap);
+extern void AVDTC_GetCapRsp(const RawAddress& bd_addr, uint8_t label,
+                            tAVDT_CFG* p_cap);
 
 /*******************************************************************************
  *
@@ -117,7 +118,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void AVDTC_GetAllCapRsp(BD_ADDR bd_addr, uint8_t label,
+extern void AVDTC_GetAllCapRsp(const RawAddress& bd_addr, uint8_t label,
                                tAVDT_CFG* p_cap);
 
 /*******************************************************************************
@@ -230,7 +231,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void AVDTC_Rej(uint8_t handle, BD_ADDR bd_addr, uint8_t cmd,
+extern void AVDTC_Rej(uint8_t handle, const RawAddress& bd_addr, uint8_t cmd,
                       uint8_t label, uint8_t err_code, uint8_t err_param);
 
 #endif /* AVDT_CAPI_H */
diff --git a/stack/include/avrc_api.h b/stack/include/avrc_api.h
index 5227089..cfac8d7 100644
--- a/stack/include/avrc_api.h
+++ b/stack/include/avrc_api.h
@@ -166,7 +166,7 @@
 /* This is the control callback function.  This function passes events
  * listed in Table 20 to the application. */
 typedef void(tAVRC_CTRL_CBACK)(uint8_t handle, uint8_t event, uint16_t result,
-                               BD_ADDR peer_addr);
+                               const RawAddress* peer_addr);
 
 /* This is the message callback function.  It is executed when AVCTP has
  * a message packet ready for the application.  The implementation of this
@@ -271,7 +271,8 @@
  *                                    perform the service search.
  *
  *****************************************************************************/
-extern uint16_t AVRC_FindService(uint16_t service_uuid, BD_ADDR bd_addr,
+extern uint16_t AVRC_FindService(uint16_t service_uuid,
+                                 const RawAddress& bd_addr,
                                  tAVRC_SDP_DB_PARAMS* p_db,
                                  tAVRC_FIND_CBACK* p_cback);
 
@@ -324,7 +325,7 @@
  *
  *****************************************************************************/
 extern uint16_t AVRC_Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb,
-                          BD_ADDR_PTR peer_addr);
+                          const RawAddress& peer_addr);
 
 /******************************************************************************
  *
diff --git a/stack/include/ble_advertiser.h b/stack/include/ble_advertiser.h
index b717c5a..69305c0 100644
--- a/stack/include/ble_advertiser.h
+++ b/stack/include/ble_advertiser.h
@@ -35,7 +35,7 @@
 void btm_ble_update_dmt_flag_bits(uint8_t* flag_value,
                                   const uint16_t connect_mode,
                                   const uint16_t disc_mode);
-void btm_acl_update_conn_addr(uint8_t conn_handle, BD_ADDR address);
+void btm_acl_update_conn_addr(uint16_t conn_handle, const RawAddress& address);
 
 // methods we expose to c code:
 void btm_ble_multi_adv_cleanup(void);
@@ -108,9 +108,9 @@
           timeout_cb) = 0;
 
   /* Register an advertising instance, status will be returned in |cb|
-  * callback, with assigned id, if operation succeeds. Instance is freed when
-  * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
-  * of the operations fails. */
+   * callback, with assigned id, if operation succeeds. Instance is freed when
+   * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
+   * of the operations fails. */
   virtual void RegisterAdvertiser(
       base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>) = 0;
 
@@ -146,6 +146,13 @@
   /*  This function disable a Multi-ADV instance */
   virtual void Unregister(uint8_t inst_id) = 0;
 
+  /* When resolving list is used, we need to suspend and resume all advertising
+   * instances for the time of operation. Suspend() saves current state,
+   * Resume() resumes the advertising.
+   */
+  virtual void Suspend() = 0;
+  virtual void Resume() = 0;
+
   /* This method is a member of BleAdvertiserHciInterface, and is exposed here
    * just for tests. It should never be called from upper layers*/
   virtual void OnAdvertisingSetTerminated(
@@ -153,7 +160,7 @@
       uint8_t num_completed_extended_adv_events) = 0;
 
   using GetAddressCallback =
-      base::Callback<void(uint8_t /* address_type*/, bt_bdaddr_t /*address*/)>;
+      base::Callback<void(uint8_t /* address_type*/, RawAddress /*address*/)>;
   virtual void GetOwnAddress(uint8_t inst_id, GetAddressCallback cb) = 0;
 };
 
diff --git a/stack/include/bnep_api.h b/stack/include/bnep_api.h
index 95b6122..4116ac9 100644
--- a/stack/include/bnep_api.h
+++ b/stack/include/bnep_api.h
@@ -81,7 +81,7 @@
  *                  All values are used to indicate the reason for failure
  *              Flag to indicate if it is just a role change
 */
-typedef void(tBNEP_CONN_STATE_CB)(uint16_t handle, BD_ADDR rem_bda,
+typedef void(tBNEP_CONN_STATE_CB)(uint16_t handle, const RawAddress& rem_bda,
                                   tBNEP_RESULT result, bool is_role_change);
 
 /* Connection indication callback prototype. Parameters are
@@ -90,7 +90,7 @@
  *              When BNEP calls this function profile should
  *              use BNEP_ConnectResp call to accept or reject the request
 */
-typedef void(tBNEP_CONNECT_IND_CB)(uint16_t handle, BD_ADDR bd_addr,
+typedef void(tBNEP_CONNECT_IND_CB)(uint16_t handle, const RawAddress& bd_addr,
                                    tBT_UUID* remote_uuid, tBT_UUID* local_uuid,
                                    bool is_role_change);
 
@@ -103,9 +103,9 @@
  *              Flag to indicate whether extension headers to be forwarded are
  *                present
  */
-typedef void(tBNEP_DATA_BUF_CB)(uint16_t handle, uint8_t* src, uint8_t* dst,
-                                uint16_t protocol, BT_HDR* p_buf,
-                                bool fw_ext_present);
+typedef void(tBNEP_DATA_BUF_CB)(uint16_t handle, const RawAddress& src,
+                                const RawAddress& dst, uint16_t protocol,
+                                BT_HDR* p_buf, bool fw_ext_present);
 
 /* Data received indication callback prototype. Parameters are
  *              Handle to the connection
@@ -117,9 +117,10 @@
  *              Flag to indicate whether extension headers to be forwarded are
  *                present
  */
-typedef void(tBNEP_DATA_IND_CB)(uint16_t handle, uint8_t* src, uint8_t* dst,
-                                uint16_t protocol, uint8_t* p_data,
-                                uint16_t len, bool fw_ext_present);
+typedef void(tBNEP_DATA_IND_CB)(uint16_t handle, const RawAddress& src,
+                                const RawAddress& dst, uint16_t protocol,
+                                uint8_t* p_data, uint16_t len,
+                                bool fw_ext_present);
 
 /* Flow control callback for TX data. Parameters are
  *              Handle to the connection
@@ -181,7 +182,7 @@
   uint8_t con_status;
 
   uint16_t l2cap_cid;
-  BD_ADDR rem_bda;
+  RawAddress rem_bda;
   uint16_t rem_mtu_size;
   uint16_t xmit_q_depth;
 
@@ -244,8 +245,9 @@
  *                  BNEP_NO_RESOURCES           if no resources
  *
  ******************************************************************************/
-extern tBNEP_RESULT BNEP_Connect(BD_ADDR p_rem_bda, tBT_UUID* src_uuid,
-                                 tBT_UUID* dst_uuid, uint16_t* p_handle);
+extern tBNEP_RESULT BNEP_Connect(const RawAddress& p_rem_bda,
+                                 tBT_UUID* src_uuid, tBT_UUID* dst_uuid,
+                                 uint16_t* p_handle);
 
 /*******************************************************************************
  *
@@ -301,9 +303,11 @@
  *                  BNEP_SUCCESS            - If written successfully
  *
  ******************************************************************************/
-extern tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, uint8_t* p_dest_addr,
-                                  BT_HDR* p_buf, uint16_t protocol,
-                                  uint8_t* p_src_addr, bool fw_ext_present);
+extern tBNEP_RESULT BNEP_WriteBuf(uint16_t handle,
+                                  const RawAddress& p_dest_addr, BT_HDR* p_buf,
+                                  uint16_t protocol,
+                                  const RawAddress* p_src_addr,
+                                  bool fw_ext_present);
 
 /*******************************************************************************
  *
@@ -329,9 +333,10 @@
  *                  BNEP_SUCCESS            - If written successfully
  *
  ******************************************************************************/
-extern tBNEP_RESULT BNEP_Write(uint16_t handle, uint8_t* p_dest_addr,
+extern tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr,
                                uint8_t* p_data, uint16_t len, uint16_t protocol,
-                               uint8_t* p_src_addr, bool fw_ext_present);
+                               const RawAddress* p_src_addr,
+                               bool fw_ext_present);
 
 /*******************************************************************************
  *
diff --git a/stack/include/bt_types.h b/stack/include/bt_types.h
index 5540a7e..6acce0f 100644
--- a/stack/include/bt_types.h
+++ b/stack/include/bt_types.h
@@ -21,6 +21,7 @@
 
 #include <stdbool.h>
 #include <stdint.h>
+#include <string.h>
 
 #ifndef FALSE
 #define FALSE false
@@ -47,7 +48,7 @@
  *
  * The convention used is the the event name contains the layer that the
  * event is going to.
-*/
+ */
 #define BT_EVT_MASK 0xFF00
 #define BT_SUB_EVT_MASK 0x00FF
 /* To Bluetooth Upper Layers        */
@@ -211,7 +212,7 @@
 #define BT_EVT_CONTEXT_SWITCH_EVT (0x0001 | BT_EVT_BTIF)
 
 /* Define the header of each buffer used in the Bluetooth stack.
-*/
+ */
 typedef struct {
   uint16_t event;
   uint16_t len;
@@ -238,7 +239,7 @@
 #define BT_PSM_ATT 0x001F /* Attribute Protocol  */
 
 /* These macros extract the HCI opcodes from a buffer
-*/
+ */
 #define HCI_GET_CMD_HDR_OPCODE(p)                    \
   (uint16_t)((*((uint8_t*)((p) + 1) + (p)->offset) + \
               (*((uint8_t*)((p) + 1) + (p)->offset + 1) << 8)))
@@ -252,7 +253,7 @@
 
 /*******************************************************************************
  * Macros to get and put bytes to and from a stream (Little Endian format).
-*/
+ */
 #define UINT64_TO_BE_STREAM(p, u64)  \
   {                                  \
     *(p)++ = (uint8_t)((u64) >> 56); \
@@ -301,12 +302,6 @@
     int ijk;                                                      \
     for (ijk = 0; ijk < 8; ijk++) *(p)++ = (uint8_t)(a)[7 - ijk]; \
   }
-#define BDADDR_TO_STREAM(p, a)                      \
-  {                                                 \
-    int ijk;                                        \
-    for (ijk = 0; ijk < BD_ADDR_LEN; ijk++)         \
-      *(p)++ = (uint8_t)(a)[BD_ADDR_LEN - 1 - ijk]; \
-  }
 #define LAP_TO_STREAM(p, a)                     \
   {                                             \
     int ijk;                                    \
@@ -358,12 +353,6 @@
              ((((uint32_t)(*((p) + 3)))) << 24));                     \
     (p) += 4;                                                         \
   }
-#define STREAM_TO_BDADDR(a, p)                                \
-  {                                                           \
-    int ijk;                                                  \
-    uint8_t* pbda = (uint8_t*)(a) + BD_ADDR_LEN - 1;          \
-    for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *(p)++; \
-  }
 #define STREAM_TO_ARRAY32(a, p)                     \
   {                                                 \
     int ijk;                                        \
@@ -418,7 +407,7 @@
 /*******************************************************************************
  * Macros to get and put bytes to and from a field (Little Endian format).
  * These are the same as to stream, except the pointer is not incremented.
-*/
+ */
 #define UINT32_TO_FIELD(p, u32)                    \
   {                                                \
     *(uint8_t*)(p) = (uint8_t)(u32);               \
@@ -442,7 +431,7 @@
 
 /*******************************************************************************
  * Macros to get and put bytes to and from a stream (Big Endian format)
-*/
+ */
 #define UINT32_TO_BE_STREAM(p, u32)  \
   {                                  \
     *(p)++ = (uint8_t)((u32) >> 24); \
@@ -513,7 +502,7 @@
 /*******************************************************************************
  * Macros to get and put bytes to and from a field (Big Endian format).
  * These are the same as to stream, except the pointer is not incremented.
-*/
+ */
 #define UINT32_TO_BE_FIELD(p, u32)                 \
   {                                                \
     *(uint8_t*)(p) = (uint8_t)((u32) >> 24);       \
@@ -536,9 +525,22 @@
   { *(uint8_t*)(p) = (uint8_t)(u8); }
 
 /* Common Bluetooth field definitions */
-#define BD_ADDR_LEN 6                 /* Device address length */
-typedef uint8_t BD_ADDR[BD_ADDR_LEN]; /* Device address */
-typedef uint8_t* BD_ADDR_PTR;         /* Pointer to Device Address */
+#define BD_ADDR_LEN 6 /* Device address length */
+
+#ifdef __cplusplus
+#include <hardware/bluetooth.h>
+
+inline void BDADDR_TO_STREAM(uint8_t*& p, const RawAddress& a) {
+  for (int ijk = 0; ijk < BD_ADDR_LEN; ijk++)
+    *(p)++ = (uint8_t)(a.address)[BD_ADDR_LEN - 1 - ijk];
+}
+
+inline void STREAM_TO_BDADDR(RawAddress& a, uint8_t*& p) {
+  uint8_t* pbda = (uint8_t*)(a.address) + BD_ADDR_LEN - 1;
+  for (int ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *(p)++;
+}
+
+#endif
 
 #define AMP_KEY_TYPE_GAMP 0
 #define AMP_KEY_TYPE_WIFI 1
@@ -683,14 +685,14 @@
  *
  * The lowest 4 bytes byte of the UUID or GUID depend on the feature. Typically,
  * the value of those bytes will be the PSM or SCN.
-*/
+ */
 #define BRCM_PROPRIETARY_UUID_BASE \
   0xDA, 0x23, 0x41, 0x02, 0xA3, 0xBB, 0xC1, 0x71, 0xBA, 0x09, 0x6f, 0x21
 #define BRCM_PROPRIETARY_GUID_BASE \
   0xda23, 0x4102, 0xa3, 0xbb, 0xc1, 0x71, 0xba, 0x09, 0x6f, 0x21
 
 /* We will not allocate a PSM in the reserved range to 3rd party apps
-*/
+ */
 #define BRCM_RESERVED_PSM_START 0x5AE1
 #define BRCM_RESERVED_PSM_END 0x5AFF
 
@@ -698,7 +700,7 @@
 #define BRCM_MATCHER_PSM 0x5AE3
 
 /* Connection statistics
-*/
+ */
 
 /* Structure to hold connection stats */
 #ifndef BT_CONN_STATS_DEFINED
@@ -722,7 +724,7 @@
  *                          Low Energy definitions
  *
  * Address types
-*/
+ */
 #define BLE_ADDR_PUBLIC 0x00
 #define BLE_ADDR_RANDOM 0x01
 #define BLE_ADDR_PUBLIC_ID 0x02
@@ -741,13 +743,15 @@
 
 #define BLE_ADDR_IS_STATIC(x) (((x)[0] & 0xC0) == 0xC0)
 
-typedef struct {
+#ifdef __cplusplus
+struct tBLE_BD_ADDR {
   tBLE_ADDR_TYPE type;
-  BD_ADDR bda;
-} tBLE_BD_ADDR;
+  RawAddress bda;
+};
+#endif
 
 /* Device Types
-*/
+ */
 #define BT_DEVICE_TYPE_BREDR 0x01
 #define BT_DEVICE_TYPE_BLE 0x02
 #define BT_DEVICE_TYPE_DUMO 0x03
@@ -926,86 +930,12 @@
 /* Define a function for logging */
 typedef void(BT_LOG_FUNC)(int trace_type, const char* fmt_str, ...);
 
-/* bd addr length and type */
-#ifndef BD_ADDR_LEN
-#define BD_ADDR_LEN 6
-typedef uint8_t BD_ADDR[BD_ADDR_LEN];
-#endif
-
-// From bd.c
-
-/*****************************************************************************
- *  Constants
- ****************************************************************************/
-
-/* global constant for "any" bd addr */
-static const BD_ADDR bd_addr_any = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
-static const BD_ADDR bd_addr_null = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-/*****************************************************************************
- *  Functions
- ****************************************************************************/
-
-/*******************************************************************************
- *
- * Function         bdcpy
- *
- * Description      Copy bd addr b to a.
- *
- *
- * Returns          void
- *
- ******************************************************************************/
-static inline void bdcpy(BD_ADDR a, const BD_ADDR b) {
-  int i;
-
-  for (i = BD_ADDR_LEN; i != 0; i--) {
-    *a++ = *b++;
-  }
+static inline bool is_sample_ltk(const BT_OCTET16 ltk) {
+  /* Sample LTK from BT Spec 5.1 | Vol 6, Part C 1
+   * 0x4C68384139F574D836BCF34E9DFB01BF */
+  const uint8_t SAMPLE_LTK[] = {0xbf, 0x01, 0xfb, 0x9d, 0x4e, 0xf3, 0xbc, 0x36,
+                                0xd8, 0x74, 0xf5, 0x39, 0x41, 0x38, 0x68, 0x4c};
+  return memcmp(ltk, SAMPLE_LTK, BT_OCTET16_LEN) == 0;
 }
 
-/*******************************************************************************
- *
- * Function         bdcmp
- *
- * Description      Compare bd addr b to a.
- *
- *
- * Returns          Zero if b==a, nonzero otherwise (like memcmp).
- *
- ******************************************************************************/
-static inline int bdcmp(const BD_ADDR a, const BD_ADDR b) {
-  int i;
-
-  for (i = BD_ADDR_LEN; i != 0; i--) {
-    if (*a++ != *b++) {
-      return -1;
-    }
-  }
-  return 0;
-}
-
-/*******************************************************************************
- *
- * Function         bdcmpany
- *
- * Description      Compare bd addr to "any" bd addr.
- *
- *
- * Returns          Zero if a equals bd_addr_any.
- *
- ******************************************************************************/
-static inline int bdcmpany(const BD_ADDR a) { return bdcmp(a, bd_addr_any); }
-
-/*******************************************************************************
- *
- * Function         bdsetany
- *
- * Description      Set bd addr to "any" bd addr.
- *
- *
- * Returns          void
- *
- ******************************************************************************/
-static inline void bdsetany(BD_ADDR a) { bdcpy(a, bd_addr_any); }
 #endif
diff --git a/stack/include/btm_api.h b/stack/include/btm_api.h
index 2c0743f..3dd5567 100644
--- a/stack/include/btm_api.h
+++ b/stack/include/btm_api.h
@@ -534,7 +534,7 @@
  *                  BTM_WRONG_MODE if the device is not up.
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_ReadRemoteDeviceName(BD_ADDR remote_bda,
+extern tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
                                             tBTM_CMPL_CB* p_cb,
                                             tBT_TRANSPORT transport);
 
@@ -566,7 +566,8 @@
  * Returns          BTM_SUCCESS if successful, otherwise an error
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_ReadRemoteVersion(BD_ADDR addr, uint8_t* lmp_version,
+extern tBTM_STATUS BTM_ReadRemoteVersion(const RawAddress& addr,
+                                         uint8_t* lmp_version,
                                          uint16_t* manufacturer,
                                          uint16_t* lmp_sub_version);
 
@@ -583,7 +584,7 @@
  * Returns          pointer to the remote supported features mask
  *
  ******************************************************************************/
-extern uint8_t* BTM_ReadRemoteFeatures(BD_ADDR addr);
+extern uint8_t* BTM_ReadRemoteFeatures(const RawAddress& addr);
 
 /*******************************************************************************
  *
@@ -602,7 +603,7 @@
  *                  or NULL if page_number is not valid
  *
  ******************************************************************************/
-extern uint8_t* BTM_ReadRemoteExtendedFeatures(BD_ADDR addr,
+extern uint8_t* BTM_ReadRemoteExtendedFeatures(const RawAddress& addr,
                                                uint8_t page_number);
 
 /*******************************************************************************
@@ -615,7 +616,7 @@
  * Returns          number of features pages read from the remote device
  *
  ******************************************************************************/
-extern uint8_t BTM_ReadNumberRemoteFeaturesPages(BD_ADDR addr);
+extern uint8_t BTM_ReadNumberRemoteFeaturesPages(const RawAddress& addr);
 
 /*******************************************************************************
  *
@@ -630,7 +631,7 @@
  *                  BTM_FEATURE_BYTES_PER_PAGE * (BTM_EXT_FEATURES_PAGE_MAX + 1)
  *
  ******************************************************************************/
-extern uint8_t* BTM_ReadAllRemoteFeatures(BD_ADDR addr);
+extern uint8_t* BTM_ReadAllRemoteFeatures(const RawAddress& addr);
 
 /*******************************************************************************
  *
@@ -644,7 +645,7 @@
  * Returns          pointer to entry, or NULL if not found
  *
  ******************************************************************************/
-extern tBTM_INQ_INFO* BTM_InqDbRead(const BD_ADDR p_bda);
+extern tBTM_INQ_INFO* BTM_InqDbRead(const RawAddress& p_bda);
 
 /*******************************************************************************
  *
@@ -687,7 +688,7 @@
  *                          is active, otherwise BTM_SUCCESS
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_ClearInqDb(BD_ADDR p_bda);
+extern tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda);
 
 /*******************************************************************************
  *
@@ -703,66 +704,6 @@
  ******************************************************************************/
 extern tBTM_STATUS BTM_ReadInquiryRspTxPower(tBTM_CMPL_CB* p_cb);
 
-/*******************************************************************************
- *
- * Function         BTM_StartDiscovery
- *
- * Description      This function is called by an application (or profile)
- *                  when it wants to trigger an service discovery using the
- *                  BTM's discovery database.
- *
- * Returns          tBTM_STATUS
- *                      BTM_CMD_STARTED if the discovery was initiated
- *                      BTM_BUSY if one is already in progress
- *                      BTM_UNKNOWN_ADDR if no addresses are in the INQ DB
- *                      BTM_ERR_PROCESSING if err initiating the command
- *
- ******************************************************************************/
-extern tBTM_STATUS BTM_StartDiscovery(tBTM_CMPL_CB* p_cmpl_cb,
-                                      BD_ADDR_PTR p_rem_addr);
-
-/*******************************************************************************
- *
- * Function         BTM_FindAttribute
- *
- * Description      This function is called by an application (or profile)
- *                  when it wants to see if an attribute exists in the BTM
- *                  discovery database.
- *
- * Returns          Pointer to matching record, or NULL
- *
- ******************************************************************************/
-extern tSDP_DISC_REC* BTM_FindAttribute(uint16_t attr_id,
-                                        tSDP_DISC_REC* p_start_rec);
-
-/*******************************************************************************
- *
- * Function         BTM_FindService
- *
- * Description      This function is called by an application (or profile)
- *                  when it wants to see if a service exists in the BTM
- *                  discovery database.
- *
- * Returns          Pointer to matching record, or NULL
- *
- ******************************************************************************/
-extern tSDP_DISC_REC* BTM_FindService(uint16_t service_uuid,
-                                      tSDP_DISC_REC* p_start_rec);
-
-/*******************************************************************************
- *
- * Function         BTM_SetDiscoveryParams
- *
- * Description      This function is called to set the BTM default discovery
- *                  parameters. These UUID and attribute filters are used during
- *                  the call to BTM_StartDiscovery.
- *
- * Returns          void
- *
- ******************************************************************************/
-extern void BTM_SetDiscoveryParams(uint16_t num_uuid, tSDP_UUID* p_uuid_list,
-                                   uint16_t num_attr, uint16_t* p_attr_list);
-
 /*****************************************************************************
  *  ACL CHANNEL MANAGEMENT FUNCTIONS
  ****************************************************************************/
@@ -775,7 +716,8 @@
  * Returns          BTM_CMD_STARTED if successfully initiated, otherwise error
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SetLinkPolicy(BD_ADDR remote_bda, uint16_t* settings);
+extern tBTM_STATUS BTM_SetLinkPolicy(const RawAddress& remote_bda,
+                                     uint16_t* settings);
 
 /*******************************************************************************
  *
@@ -810,7 +752,8 @@
  * Returns          BTM_CMD_STARTED if successfully initiated, otherwise error
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SetLinkSuperTout(BD_ADDR remote_bda, uint16_t timeout);
+extern tBTM_STATUS BTM_SetLinkSuperTout(const RawAddress& remote_bda,
+                                        uint16_t timeout);
 /*******************************************************************************
  *
  * Function         BTM_GetLinkSuperTout
@@ -820,7 +763,7 @@
  * Returns          status of the operation
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_GetLinkSuperTout(BD_ADDR remote_bda,
+extern tBTM_STATUS BTM_GetLinkSuperTout(const RawAddress& remote_bda,
                                         uint16_t* p_timeout);
 
 /*******************************************************************************
@@ -833,7 +776,8 @@
  * Returns          true if connection is up, else false.
  *
  ******************************************************************************/
-extern bool BTM_IsAclConnectionUp(BD_ADDR remote_bda, tBT_TRANSPORT transport);
+extern bool BTM_IsAclConnectionUp(const RawAddress& remote_bda,
+                                  tBT_TRANSPORT transport);
 
 /*******************************************************************************
  *
@@ -846,7 +790,8 @@
  *                  BTM_UNKNOWN_ADDR if no active link with bd addr specified
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_GetRole(BD_ADDR remote_bd_addr, uint8_t* p_role);
+extern tBTM_STATUS BTM_GetRole(const RawAddress& remote_bd_addr,
+                               uint8_t* p_role);
 
 /*******************************************************************************
  *
@@ -866,8 +811,8 @@
  *                                       role switching
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SwitchRole(BD_ADDR remote_bd_addr, uint8_t new_role,
-                                  tBTM_CMPL_CB* p_cb);
+extern tBTM_STATUS BTM_SwitchRole(const RawAddress& remote_bd_addr,
+                                  uint8_t new_role, tBTM_CMPL_CB* p_cb);
 
 /*******************************************************************************
  *
@@ -875,7 +820,7 @@
  *
  * Description      This function is called to read the link policy settings.
  *                  The address of link policy results are returned in the
- *                  callback. (tBTM_RSSI_RESULTS)
+ *                  callback. (tBTM_RSSI_RESULT)
  *
  * Returns          BTM_CMD_STARTED if command issued to controller.
  *                  BTM_NO_RESOURCES if memory couldn't be allocated to issue
@@ -884,7 +829,44 @@
  *                  BTM_BUSY if command is already in progress
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_ReadRSSI(const BD_ADDR remote_bda, tBTM_CMPL_CB* p_cb);
+extern tBTM_STATUS BTM_ReadRSSI(const RawAddress& remote_bda,
+                                tBTM_CMPL_CB* p_cb);
+
+/*******************************************************************************
+ *
+ * Function         BTM_ReadFailedContactCounter
+ *
+ * Description      This function is called to read the failed contact counter.
+ *                  The result is returned in the callback.
+ *                  (tBTM_FAILED_CONTACT_COUNTER_RESULT)
+ *
+ * Returns          BTM_CMD_STARTED if command issued to controller.
+ *                  BTM_NO_RESOURCES if memory couldn't be allocated to issue
+ *                                   the command
+ *                  BTM_UNKNOWN_ADDR if no active link with bd addr specified
+ *                  BTM_BUSY if command is already in progress
+ *
+ ******************************************************************************/
+extern tBTM_STATUS BTM_ReadFailedContactCounter(const RawAddress& remote_bda,
+                                                tBTM_CMPL_CB* p_cb);
+
+/*******************************************************************************
+ *
+ * Function         BTM_ReadAutomaticFlushTimeout
+ *
+ * Description      This function is called to read the automatic flush timeout.
+ *                  The result is returned in the callback.
+ *                  (tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT)
+ *
+ * Returns          BTM_CMD_STARTED if command issued to controller.
+ *                  BTM_NO_RESOURCES if memory couldn't be allocated to issue
+ *                                   the command
+ *                  BTM_UNKNOWN_ADDR if no active link with bd addr specified
+ *                  BTM_BUSY if command is already in progress
+ *
+ ******************************************************************************/
+extern tBTM_STATUS BTM_ReadAutomaticFlushTimeout(const RawAddress& remote_bda,
+                                                 tBTM_CMPL_CB* p_cb);
 
 /*******************************************************************************
  *
@@ -893,7 +875,7 @@
  * Description      This function is called to read the current connection
  *                  TX power of the connection. The TX power level results
  *                  are returned in the callback.
- *                  (tBTM_RSSI_RESULTS)
+ *                  (tBTM_RSSI_RESULT)
  *
  * Returns          BTM_CMD_STARTED if command issued to controller.
  *                  BTM_NO_RESOURCES if memory couldn't be allocated to issue
@@ -902,8 +884,8 @@
  *                  BTM_BUSY if command is already in progress
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_ReadTxPower(BD_ADDR remote_bda, tBT_TRANSPORT transport,
-                                   tBTM_CMPL_CB* p_cb);
+extern tBTM_STATUS BTM_ReadTxPower(const RawAddress& remote_bda,
+                                   tBT_TRANSPORT transport, tBTM_CMPL_CB* p_cb);
 
 /*******************************************************************************
  *
@@ -911,7 +893,7 @@
  *
  * Description      This function is called to read the link quality.
  *                  The value of the link quality is returned in the callback.
- *                  (tBTM_LINK_QUALITY_RESULTS)
+ *                  (tBTM_LINK_QUALITY_RESULT)
  *
  * Returns          BTM_CMD_STARTED if command issued to controller.
  *                  BTM_NO_RESOURCES if memory couldn't be allocated to issue
@@ -920,7 +902,8 @@
  *                  BTM_BUSY if command is already in progress
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_ReadLinkQuality(BD_ADDR remote_bda, tBTM_CMPL_CB* p_cb);
+extern tBTM_STATUS BTM_ReadLinkQuality(const RawAddress& remote_bda,
+                                       tBTM_CMPL_CB* p_cb);
 
 /*******************************************************************************
  *
@@ -969,7 +952,7 @@
  * Returns          BTM_CMD_STARTED if successfully initiated, otherwise error
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SetQoS(BD_ADDR bd, FLOW_SPEC* p_flow,
+extern tBTM_STATUS BTM_SetQoS(const RawAddress& bd, FLOW_SPEC* p_flow,
                               tBTM_CMPL_CB* p_cb);
 
 /*****************************************************************************
@@ -992,7 +975,7 @@
  *                                   with the sco index used for the connection.
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_CreateSco(BD_ADDR remote_bda, bool is_orig,
+extern tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig,
                                  uint16_t pkt_types, uint16_t* p_sco_inx,
                                  tBTM_SCO_CB* p_conn_cb,
                                  tBTM_SCO_CB* p_disc_cb);
@@ -1083,7 +1066,7 @@
  * Returns          pointer to BD address or NULL if not known
  *
  ******************************************************************************/
-extern uint8_t* BTM_ReadScoBdAddr(uint16_t sco_inx);
+extern const RawAddress* BTM_ReadScoBdAddr(uint16_t sco_inx);
 
 /*******************************************************************************
  *
@@ -1285,7 +1268,8 @@
  * Returns          bool    true or false is device found
  *
  ******************************************************************************/
-extern bool BTM_GetSecurityFlags(BD_ADDR bd_addr, uint8_t* p_sec_flags);
+extern bool BTM_GetSecurityFlags(const RawAddress& bd_addr,
+                                 uint8_t* p_sec_flags);
 
 /*******************************************************************************
  *
@@ -1302,7 +1286,7 @@
  * Returns          bool    true or false is device found
  *
  ******************************************************************************/
-extern bool BTM_GetSecurityFlagsByTransport(BD_ADDR bd_addr,
+extern bool BTM_GetSecurityFlagsByTransport(const RawAddress& bd_addr,
                                             uint8_t* p_sec_flags,
                                             tBT_TRANSPORT transport);
 
@@ -1316,7 +1300,7 @@
  *                  otherwise, the trusted mask
  *
  ******************************************************************************/
-extern uint32_t* BTM_ReadTrustedMask(BD_ADDR bd_addr);
+extern uint32_t* BTM_ReadTrustedMask(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1391,7 +1375,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTM_SetOutService(BD_ADDR bd_addr, uint8_t service_id,
+extern void BTM_SetOutService(const RawAddress& bd_addr, uint8_t service_id,
                               uint32_t mx_chan_id);
 
 /*******************************************************************************
@@ -1421,22 +1405,23 @@
  * Returns          true if added OK, else false
  *
  ******************************************************************************/
-extern bool BTM_SecAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class,
+extern bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class,
                              BD_NAME bd_name, uint8_t* features,
                              uint32_t trusted_mask[], LINK_KEY link_key,
                              uint8_t key_type, tBTM_IO_CAP io_cap,
                              uint8_t pin_length);
 
-/*******************************************************************************
+/** Free resources associated with the device associated with |bd_addr| address.
  *
- * Function         BTM_SecDeleteDevice
+ * *** WARNING ***
+ * tBTM_SEC_DEV_REC associated with bd_addr becomes invalid after this function
+ * is called, also any of it's fields. i.e. if you use p_dev_rec->bd_addr, it is
+ * no longer valid!
+ * *** WARNING ***
  *
- * Description      Free resources associated with the device.
- *
- * Returns          true if rmoved OK, false if not found
- *
- ******************************************************************************/
-extern bool BTM_SecDeleteDevice(BD_ADDR bd_addr);
+ * Returns true if removed OK, false if not found or ACL link is active.
+ */
+extern bool BTM_SecDeleteDevice(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1446,7 +1431,7 @@
  *                  remove device.
  *
  ******************************************************************************/
-extern void BTM_SecClearSecurityFlags(BD_ADDR bd_addr);
+extern void BTM_SecClearSecurityFlags(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1460,7 +1445,8 @@
  * Returns          BTM_SUCCESS if successful, otherwise error code
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SecGetDeviceLinkKey(BD_ADDR bd_addr, LINK_KEY link_key);
+extern tBTM_STATUS BTM_SecGetDeviceLinkKey(const RawAddress& bd_addr,
+                                           LINK_KEY link_key);
 
 /*******************************************************************************
  *
@@ -1476,7 +1462,8 @@
  *                  otherwise.
  *
  ******************************************************************************/
-extern tBTM_LINK_KEY_TYPE BTM_SecGetDeviceLinkKeyType(BD_ADDR bd_addr);
+extern tBTM_LINK_KEY_TYPE BTM_SecGetDeviceLinkKeyType(
+    const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1497,8 +1484,9 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTM_PINCodeReply(BD_ADDR bd_addr, uint8_t res, uint8_t pin_len,
-                             uint8_t* p_pin, uint32_t trusted_mask[]);
+extern void BTM_PINCodeReply(const RawAddress& bd_addr, uint8_t res,
+                             uint8_t pin_len, uint8_t* p_pin,
+                             uint32_t trusted_mask[]);
 
 /*******************************************************************************
  *
@@ -1514,8 +1502,8 @@
  * Returns          BTM_CMD_STARTED if successfully initiated, otherwise error
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SecBond(BD_ADDR bd_addr, uint8_t pin_len, uint8_t* p_pin,
-                               uint32_t trusted_mask[]);
+extern tBTM_STATUS BTM_SecBond(const RawAddress& bd_addr, uint8_t pin_len,
+                               uint8_t* p_pin, uint32_t trusted_mask[]);
 
 /*******************************************************************************
  *
@@ -1534,7 +1522,7 @@
  * Returns          BTM_CMD_STARTED if successfully initiated, otherwise error
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SecBondByTransport(BD_ADDR bd_addr,
+extern tBTM_STATUS BTM_SecBondByTransport(const RawAddress& bd_addr,
                                           tBT_TRANSPORT transport,
                                           uint8_t pin_len, uint8_t* p_pin,
                                           uint32_t trusted_mask[]);
@@ -1549,7 +1537,7 @@
  * Returns          BTM_CMD_STARTED if successfully initiated, otherwise error
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SecBondCancel(BD_ADDR bd_addr);
+extern tBTM_STATUS BTM_SecBondCancel(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1579,7 +1567,8 @@
  *                  BTM_MODE_UNSUPPORTED - if security manager not linked in.
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SetEncryption(BD_ADDR bd_addr, tBT_TRANSPORT transport,
+extern tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr,
+                                     tBT_TRANSPORT transport,
                                      tBTM_SEC_CBACK* p_callback,
                                      void* p_ref_data,
                                      tBTM_BLE_SEC_ACT sec_act);
@@ -1596,7 +1585,7 @@
  *                  bd_addr       - Address of the peer device
  *
  ******************************************************************************/
-extern void BTM_ConfirmReqReply(tBTM_STATUS res, BD_ADDR bd_addr);
+extern void BTM_ConfirmReqReply(tBTM_STATUS res, const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1612,7 +1601,7 @@
  *                                  0 - 999999(0xF423F).
  *
  ******************************************************************************/
-extern void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr,
+extern void BTM_PasskeyReqReply(tBTM_STATUS res, const RawAddress& bd_addr,
                                 uint32_t passkey);
 
 /*******************************************************************************
@@ -1629,7 +1618,8 @@
  *                  type - notification type
  *
  ******************************************************************************/
-extern void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type);
+extern void BTM_SendKeypressNotif(const RawAddress& bd_addr,
+                                  tBTM_SP_KEY_TYPE type);
 
 /*******************************************************************************
  *
@@ -1646,8 +1636,8 @@
  *                  auth_req- MITM protection required or not.
  *
  ******************************************************************************/
-extern void BTM_IoCapRsp(BD_ADDR bd_addr, tBTM_IO_CAP io_cap, tBTM_OOB_DATA oob,
-                         tBTM_AUTH_REQ auth_req);
+extern void BTM_IoCapRsp(const RawAddress& bd_addr, tBTM_IO_CAP io_cap,
+                         tBTM_OOB_DATA oob, tBTM_AUTH_REQ auth_req);
 
 /*******************************************************************************
  *
@@ -1671,7 +1661,7 @@
  *                  r           - simple pairing Randomizer  C.
  *
  ******************************************************************************/
-extern void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr,
+extern void BTM_RemoteOobDataReply(tBTM_STATUS res, const RawAddress& bd_addr,
                                    BT_OCTET16 c, BT_OCTET16 r);
 
 /*******************************************************************************
@@ -1710,7 +1700,7 @@
  *                  else false.
  *
  ******************************************************************************/
-extern bool BTM_BothEndsSupportSecureConnections(BD_ADDR bd_addr);
+extern bool BTM_BothEndsSupportSecureConnections(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1725,7 +1715,7 @@
  *                  else false.
  *
  ******************************************************************************/
-extern bool BTM_PeerSupportsSecureConnections(BD_ADDR bd_addr);
+extern bool BTM_PeerSupportsSecureConnections(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1755,7 +1745,7 @@
  * Returns          Pointer to the name or NULL
  *
  ******************************************************************************/
-extern char* BTM_SecReadDevName(BD_ADDR bd_addr);
+extern char* BTM_SecReadDevName(const RawAddress& bd_addr);
 
 /*****************************************************************************
  *  POWER MANAGEMENT FUNCTIONS
@@ -1785,7 +1775,7 @@
  *                  BTM_UNKNOWN_ADDR if bd addr is not active or bad
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, BD_ADDR remote_bda,
+extern tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda,
                                     tBTM_PM_PWR_MD* p_mode);
 
 /*******************************************************************************
@@ -1808,7 +1798,8 @@
  *                  BTM_UNKNOWN_ADDR if bd addr is not active or bad
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_ReadPowerMode(BD_ADDR remote_bda, tBTM_PM_MODE* p_mode);
+extern tBTM_STATUS BTM_ReadPowerMode(const RawAddress& remote_bda,
+                                     tBTM_PM_MODE* p_mode);
 
 /*******************************************************************************
  *
@@ -1828,8 +1819,9 @@
  *                  BTM_CMD_STORED if the command is stored
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SetSsrParams(BD_ADDR remote_bda, uint16_t max_lat,
-                                    uint16_t min_rmt_to, uint16_t min_loc_to);
+extern tBTM_STATUS BTM_SetSsrParams(const RawAddress& remote_bda,
+                                    uint16_t max_lat, uint16_t min_rmt_to,
+                                    uint16_t min_loc_to);
 
 /*******************************************************************************
  *
@@ -1841,7 +1833,7 @@
  * Returns          the handle of the connection, or 0xFFFF if none.
  *
  ******************************************************************************/
-extern uint16_t BTM_GetHCIConnHandle(const BD_ADDR remote_bda,
+extern uint16_t BTM_GetHCIConnHandle(const RawAddress& remote_bda,
                                      tBT_TRANSPORT transport);
 
 /*******************************************************************************
@@ -1857,7 +1849,8 @@
  *                                 the results
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_DeleteStoredLinkKey(BD_ADDR bd_addr, tBTM_CMPL_CB* p_cb);
+extern tBTM_STATUS BTM_DeleteStoredLinkKey(const RawAddress* bd_addr,
+                                           tBTM_CMPL_CB* p_cb);
 
 /*******************************************************************************
  *
diff --git a/stack/include/btm_api_types.h b/stack/include/btm_api_types.h
index e4a1106..058aabc 100644
--- a/stack/include/btm_api_types.h
+++ b/stack/include/btm_api_types.h
@@ -132,7 +132,7 @@
  * Parameters are the BD Address of remote and the Dev Class of remote. If the
  * app returns none zero, the connection or inquiry result will be dropped.
 */
-typedef uint8_t(tBTM_FILTER_CB)(BD_ADDR bd_addr, DEV_CLASS dc);
+typedef uint8_t(tBTM_FILTER_CB)(const RawAddress& bd_addr, DEV_CLASS dc);
 
 /*****************************************************************************
  *  DEVICE DISCOVERY - Inquiry, Remote Name, Discovery, Class of Device
@@ -595,7 +595,7 @@
 
 typedef union /* contains the inquiry filter condition */
 {
-  BD_ADDR bdaddr_cond;
+  RawAddress bdaddr_cond;
   tBTM_COD_COND cod_cond;
 } tBTM_INQ_FILT_COND;
 
@@ -636,7 +636,7 @@
 */
 typedef struct {
   uint16_t clock_offset;
-  BD_ADDR remote_bd_addr;
+  RawAddress remote_bd_addr;
   DEV_CLASS dev_class;
   uint8_t page_scan_rep_mode;
   uint8_t page_scan_per_mode;
@@ -685,7 +685,7 @@
 /* Structure returned with remote name  request */
 typedef struct {
   uint16_t status;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t length;
   BD_NAME remote_bd_name;
 } tBTM_REMOTE_DEV_NAME;
@@ -756,7 +756,7 @@
 typedef struct {
   uint8_t hci_status;     /* HCI status returned with the event */
   uint8_t role;           /* BTM_ROLE_MASTER or BTM_ROLE_SLAVE */
-  BD_ADDR remote_bd_addr; /* Remote BD addr involved with the switch */
+  RawAddress remote_bd_addr; /* Remote BD addr involved with the switch */
 } tBTM_ROLE_SWITCH_CMPL;
 
 /* Structure returned with QoS information (in tBTM_CMPL_CB callback function)
@@ -775,8 +775,30 @@
   tBTM_STATUS status;
   uint8_t hci_status;
   int8_t rssi;
-  BD_ADDR rem_bda;
-} tBTM_RSSI_RESULTS;
+  RawAddress rem_bda;
+} tBTM_RSSI_RESULT;
+
+/* Structure returned with read failed contact counter event
+ * (in tBTM_CMPL_CB callback function) in response to
+ * BTM_ReadFailedContactCounter call.
+ */
+typedef struct {
+  tBTM_STATUS status;
+  uint8_t hci_status;
+  uint16_t failed_contact_counter;
+  RawAddress rem_bda;
+} tBTM_FAILED_CONTACT_COUNTER_RESULT;
+
+/* Structure returned with read automatic flush timeout event
+ * (in tBTM_CMPL_CB callback function) in response to
+ * BTM_ReadAutomaticFlushTimeout call.
+ */
+typedef struct {
+  tBTM_STATUS status;
+  uint8_t hci_status;
+  uint16_t automatic_flush_timeout;
+  RawAddress rem_bda;
+} tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT;
 
 /* Structure returned with read current TX power event (in tBTM_CMPL_CB callback
  * function) in response to BTM_ReadTxPower call.
@@ -785,8 +807,8 @@
   tBTM_STATUS status;
   uint8_t hci_status;
   int8_t tx_power;
-  BD_ADDR rem_bda;
-} tBTM_TX_POWER_RESULTS;
+  RawAddress rem_bda;
+} tBTM_TX_POWER_RESULT;
 
 /* Structure returned with read link quality event (in tBTM_CMPL_CB callback
  * function) in response to BTM_ReadLinkQuality call.
@@ -795,8 +817,8 @@
   tBTM_STATUS status;
   uint8_t hci_status;
   uint8_t link_quality;
-  BD_ADDR rem_bda;
-} tBTM_LINK_QUALITY_RESULTS;
+  RawAddress rem_bda;
+} tBTM_LINK_QUALITY_RESULT;
 
 /* Structure returned with read inq tx power quality event (in tBTM_CMPL_CB
  * callback function) in response to BTM_ReadInquiryRspTxPower call.
@@ -805,7 +827,7 @@
   tBTM_STATUS status;
   uint8_t hci_status;
   int8_t tx_power;
-} tBTM_INQ_TXPWR_RESULTS;
+} tBTM_INQ_TXPWR_RESULT;
 
 enum {
   BTM_BL_CONN_EVT,
@@ -829,7 +851,7 @@
 /* the data type associated with BTM_BL_CONN_EVT */
 typedef struct {
   tBTM_BL_EVENT event;     /* The event reported. */
-  BD_ADDR_PTR p_bda;       /* The address of the newly connected device */
+  const RawAddress* p_bda; /* The address of the newly connected device */
   DEV_CLASS_PTR p_dc;      /* The device class */
   BD_NAME_PTR p_bdn;       /* The device name */
   uint8_t* p_features;     /* pointer to the remote device's features page[0]
@@ -841,7 +863,7 @@
 /* the data type associated with BTM_BL_DISCN_EVT */
 typedef struct {
   tBTM_BL_EVENT event;     /* The event reported. */
-  BD_ADDR_PTR p_bda;       /* The address of the disconnected device */
+  const RawAddress* p_bda; /* The address of the disconnected device */
   uint16_t handle;         /* disconnected connection handle */
   tBT_TRANSPORT transport; /* link is LE link or not */
 } tBTM_BL_DISCN_DATA;
@@ -865,7 +887,7 @@
 /* the data type associated with BTM_BL_ROLE_CHG_EVT */
 typedef struct {
   tBTM_BL_EVENT event; /* The event reported. */
-  BD_ADDR_PTR p_bda;   /* The address of the peer connected device */
+  const RawAddress* p_bda; /* The address of the peer connected device */
   uint8_t new_role;
   uint8_t hci_status; /* HCI status returned with the event */
 } tBTM_BL_ROLE_CHG_DATA;
@@ -891,7 +913,7 @@
  * changes. First param is BD address, second is if added or removed.
  * Registered through BTM_AclRegisterForChanges call.
 */
-typedef void(tBTM_ACL_DB_CHANGE_CB)(BD_ADDR p_bda, DEV_CLASS p_dc,
+typedef void(tBTM_ACL_DB_CHANGE_CB)(const RawAddress& p_bda, DEV_CLASS p_dc,
                                     BD_NAME p_bdn, uint8_t* features,
                                     bool is_new, uint16_t handle,
                                     tBT_TRANSPORT transport);
@@ -989,7 +1011,7 @@
 typedef struct {
   uint16_t rx_pkt_len;
   uint16_t tx_pkt_len;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t link_type; /* BTM_LINK_TYPE_SCO or BTM_LINK_TYPE_ESCO */
   uint8_t tx_interval;
   uint8_t retrans_window;
@@ -1000,7 +1022,7 @@
   uint16_t sco_inx;
   uint16_t rx_pkt_len;
   uint16_t tx_pkt_len;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t hci_status;
   uint8_t tx_interval;
   uint8_t retrans_window;
@@ -1008,7 +1030,7 @@
 
 typedef struct {
   uint16_t sco_inx;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   DEV_CLASS dev_class;
   tBTM_SCO_TYPE link_type;
 } tBTM_ESCO_CONN_REQ_EVT_DATA;
@@ -1302,11 +1324,9 @@
  *              Is originator of the connection
  *              Result of the operation
 */
-typedef uint8_t(tBTM_AUTHORIZE_CALLBACK)(BD_ADDR bd_addr, DEV_CLASS dev_class,
-                                         tBTM_BD_NAME bd_name,
-                                         uint8_t* service_name,
-                                         uint8_t service_id,
-                                         bool is_originator);
+typedef uint8_t(tBTM_AUTHORIZE_CALLBACK)(
+    const RawAddress& bd_addr, DEV_CLASS dev_class, tBTM_BD_NAME bd_name,
+    uint8_t* service_name, uint8_t service_id, bool is_originator);
 
 /* Get PIN for the connection.  Parameters are
  *              BD Address of remote
@@ -1314,15 +1334,17 @@
  *              BD Name of remote
  *              Flag indicating the minimum pin code length to be 16 digits
 */
-typedef uint8_t(tBTM_PIN_CALLBACK)(BD_ADDR bd_addr, DEV_CLASS dev_class,
-                                   tBTM_BD_NAME bd_name, bool min_16_digit);
+typedef uint8_t(tBTM_PIN_CALLBACK)(const RawAddress& bd_addr,
+                                   DEV_CLASS dev_class, tBTM_BD_NAME bd_name,
+                                   bool min_16_digit);
 
 /* New Link Key for the connection.  Parameters are
  *              BD Address of remote
  *              Link Key
  *              Key Type: Combination, Local Unit, or Remote Unit
 */
-typedef uint8_t(tBTM_LINK_KEY_CALLBACK)(BD_ADDR bd_addr, DEV_CLASS dev_class,
+typedef uint8_t(tBTM_LINK_KEY_CALLBACK)(const RawAddress& bd_addr,
+                                        DEV_CLASS dev_class,
                                         tBTM_BD_NAME bd_name, uint8_t* key,
                                         uint8_t key_type);
 
@@ -1330,7 +1352,7 @@
  *              BD Address of remote
  *              BD Name of remote
 */
-typedef void(tBTM_RMT_NAME_CALLBACK)(BD_ADDR bd_addr, DEV_CLASS dc,
+typedef void(tBTM_RMT_NAME_CALLBACK)(const RawAddress& bd_addr, DEV_CLASS dc,
                                      tBTM_BD_NAME bd_name);
 
 /* Authentication complete for the connection.  Parameters are
@@ -1339,7 +1361,7 @@
  *              BD Name of remote
  *
 */
-typedef uint8_t(tBTM_AUTH_COMPLETE_CALLBACK)(BD_ADDR bd_addr,
+typedef uint8_t(tBTM_AUTH_COMPLETE_CALLBACK)(const RawAddress& bd_addr,
                                              DEV_CLASS dev_class,
                                              tBTM_BD_NAME bd_name, int result);
 
@@ -1407,7 +1429,7 @@
 
 /* data type for BTM_SP_IO_REQ_EVT */
 typedef struct {
-  BD_ADDR bd_addr;        /* peer address */
+  RawAddress bd_addr;     /* peer address */
   tBTM_IO_CAP io_cap;     /* local IO capabilities */
   tBTM_OOB_DATA oob_data; /* OOB data present (locally) for the peer device */
   tBTM_AUTH_REQ auth_req; /* Authentication required (for local device) */
@@ -1416,7 +1438,7 @@
 
 /* data type for BTM_SP_IO_RSP_EVT */
 typedef struct {
-  BD_ADDR bd_addr;    /* peer address */
+  RawAddress bd_addr; /* peer address */
   tBTM_IO_CAP io_cap; /* peer IO capabilities */
   tBTM_OOB_DATA
       oob_data; /* OOB data present at peer device for the local device */
@@ -1425,7 +1447,7 @@
 
 /* data type for BTM_SP_CFM_REQ_EVT */
 typedef struct {
-  BD_ADDR bd_addr;      /* peer address */
+  RawAddress bd_addr;   /* peer address */
   DEV_CLASS dev_class;  /* peer CoD */
   tBTM_BD_NAME bd_name; /* peer device name */
   uint32_t num_val; /* the numeric value for comparison. If just_works, do not
@@ -1439,14 +1461,14 @@
 
 /* data type for BTM_SP_KEY_REQ_EVT */
 typedef struct {
-  BD_ADDR bd_addr;      /* peer address */
+  RawAddress bd_addr;   /* peer address */
   DEV_CLASS dev_class;  /* peer CoD */
   tBTM_BD_NAME bd_name; /* peer device name */
 } tBTM_SP_KEY_REQ;
 
 /* data type for BTM_SP_KEY_NOTIF_EVT */
 typedef struct {
-  BD_ADDR bd_addr;      /* peer address */
+  RawAddress bd_addr;   /* peer address */
   DEV_CLASS dev_class;  /* peer CoD */
   tBTM_BD_NAME bd_name; /* peer device name */
   uint32_t passkey;     /* passkey */
@@ -1464,7 +1486,7 @@
 
 /* data type for BTM_SP_KEYPRESS_EVT */
 typedef struct {
-  BD_ADDR bd_addr; /* peer address */
+  RawAddress bd_addr; /* peer address */
   tBTM_SP_KEY_TYPE notif_type;
 } tBTM_SP_KEYPRESS;
 
@@ -1477,14 +1499,14 @@
 
 /* data type for BTM_SP_RMT_OOB_EVT */
 typedef struct {
-  BD_ADDR bd_addr;      /* peer address */
+  RawAddress bd_addr;   /* peer address */
   DEV_CLASS dev_class;  /* peer CoD */
   tBTM_BD_NAME bd_name; /* peer device name */
 } tBTM_SP_RMT_OOB;
 
 /* data type for BTM_SP_COMPLT_EVT */
 typedef struct {
-  BD_ADDR bd_addr;      /* peer address */
+  RawAddress bd_addr;   /* peer address */
   DEV_CLASS dev_class;  /* peer CoD */
   tBTM_BD_NAME bd_name; /* peer device name */
   tBTM_STATUS status;   /* status of the simple pairing process */
@@ -1492,7 +1514,7 @@
 
 /* data type for BTM_SP_UPGRADE_EVT */
 typedef struct {
-  BD_ADDR bd_addr; /* peer address */
+  RawAddress bd_addr; /* peer address */
   bool upgrade;    /* true, to upgrade the link key */
 } tBTM_SP_UPGRADE;
 
@@ -1514,7 +1536,7 @@
 */
 typedef uint8_t(tBTM_SP_CALLBACK)(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data);
 
-typedef void(tBTM_MKEY_CALLBACK)(BD_ADDR bd_addr, uint8_t status,
+typedef void(tBTM_MKEY_CALLBACK)(const RawAddress& bd_addr, uint8_t status,
                                  uint8_t key_flag);
 
 /* Encryption enabled/disabled complete: Optionally passed with
@@ -1524,7 +1546,7 @@
  *              optional data passed in by BTM_SetEncryption
  *              tBTM_STATUS - result of the operation
 */
-typedef void(tBTM_SEC_CBACK)(BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+typedef void(tBTM_SEC_CBACK)(const RawAddress* bd_addr, tBT_TRANSPORT trasnport,
                              void* p_ref_data, tBTM_STATUS result);
 
 /* Bond Cancel complete. Parameters are
@@ -1655,7 +1677,7 @@
 typedef struct {
   BT_OCTET16 irk;
   tBLE_ADDR_TYPE addr_type;
-  BD_ADDR static_addr;
+  RawAddress static_addr;
 } tBTM_LE_PID_KEYS;
 
 typedef union {
@@ -1687,7 +1709,7 @@
 /* Simple Pairing Events.  Called by the stack when Simple Pairing related
  * events occur.
 */
-typedef uint8_t(tBTM_LE_CALLBACK)(tBTM_LE_EVT event, BD_ADDR bda,
+typedef uint8_t(tBTM_LE_CALLBACK)(tBTM_LE_EVT event, const RawAddress& bda,
                                   tBTM_LE_EVT_DATA* p_data);
 
 #define BTM_BLE_KEY_TYPE_ID 1
@@ -1729,7 +1751,7 @@
 /* Callback function for when a link supervision timeout event occurs.
  * This asynchronous event is enabled/disabled by calling BTM_RegForLstoEvt().
 */
-typedef void(tBTM_LSTO_CBACK)(BD_ADDR remote_bda, uint16_t timeout);
+typedef void(tBTM_LSTO_CBACK)(const RawAddress& remote_bda, uint16_t timeout);
 
 /*****************************************************************************
  *  POWER MANAGEMENT
@@ -1783,8 +1805,9 @@
 /*************************************
  *  Power Manager Callback Functions
  *************************************/
-typedef void(tBTM_PM_STATUS_CBACK)(BD_ADDR p_bda, tBTM_PM_STATUS status,
-                                   uint16_t value, uint8_t hci_status);
+typedef void(tBTM_PM_STATUS_CBACK)(const RawAddress& p_bda,
+                                   tBTM_PM_STATUS status, uint16_t value,
+                                   uint8_t hci_status);
 
 /************************
  *  Stored Linkkey Types
@@ -1809,7 +1832,7 @@
 
 typedef struct {
   tBTM_MIP_EVT event;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint16_t mip_id;
 } tBTM_MIP_MODE_CHANGE;
 
@@ -1830,7 +1853,7 @@
 
 typedef struct {
   tBTM_MIP_EVT event;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t data[11]; /* data[0] shows Vender-specific device type */
 } tBTM_MIP_EIR_HANDSHAKE;
 
@@ -1852,7 +1875,7 @@
 typedef void(tBTM_MIP_EVENTS_CB)(tBTM_MIP_EVT event, tBTM_MIP_EVENT_DATA data);
 
 /* MIP Device query callback function  */
-typedef bool(tBTM_MIP_QUERY_CB)(BD_ADDR dev_addr, uint8_t* p_mode,
+typedef bool(tBTM_MIP_QUERY_CB)(const RawAddress& dev_addr, uint8_t* p_mode,
                                 LINK_KEY link_key);
 
 /* ACL link on, SCO link ongoing, sniff mode */
diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h
index ee1ede6..49b11e5 100644
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -52,7 +52,7 @@
  * Returns          true if added OK, else false
  *
  ******************************************************************************/
-extern bool BTM_SecAddBleDevice(const BD_ADDR bd_addr, BD_NAME bd_name,
+extern bool BTM_SecAddBleDevice(const RawAddress& bd_addr, BD_NAME bd_name,
                                 tBT_DEVICE_TYPE dev_type,
                                 tBLE_ADDR_TYPE addr_type);
 
@@ -71,7 +71,8 @@
  * Returns          true if added OK, else false
  *
  ******************************************************************************/
-extern bool BTM_SecAddBleKey(BD_ADDR bd_addr, tBTM_LE_KEY_VALUE* p_le_key,
+extern bool BTM_SecAddBleKey(const RawAddress& bd_addr,
+                             tBTM_LE_KEY_VALUE* p_le_key,
                              tBTM_LE_KEY_TYPE key_type);
 
 /*******************************************************************************
@@ -247,7 +248,7 @@
  * Returns          None
  *
  ******************************************************************************/
-extern void BTM_SecurityGrant(BD_ADDR bd_addr, uint8_t res);
+extern void BTM_SecurityGrant(const RawAddress& bd_addr, uint8_t res);
 
 /*******************************************************************************
  *
@@ -264,7 +265,8 @@
  *                               BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
  *
  ******************************************************************************/
-extern void BTM_BlePasskeyReply(BD_ADDR bd_addr, uint8_t res, uint32_t passkey);
+extern void BTM_BlePasskeyReply(const RawAddress& bd_addr, uint8_t res,
+                                uint32_t passkey);
 
 /*******************************************************************************
  *
@@ -278,7 +280,7 @@
  *                  res          - comparison result BTM_SUCCESS if success
  *
  ******************************************************************************/
-extern void BTM_BleConfirmReply(BD_ADDR bd_addr, uint8_t res);
+extern void BTM_BleConfirmReply(const RawAddress& bd_addr, uint8_t res);
 
 /*******************************************************************************
  *
@@ -292,8 +294,8 @@
  *                  p_data      - simple pairing Randomizer  C.
  *
  ******************************************************************************/
-extern void BTM_BleOobDataReply(BD_ADDR bd_addr, uint8_t res, uint8_t len,
-                                uint8_t* p_data);
+extern void BTM_BleOobDataReply(const RawAddress& bd_addr, uint8_t res,
+                                uint8_t len, uint8_t* p_data);
 
 /*******************************************************************************
  *
@@ -308,8 +310,8 @@
  *                  p_r         - pointer to Randomizer.
  *
  ******************************************************************************/
-extern void BTM_BleSecureConnectionOobDataReply(BD_ADDR bd_addr, uint8_t* p_c,
-                                                uint8_t* p_r);
+extern void BTM_BleSecureConnectionOobDataReply(const RawAddress& bd_addr,
+                                                uint8_t* p_c, uint8_t* p_r);
 
 /*******************************************************************************
  *
@@ -327,8 +329,8 @@
  * Returns          true if signing sucessul, otherwise false.
  *
  ******************************************************************************/
-extern bool BTM_BleDataSignature(BD_ADDR bd_addr, uint8_t* p_text, uint16_t len,
-                                 BLE_SIGNATURE signature);
+extern bool BTM_BleDataSignature(const RawAddress& bd_addr, uint8_t* p_text,
+                                 uint16_t len, BLE_SIGNATURE signature);
 
 /*******************************************************************************
  *
@@ -345,7 +347,7 @@
  * Returns          true if signature verified correctly; otherwise false.
  *
  ******************************************************************************/
-extern bool BTM_BleVerifySignature(BD_ADDR bd_addr, uint8_t* p_orig,
+extern bool BTM_BleVerifySignature(const RawAddress& bd_addr, uint8_t* p_orig,
                                    uint16_t len, uint32_t counter,
                                    uint8_t* p_comp);
 
@@ -358,11 +360,24 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTM_ReadConnectionAddr(BD_ADDR remote_bda, BD_ADDR local_conn_addr,
+extern void BTM_ReadConnectionAddr(const RawAddress& remote_bda,
+                                   RawAddress& local_conn_addr,
                                    tBLE_ADDR_TYPE* p_addr_type);
 
 /*******************************************************************************
  *
+ * Function         BTM_IsBleConnection
+ *
+ * Description      This function is called to check if the connection handle
+ *                  for an LE link
+ *
+ * Returns          true if connection is LE link, otherwise false.
+ *
+ ******************************************************************************/
+extern bool BTM_IsBleConnection(uint16_t conn_handle);
+
+/*******************************************************************************
+ *
  * Function         BTM_ReadRemoteConnectionAddr
  *
  * Description      Read the remote device address currently used.
@@ -370,7 +385,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern bool BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr,
+extern bool BTM_ReadRemoteConnectionAddr(const RawAddress& pseudo_addr,
+                                         RawAddress& conn_addr,
                                          tBLE_ADDR_TYPE* p_addr_type);
 
 /*******************************************************************************
@@ -410,7 +426,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern bool BTM_BleUpdateBgConnDev(bool add_remove, BD_ADDR remote_bda);
+extern bool BTM_BleUpdateBgConnDev(bool add_remove,
+                                   const RawAddress& remote_bda);
 
 /*******************************************************************************
  *
@@ -445,7 +462,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTM_BleSetPrefConnParams(BD_ADDR bd_addr, uint16_t min_conn_int,
+extern void BTM_BleSetPrefConnParams(const RawAddress& bd_addr,
+                                     uint16_t min_conn_int,
                                      uint16_t max_conn_int,
                                      uint16_t slave_latency,
                                      uint16_t supervision_tout);
@@ -517,7 +535,7 @@
  *                  p_addr_type: output parameter to read the address type.
  *
  ******************************************************************************/
-extern void BTM_ReadDevInfo(const BD_ADDR remote_bda,
+extern void BTM_ReadDevInfo(const RawAddress& remote_bda,
                             tBT_DEVICE_TYPE* p_dev_type,
                             tBLE_ADDR_TYPE* p_addr_type);
 
@@ -535,7 +553,7 @@
  * Return           true if an active link is identified; false otherwise
  *
  ******************************************************************************/
-extern bool BTM_ReadConnectedTransportAddress(BD_ADDR remote_bda,
+extern bool BTM_ReadConnectedTransportAddress(RawAddress* remote_bda,
                                               tBT_TRANSPORT transport);
 
 /*******************************************************************************
@@ -622,7 +640,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void BTM_BleTurnOnPrivacyOnRemote(BD_ADDR bd_addr, bool privacy_on);
+extern void BTM_BleTurnOnPrivacyOnRemote(const RawAddress& bd_addr,
+                                         bool privacy_on);
 
 /*******************************************************************************
  *
@@ -685,7 +704,7 @@
  * Returns          true to use LE, false use BR/EDR.
  *
  ******************************************************************************/
-extern bool BTM_UseLeLink(BD_ADDR bd_addr);
+extern bool BTM_UseLeLink(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -711,7 +730,8 @@
  * Returns          bool    true if LE device is found, false otherwise.
  *
  ******************************************************************************/
-extern bool BTM_GetLeSecurityState(BD_ADDR bd_addr, uint8_t* p_le_dev_sec_flags,
+extern bool BTM_GetLeSecurityState(const RawAddress& bd_addr,
+                                   uint8_t* p_le_dev_sec_flags,
                                    uint8_t* p_le_key_size);
 
 /*******************************************************************************
@@ -724,7 +744,7 @@
  * Returns          bool true if security procedure is running, false otherwise.
  *
  ******************************************************************************/
-extern bool BTM_BleSecurityProcedureIsRunning(BD_ADDR bd_addr);
+extern bool BTM_BleSecurityProcedureIsRunning(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -737,7 +757,7 @@
  * Returns          the key size or 0 if the size can't be retrieved.
  *
  ******************************************************************************/
-extern uint8_t BTM_BleGetSupportedKeySize(BD_ADDR bd_addr);
+extern uint8_t BTM_BleGetSupportedKeySize(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -820,9 +840,49 @@
  * Returns          BTM_SUCCESS if success; otherwise failed.
  *
  ******************************************************************************/
-extern tBTM_STATUS BTM_SetBleDataLength(BD_ADDR bd_addr,
+extern tBTM_STATUS BTM_SetBleDataLength(const RawAddress& bd_addr,
                                         uint16_t tx_pdu_length);
 
+/*******************************************************************************
+ *
+ * Function         BTM_BleReadPhy
+ *
+ * Description      To read the current PHYs for specified LE connection
+ *
+ *
+ * Returns          BTM_SUCCESS if success; otherwise failed.
+ *
+ ******************************************************************************/
+extern void BTM_BleReadPhy(
+    const RawAddress& bd_addr,
+    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb);
+
+/*******************************************************************************
+ *
+ * Function         BTM_BleSetDefaultPhy
+ *
+ * Description      To set preferred PHY for ensuing LE connections
+ *
+ *
+ * Returns          BTM_SUCCESS if success; otherwise failed.
+ *
+ ******************************************************************************/
+extern tBTM_STATUS BTM_BleSetDefaultPhy(uint8_t all_phys, uint8_t tx_phys,
+                                        uint8_t rx_phys);
+
+/*******************************************************************************
+ *
+ * Function         BTM_BleSetPhy
+ *
+ * Description      To set PHY preferences for specified LE connection
+ *
+ *
+ * Returns          BTM_SUCCESS if success; otherwise failed.
+ *
+ ******************************************************************************/
+extern void BTM_BleSetPhy(const RawAddress& bd_addr, uint8_t tx_phys,
+                          uint8_t rx_phys, uint16_t phy_options);
+
 extern void btm_ble_multi_adv_cleanup(void);
 
 #endif
diff --git a/stack/include/btm_ble_api_types.h b/stack/include/btm_ble_api_types.h
index 0ae3e52..57ef0d1 100644
--- a/stack/include/btm_ble_api_types.h
+++ b/stack/include/btm_ble_api_types.h
@@ -474,7 +474,7 @@
 
 typedef struct {
   bool in_use;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   uint8_t pf_counter[BTM_BLE_PF_TYPE_MAX]; /* number of filter indexed by
                                               tBTM_BLE_PF_COND_TYPE */
 } tBTM_BLE_PF_COUNT;
@@ -541,19 +541,8 @@
   tBTM_BLE_ENERGY_INFO_CBACK* p_ener_cback;
 } tBTM_BLE_ENERGY_INFO_CB;
 
-typedef bool(tBTM_BLE_SEL_CBACK)(BD_ADDR random_bda, uint8_t* p_remote_name);
 typedef void(tBTM_BLE_CTRL_FEATURES_CBACK)(tBTM_STATUS status);
 
-/* callback function for SMP signing algorithm, signed data in little endian
- * order with tlen bits long */
-typedef void(tBTM_BLE_SIGN_CBACK)(void* p_ref_data, uint8_t* p_signing_data);
-typedef void(tBTM_BLE_VERIFY_CBACK)(void* p_ref_data, bool match);
-/* random address set complete callback */
-typedef void(tBTM_BLE_RANDOM_SET_CBACK)(BD_ADDR random_bda);
-
-typedef void(tBTM_BLE_SCAN_REQ_CBACK)(BD_ADDR remote_bda,
-                                      tBLE_ADDR_TYPE addr_type,
-                                      uint8_t adv_evt);
 typedef void (*tBLE_SCAN_PARAM_SETUP_CBACK)(tGATT_IF client_if,
                                             tBTM_STATUS status);
 
diff --git a/stack/include/btu.h b/stack/include/btu.h
index 2b6834d..a69ad41 100644
--- a/stack/include/btu.h
+++ b/stack/include/btu.h
@@ -37,8 +37,6 @@
 /* Global BTU data */
 extern uint8_t btu_trace_level;
 
-extern const BD_ADDR BT_BD_ANY;
-
 /* Functions provided by btu_hcif.cc
  ***********************************
 */
diff --git a/stack/include/gap_api.h b/stack/include/gap_api.h
index 024ea54..d9a7217 100644
--- a/stack/include/gap_api.h
+++ b/stack/include/gap_api.h
@@ -122,7 +122,7 @@
 /* Definition of the GAP_FindAddrByName results structure */
 typedef struct {
   uint16_t status;
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   tBTM_BD_NAME devname;
 } tGAP_FINDADDR_RESULTS;
 
@@ -135,15 +135,15 @@
 
 typedef union {
   tGAP_BLE_PREF_PARAM conn_param;
-  BD_ADDR reconn_bda;
+  RawAddress reconn_bda;
   uint16_t icon;
   uint8_t* p_dev_name;
   uint8_t addr_resolution;
 
 } tGAP_BLE_ATTR_VALUE;
 
-typedef void(tGAP_BLE_CMPL_CBACK)(bool status, BD_ADDR addr, uint16_t length,
-                                  char* p_name);
+typedef void(tGAP_BLE_CMPL_CBACK)(bool status, const RawAddress& addr,
+                                  uint16_t length, char* p_name);
 
 /*****************************************************************************
  *  External Function Declarations
@@ -162,8 +162,8 @@
  *
  ******************************************************************************/
 extern uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id,
-                             bool is_server, BD_ADDR p_rem_bda, uint16_t psm,
-                             tL2CAP_CFG_INFO* p_cfg,
+                             bool is_server, const RawAddress* p_rem_bda,
+                             uint16_t psm, tL2CAP_CFG_INFO* p_cfg,
                              tL2CAP_ERTM_INFO* ertm_info, uint16_t security,
                              uint8_t chan_mode_mask, tGAP_CONN_CALLBACK* p_cb,
                              tBT_TRANSPORT transport);
@@ -283,7 +283,7 @@
  *                  GAP_ERR_BAD_HANDLE  - invalid handle
  *
  ******************************************************************************/
-extern uint8_t* GAP_ConnGetRemoteAddr(uint16_t gap_handle);
+extern const RawAddress* GAP_ConnGetRemoteAddr(uint16_t gap_handle);
 
 /*******************************************************************************
  *
@@ -346,7 +346,7 @@
  * Returns          true if read started, else false if GAP is busy
  *
  ******************************************************************************/
-extern bool GAP_BleReadPeerPrefConnParams(BD_ADDR peer_bda);
+extern bool GAP_BleReadPeerPrefConnParams(const RawAddress& peer_bda);
 
 /*******************************************************************************
  *
@@ -358,7 +358,7 @@
  * Returns          true if request accepted
  *
  ******************************************************************************/
-extern bool GAP_BleReadPeerDevName(BD_ADDR peer_bda,
+extern bool GAP_BleReadPeerDevName(const RawAddress& peer_bda,
                                    tGAP_BLE_CMPL_CBACK* p_cback);
 
 /*******************************************************************************
@@ -370,7 +370,7 @@
  * Returns          true if request accepted
  *
  ******************************************************************************/
-extern bool GAP_BleReadPeerAddressResolutionCap(BD_ADDR peer_bda,
+extern bool GAP_BleReadPeerAddressResolutionCap(const RawAddress& peer_bda,
                                                 tGAP_BLE_CMPL_CBACK* p_cback);
 
 /*******************************************************************************
@@ -382,6 +382,6 @@
  * Returns          true if request accepted
  *
  ******************************************************************************/
-extern bool GAP_BleCancelReadPeerDevName(BD_ADDR peer_bda);
+extern bool GAP_BleCancelReadPeerDevName(const RawAddress& peer_bda);
 
 #endif /* GAP_API_H */
diff --git a/stack/include/gatt_api.h b/stack/include/gatt_api.h
index 18aa91f..48ca8e3 100644
--- a/stack/include/gatt_api.h
+++ b/stack/include/gatt_api.h
@@ -561,8 +561,9 @@
                                tGATT_STATUS status, tGATT_CL_COMPLETE* p_data);
 
 /* Define a callback function when an initialized connection is established. */
-typedef void(tGATT_CONN_CBACK)(tGATT_IF gatt_if, BD_ADDR bda, uint16_t conn_id,
-                               bool connected, tGATT_DISCONN_REASON reason,
+typedef void(tGATT_CONN_CBACK)(tGATT_IF gatt_if, const RawAddress& bda,
+                               uint16_t conn_id, bool connected,
+                               tGATT_DISCONN_REASON reason,
                                tBT_TRANSPORT transport);
 
 /* attribute request callback for ATT server */
@@ -573,7 +574,7 @@
 typedef void(tGATT_CONGESTION_CBACK)(uint16_t conn_id, bool congested);
 
 /* Define a callback function when encryption is established. */
-typedef void(tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, BD_ADDR bda);
+typedef void(tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, const RawAddress& bda);
 
 /* Define a callback function when phy is updated. */
 typedef void(tGATT_PHY_UPDATE_CB)(tGATT_IF gatt_if, uint16_t conn_id,
@@ -619,7 +620,7 @@
 typedef uint8_t tGATTS_SRV_CHG_CMD;
 
 typedef struct {
-  BD_ADDR bda;
+  RawAddress bda;
   bool srv_changed;
 } tGATTS_SRV_CHG;
 
@@ -653,18 +654,6 @@
  *  External Function Declarations
  ******************************************************************************/
 
-/*******************************************************************************
- *
- * Function         GATT_SetTraceLevel
- *
- * Description      This function sets the trace level.  If called with
- *                  a value of 0xFF, it simply returns the current trace level.
- *
- * Returns          The new or current trace level
- *
- ******************************************************************************/
-extern uint8_t GATT_SetTraceLevel(uint8_t new_level);
-
 /******************************************************************************/
 /* GATT Profile API Functions */
 /******************************************************************************/
@@ -829,12 +818,6 @@
  ******************************************************************************/
 extern tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu);
 
-extern void GATTC_ReadPHY(
-    uint16_t conn_id,
-    base::Callback<void(uint8_t tx_phy, uint8_t rx_phy, uint8_t status)> cb);
-extern void GATTC_SetPreferredPHY(uint16_t conn_id, uint8_t tx_phy,
-                                  uint8_t rx_phy, uint16_t phy_options);
-
 /*******************************************************************************
  *
  * Function         GATTC_Discover
@@ -931,7 +914,7 @@
  * Returns          void
  *
  ******************************************************************************/
-extern void GATT_SetIdleTimeout(BD_ADDR bd_addr, uint16_t idle_tout,
+extern void GATT_SetIdleTimeout(const RawAddress& bd_addr, uint16_t idle_tout,
                                 tGATT_TRANSPORT transport);
 
 /*******************************************************************************
@@ -998,11 +981,12 @@
  * Returns          true if connection started; else false
  *
  ******************************************************************************/
-extern bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
-                         tBT_TRANSPORT transport, bool opportunistic);
-extern bool GATT_Connect(tGATT_IF gatt_if, BD_ADDR bd_addr, bool is_direct,
-                         tBT_TRANSPORT transport, bool opportunistic,
-                         uint8_t initiating_phys);
+extern bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr,
+                         bool is_direct, tBT_TRANSPORT transport,
+                         bool opportunistic);
+extern bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr,
+                         bool is_direct, tBT_TRANSPORT transport,
+                         bool opportunistic, uint8_t initiating_phys);
 
 /*******************************************************************************
  *
@@ -1021,7 +1005,7 @@
  * Returns          true if connection started; else false
  *
  ******************************************************************************/
-extern bool GATT_CancelConnect(tGATT_IF gatt_if, BD_ADDR bd_addr,
+extern bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr,
                                bool is_direct);
 
 /*******************************************************************************
@@ -1054,7 +1038,7 @@
  *
  ******************************************************************************/
 extern bool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if,
-                                    BD_ADDR bd_addr,
+                                    RawAddress& bd_addr,
                                     tBT_TRANSPORT* p_transport);
 
 /*******************************************************************************
@@ -1073,7 +1057,8 @@
  * Returns          true the ligical link is connected
  *
  ******************************************************************************/
-extern bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr,
+extern bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if,
+                                      const RawAddress& bd_addr,
                                       uint16_t* p_conn_id,
                                       tBT_TRANSPORT transport);
 
@@ -1086,8 +1071,8 @@
  * Returns          None.
  *
  ******************************************************************************/
-extern void GATT_ConfigServiceChangeCCC(BD_ADDR remote_bda, bool enable,
-                                        tBT_TRANSPORT transport);
+extern void GATT_ConfigServiceChangeCCC(const RawAddress& remote_bda,
+                                        bool enable, tBT_TRANSPORT transport);
 
 // Enables the GATT profile on the device.
 // It clears out the control blocks, and registers with L2CAP.
@@ -1098,7 +1083,7 @@
 
 // Link encryption complete notification for all encryption process
 // initiated outside GATT.
-extern void gatt_notify_enc_cmpl(BD_ADDR bd_addr);
+extern void gatt_notify_enc_cmpl(const RawAddress& bd_addr);
 
 // Reset bg device list.
 extern void gatt_reset_bgdev_list(void);
diff --git a/stack/include/hcidefs.h b/stack/include/hcidefs.h
index fbaba54..e40e55d 100644
--- a/stack/include/hcidefs.h
+++ b/stack/include/hcidefs.h
@@ -24,9 +24,10 @@
 #define HCI_PROTO_VERSION_2_0 0x03 /* Version for BT spec 2.0          */
 #define HCI_PROTO_VERSION_2_1 0x04 /* Version for BT spec 2.1 [Lisbon] */
 #define HCI_PROTO_VERSION_3_0 0x05 /* Version for BT spec 3.0          */
-#define HCI_PROTO_VERSION_4_0 0x06 /* Version for BT spec 4.0          */
+#define HCI_PROTO_VERSION_4_0 0x06 /* Version for BT spec 4.0 [LE]     */
 #define HCI_PROTO_VERSION_4_1 0x07 /* Version for BT spec 4.1          */
 #define HCI_PROTO_VERSION_4_2 0x08 /* Version for BT spec 4.2          */
+#define HCI_PROTO_VERSION_5_0 0x09 /* Version for BT spec 5.0          */
 
 /*
  *  Definitions for HCI groups
@@ -37,6 +38,7 @@
 #define HCI_GRP_INFORMATIONAL_PARAMS (0x04 << 10)    /* 0x1000 */
 #define HCI_GRP_STATUS_PARAMS (0x05 << 10)           /* 0x1400 */
 #define HCI_GRP_TESTING_CMDS (0x06 << 10)            /* 0x1800 */
+#define HCI_GRP_BLE_CMDS (0x08 << 10)               /* 0x2000 (LE Commands) */
 
 #define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10) /* 0xFC00 */
 
@@ -166,8 +168,10 @@
 #define HCI_WRITE_CLASS_OF_DEVICE (0x0024 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
 #define HCI_READ_VOICE_SETTINGS (0x0025 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
 #define HCI_WRITE_VOICE_SETTINGS (0x0026 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_READ_AUTO_FLUSH_TOUT (0x0027 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_WRITE_AUTO_FLUSH_TOUT (0x0028 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AUTOMATIC_FLUSH_TIMEOUT \
+  (0x0027 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT \
+  (0x0028 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
 #define HCI_READ_NUM_BCAST_REXMITS (0x0029 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
 #define HCI_WRITE_NUM_BCAST_REXMITS (0x002A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
 #define HCI_READ_HOLD_MODE_ACTIVITY (0x002B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
@@ -269,8 +273,8 @@
 #define HCI_INFORMATIONAL_CMDS_LAST HCI_READ_LOCAL_SUPPORTED_CODECS
 
 /* Commands of HCI_GRP_STATUS_PARAMS group */
-#define HCI_READ_FAILED_CONTACT_COUNT (0x0001 | HCI_GRP_STATUS_PARAMS)
-#define HCI_RESET_FAILED_CONTACT_COUNT (0x0002 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_FAILED_CONTACT_COUNTER (0x0001 | HCI_GRP_STATUS_PARAMS)
+#define HCI_RESET_FAILED_CONTACT_COUNTER (0x0002 | HCI_GRP_STATUS_PARAMS)
 #define HCI_GET_LINK_QUALITY (0x0003 | HCI_GRP_STATUS_PARAMS)
 #define HCI_READ_RSSI (0x0005 | HCI_GRP_STATUS_PARAMS)
 #define HCI_READ_AFH_CH_MAP (0x0006 | HCI_GRP_STATUS_PARAMS)
@@ -282,7 +286,7 @@
 #define HCI_READ_LOCAL_AMP_ASSOC (0x000A | HCI_GRP_STATUS_PARAMS)
 #define HCI_WRITE_REMOTE_AMP_ASSOC (0x000B | HCI_GRP_STATUS_PARAMS)
 
-#define HCI_STATUS_PARAMS_CMDS_FIRST HCI_READ_FAILED_CONTACT_COUNT
+#define HCI_STATUS_PARAMS_CMDS_FIRST HCI_READ_FAILED_CONTACT_COUNTER
 #define HCI_STATUS_PARAMS_CMDS_LAST HCI_WRITE_REMOTE_AMP_ASSOC
 
 /* Commands of HCI_GRP_TESTING_CMDS group */
@@ -304,8 +308,7 @@
 #define HCI_VSC_MULTI_AV_HANDLE 0x0AAA
 #define HCI_VSC_BURST_MODE_HANDLE 0x0BBB
 
-/* BLE HCI */
-#define HCI_GRP_BLE_CMDS (0x08 << 10)
+/* BLE HCI Group Commands */
 /* Commands of BLE Controller setup and configuration */
 #define HCI_BLE_SET_EVENT_MASK (0x0001 | HCI_GRP_BLE_CMDS)
 #define HCI_BLE_READ_BUFFER_SIZE (0x0002 | HCI_GRP_BLE_CMDS)
@@ -355,9 +358,11 @@
 #define HCI_BLE_READ_RESOLVABLE_ADDR_LOCAL (0x002C | HCI_GRP_BLE_CMDS)
 #define HCI_BLE_SET_ADDR_RESOLUTION_ENABLE (0x002D | HCI_GRP_BLE_CMDS)
 #define HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT (0x002E | HCI_GRP_BLE_CMDS)
-#define HCI_LE_READ_PHY (0x30 | HCI_GRP_BLE_CMDS)
-#define HCI_LE_SET_DEFAULT_PHY (0x31 | HCI_GRP_BLE_CMDS)
-#define HCI_LE_SET_PHY (0x32 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_PHY (0x0030 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_DEFAULT_PHY (0x0031 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_PHY (0x0032 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ENH_RECEIVER_TEST (0x0033 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ENH_TRANSMITTER_TEST (0x0034 | HCI_GRP_BLE_CMDS)
 #define HCI_LE_SET_EXT_ADVERTISING_RANDOM_ADDRESS (0x35 | HCI_GRP_BLE_CMDS)
 #define HCI_LE_SET_EXT_ADVERTISING_PARAM (0x36 | HCI_GRP_BLE_CMDS)
 #define HCI_LE_SET_EXT_ADVERTISING_DATA (0x37 | HCI_GRP_BLE_CMDS)
@@ -441,324 +446,48 @@
 #define HCI_LE_INIT_MA_STATE 0x00000800
 
 /* LE Supported States */
-/* Non Connectable Adv state is supported. 0x0000000000000001 */
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK 0x01
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF 0
-#define HCI_LE_STATES_NON_CONN_ADV_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF] &   \
-   HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK)
-
-/* Scanneable Connectable Adv state  is supported. 0x0000000000000002 */
-#define HCI_SUPP_LE_STATES_SCAN_ADV_MASK 0x02
-#define HCI_SUPP_LE_STATESSCAN_ADV_OFF 0
-#define HCI_LE_STATES_SCAN_ADV_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATESSCAN_ADV_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASK)
-
-/* Connectable Adv state is supported. 0x0000000000000004 */
-#define HCI_SUPP_LE_STATES_CONN_ADV_MASK 0x04
-#define HCI_SUPP_LE_STATES_CONN_ADV_OFF 0
-#define HCI_LE_STATES_CONN_ADV_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASK)
-
-/* Hi duty Cycle Directed Adv state is supported. 0x0000000000000008 */
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK 0x08
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF 0
-#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF] &   \
-   HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK)
-
-/* Passive Scan state is supported. 0x0000000000000010 */
-#define HCI_SUPP_LE_STATES_PASS_SCAN_MASK 0x10
-#define HCI_SUPP_LE_STATES_PASS_SCAN_OFF 0
-#define HCI_LE_STATES_PASS_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASK)
-
-/* Active Scan state is supported. 0x0000000000000020 */
-#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK 0x20
-#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF 0
-#define HCI_LE_STATES_ACTIVE_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK)
-
-/* Initiating state is supported. 0x0000000000000040 (or connection state in
- * master role is also supported) */
-#define HCI_SUPP_LE_STATES_INIT_MASK 0x40
-#define HCI_SUPP_LE_STATES_INIT_OFF 0
-#define HCI_LE_STATES_INIT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_INIT_OFF] & HCI_SUPP_LE_STATES_INIT_MASK)
-
-/* connection state in slave  role is also supported. 0x0000000000000080 */
-#define HCI_SUPP_LE_STATES_SLAVE_MASK 0x80
-#define HCI_SUPP_LE_STATES_SLAVE_OFF 0
-#define HCI_LE_STATES_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_SLAVE_OFF] & HCI_SUPP_LE_STATES_SLAVE_MASK)
-
-/* Non Connectable Adv state and Passive Scanning State combination is
- * supported. 0x0000000000000100 */
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK 0x01
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF 1
-#define HCI_LE_STATES_NON_CONN_ADV_PASS_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK)
-
-/* Scannable Adv state and Passive Scanning State combination is supported.
- * 0x0000000000000200 */
-#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK 0x02
-#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF 1
-#define HCI_LE_STATES_SCAN_ADV_PASS_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK)
-
-/* Connectable Adv state and Passive Scanning State combination is supported.
- * 0x0000000000000400 */
-#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK 0x04
-#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF 1
-#define HCI_LE_STATES_CONN_ADV_PASS_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK)
-
-/* High Duty Cycl Directed ADv and Passive Scanning State combination is
- * supported. 0x0000000000000800 */
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK 0x08
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF 1
-#define HCI_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK] &  \
-   HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF)
-
-/* Non Connectable Adv state and Passive Scanning State combination is
- * supported. 0x0000000000001000 */
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK 0x10
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF 1
-#define HCI_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK)
-
-/* Scannable Adv state and Active Scanning State combination is supported.
- * 0x0000000000002000 */
-#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK 0x20
-#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF 1
-#define HCI_LE_STATES_SCAN_ADV_ACTIVE_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK)
-
-/* Connectable Adv state and Active Scanning State combination is supported.
- * 0x0000000000004000 */
-#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK 0x40
-#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF 1
-#define HCI_LE_STATES_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK)
-
-/* High Duty Cycl Directed ADv and ACtive Scanning State combination is
- * supported. 0x0000000000008000 */
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK 0x80
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF 1
-#define HCI_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK] &  \
-   HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF)
-
-/* Non-Connectable Adv state and Initiating State combination is supported.
- * 0x0000000000010000 */
-#define HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK 0x01
-#define HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF 2
-#define HCI_LE_STATES_NON_CONN_INIT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF] &   \
-   HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK)
-
-/* Scannable Adv state and Initiating State combination is supported.
- * 0x0000000000020000 */
-#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK 0x02
-#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF 2
-#define HCI_LE_STATES_SCAN_ADV_INIT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF] &   \
-   HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK)
-
-/* Non-Connectable Adv state and Master Role combination is supported.
- * 0x0000000000040000 */
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK 0x04
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF 2
-#define HCI_LE_STATES_NON_CONN_ADV_MASTER_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF] &   \
-   HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK)
-
-/* Scannable Adv state and Master Role combination is supported.
- * 0x0000000000040000 */
-#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK 0x08
-#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF 2
-#define HCI_LE_STATES_SCAN_ADV_MASTER_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF] &   \
-   HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK)
-
-/* Non-Connectable Adv and Slave Role combination is supported.
- * 0x000000000100000 */
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK 0x10
-#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF 2
-#define HCI_LE_STATES_NON_CONN_ADV_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF] &   \
-   HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK)
-
-/* Scannable Adv and Slave Role combination is supported. 0x000000000200000 */
-#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK 0x20
-#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF 2
-#define HCI_LE_STATES_SCAN_ADV_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF] &   \
-   HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK)
-
-/* Passive Scan and Initiating State combination is supported.
- * 0x000000000400000 */
-#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK 0x40
-#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF 2
-#define HCI_LE_STATES_PASS_SCAN_INIT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF] &   \
-   HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK)
-
-/* Active Scan and Initiating State combination is supported.
- * 0x000000000800000 */
-#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK 0x80
-#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF 2
-#define HCI_LE_STATES_ACTIVE_SCAN_INIT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF] &   \
-   HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK)
-
-/* Passive Scan and Master Role combination is supported. 0x000000001000000 */
-#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK 0x01
-#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF 3
-#define HCI_LE_STATES_PASS_SCAN_MASTER_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF] &   \
-   HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK)
-
-/* Active Scan and Master Role combination is supported. 0x000000002000000 */
-#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK 0x02
-#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF 3
-#define HCI_LE_STATES_ACTIVE_SCAN_MASTER_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF] &   \
-   HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK)
-
-/* Passive Scan and Slave Role combination is supported. 0x000000004000000 */
-#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK 0x04
-#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF 3
-#define HCI_LE_STATES_PASS_SCAN_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF] &   \
-   HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK)
-
-/* Active Scan and Slave Role combination is supported. 0x000000008000000 */
-#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK 0x08
-#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF 3
-#define HCI_LE_STATES_ACTIVE_SCAN_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF] &   \
-   HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK)
-
-/* Link Layer Topology Added States Combo */
-/* Initiating State and Master Role combination supported.
-  Master Role and Master Role combination is also supported. 0x0000000010000000
-  */
-#define HCI_SUPP_LE_STATES_INIT_MASTER_MASK 0x10
-#define HCI_SUPP_LE_STATES_INIT_MASTER_OFF 3
-#define HCI_LE_STATES_INIT_MASTER_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_OFF] &   \
-   HCI_SUPP_LE_STATES_INIT_MASTER_MASK)
-
-/* Low Duty Cycle Directed Advertising State . 0x0000000020000000 */
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASK 0x20
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_OFF 3
-#define HCI_LE_STATES_LOW_DUTY_DIR_ADV_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_LOW_DUTY_DIR_ADV_OFF] &   \
-   HCI_SUPP_LE_STATES_LOW_DUTY_DIR_ADV_MASK)
-
-/* Low Duty Cycle Directed Advertising State and Passive scan combination.
- * 0x0000000040000000 */
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_MASK 0x40
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_OFF 3
-#define HCI_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_MASK)
-
-/* Low Duty Cycle Directed Advertising State and Active scan combination.
- * 0x0000000080000000 */
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_MASK 0x80
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_OFF 3
-#define HCI_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_OFF] &   \
-   HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_MASK)
-
-/* Connectable Advertising State and Initiating State combination supported.
- * 0x0000000100000000 */
-#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK 0x01
-#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF 4
-#define HCI_LE_STATES_CONN_ADV_INIT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF] &   \
-   HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK)
-
-/* High Duty Cycle Directed Advertising State and Initiating State combination
- * supported. */
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK 0x02
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF 4
-#define HCI_LE_STATES_HI_DUTY_DIR_ADV_INIT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF] &   \
-   HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK)
-
-/* Low Duty Cycle Directed Advertising State and Initiating State combination
- * supported.*/
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK 0x04
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF 4
-#define HCI_LE_STATES_LO_DUTY_DIR_ADV_INIT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF] &   \
-   HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK)
-
-/* Connectable Advertising State and Master Role combination supported.*/
-#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK 0x08
-#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF 4
-#define HCI_LE_STATES_CONN_ADV_MASTER_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF] &   \
-   HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK)
-
-/* High Duty Cycle Directed Advertising State and Master Role combination
- * supported.*/
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK 0x10
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF 4
-#define HCI_LE_STATES_HI_DUTY_DIR_ADV_MASTER_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF] &   \
-   HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK)
-
-/* Low Duty Cycle Directed Advertising State and Master Role combination
- * supported.*/
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK 0x20
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF 4
-#define HCI_LE_STATES_LO_DUTY_DIR_ADV_MASTER_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF] &   \
-   HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK)
-
-/* Connectable Advertising State and Slave Role combination supported. */
-#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK 0x40
-#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF 4
-#define HCI_LE_STATES_CONN_ADV_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF] &   \
-   HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK)
-
-/* High Duty Cycle Directed Advertising State and slave Role combination
- * supported.*/
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK 0x80
-#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF 4
-#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF] &   \
-   HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK)
-
-/* Low Duty Cycle Directed Advertising State and slave Role combination
- * supported.*/
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK 0x01
-#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF 5
-#define HCI_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF] &   \
-   HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK)
-
-/* Initiating State and Slave Role combination supported.
-   Master Role and Slave Role combination also supported.
- */
-#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK 0x02
-#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF 5
-#define HCI_LE_STATES_INIT_MASTER_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF] &   \
-   HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK)
+constexpr uint8_t HCI_LE_STATES_NON_CONN_ADV_BIT = 0;
+constexpr uint8_t HCI_LE_STATES_SCAN_ADV_BIT = 1;
+constexpr uint8_t HCI_LE_STATES_CONN_ADV_BIT = 2;
+constexpr uint8_t HCI_LE_STATES_HI_DUTY_DIR_ADV_BIT = 3;
+constexpr uint8_t HCI_LE_STATES_PASS_SCAN_BIT = 4;
+constexpr uint8_t HCI_LE_STATES_ACTIVE_SCAN_BIT = 5;
+constexpr uint8_t HCI_LE_STATES_INIT_BIT = 6;
+constexpr uint8_t HCI_LE_STATES_SLAVE_BIT = 7;
+constexpr uint8_t HCI_LE_STATES_NON_CONN_ADV_PASS_SCAN_BIT = 8;
+constexpr uint8_t HCI_LE_STATES_SCAN_ADV_PASS_SCAN_BIT = 9;
+constexpr uint8_t HCI_LE_STATES_CONN_ADV_PASS_SCAN_BIT = 10;
+constexpr uint8_t HCI_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_BIT = 11;
+constexpr uint8_t HCI_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_BIT = 12;
+constexpr uint8_t HCI_LE_STATES_SCAN_ADV_ACTIVE_SCAN_BIT = 13;
+constexpr uint8_t HCI_LE_STATES_CONN_ADV_ACTIVE_SCAN_BIT = 14;
+constexpr uint8_t HCI_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_BIT = 15;
+constexpr uint8_t HCI_LE_STATES_NON_CONN_INIT_BIT = 16;
+constexpr uint8_t HCI_LE_STATES_SCAN_ADV_INIT_BIT = 17;
+constexpr uint8_t HCI_LE_STATES_NON_CONN_ADV_MASTER_BIT = 18;
+constexpr uint8_t HCI_LE_STATES_SCAN_ADV_MASTER_BIT = 19;
+constexpr uint8_t HCI_LE_STATES_NON_CONN_ADV_SLAVE_BIT = 20;
+constexpr uint8_t HCI_LE_STATES_SCAN_ADV_SLAVE_BIT = 21;
+constexpr uint8_t HCI_LE_STATES_PASS_SCAN_INIT_BIT = 22;
+constexpr uint8_t HCI_LE_STATES_ACTIVE_SCAN_INIT_BIT = 23;
+constexpr uint8_t HCI_LE_STATES_PASS_SCAN_MASTER_BIT = 24;
+constexpr uint8_t HCI_LE_STATES_ACTIVE_SCAN_MASTER_BIT = 25;
+constexpr uint8_t HCI_LE_STATES_PASS_SCAN_SLAVE_BIT = 26;
+constexpr uint8_t HCI_LE_STATES_ACTIVE_SCAN_SLAVE_BIT = 27;
+constexpr uint8_t HCI_LE_STATES_INIT_MASTER_BIT = 28;
+constexpr uint8_t HCI_LE_STATES_LOW_DUTY_DIR_ADV_BIT = 29;
+constexpr uint8_t HCI_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_BIT = 30;
+constexpr uint8_t HCI_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_BIT = 31;
+constexpr uint8_t HCI_LE_STATES_CONN_ADV_INIT_BIT = 32;
+constexpr uint8_t HCI_LE_STATES_HI_DUTY_DIR_ADV_INIT_BIT = 33;
+constexpr uint8_t HCI_LE_STATES_LO_DUTY_DIR_ADV_INIT_BIT = 34;
+constexpr uint8_t HCI_LE_STATES_CONN_ADV_MASTER_BIT = 35;
+constexpr uint8_t HCI_LE_STATES_HI_DUTY_DIR_ADV_MASTER_BIT = 36;
+constexpr uint8_t HCI_LE_STATES_LO_DUTY_DIR_ADV_MASTER_BIT = 37;
+constexpr uint8_t HCI_LE_STATES_CONN_ADV_SLAVE_BIT = 38;
+constexpr uint8_t HCI_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_BIT = 39;
+constexpr uint8_t HCI_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_BIT = 40;
+constexpr uint8_t HCI_LE_STATES_INIT_MASTER_SLAVE_BIT = 41;
 
 /*
  *  Definitions for HCI Events
@@ -841,7 +570,7 @@
 #define HCI_BLE_DATA_LENGTH_CHANGE_EVT 0x07
 #define HCI_BLE_ENHANCED_CONN_COMPLETE_EVT 0x0a
 #define HCI_BLE_DIRECT_ADV_EVT 0x0b
-#define HCI_LE_PHY_UPDATE_COMPLETE_EVT 0x0C
+#define HCI_BLE_PHY_UPDATE_COMPLETE_EVT 0x0c
 #define HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT 0x0D
 #define HCI_LE_ADVERTISING_SET_TERMINATED_EVT 0x12
 
@@ -1363,8 +1092,8 @@
   (((x)&HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_TRANSPNT)
 
 /* Retransmit timer definitions in 0.625 */
-#define HCI_MAX_AUTO_FLUSH_TOUT 0x07FF
-#define HCI_DEFAULT_AUTO_FLUSH_TOUT 0 /* No auto flush */
+#define HCI_MAX_AUTOMATIC_FLUSH_TIMEOUT 0x07FF
+#define HCI_DEFAULT_AUTOMATIC_FLUSH_TIMEOUT 0 /* No auto flush */
 
 /* Broadcast retransmitions */
 #define HCI_DEFAULT_NUM_BCAST_RETRAN 1
@@ -1572,1628 +1301,342 @@
 #define HCI_FEATURES_KNOWN(x) \
   (((x)[0] | (x)[1] | (x)[2] | (x)[3] | (x)[4] | (x)[5] | (x)[6] | (x)[7]) != 0)
 
-/*
- *   LMP features encoding - page 0
-*/
-#define HCI_FEATURE_3_SLOT_PACKETS_MASK 0x01
-#define HCI_FEATURE_3_SLOT_PACKETS_OFF 0
-#define HCI_3_SLOT_PACKETS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_3_SLOT_PACKETS_OFF] & HCI_FEATURE_3_SLOT_PACKETS_MASK)
+/* LMP features encoding - page 0 */
+#define HCI_3_SLOT_PACKETS_SUPPORTED(x) ((x)[0] & 0x01)
+#define HCI_5_SLOT_PACKETS_SUPPORTED(x) ((x)[0] & 0x02)
+#define HCI_ENCRYPTION_SUPPORTED(x) ((x)[0] & 0x04)
+#define HCI_SLOT_OFFSET_SUPPORTED(x) ((x)[0] & 0x08)
+#define HCI_TIMING_ACC_SUPPORTED(x) ((x)[0] & 0x10)
+#define HCI_SWITCH_SUPPORTED(x) ((x)[0] & 0x20)
+#define HCI_HOLD_MODE_SUPPORTED(x) ((x)[0] & 0x40)
+#define HCI_SNIFF_MODE_SUPPORTED(x) ((x)[0] & 0x80)
 
-#define HCI_FEATURE_5_SLOT_PACKETS_MASK 0x02
-#define HCI_FEATURE_5_SLOT_PACKETS_OFF 0
-#define HCI_5_SLOT_PACKETS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_5_SLOT_PACKETS_OFF] & HCI_FEATURE_5_SLOT_PACKETS_MASK)
+#define HCI_PARK_MODE_SUPPORTED(x) ((x)[1] & 0x01)
+#define HCI_RSSI_SUPPORTED(x) ((x)[1] & 0x02)
+#define HCI_CQM_DATA_RATE_SUPPORTED(x) ((x)[1] & 0x04)
+#define HCI_SCO_LINK_SUPPORTED(x) ((x)[1] & 0x08)
+#define HCI_HV2_PACKETS_SUPPORTED(x) ((x)[1] & 0x10)
+#define HCI_HV3_PACKETS_SUPPORTED(x) ((x)[1] & 0x20)
+#define HCI_LMP_U_LAW_SUPPORTED(x) ((x)[1] & 0x40)
+#define HCI_LMP_A_LAW_SUPPORTED(x) ((x)[1] & 0x80)
 
-#define HCI_FEATURE_ENCRYPTION_MASK 0x04
-#define HCI_FEATURE_ENCRYPTION_OFF 0
-#define HCI_ENCRYPTION_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ENCRYPTION_OFF] & HCI_FEATURE_ENCRYPTION_MASK)
+#define HCI_LMP_CVSD_SUPPORTED(x) ((x)[2] & 0x01)
+#define HCI_PAGING_SCHEME_SUPPORTED(x) ((x)[2] & 0x02)
+#define HCI_POWER_CTRL_SUPPORTED(x) ((x)[2] & 0x04)
+#define HCI_LMP_TRANSPNT_SUPPORTED(x) ((x)[2] & 0x08)
+#define HCI_FLOW_CTRL_LAG_VALUE(x) (((x)[2] & 0x70) >> 4)
+#define HCI_LMP_BCAST_ENC_SUPPORTED(x) ((x)[2] & 0x80)
 
-#define HCI_FEATURE_SLOT_OFFSET_MASK 0x08
-#define HCI_FEATURE_SLOT_OFFSET_OFF 0
-#define HCI_SLOT_OFFSET_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_SLOT_OFFSET_OFF] & HCI_FEATURE_SLOT_OFFSET_MASK)
+#define HCI_LMP_SCATTER_MODE_SUPPORTED(x) ((x)[3] & 0x01)
+#define HCI_EDR_ACL_2MPS_SUPPORTED(x) ((x)[3] & 0x02)
+#define HCI_EDR_ACL_3MPS_SUPPORTED(x) ((x)[3] & 0x04)
+#define HCI_ENHANCED_INQ_SUPPORTED(x) ((x)[3] & 0x08)
+#define HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(x) ((x)[3] & 0x10)
+#define HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(x) ((x)[3] & 0x20)
+#define HCI_LMP_INQ_RSSI_SUPPORTED(x) ((x)[3] & 0x40)
+#define HCI_ESCO_EV3_SUPPORTED(x) ((x)[3] & 0x80)
 
-#define HCI_FEATURE_TIMING_ACC_MASK 0x10
-#define HCI_FEATURE_TIMING_ACC_OFF 0
-#define HCI_TIMING_ACC_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_TIMING_ACC_OFF] & HCI_FEATURE_TIMING_ACC_MASK)
+#define HCI_ESCO_EV4_SUPPORTED(x) ((x)[4] & 0x01)
+#define HCI_ESCO_EV5_SUPPORTED(x) ((x)[4] & 0x02)
+#define HCI_LMP_ABSENCE_MASKS_SUPPORTED(x) ((x)[4] & 0x04)
+#define HCI_LMP_AFH_CAP_SLAVE_SUPPORTED(x) ((x)[4] & 0x08)
+#define HCI_LMP_AFH_CLASS_SLAVE_SUPPORTED(x) ((x)[4] & 0x10)
+#define HCI_BREDR_NOT_SPT_SUPPORTED(x) ((x)[4] & 0x20)
+#define HCI_LE_SPT_SUPPORTED(x) ((x)[4] & 0x40)
+#define HCI_3_SLOT_EDR_ACL_SUPPORTED(x) ((x)[4] & 0x80)
 
-#define HCI_FEATURE_SWITCH_MASK 0x20
-#define HCI_FEATURE_SWITCH_OFF 0
-#define HCI_SWITCH_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_SWITCH_OFF] & HCI_FEATURE_SWITCH_MASK)
+#define HCI_5_SLOT_EDR_ACL_SUPPORTED(x) ((x)[5] & 0x01)
+#define HCI_SNIFF_SUB_RATE_SUPPORTED(x) ((x)[5] & 0x02)
+#define HCI_ATOMIC_ENCRYPT_SUPPORTED(x) ((x)[5] & 0x04)
+#define HCI_LMP_AFH_CAP_MASTR_SUPPORTED(x) ((x)[5] & 0x08)
+#define HCI_LMP_AFH_CLASS_MASTR_SUPPORTED(x) ((x)[5] & 0x10)
+#define HCI_EDR_ESCO_2MPS_SUPPORTED(x) ((x)[5] & 0x20)
+#define HCI_EDR_ESCO_3MPS_SUPPORTED(x) ((x)[5] & 0x40)
+#define HCI_3_SLOT_EDR_ESCO_SUPPORTED(x) ((x)[5] & 0x80)
 
-#define HCI_FEATURE_HOLD_MODE_MASK 0x40
-#define HCI_FEATURE_HOLD_MODE_OFF 0
-#define HCI_HOLD_MODE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_HOLD_MODE_OFF] & HCI_FEATURE_HOLD_MODE_MASK)
-
-#define HCI_FEATURE_SNIFF_MODE_MASK 0x80
-#define HCI_FEATURE_SNIFF_MODE_OFF 0
-#define HCI_SNIFF_MODE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_SNIFF_MODE_OFF] & HCI_FEATURE_SNIFF_MODE_MASK)
-
-#define HCI_FEATURE_PARK_MODE_MASK 0x01
-#define HCI_FEATURE_PARK_MODE_OFF 1
-#define HCI_PARK_MODE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_PARK_MODE_OFF] & HCI_FEATURE_PARK_MODE_MASK)
-
-#define HCI_FEATURE_RSSI_MASK 0x02
-#define HCI_FEATURE_RSSI_OFF 1
-#define HCI_RSSI_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_RSSI_OFF] & HCI_FEATURE_RSSI_MASK)
-
-#define HCI_FEATURE_CQM_DATA_RATE_MASK 0x04
-#define HCI_FEATURE_CQM_DATA_RATE_OFF 1
-#define HCI_CQM_DATA_RATE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_CQM_DATA_RATE_OFF] & HCI_FEATURE_CQM_DATA_RATE_MASK)
-
-#define HCI_FEATURE_SCO_LINK_MASK 0x08
-#define HCI_FEATURE_SCO_LINK_OFF 1
-#define HCI_SCO_LINK_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_SCO_LINK_OFF] & HCI_FEATURE_SCO_LINK_MASK)
-
-#define HCI_FEATURE_HV2_PACKETS_MASK 0x10
-#define HCI_FEATURE_HV2_PACKETS_OFF 1
-#define HCI_HV2_PACKETS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_HV2_PACKETS_OFF] & HCI_FEATURE_HV2_PACKETS_MASK)
-
-#define HCI_FEATURE_HV3_PACKETS_MASK 0x20
-#define HCI_FEATURE_HV3_PACKETS_OFF 1
-#define HCI_HV3_PACKETS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_HV3_PACKETS_OFF] & HCI_FEATURE_HV3_PACKETS_MASK)
-
-#define HCI_FEATURE_U_LAW_MASK 0x40
-#define HCI_FEATURE_U_LAW_OFF 1
-#define HCI_LMP_U_LAW_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_U_LAW_OFF] & HCI_FEATURE_U_LAW_MASK)
-
-#define HCI_FEATURE_A_LAW_MASK 0x80
-#define HCI_FEATURE_A_LAW_OFF 1
-#define HCI_LMP_A_LAW_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_A_LAW_OFF] & HCI_FEATURE_A_LAW_MASK)
-
-#define HCI_FEATURE_CVSD_MASK 0x01
-#define HCI_FEATURE_CVSD_OFF 2
-#define HCI_LMP_CVSD_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_CVSD_OFF] & HCI_FEATURE_CVSD_MASK)
-
-#define HCI_FEATURE_PAGING_SCHEME_MASK 0x02
-#define HCI_FEATURE_PAGING_SCHEME_OFF 2
-#define HCI_PAGING_SCHEME_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_PAGING_SCHEME_OFF] & HCI_FEATURE_PAGING_SCHEME_MASK)
-
-#define HCI_FEATURE_POWER_CTRL_MASK 0x04
-#define HCI_FEATURE_POWER_CTRL_OFF 2
-#define HCI_POWER_CTRL_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_POWER_CTRL_OFF] & HCI_FEATURE_POWER_CTRL_MASK)
-
-#define HCI_FEATURE_TRANSPNT_MASK 0x08
-#define HCI_FEATURE_TRANSPNT_OFF 2
-#define HCI_LMP_TRANSPNT_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_TRANSPNT_OFF] & HCI_FEATURE_TRANSPNT_MASK)
-
-#define HCI_FEATURE_FLOW_CTRL_LAG_MASK 0x70
-#define HCI_FEATURE_FLOW_CTRL_LAG_OFF 2
-#define HCI_FLOW_CTRL_LAG_VALUE(x) \
-  (((x)[HCI_FEATURE_FLOW_CTRL_LAG_OFF] & HCI_FEATURE_FLOW_CTRL_LAG_MASK) >> 4)
-
-#define HCI_FEATURE_BROADCAST_ENC_MASK 0x80
-#define HCI_FEATURE_BROADCAST_ENC_OFF 2
-#define HCI_LMP_BCAST_ENC_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_BROADCAST_ENC_OFF] & HCI_FEATURE_BROADCAST_ENC_MASK)
-
-#define HCI_FEATURE_SCATTER_MODE_MASK 0x01
-#define HCI_FEATURE_SCATTER_MODE_OFF 3
-#define HCI_LMP_SCATTER_MODE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_SCATTER_MODE_OFF] & HCI_FEATURE_SCATTER_MODE_MASK)
-
-#define HCI_FEATURE_EDR_ACL_2MPS_MASK 0x02
-#define HCI_FEATURE_EDR_ACL_2MPS_OFF 3
-#define HCI_EDR_ACL_2MPS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_EDR_ACL_2MPS_OFF] & HCI_FEATURE_EDR_ACL_2MPS_MASK)
-
-#define HCI_FEATURE_EDR_ACL_3MPS_MASK 0x04
-#define HCI_FEATURE_EDR_ACL_3MPS_OFF 3
-#define HCI_EDR_ACL_3MPS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_EDR_ACL_3MPS_OFF] & HCI_FEATURE_EDR_ACL_3MPS_MASK)
-
-#define HCI_FEATURE_ENHANCED_INQ_MASK 0x08
-#define HCI_FEATURE_ENHANCED_INQ_OFF 3
-#define HCI_ENHANCED_INQ_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ENHANCED_INQ_OFF] & HCI_FEATURE_ENHANCED_INQ_MASK)
-
-#define HCI_FEATURE_INTERLACED_INQ_SCAN_MASK 0x10
-#define HCI_FEATURE_INTERLACED_INQ_SCAN_OFF 3
-#define HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_INTERLACED_INQ_SCAN_OFF] &    \
-   HCI_FEATURE_INTERLACED_INQ_SCAN_MASK)
-
-#define HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK 0x20
-#define HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF 3
-#define HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF] &    \
-   HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK)
-
-#define HCI_FEATURE_INQ_RSSI_MASK 0x40
-#define HCI_FEATURE_INQ_RSSI_OFF 3
-#define HCI_LMP_INQ_RSSI_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_INQ_RSSI_OFF] & HCI_FEATURE_INQ_RSSI_MASK)
-
-#define HCI_FEATURE_ESCO_EV3_MASK 0x80
-#define HCI_FEATURE_ESCO_EV3_OFF 3
-#define HCI_ESCO_EV3_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ESCO_EV3_OFF] & HCI_FEATURE_ESCO_EV3_MASK)
-
-#define HCI_FEATURE_ESCO_EV4_MASK 0x01
-#define HCI_FEATURE_ESCO_EV4_OFF 4
-#define HCI_ESCO_EV4_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ESCO_EV4_OFF] & HCI_FEATURE_ESCO_EV4_MASK)
-
-#define HCI_FEATURE_ESCO_EV5_MASK 0x02
-#define HCI_FEATURE_ESCO_EV5_OFF 4
-#define HCI_ESCO_EV5_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ESCO_EV5_OFF] & HCI_FEATURE_ESCO_EV5_MASK)
-
-#define HCI_FEATURE_ABSENCE_MASKS_MASK 0x04
-#define HCI_FEATURE_ABSENCE_MASKS_OFF 4
-#define HCI_LMP_ABSENCE_MASKS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ABSENCE_MASKS_OFF] & HCI_FEATURE_ABSENCE_MASKS_MASK)
-
-#define HCI_FEATURE_AFH_CAP_SLAVE_MASK 0x08
-#define HCI_FEATURE_AFH_CAP_SLAVE_OFF 4
-#define HCI_LMP_AFH_CAP_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_AFH_CAP_SLAVE_OFF] & HCI_FEATURE_AFH_CAP_SLAVE_MASK)
-
-#define HCI_FEATURE_AFH_CLASS_SLAVE_MASK 0x10
-#define HCI_FEATURE_AFH_CLASS_SLAVE_OFF 4
-#define HCI_LMP_AFH_CLASS_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_AFH_CLASS_SLAVE_OFF] & HCI_FEATURE_AFH_CLASS_SLAVE_MASK)
-
-#define HCI_FEATURE_BREDR_NOT_SPT_MASK 0x20
-#define HCI_FEATURE_BREDR_NOT_SPT_OFF 4
-#define HCI_BREDR_NOT_SPT_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_BREDR_NOT_SPT_OFF] & HCI_FEATURE_BREDR_NOT_SPT_MASK)
-
-#define HCI_FEATURE_LE_SPT_MASK 0x40
-#define HCI_FEATURE_LE_SPT_OFF 4
-#define HCI_LE_SPT_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_LE_SPT_OFF] & HCI_FEATURE_LE_SPT_MASK)
-
-#define HCI_FEATURE_3_SLOT_EDR_ACL_MASK 0x80
-#define HCI_FEATURE_3_SLOT_EDR_ACL_OFF 4
-#define HCI_3_SLOT_EDR_ACL_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_3_SLOT_EDR_ACL_OFF] & HCI_FEATURE_3_SLOT_EDR_ACL_MASK)
-
-#define HCI_FEATURE_5_SLOT_EDR_ACL_MASK 0x01
-#define HCI_FEATURE_5_SLOT_EDR_ACL_OFF 5
-#define HCI_5_SLOT_EDR_ACL_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_5_SLOT_EDR_ACL_OFF] & HCI_FEATURE_5_SLOT_EDR_ACL_MASK)
-
-#define HCI_FEATURE_SNIFF_SUB_RATE_MASK 0x02
-#define HCI_FEATURE_SNIFF_SUB_RATE_OFF 5
-#define HCI_SNIFF_SUB_RATE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_SNIFF_SUB_RATE_OFF] & HCI_FEATURE_SNIFF_SUB_RATE_MASK)
-
-#define HCI_FEATURE_ATOMIC_ENCRYPT_MASK 0x04
-#define HCI_FEATURE_ATOMIC_ENCRYPT_OFF 5
-#define HCI_ATOMIC_ENCRYPT_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ATOMIC_ENCRYPT_OFF] & HCI_FEATURE_ATOMIC_ENCRYPT_MASK)
-
-#define HCI_FEATURE_AFH_CAP_MASTR_MASK 0x08
-#define HCI_FEATURE_AFH_CAP_MASTR_OFF 5
-#define HCI_LMP_AFH_CAP_MASTR_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_AFH_CAP_MASTR_OFF] & HCI_FEATURE_AFH_CAP_MASTR_MASK)
-
-#define HCI_FEATURE_AFH_CLASS_MASTR_MASK 0x10
-#define HCI_FEATURE_AFH_CLASS_MASTR_OFF 5
-#define HCI_LMP_AFH_CLASS_MASTR_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_AFH_CLASS_MASTR_OFF] & HCI_FEATURE_AFH_CLASS_MASTR_MASK)
-
-#define HCI_FEATURE_EDR_ESCO_2MPS_MASK 0x20
-#define HCI_FEATURE_EDR_ESCO_2MPS_OFF 5
-#define HCI_EDR_ESCO_2MPS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_EDR_ESCO_2MPS_OFF] & HCI_FEATURE_EDR_ESCO_2MPS_MASK)
-
-#define HCI_FEATURE_EDR_ESCO_3MPS_MASK 0x40
-#define HCI_FEATURE_EDR_ESCO_3MPS_OFF 5
-#define HCI_EDR_ESCO_3MPS_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_EDR_ESCO_3MPS_OFF] & HCI_FEATURE_EDR_ESCO_3MPS_MASK)
-
-#define HCI_FEATURE_3_SLOT_EDR_ESCO_MASK 0x80
-#define HCI_FEATURE_3_SLOT_EDR_ESCO_OFF 5
-#define HCI_3_SLOT_EDR_ESCO_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_3_SLOT_EDR_ESCO_OFF] & HCI_FEATURE_3_SLOT_EDR_ESCO_MASK)
-
-#define HCI_FEATURE_EXT_INQ_RSP_MASK 0x01
-#define HCI_FEATURE_EXT_INQ_RSP_OFF 6
-#define HCI_EXT_INQ_RSP_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_EXT_INQ_RSP_OFF] & HCI_FEATURE_EXT_INQ_RSP_MASK)
-
-#if 1 /* TOKYO spec definition */
-#define HCI_FEATURE_SIMUL_LE_BREDR_MASK 0x02
-#define HCI_FEATURE_SIMUL_LE_BREDR_OFF 6
-#define HCI_SIMUL_LE_BREDR_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_SIMUL_LE_BREDR_OFF] & HCI_FEATURE_SIMUL_LE_BREDR_MASK)
-
-#else
-#define HCI_FEATURE_ANUM_PIN_AWARE_MASK 0x02
-#define HCI_FEATURE_ANUM_PIN_AWARE_OFF 6
-#define HCI_ANUM_PIN_AWARE_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ANUM_PIN_AWARE_OFF] & HCI_FEATURE_ANUM_PIN_AWARE_MASK)
-#endif
-
-#define HCI_FEATURE_ANUM_PIN_CAP_MASK 0x04
-#define HCI_FEATURE_ANUM_PIN_CAP_OFF 6
-#define HCI_ANUM_PIN_CAP_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ANUM_PIN_CAP_OFF] & HCI_FEATURE_ANUM_PIN_CAP_MASK)
-
-#define HCI_FEATURE_SIMPLE_PAIRING_MASK 0x08
-#define HCI_FEATURE_SIMPLE_PAIRING_OFF 6
-#define HCI_SIMPLE_PAIRING_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_SIMPLE_PAIRING_OFF] & HCI_FEATURE_SIMPLE_PAIRING_MASK)
-
-#define HCI_FEATURE_ENCAP_PDU_MASK 0x10
-#define HCI_FEATURE_ENCAP_PDU_OFF 6
-#define HCI_ENCAP_PDU_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ENCAP_PDU_OFF] & HCI_FEATURE_ENCAP_PDU_MASK)
-
-#define HCI_FEATURE_ERROR_DATA_MASK 0x20
-#define HCI_FEATURE_ERROR_DATA_OFF 6
-#define HCI_ERROR_DATA_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_ERROR_DATA_OFF] & HCI_FEATURE_ERROR_DATA_MASK)
-
-#define HCI_FEATURE_NON_FLUSHABLE_PB_MASK 0x40
-#define HCI_FEATURE_NON_FLUSHABLE_PB_OFF 6
-
+#define HCI_EXT_INQ_RSP_SUPPORTED(x) ((x)[6] & 0x01)
+#define HCI_SIMUL_LE_BREDR_SUPPORTED(x) ((x)[6] & 0x02)
+#define HCI_ANUM_PIN_CAP_SUPPORTED(x) ((x)[6] & 0x04)
+#define HCI_SIMPLE_PAIRING_SUPPORTED(x) ((x)[6] & 0x08)
+#define HCI_ENCAP_PDU_SUPPORTED(x) ((x)[6] & 0x10)
+#define HCI_ERROR_DATA_SUPPORTED(x) ((x)[6] & 0x20)
 /* This feature is causing frequent link drops when doing call switch with
  * certain av/hfp headsets */
-#define HCI_NON_FLUSHABLE_PB_SUPPORTED(x) \
-  (0)  //((x)[HCI_FEATURE_NON_FLUSHABLE_PB_OFF] &
-       // HCI_FEATURE_NON_FLUSHABLE_PB_MASK)
+// TODO: move the disabling somewhere else
+#define HCI_NON_FLUSHABLE_PB_SUPPORTED(x) (0)  //((x)[6] & 0x40)
+#define HCI_LINK_SUP_TO_EVT_SUPPORTED(x) ((x)[7] & 0x01)
+#define HCI_INQ_RESP_TX_SUPPORTED(x) ((x)[7] & 0x02)
+#define HCI_LMP_EXTENDED_SUPPORTED(x) ((x)[7] & 0x80)
 
-#define HCI_FEATURE_LINK_SUP_TO_EVT_MASK 0x01
-#define HCI_FEATURE_LINK_SUP_TO_EVT_OFF 7
-#define HCI_LINK_SUP_TO_EVT_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_LINK_SUP_TO_EVT_OFF] & HCI_FEATURE_LINK_SUP_TO_EVT_MASK)
+/* LMP features encoding - page 1 */
+#define HCI_SSP_HOST_SUPPORTED(x) ((x)[0] & 0x01)
+#define HCI_LE_HOST_SUPPORTED(x) ((x)[0] & 0x02)
+#define HCI_SIMUL_DUMO_HOST_SUPPORTED(x) ((x)[0] & 0x04)
+#define HCI_SC_HOST_SUPPORTED(x) ((x)[0] & 0x08)
 
-#define HCI_FEATURE_INQ_RESP_TX_MASK 0x02
-#define HCI_FEATURE_INQ_RESP_TX_OFF 7
-#define HCI_INQ_RESP_TX_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_INQ_RESP_TX_OFF] & HCI_FEATURE_INQ_RESP_TX_MASK)
+/* LMP features encoding - page 2 */
+#define HCI_CSB_MASTER_SUPPORTED(x) ((x)[0] & 0x01)
+#define HCI_CSB_SLAVE_SUPPORTED(x) ((x)[0] & 0x02)
+#define HCI_SYNC_TRAIN_MASTER_SUPPORTED(x) ((x)[0] & 0x04)
+#define HCI_SYNC_SCAN_SLAVE_SUPPORTED(x) ((x)[0] & 0x08)
+#define HCI_INQ_RESP_NOTIF_SUPPORTED(x) ((x)[0] & 0x10)
 
-#define HCI_FEATURE_EXTENDED_MASK 0x80
-#define HCI_FEATURE_EXTENDED_OFF 7
-#define HCI_LMP_EXTENDED_SUPPORTED(x) \
-  ((x)[HCI_FEATURE_EXTENDED_OFF] & HCI_FEATURE_EXTENDED_MASK)
+#define HCI_SC_CTRLR_SUPPORTED(x) ((x)[1] & 0x01)
+#define HCI_PING_SUPPORTED(x) ((x)[1] & 0x02)
 
-/*
- *   LMP features encoding - page 1
-*/
-#define HCI_EXT_FEATURE_SSP_HOST_MASK 0x01
-#define HCI_EXT_FEATURE_SSP_HOST_OFF 0
-#define HCI_SSP_HOST_SUPPORTED(x) \
-  ((x)[HCI_EXT_FEATURE_SSP_HOST_OFF] & HCI_EXT_FEATURE_SSP_HOST_MASK)
+/*  LE features encoding - page 0 (the only page for now) */
+#define HCI_LE_ENCRYPTION_SUPPORTED(x) ((x)[0] & 0x01)
+#define HCI_LE_CONN_PARAM_REQ_SUPPORTED(x) ((x)[0] & 0x02)
+#define HCI_LE_EXT_REJ_IND_SUPPORTED(x) ((x)[0] & 0x04)
+#define HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(x) ((x)[0] & 0x08)
+#define HCI_LE_DATA_LEN_EXT_SUPPORTED(x) ((x)[0] & 0x20)
+#define HCI_LE_ENHANCED_PRIVACY_SUPPORTED(x) ((x)[0] & 0x40)
+#define HCI_LE_EXT_SCAN_FILTER_POLICY_SUPPORTED(x) ((x)[0] & 0x80)
 
-#define HCI_EXT_FEATURE_LE_HOST_MASK 0x02
-#define HCI_EXT_FEATURE_LE_HOST_OFF 0
-#define HCI_LE_HOST_SUPPORTED(x) \
-  ((x)[HCI_EXT_FEATURE_LE_HOST_OFF] & HCI_EXT_FEATURE_LE_HOST_MASK)
+#define HCI_LE_2M_PHY_SUPPORTED(x) ((x)[1] & 0x01)
+#define HCI_LE_CODED_PHY_SUPPORTED(x) ((x)[1] & 0x08)
+#define HCI_LE_EXTENDED_ADVERTISING_SUPPORTED(x) ((x)[1] & 0x10)
+#define HCI_LE_PERIODIC_ADVERTISING_SUPPORTED(x) ((x)[1] & 0x20)
 
-#define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK 0x04
-#define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF 0
-#define HCI_SIMUL_DUMO_HOST_SUPPORTED(x)      \
-  ((x)[HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF] & \
-   HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK)
-
-#define HCI_EXT_FEATURE_SC_HOST_MASK 0x08
-#define HCI_EXT_FEATURE_SC_HOST_OFF 0
-#define HCI_SC_HOST_SUPPORTED(x) \
-  ((x)[HCI_EXT_FEATURE_SC_HOST_OFF] & HCI_EXT_FEATURE_SC_HOST_MASK)
-
-/*
- *   LMP features encoding - page 2
-*/
-#define HCI_EXT_FEATURE_CSB_MASTER_MASK 0x01
-#define HCI_EXT_FEATURE_CSB_MASTER_OFF 0
-#define HCI_CSB_MASTER_SUPPORTED(x) \
-  ((x)[HCI_EXT_FEATURE_CSB_MASTER_OFF] & HCI_EXT_FEATURE_CSB_MASTER_MASK)
-
-#define HCI_EXT_FEATURE_CSB_SLAVE_MASK 0x02
-#define HCI_EXT_FEATURE_CSB_SLAVE_OFF 0
-#define HCI_CSB_SLAVE_SUPPORTED(x) \
-  ((x)[HCI_EXT_FEATURE_CSB_SLAVE_OFF] & HCI_EXT_FEATURE_CSB_SLAVE_MASK)
-
-#define HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_MASK 0x04
-#define HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_OFF 0
-#define HCI_SYNC_TRAIN_MASTER_SUPPORTED(x)      \
-  ((x)[HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_OFF] & \
-   HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_MASK)
-
-#define HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_MASK 0x08
-#define HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_OFF 0
-#define HCI_SYNC_SCAN_SLAVE_SUPPORTED(x)      \
-  ((x)[HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_OFF] & \
-   HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_MASK)
-
-#define HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK 0x10
-#define HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF 0
-#define HCI_INQ_RESP_NOTIF_SUPPORTED(x)      \
-  ((x)[HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF] & \
-   HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK)
-
-#define HCI_EXT_FEATURE_SC_CTRLR_MASK 0x01
-#define HCI_EXT_FEATURE_SC_CTRLR_OFF 1
-#define HCI_SC_CTRLR_SUPPORTED(x) \
-  ((x)[HCI_EXT_FEATURE_SC_CTRLR_OFF] & HCI_EXT_FEATURE_SC_CTRLR_MASK)
-
-#define HCI_EXT_FEATURE_PING_MASK 0x02
-#define HCI_EXT_FEATURE_PING_OFF 1
-#define HCI_PING_SUPPORTED(x) \
-  ((x)[HCI_EXT_FEATURE_PING_OFF] & HCI_EXT_FEATURE_PING_MASK)
-
-/*
- *   LE features encoding - page 0 (the only page for now)
-*/
-/* LE Encryption */
-#define HCI_LE_FEATURE_LE_ENCRYPTION_MASK 0x01
-#define HCI_LE_FEATURE_LE_ENCRYPTION_OFF 0
-#define HCI_LE_ENCRYPTION_SUPPORTED(x) \
-  ((x)[HCI_LE_FEATURE_LE_ENCRYPTION_OFF] & HCI_LE_FEATURE_LE_ENCRYPTION_MASK)
-
-/* Connection Parameters Request Procedure */
-#define HCI_LE_FEATURE_CONN_PARAM_REQ_MASK 0x02
-#define HCI_LE_FEATURE_CONN_PARAM_REQ_OFF 0
-#define HCI_LE_CONN_PARAM_REQ_SUPPORTED(x) \
-  ((x)[HCI_LE_FEATURE_CONN_PARAM_REQ_OFF] & HCI_LE_FEATURE_CONN_PARAM_REQ_MASK)
-
-/* Extended Reject Indication */
-#define HCI_LE_FEATURE_EXT_REJ_IND_MASK 0x04
-#define HCI_LE_FEATURE_EXT_REJ_IND_OFF 0
-#define HCI_LE_EXT_REJ_IND_SUPPORTED(x) \
-  ((x)[HCI_LE_FEATURE_EXT_REJ_IND_OFF] & HCI_LE_FEATURE_EXT_REJ_IND_MASK)
-
-/* Slave-initiated Features Exchange */
-#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK 0x08
-#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF 0
-#define HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(x)  \
-  ((x)[HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF] & \
-   HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK)
-
-/* Enhanced privacy Feature: bit 6 */
-#define HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK 0x40
-#define HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF 0
-#define HCI_LE_ENHANCED_PRIVACY_SUPPORTED(x)  \
-  ((x)[HCI_LE_FEATURE_ENHANCED_PRIVACY_OFF] & \
-   HCI_LE_FEATURE_ENHANCED_PRIVACY_MASK)
-
-/* Extended scanner filter policy : 7 */
-#define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK 0x80
-#define HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF 0
-#define HCI_LE_EXT_SCAN_FILTER_POLICY_SUPPORTED(x)  \
-  ((x)[HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_OFF] & \
-   HCI_LE_FEATURE_EXT_SCAN_FILTER_POLICY_MASK)
-
-/* Slave-initiated Features Exchange */
-#define HCI_LE_FEATURE_DATA_LEN_EXT_MASK 0x20
-#define HCI_LE_FEATURE_DATA_LEN_EXT_OFF 0
-#define HCI_LE_DATA_LEN_EXT_SUPPORTED(x) \
-  ((x)[HCI_LE_FEATURE_DATA_LEN_EXT_OFF] & HCI_LE_FEATURE_DATA_LEN_EXT_MASK)
-
-/*
- *   Local Supported Commands encoding
-*/
+/* Supported Commands*/
 #define HCI_NUM_SUPP_COMMANDS_BYTES 64
 
-/* Supported Commands Byte 0 */
-#define HCI_SUPP_COMMANDS_INQUIRY_MASK 0x01
-#define HCI_SUPP_COMMANDS_INQUIRY_OFF 0
-#define HCI_INQUIRY_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_INQUIRY_OFF] & HCI_SUPP_COMMANDS_INQUIRY_MASK)
+#define HCI_INQUIRY_SUPPORTED(x) ((x)[0] & 0x01)
+#define HCI_INQUIRY_CANCEL_SUPPORTED(x) ((x)[0] & 0x02)
+#define HCI_PERIODIC_INQUIRY_SUPPORTED(x) ((x)[0] & 0x04)
+#define HCI_EXIT_PERIODIC_INQUIRY_SUPPORTED(x) ((x)[0] & 0x08)
+#define HCI_CREATE_CONN_SUPPORTED(x) ((x)[0] & 0x10)
+#define HCI_DISCONNECT_SUPPORTED(x) ((x)[0] & 0x20)
+#define HCI_ADD_SCO_CONN_SUPPORTED(x) ((x)[0] & 0x40)
+#define HCI_CANCEL_CREATE_CONN_SUPPORTED(x) ((x)[0] & 0x80)
 
-#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK 0x02
-#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF 0
-#define HCI_INQUIRY_CANCEL_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF] & \
-   HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK)
+#define HCI_ACCEPT_CONN_REQUEST_SUPPORTED(x) ((x)[1] & 0x01)
+#define HCI_REJECT_CONN_REQUEST_SUPPORTED(x) ((x)[1] & 0x02)
+#define HCI_LINK_KEY_REQUEST_REPLY_SUPPORTED(x) ((x)[1] & 0x04)
+#define HCI_LINK_KEY_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[1] & 0x08)
+#define HCI_PIN_CODE_REQUEST_REPLY_SUPPORTED(x) ((x)[1] & 0x10)
+#define HCI_PIN_CODE_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[1] & 0x20)
+#define HCI_CHANGE_CONN_PKT_TYPE_SUPPORTED(x) ((x)[1] & 0x40)
+#define HCI_AUTH_REQUEST_SUPPORTED(x) ((x)[1] & 0x80)
 
-#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK 0x04
-#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF 0
-#define HCI_PERIODIC_INQUIRY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF] & \
-   HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK)
+#define HCI_SET_CONN_ENCRYPTION_SUPPORTED(x) ((x)[2] & 0x01)
+#define HCI_CHANGE_CONN_LINK_KEY_SUPPORTED(x) ((x)[2] & 0x02)
+#define HCI_MASTER_LINK_KEY_SUPPORTED(x) ((x)[2] & 0x04)
+#define HCI_REMOTE_NAME_REQUEST_SUPPORTED(x) ((x)[2] & 0x08)
+#define HCI_CANCEL_REMOTE_NAME_REQUEST_SUPPORTED(x) ((x)[2] & 0x10)
+#define HCI_READ_REMOTE_SUPP_FEATURES_SUPPORTED(x) ((x)[2] & 0x20)
+#define HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(x) ((x)[2] & 0x40)
+#define HCI_READ_REMOTE_VER_INFO_SUPPORTED(x) ((x)[2] & 0x80)
 
-#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK 0x08
-#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF 0
-#define HCI_EXIT_PERIODIC_INQUIRY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF] & \
-   HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK)
+#define HCI_READ_CLOCK_OFFSET_SUPPORTED(x) ((x)[3] & 0x01)
+#define HCI_READ_LMP_HANDLE_SUPPORTED(x) ((x)[3] & 0x02)
+/* rest of bits in 3-rd byte are reserved */
 
-#define HCI_SUPP_COMMANDS_CREATE_CONN_MASK 0x10
-#define HCI_SUPP_COMMANDS_CREATE_CONN_OFF 0
-#define HCI_CREATE_CONN_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CREATE_CONN_MASK)
+#define HCI_HOLD_MODE_CMD_SUPPORTED(x) ((x)[4] & 0x02)
+#define HCI_SNIFF_MODE_CMD_SUPPORTED(x) ((x)[4] & 0x04)
+#define HCI_EXIT_SNIFF_MODE_SUPPORTED(x) ((x)[4] & 0x08)
+#define HCI_PARK_STATE_SUPPORTED(x) ((x)[4] & 0x10)
+#define HCI_EXIT_PARK_STATE_SUPPORTED(x) ((x)[4] & 0x20)
+#define HCI_QOS_SETUP_SUPPORTED(x) ((x)[4] & 0x40)
+#define HCI_ROLE_DISCOVERY_SUPPORTED(x) ((x)[4] & 0x80)
 
-#define HCI_SUPP_COMMANDS_DISCONNECT_MASK 0x20
-#define HCI_SUPP_COMMANDS_DISCONNECT_OFF 0
-#define HCI_DISCONNECT_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_DISCONNECT_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_MASK)
+#define HCI_SWITCH_ROLE_SUPPORTED(x) ((x)[5] & 0x01)
+#define HCI_READ_LINK_POLICY_SET_SUPPORTED(x) ((x)[5] & 0x02)
+#define HCI_WRITE_LINK_POLICY_SET_SUPPORTED(x) ((x)[5] & 0x04)
+#define HCI_READ_DEF_LINK_POLICY_SET_SUPPORTED(x) ((x)[5] & 0x08)
+#define HCI_WRITE_DEF_LINK_POLICY_SET_SUPPORTED(x) ((x)[5] & 0x10)
+#define HCI_FLOW_SPECIFICATION_SUPPORTED(x) ((x)[5] & 0x20)
+#define HCI_SET_EVENT_MASK_SUPPORTED(x) ((x)[5] & 0x40)
+#define HCI_RESET_SUPPORTED(x) ((x)[5] & 0x80)
 
-#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK 0x40
-#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF 0
-#define HCI_ADD_SCO_CONN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF] & \
-   HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK)
+#define HCI_SET_EVENT_FILTER_SUPPORTED(x) ((x)[6] & 0x01)
+#define HCI_FLUSH_SUPPORTED(x) ((x)[6] & 0x02)
+#define HCI_READ_PIN_TYPE_SUPPORTED(x) ((x)[6] & 0x04)
+#define HCI_WRITE_PIN_TYPE_SUPPORTED(x) ((x)[6] & 0x08)
+#define HCI_CREATE_NEW_UNIT_KEY_SUPPORTED(x) ((x)[6] & 0x10)
+#define HCI_READ_STORED_LINK_KEY_SUPPORTED(x) ((x)[6] & 0x20)
+#define HCI_WRITE_STORED_LINK_KEY_SUPPORTED(x) ((x)[6] & 0x40)
+#define HCI_DELETE_STORED_LINK_KEY_SUPPORTED(x) ((x)[6] & 0x80)
 
-#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK 0x80
-#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF 0
-#define HCI_CANCEL_CREATE_CONN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF] & \
-   HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK)
+#define HCI_WRITE_LOCAL_NAME_SUPPORTED(x) ((x)[7] & 0x01)
+#define HCI_READ_LOCAL_NAME_SUPPORTED(x) ((x)[7] & 0x02)
+#define HCI_READ_CONN_ACCEPT_TOUT_SUPPORTED(x) ((x)[7] & 0x04)
+#define HCI_WRITE_CONN_ACCEPT_TOUT_SUPPORTED(x) ((x)[7] & 0x08)
+#define HCI_READ_PAGE_TOUT_SUPPORTED(x) ((x)[7] & 0x10)
+#define HCI_WRITE_PAGE_TOUT_SUPPORTED(x) ((x)[7] & 0x20)
+#define HCI_READ_SCAN_ENABLE_SUPPORTED(x) ((x)[7] & 0x40)
+#define HCI_WRITE_SCAN_ENABLE_SUPPORTED(x) ((x)[7] & 0x80)
 
-#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK 0x01
-#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF 1
-#define HCI_ACCEPT_CONN_REQUEST_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF] & \
-   HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK)
+#define HCI_READ_PAGE_SCAN_ACTIVITY_SUPPORTED(x) ((x)[8] & 0x01)
+#define HCI_WRITE_PAGE_SCAN_ACTIVITY_SUPPORTED(x) ((x)[8] & 0x02)
+#define HCI_READ_INQURIY_SCAN_ACTIVITY_SUPPORTED(x) ((x)[8] & 0x04)
+#define HCI_WRITE_INQURIY_SCAN_ACTIVITY_SUPPORTED(x) ((x)[8] & 0x08)
+#define HCI_READ_AUTH_ENABLE_SUPPORTED(x) ((x)[8] & 0x10)
+#define HCI_WRITE_AUTH_ENABLE_SUPPORTED(x) ((x)[8] & 0x20)
+#define HCI_READ_ENCRYPT_ENABLE_SUPPORTED(x) ((x)[8] & 0x40)
+#define HCI_WRITE_ENCRYPT_ENABLE_SUPPORTED(x) ((x)[8] & 0x80)
 
-#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK 0x02
-#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF 1
-#define HCI_REJECT_CONN_REQUEST_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF] & \
-   HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK)
+#define HCI_READ_CLASS_DEVICE_SUPPORTED(x) ((x)[9] & 0x01)
+#define HCI_WRITE_CLASS_DEVICE_SUPPORTED(x) ((x)[9] & 0x02)
+#define HCI_READ_VOICE_SETTING_SUPPORTED(x) ((x)[9] & 0x04)
+#define HCI_WRITE_VOICE_SETTING_SUPPORTED(x) ((x)[9] & 0x08)
+#define HCI_READ_AUTOMATIC_FLUSH_TIMEOUT_SUPPORTED(x) ((x)[9] & 0x10)
+#define HCI_WRITE_AUTOMATIC_FLUSH_TIMEOUT_SUPPORTED(x) ((x)[9] & 0x20)
+#define HCI_READ_NUM_BROAD_RETRANS_SUPPORTED(x) ((x)[9] & 0x40)
+#define HCI_WRITE_NUM_BROAD_RETRANS_SUPPORTED(x) ((x)[9] & 0x80)
 
-#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK 0x04
-#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF 1
-#define HCI_LINK_KEY_REQUEST_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK)
+#define HCI_READ_HOLD_MODE_ACTIVITY_SUPPORTED(x) ((x)[10] & 0x01)
+#define HCI_WRITE_HOLD_MODE_ACTIVITY_SUPPORTED(x) ((x)[10] & 0x02)
+#define HCI_READ_TRANS_PWR_LEVEL_SUPPORTED(x) ((x)[10] & 0x04)
+#define HCI_READ_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x) ((x)[10] & 0x08)
+#define HCI_WRITE_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x) ((x)[10] & 0x10)
+#define HCI_SET_HOST_CTRLR_TO_HOST_FC_SUPPORTED(x) ((x)[10] & 0x20)
+#define HCI_HOST_BUFFER_SIZE_SUPPORTED(x) ((x)[10] & 0x40)
+#define HCI_HOST_NUM_COMPLETED_PKTS_SUPPORTED(x) ((x)[10] & 0x80)
 
-#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK 0x08
-#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF 1
-#define HCI_LINK_KEY_REQUEST_NEG_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK)
+#define HCI_READ_LINK_SUP_TOUT_SUPPORTED(x) ((x)[11] & 0x01)
+#define HCI_WRITE_LINK_SUP_TOUT_SUPPORTED(x) ((x)[11] & 0x02)
+#define HCI_READ_NUM_SUPP_IAC_SUPPORTED(x) ((x)[11] & 0x04)
+#define HCI_READ_CURRENT_IAC_LAP_SUPPORTED(x) ((x)[11] & 0x08)
+#define HCI_WRITE_CURRENT_IAC_LAP_SUPPORTED(x) ((x)[11] & 0x10)
+#define HCI_READ_PAGE_SCAN_PER_MODE_SUPPORTED(x) ((x)[11] & 0x20)
+#define HCI_WRITE_PAGE_SCAN_PER_MODE_SUPPORTED(x) ((x)[11] & 0x40)
+#define HCI_READ_PAGE_SCAN_MODE_SUPPORTED(x) ((x)[11] & 0x80)
 
-#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK 0x10
-#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF 1
-#define HCI_PIN_CODE_REQUEST_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK)
+#define HCI_WRITE_PAGE_SCAN_MODE_SUPPORTED(x) ((x)[12] & 0x01)
+#define HCI_SET_AFH_CHNL_CLASS_SUPPORTED(x) ((x)[12] & 0x02)
+#define HCI_READ_INQUIRY_SCAN_TYPE_SUPPORTED(x) ((x)[12] & 0x10)
+#define HCI_WRITE_INQUIRY_SCAN_TYPE_SUPPORTED(x) ((x)[12] & 0x20)
+#define HCI_READ_INQUIRY_MODE_SUPPORTED(x) ((x)[12] & 0x40)
+#define HCI_WRITE_INQUIRY_MODE_SUPPORTED(x) ((x)[12] & 0x80)
 
-#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK 0x20
-#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF 1
-#define HCI_PIN_CODE_REQUEST_NEG_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK)
+#define HCI_READ_PAGE_SCAN_TYPE_SUPPORTED(x) ((x)[13] & 0x01)
+#define HCI_WRITE_PAGE_SCAN_TYPE_SUPPORTED(x) ((x)[13] & 0x02)
+#define HCI_READ_AFH_CHNL_ASSESS_MODE_SUPPORTED(x) ((x)[13] & 0x04)
+#define HCI_WRITE_AFH_CHNL_ASSESS_MODE_SUPPORTED(x) ((x)[13] & 0x08)
 
-#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK 0x40
-#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF 1
-#define HCI_CHANGE_CONN_PKT_TYPE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF] & \
-   HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK)
+#define HCI_READ_LOCAL_VER_INFO_SUPPORTED(x) ((x)[14] & 0x08)
+#define HCI_READ_LOCAL_SUP_CMDS_SUPPORTED(x) ((x)[14] & 0x10)
+#define HCI_READ_LOCAL_SUPP_FEATURES_SUPPORTED(x) ((x)[14] & 0x20)
+#define HCI_READ_LOCAL_EXT_FEATURES_SUPPORTED(x) ((x)[14] & 0x40)
+#define HCI_READ_BUFFER_SIZE_SUPPORTED(x) ((x)[14] & 0x80)
 
-#define HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK 0x80
-#define HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF 1
-#define HCI_AUTH_REQUEST_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF] & \
-   HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK)
+#define HCI_READ_COUNTRY_CODE_SUPPORTED(x) ((x)[15] & 0x01)
+#define HCI_READ_BD_ADDR_SUPPORTED(x) ((x)[15] & 0x02)
+#define HCI_READ_FAIL_CONTACT_CNTR_SUPPORTED(x) ((x)[15] & 0x04)
+#define HCI_RESET_FAIL_CONTACT_CNTR_SUPPORTED(x) ((x)[15] & 0x08)
+#define HCI_GET_LINK_QUALITY_SUPPORTED(x) ((x)[15] & 0x10)
+#define HCI_READ_RSSI_SUPPORTED(x) ((x)[15] & 0x20)
+#define HCI_READ_AFH_CH_MAP_SUPPORTED(x) ((x)[15] & 0x40)
+#define HCI_READ_BD_CLOCK_SUPPORTED(x) ((x)[15] & 0x80)
 
-#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK 0x01
-#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF 2
-#define HCI_SET_CONN_ENCRYPTION_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF] & \
-   HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK)
+#define HCI_READ_LOOPBACK_MODE_SUPPORTED(x) ((x)[16] & 0x01)
+#define HCI_WRITE_LOOPBACK_MODE_SUPPORTED(x) ((x)[16] & 0x02)
+#define HCI_ENABLE_DEV_UNDER_TEST_SUPPORTED(x) ((x)[16] & 0x04)
+#define HCI_SETUP_SYNCH_CONN_SUPPORTED(x) ((x)[16] & 0x08)
+#define HCI_ACCEPT_SYNCH_CONN_SUPPORTED(x) ((x)[16] & 0x10)
+#define HCI_REJECT_SYNCH_CONN_SUPPORTED(x) ((x)[16] & 0x20)
 
-#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK 0x02
-#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF 2
-#define HCI_CHANGE_CONN_LINK_KEY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF] & \
-   HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK)
+#define HCI_READ_EXT_INQUIRY_RESP_SUPPORTED(x) ((x)[17] & 0x01)
+#define HCI_WRITE_EXT_INQUIRY_RESP_SUPPORTED(x) ((x)[17] & 0x02)
+#define HCI_REFRESH_ENCRYPTION_KEY_SUPPORTED(x) ((x)[17] & 0x04)
+#define HCI_SNIFF_SUB_RATE_CMD_SUPPORTED(x) ((x)[17] & 0x10)
+#define HCI_READ_SIMPLE_PAIRING_MODE_SUPPORTED(x) ((x)[17] & 0x20)
+#define HCI_WRITE_SIMPLE_PAIRING_MODE_SUPPORTED(x) ((x)[17] & 0x40)
+#define HCI_READ_LOCAL_OOB_DATA_SUPPORTED(x) ((x)[17] & 0x80)
 
-#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK 0x04
-#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF 2
-#define HCI_MASTER_LINK_KEY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF] & \
-   HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK)
+#define HCI_READ_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x) ((x)[18] & 0x01)
+#define HCI_WRITE_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x) ((x)[18] & 0x02)
+#define HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x) ((x)[18] & 0x04)
+#define HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x) ((x)[18] & 0x08)
+#define HCI_IO_CAPABILITY_REQUEST_REPLY_SUPPORTED(x) ((x)[18] & 0x80)
 
-#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK 0x08
-#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF 2
-#define HCI_REMOTE_NAME_REQUEST_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF] & \
-   HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK)
+#define HCI_USER_CONFIRMATION_REQUEST_REPLY_SUPPORTED(x) ((x)[19] & 0x01)
+#define HCI_USER_CONFIRMATION_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[19] & 0x02)
+#define HCI_USER_PASSKEY_REQUEST_REPLY_SUPPORTED(x) ((x)[19] & 0x04)
+#define HCI_USER_PASSKEY_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[19] & 0x08)
+#define HCI_REMOTE_OOB_DATA_REQUEST_REPLY_SUPPORTED(x) ((x)[19] & 0x10)
+#define HCI_WRITE_SIMPLE_PAIRING_DBG_MODE_SUPPORTED(x) ((x)[19] & 0x20)
+#define HCI_ENHANCED_FLUSH_SUPPORTED(x) ((x)[19] & 0x40)
+#define HCI_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[19] & 0x80)
 
-#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK 0x10
-#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF 2
-#define HCI_CANCEL_REMOTE_NAME_REQUEST_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF] & \
-   HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK)
+#define HCI_SEND_NOTIF_SUPPORTED(x) ((x)[20] & 0x04)
+#define HCI_IO_CAP_REQ_NEG_REPLY_SUPPORTED(x) ((x)[20] & 0x08)
+#define HCI_READ_ENCR_KEY_SIZE_SUPPORTED(x) ((x)[20] & 0x10)
 
-#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK 0x20
-#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF 2
-#define HCI_READ_REMOTE_SUPP_FEATURES_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF] & \
-   HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK)
+#define HCI_CREATE_PHYSICAL_LINK_SUPPORTED(x) ((x)[21] & 0x01)
+#define HCI_ACCEPT_PHYSICAL_LINK_SUPPORTED(x) ((x)[21] & 0x02)
+#define HCI_DISCONNECT_PHYSICAL_LINK_SUPPORTED(x) ((x)[21] & 0x04)
+#define HCI_CREATE_LOGICAL_LINK_SUPPORTED(x) ((x)[21] & 0x08)
+#define HCI_ACCEPT_LOGICAL_LINK_SUPPORTED(x) ((x)[21] & 0x10)
+#define HCI_DISCONNECT_LOGICAL_LINK_SUPPORTED(x) ((x)[21] & 0x20)
+#define HCI_LOGICAL_LINK_CANCEL_SUPPORTED(x) ((x)[21] & 0x40)
+#define HCI_FLOW_SPEC_MODIFY_SUPPORTED(x) ((x)[21] & 0x80)
 
-#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF 2
-#define HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF] & \
-   HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK)
+#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x) ((x)[22] & 0x01)
+#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x) ((x)[22] & 0x02)
+#define HCI_SET_EVENT_MASK_PAGE_2_SUPPORTED(x) ((x)[22] & 0x04)
+#define HCI_READ_LOCATION_DATA_SUPPORTED(x) ((x)[22] & 0x08)
+#define HCI_WRITE_LOCATION_DATA_SUPPORTED(x) ((x)[22] & 0x10)
+#define HCI_READ_LOCAL_AMP_INFO_SUPPORTED(x) ((x)[22] & 0x20)
+#define HCI_READ_LOCAL_AMP_ASSOC_SUPPORTED(x) ((x)[22] & 0x40)
+#define HCI_WRITE_REMOTE_AMP_ASSOC_SUPPORTED(x) ((x)[22] & 0x80)
 
-#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK 0x80
-#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF 2
-#define HCI_READ_REMOTE_VER_INFO_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF] & \
-   HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK)
+#define HCI_READ_FLOW_CONTROL_MODE_SUPPORTED(x) ((x)[23] & 0x01)
+#define HCI_WRITE_FLOW_CONTROL_MODE_SUPPORTED(x) ((x)[23] & 0x02)
+#define HCI_READ_DATA_BLOCK_SIZE_SUPPORTED(x) ((x)[23] & 0x04)
+#define HCI_ENABLE_AMP_RCVR_REPORTS_SUPPORTED(x) ((x)[23] & 0x20)
+#define HCI_AMP_TEST_END_SUPPORTED(x) ((x)[23] & 0x40)
+#define HCI_AMP_TEST_SUPPORTED(x) ((x)[23] & 0x80)
 
-#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF 3
-#define HCI_READ_CLOCK_OFFSET_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF] & \
-   HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK)
+#define HCI_READ_TRANSMIT_POWER_LEVEL_SUPPORTED(x) ((x)[24] & 0x01)
+#define HCI_READ_BE_FLUSH_TOUT_SUPPORTED(x) ((x)[24] & 0x04)
+#define HCI_WRITE_BE_FLUSH_TOUT_SUPPORTED(x) ((x)[24] & 0x08)
+#define HCI_SHORT_RANGE_MODE_SUPPORTED(x) ((x)[24] & 0x10)
 
-#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK 0x02
-#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF 3
-#define HCI_READ_LMP_HANDLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK)
+#define HCI_ENH_SETUP_SYNCH_CONN_SUPPORTED(x) ((x)[29] & 0x08)
+#define HCI_ENH_ACCEPT_SYNCH_CONN_SUPPORTED(x) ((x)[29] & 0x10)
+#define HCI_READ_LOCAL_CODECS_SUPPORTED(x) ((x)[29] & 0x20)
+#define HCI_SET_MWS_CHANNEL_PARAMETERS_SUPPORTED(x) ((x)[29] & 0x40)
+#define HCI_SET_EXTERNAL_FRAME_CONFIGURATION_SUPPORTED(x) ((x)[29] & 0x80)
 
-#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK 0x02
-#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF 4
-#define HCI_HOLD_MODE_CMD_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF] & \
-   HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK)
+#define HCI_SET_MWS_SIGNALING_SUPPORTED(x) ((x)[30] & 0x01)
+#define HCI_SET_MWS_TRANSPORT_LAYER_SUPPORTED(x) ((x)[30] & 0x02)
+#define HCI_SET_MWS_SCAN_FREQUENCY_TABLE_SUPPORTED(x) ((x)[30] & 0x04)
+#define HCI_GET_MWS_TRANS_LAYER_CFG_SUPPORTED(x) ((x)[30] & 0x08)
+#define HCI_SET_MWS_PATTERN_CONFIGURATION_SUPPORTED(x) ((x)[30] & 0x10)
+#define HCI_SET_TRIG_CLK_CAP_SUPPORTED(x) ((x)[30] & 0x20)
+#define HCI_TRUNCATED_PAGE_SUPPORTED(x) ((x)[30] & 0x40)
+#define HCI_TRUNCATED_PAGE_CANCEL_SUPPORTED(x) ((x)[30] & 0x80)
 
-#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK 0x04
-#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF 4
-#define HCI_SNIFF_MODE_CMD_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF] & \
-   HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK)
+#define HCI_SET_CONLESS_SLAVE_BRCST_SUPPORTED(x) ((x)[31] & 0x01)
+#define HCI_SET_CONLESS_SLAVE_BRCST_RECEIVE_SUPPORTED(x) ((x)[31] & 0x02)
+#define HCI_START_SYNC_TRAIN_SUPPORTED(x) ((x)[31] & 0x04)
+#define HCI_RECEIVE_SYNC_TRAIN_SUPPORTED(x) ((x)[31] & 0x08)
+#define HCI_SET_RESERVED_LT_ADDR_SUPPORTED(x) ((x)[31] & 0x10)
+#define HCI_DELETE_RESERVED_LT_ADDR_SUPPORTED(x) ((x)[31] & 0x20)
+#define HCI_SET_CONLESS_SLAVE_BRCST_DATA_SUPPORTED(x) ((x)[31] & 0x40)
+#define HCI_READ_SYNC_TRAIN_PARAM_SUPPORTED(x) ((x)[31] & 0x80)
 
-#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK 0x08
-#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF 4
-#define HCI_EXIT_SNIFF_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK)
+#define HCI_WRITE_SYNC_TRAIN_PARAM_SUPPORTED(x) ((x)[32] & 0x01)
+#define HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_SUPPORTED(x) ((x)[32] & 0x02)
+#define HCI_READ_SECURE_CONNS_SUPPORT_SUPPORTED(x) ((x)[32] & 0x04)
+#define HCI_WRITE_SECURE_CONNS_SUPPORT_SUPPORTED(x) ((x)[32] & 0x08)
+#define HCI_READ_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x) ((x)[32] & 0x10)
+#define HCI_WRITE_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x) ((x)[32] & 0x20)
+#define HCI_READ_LOCAL_OOB_EXTENDED_DATA_SUPPORTED(x) ((x)[32] & 0x40)
+#define HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_SUPPORTED(x) ((x)[32] & 0x80)
 
-#define HCI_SUPP_COMMANDS_PARK_STATE_MASK 0x10
-#define HCI_SUPP_COMMANDS_PARK_STATE_OFF 4
-#define HCI_PARK_STATE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_PARK_STATE_MASK)
+#define HCI_LE_RC_CONN_PARAM_UPD_RPY_SUPPORTED(x) ((x)[33] & 0x10)
+#define HCI_LE_RC_CONN_PARAM_UPD_NEG_RPY_SUPPORTED(x) ((x)[33] & 0x20)
 
-#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK 0x20
-#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF 4
-#define HCI_EXIT_PARK_STATE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF] & \
-   HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK)
+#define HCI_LE_READ_PHY_SUPPORTED(x) ((x)[35] & 0x10)
+#define HCI_LE_SET_DEFAULT_PHY_SUPPORTED(x) ((x)[35] & 0x20)
+#define HCI_LE_SET_PHY_SUPPORTED(x) ((x)[35] & 0x40)
+#define HCI_LE_ENH_RX_TEST_SUPPORTED(x) ((x)[35] & 0x80)
 
-#define HCI_SUPP_COMMANDS_QOS_SETUP_MASK 0x40
-#define HCI_SUPP_COMMANDS_QOS_SETUP_OFF 4
-#define HCI_QOS_SETUP_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_QOS_SETUP_OFF] & HCI_SUPP_COMMANDS_QOS_SETUP_MASK)
+#define HCI_LE_ENH_TX_TEST_SUPPORTED(x) ((x)[36] & 0x01)
 
-#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK 0x80
-#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF 4
-#define HCI_ROLE_DISCOVERY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF] & \
-   HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK)
-
-#define HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK 0x01
-#define HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF 5
-#define HCI_SWITCH_ROLE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF] & HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK 0x02
-#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF 5
-#define HCI_READ_LINK_POLICY_SET_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK 0x04
-#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF 5
-#define HCI_WRITE_LINK_POLICY_SET_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK 0x08
-#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF 5
-#define HCI_READ_DEF_LINK_POLICY_SET_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF] & \
-   HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK 0x10
-#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF 5
-#define HCI_WRITE_DEF_LINK_POLICY_SET_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK)
-
-#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK 0x20
-#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF 5
-#define HCI_FLOW_SPECIFICATION_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF] & \
-   HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK 0x40
-#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF 5
-#define HCI_SET_EVENT_MASK_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF] & \
-   HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK)
-
-#define HCI_SUPP_COMMANDS_RESET_MASK 0x80
-#define HCI_SUPP_COMMANDS_RESET_OFF 5
-#define HCI_RESET_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_RESET_OFF] & HCI_SUPP_COMMANDS_RESET_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK 0x01
-#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF 6
-#define HCI_SET_EVENT_FILTER_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF] & \
-   HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK)
-
-#define HCI_SUPP_COMMANDS_FLUSH_MASK 0x02
-#define HCI_SUPP_COMMANDS_FLUSH_OFF 6
-#define HCI_FLUSH_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_FLUSH_OFF] & HCI_SUPP_COMMANDS_FLUSH_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF 6
-#define HCI_READ_PIN_TYPE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK 0x08
-#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF 6
-#define HCI_WRITE_PIN_TYPE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK)
-
-#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK 0x10
-#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF 6
-#define HCI_CREATE_NEW_UNIT_KEY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF] & \
-   HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK 0x20
-#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF 6
-#define HCI_READ_STORED_LINK_KEY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF] & \
-   HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK 0x40
-#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF 6
-#define HCI_WRITE_STORED_LINK_KEY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK)
-
-#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK 0x80
-#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF 6
-#define HCI_DELETE_STORED_LINK_KEY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF] & \
-   HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK 0x01
-#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF 7
-#define HCI_WRITE_LOCAL_NAME_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK 0x02
-#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF 7
-#define HCI_READ_LOCAL_NAME_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF 7
-#define HCI_READ_CONN_ACCEPT_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK 0x08
-#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF 7
-#define HCI_WRITE_CONN_ACCEPT_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK 0x10
-#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF 7
-#define HCI_READ_PAGE_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK 0x20
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF 7
-#define HCI_WRITE_PAGE_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF 7
-#define HCI_READ_SCAN_ENABLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK 0x80
-#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF 7
-#define HCI_WRITE_SCAN_ENABLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF 8
-#define HCI_READ_PAGE_SCAN_ACTIVITY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF] & \
-   HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF 8
-#define HCI_WRITE_PAGE_SCAN_ACTIVITY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF 8
-#define HCI_READ_INQURIY_SCAN_ACTIVITY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF] & \
-   HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK 0x08
-#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF 8
-#define HCI_WRITE_INQURIY_SCAN_ACTIVITY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK 0x10
-#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF 8
-#define HCI_READ_AUTH_ENABLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK 0x20
-#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF 8
-#define HCI_WRITE_AUTH_ENABLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF 8
-#define HCI_READ_ENCRYPT_ENABLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK 0x80
-#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF 8
-#define HCI_WRITE_ENCRYPT_ENABLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF 9
-#define HCI_READ_CLASS_DEVICE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF 9
-#define HCI_WRITE_CLASS_DEVICE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF 9
-#define HCI_READ_VOICE_SETTING_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF] & \
-   HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK 0x08
-#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF 9
-#define HCI_WRITE_VOICE_SETTING_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK 0x10
-#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF 9
-#define HCI_READ_AUTO_FLUSH_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK 0x20
-#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF 9
-#define HCI_WRITE_AUTO_FLUSH_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF 9
-#define HCI_READ_NUM_BROAD_RETRANS_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF] & \
-   HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK 0x80
-#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF 9
-#define HCI_WRITE_NUM_BROAD_RETRANS_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF 10
-#define HCI_READ_HOLD_MODE_ACTIVITY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF] & \
-   HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF 10
-#define HCI_WRITE_HOLD_MODE_ACTIVITY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF 10
-#define HCI_READ_TRANS_PWR_LEVEL_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF] & \
-   HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK 0x08
-#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF 10
-#define HCI_READ_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK 0x10
-#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF 10
-#define HCI_WRITE_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK 0x20
-#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF 10
-#define HCI_SET_HOST_CTRLR_TO_HOST_FC_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF] & \
-   HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK)
-
-#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK 0x40
-#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF 10
-#define HCI_HOST_BUFFER_SIZE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF] & \
-   HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK)
-
-#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK 0x80
-#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF 10
-#define HCI_HOST_NUM_COMPLETED_PKTS_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF] & \
-   HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF 11
-#define HCI_READ_LINK_SUP_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF 11
-#define HCI_WRITE_LINK_SUP_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF 11
-#define HCI_READ_NUM_SUPP_IAC_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF] & \
-   HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK 0x08
-#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF 11
-#define HCI_READ_CURRENT_IAC_LAP_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF] & \
-   HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK 0x10
-#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF 11
-#define HCI_WRITE_CURRENT_IAC_LAP_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK 0x20
-#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF 11
-#define HCI_READ_PAGE_SCAN_PER_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK 0x40
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF 11
-#define HCI_WRITE_PAGE_SCAN_PER_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK 0x80
-#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF 11
-#define HCI_READ_PAGE_SCAN_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK 0x01
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF 12
-#define HCI_WRITE_PAGE_SCAN_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK 0x02
-#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF 12
-#define HCI_SET_AFH_CHNL_CLASS_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF] & \
-   HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK 0x10
-#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF 12
-#define HCI_READ_INQUIRY_SCAN_TYPE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK 0x20
-#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF 12
-#define HCI_WRITE_INQUIRY_SCAN_TYPE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF 12
-#define HCI_READ_INQUIRY_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK 0x80
-#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF 12
-#define HCI_WRITE_INQUIRY_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF 13
-#define HCI_READ_PAGE_SCAN_TYPE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF 13
-#define HCI_WRITE_PAGE_SCAN_TYPE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF 13
-#define HCI_READ_AFH_CHNL_ASSESS_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK 0x08
-#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF 13
-#define HCI_WRITE_AFH_CHNL_ASSESS_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK 0x08
-#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF 14
-#define HCI_READ_LOCAL_VER_INFO_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK 0x10
-#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF 14
-#define HCI_READ_LOCAL_SUP_CMDS_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK 0x20
-#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF 14
-#define HCI_READ_LOCAL_SUPP_FEATURES_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF 14
-#define HCI_READ_LOCAL_EXT_FEATURES_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK 0x80
-#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF 14
-#define HCI_READ_BUFFER_SIZE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF 15
-#define HCI_READ_COUNTRY_CODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK 0x02
-#define HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF 15
-#define HCI_READ_BD_ADDR_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF] & \
-   HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF 15
-#define HCI_READ_FAIL_CONTACT_CNTR_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF] & \
-   HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK)
-
-#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK 0x08
-#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF 15
-#define HCI_RESET_FAIL_CONTACT_CNTR_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF] & \
-   HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK)
-
-#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK 0x10
-#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF 15
-#define HCI_GET_LINK_QUALITY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF] & \
-   HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_RSSI_MASK 0x20
-#define HCI_SUPP_COMMANDS_READ_RSSI_OFF 15
-#define HCI_READ_RSSI_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_READ_RSSI_OFF] & HCI_SUPP_COMMANDS_READ_RSSI_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF 15
-#define HCI_READ_AFH_CH_MAP_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF] & \
-   HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK 0x80
-#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF 15
-#define HCI_READ_BD_CLOCK_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF] & \
-   HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF 16
-#define HCI_READ_LOOPBACK_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF 16
-#define HCI_WRITE_LOOPBACK_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK 0x04
-#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF 16
-#define HCI_ENABLE_DEV_UNDER_TEST_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF] & \
-   HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK)
-
-#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK 0x08
-#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF 16
-#define HCI_SETUP_SYNCH_CONN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF] & \
-   HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK)
-
-#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK 0x10
-#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF 16
-#define HCI_ACCEPT_SYNCH_CONN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF] & \
-   HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK)
-
-#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK 0x20
-#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF 16
-#define HCI_REJECT_SYNCH_CONN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF] & \
-   HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF 17
-#define HCI_READ_EXT_INQUIRY_RESP_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF] & \
-   HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF 17
-#define HCI_WRITE_EXT_INQUIRY_RESP_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK)
-
-#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK 0x04
-#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF 17
-#define HCI_REFRESH_ENCRYPTION_KEY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF] & \
-   HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK)
-
-/* Octet 17, bit 3 is reserved */
-
-#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK 0x10
-#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF 17
-#define HCI_SNIFF_SUB_RATE_CMD_SUPPORTED(x)    \
-  ((x)[HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF] & \
-   HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK 0x20
-#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF 17
-#define HCI_READ_SIMPLE_PAIRING_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK 0x40
-#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF 17
-#define HCI_WRITE_SIMPLE_PAIRING_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK 0x80
-#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF 17
-#define HCI_READ_LOCAL_OOB_DATA_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF 18
-#define HCI_READ_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF] & \
-   HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF 18
-#define HCI_WRITE_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF 18
-#define HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & \
-   HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK 0x08
-#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF 18
-#define HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK)
-
-#define HCI_SUPP_COMMANDS_IO_CAPABILITY_REQUEST_REPLY_MASK 0x80
-#define HCI_SUPP_COMMANDS_IO_CAPABILITY_REQUEST_REPLY_OFF 18
-#define HCI_IO_CAPABILITY_REQUEST_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_IO_CAPABILITY_REQUEST_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_IO_CAPABILITY_REQUEST_REPLY_MASK)
-
-#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK 0x01
-#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF 19
-#define HCI_USER_CONFIRMATION_REQUEST_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK)
-
-#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK 0x02
-#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF 19
-#define HCI_USER_CONFIRMATION_REQUEST_NEG_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK)
-
-#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK 0x04
-#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF 19
-#define HCI_USER_PASSKEY_REQUEST_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK)
-
-#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK 0x08
-#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF 19
-#define HCI_USER_PASSKEY_REQUEST_NEG_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK)
-
-#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK 0x10
-#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF 19
-#define HCI_REMOTE_OOB_DATA_REQUEST_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK 0x20
-#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF 19
-#define HCI_WRITE_SIMPLE_PAIRING_DBG_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK 0x40
-#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF 19
-#define HCI_ENHANCED_FLUSH_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF] & \
-   HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK)
-
-#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK 0x80
-#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF 19
-#define HCI_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK)
-
-/* Supported Commands (Byte 20) */
-#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK 0x04
-#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF 20
-#define HCI_SEND_NOTIF_SUPPORTED(x)                 \
-  ((x)[HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF] & \
-   HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK)
-
-#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK 0x08
-#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF 20
-#define HCI_IO_CAP_REQ_NEG_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK 0x10
-#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF 20
-#define HCI_READ_ENCR_KEY_SIZE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK)
-
-/* Supported Commands (Byte 21) */
-#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK 0x01
-#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF 21
-#define HCI_CREATE_PHYSICAL_LINK_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF] & \
-   HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK)
-
-#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK 0x02
-#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF 21
-#define HCI_ACCEPT_PHYSICAL_LINK_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF] & \
-   HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK)
-
-#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK 0x04
-#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF 21
-#define HCI_DISCONNECT_PHYSICAL_LINK_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF] & \
-   HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK)
-
-#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK 0x08
-#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF 21
-#define HCI_CREATE_LOGICAL_LINK_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF] & \
-   HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK)
-
-#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK 0x10
-#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF 21
-#define HCI_ACCEPT_LOGICAL_LINK_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF] & \
-   HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK)
-
-#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK 0x20
-#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF 21
-#define HCI_DISCONNECT_LOGICAL_LINK_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF] & \
-   HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK)
-
-#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK 0x40
-#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF 21
-#define HCI_LOGICAL_LINK_CANCEL_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF] & \
-   HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK)
-
-#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK 0x80
-#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF 21
-#define HCI_FLOW_SPEC_MODIFY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF] & \
-   HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK)
-
-/* Supported Commands (Byte 22) */
-#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF 22
-#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF 22
-#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK 0x04
-#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF 22
-#define HCI_SET_EVENT_MASK_PAGE_2_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF] & \
-   HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK 0x08
-#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF 22
-#define HCI_READ_LOCATION_DATA_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK 0x10
-#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF 22
-#define HCI_WRITE_LOCATION_DATA_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK 0x20
-#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF 22
-#define HCI_READ_LOCAL_AMP_INFO_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF 22
-#define HCI_READ_LOCAL_AMP_ASSOC_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK 0x80
-#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF 22
-#define HCI_WRITE_REMOTE_AMP_ASSOC_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK)
-
-/* Supported Commands (Byte 23) */
-#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF 23
-#define HCI_READ_FLOW_CONTROL_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK 0x02
-#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF 23
-#define HCI_WRITE_FLOW_CONTROL_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF 23
-#define HCI_READ_DATA_BLOCK_SIZE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF] & \
-   HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK)
-
-#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK 0x20
-#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF 23
-#define HCI_ENABLE_AMP_RCVR_REPORTS_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF] & \
-   HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK)
-
-#define HCI_SUPP_COMMANDS_AMP_TEST_END_MASK 0x40
-#define HCI_SUPP_COMMANDS_AMP_TEST_END_OFF 23
-#define HCI_AMP_TEST_END_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_AMP_TEST_END_OFF] & \
-   HCI_SUPP_COMMANDS_AMP_TEST_END_MASK)
-
-#define HCI_SUPP_COMMANDS_AMP_TEST_MASK 0x80
-#define HCI_SUPP_COMMANDS_AMP_TEST_OFF 23
-#define HCI_AMP_TEST_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_AMP_TEST_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_MASK)
-
-/* Supported Commands (Byte 24) */
-#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK 0x01
-#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF 24
-#define HCI_READ_TRANSMIT_POWER_LEVEL_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF] & \
-   HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF 24
-#define HCI_READ_BE_FLUSH_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK 0x08
-#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF 24
-#define HCI_WRITE_BE_FLUSH_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK 0x10
-#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF 24
-#define HCI_SHORT_RANGE_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK)
-
-/* LE commands TBD
- * Supported Commands (Byte 24 continued)
- * Supported Commands (Byte 25)
- * Supported Commands (Byte 26)
- * Supported Commands (Byte 27)
- * Supported Commands (Byte 28)
-*/
-
-/* Supported Commands (Byte 29) */
-#define HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_MASK 0x08
-#define HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_OFF 29
-#define HCI_ENH_SETUP_SYNCH_CONN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_OFF] & \
-   HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_MASK)
-
-#define HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_MASK 0x10
-#define HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_OFF 29
-#define HCI_ENH_ACCEPT_SYNCH_CONN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_OFF] & \
-   HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_MASK 0x20
-#define HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_OFF 29
-#define HCI_READ_LOCAL_CODECS_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_MASK 0x40
-#define HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_OFF 29
-#define HCI_SET_MWS_CHANNEL_PARAMETERS_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_OFF] & \
-   HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_MASK 0x80
-#define HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_OFF 29
-#define HCI_SET_EXTERNAL_FRAME_CONFIGURATION_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_OFF] &        \
-   HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_MASK)
-
-/* Supported Commands (Byte 30) */
-#define HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_MASK 0x01
-#define HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_OFF 30
-#define HCI_SET_MWS_SIGNALING_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_OFF] & \
-   HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_MASK 0x02
-#define HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_OFF 30
-#define HCI_SET_MWS_TRANSPORT_LAYER_SUPPORTED(x)    \
-  ((x)[HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_OFF] & \
-   HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_MASK 0x04
-#define HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_OFF 30
-#define HCI_SET_MWS_SCAN_FREQUENCY_TABLE_SUPPORTED(x)   \
-  ((x)[HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_OFF] & \
-   HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_MASK)
-
-#define HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_MASK 0x08
-#define HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_OFF 30
-#define HCI_GET_MWS_TRANS_LAYER_CFG_SUPPORTED(x)     \
-  ((x)[HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_OFF] & \
-   HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_MASK)
-
-#define HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_MASK 0x10
-#define HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_OFF 30
-#define HCI_SET_MWS_PATTERN_CONFIGURATION_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_OFF] &   \
-   HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_MASK)
-
-/* Supported Commands (Byte 30 bit 5) */
-#define HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_MASK 0x20
-#define HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_OFF 30
-#define HCI_SET_TRIG_CLK_CAP_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_OFF] & \
-   HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_MASK)
-
-/* Supported Commands (Byte 30 bit 6-7) */
-#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE 0x06
-#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_OFF 30
-#define HCI_TRUNCATED_PAGE_SUPPORTED(x) \
-  ((x)[HCI_SUPP_COMMANDS_TRUNCATED_PAGE_OFF] & HCI_SUPP_COMMANDS_TRUNCATED_PAGE)
-
-#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL 0x07
-#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL_OFF 30
-#define HCI_TRUNCATED_PAGE_CANCEL_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL_OFF] & \
-   HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL)
-
-/* Supported Commands (Byte 31 bit 6-7) */
-#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST 0x00
-#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_OFF 31
-#define HCI_SET_CONLESS_SLAVE_BRCST_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_OFF] & \
-   HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST)
-
-#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE 0x01
-#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE_OFF 31
-#define HCI_SET_CONLESS_SLAVE_BRCST_RECEIVE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE_OFF] & \
-   HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE)
-
-#define HCI_SUPP_COMMANDS_START_SYNC_TRAIN 0x02
-#define HCI_SUPP_COMMANDS_START_SYNC_TRAIN_OFF 31
-#define HCI_START_SYNC_TRAIN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_START_SYNC_TRAIN_OFF] & \
-   HCI_SUPP_COMMANDS_START_SYNC_TRAIN)
-
-#define HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN 0x03
-#define HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN_OFF 31
-#define HCI_RECEIVE_SYNC_TRAIN_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN_OFF] & \
-   HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN)
-
-#define HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR 0x04
-#define HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR_OFF 31
-#define HCI_SET_RESERVED_LT_ADDR_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR_OFF] & \
-   HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR)
-
-#define HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR 0x05
-#define HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR_OFF 31
-#define HCI_DELETE_RESERVED_LT_ADDR_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR_OFF] & \
-   HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR)
-
-#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA 0x06
-#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA_OFF 31
-#define HCI_SET_CONLESS_SLAVE_BRCST_DATA_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA_OFF] & \
-   HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA)
-
-#define HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM 0x07
-#define HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM_OFF 31
-#define HCI_READ_SYNC_TRAIN_PARAM_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM_OFF] & \
-   HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM)
-
-/* Supported Commands (Byte 32 bit 0) */
-#define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM 0x00
-#define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF 32
-#define HCI_WRITE_SYNC_TRAIN_PARAM_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM)
-
-#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK 0x02
-#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF 32
-#define HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF] & \
-   HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK 0x04
-#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF 32
-#define HCI_READ_SECURE_CONNS_SUPPORT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF] & \
-   HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK 0x08
-#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF 32
-#define HCI_WRITE_SECURE_CONNS_SUPPORT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK 0x10
-#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF 32
-#define HCI_READ_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK 0x20
-#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF 32
-#define HCI_WRITE_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK)
-
-#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK 0x40
-#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF 32
-#define HCI_READ_LOCAL_OOB_EXTENDED_DATA_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF] & \
-   HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK)
-
-#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK 0x80
-#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF 32
-#define HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF] & \
-   HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK)
-
-/* supported LE remote control connection parameter request reply */
-#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK 0x10
-#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF 33
-#define HCI_LE_RC_CONN_PARAM_UPD_RPY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF] & \
-   HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK)
-
-#define HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK 0x20
-#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF 33
-#define HCI_LE_RC_CONN_PARAM_UPD_NEG_RPY_SUPPORTED(x)        \
-  ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF] & \
-   HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK)
-
-#define HCI_LE_2M_PHY_SUPPORTED(x) (((x)[1] & 0x01))     // BIT 8 SET
-#define HCI_LE_CODED_PHY_SUPPORTED(x) (((x)[1] & 0x08))  // BIT 11 SET
-
-/* LE Advertising Extension related Procedurs */
-#define HCI_LE_EXTENDED_ADVERTISING_SUPPORTED(x) \
-  (((x)[1] & 0x10))  // BIT 12 SET
-#define HCI_LE_PERIODIC_ADVERTISING_SUPPORTED(x) \
-  (((x)[1] & 0x20))  // BIT 13 SET
+#define HCI_LE_SET_PRIVACY_MODE_SUPPORTED(x) ((x)[39] & 0x04)
 
 #endif
diff --git a/stack/include/hcimsgs.h b/stack/include/hcimsgs.h
index 0a1984f..3a20851 100644
--- a/stack/include/hcimsgs.h
+++ b/stack/include/hcimsgs.h
@@ -64,7 +64,8 @@
 
 #define HCIC_PARAM_SIZE_EXIT_PER_INQ 0
 /* Create Connection */
-extern void btsnd_hcic_create_conn(BD_ADDR dest, uint16_t packet_types,
+extern void btsnd_hcic_create_conn(const RawAddress& dest,
+                                   uint16_t packet_types,
                                    uint8_t page_scan_rep_mode,
                                    uint8_t page_scan_mode,
                                    uint16_t clock_offset, uint8_t allow_switch);
@@ -100,7 +101,7 @@
 /* Add SCO Connection */
 
 /* Create Connection Cancel */
-extern void btsnd_hcic_create_conn_cancel(BD_ADDR dest);
+extern void btsnd_hcic_create_conn_cancel(const RawAddress& dest);
 
 #define HCIC_PARAM_SIZE_CREATE_CONN_CANCEL 6
 
@@ -108,7 +109,7 @@
 /* Create Connection Cancel */
 
 /* Accept Connection Request */
-extern void btsnd_hcic_accept_conn(BD_ADDR bd_addr, uint8_t role);
+extern void btsnd_hcic_accept_conn(const RawAddress& bd_addr, uint8_t role);
 
 #define HCIC_PARAM_SIZE_ACCEPT_CONN 7
 
@@ -117,7 +118,7 @@
 /* Accept Connection Request */
 
 /* Reject Connection Request */
-extern void btsnd_hcic_reject_conn(BD_ADDR bd_addr, uint8_t reason);
+extern void btsnd_hcic_reject_conn(const RawAddress& bd_addr, uint8_t reason);
 
 #define HCIC_PARAM_SIZE_REJECT_CONN 7
 
@@ -126,7 +127,8 @@
 /* Reject Connection Request */
 
 /* Link Key Request Reply */
-extern void btsnd_hcic_link_key_req_reply(BD_ADDR bd_addr, LINK_KEY link_key);
+extern void btsnd_hcic_link_key_req_reply(const RawAddress& bd_addr,
+                                          LINK_KEY link_key);
 
 #define HCIC_PARAM_SIZE_LINK_KEY_REQ_REPLY 22
 
@@ -135,7 +137,7 @@
 /* Link Key Request Reply  */
 
 /* Link Key Request Neg Reply */
-extern void btsnd_hcic_link_key_neg_reply(BD_ADDR bd_addr);
+extern void btsnd_hcic_link_key_neg_reply(const RawAddress& bd_addr);
 
 #define HCIC_PARAM_SIZE_LINK_KEY_NEG_REPLY 6
 
@@ -143,7 +145,8 @@
 /* Link Key Request Neg Reply  */
 
 /* PIN Code Request Reply */
-extern void btsnd_hcic_pin_code_req_reply(BD_ADDR bd_addr, uint8_t pin_code_len,
+extern void btsnd_hcic_pin_code_req_reply(const RawAddress& bd_addr,
+                                          uint8_t pin_code_len,
                                           PIN_CODE pin_code);
 
 #define HCIC_PARAM_SIZE_PIN_CODE_REQ_REPLY 23
@@ -154,7 +157,7 @@
 /* PIN Code Request Reply  */
 
 /* Link Key Request Neg Reply */
-extern void btsnd_hcic_pin_code_neg_reply(BD_ADDR bd_addr);
+extern void btsnd_hcic_pin_code_neg_reply(const RawAddress& bd_addr);
 
 #define HCIC_PARAM_SIZE_PIN_CODE_NEG_REPLY 6
 
@@ -186,7 +189,8 @@
 /* Set Connection Encryption */
 
 /* Remote Name Request */
-extern void btsnd_hcic_rmt_name_req(BD_ADDR bd_addr, uint8_t page_scan_rep_mode,
+extern void btsnd_hcic_rmt_name_req(const RawAddress& bd_addr,
+                                    uint8_t page_scan_rep_mode,
                                     uint8_t page_scan_mode,
                                     uint16_t clock_offset);
 
@@ -199,7 +203,7 @@
 /* Remote Name Request */
 
 /* Remote Name Request Cancel */
-extern void btsnd_hcic_rmt_name_req_cancel(BD_ADDR bd_addr);
+extern void btsnd_hcic_rmt_name_req_cancel(const RawAddress& bd_addr);
 
 #define HCIC_PARAM_SIZE_RMT_NAME_REQ_CANCEL 6
 
@@ -240,9 +244,9 @@
 #define HCI_SETUP_ESCO_PKT_TYPES_OFF 15
 
 extern void btsnd_hcic_accept_esco_conn(
-    BD_ADDR bd_addr, uint32_t transmit_bandwidth, uint32_t receive_bandwidth,
-    uint16_t max_latency, uint16_t content_fmt, uint8_t retrans_effort,
-    uint16_t packet_types);
+    const RawAddress& bd_addr, uint32_t transmit_bandwidth,
+    uint32_t receive_bandwidth, uint16_t max_latency, uint16_t content_fmt,
+    uint8_t retrans_effort, uint16_t packet_types);
 #define HCIC_PARAM_SIZE_ACCEPT_ESCO 21
 
 #define HCI_ACCEPT_ESCO_BDADDR_OFF 0
@@ -253,7 +257,8 @@
 #define HCI_ACCEPT_ESCO_RETRAN_EFF_OFF 18
 #define HCI_ACCEPT_ESCO_PKT_TYPES_OFF 19
 
-extern void btsnd_hcic_reject_esco_conn(BD_ADDR bd_addr, uint8_t reason);
+extern void btsnd_hcic_reject_esco_conn(const RawAddress& bd_addr,
+                                        uint8_t reason);
 #define HCIC_PARAM_SIZE_REJECT_ESCO 7
 
 #define HCI_REJECT_ESCO_BDADDR_OFF 0
@@ -318,7 +323,7 @@
 /* QoS Setup */
 
 /* Switch Role Request */
-extern void btsnd_hcic_switch_role(BD_ADDR bd_addr, uint8_t role);
+extern void btsnd_hcic_switch_role(const RawAddress& bd_addr, uint8_t role);
 
 #define HCIC_PARAM_SIZE_SWITCH_ROLE 7
 
@@ -377,8 +382,9 @@
 #define HCIC_EXT_INQ_RESP_FEC_OFF 0
 #define HCIC_EXT_INQ_RESP_RESPONSE 1
 /* IO Capabilities Response */
-extern void btsnd_hcic_io_cap_req_reply(BD_ADDR bd_addr, uint8_t capability,
-                                        uint8_t oob_present, uint8_t auth_req);
+extern void btsnd_hcic_io_cap_req_reply(const RawAddress& bd_addr,
+                                        uint8_t capability, uint8_t oob_present,
+                                        uint8_t auth_req);
 
 #define HCIC_PARAM_SIZE_IO_CAP_RESP 9
 
@@ -388,7 +394,8 @@
 #define HCI_IO_CAP_AUTH_REQ_OFF 8
 
 /* IO Capabilities Req Neg Reply */
-extern void btsnd_hcic_io_cap_req_neg_reply(BD_ADDR bd_addr, uint8_t err_code);
+extern void btsnd_hcic_io_cap_req_neg_reply(const RawAddress& bd_addr,
+                                            uint8_t err_code);
 
 #define HCIC_PARAM_SIZE_IO_CAP_NEG_REPLY 7
 
@@ -400,27 +407,28 @@
 
 #define HCIC_PARAM_SIZE_R_LOCAL_OOB 0
 
-extern void btsnd_hcic_user_conf_reply(BD_ADDR bd_addr, bool is_yes);
+extern void btsnd_hcic_user_conf_reply(const RawAddress& bd_addr, bool is_yes);
 
 #define HCIC_PARAM_SIZE_UCONF_REPLY 6
 
 #define HCI_USER_CONF_BD_ADDR_OFF 0
 
-extern void btsnd_hcic_user_passkey_reply(BD_ADDR bd_addr, uint32_t value);
+extern void btsnd_hcic_user_passkey_reply(const RawAddress& bd_addr,
+                                          uint32_t value);
 
 #define HCIC_PARAM_SIZE_U_PKEY_REPLY 10
 
 #define HCI_USER_PASSKEY_BD_ADDR_OFF 0
 #define HCI_USER_PASSKEY_VALUE_OFF 6
 
-extern void btsnd_hcic_user_passkey_neg_reply(BD_ADDR bd_addr);
+extern void btsnd_hcic_user_passkey_neg_reply(const RawAddress& bd_addr);
 
 #define HCIC_PARAM_SIZE_U_PKEY_NEG_REPLY 6
 
 #define HCI_USER_PASSKEY_NEG_BD_ADDR_OFF 0
 
 /* Remote OOB Data Request Reply */
-extern void btsnd_hcic_rem_oob_reply(BD_ADDR bd_addr, uint8_t* p_c,
+extern void btsnd_hcic_rem_oob_reply(const RawAddress& bd_addr, uint8_t* p_c,
                                      uint8_t* p_r);
 
 #define HCIC_PARAM_SIZE_REM_OOB_REPLY 38
@@ -430,7 +438,7 @@
 #define HCI_REM_OOB_DATA_R_OFF 22
 
 /* Remote OOB Data Request Negative Reply */
-extern void btsnd_hcic_rem_oob_neg_reply(BD_ADDR bd_addr);
+extern void btsnd_hcic_rem_oob_neg_reply(const RawAddress& bd_addr);
 
 #define HCIC_PARAM_SIZE_REM_OOB_NEG_REPLY 6
 
@@ -452,7 +460,8 @@
 #define HCIC_PARAM_SIZE_ENHANCED_FLUSH 3
 #endif
 
-extern void btsnd_hcic_send_keypress_notif(BD_ADDR bd_addr, uint8_t notif);
+extern void btsnd_hcic_send_keypress_notif(const RawAddress& bd_addr,
+                                           uint8_t notif);
 
 #define HCIC_PARAM_SIZE_SEND_KEYPRESS_NOTIF 7
 
@@ -477,7 +486,8 @@
 /* Set Event Filter */
 
 /* Delete Stored Key */
-extern void btsnd_hcic_delete_stored_key(BD_ADDR bd_addr, bool delete_all_flag);
+extern void btsnd_hcic_delete_stored_key(const RawAddress& bd_addr,
+                                         bool delete_all_flag);
 
 #define HCIC_PARAM_SIZE_DELETE_STORED_KEY 7
 
@@ -552,7 +562,7 @@
 extern void btsnd_hcic_write_auto_flush_tout(
     uint16_t handle, uint16_t timeout); /* Write Retransmit Timout */
 
-#define HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT 4
+#define HCIC_PARAM_SIZE_WRITE_AUTOMATIC_FLUSH_TIMEOUT 4
 
 #define HCI_FLUSH_TOUT_HANDLE_OFF 0
 #define HCI_FLUSH_TOUT_TOUT_OFF 2
@@ -602,6 +612,11 @@
 
 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::Callback<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_failed_contact_counter(uint16_t handle);
+extern void btsnd_hcic_read_automatic_flush_timeout(uint16_t handle);
 extern void btsnd_hcic_enable_test_mode(
     void); /* Enable Device Under Test Mode */
 extern void btsnd_hcic_write_pagescan_type(
@@ -617,7 +632,7 @@
 
 /* Enhanced accept SCO connection request (CSA2) */
 extern void btsnd_hcic_enhanced_accept_synchronous_connection(
-    BD_ADDR bd_addr, enh_esco_params_t* p_parms);
+    const RawAddress& bd_addr, enh_esco_params_t* p_parms);
 
 #define HCI_DATA_HANDLE_MASK 0x0FFF
 
@@ -695,6 +710,13 @@
 #define HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_LOCAL 7
 #define HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE 1
 #define HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT 2
+
+#define HCIC_PARAM_SIZE_BLE_READ_PHY 2
+#define HCIC_PARAM_SIZE_BLE_SET_DEFAULT_PHY 3
+#define HCIC_PARAM_SIZE_BLE_SET_PHY 7
+#define HCIC_PARAM_SIZE_BLE_ENH_RX_TEST 3
+#define HCIC_PARAM_SIZE_BLE_ENH_TX_TEST 4
+
 #define HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH 6
 #define HCIC_PARAM_SIZE_BLE_WRITE_EXTENDED_SCAN_PARAM 11
 
@@ -707,11 +729,11 @@
 
 extern void btsnd_hcic_ble_set_local_used_feat(uint8_t feat_set[8]);
 
-extern void btsnd_hcic_ble_set_random_addr(BD_ADDR random_addr);
+extern void btsnd_hcic_ble_set_random_addr(const RawAddress& random_addr);
 
 extern void btsnd_hcic_ble_write_adv_params(
     uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type,
-    uint8_t addr_type_own, uint8_t addr_type_dir, BD_ADDR direct_bda,
+    uint8_t addr_type_own, uint8_t addr_type_dir, const RawAddress& direct_bda,
     uint8_t channel_map, uint8_t adv_filter_policy);
 
 extern void btsnd_hcic_ble_read_adv_chnl_tx_power(void);
@@ -732,7 +754,7 @@
 
 extern void btsnd_hcic_ble_create_ll_conn(
     uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
-    uint8_t addr_type_peer, BD_ADDR bda_peer, uint8_t addr_type_own,
+    uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
     uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
     uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len);
 
@@ -742,10 +764,11 @@
 
 extern void btsnd_hcic_ble_clear_white_list(void);
 
-extern void btsnd_hcic_ble_add_white_list(uint8_t addr_type, BD_ADDR bda);
+extern void btsnd_hcic_ble_add_white_list(uint8_t addr_type,
+                                          const RawAddress& bda);
 
 extern void btsnd_hcic_ble_remove_from_white_list(uint8_t addr_type,
-                                                  BD_ADDR bda);
+                                                  const RawAddress& bda);
 
 extern void btsnd_hcic_ble_upd_ll_conn_params(
     uint16_t handle, uint16_t conn_int_min, uint16_t conn_int_max,
@@ -808,7 +831,7 @@
                                            uint16_t tx_time);
 
 extern void btsnd_hcic_ble_add_device_resolving_list(
-    uint8_t addr_type_peer, BD_ADDR bda_peer,
+    uint8_t addr_type_peer, const RawAddress& bda_peer,
     uint8_t irk_peer[HCIC_BLE_IRK_SIZE], uint8_t irk_local[HCIC_BLE_IRK_SIZE]);
 
 struct scanning_phy_cfg {
@@ -837,28 +860,31 @@
   uint16_t max_ce_len;
 };
 
-extern void btsnd_hcic_ble_ext_create_conn(
-    uint8_t init_filter_policy, uint8_t addr_type_own, uint8_t addr_type_peer,
-    BD_ADDR bda_peer, uint8_t initiating_phys, EXT_CONN_PHY_CFG* phy_cfg);
+extern void btsnd_hcic_ble_ext_create_conn(uint8_t init_filter_policy,
+                                           uint8_t addr_type_own,
+                                           uint8_t addr_type_peer,
+                                           const RawAddress& bda_peer,
+                                           uint8_t initiating_phys,
+                                           EXT_CONN_PHY_CFG* phy_cfg);
 
 extern void btsnd_hcic_ble_add_device_resolving_list(
-    uint8_t addr_type_peer, BD_ADDR bda_peer,
+    uint8_t addr_type_peer, const RawAddress& bda_peer,
     uint8_t irk_peer[HCIC_BLE_IRK_SIZE], uint8_t irk_local[HCIC_BLE_IRK_SIZE]);
 
 extern void btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer,
-                                                    BD_ADDR bda_peer);
+                                                    const RawAddress& bda_peer);
 
 extern void btsnd_hcic_ble_set_privacy_mode(uint8_t addr_type_peer,
-                                            BD_ADDR bda_peer,
+                                            const RawAddress& bda_peer,
                                             uint8_t privacy_type);
 
 extern void btsnd_hcic_ble_clear_resolving_list(void);
 
-extern void btsnd_hcic_ble_read_resolvable_addr_peer(uint8_t addr_type_peer,
-                                                     BD_ADDR bda_peer);
+extern void btsnd_hcic_ble_read_resolvable_addr_peer(
+    uint8_t addr_type_peer, const RawAddress& bda_peer);
 
-extern void btsnd_hcic_ble_read_resolvable_addr_local(uint8_t addr_type_peer,
-                                                      BD_ADDR bda_peer);
+extern void btsnd_hcic_ble_read_resolvable_addr_local(
+    uint8_t addr_type_peer, const RawAddress& bda_peer);
 
 extern void btsnd_hcic_ble_set_addr_resolution_enable(
     uint8_t addr_resolution_enable);
diff --git a/stack/include/hidd_api.h b/stack/include/hidd_api.h
index 0db58dc..85785e8 100644
--- a/stack/include/hidd_api.h
+++ b/stack/include/hidd_api.h
@@ -47,7 +47,7 @@
   HID_DHOST_EVT_SUSPEND,
   HID_DHOST_EVT_EXIT_SUSPEND,
 };
-typedef void(tHID_DEV_HOST_CALLBACK)(BD_ADDR bd_addr, uint8_t event,
+typedef void(tHID_DEV_HOST_CALLBACK)(const RawAddress& bd_addr, uint8_t event,
                                      uint32_t data, BT_HDR* p_buf);
 
 /*****************************************************************************
@@ -147,7 +147,7 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-extern tHID_STATUS HID_DevPlugDevice(BD_ADDR addr);
+extern tHID_STATUS HID_DevPlugDevice(const RawAddress& addr);
 
 /*******************************************************************************
  *
@@ -158,7 +158,7 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-extern tHID_STATUS HID_DevUnplugDevice(BD_ADDR addr);
+extern tHID_STATUS HID_DevUnplugDevice(const RawAddress& addr);
 
 /*******************************************************************************
  *
@@ -213,7 +213,7 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-extern tHID_STATUS HID_DevGetDevice(BD_ADDR* addr);
+extern tHID_STATUS HID_DevGetDevice(RawAddress* addr);
 
 /*******************************************************************************
  *
diff --git a/stack/include/hidh_api.h b/stack/include/hidh_api.h
index 9ff6f49..5b43b44 100644
--- a/stack/include/hidh_api.h
+++ b/stack/include/hidh_api.h
@@ -81,7 +81,7 @@
   HID_HDEV_EVT_VC_UNPLUG
 };
 typedef void(tHID_HOST_DEV_CALLBACK)(
-    uint8_t dev_handle, BD_ADDR addr,
+    uint8_t dev_handle, const RawAddress& addr,
     uint8_t event,  /* Event from HID-DEVICE. */
     uint32_t data,  /* Integer data corresponding to the event.*/
     BT_HDR* p_buf); /* Pointer data corresponding to the event. */
@@ -99,7 +99,8 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-extern tHID_STATUS HID_HostGetSDPRecord(BD_ADDR addr, tSDP_DISCOVERY_DB* p_db,
+extern tHID_STATUS HID_HostGetSDPRecord(const RawAddress& addr,
+                                        tSDP_DISCOVERY_DB* p_db,
                                         uint32_t db_len,
                                         tHID_HOST_SDP_CALLBACK* sdp_cback);
 
@@ -134,7 +135,7 @@
  * Returns          tHID_STATUS
  *
  ******************************************************************************/
-extern tHID_STATUS HID_HostAddDev(BD_ADDR addr, uint16_t attr_mask,
+extern tHID_STATUS HID_HostAddDev(const RawAddress& addr, uint16_t attr_mask,
                                   uint8_t* handle);
 
 /*******************************************************************************
@@ -214,7 +215,7 @@
  * Returns          true if device exists else false
  *
  ******************************************************************************/
-bool hid_known_hid_device(BD_ADDR bd_addr);
+bool hid_known_hid_device(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
diff --git a/stack/include/l2c_api.h b/stack/include/l2c_api.h
index 6ac7c4b..6d7f423 100644
--- a/stack/include/l2c_api.h
+++ b/stack/include/l2c_api.h
@@ -1,20 +1,20 @@
 /******************************************************************************
- *
- *  Copyright (C) 1999-2012 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
+*
+*  Copyright (C) 1999-2012 Broadcom Corporation
+*
+*  Licensed under the Apache License, Version 2.0 (the "License");
+*  you may not use this file except in compliance with the License.
+*  You may obtain a copy of the License at:
+*
+*  http://www.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*
+******************************************************************************/
 
 /******************************************************************************
  *
@@ -36,7 +36,7 @@
 
 /* Define the minimum offset that L2CAP needs in a buffer. This is made up of
  * HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) => 9
-*/
+ */
 #define L2CAP_MIN_OFFSET 13 /* plus control(2), SDU length(2) */
 
 #define L2CAP_LCC_SDU_LENGTH 2
@@ -112,7 +112,7 @@
 #define L2CAP_ROLE_CHECK_SWITCH 0xC0
 
 /* Values for 'allowed_modes' field passed in structure tL2CAP_ERTM_INFO
-*/
+ */
 #define L2CAP_FCR_CHAN_OPT_BASIC (1 << L2CAP_FCR_BASIC_MODE)
 #define L2CAP_FCR_CHAN_OPT_ERTM (1 << L2CAP_FCR_ERTM_MODE)
 #define L2CAP_FCR_CHAN_OPT_STREAM (1 << L2CAP_FCR_STREAM_MODE)
@@ -124,7 +124,7 @@
 /* Validity check for PSM.  PSM values must be odd.  Also, all PSM values must
  * be assigned such that the least significant bit of the most sigificant
  * octet equals zero.
-*/
+ */
 #define L2C_INVALID_PSM(psm) (((psm)&0x0101) != 0x0001)
 #define L2C_IS_VALID_PSM(psm) (((psm)&0x0101) == 0x0001)
 #define L2C_IS_VALID_LE_PSM(psm) (((psm) > 0x0000) && ((psm) < 0x0100))
@@ -151,7 +151,7 @@
 /* Define a structure to hold the configuration parameters. Since the
  * parameters are optional, for each parameter there is a boolean to
  * use to signify its presence or absence.
-*/
+ */
 typedef struct {
   uint16_t result; /* Only used in confirm messages */
   bool mtu_present;
@@ -171,7 +171,7 @@
 
 /* Define a structure to hold the configuration parameter for LE L2CAP
  * connection oriented channels.
-*/
+ */
 typedef struct {
   uint16_t mtu;
   uint16_t mps;
@@ -197,72 +197,73 @@
  *              Local CID assigned to the connection
  *              PSM that the remote wants to connect to
  *              Identifier that the remote sent
-*/
-typedef void(tL2CA_CONNECT_IND_CB)(BD_ADDR, uint16_t, uint16_t, uint8_t);
+ */
+typedef void(tL2CA_CONNECT_IND_CB)(const RawAddress&, uint16_t, uint16_t,
+                                   uint8_t);
 
 /* Connection confirmation callback prototype. Parameters are
  *              Local CID
  *              Result - 0 = connected, non-zero means failure reason
-*/
+ */
 typedef void(tL2CA_CONNECT_CFM_CB)(uint16_t, uint16_t);
 
 /* Connection pending callback prototype. Parameters are
  *              Local CID
-*/
+ */
 typedef void(tL2CA_CONNECT_PND_CB)(uint16_t);
 
 /* Configuration indication callback prototype. Parameters are
  *              Local CID assigned to the connection
  *              Pointer to configuration info
-*/
+ */
 typedef void(tL2CA_CONFIG_IND_CB)(uint16_t, tL2CAP_CFG_INFO*);
 
 /* Configuration confirm callback prototype. Parameters are
  *              Local CID assigned to the connection
  *              Pointer to configuration info
-*/
+ */
 typedef void(tL2CA_CONFIG_CFM_CB)(uint16_t, tL2CAP_CFG_INFO*);
 
 /* Disconnect indication callback prototype. Parameters are
  *              Local CID
  *              Boolean whether upper layer should ack this
-*/
+ */
 typedef void(tL2CA_DISCONNECT_IND_CB)(uint16_t, bool);
 
 /* Disconnect confirm callback prototype. Parameters are
  *              Local CID
  *              Result
-*/
+ */
 typedef void(tL2CA_DISCONNECT_CFM_CB)(uint16_t, uint16_t);
 
 /* QOS Violation indication callback prototype. Parameters are
  *              BD Address of violating device
-*/
-typedef void(tL2CA_QOS_VIOLATION_IND_CB)(BD_ADDR);
+ */
+typedef void(tL2CA_QOS_VIOLATION_IND_CB)(const RawAddress&);
 
 /* Data received indication callback prototype. Parameters are
  *              Local CID
  *              Address of buffer
-*/
+ */
 typedef void(tL2CA_DATA_IND_CB)(uint16_t, BT_HDR*);
 
 /* Echo response callback prototype. Note that this is not included in the
  * registration information, but is passed to L2CAP as part of the API to
  * actually send an echo request. Parameters are
  *              Result
-*/
+ */
 typedef void(tL2CA_ECHO_RSP_CB)(uint16_t);
 
 /* Callback function prototype to pass broadcom specific echo response  */
 /* to the upper layer                                                   */
-typedef void(tL2CA_ECHO_DATA_CB)(BD_ADDR, uint16_t, uint8_t*);
+typedef void(tL2CA_ECHO_DATA_CB)(const RawAddress&, uint16_t, uint8_t*);
 
 /* Congestion status callback protype. This callback is optional. If
  * an application tries to send data when the transmit queue is full,
  * the data will anyways be dropped. The parameter is:
  *              Local CID
  *              true if congested, false if uncongested
-*/
+ */
 typedef void(tL2CA_CONGESTION_STATUS_CB)(uint16_t, bool);
 
 /* Callback prototype for number of packets completed events.
@@ -271,8 +272,8 @@
  * This callback is originally designed for 3DG devices.
  * The parameter is:
  *          peer BD_ADDR
-*/
-typedef void(tL2CA_NOCP_CB)(BD_ADDR);
+ */
+typedef void(tL2CA_NOCP_CB)(const RawAddress&);
 
 /* Transmit complete callback protype. This callback is optional. If
  * set, L2CAP will call it when packets are sent or flushed. If the
@@ -280,14 +281,14 @@
  * mode only). The parameters are:
  *              Local CID
  *              Number of SDUs sent or dropped
-*/
+ */
 typedef void(tL2CA_TX_COMPLETE_CB)(uint16_t, uint16_t);
 
 /* Define the structure that applications use to register with
  * L2CAP. This structure includes callback functions. All functions
  * MUST be provided, with the exception of the "connect pending"
  * callback and "congestion status" callback.
-*/
+ */
 typedef struct {
   tL2CA_CONNECT_IND_CB* pL2CA_ConnectInd_Cb;
   tL2CA_CONNECT_CFM_CB* pL2CA_ConnectCfm_Cb;
@@ -305,7 +306,7 @@
 
 /* Define the structure that applications use to create or accept
  * connections with enhanced retransmission mode.
-*/
+ */
 typedef struct {
   uint8_t preferred_mode;
   uint8_t allowed_modes;
@@ -389,7 +390,7 @@
  * Returns          the CID of the connection, or 0 if it failed to start
  *
  ******************************************************************************/
-extern uint16_t L2CA_ConnectReq(uint16_t psm, BD_ADDR p_bd_addr);
+extern uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr);
 
 /*******************************************************************************
  *
@@ -402,8 +403,8 @@
  * Returns          true for success, false for failure
  *
  ******************************************************************************/
-extern bool L2CA_ConnectRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
-                            uint16_t result, uint16_t status);
+extern bool L2CA_ConnectRsp(const RawAddress& p_bd_addr, uint8_t id,
+                            uint16_t lcid, uint16_t result, uint16_t status);
 
 /*******************************************************************************
  *
@@ -418,7 +419,7 @@
  * Returns          the CID of the connection, or 0 if it failed to start
  *
  ******************************************************************************/
-extern uint16_t L2CA_ErtmConnectReq(uint16_t psm, BD_ADDR p_bd_addr,
+extern uint16_t L2CA_ErtmConnectReq(uint16_t psm, const RawAddress& p_bd_addr,
                                     tL2CAP_ERTM_INFO* p_ertm_info);
 
 /*******************************************************************************
@@ -461,7 +462,7 @@
  * Returns          the CID of the connection, or 0 if it failed to start
  *
  ******************************************************************************/
-extern uint16_t L2CA_ConnectLECocReq(uint16_t psm, BD_ADDR p_bd_addr,
+extern uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr,
                                      tL2CAP_LE_CFG_INFO* p_cfg);
 
 /*******************************************************************************
@@ -475,9 +476,9 @@
  * Returns          true for success, false for failure
  *
  ******************************************************************************/
-extern bool L2CA_ConnectLECocRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
-                                 uint16_t result, uint16_t status,
-                                 tL2CAP_LE_CFG_INFO* p_cfg);
+extern bool L2CA_ConnectLECocRsp(const RawAddress& p_bd_addr, uint8_t id,
+                                 uint16_t lcid, uint16_t result,
+                                 uint16_t status, tL2CAP_LE_CFG_INFO* p_cfg);
 
 /*******************************************************************************
  *
@@ -511,8 +512,8 @@
  * Returns          true for success, false for failure
  *
  ******************************************************************************/
-extern bool L2CA_ErtmConnectRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
-                                uint16_t result, uint16_t status,
+extern bool L2CA_ErtmConnectRsp(const RawAddress& p_bd_addr, uint8_t id,
+                                uint16_t lcid, uint16_t result, uint16_t status,
                                 tL2CAP_ERTM_INFO* p_ertm_info);
 
 /*******************************************************************************
@@ -584,7 +585,7 @@
  * Returns          true if echo request sent, else false.
  *
  ******************************************************************************/
-extern bool L2CA_Ping(BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB* p_cb);
+extern bool L2CA_Ping(const RawAddress& p_bd_addr, tL2CA_ECHO_RSP_CB* p_cb);
 
 /*******************************************************************************
  *
@@ -596,7 +597,7 @@
  * Returns          true if echo request sent, else false.
  *
  ******************************************************************************/
-extern bool L2CA_Echo(BD_ADDR p_bd_addr, BT_HDR* p_data,
+extern bool L2CA_Echo(const RawAddress& p_bd_addr, BT_HDR* p_data,
                       tL2CA_ECHO_DATA_CB* p_callback);
 
 // Given a local channel identifier, |lcid|, this function returns the bound
@@ -633,16 +634,17 @@
  *                  A timeout of zero means that the connection will be torn
  *                  down immediately when the last channel is removed.
  *                  A timeout of 0xFFFF means no timeout. Values are in seconds.
- *                  A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
- *                  then the idle timeouts for all active l2cap links will be
- *                  changed.
+ *                  A bd_addr is the remote BD address. If bd_addr =
+ *                  RawAddress::kAny, then the idle timeouts for all active
+ *                  l2cap links will be changed.
  *
  * Returns          true if command succeeded, false if failed
  *
  * NOTE             This timeout applies to all logical channels active on the
  *                  ACL link.
  ******************************************************************************/
-extern bool L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, uint16_t timeout,
+extern bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr,
+                                        uint16_t timeout,
                                         tBT_TRANSPORT transport);
 
 /*******************************************************************************
@@ -686,7 +688,7 @@
  *
  ******************************************************************************/
 extern uint16_t L2CA_LocalLoopbackReq(uint16_t psm, uint16_t handle,
-                                      BD_ADDR p_bd_addr);
+                                      const RawAddress& p_bd_addr);
 
 /*******************************************************************************
  *
@@ -715,7 +717,7 @@
  * Returns          true if a valid channel, else false
  *
  ******************************************************************************/
-extern bool L2CA_SetAclPriority(BD_ADDR bd_addr, uint8_t priority);
+extern bool L2CA_SetAclPriority(const RawAddress& bd_addr, uint8_t priority);
 
 /*******************************************************************************
  *
@@ -765,7 +767,7 @@
  * Returns
  *
  ******************************************************************************/
-extern bool L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, BD_ADDR p_bda);
+extern bool L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, const RawAddress& p_bda);
 
 /*******************************************************************************
  *
@@ -794,8 +796,8 @@
  *                           0x0000 : No automatic flush
  *                           L2CAP_NO_RETRANSMISSION : No retransmission
  *                           0x0002 - 0xFFFE : flush time out, if
- *                                             (flush_tout * 8) + 3 / 5)
- *                                               <= HCI_MAX_AUTO_FLUSH_TOUT
+ *                                             (flush_tout * 8) + 3 / 5) <=
+ *                                             HCI_MAX_AUTOMATIC_FLUSH_TIMEOUT
  *                                             (in 625us slot).
  *                                    Otherwise, return false.
  *                           L2CAP_NO_AUTOMATIC_FLUSH : No automatic flush
@@ -805,7 +807,8 @@
  * NOTE             This flush timeout applies to all logical channels active on
  *                  the ACL link.
  ******************************************************************************/
-extern bool L2CA_SetFlushTimeout(BD_ADDR bd_addr, uint16_t flush_tout);
+extern bool L2CA_SetFlushTimeout(const RawAddress& bd_addr,
+                                 uint16_t flush_tout);
 
 /*******************************************************************************
  *
@@ -849,8 +852,8 @@
  *  Return value:    true if peer is connected
  *
  ******************************************************************************/
-extern bool L2CA_GetPeerFeatures(BD_ADDR bd_addr, uint32_t* p_ext_feat,
-                                 uint8_t* p_chnl_mask);
+extern bool L2CA_GetPeerFeatures(const RawAddress& bd_addr,
+                                 uint32_t* p_ext_feat, uint8_t* p_chnl_mask);
 
 /*******************************************************************************
  *
@@ -864,7 +867,7 @@
  *  Return value:    true if found lcb for the given handle, false otherwise
  *
  ******************************************************************************/
-extern bool L2CA_GetBDAddrbyHandle(uint16_t handle, BD_ADDR bd_addr);
+extern bool L2CA_GetBDAddrbyHandle(uint16_t handle, RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -889,28 +892,28 @@
  *      BD Address of remote
  *      Data Type
  *      Data
-*/
+ */
 #define L2CAP_UCD_INFO_TYPE_RECEPTION 0x01
 #define L2CAP_UCD_INFO_TYPE_MTU 0x02
 
-typedef void(tL2CA_UCD_DISCOVER_CB)(BD_ADDR, uint8_t, uint32_t);
+typedef void(tL2CA_UCD_DISCOVER_CB)(const RawAddress&, uint8_t, uint32_t);
 
 /* UCD data received. Parameters are
  *      BD Address of remote
  *      Pointer to buffer with data
-*/
-typedef void(tL2CA_UCD_DATA_CB)(BD_ADDR, BT_HDR*);
+ */
+typedef void(tL2CA_UCD_DATA_CB)(const RawAddress&, BT_HDR*);
 
 /* Congestion status callback protype. This callback is optional. If
  * an application tries to send data when the transmit queue is full,
  * the data will anyways be dropped. The parameter is:
  *              remote BD_ADDR
  *              true if congested, false if uncongested
-*/
-typedef void(tL2CA_UCD_CONGESTION_STATUS_CB)(BD_ADDR, bool);
+ */
+typedef void(tL2CA_UCD_CONGESTION_STATUS_CB)(const RawAddress&, bool);
 
 /* UCD registration info (the callback addresses and PSM)
-*/
+ */
 typedef struct {
   tL2CA_UCD_DISCOVER_CB* pL2CA_UCD_Discover_Cb;
   tL2CA_UCD_DATA_CB* pL2CA_UCD_Data_Cb;
@@ -958,7 +961,8 @@
  *  Return value:   true if successs
  *
  ******************************************************************************/
-extern bool L2CA_UcdDiscover(uint16_t psm, BD_ADDR rem_bda, uint8_t info_type);
+extern bool L2CA_UcdDiscover(uint16_t psm, const RawAddress& rem_bda,
+                             uint8_t info_type);
 
 /*******************************************************************************
  *
@@ -977,8 +981,8 @@
  *                  L2CAP_DW_FAILED,  if error
  *
  ******************************************************************************/
-extern uint16_t L2CA_UcdDataWrite(uint16_t psm, BD_ADDR rem_bda, BT_HDR* p_buf,
-                                  uint16_t flags);
+extern uint16_t L2CA_UcdDataWrite(uint16_t psm, const RawAddress& rem_bda,
+                                  BT_HDR* p_buf, uint16_t flags);
 
 /*******************************************************************************
  *
@@ -992,7 +996,7 @@
  *  Return value:   true if successs
  *
  ******************************************************************************/
-extern bool L2CA_UcdSetIdleTimeout(BD_ADDR rem_bda, uint16_t timeout);
+extern bool L2CA_UcdSetIdleTimeout(const RawAddress& rem_bda, uint16_t timeout);
 
 /*******************************************************************************
  *
@@ -1003,7 +1007,7 @@
  * Returns          true if a valid channel, else false
  *
  ******************************************************************************/
-extern bool L2CA_UCDSetTxPriority(BD_ADDR rem_bda,
+extern bool L2CA_UCDSetTxPriority(const RawAddress& rem_bda,
                                   tL2CAP_CHNL_PRIORITY priority);
 
 /*******************************************************************************
@@ -1018,27 +1022,27 @@
  *      true if channel is connected, false if disconnected
  *      Reason for connection failure
  *      transport : physical transport, BR/EDR or LE
-*/
-typedef void(tL2CA_FIXED_CHNL_CB)(uint16_t, BD_ADDR, bool, uint16_t,
+ */
+typedef void(tL2CA_FIXED_CHNL_CB)(uint16_t, const RawAddress&, bool, uint16_t,
                                   tBT_TRANSPORT);
 
 /* Signalling data received. Parameters are
  *      channel
  *      BD Address of remote
  *      Pointer to buffer with data
-*/
-typedef void(tL2CA_FIXED_DATA_CB)(uint16_t, BD_ADDR, BT_HDR*);
+ */
+typedef void(tL2CA_FIXED_DATA_CB)(uint16_t, const RawAddress&, BT_HDR*);
 
 /* Congestion status callback protype. This callback is optional. If
  * an application tries to send data when the transmit queue is full,
  * the data will anyways be dropped. The parameter is:
  *      remote BD_ADDR
  *      true if congested, false if uncongested
-*/
-typedef void(tL2CA_FIXED_CONGESTION_STATUS_CB)(BD_ADDR, bool);
+ */
+typedef void(tL2CA_FIXED_CONGESTION_STATUS_CB)(const RawAddress&, bool);
 
 /* Fixed channel registration info (the callback addresses and channel config)
-*/
+ */
 typedef struct {
   tL2CA_FIXED_CHNL_CB* pL2CA_FixedConn_Cb;
   tL2CA_FIXED_DATA_CB* pL2CA_FixedData_Cb;
@@ -1078,8 +1082,9 @@
  *  Return value:   true if connection started
  *
  ******************************************************************************/
-extern bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR bd_addr);
-extern bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR bd_addr,
+extern bool L2CA_ConnectFixedChnl(uint16_t fixed_cid,
+                                  const RawAddress& bd_addr);
+extern bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& bd_addr,
                                   uint8_t initiating_phys);
 
 /*******************************************************************************
@@ -1096,7 +1101,8 @@
  *                  L2CAP_DW_FAILED,  if error
  *
  ******************************************************************************/
-extern uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, BD_ADDR rem_bda,
+extern uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid,
+                                       const RawAddress& rem_bda,
                                        BT_HDR* p_buf);
 
 /*******************************************************************************
@@ -1112,7 +1118,7 @@
  *  Return value:   true if channel removed
  *
  ******************************************************************************/
-extern bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda);
+extern bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda);
 
 /*******************************************************************************
  *
@@ -1124,15 +1130,15 @@
  *                  it. A timeout of zero means that the connection will be torn
  *                  down immediately when the last channel is removed.
  *                  A timeout of 0xFFFF means no timeout. Values are in seconds.
- *                  A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
- *                  then the idle timeouts for all active l2cap links will be
- *                  changed.
+ *                  A bd_addr is the remote BD address. If bd_addr =
+ *                  RawAddress::kAny, then the idle timeouts for all active
+ *                  l2cap links will be changed.
  *
  * Returns          true if command succeeded, false if failed
  *
  ******************************************************************************/
-extern bool L2CA_SetFixedChannelTout(BD_ADDR rem_bda, uint16_t fixed_cid,
-                                     uint16_t idle_tout);
+extern bool L2CA_SetFixedChannelTout(const RawAddress& rem_bda,
+                                     uint16_t fixed_cid, uint16_t idle_tout);
 
 #endif /* (L2CAP_NUM_FIXED_CHNLS > 0) */
 
@@ -1178,7 +1184,7 @@
  *  Return value:   true if connection was cancelled
  *
  ******************************************************************************/
-extern bool L2CA_CancelBleConnectReq(BD_ADDR rem_bda);
+extern bool L2CA_CancelBleConnectReq(const RawAddress& rem_bda);
 
 /*******************************************************************************
  *
@@ -1191,9 +1197,9 @@
  *  Return value:   true if update started
  *
  ******************************************************************************/
-extern bool L2CA_UpdateBleConnParams(BD_ADDR rem_bdRa, uint16_t min_int,
-                                     uint16_t max_int, uint16_t latency,
-                                     uint16_t timeout);
+extern bool L2CA_UpdateBleConnParams(const RawAddress& rem_bdRa,
+                                     uint16_t min_int, uint16_t max_int,
+                                     uint16_t latency, uint16_t timeout);
 
 /*******************************************************************************
  *
@@ -1207,7 +1213,8 @@
  *  Return value:   true if update started
  *
  ******************************************************************************/
-extern bool L2CA_EnableUpdateBleConnParams(BD_ADDR rem_bda, bool enable);
+extern bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda,
+                                           bool enable);
 
 /*******************************************************************************
  *
@@ -1218,7 +1225,7 @@
  * Returns          link role.
  *
  ******************************************************************************/
-extern uint8_t L2CA_GetBleConnRole(BD_ADDR bd_addr);
+extern uint8_t L2CA_GetBleConnRole(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -1232,7 +1239,7 @@
  * Returns          disconnect reason
  *
  ******************************************************************************/
-extern uint16_t L2CA_GetDisconnectReason(BD_ADDR remote_bda,
+extern uint16_t L2CA_GetDisconnectReason(const RawAddress& remote_bda,
                                          tBT_TRANSPORT transport);
 
 #endif /* L2C_API_H */
diff --git a/stack/include/l2cap_client.h b/stack/include/l2cap_client.h
index c5ecaf6..fb4e922 100644
--- a/stack/include/l2cap_client.h
+++ b/stack/include/l2cap_client.h
@@ -60,7 +60,7 @@
 // while |l2cap_client_is_connected|. |client| and |remote_bdaddr| must not be
 // NULL. |psm| must be greater than zero.
 bool l2cap_client_connect(l2cap_client_t* client,
-                          const bt_bdaddr_t* remote_bdaddr, uint16_t psm);
+                          const RawAddress& remote_bdaddr, uint16_t psm);
 
 // Disconnects a connected |client|. This function is asynchronous and
 // idempotent. It will indicate completion with a 'disconnected' callback.
diff --git a/stack/include/mca_api.h b/stack/include/mca_api.h
index 2d0128f..3c962d0 100644
--- a/stack/include/mca_api.h
+++ b/stack/include/mca_api.h
@@ -165,13 +165,13 @@
 
 /* This data structure is associated with MCA_CONNECT_IND_EVT. */
 typedef struct {
-  BD_ADDR bd_addr; /* The peer address */
+  RawAddress bd_addr; /* The peer address */
   uint16_t mtu;    /* peer mtu */
 } tMCA_CONNECT_IND;
 
 /* This data structure is associated with MCA_DISCONNECT_IND_EVT. */
 typedef struct {
-  BD_ADDR bd_addr; /* The peer address */
+  RawAddress bd_addr; /* The peer address */
   uint16_t reason; /* disconnect reason given by L2CAP */
 } tMCA_DISCONNECT_IND;
 
@@ -332,7 +332,7 @@
  * Returns          MCA_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-extern tMCA_RESULT MCA_ConnectReq(tMCA_HANDLE handle, BD_ADDR bd_addr,
+extern tMCA_RESULT MCA_ConnectReq(tMCA_HANDLE handle, const RawAddress& bd_addr,
                                   uint16_t ctrl_psm, uint16_t sec_mask);
 
 /*******************************************************************************
@@ -525,7 +525,7 @@
   tMCA_RESULT (*create_mdep)(tMCA_HANDLE handle, tMCA_DEP* p_dep,
                              tMCA_CS* p_cs);
   tMCA_RESULT (*delete_mdep)(tMCA_HANDLE handle, tMCA_DEP dep);
-  tMCA_RESULT (*connect_mcl)(tMCA_HANDLE handle, BD_ADDR bd_addr,
+  tMCA_RESULT (*connect_mcl)(tMCA_HANDLE handle, const RawAddress& bd_addr,
                              uint16_t ctrl_psm, uint16_t sec_mask);
   tMCA_RESULT (*disconnect_mcl)(tMCA_CL mcl);
   tMCA_RESULT (*create_mdl_request)(tMCA_CL mcl, tMCA_DEP dep,
diff --git a/stack/include/pan_api.h b/stack/include/pan_api.h
index b4c880c..d46aa3f 100644
--- a/stack/include/pan_api.h
+++ b/stack/include/pan_api.h
@@ -96,7 +96,7 @@
  *      to the application. The second parameter true means
  *      to create the bridge and false means to remove it.
 */
-typedef void(tPAN_CONN_STATE_CB)(uint16_t handle, BD_ADDR bd_addr,
+typedef void(tPAN_CONN_STATE_CB)(uint16_t handle, const RawAddress& bd_addr,
                                  tPAN_RESULT state, bool is_role_change,
                                  uint8_t src_role, uint8_t dst_role);
 
@@ -105,7 +105,7 @@
  *      whether to create the bridge or remove it. true means
  *      to create the bridge and false means to remove it.
 */
-typedef void(tPAN_BRIDGE_REQ_CB)(BD_ADDR bd_addr, bool state);
+typedef void(tPAN_BRIDGE_REQ_CB)(const RawAddress& bd_addr, bool state);
 
 /* Data received indication callback prototype. Parameters are
  *              Source BD/Ethernet Address
@@ -118,9 +118,10 @@
  *                      false - Use it for internal stack
  *                      true  - Send it across the ethernet as well
 */
-typedef void(tPAN_DATA_IND_CB)(uint16_t handle, BD_ADDR src, BD_ADDR dst,
-                               uint16_t protocol, uint8_t* p_data, uint16_t len,
-                               bool ext, bool forward);
+typedef void(tPAN_DATA_IND_CB)(uint16_t handle, const RawAddress& src,
+                               const RawAddress& dst, uint16_t protocol,
+                               uint8_t* p_data, uint16_t len, bool ext,
+                               bool forward);
 
 /* Data buffer received indication callback prototype. Parameters are
  *              Source BD/Ethernet Address
@@ -132,9 +133,9 @@
  *                      false - Use it for internal stack
  *                      true  - Send it across the ethernet as well
 */
-typedef void(tPAN_DATA_BUF_IND_CB)(uint16_t handle, BD_ADDR src, BD_ADDR dst,
-                                   uint16_t protocol, BT_HDR* p_buf, bool ext,
-                                   bool forward);
+typedef void(tPAN_DATA_BUF_IND_CB)(uint16_t handle, const RawAddress& src,
+                                   const RawAddress& dst, uint16_t protocol,
+                                   BT_HDR* p_buf, bool ext, bool forward);
 
 /* Flow control callback for TX data. Parameters are
  *              Handle to the connection
@@ -282,7 +283,7 @@
  *                                     allowed at that point of time
  *
  ******************************************************************************/
-extern tPAN_RESULT PAN_Connect(BD_ADDR rem_bda, uint8_t src_role,
+extern tPAN_RESULT PAN_Connect(const RawAddress& rem_bda, uint8_t src_role,
                                uint8_t dst_role, uint16_t* handle);
 
 /*******************************************************************************
@@ -323,9 +324,9 @@
  *                                           there is an error in sending data
  *
  ******************************************************************************/
-extern tPAN_RESULT PAN_Write(uint16_t handle, BD_ADDR dst, BD_ADDR src,
-                             uint16_t protocol, uint8_t* p_data, uint16_t len,
-                             bool ext);
+extern tPAN_RESULT PAN_Write(uint16_t handle, const RawAddress& dst,
+                             const RawAddress& src, uint16_t protocol,
+                             uint8_t* p_data, uint16_t len, bool ext);
 
 /*******************************************************************************
  *
@@ -349,8 +350,9 @@
  *                                           there is an error in sending data
  *
  ******************************************************************************/
-extern tPAN_RESULT PAN_WriteBuf(uint16_t handle, BD_ADDR dst, BD_ADDR src,
-                                uint16_t protocol, BT_HDR* p_buf, bool ext);
+extern tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst,
+                                const RawAddress& src, uint16_t protocol,
+                                BT_HDR* p_buf, bool ext);
 
 /*******************************************************************************
  *
diff --git a/stack/include/port_api.h b/stack/include/port_api.h
index ac7aeab..7971235 100644
--- a/stack/include/port_api.h
+++ b/stack/include/port_api.h
@@ -196,7 +196,7 @@
  *                                 the peer device (client).
  *                  is_server    - true if requesting application is a server
  *                  mtu          - Maximum frame size the application can accept
- *                  bd_addr      - BD_ADDR of the peer (client)
+ *                  bd_addr      - address of the peer (client)
  *                  mask         - specifies events to be enabled.  A value
  *                                 of zero disables all events.
  *                  p_handle     - OUT pointer to the handle.
@@ -214,7 +214,7 @@
  *
  ******************************************************************************/
 extern int RFCOMM_CreateConnection(uint16_t uuid, uint8_t scn, bool is_server,
-                                   uint16_t mtu, BD_ADDR bd_addr,
+                                   uint16_t mtu, const RawAddress& bd_addr,
                                    uint16_t* p_handle,
                                    tPORT_CALLBACK* p_mgmt_cb);
 
@@ -309,7 +309,7 @@
  *                  p_lcid     - OUT L2CAP's LCID
  *
  ******************************************************************************/
-extern int PORT_CheckConnection(uint16_t handle, BD_ADDR bd_addr,
+extern int PORT_CheckConnection(uint16_t handle, RawAddress& bd_addr,
                                 uint16_t* p_lcid);
 
 /*******************************************************************************
@@ -323,7 +323,7 @@
  *                  bd_addr    - bd_addr of the peer
  *
  ******************************************************************************/
-extern bool PORT_IsOpening(BD_ADDR bd_addr);
+extern bool PORT_IsOpening(RawAddress& bd_addr);
 
 /*******************************************************************************
  *
diff --git a/stack/include/sdp_api.h b/stack/include/sdp_api.h
index a5eead1..72ccd0e 100644
--- a/stack/include/sdp_api.h
+++ b/stack/include/sdp_api.h
@@ -72,7 +72,7 @@
 typedef void(tSDP_DISC_CMPL_CB2)(uint16_t result, void* user_data);
 
 typedef struct {
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
   uint16_t peer_mtu;
 } tSDP_DR_OPEN;
 
@@ -112,7 +112,7 @@
   tSDP_DISC_ATTR* p_first_attr;      /* First attribute of record    */
   struct t_sdp_disc_rec* p_next_rec; /* Addr of next linked record   */
   uint32_t time_read;                /* The time the record was read */
-  BD_ADDR remote_bd_addr;            /* Remote BD address            */
+  RawAddress remote_bd_addr;         /* Remote BD address            */
 } tSDP_DISC_REC;
 
 typedef struct {
@@ -200,8 +200,8 @@
  * Returns          true if discovery started, false if failed.
  *
  ******************************************************************************/
-bool SDP_ServiceSearchRequest(uint8_t* p_bd_addr, tSDP_DISCOVERY_DB* p_db,
-                              tSDP_DISC_CMPL_CB* p_cb);
+bool SDP_ServiceSearchRequest(const RawAddress& p_bd_addr,
+                              tSDP_DISCOVERY_DB* p_db, tSDP_DISC_CMPL_CB* p_cb);
 
 /*******************************************************************************
  *
@@ -216,7 +216,7 @@
  * Returns          true if discovery started, false if failed.
  *
  ******************************************************************************/
-bool SDP_ServiceSearchAttributeRequest(uint8_t* p_bd_addr,
+bool SDP_ServiceSearchAttributeRequest(const RawAddress& p_bd_addr,
                                        tSDP_DISCOVERY_DB* p_db,
                                        tSDP_DISC_CMPL_CB* p_cb);
 
@@ -234,7 +234,7 @@
  * Returns          true if discovery started, false if failed.
  *
  ******************************************************************************/
-bool SDP_ServiceSearchAttributeRequest2(uint8_t* p_bd_addr,
+bool SDP_ServiceSearchAttributeRequest2(const RawAddress& p_bd_addr,
                                         tSDP_DISCOVERY_DB* p_db,
                                         tSDP_DISC_CMPL_CB2* p_cb,
                                         void* user_data);
@@ -583,8 +583,9 @@
  * Returns          SDP_SUCCESS if query started successfully, else error
  *
  ******************************************************************************/
-uint16_t SDP_DiDiscover(BD_ADDR remote_device, tSDP_DISCOVERY_DB* p_db,
-                        uint32_t len, tSDP_DISC_CMPL_CB* p_cb);
+uint16_t SDP_DiDiscover(const RawAddress& remote_device,
+                        tSDP_DISCOVERY_DB* p_db, uint32_t len,
+                        tSDP_DISC_CMPL_CB* p_cb);
 
 /*******************************************************************************
  *
diff --git a/stack/include/smp_api.h b/stack/include/smp_api.h
index 7e84217..10cff74 100644
--- a/stack/include/smp_api.h
+++ b/stack/include/smp_api.h
@@ -75,7 +75,7 @@
  * Returns          SMP_STARTED if bond started, else otherwise exception.
  *
  ******************************************************************************/
-extern tSMP_STATUS SMP_Pair(BD_ADDR bd_addr);
+extern tSMP_STATUS SMP_Pair(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -87,7 +87,7 @@
  *                  failure.
  *
  ******************************************************************************/
-extern tSMP_STATUS SMP_BR_PairWith(BD_ADDR bd_addr);
+extern tSMP_STATUS SMP_BR_PairWith(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -98,7 +98,7 @@
  * Returns          true - pairing cancelled
  *
  ******************************************************************************/
-extern bool SMP_PairCancel(BD_ADDR bd_addr);
+extern bool SMP_PairCancel(const RawAddress& bd_addr);
 
 /*******************************************************************************
  *
@@ -114,7 +114,7 @@
  * Returns          None
  *
  ******************************************************************************/
-extern void SMP_SecurityGrant(BD_ADDR bd_addr, uint8_t res);
+extern void SMP_SecurityGrant(const RawAddress& bd_addr, uint8_t res);
 
 /*******************************************************************************
  *
@@ -130,7 +130,8 @@
  *                             BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
  *
  ******************************************************************************/
-extern void SMP_PasskeyReply(BD_ADDR bd_addr, uint8_t res, uint32_t passkey);
+extern void SMP_PasskeyReply(const RawAddress& bd_addr, uint8_t res,
+                             uint32_t passkey);
 
 /*******************************************************************************
  *
@@ -144,7 +145,7 @@
  *                  res          - comparison result SMP_SUCCESS if success
  *
  ******************************************************************************/
-extern void SMP_ConfirmReply(BD_ADDR bd_addr, uint8_t res);
+extern void SMP_ConfirmReply(const RawAddress& bd_addr, uint8_t res);
 
 /*******************************************************************************
  *
@@ -158,8 +159,8 @@
  *                  p_data      - SM Randomizer  C.
  *
  ******************************************************************************/
-extern void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, uint8_t len,
-                             uint8_t* p_data);
+extern void SMP_OobDataReply(const RawAddress& bd_addr, tSMP_STATUS res,
+                             uint8_t len, uint8_t* p_data);
 
 /*******************************************************************************
  *
@@ -202,7 +203,7 @@
  *                  value        - keypress notification parameter value
  *
  ******************************************************************************/
-extern void SMP_KeypressNotification(BD_ADDR bd_addr, uint8_t value);
+extern void SMP_KeypressNotification(const RawAddress& bd_addr, uint8_t value);
 
 /*******************************************************************************
  *
@@ -220,11 +221,11 @@
     tBLE_BD_ADDR* addr_to_send_to);
 
 // Called when LTK request is received from controller.
-extern bool smp_proc_ltk_request(BD_ADDR bda);
+extern bool smp_proc_ltk_request(const RawAddress& bda);
 
 // Called when link is encrypted and notified to slave device.
 // Proceed to send LTK, DIV and ER to master if bonding the devices.
-extern void smp_link_encrypted(BD_ADDR bda, uint8_t encr_enable);
+extern void smp_link_encrypted(const RawAddress& bda, uint8_t encr_enable);
 
 //
 // The AES-CMAC Generation Function with tlen implemented.
diff --git a/stack/include/smp_api_types.h b/stack/include/smp_api_types.h
index f300ec4..a21af4b 100644
--- a/stack/include/smp_api_types.h
+++ b/stack/include/smp_api_types.h
@@ -270,7 +270,7 @@
 
 /* Security Manager events - Called by the stack when Security Manager related
  * events occur.*/
-typedef uint8_t(tSMP_CALLBACK)(tSMP_EVT event, BD_ADDR bd_addr,
+typedef uint8_t(tSMP_CALLBACK)(tSMP_EVT event, const RawAddress& bd_addr,
                                tSMP_EVT_DATA* p_data);
 
 /* callback function for CMAC algorithm
diff --git a/stack/include/srvc_api.h b/stack/include/srvc_api.h
index 3219e20..9f0e1aa 100644
--- a/stack/include/srvc_api.h
+++ b/stack/include/srvc_api.h
@@ -75,13 +75,13 @@
   uint8_t* data_string[DIS_MAX_STRING_DATA];
 } tDIS_VALUE;
 
-typedef void(tDIS_READ_CBACK)(BD_ADDR addr, tDIS_VALUE* p_dis_value);
+typedef void(tDIS_READ_CBACK)(const RawAddress& addr, tDIS_VALUE* p_dis_value);
 
 /*****************************************************************************
  *  Data structure used by Battery Service
  ****************************************************************************/
 typedef struct {
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   bool need_rsp;
   uint16_t clt_cfg;
 } tBA_WRITE_DATA;
@@ -162,8 +162,8 @@
  * Returns          void
  *
  ******************************************************************************/
-extern bool DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK* p_cback,
-                            tDIS_ATTR_MASK mask);
+extern bool DIS_ReadDISInfo(const RawAddress& peer_bda,
+                            tDIS_READ_CBACK* p_cback, tDIS_ATTR_MASK mask);
 
 /*******************************************************************************
  *      BATTERY SERVICE API
@@ -193,7 +193,7 @@
  * Description      Send battery level notification
  *
  ******************************************************************************/
-extern void Battery_Notify(uint8_t app_id, BD_ADDR remote_bda,
+extern void Battery_Notify(uint8_t app_id, const RawAddress& remote_bda,
                            uint8_t battery_level);
 
 #endif
diff --git a/stack/l2cap/l2c_api.cc b/stack/l2cap/l2c_api.cc
index d85bea4..809199f 100644
--- a/stack/l2cap/l2c_api.cc
+++ b/stack/l2cap/l2c_api.cc
@@ -25,6 +25,7 @@
 #define LOG_TAG "bt_l2cap"
 
 #include <base/logging.h>
+#include <base/strings/stringprintf.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -41,7 +42,7 @@
 #include "osi/include/allocator.h"
 #include "osi/include/log.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
+using base::StringPrintf;
 
 /*******************************************************************************
  *
@@ -204,7 +205,7 @@
  * Returns          the CID of the connection, or 0 if it failed to start
  *
  ******************************************************************************/
-uint16_t L2CA_ConnectReq(uint16_t psm, BD_ADDR p_bd_addr) {
+uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) {
   return L2CA_ErtmConnectReq(psm, p_bd_addr, NULL);
 }
 
@@ -225,20 +226,16 @@
  * Returns          the CID of the connection, or 0 if it failed to start
  *
  ******************************************************************************/
-uint16_t L2CA_ErtmConnectReq(uint16_t psm, BD_ADDR p_bd_addr,
+uint16_t L2CA_ErtmConnectReq(uint16_t psm, const RawAddress& p_bd_addr,
                              tL2CAP_ERTM_INFO* p_ertm_info) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
   tL2C_RCB* p_rcb;
 
-  L2CAP_TRACE_API(
-      "L2CA_ErtmConnectReq()  PSM: 0x%04x  BDA: %08x%04x  p_ertm_info: 0x%08x "
-      "allowed:0x%x preferred:%d",
-      psm, (p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) + (p_bd_addr[2] << 8) +
-               p_bd_addr[3],
-      (p_bd_addr[4] << 8) + p_bd_addr[5], p_ertm_info,
-      (p_ertm_info) ? p_ertm_info->allowed_modes : 0,
-      (p_ertm_info) ? p_ertm_info->preferred_mode : 0);
+  VLOG(1) << __func__ << "BDA " << p_bd_addr
+          << StringPrintf(" PSM: 0x%04x allowed:0x%x preferred:%d", psm,
+                          (p_ertm_info) ? p_ertm_info->allowed_modes : 0,
+                          (p_ertm_info) ? p_ertm_info->preferred_mode : 0);
 
   /* Fail if we have not established communications with the controller */
   if (!BTM_IsDeviceUp()) {
@@ -443,11 +440,10 @@
  * Returns          the CID of the connection, or 0 if it failed to start
  *
  ******************************************************************************/
-uint16_t L2CA_ConnectLECocReq(uint16_t psm, BD_ADDR p_bd_addr,
+uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr,
                               tL2CAP_LE_CFG_INFO* p_cfg) {
-  L2CAP_TRACE_API("%s PSM: 0x%04x BDA: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
-                  psm, p_bd_addr[0], p_bd_addr[1], p_bd_addr[2], p_bd_addr[3],
-                  p_bd_addr[4], p_bd_addr[5]);
+  VLOG(1) << __func__ << " BDA: " << p_bd_addr
+          << StringPrintf(" PSM: 0x%04x", psm);
 
   /* Fail if we have not established communications with the controller */
   if (!BTM_IsDeviceUp()) {
@@ -528,13 +524,12 @@
  * Returns          true for success, false for failure
  *
  ******************************************************************************/
-bool L2CA_ConnectLECocRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
-                          uint16_t result, uint16_t status,
+bool L2CA_ConnectLECocRsp(const RawAddress& p_bd_addr, uint8_t id,
+                          uint16_t lcid, uint16_t result, uint16_t status,
                           tL2CAP_LE_CFG_INFO* p_cfg) {
-  L2CAP_TRACE_API(
-      "%s CID: 0x%04x Result: %d Status: %d BDA: %02x:%02x:%02x:%02x:%02x:%02x",
-      __func__, lcid, result, status, p_bd_addr[0], p_bd_addr[1], p_bd_addr[2],
-      p_bd_addr[3], p_bd_addr[4], p_bd_addr[5]);
+  VLOG(1) << __func__ << " BDA: " << p_bd_addr
+          << StringPrintf(" CID: 0x%04x Result: %d Status: %d", lcid, result,
+                          status);
 
   /* First, find the link control block */
   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE);
@@ -564,7 +559,7 @@
     l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL);
   else {
     tL2C_CONN_INFO conn_info;
-    memcpy(conn_info.bd_addr, p_bd_addr, BD_ADDR_LEN);
+    conn_info.bd_addr = p_bd_addr;
     conn_info.l2cap_result = result;
     conn_info.l2cap_status = status;
     l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP_NEG, &conn_info);
@@ -650,7 +645,7 @@
  * Returns          true for success, false for failure
  *
  ******************************************************************************/
-bool L2CA_ConnectRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
+bool L2CA_ConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid,
                      uint16_t result, uint16_t status) {
   return L2CA_ErtmConnectRsp(p_bd_addr, id, lcid, result, status, NULL);
 }
@@ -666,18 +661,15 @@
  * Returns          true for success, false for failure
  *
  ******************************************************************************/
-bool L2CA_ErtmConnectRsp(BD_ADDR p_bd_addr, uint8_t id, uint16_t lcid,
+bool L2CA_ErtmConnectRsp(const RawAddress& p_bd_addr, uint8_t id, uint16_t lcid,
                          uint16_t result, uint16_t status,
                          tL2CAP_ERTM_INFO* p_ertm_info) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
 
-  L2CAP_TRACE_API(
-      "L2CA_ErtmConnectRsp()  CID: 0x%04x  Result: %d  Status: %d  BDA: "
-      "%08x%04x  p_ertm_info:0x%08x",
-      lcid, result, status, (p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) +
-                                (p_bd_addr[2] << 8) + p_bd_addr[3],
-      (p_bd_addr[4] << 8) + p_bd_addr[5], p_ertm_info);
+  VLOG(1) << __func__ << " BDA: " << p_bd_addr
+          << StringPrintf(" CID:0x%04x  Result:%d  Status:%d", lcid, result,
+                          status);
 
   /* First, find the link control block */
   p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR);
@@ -895,12 +887,10 @@
  * Returns          true if echo request sent, else false.
  *
  ******************************************************************************/
-bool L2CA_Ping(BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB* p_callback) {
+bool L2CA_Ping(const RawAddress& p_bd_addr, tL2CA_ECHO_RSP_CB* p_callback) {
   tL2C_LCB* p_lcb;
 
-  L2CAP_TRACE_API("L2CA_Ping()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
-                  p_bd_addr[0], p_bd_addr[1], p_bd_addr[2], p_bd_addr[3],
-                  p_bd_addr[4], p_bd_addr[5]);
+  VLOG(1) << __func__ << " BDA: " << p_bd_addr;
 
   /* Fail if we have not established communications with the controller */
   if (!BTM_IsDeviceUp()) return (false);
@@ -942,8 +932,8 @@
   if (p_lcb->link_state == LST_CONNECTED) {
     l2cu_adj_id(p_lcb, L2CAP_ADJ_BRCM_ID); /* Make sure not using Broadcom ID */
     l2cu_send_peer_echo_req(p_lcb, NULL, 0);
-    alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_ECHO_RSP_TIMEOUT_MS,
-                       l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_ECHO_RSP_TIMEOUT_MS,
+                       l2c_lcb_timer_timeout, p_lcb);
   }
 
   return (true);
@@ -959,20 +949,18 @@
  * Returns          true if echo request sent, else false.
  *
  ******************************************************************************/
-bool L2CA_Echo(BD_ADDR p_bd_addr, BT_HDR* p_data,
+bool L2CA_Echo(const RawAddress& p_bd_addr, BT_HDR* p_data,
                tL2CA_ECHO_DATA_CB* p_callback) {
   tL2C_LCB* p_lcb;
   uint8_t* pp;
 
-  L2CAP_TRACE_API("L2CA_Echo() BDA: %08X%04X",
-                  ((p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) +
-                   (p_bd_addr[2] << 8) + (p_bd_addr[3])),
-                  ((p_bd_addr[4] << 8) + (p_bd_addr[5])));
+  VLOG(1) << __func__ << " BDA: " << p_bd_addr;
+  ;
 
   /* Fail if we have not established communications with the controller */
   if (!BTM_IsDeviceUp()) return (false);
 
-  if ((memcmp(BT_BD_ANY, p_bd_addr, BD_ADDR_LEN) == 0) && (p_data == NULL)) {
+  if (RawAddress::kAny == p_bd_addr && (p_data == NULL)) {
     /* Only register callback without sending message. */
     l2cb.p_echo_data_cb = p_callback;
     return true;
@@ -1067,20 +1055,20 @@
  *                  A timeout of zero means that the connection will be torn
  *                  down immediately when the last channel is removed.
  *                  A timeout of 0xFFFF means no timeout. Values are in seconds.
- *                  A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
- *                  then the idle timeouts for all active l2cap links will be
- *                  changed.
+ *                  A bd_addr is the remote BD address. If bd_addr =
+ *                  RawAddress::kAny, then the idle timeouts for all active
+ *                  l2cap links will be changed.
  *
  * Returns          true if command succeeded, false if failed
  *
  * NOTE             This timeout applies to all logical channels active on the
  *                  ACL link.
  ******************************************************************************/
-bool L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, uint16_t timeout,
+bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout,
                                  tBT_TRANSPORT transport) {
   tL2C_LCB* p_lcb;
 
-  if (memcmp(BT_BD_ANY, bd_addr, BD_ADDR_LEN)) {
+  if (RawAddress::kAny != bd_addr) {
     p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, transport);
     if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
       p_lcb->idle_timeout = timeout;
@@ -1167,7 +1155,7 @@
  *
  ******************************************************************************/
 uint16_t L2CA_LocalLoopbackReq(uint16_t psm, uint16_t handle,
-                               BD_ADDR p_bd_addr) {
+                               const RawAddress& p_bd_addr) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
   tL2C_RCB* p_rcb;
@@ -1225,12 +1213,8 @@
  * Returns          true if a valid channel, else false
  *
  ******************************************************************************/
-bool L2CA_SetAclPriority(BD_ADDR bd_addr, uint8_t priority) {
-  L2CAP_TRACE_API(
-      "L2CA_SetAclPriority()  bdaddr: %02x%02x%02x%02x%04x, priority:%d",
-      bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3],
-      (bd_addr[4] << 8) + bd_addr[5], priority);
-
+bool L2CA_SetAclPriority(const RawAddress& bd_addr, uint8_t priority) {
+  VLOG(1) << __func__ << " BDA: " << bd_addr << ", priority: " << priority;
   return (l2cu_set_acl_priority(bd_addr, priority, false));
 }
 
@@ -1391,7 +1375,7 @@
  *                           L2CAP_NO_RETRANSMISSION : No retransmission
  *                           0x0002 - 0xFFFE : flush time out, if
  *                                            (flush_tout * 8) + 3 / 5) <=
- *                                             HCI_MAX_AUTO_FLUSH_TOUT
+ *                                             HCI_MAX_AUTOMATIC_FLUSH_TIMEOUT
  *                                            (in 625us slot).
  *                                    Otherwise, return false.
  *                           L2CAP_NO_AUTOMATIC_FLUSH : No automatic flush
@@ -1401,7 +1385,7 @@
  * NOTE             This flush timeout applies to all logical channels active on
  *                  the ACL link.
  ******************************************************************************/
-bool L2CA_SetFlushTimeout(BD_ADDR bd_addr, uint16_t flush_tout) {
+bool L2CA_SetFlushTimeout(const RawAddress& bd_addr, uint16_t flush_tout) {
   tL2C_LCB* p_lcb;
   uint16_t hci_flush_to;
   uint32_t temp;
@@ -1426,7 +1410,7 @@
     temp = (((uint32_t)flush_tout * 8) + 3) / 5;
 
     /* if L2CAP flush_to within range of HCI, set HCI flush timeout */
-    if (temp > HCI_MAX_AUTO_FLUSH_TOUT) {
+    if (temp > HCI_MAX_AUTOMATIC_FLUSH_TIMEOUT) {
       L2CAP_TRACE_WARNING(
           "WARNING L2CA_SetFlushTimeout timeout(0x%x) is out of range",
           flush_tout);
@@ -1436,23 +1420,19 @@
     }
   }
 
-  if (memcmp(BT_BD_ANY, bd_addr, BD_ADDR_LEN)) {
+  if (RawAddress::kAny != bd_addr) {
     p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
 
     if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED)) {
       if (p_lcb->link_flush_tout != flush_tout) {
         p_lcb->link_flush_tout = flush_tout;
 
-        L2CAP_TRACE_API(
-            "L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
-            flush_tout, bd_addr[3], bd_addr[4], bd_addr[5]);
+        VLOG(1) << __func__ << " BDA: " << bd_addr << " " << flush_tout << "ms";
 
         btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to);
       }
     } else {
-      L2CAP_TRACE_WARNING(
-          "WARNING L2CA_SetFlushTimeout No lcb for bd_addr [...;%02x%02x%02x]",
-          bd_addr[3], bd_addr[4], bd_addr[5]);
+      LOG(WARNING) << __func__ << " No lcb for bd_addr " << bd_addr;
       return (false);
     }
   } else {
@@ -1464,10 +1444,8 @@
         if (p_lcb->link_flush_tout != flush_tout) {
           p_lcb->link_flush_tout = flush_tout;
 
-          L2CAP_TRACE_API(
-              "L2CA_SetFlushTimeout 0x%04x ms for bd_addr [...;%02x%02x%02x]",
-              flush_tout, p_lcb->remote_bd_addr[3], p_lcb->remote_bd_addr[4],
-              p_lcb->remote_bd_addr[5]);
+          VLOG(1) << __func__ << " BDA: " << p_lcb->remote_bd_addr << " "
+                  << flush_tout << "ms";
 
           btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to);
         }
@@ -1490,32 +1468,26 @@
  *  Return value:    true if peer is connected
  *
  ******************************************************************************/
-bool L2CA_GetPeerFeatures(BD_ADDR bd_addr, uint32_t* p_ext_feat,
+bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat,
                           uint8_t* p_chnl_mask) {
   tL2C_LCB* p_lcb;
 
   /* We must already have a link to the remote */
   p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
   if (p_lcb == NULL) {
-    L2CAP_TRACE_WARNING("L2CA_GetPeerFeatures() No BDA: %08x%04x",
-                        (bd_addr[0] << 24) + (bd_addr[1] << 16) +
-                            (bd_addr[2] << 8) + bd_addr[3],
-                        (bd_addr[4] << 8) + bd_addr[5]);
-    return (false);
+    LOG(WARNING) << __func__ << " No BDA: " << bd_addr;
+    return false;
   }
 
-  L2CAP_TRACE_API(
-      "L2CA_GetPeerFeatures() BDA: %08x%04x  ExtFea: 0x%08x  Chnl_Mask[0]: "
-      "0x%02x",
-      (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
-      (bd_addr[4] << 8) + bd_addr[5], p_lcb->peer_ext_fea,
-      p_lcb->peer_chnl_mask[0]);
+  VLOG(1) << __func__ << " BDA: " << bd_addr
+          << StringPrintf(" ExtFea: 0x%08x Chnl_Mask[0]: 0x%02x",
+                          p_lcb->peer_ext_fea, p_lcb->peer_chnl_mask[0]);
 
   *p_ext_feat = p_lcb->peer_ext_fea;
 
   memcpy(p_chnl_mask, p_lcb->peer_chnl_mask, L2CAP_FIXED_CHNL_ARRAY_SIZE);
 
-  return (true);
+  return true;
 }
 
 /*******************************************************************************
@@ -1530,14 +1502,14 @@
  *  Return value:    true if found lcb for the given handle, false otherwise
  *
  ******************************************************************************/
-bool L2CA_GetBDAddrbyHandle(uint16_t handle, BD_ADDR bd_addr) {
+bool L2CA_GetBDAddrbyHandle(uint16_t handle, RawAddress& bd_addr) {
   tL2C_LCB* p_lcb = NULL;
   bool found_dev = false;
 
   p_lcb = l2cu_find_lcb_by_handle(handle);
   if (p_lcb) {
     found_dev = true;
-    memcpy(bd_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
+    bd_addr = p_lcb->remote_bd_addr;
   }
 
   return found_dev;
@@ -1606,20 +1578,18 @@
  *  Return value:   true if connection started
  *
  ******************************************************************************/
-bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda) {
+bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
   uint8_t phy = controller_get_interface()->get_le_all_initiating_phys();
   return L2CA_ConnectFixedChnl(fixed_cid, rem_bda, phy);
 }
 
-bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda,
+bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda,
                            uint8_t initiating_phys) {
   tL2C_LCB* p_lcb;
   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
 
-  L2CAP_TRACE_API(
-      "%s() CID: 0x%04x  BDA: %08x%04x", __func__, fixed_cid,
-      (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
-      (rem_bda[4] << 8) + rem_bda[5]);
+  VLOG(1) << __func__ << " BDA: " << rem_bda
+          << StringPrintf("CID: 0x%04x ", fixed_cid);
 
   // Check CID is valid and registered
   if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) ||
@@ -1654,11 +1624,8 @@
 
     // Check for supported channel
     if (!(peer_channel_mask & (1 << fixed_cid))) {
-      L2CAP_TRACE_EVENT("%s() CID:0x%04x  BDA: %08x%04x not supported",
-                        __func__, fixed_cid,
-                        (rem_bda[0] << 24) + (rem_bda[1] << 16) +
-                            (rem_bda[2] << 8) + rem_bda[3],
-                        (rem_bda[4] << 8) + rem_bda[5]);
+      VLOG(2) << __func__ << " BDA " << rem_bda
+              << StringPrintf(" CID:0x%04x not supported", fixed_cid);
       return false;
     }
 
@@ -1724,15 +1691,13 @@
  *                  L2CAP_DW_FAILED,  if error
  *
  ******************************************************************************/
-uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, BD_ADDR rem_bda,
+uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda,
                                 BT_HDR* p_buf) {
   tL2C_LCB* p_lcb;
   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
 
-  L2CAP_TRACE_API(
-      "L2CA_SendFixedChnlData()  CID: 0x%04x  BDA: %08x%04x", fixed_cid,
-      (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
-      (rem_bda[4] << 8) + rem_bda[5]);
+  VLOG(2) << __func__ << " BDA: " << rem_bda
+          << StringPrintf(" CID: 0x%04x", fixed_cid);
 
   if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
     transport = BT_TRANSPORT_LE;
@@ -1840,7 +1805,7 @@
  *  Return value:   true if channel removed
  *
  ******************************************************************************/
-bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, BD_ADDR rem_bda) {
+bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
@@ -1862,18 +1827,13 @@
 
   if (((p_lcb) == NULL) ||
       (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL])) {
-    L2CAP_TRACE_WARNING(
-        "L2CA_RemoveFixedChnl()  CID: 0x%04x  BDA: %08x%04x not connected",
-        fixed_cid, (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) +
-                       rem_bda[3],
-        (rem_bda[4] << 8) + rem_bda[5]);
+    LOG(WARNING) << __func__ << " BDA: " << rem_bda
+                 << StringPrintf(" CID: 0x%04x not connected", fixed_cid);
     return (false);
   }
 
-  L2CAP_TRACE_API(
-      "L2CA_RemoveFixedChnl()  CID: 0x%04x  BDA: %08x%04x", fixed_cid,
-      (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
-      (rem_bda[4] << 8) + rem_bda[5]);
+  VLOG(2) << __func__ << " BDA: " << rem_bda
+          << StringPrintf(" CID: 0x%04x", fixed_cid);
 
   /* Release the CCB, starting an inactivity timeout on the LCB if no other CCBs
    * exist */
@@ -1906,14 +1866,12 @@
  *                  it. A timeout of zero means that the connection will be torn
  *                  down immediately when the last channel is removed.
  *                  A timeout of 0xFFFF means no timeout. Values are in seconds.
- *                  A bd_addr is the remote BD address. If bd_addr = BT_BD_ANY,
- *                  then the idle timeouts for all active l2cap links will be
- *                  changed.
+ *                  A bd_addr is the remote BD address.
  *
  * Returns          true if command succeeded, false if failed
  *
  ******************************************************************************/
-bool L2CA_SetFixedChannelTout(BD_ADDR rem_bda, uint16_t fixed_cid,
+bool L2CA_SetFixedChannelTout(const RawAddress& rem_bda, uint16_t fixed_cid,
                               uint16_t idle_tout) {
   tL2C_LCB* p_lcb;
   tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
@@ -1925,11 +1883,8 @@
   p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport);
   if (((p_lcb) == NULL) ||
       (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL])) {
-    L2CAP_TRACE_WARNING(
-        "L2CA_SetFixedChannelTout()  CID: 0x%04x  BDA: %08x%04x not connected",
-        fixed_cid, (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) +
-                       rem_bda[3],
-        (rem_bda[4] << 8) + rem_bda[5]);
+    LOG(WARNING) << __func__ << " BDA: " << rem_bda
+                 << StringPrintf(" CID: 0x%04x not connected", fixed_cid);
     return (false);
   }
 
@@ -2037,7 +1992,7 @@
  * Returns          true if registered OK, else false
  *
  ******************************************************************************/
-bool L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, BD_ADDR p_bda) {
+bool L2CA_RegForNoCPEvt(tL2CA_NOCP_CB* p_cb, const RawAddress& p_bda) {
   tL2C_LCB* p_lcb;
 
   /* Find the link that is associated with this remote bdaddr */
diff --git a/stack/l2cap/l2c_ble.cc b/stack/l2cap/l2c_ble.cc
index dc8cda0..078f75f 100644
--- a/stack/l2cap/l2c_ble.cc
+++ b/stack/l2cap/l2c_ble.cc
@@ -22,6 +22,8 @@
  *
  ******************************************************************************/
 
+#include <base/logging.h>
+#include <base/strings/stringprintf.h>
 #include <string.h>
 #include "bt_target.h"
 #include "bt_utils.h"
@@ -35,7 +37,7 @@
 #include "osi/include/osi.h"
 #include "stack_config.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
+using base::StringPrintf;
 
 static void l2cble_start_conn_update(tL2C_LCB* p_lcb);
 
@@ -50,7 +52,7 @@
  *  Return value:   true if connection was cancelled
  *
  ******************************************************************************/
-bool L2CA_CancelBleConnectReq(BD_ADDR rem_bda) {
+bool L2CA_CancelBleConnectReq(const RawAddress& rem_bda) {
   tL2C_LCB* p_lcb;
 
   /* There can be only one BLE connection request outstanding at a time */
@@ -59,16 +61,11 @@
     return (false);
   }
 
-  if (memcmp(rem_bda, l2cb.ble_connecting_bda, BD_ADDR_LEN)) {
-    L2CAP_TRACE_WARNING(
-        "%s - different  BDA Connecting: %08x%04x  Cancel: %08x%04x", __func__,
-        (l2cb.ble_connecting_bda[0] << 24) +
-            (l2cb.ble_connecting_bda[1] << 16) +
-            (l2cb.ble_connecting_bda[2] << 8) + l2cb.ble_connecting_bda[3],
-        (l2cb.ble_connecting_bda[4] << 8) + l2cb.ble_connecting_bda[5],
-        (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) +
-            rem_bda[3],
-        (rem_bda[4] << 8) + rem_bda[5]);
+  if (rem_bda != l2cb.ble_connecting_bda) {
+    LOG(WARNING) << __func__
+                 << " different BDA Connecting: " << l2cb.ble_connecting_bda
+                 << " Cancel: " << rem_bda;
+
     btm_ble_dequeue_direct_conn_req(rem_bda);
     return (false);
   }
@@ -100,7 +97,7 @@
  *  Return value:   true if update started
  *
  ******************************************************************************/
-bool L2CA_UpdateBleConnParams(BD_ADDR rem_bda, uint16_t min_int,
+bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int,
                               uint16_t max_int, uint16_t latency,
                               uint16_t timeout) {
   tL2C_LCB* p_lcb;
@@ -111,18 +108,12 @@
 
   /* If we don't have one, create one and accept the connection. */
   if (!p_lcb || !p_acl_cb) {
-    L2CAP_TRACE_WARNING("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
-                        (rem_bda[0] << 24) + (rem_bda[1] << 16) +
-                            (rem_bda[2] << 8) + rem_bda[3],
-                        (rem_bda[4] << 8) + rem_bda[5]);
+    LOG(WARNING) << __func__ << " - unknown BD_ADDR " << rem_bda;
     return (false);
   }
 
   if (p_lcb->transport != BT_TRANSPORT_LE) {
-    L2CAP_TRACE_WARNING("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
-                        (rem_bda[0] << 24) + (rem_bda[1] << 16) +
-                            (rem_bda[2] << 8) + rem_bda[3],
-                        (rem_bda[4] << 8) + rem_bda[5]);
+    LOG(WARNING) << __func__ << " - BD_ADDR " << rem_bda << " not LE";
     return (false);
   }
 
@@ -148,7 +139,7 @@
  *  Return value:   true if update started
  *
  ******************************************************************************/
-bool L2CA_EnableUpdateBleConnParams(BD_ADDR rem_bda, bool enable) {
+bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable) {
   if (stack_config_get_interface()->get_pts_conn_updates_disabled())
     return false;
 
@@ -158,25 +149,18 @@
   p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE);
 
   if (!p_lcb) {
-    L2CAP_TRACE_WARNING(
-        "L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x",
-        (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) +
-            rem_bda[3],
-        (rem_bda[4] << 8) + rem_bda[5]);
-    return (false);
+    LOG(WARNING) << __func__ << " - unknown BD_ADDR " << rem_bda;
+    return false;
   }
 
-  L2CAP_TRACE_API(
-      "%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x", __func__,
-      (rem_bda[0] << 24) + (rem_bda[1] << 16) + (rem_bda[2] << 8) + rem_bda[3],
-      (rem_bda[4] << 8) + rem_bda[5], enable, p_lcb->conn_update_mask);
+  VLOG(2) << __func__ << " - BD_ADDR " << rem_bda
+          << StringPrintf(" enable %d current upd state 0x%02x", enable,
+                          p_lcb->conn_update_mask);
 
   if (p_lcb->transport != BT_TRANSPORT_LE) {
-    L2CAP_TRACE_WARNING("%s - BD_ADDR %08x%04x not LE (link role %d)", __func__,
-                        (rem_bda[0] << 24) + (rem_bda[1] << 16) +
-                            (rem_bda[2] << 8) + rem_bda[3],
-                        (rem_bda[4] << 8) + rem_bda[5], p_lcb->link_role);
-    return (false);
+    LOG(WARNING) << __func__ << " - BD_ADDR " << rem_bda
+                 << " not LE, link role " << p_lcb->link_role;
+    return false;
   }
 
   if (enable)
@@ -198,7 +182,7 @@
  * Returns          link role.
  *
  ******************************************************************************/
-uint8_t L2CA_GetBleConnRole(BD_ADDR bd_addr) {
+uint8_t L2CA_GetBleConnRole(const RawAddress& bd_addr) {
   uint8_t role = HCI_ROLE_UNKNOWN;
 
   tL2C_LCB* p_lcb;
@@ -217,7 +201,8 @@
  * Returns          disconnect reason
  *
  ******************************************************************************/
-uint16_t L2CA_GetDisconnectReason(BD_ADDR remote_bda, tBT_TRANSPORT transport) {
+uint16_t L2CA_GetDisconnectReason(const RawAddress& remote_bda,
+                                  tBT_TRANSPORT transport) {
   tL2C_LCB* p_lcb;
   uint16_t reason = 0;
 
@@ -238,7 +223,7 @@
  * Returns none
  *
  ******************************************************************************/
-void l2cble_notify_le_connection(BD_ADDR bda) {
+void l2cble_notify_le_connection(const RawAddress& bda) {
   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
   tACL_CONN* p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE);
   tL2C_CCB* p_ccb;
@@ -271,9 +256,9 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2cble_scanner_conn_comp(uint16_t handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
-                              uint16_t conn_interval, uint16_t conn_latency,
-                              uint16_t conn_timeout) {
+void l2cble_scanner_conn_comp(uint16_t handle, const RawAddress& bda,
+                              tBLE_ADDR_TYPE type, uint16_t conn_interval,
+                              uint16_t conn_latency, uint16_t conn_timeout) {
   tL2C_LCB* p_lcb;
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda);
 
@@ -354,7 +339,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2cble_advertiser_conn_comp(uint16_t handle, BD_ADDR bda,
+void l2cble_advertiser_conn_comp(uint16_t handle, const RawAddress& bda,
                                  UNUSED_ATTR tBLE_ADDR_TYPE type,
                                  UNUSED_ATTR uint16_t conn_interval,
                                  UNUSED_ATTR uint16_t conn_latency,
@@ -419,8 +404,7 @@
   }
 
   /* when adv and initiating are both active, cancel the direct connection */
-  if (l2cb.is_ble_connecting &&
-      memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0) {
+  if (l2cb.is_ble_connecting && bda == l2cb.ble_connecting_bda) {
     L2CA_CancelBleConnectReq(bda);
   }
 }
@@ -435,7 +419,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2cble_conn_comp(uint16_t handle, uint8_t role, BD_ADDR bda,
+void l2cble_conn_comp(uint16_t handle, uint8_t role, const RawAddress& bda,
                       tBLE_ADDR_TYPE type, uint16_t conn_interval,
                       uint16_t conn_latency, uint16_t conn_timeout) {
   btm_ble_update_link_topology_mask(role, true);
@@ -464,6 +448,10 @@
 static void l2cble_start_conn_update(tL2C_LCB* p_lcb) {
   uint16_t min_conn_int, max_conn_int, slave_latency, supervision_tout;
   tACL_CONN* p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
+  if (!p_acl_cb) {
+    LOG(ERROR) << "No known connection ACL for " << p_lcb->remote_bd_addr;
+    return;
+  }
 
   // TODO(armansito): The return value of this call wasn't being used but the
   // logic of this function might be depending on its side effects. We should
@@ -694,7 +682,8 @@
       if (p_ccb) {
         L2CAP_TRACE_WARNING("L2CAP - rcvd conn req for duplicated cid: 0x%04x",
                             rcid);
-        l2cu_reject_ble_connection(p_lcb, id, L2CAP_LE_SOURCE_CID_ALREADY_ALLOCATED);
+        l2cu_reject_ble_connection(p_lcb, id,
+                                   L2CAP_LE_SOURCE_CID_ALREADY_ALLOCATED);
         break;
       }
 
@@ -885,7 +874,7 @@
   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
   uint16_t scan_int;
   uint16_t scan_win;
-  BD_ADDR peer_addr;
+  RawAddress peer_addr;
   uint8_t peer_addr_type = BLE_ADDR_PUBLIC;
   uint8_t own_addr_type = BLE_ADDR_PUBLIC;
 
@@ -903,7 +892,7 @@
                  : p_cb->scan_win;
 
   peer_addr_type = p_lcb->ble_addr_type;
-  memcpy(peer_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
+  peer_addr = p_lcb->remote_bd_addr;
 
 #if (BLE_PRIVACY_SPT == TRUE)
   own_addr_type =
@@ -913,13 +902,13 @@
       own_addr_type |= BLE_ADDR_TYPE_ID_BIT;
 
     btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
-    btm_random_pseudo_to_identity_addr(peer_addr, &peer_addr_type);
+    btm_random_pseudo_to_identity_addr(&peer_addr, &peer_addr_type);
   } else {
     btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, true);
 
     // If we have a current RPA, use that instead.
-    if (!bdaddr_is_empty((const bt_bdaddr_t*)p_dev_rec->ble.cur_rand_addr)) {
-      memcpy(peer_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
+    if (!p_dev_rec->ble.cur_rand_addr.IsEmpty()) {
+      peer_addr = p_dev_rec->ble.cur_rand_addr;
     }
   }
 #endif
@@ -959,9 +948,9 @@
 
   p_lcb->link_state = LST_CONNECTING;
   l2cb.is_ble_connecting = true;
-  memcpy(l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
-  alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_BLE_LINK_CONNECT_TIMEOUT_MS,
-                     l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+  l2cb.ble_connecting_bda = p_lcb->remote_bd_addr;
+  alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_BLE_LINK_CONNECT_TIMEOUT_MS,
+                     l2c_lcb_timer_timeout, p_lcb);
   btm_ble_set_conn_st(BLE_DIR_CONN);
 
   return (true);
@@ -1128,9 +1117,9 @@
       if ((p_lcb->link_state == LST_CONNECTED) &&
           (!list_is_empty(p_lcb->link_xmit_data_q)) &&
           (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
-        alarm_set_on_queue(
-            p_lcb->l2c_lcb_timer, L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
-            l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+        alarm_set_on_mloop(p_lcb->l2c_lcb_timer,
+                           L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
+                           l2c_lcb_timer_timeout, p_lcb);
       }
     }
   }
@@ -1239,7 +1228,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda,
+void l2cble_set_fixed_channel_tx_data_length(const RawAddress& remote_bda,
                                              uint16_t fix_cid,
                                              uint16_t tx_mtu) {
   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(remote_bda, BT_TRANSPORT_LE);
@@ -1363,8 +1352,9 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2cble_sec_comp(BD_ADDR p_bda, tBT_TRANSPORT transport, void* p_ref_data,
-                     uint8_t status) {
+void l2cble_sec_comp(const RawAddress* bda, tBT_TRANSPORT transport,
+                     void* p_ref_data, uint8_t status) {
+  const RawAddress& p_bda = *bda;
   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, BT_TRANSPORT_LE);
   tL2CAP_SEC_DATA* p_buf = NULL;
   uint8_t sec_flag;
@@ -1439,8 +1429,9 @@
  *                  false - failure
  *
  ******************************************************************************/
-bool l2ble_sec_access_req(BD_ADDR bd_addr, uint16_t psm, bool is_originator,
-                          tL2CAP_SEC_CBACK* p_callback, void* p_ref_data) {
+bool l2ble_sec_access_req(const RawAddress& bd_addr, uint16_t psm,
+                          bool is_originator, tL2CAP_SEC_CBACK* p_callback,
+                          void* p_ref_data) {
   L2CAP_TRACE_DEBUG("%s", __func__);
   bool status;
   tL2C_LCB* p_lcb = NULL;
diff --git a/stack/l2cap/l2c_csm.cc b/stack/l2cap/l2c_csm.cc
index 7c36286..66033ee 100644
--- a/stack/l2cap/l2c_csm.cc
+++ b/stack/l2cap/l2c_csm.cc
@@ -35,8 +35,6 @@
 #include "l2c_int.h"
 #include "l2cdefs.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
@@ -169,7 +167,7 @@
       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
         p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
         l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
-                             true, &l2c_link_sec_comp, p_ccb);
+                             true, &l2c_link_sec_comp2, p_ccb);
       } else {
         p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
         btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
@@ -194,7 +192,7 @@
       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
         p_ccb->chnl_state = CST_ORIG_W4_SEC_COMP;
         l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
-                             true, &l2c_link_sec_comp, p_ccb);
+                             true, &l2c_link_sec_comp2, p_ccb);
       } else {
         /* Cancel sniff mode if needed */
         {
@@ -229,9 +227,9 @@
                                                    L2CAP_CONN_NO_LINK);
         } else {
           l2cu_send_peer_connect_req(p_ccb);
-          alarm_set_on_queue(
-              p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
-              l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+          alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
+                             L2CAP_CHNL_CONNECT_TIMEOUT_MS,
+                             l2c_ccb_timer_timeout, p_ccb);
         }
       }
       break;
@@ -252,7 +250,7 @@
       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
         p_ccb->chnl_state = CST_TERM_W4_SEC_COMP;
         l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
-                             false, &l2c_link_sec_comp, p_ccb);
+                             false, &l2c_link_sec_comp2, p_ccb);
       } else {
         /* Cancel sniff mode if needed */
         {
@@ -343,7 +341,7 @@
     case L2CEVT_LP_CONNECT_CFM:  /* Link came up         */
       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
         l2ble_sec_access_req(p_ccb->p_lcb->remote_bd_addr, p_ccb->p_rcb->psm,
-                             false, &l2c_link_sec_comp, p_ccb);
+                             false, &l2c_link_sec_comp2, p_ccb);
       } else {
         btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr,
                                  p_ccb->p_rcb->psm, p_ccb->p_lcb->handle, true,
@@ -356,9 +354,8 @@
        * needed) */
       p_ccb->chnl_state = CST_W4_L2CAP_CONNECT_RSP;
       if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) {
-        alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
-                           l2c_ccb_timer_timeout, p_ccb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
+                           l2c_ccb_timer_timeout, p_ccb);
         l2cble_credit_based_conn_req(p_ccb); /* Start Connection     */
       } else {
         if (!p_ccb->p_lcb->w4_info_rsp) {
@@ -367,9 +364,9 @@
             l2cu_release_ccb(p_ccb);
             (*connect_cfm)(local_cid, L2CAP_CONN_NO_LINK);
           } else {
-            alarm_set_on_queue(
-                p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
-                l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+            alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
+                               L2CAP_CHNL_CONNECT_TIMEOUT_MS,
+                               l2c_ccb_timer_timeout, p_ccb);
             l2cu_send_peer_connect_req(p_ccb); /* Start Connection     */
           }
         }
@@ -446,9 +443,8 @@
        * needed) */
       if (!p_ccb->p_lcb->w4_info_rsp) {
         /* Don't need to get info from peer or already retrieved so continue */
-        alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
-                           l2c_ccb_timer_timeout, p_ccb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
+                           l2c_ccb_timer_timeout, p_ccb);
         L2CAP_TRACE_API("L2CAP - Calling Connect_Ind_Cb(), CID: 0x%04x",
                         p_ccb->local_cid);
 
@@ -474,9 +470,9 @@
       if (((tL2C_CONN_INFO*)p_data)->status == BTM_DELAY_CHECK) {
         /* start a timer - encryption change not received before L2CAP connect
          * req */
-        alarm_set_on_queue(
-            p_ccb->l2c_ccb_timer, L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS,
-            l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
+                           L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS,
+                           l2c_ccb_timer_timeout, p_ccb);
       } else {
         if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
           l2cu_reject_ble_connection(p_ccb->p_lcb, p_ccb->remote_id,
@@ -566,9 +562,8 @@
         p_ccb->chnl_state = CST_OPEN;
       } else {
         p_ccb->chnl_state = CST_CONFIG;
-        alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
-                           l2c_ccb_timer_timeout, p_ccb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
+                           l2c_ccb_timer_timeout, p_ccb);
       }
       L2CAP_TRACE_API("L2CAP - Calling Connect_Cfm_Cb(), CID: 0x%04x, Success",
                       p_ccb->local_cid);
@@ -578,9 +573,9 @@
 
     case L2CEVT_L2CAP_CONNECT_RSP_PND: /* Got peer connect pending */
       p_ccb->remote_cid = p_ci->remote_cid;
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer,
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
                          L2CAP_CHNL_CONNECT_EXT_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+                         l2c_ccb_timer_timeout, p_ccb);
       if (p_ccb->p_rcb->api.pL2CA_ConnectPnd_Cb) {
         L2CAP_TRACE_API("L2CAP - Calling Connect_Pnd_Cb(), CID: 0x%04x",
                         p_ccb->local_cid);
@@ -608,9 +603,9 @@
       if (p_ccb->remote_cid != 0) {
         l2cu_send_peer_disc_req(p_ccb);
         p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
-        alarm_set_on_queue(
-            p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
-            l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
+                           L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
+                           l2c_ccb_timer_timeout, p_ccb);
       } else {
         tL2CA_DISCONNECT_CFM_CB* disconnect_cfm =
             p_ccb->p_rcb->api.pL2CA_DisconnectCfm_Cb;
@@ -635,9 +630,8 @@
         (*connect_cfm)(local_cid, L2CAP_CONN_NO_LINK);
       } else {
         /* We have feature info, so now send peer connect request */
-        alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
-                           l2c_ccb_timer_timeout, p_ccb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
+                           l2c_ccb_timer_timeout, p_ccb);
         l2cu_send_peer_connect_req(p_ccb); /* Start Connection     */
       }
       break;
@@ -695,16 +689,15 @@
         if ((!p_ci) || (p_ci->l2cap_result == L2CAP_CONN_OK)) {
           l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_OK, 0);
           p_ccb->chnl_state = CST_CONFIG;
-          alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
-                             l2c_ccb_timer_timeout, p_ccb,
-                             btu_general_alarm_queue);
+          alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
+                             l2c_ccb_timer_timeout, p_ccb);
         } else {
           /* If pending, stay in same state and start extended timer */
           l2cu_send_peer_connect_rsp(p_ccb, p_ci->l2cap_result,
                                      p_ci->l2cap_status);
-          alarm_set_on_queue(
-              p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_EXT_TIMEOUT_MS,
-              l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+          alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
+                             L2CAP_CHNL_CONNECT_EXT_TIMEOUT_MS,
+                             l2c_ccb_timer_timeout, p_ccb);
         }
       }
       break;
@@ -736,14 +729,14 @@
     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
       l2cu_send_peer_disc_req(p_ccb);
       p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       break;
 
     case L2CEVT_L2CAP_INFO_RSP:
       /* We have feature info, so now give the upper layer connect IND */
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       L2CAP_TRACE_API("L2CAP - Calling Connect_Ind_Cb(), CID: 0x%04x",
                       p_ccb->local_cid);
 
@@ -877,8 +870,8 @@
       break;
 
     case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP;
       L2CAP_TRACE_API(
           "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x  Conf Needed",
@@ -889,8 +882,8 @@
     case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req   */
       l2cu_process_our_cfg_req(p_ccb, p_cfg);
       l2cu_send_peer_config_req(p_ccb, p_cfg);
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       break;
 
     case L2CEVT_L2CA_CONFIG_RSP: /* Upper layer config rsp   */
@@ -949,15 +942,15 @@
 
     case L2CEVT_L2CA_CONFIG_RSP_NEG: /* Upper layer config reject */
       l2cu_send_peer_config_rsp(p_ccb, p_cfg);
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       break;
 
     case L2CEVT_L2CA_DISCONNECT_REQ: /* Upper wants to disconnect */
       l2cu_send_peer_disc_req(p_ccb);
       p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       break;
 
     case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd    */
@@ -1056,8 +1049,8 @@
       p_ccb->chnl_state = CST_CONFIG;
       p_ccb->config_done &= ~CFG_DONE_MASK;
 
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
 
       cfg_result = l2cu_process_peer_cfg_req(p_ccb, p_cfg);
       if (cfg_result == L2CAP_PEER_CFG_OK) {
@@ -1093,8 +1086,8 @@
       }
 
       p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP;
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       L2CAP_TRACE_API(
           "L2CAP - Calling Disconnect_Ind_Cb(), CID: 0x%04x  Conf Needed",
           p_ccb->local_cid);
@@ -1125,8 +1118,8 @@
         l2cu_send_peer_disc_req(p_ccb);
 
       p_ccb->chnl_state = CST_W4_L2CAP_DISCONNECT_RSP;
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       break;
 
     case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
@@ -1139,8 +1132,8 @@
       p_ccb->config_done &= ~CFG_DONE_MASK;
       l2cu_process_our_cfg_req(p_ccb, (tL2CAP_CFG_INFO*)p_data);
       l2cu_send_peer_config_req(p_ccb, (tL2CAP_CFG_INFO*)p_data);
-      alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
-                         l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
+                         l2c_ccb_timer_timeout, p_ccb);
       break;
 
     case L2CEVT_TIMEOUT:
diff --git a/stack/l2cap/l2c_fcr.cc b/stack/l2cap/l2c_fcr.cc
index 47714e1..4e9026f 100644
--- a/stack/l2cap/l2c_fcr.cc
+++ b/stack/l2cap/l2c_fcr.cc
@@ -24,6 +24,7 @@
  ******************************************************************************/
 
 #include <base/logging.h>
+#include <log/log.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -38,8 +39,6 @@
 #include "l2c_int.h"
 #include "l2cdefs.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /* Flag passed to retransmit_i_frames() when all packets should be retransmitted
  */
 #define L2C_FCR_RETX_ALL_PKTS 0xFF
@@ -180,8 +179,8 @@
 
   /* Only start a timer that was not started */
   if (!alarm_is_scheduled(p_ccb->fcrb.mon_retrans_timer)) {
-    alarm_set_on_queue(p_ccb->fcrb.mon_retrans_timer, tout,
-                       l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_ccb->fcrb.mon_retrans_timer, tout,
+                       l2c_ccb_timer_timeout, p_ccb);
   }
 }
 
@@ -712,9 +711,8 @@
          * final,  */
         /* then it speeds up recovery significantly if we poll him back soon
          * after his poll. */
-        alarm_set_on_queue(p_ccb->fcrb.mon_retrans_timer, BT_1SEC_TIMEOUT_MS,
-                           l2c_ccb_timer_timeout, p_ccb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->fcrb.mon_retrans_timer, BT_1SEC_TIMEOUT_MS,
+                           l2c_ccb_timer_timeout, p_ccb);
       }
       osi_free(p_buf);
       return;
@@ -844,6 +842,14 @@
       return;
     }
 
+    if (sdu_length < p_buf->len) {
+      L2CAP_TRACE_ERROR("%s: Invalid sdu_length: %d", __func__, sdu_length);
+      android_errorWriteWithInfoLog(0x534e4554, "112321180", -1, NULL, 0);
+      /* Discard the buffer */
+      osi_free(p_buf);
+      return;
+    }
+
     p_data = (BT_HDR*)osi_malloc(L2CAP_MAX_BUF_SIZE);
     if (p_data == NULL) {
       osi_free(p_buf);
@@ -1301,9 +1307,8 @@
     if (delay_ack) {
       /* If it is the first I frame we did not ack, start ack timer */
       if (!alarm_is_scheduled(p_ccb->fcrb.ack_timer)) {
-        alarm_set_on_queue(p_ccb->fcrb.ack_timer, L2CAP_FCR_ACK_TIMEOUT_MS,
-                           l2c_fcrb_ack_timer_timeout, p_ccb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->fcrb.ack_timer, L2CAP_FCR_ACK_TIMEOUT_MS,
+                           l2c_fcrb_ack_timer_timeout, p_ccb);
       }
     } else if ((fixed_queue_is_empty(p_ccb->xmit_hold_q) ||
                 l2c_fcr_is_flow_controlled(p_ccb)) &&
@@ -2198,9 +2203,8 @@
 
         l2cu_process_our_cfg_req(p_ccb, &p_ccb->our_cfg);
         l2cu_send_peer_config_req(p_ccb, &p_ccb->our_cfg);
-        alarm_set_on_queue(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
-                           l2c_ccb_timer_timeout, p_ccb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS,
+                           l2c_ccb_timer_timeout, p_ccb);
         return (true);
       }
     }
diff --git a/stack/l2cap/l2c_int.h b/stack/l2cap/l2c_int.h
index dde6c8a..14eb1e5 100644
--- a/stack/l2cap/l2c_int.h
+++ b/stack/l2cap/l2c_int.h
@@ -256,8 +256,9 @@
 #define L2CAP_CBB_DEFAULT_DATA_RATE_BUFF_QUOTA 100
 #endif
 
-typedef void(tL2CAP_SEC_CBACK)(BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
-                               void* p_ref_data, tBTM_STATUS result);
+typedef void(tL2CAP_SEC_CBACK)(const RawAddress& bd_addr,
+                               tBT_TRANSPORT trasnport, void* p_ref_data,
+                               tBTM_STATUS result);
 
 typedef struct {
   uint16_t psm;
@@ -392,7 +393,7 @@
 
   tL2C_CCB* p_pending_ccb;  /* ccb of waiting channel during link disconnect */
   alarm_t* info_resp_timer; /* Timer entry for info resp timeout evt */
-  BD_ADDR remote_bd_addr;   /* The BD address of the remote */
+  RawAddress remote_bd_addr; /* The BD address of the remote */
 
   uint8_t link_role; /* Master or slave */
   uint8_t id;
@@ -512,7 +513,7 @@
 
   uint16_t num_ble_links_active; /* Number of LE links active */
   bool is_ble_connecting;
-  BD_ADDR ble_connecting_bda;
+  RawAddress ble_connecting_bda;
   uint16_t controller_le_xmit_window; /* Total ACL window for all links */
   tL2C_BLE_FIXED_CHNLS_MASK l2c_ble_fixed_chnls_mask;  // LE fixed channels mask
   uint16_t num_lm_ble_bufs;         /* # of ACL buffers on controller */
@@ -536,7 +537,7 @@
  * fields will always be filled in.
 */
 typedef struct {
-  BD_ADDR bd_addr;       /* Remote BD address */
+  RawAddress bd_addr;    /* Remote BD address */
   uint8_t status;        /* Connection status */
   uint16_t psm;          /* PSM of the connection */
   uint16_t l2cap_result; /* L2CAP result */
@@ -589,17 +590,18 @@
  ***********************************
 */
 extern bool l2cu_can_allocate_lcb(void);
-extern tL2C_LCB* l2cu_allocate_lcb(BD_ADDR p_bd_addr, bool is_bonding,
+extern tL2C_LCB* l2cu_allocate_lcb(const RawAddress& p_bd_addr, bool is_bonding,
                                    tBT_TRANSPORT transport);
 extern bool l2cu_start_post_bond_timer(uint16_t handle);
 extern void l2cu_release_lcb(tL2C_LCB* p_lcb);
-extern tL2C_LCB* l2cu_find_lcb_by_bd_addr(BD_ADDR p_bd_addr,
+extern tL2C_LCB* l2cu_find_lcb_by_bd_addr(const RawAddress& p_bd_addr,
                                           tBT_TRANSPORT transport);
 extern tL2C_LCB* l2cu_find_lcb_by_handle(uint16_t handle);
-extern void l2cu_update_lcb_4_bonding(BD_ADDR p_bd_addr, bool is_bonding);
+extern void l2cu_update_lcb_4_bonding(const RawAddress& p_bd_addr,
+                                      bool is_bonding);
 
 extern uint8_t l2cu_get_conn_role(tL2C_LCB* p_this_lcb);
-extern bool l2cu_set_acl_priority(BD_ADDR bd_addr, uint8_t priority,
+extern bool l2cu_set_acl_priority(const RawAddress& bd_addr, uint8_t priority,
                                   bool reset_after_rs);
 
 extern void l2cu_enqueue_ccb(tL2C_CCB* p_ccb);
@@ -713,16 +715,16 @@
 extern bool l2cu_create_conn_after_switch(tL2C_LCB* p_lcb);
 extern BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb,
                                             tL2C_TX_COMPLETE_CB_INFO* p_cbi);
-extern void l2cu_resubmit_pending_sec_req(BD_ADDR p_bda);
+extern void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda);
 extern void l2cu_initialize_amp_ccb(tL2C_LCB* p_lcb);
 extern void l2cu_adjust_out_mps(tL2C_CCB* p_ccb);
 
 /* Functions provided by l2c_link.cc
  ***********************************
 */
-extern bool l2c_link_hci_conn_req(BD_ADDR bd_addr);
+extern bool l2c_link_hci_conn_req(const RawAddress& bd_addr);
 extern bool l2c_link_hci_conn_comp(uint8_t status, uint16_t handle,
-                                   BD_ADDR p_bda);
+                                   const RawAddress& p_bda);
 extern bool l2c_link_hci_disc_comp(uint16_t handle, uint8_t reason);
 extern bool l2c_link_hci_qos_violation(uint16_t handle);
 extern void l2c_link_timeout(tL2C_LCB* p_lcb);
@@ -735,12 +737,14 @@
                                                   uint8_t* p, uint16_t evt_len);
 extern void l2c_link_processs_num_bufs(uint16_t num_lm_acl_bufs);
 extern uint8_t l2c_link_pkts_rcvd(uint16_t* num_pkts, uint16_t* handles);
-extern void l2c_link_role_changed(BD_ADDR bd_addr, uint8_t new_role,
+extern void l2c_link_role_changed(const RawAddress* bd_addr, uint8_t new_role,
                                   uint8_t hci_status);
-extern void l2c_link_sec_comp(BD_ADDR p_bda, tBT_TRANSPORT trasnport,
+extern void l2c_link_sec_comp(const RawAddress* p_bda, tBT_TRANSPORT trasnport,
                               void* p_ref_data, uint8_t status);
+extern void l2c_link_sec_comp2(const RawAddress& p_bda, tBT_TRANSPORT trasnport,
+                               void* p_ref_data, uint8_t status);
 extern void l2c_link_segments_xmitted(BT_HDR* p_msg);
-extern void l2c_pin_code_request(BD_ADDR bd_addr);
+extern void l2c_pin_code_request(const RawAddress& bd_addr);
 extern void l2c_link_adjust_chnl_allocation(void);
 
 extern void l2c_link_processs_ble_num_bufs(uint16_t num_lm_acl_bufs);
@@ -801,11 +805,12 @@
 extern bool l2cble_create_conn(tL2C_LCB* p_lcb);
 extern void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p,
                                    uint16_t pkt_len);
-extern void l2cble_conn_comp(uint16_t handle, uint8_t role, BD_ADDR bda,
-                             tBLE_ADDR_TYPE type, uint16_t conn_interval,
-                             uint16_t conn_latency, uint16_t conn_timeout);
+extern void l2cble_conn_comp(uint16_t handle, uint8_t role,
+                             const RawAddress& bda, tBLE_ADDR_TYPE type,
+                             uint16_t conn_interval, uint16_t conn_latency,
+                             uint16_t conn_timeout);
 extern bool l2cble_init_direct_conn(tL2C_LCB* p_lcb);
-extern void l2cble_notify_le_connection(BD_ADDR bda);
+extern void l2cble_notify_le_connection(const RawAddress& bda);
 extern void l2c_ble_link_adjust_allocation(void);
 extern void l2cble_process_conn_update_evt(uint16_t handle, uint8_t status,
                                            uint16_t interval, uint16_t latency,
@@ -816,7 +821,7 @@
 extern void l2cble_send_peer_disc_req(tL2C_CCB* p_ccb);
 extern void l2cble_send_flow_control_credit(tL2C_CCB* p_ccb,
                                             uint16_t credit_value);
-extern bool l2ble_sec_access_req(BD_ADDR bd_addr, uint16_t psm,
+extern bool l2ble_sec_access_req(const RawAddress& bd_addr, uint16_t psm,
                                  bool is_originator,
                                  tL2CAP_SEC_CBACK* p_callback,
                                  void* p_ref_data);
@@ -830,9 +835,8 @@
 #endif
 
 extern void l2cble_update_data_length(tL2C_LCB* p_lcb);
-extern void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda,
-                                                    uint16_t fix_cid,
-                                                    uint16_t tx_mtu);
+extern void l2cble_set_fixed_channel_tx_data_length(
+    const RawAddress& remote_bda, uint16_t fix_cid, uint16_t tx_mtu);
 extern void l2cble_process_data_length_change_event(uint16_t handle,
                                                     uint16_t tx_data_len,
                                                     uint16_t rx_data_len);
diff --git a/stack/l2cap/l2c_link.cc b/stack/l2cap/l2c_link.cc
index 2730242..bd4a610 100644
--- a/stack/l2cap/l2c_link.cc
+++ b/stack/l2cap/l2c_link.cc
@@ -32,7 +32,6 @@
 #include "bt_common.h"
 #include "bt_types.h"
 #include "bt_utils.h"
-#include "btcore/include/bdaddr.h"
 #include "btm_api.h"
 #include "btm_int.h"
 #include "btu.h"
@@ -43,8 +42,6 @@
 #include "l2cdefs.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
                                    tL2C_TX_COMPLETE_CB_INFO* p_cbi);
 
@@ -58,7 +55,7 @@
  * Returns          true, if accept conn
  *
  ******************************************************************************/
-bool l2c_link_hci_conn_req(BD_ADDR bd_addr) {
+bool l2c_link_hci_conn_req(const RawAddress& bd_addr) {
   tL2C_LCB* p_lcb;
   tL2C_LCB* p_lcb_cur;
   int xx;
@@ -103,8 +100,8 @@
     p_lcb->link_state = LST_CONNECTING;
 
     /* Start a timer waiting for connect complete */
-    alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS,
-                       l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS,
+                       l2c_lcb_timer_timeout, p_lcb);
     return (true);
   }
 
@@ -146,7 +143,8 @@
  * Returns          void
  *
  ******************************************************************************/
-bool l2c_link_hci_conn_comp(uint8_t status, uint16_t handle, BD_ADDR p_bda) {
+bool l2c_link_hci_conn_comp(uint8_t status, uint16_t handle,
+                            const RawAddress& p_bda) {
   tL2C_CONN_INFO ci;
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
@@ -156,7 +154,7 @@
 
   /* Save the parameters */
   ci.status = status;
-  memcpy(ci.bd_addr, p_bda, BD_ADDR_LEN);
+  ci.bd_addr = p_bda;
 
   /* See if we have a link control block for the remote device */
   p_lcb = l2cu_find_lcb_by_bd_addr(ci.bd_addr, BT_TRANSPORT_BR_EDR);
@@ -216,12 +214,12 @@
 
     if (p_lcb->p_echo_rsp_cb) {
       l2cu_send_peer_echo_req(p_lcb, NULL, 0);
-      alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_ECHO_RSP_TIMEOUT_MS,
-                         l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_ECHO_RSP_TIMEOUT_MS,
+                         l2c_lcb_timer_timeout, p_lcb);
     } else if (!p_lcb->ccb_queue.p_first_ccb) {
       period_ms_t timeout_ms = L2CAP_LINK_STARTUP_TOUT * 1000;
-      alarm_set_on_queue(p_lcb->l2c_lcb_timer, timeout_ms,
-                         l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms,
+                         l2c_lcb_timer_timeout, p_lcb);
     }
   }
   /* Max number of acl connections.                          */
@@ -272,8 +270,15 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2c_link_sec_comp(BD_ADDR p_bda, UNUSED_ATTR tBT_TRANSPORT transport,
-                       void* p_ref_data, uint8_t status) {
+void l2c_link_sec_comp(const RawAddress* p_bda,
+                       UNUSED_ATTR tBT_TRANSPORT transport, void* p_ref_data,
+                       uint8_t status) {
+  l2c_link_sec_comp2(*p_bda, transport, p_ref_data, status);
+}
+
+void l2c_link_sec_comp2(const RawAddress& p_bda,
+                        UNUSED_ATTR tBT_TRANSPORT transport, void* p_ref_data,
+                        uint8_t status) {
   tL2C_CONN_INFO ci;
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
@@ -286,7 +291,7 @@
 
   /* Save the parameters */
   ci.status = status;
-  memcpy(ci.bd_addr, p_bda, BD_ADDR_LEN);
+  ci.bd_addr = p_bda;
 
   p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, transport);
 
@@ -309,9 +314,9 @@
         case BTM_DELAY_CHECK:
           /* start a timer - encryption change not received before L2CAP connect
            * req */
-          alarm_set_on_queue(
-              p_ccb->l2c_ccb_timer, L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS,
-              l2c_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+          alarm_set_on_mloop(p_ccb->l2c_ccb_timer,
+                             L2CAP_DELAY_CHECK_SM4_TIMEOUT_MS,
+                             l2c_ccb_timer_timeout, p_ccb);
           return;
 
         default:
@@ -380,7 +385,7 @@
 #if (BTM_SCO_INCLUDED == TRUE)
     if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
       /* Tell SCO management to drop any SCOs on this ACL */
-      btm_sco_acl_removed(p_lcb->remote_bd_addr);
+      btm_sco_acl_removed(&p_lcb->remote_bd_addr);
 #endif
 
     /* If waiting for disconnect and reconnect is pending start the reconnect
@@ -417,16 +422,13 @@
                 xx + L2CAP_FIRST_FIXED_CHNL, p_lcb->remote_bd_addr, false,
                 p_lcb->disc_reason, p_lcb->transport);
             if (p_lcb->p_fixed_ccbs[xx] == NULL) {
-              bdstr_t bd_addr_str = {0};
               L2CAP_TRACE_ERROR(
                   "%s: unexpected p_fixed_ccbs[%d] is NULL remote_bd_addr = %s "
                   "p_lcb = %p in_use = %d link_state = %d handle = %d "
                   "link_role = %d is_bonding = %d disc_reason = %d transport = "
                   "%d",
-                  __func__, xx,
-                  bdaddr_to_string((bt_bdaddr_t*)&p_lcb->remote_bd_addr,
-                                   bd_addr_str, sizeof(bd_addr_str)),
-                  p_lcb, p_lcb->in_use, p_lcb->link_state, p_lcb->handle,
+                  __func__, xx, p_lcb->remote_bd_addr.ToString().c_str(), p_lcb,
+                  p_lcb->in_use, p_lcb->link_state, p_lcb->handle,
                   p_lcb->link_role, p_lcb->is_bonding, p_lcb->disc_reason,
                   p_lcb->transport);
             }
@@ -586,9 +588,8 @@
       }
 
       if (start_timeout) {
-        alarm_set_on_queue(p_lcb->l2c_lcb_timer, timeout_ms,
-                           l2c_lcb_timer_timeout, p_lcb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms,
+                           l2c_lcb_timer_timeout, p_lcb);
       }
     } else {
       /* Check in case we were flow controlled */
@@ -619,9 +620,9 @@
          p_ccb = p_ccb->p_next_ccb) {
       if ((p_ccb->chnl_state == CST_ORIG_W4_SEC_COMP) ||
           (p_ccb->chnl_state == CST_TERM_W4_SEC_COMP)) {
-        alarm_set_on_queue(
-            p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
-            l2c_info_resp_timer_timeout, p_lcb, btu_general_alarm_queue);
+        alarm_set_on_mloop(p_lcb->info_resp_timer,
+                           L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
+                           l2c_info_resp_timer_timeout, p_lcb);
         return;
       }
     }
@@ -634,7 +635,7 @@
       /* Notify active channels that peer info is finished */
       if (p_lcb->ccb_queue.p_first_ccb) {
         ci.status = HCI_SUCCESS;
-        memcpy(ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
+        ci.bd_addr = p_lcb->remote_bd_addr;
 
         for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
              p_ccb = p_ccb->p_next_ccb) {
@@ -757,9 +758,9 @@
       if ((p_lcb->link_state == LST_CONNECTED) &&
           (!list_is_empty(p_lcb->link_xmit_data_q)) &&
           (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
-        alarm_set_on_queue(
-            p_lcb->l2c_lcb_timer, L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
-            l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+        alarm_set_on_mloop(p_lcb->l2c_lcb_timer,
+                           L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
+                           l2c_lcb_timer_timeout, p_lcb);
       }
     }
   }
@@ -848,7 +849,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2c_link_role_changed(BD_ADDR bd_addr, uint8_t new_role,
+void l2c_link_role_changed(const RawAddress* bd_addr, uint8_t new_role,
                            uint8_t hci_status) {
   tL2C_LCB* p_lcb;
   int xx;
@@ -857,13 +858,13 @@
    * invalid) */
   if (bd_addr) {
     /* If here came form hci role change event */
-    p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
+    p_lcb = l2cu_find_lcb_by_bd_addr(*bd_addr, BT_TRANSPORT_BR_EDR);
     if (p_lcb) {
       p_lcb->link_role = new_role;
 
       /* Reset high priority link if needed */
       if (hci_status == HCI_SUCCESS)
-        l2cu_set_acl_priority(bd_addr, p_lcb->acl_priority, true);
+        l2cu_set_acl_priority(*bd_addr, p_lcb->acl_priority, true);
     }
   }
 
@@ -888,12 +889,12 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2c_pin_code_request(BD_ADDR bd_addr) {
+void l2c_pin_code_request(const RawAddress& bd_addr) {
   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
 
   if ((p_lcb) && (!p_lcb->ccb_queue.p_first_ccb)) {
-    alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_EXT_TIMEOUT_MS,
-                       l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_EXT_TIMEOUT_MS,
+                       l2c_lcb_timer_timeout, p_lcb);
   }
 }
 
@@ -1080,9 +1081,9 @@
     /* so we may need a timer to kick off this link's transmissions.         */
     if ((!list_is_empty(p_lcb->link_xmit_data_q)) &&
         (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) {
-      alarm_set_on_queue(p_lcb->l2c_lcb_timer,
+      alarm_set_on_mloop(p_lcb->l2c_lcb_timer,
                          L2CAP_LINK_FLOW_CONTROL_TIMEOUT_MS,
-                         l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+                         l2c_lcb_timer_timeout, p_lcb);
     }
   }
 }
@@ -1096,7 +1097,8 @@
  * Returns          true for success, false for fail
  *
  ******************************************************************************/
-static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
+static bool l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf,
+                                   tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
   uint16_t num_segs;
   uint16_t xmit_window, acl_data_size;
   const controller_t* controller = controller_get_interface();
@@ -1186,8 +1188,7 @@
   }
 #endif
 
-  if (p_cbi)
-    l2cu_tx_complete(p_cbi);
+  if (p_cbi) l2cu_tx_complete(p_cbi);
 
   return true;
 }
diff --git a/stack/l2cap/l2c_main.cc b/stack/l2cap/l2c_main.cc
index 6a86aea..6ce71e9 100644
--- a/stack/l2cap/l2c_main.cc
+++ b/stack/l2cap/l2c_main.cc
@@ -40,8 +40,6 @@
 #include "osi/include/log.h"
 #include "osi/include/osi.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
@@ -103,9 +101,8 @@
         list_append(l2cb.rcv_pending_q, p_msg);
 
         if (list_length(l2cb.rcv_pending_q) == 1) {
-          alarm_set_on_queue(l2cb.receive_hold_timer, BT_1SEC_TIMEOUT_MS,
-                             l2c_receive_hold_timer_timeout, NULL,
-                             btu_general_alarm_queue);
+          alarm_set_on_mloop(l2cb.receive_hold_timer, BT_1SEC_TIMEOUT_MS,
+                             l2c_receive_hold_timer_timeout, NULL);
         }
 
         return;
@@ -367,7 +364,7 @@
 
           p_lcb->w4_info_rsp = false;
           ci.status = HCI_SUCCESS;
-          memcpy(ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
+          ci.bd_addr = p_lcb->remote_bd_addr;
 
           /* For all channels, send the event through their FSMs */
           for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
@@ -826,7 +823,7 @@
 #endif
 
         ci.status = HCI_SUCCESS;
-        memcpy(ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR));
+        ci.bd_addr = p_lcb->remote_bd_addr;
         for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb;
              p_ccb = p_ccb->p_next_ccb) {
           l2c_csm_execute(p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci);
@@ -877,9 +874,8 @@
 
   /* If anyone still in the queue, restart the timeout */
   if (!list_is_empty(l2cb.rcv_pending_q)) {
-    alarm_set_on_queue(l2cb.receive_hold_timer, BT_1SEC_TIMEOUT_MS,
-                       l2c_receive_hold_timer_timeout, NULL,
-                       btu_general_alarm_queue);
+    alarm_set_on_mloop(l2cb.receive_hold_timer, BT_1SEC_TIMEOUT_MS,
+                       l2c_receive_hold_timer_timeout, NULL);
   }
 }
 
diff --git a/stack/l2cap/l2c_ucd.cc b/stack/l2cap/l2c_ucd.cc
index 2e9f695..2216368 100644
--- a/stack/l2cap/l2c_ucd.cc
+++ b/stack/l2cap/l2c_ucd.cc
@@ -38,9 +38,7 @@
 
 #if (L2CAP_UCD_INCLUDED == TRUE)
 
-extern fixed_queue_t* btu_bta_alarm_queue;
-
-static bool l2c_ucd_connect(BD_ADDR rem_bda);
+static bool l2c_ucd_connect(const RawAddress& rem_bda);
 
 /*******************************************************************************
  *
@@ -51,7 +49,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void l2c_ucd_discover_cback(BD_ADDR rem_bda, uint8_t info_type,
+static void l2c_ucd_discover_cback(const RawAddress& rem_bda, uint8_t info_type,
                                    uint32_t data) {
   tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
   uint16_t xx;
@@ -86,7 +84,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void l2c_ucd_data_ind_cback(BD_ADDR rem_bda, BT_HDR* p_buf) {
+static void l2c_ucd_data_ind_cback(const RawAddress& rem_bda, BT_HDR* p_buf) {
   uint8_t* p;
   uint16_t psm;
   tL2C_RCB* p_rcb;
@@ -118,7 +116,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void l2c_ucd_congestion_status_cback(BD_ADDR rem_bda,
+static void l2c_ucd_congestion_status_cback(const RawAddress& rem_bda,
                                             bool is_congested) {
   tL2C_RCB* p_rcb = &l2cb.rcb_pool[0];
   uint16_t xx;
@@ -309,7 +307,8 @@
  *  Return value:   true if successs
  *
  ******************************************************************************/
-bool L2CA_UcdDiscover(uint16_t psm, BD_ADDR rem_bda, uint8_t info_type) {
+bool L2CA_UcdDiscover(uint16_t psm, const RawAddress& rem_bda,
+                      uint8_t info_type) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
   tL2C_RCB* p_rcb;
@@ -373,8 +372,8 @@
  *                  L2CAP_DW_FAILED,  if error
  *
  ******************************************************************************/
-uint16_t L2CA_UcdDataWrite(uint16_t psm, BD_ADDR rem_bda, BT_HDR* p_buf,
-                           uint16_t flags) {
+uint16_t L2CA_UcdDataWrite(uint16_t psm, const RawAddress& rem_bda,
+                           BT_HDR* p_buf, uint16_t flags) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
   tL2C_RCB* p_rcb;
@@ -469,7 +468,7 @@
  *  Return value:   true if successs
  *
  ******************************************************************************/
-bool L2CA_UcdSetIdleTimeout(BD_ADDR rem_bda, uint16_t timeout) {
+bool L2CA_UcdSetIdleTimeout(const RawAddress& rem_bda, uint16_t timeout) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
 
@@ -501,7 +500,8 @@
  * Returns          true if a valid channel, else false
  *
  ******************************************************************************/
-bool L2CA_UCDSetTxPriority(BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority) {
+bool L2CA_UCDSetTxPriority(const RawAddress& rem_bda,
+                           tL2CAP_CHNL_PRIORITY priority) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
 
@@ -541,7 +541,7 @@
  *  Return value:   true if successs
  *
  ******************************************************************************/
-static bool l2c_ucd_connect(BD_ADDR rem_bda) {
+static bool l2c_ucd_connect(const RawAddress& rem_bda) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
   tL2C_RCB* p_rcb;
@@ -963,14 +963,13 @@
           if (!fixed_queue_is_empty(p_ccb->p_lcb->ucd_out_sec_pending_q)) {
             /* start a timer to send next UCD packet in OPEN state */
             /* it will prevent stack overflow */
-            alarm_set_on_queue(p_ccb->l2c_ccb_timer, 0, l2c_ccb_timer_timeout,
-                               p_ccb, btu_general_alarm_queue);
+            alarm_set_on_mloop(p_ccb->l2c_ccb_timer, 0, l2c_ccb_timer_timeout,
+                               p_ccb);
           } else {
             /* start a timer for idle timeout of UCD */
             period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000;
-            alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms,
-                               l2c_ccb_timer_timeout, p_ccb,
-                               btu_general_alarm_queue);
+            alarm_set_on_mloop(p_ccb->l2c_ccb_timer, timeout_ms,
+                               l2c_ccb_timer_timeout, p_ccb);
           }
           break;
 
@@ -980,9 +979,8 @@
 
           /* start a timer for idle timeout of UCD */
           period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000;
-          alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms,
-                             l2c_ccb_timer_timeout, p_ccb,
-                             btu_general_alarm_queue);
+          alarm_set_on_mloop(p_ccb->l2c_ccb_timer, timeout_ms,
+                             l2c_ccb_timer_timeout, p_ccb);
           break;
 
         case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
@@ -1013,14 +1011,13 @@
           if (!fixed_queue_is_empty(p_ccb->p_lcb->ucd_in_sec_pending_q)) {
             /* start a timer to check next UCD packet in OPEN state */
             /* it will prevent stack overflow */
-            alarm_set_on_queue(p_ccb->l2c_ccb_timer, 0, l2c_ccb_timer_timeout,
-                               p_ccb, btu_general_alarm_queue);
+            alarm_set_on_mloop(p_ccb->l2c_ccb_timer, 0, l2c_ccb_timer_timeout,
+                               p_ccb);
           } else {
             /* start a timer for idle timeout of UCD */
             period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000;
-            alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms,
-                               l2c_ccb_timer_timeout, p_ccb,
-                               btu_general_alarm_queue);
+            alarm_set_on_mloop(p_ccb->l2c_ccb_timer, timeout_ms,
+                               l2c_ccb_timer_timeout, p_ccb);
           }
           break;
 
@@ -1034,9 +1031,8 @@
 
           /* start a timer for idle timeout of UCD */
           period_ms_t timeout_ms = p_ccb->fixed_chnl_idle_tout * 1000;
-          alarm_set_on_queue(p_ccb->l2c_ccb_timer, timeout_ms,
-                             l2c_ccb_timer_timeout, p_ccb,
-                             btu_general_alarm_queue);
+          alarm_set_on_mloop(p_ccb->l2c_ccb_timer, timeout_ms,
+                             l2c_ccb_timer_timeout, p_ccb);
           break;
 
         case L2CEVT_L2CA_DATA_WRITE: /* Upper layer data to send */
diff --git a/stack/l2cap/l2c_utils.cc b/stack/l2cap/l2c_utils.cc
index d671110..943b72c 100644
--- a/stack/l2cap/l2c_utils.cc
+++ b/stack/l2cap/l2c_utils.cc
@@ -39,8 +39,6 @@
 #include "l2cdefs.h"
 #include "osi/include/allocator.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*******************************************************************************
  *
  * Function         l2cu_can_allocate_lcb
@@ -66,7 +64,7 @@
  * Returns          LCB address or NULL if none found
  *
  ******************************************************************************/
-tL2C_LCB* l2cu_allocate_lcb(BD_ADDR p_bd_addr, bool is_bonding,
+tL2C_LCB* l2cu_allocate_lcb(const RawAddress& p_bd_addr, bool is_bonding,
                             tBT_TRANSPORT transport) {
   int xx;
   tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
@@ -77,7 +75,7 @@
       alarm_free(p_lcb->info_resp_timer);
       memset(p_lcb, 0, sizeof(tL2C_LCB));
 
-      memcpy(p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
+      p_lcb->remote_bd_addr = p_bd_addr;
 
       p_lcb->in_use = true;
       p_lcb->link_state = LST_DISCONNECTED;
@@ -123,14 +121,12 @@
  * Returns          Nothing
  *
  ******************************************************************************/
-void l2cu_update_lcb_4_bonding(BD_ADDR p_bd_addr, bool is_bonding) {
+void l2cu_update_lcb_4_bonding(const RawAddress& p_bd_addr, bool is_bonding) {
   tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR);
 
   if (p_lcb) {
-    L2CAP_TRACE_DEBUG("l2cu_update_lcb_4_bonding  BDA: %08x%04x is_bonding: %d",
-                      (p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) +
-                          (p_bd_addr[2] << 8) + p_bd_addr[3],
-                      (p_bd_addr[4] << 8) + p_bd_addr[5], is_bonding);
+    VLOG(1) << __func__ << " BDA: " << p_bd_addr
+            << " is_bonding: " << is_bonding;
     p_lcb->is_bonding = is_bonding;
   }
 }
@@ -180,7 +176,7 @@
   }
 
   // Reset BLE connecting flag only if the address matches
-  if (!memcmp(l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN))
+  if (l2cb.ble_connecting_bda == p_lcb->remote_bd_addr)
     l2cb.is_ble_connecting = false;
 
 #if (L2CAP_NUM_FIXED_CHNLS > 0)
@@ -260,13 +256,14 @@
  * Returns          pointer to matched LCB, or NULL if no match
  *
  ******************************************************************************/
-tL2C_LCB* l2cu_find_lcb_by_bd_addr(BD_ADDR p_bd_addr, tBT_TRANSPORT transport) {
+tL2C_LCB* l2cu_find_lcb_by_bd_addr(const RawAddress& p_bd_addr,
+                                   tBT_TRANSPORT transport) {
   int xx;
   tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
 
   for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
     if ((p_lcb->in_use) && p_lcb->transport == transport &&
-        (!memcmp(p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN))) {
+        (p_lcb->remote_bd_addr == p_bd_addr)) {
       return (p_lcb);
     }
   }
@@ -1058,9 +1055,8 @@
   UINT16_TO_STREAM(p, info_type);
 
   p_lcb->w4_info_rsp = true;
-  alarm_set_on_queue(p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
-                     l2c_info_resp_timer_timeout, p_lcb,
-                     btu_general_alarm_queue);
+  alarm_set_on_mloop(p_lcb->info_resp_timer, L2CAP_WAIT_INFO_RSP_TIMEOUT_MS,
+                     l2c_info_resp_timer_timeout, p_lcb);
 
   l2c_link_check_send_pkts(p_lcb, NULL, p_buf);
 }
@@ -1560,8 +1556,8 @@
       p_lcb->link_state = LST_DISCONNECTING;
       timeout_ms = L2CAP_LINK_DISCONNECT_TIMEOUT_MS;
     }
-    alarm_set_on_queue(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout,
-                       p_lcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout,
+                       p_lcb);
     return (true);
   }
 
@@ -2057,7 +2053,7 @@
         p_lcb->link_flush_tout = p_cfg->flush_to;
 
         /* If the timeout is within range of HCI, set the flush timeout */
-        if (p_cfg->flush_to <= ((HCI_MAX_AUTO_FLUSH_TOUT * 5) / 8)) {
+        if (p_cfg->flush_to <= ((HCI_MAX_AUTOMATIC_FLUSH_TIMEOUT * 5) / 8)) {
           /* Convert flush timeout to 0.625 ms units, with round */
           hci_flush_to = ((p_cfg->flush_to * 8) + 3) / 5;
           btsnd_hcic_write_auto_flush_tout(p_lcb->handle, hci_flush_to);
@@ -2179,9 +2175,9 @@
 
         if (BTM_SwitchRole(p_lcb_cur->remote_bd_addr, HCI_ROLE_MASTER, NULL) ==
             BTM_CMD_STARTED) {
-          alarm_set_on_queue(
-              p_lcb->l2c_lcb_timer, L2CAP_LINK_ROLE_SWITCH_TIMEOUT_MS,
-              l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+          alarm_set_on_mloop(p_lcb->l2c_lcb_timer,
+                             L2CAP_LINK_ROLE_SWITCH_TIMEOUT_MS,
+                             l2c_lcb_timer_timeout, p_lcb);
           return (true);
         }
       }
@@ -2276,8 +2272,8 @@
 
   btm_acl_update_busy_level(BTM_BLI_PAGE_EVT);
 
-  alarm_set_on_queue(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS,
-                     l2c_lcb_timer_timeout, p_lcb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_lcb->l2c_lcb_timer, L2CAP_LINK_CONNECT_TIMEOUT_MS,
+                     l2c_lcb_timer_timeout, p_lcb);
 
   return (true);
 }
@@ -2362,7 +2358,7 @@
  *
  ******************************************************************************/
 
-bool l2cu_set_acl_priority(BD_ADDR bd_addr, uint8_t priority,
+bool l2cu_set_acl_priority(const RawAddress& bd_addr, uint8_t priority,
                            bool reset_after_rs) {
   tL2C_LCB* p_lcb;
   uint8_t* pp;
@@ -2434,7 +2430,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void l2cu_resubmit_pending_sec_req(BD_ADDR p_bda) {
+void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda) {
   tL2C_LCB* p_lcb;
   tL2C_CCB* p_ccb;
   tL2C_CCB* p_next_ccb;
@@ -2444,7 +2440,7 @@
 
   /* If we are called with a BDA, only resubmit for that BDA */
   if (p_bda) {
-    p_lcb = l2cu_find_lcb_by_bd_addr(p_bda, BT_TRANSPORT_BR_EDR);
+    p_lcb = l2cu_find_lcb_by_bd_addr(*p_bda, BT_TRANSPORT_BR_EDR);
 
     /* If we don't have one, this is an error */
     if (p_lcb) {
@@ -2654,8 +2650,8 @@
 
   if (start_timeout) {
     L2CAP_TRACE_DEBUG("%s starting IDLE timeout: %d ms", __func__, timeout_ms);
-    alarm_set_on_queue(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout,
-                       p_lcb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout,
+                       p_lcb);
   } else {
     alarm_cancel(p_lcb->l2c_lcb_timer);
   }
@@ -3245,8 +3241,7 @@
 #endif /* (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE) */
 
 void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
-  if (p_cbi->cb != NULL)
-      p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu);
+  if (p_cbi->cb != NULL) p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu);
 }
 
 /******************************************************************************
@@ -3259,7 +3254,8 @@
  * Returns          pointer to buffer or NULL
  *
  ******************************************************************************/
-BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
+BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb,
+                                     tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
   tL2C_CCB* p_ccb;
   BT_HDR* p_buf;
 
diff --git a/stack/l2cap/l2cap_client.cc b/stack/l2cap/l2cap_client.cc
index 8c4eafe..6ccf8c5 100644
--- a/stack/l2cap/l2cap_client.cc
+++ b/stack/l2cap/l2cap_client.cc
@@ -23,7 +23,6 @@
 #include <base/logging.h>
 #include <string.h>
 
-#include "btcore/include/bdaddr.h"
 #include "osi/include/allocator.h"
 #include "osi/include/buffer.h"
 #include "osi/include/list.h"
@@ -127,17 +126,16 @@
 }
 
 bool l2cap_client_connect(l2cap_client_t* client,
-                          const bt_bdaddr_t* remote_bdaddr, uint16_t psm) {
+                          const RawAddress& remote_bdaddr, uint16_t psm) {
   CHECK(client != NULL);
-  CHECK(remote_bdaddr != NULL);
   CHECK(psm != 0);
-  CHECK(!bdaddr_is_empty(remote_bdaddr));
+  CHECK(!remote_bdaddr.IsEmpty());
   CHECK(client->local_channel_id == 0);
   CHECK(!client->configured_self);
   CHECK(!client->configured_peer);
   CHECK(!L2C_INVALID_PSM(psm));
 
-  client->local_channel_id = L2CA_ConnectReq(psm, (uint8_t*)remote_bdaddr);
+  client->local_channel_id = L2CA_ConnectReq(psm, remote_bdaddr);
   if (!client->local_channel_id) {
     LOG_ERROR(LOG_TAG, "%s unable to create L2CAP connection.", __func__);
     return false;
diff --git a/stack/mcap/mca_api.cc b/stack/mcap/mca_api.cc
index c0ca4ea..44ab256 100644
--- a/stack/mcap/mca_api.cc
+++ b/stack/mcap/mca_api.cc
@@ -302,7 +302,7 @@
  * Returns          MCA_SUCCESS if successful, otherwise error.
  *
  ******************************************************************************/
-tMCA_RESULT MCA_ConnectReq(tMCA_HANDLE handle, BD_ADDR bd_addr,
+tMCA_RESULT MCA_ConnectReq(tMCA_HANDLE handle, const RawAddress& bd_addr,
                            uint16_t ctrl_psm, uint16_t sec_mask) {
   tMCA_RESULT result = MCA_BAD_HANDLE;
   tMCA_CCB* p_ccb;
@@ -415,12 +415,13 @@
       /* save the info required by dcb connection */
       p_dcb->p_chnl_cfg = p_chnl_cfg;
       p_dcb->mdl_id = mdl_id;
-      tMCA_CCB_MSG* p_evt_data =
-          (tMCA_CCB_MSG*)osi_malloc(sizeof(tMCA_CCB_MSG));
       if (!p_ccb->data_vpsm)
         p_ccb->data_vpsm =
             L2CA_Register(data_psm, (tL2CAP_APPL_INFO*)&mca_l2c_int_appl);
       if (p_ccb->data_vpsm) {
+        tMCA_CCB_EVT* mca_ccb_evt =
+            (tMCA_CCB_EVT*)osi_malloc(sizeof(tMCA_CCB_EVT));
+        tMCA_CCB_MSG* p_evt_data = &mca_ccb_evt->api;
         p_evt_data->dcb_idx = mca_dcb_to_hdl(p_dcb);
         p_evt_data->mdep_id = peer_dep_id;
         p_evt_data->mdl_id = mdl_id;
@@ -428,10 +429,8 @@
         p_evt_data->op_code = MCA_OP_MDL_CREATE_REQ;
         p_evt_data->hdr.event = MCA_CCB_API_REQ_EVT;
         p_evt_data->hdr.layer_specific = false;
-        mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, (tMCA_CCB_EVT*)p_evt_data);
+        mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, mca_ccb_evt);
         return MCA_SUCCESS;
-      } else {
-        osi_free(p_evt_data);
       }
 
       mca_dcb_dealloc(p_dcb, NULL);
@@ -460,8 +459,6 @@
                              const tMCA_CHNL_CFG* p_chnl_cfg) {
   tMCA_RESULT result = MCA_BAD_HANDLE;
   tMCA_CCB* p_ccb = mca_ccb_by_hdl(mcl);
-  tMCA_CCB_MSG evt_data;
-  tMCA_DCB* p_dcb;
 
   MCA_TRACE_API("MCA_CreateMdlRsp: %d dep=%d mdl_id=%d cfg=%d rsp_code=%d", mcl,
                 dep, mdl_id, cfg, rsp_code);
@@ -474,10 +471,11 @@
     if (p_ccb->p_rx_msg && (p_ccb->p_rx_msg->mdep_id == dep) &&
         (p_ccb->p_rx_msg->mdl_id == mdl_id) &&
         (p_ccb->p_rx_msg->op_code == MCA_OP_MDL_CREATE_REQ)) {
+      tMCA_CCB_MSG evt_data;
       result = MCA_SUCCESS;
       evt_data.dcb_idx = 0;
       if (rsp_code == MCA_RSP_SUCCESS) {
-        p_dcb = mca_dcb_alloc(p_ccb, dep);
+        tMCA_DCB* p_dcb = mca_dcb_alloc(p_ccb, dep);
         if (p_dcb) {
           evt_data.dcb_idx = mca_dcb_to_hdl(p_dcb);
           p_dcb->p_chnl_cfg = p_chnl_cfg;
@@ -493,7 +491,9 @@
         evt_data.param = cfg;
         evt_data.rsp_code = rsp_code;
         evt_data.op_code = MCA_OP_MDL_CREATE_RSP;
-        mca_ccb_event(p_ccb, MCA_CCB_API_RSP_EVT, (tMCA_CCB_EVT*)&evt_data);
+        tMCA_CCB_EVT mca_ccb_evt;
+        mca_ccb_evt.api = evt_data;
+        mca_ccb_event(p_ccb, MCA_CCB_API_RSP_EVT, &mca_ccb_evt);
       }
     } else {
       MCA_TRACE_ERROR(
@@ -570,8 +570,9 @@
     p_dcb = mca_dcb_alloc(p_ccb, dep);
     result = MCA_NO_RESOURCES;
     if (p_dcb) {
-      tMCA_CCB_MSG* p_evt_data =
-          (tMCA_CCB_MSG*)osi_malloc(sizeof(tMCA_CCB_MSG));
+      tMCA_CCB_EVT* mca_ccb_evt =
+          (tMCA_CCB_EVT*)osi_malloc(sizeof(tMCA_CCB_EVT));
+      tMCA_CCB_MSG* p_evt_data = &mca_ccb_evt->api;
 
       p_dcb->p_chnl_cfg = p_chnl_cfg;
       p_dcb->mdl_id = mdl_id;
@@ -582,7 +583,7 @@
       p_evt_data->mdl_id = mdl_id;
       p_evt_data->op_code = MCA_OP_MDL_RECONNECT_REQ;
       p_evt_data->hdr.event = MCA_CCB_API_REQ_EVT;
-      mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, (tMCA_CCB_EVT*)p_evt_data);
+      mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, mca_ccb_evt);
       return MCA_SUCCESS;
     }
   }
@@ -607,7 +608,6 @@
                                 const tMCA_CHNL_CFG* p_chnl_cfg) {
   tMCA_RESULT result = MCA_BAD_HANDLE;
   tMCA_CCB* p_ccb = mca_ccb_by_hdl(mcl);
-  tMCA_CCB_MSG evt_data;
   tMCA_DCB* p_dcb;
 
   MCA_TRACE_API("MCA_ReconnectMdlRsp: %d ", mcl);
@@ -620,6 +620,7 @@
     if (p_ccb->p_rx_msg && (p_ccb->p_rx_msg->mdl_id == mdl_id) &&
         (p_ccb->p_rx_msg->op_code == MCA_OP_MDL_RECONNECT_REQ)) {
       result = MCA_SUCCESS;
+      tMCA_CCB_MSG evt_data;
       evt_data.dcb_idx = 0;
       if (rsp_code == MCA_RSP_SUCCESS) {
         p_dcb = mca_dcb_alloc(p_ccb, dep);
@@ -637,7 +638,9 @@
       evt_data.mdl_id = mdl_id;
       evt_data.rsp_code = rsp_code;
       evt_data.op_code = MCA_OP_MDL_RECONNECT_RSP;
-      mca_ccb_event(p_ccb, MCA_CCB_API_RSP_EVT, (tMCA_CCB_EVT*)&evt_data);
+      tMCA_CCB_EVT mca_ccb_evt;
+      mca_ccb_evt.api = evt_data;
+      mca_ccb_event(p_ccb, MCA_CCB_API_RSP_EVT, &mca_ccb_evt);
     } else {
       MCA_TRACE_ERROR(
           "The given MCL is not expecting a MCA_ReconnectMdlRsp with the given "
@@ -728,11 +731,12 @@
       return MCA_BUSY;
     }
 
-    tMCA_CCB_MSG* p_evt_data = (tMCA_CCB_MSG*)osi_malloc(sizeof(tMCA_CCB_MSG));
+    tMCA_CCB_EVT* mca_ccb_evt = (tMCA_CCB_EVT*)osi_malloc(sizeof(tMCA_CCB_EVT));
+    tMCA_CCB_MSG* p_evt_data = &mca_ccb_evt->api;
     result = MCA_SUCCESS;
     p_evt_data->op_code = MCA_OP_MDL_ABORT_REQ;
     p_evt_data->hdr.event = MCA_CCB_API_REQ_EVT;
-    mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, (tMCA_CCB_EVT*)p_evt_data);
+    mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, mca_ccb_evt);
   }
   return result;
 }
@@ -763,12 +767,13 @@
       return MCA_BAD_PARAMS;
     }
 
-    tMCA_CCB_MSG* p_evt_data = (tMCA_CCB_MSG*)osi_malloc(sizeof(tMCA_CCB_MSG));
+    tMCA_CCB_EVT* mca_ccb_evt = (tMCA_CCB_EVT*)osi_malloc(sizeof(tMCA_CCB_EVT));
+    tMCA_CCB_MSG* p_evt_data = &mca_ccb_evt->api;
     result = MCA_SUCCESS;
     p_evt_data->mdl_id = mdl_id;
     p_evt_data->op_code = MCA_OP_MDL_DELETE_REQ;
     p_evt_data->hdr.event = MCA_CCB_API_REQ_EVT;
-    mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, (tMCA_CCB_EVT*)p_evt_data);
+    mca_ccb_event(p_ccb, MCA_CCB_API_REQ_EVT, mca_ccb_evt);
   }
   return result;
 }
diff --git a/stack/mcap/mca_cact.cc b/stack/mcap/mca_cact.cc
index 5565944..96434e1 100644
--- a/stack/mcap/mca_cact.cc
+++ b/stack/mcap/mca_cact.cc
@@ -35,8 +35,6 @@
 
 #include "btu.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*****************************************************************************
  * constants
  ****************************************************************************/
@@ -132,8 +130,8 @@
       p_pkt->len = p - p_start;
       L2CA_DataWrite(p_ccb->lcid, p_pkt);
       period_ms_t interval_ms = p_ccb->p_rcb->reg.rsp_tout * 1000;
-      alarm_set_on_queue(p_ccb->mca_ccb_timer, interval_ms,
-                         mca_ccb_timer_timeout, p_ccb, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->mca_ccb_timer, interval_ms,
+                         mca_ccb_timer_timeout, p_ccb);
     }
     /* else the L2CAP channel is congested. keep the message to be sent later */
   } else {
@@ -544,7 +542,7 @@
   tMCA_CTRL evt_data;
   p_ccb->cong = false;
   evt_data.connect_ind.mtu = p_data->open.peer_mtu;
-  memcpy(evt_data.connect_ind.bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
+  evt_data.connect_ind.bd_addr = p_ccb->peer_addr;
   mca_ccb_report_event(p_ccb, MCA_CONNECT_IND_EVT, &evt_data);
 }
 
diff --git a/stack/mcap/mca_csm.cc b/stack/mcap/mca_csm.cc
index 3c437f6..9ff1915 100644
--- a/stack/mcap/mca_csm.cc
+++ b/stack/mcap/mca_csm.cc
@@ -178,7 +178,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-tMCA_CCB* mca_ccb_by_bd(tMCA_HANDLE handle, BD_ADDR bd_addr) {
+tMCA_CCB* mca_ccb_by_bd(tMCA_HANDLE handle, const RawAddress& bd_addr) {
   tMCA_CCB* p_ccb = NULL;
   tMCA_RCB* p_rcb = mca_rcb_by_handle(handle);
   tMCA_CCB* p_ccb_tmp;
@@ -189,7 +189,7 @@
     p_ccb_tmp = &mca_cb.ccb[i * MCA_NUM_LINKS];
     for (i = 0; i < MCA_NUM_LINKS; i++, p_ccb_tmp++) {
       if (p_ccb_tmp->state != MCA_CCB_NULL_ST &&
-          memcmp(p_ccb_tmp->peer_addr, bd_addr, BD_ADDR_LEN) == 0) {
+          p_ccb_tmp->peer_addr == bd_addr) {
         p_ccb = p_ccb_tmp;
         break;
       }
@@ -209,7 +209,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-tMCA_CCB* mca_ccb_alloc(tMCA_HANDLE handle, BD_ADDR bd_addr) {
+tMCA_CCB* mca_ccb_alloc(tMCA_HANDLE handle, const RawAddress& bd_addr) {
   tMCA_CCB* p_ccb = NULL;
   tMCA_RCB* p_rcb = mca_rcb_by_handle(handle);
   tMCA_CCB* p_ccb_tmp;
@@ -225,7 +225,7 @@
         p_ccb_tmp->mca_ccb_timer = alarm_new("mca.mca_ccb_timer");
         p_ccb_tmp->state = MCA_CCB_OPENING_ST;
         p_ccb_tmp->cong = true;
-        memcpy(p_ccb_tmp->peer_addr, bd_addr, BD_ADDR_LEN);
+        p_ccb_tmp->peer_addr = bd_addr;
         p_ccb = p_ccb_tmp;
         break;
       }
@@ -260,7 +260,7 @@
 
   if (p_data) {
     /* non-NULL -> an action function -> report disconnect event */
-    memcpy(evt_data.disconnect_ind.bd_addr, p_ccb->peer_addr, BD_ADDR_LEN);
+    evt_data.disconnect_ind.bd_addr = p_ccb->peer_addr;
     evt_data.disconnect_ind.reason = p_data->close.reason;
     mca_ccb_report_event(p_ccb, MCA_DISCONNECT_IND_EVT, &evt_data);
   }
diff --git a/stack/mcap/mca_dact.cc b/stack/mcap/mca_dact.cc
index a99d47c..d05f3cd 100644
--- a/stack/mcap/mca_dact.cc
+++ b/stack/mcap/mca_dact.cc
@@ -111,13 +111,14 @@
  *
  ******************************************************************************/
 void mca_dcb_do_disconn(tMCA_DCB* p_dcb, UNUSED_ATTR tMCA_DCB_EVT* p_data) {
-  tMCA_CLOSE close;
-
   if ((p_dcb->lcid == 0) || (L2CA_DisconnectReq(p_dcb->lcid) == false)) {
+    tMCA_CLOSE close;
     close.param = MCA_INT;
     close.reason = L2CAP_DISC_OK;
     close.lcid = 0;
-    mca_dcb_event(p_dcb, MCA_DCB_TC_CLOSE_EVT, (tMCA_DCB_EVT*)&close);
+    tMCA_DCB_EVT mca_dcb_evt;
+    mca_dcb_evt.close = close;
+    mca_dcb_event(p_dcb, MCA_DCB_TC_CLOSE_EVT, &mca_dcb_evt);
   }
 }
 
diff --git a/stack/mcap/mca_int.h b/stack/mcap/mca_int.h
index b2e449b..55765fd 100644
--- a/stack/mcap/mca_int.h
+++ b/stack/mcap/mca_int.h
@@ -218,7 +218,7 @@
   alarm_t* mca_ccb_timer; /* MCA CCB timer entry */
   tMCA_CCB_MSG* p_tx_req; /* Current request being sent/awaiting response */
   tMCA_CCB_MSG* p_rx_msg; /* Current message received/being processed */
-  BD_ADDR peer_addr;      /* BD address of peer */
+  RawAddress peer_addr;   /* BD address of peer */
   uint16_t sec_mask;      /* Security mask for connections as initiator */
   uint16_t ctrl_vpsm;     /* The virtual PSM that peer is listening for control
                              channel */
@@ -278,8 +278,8 @@
 
 /* csm functions */
 extern void mca_ccb_event(tMCA_CCB* p_ccb, uint8_t event, tMCA_CCB_EVT* p_data);
-extern tMCA_CCB* mca_ccb_by_bd(tMCA_HANDLE handle, BD_ADDR bd_addr);
-extern tMCA_CCB* mca_ccb_alloc(tMCA_HANDLE handle, BD_ADDR bd_addr);
+extern tMCA_CCB* mca_ccb_by_bd(tMCA_HANDLE handle, const RawAddress& bd_addr);
+extern tMCA_CCB* mca_ccb_alloc(tMCA_HANDLE handle, const RawAddress& bd_addr);
 extern void mca_ccb_rsp_tout(tMCA_CCB* p_ccb, tMCA_CCB_EVT* p_data);
 extern void mca_ccb_dealloc(tMCA_CCB* p_ccb, tMCA_CCB_EVT* p_data);
 extern tMCA_CL mca_ccb_to_hdl(tMCA_CCB* p_ccb);
@@ -337,13 +337,13 @@
 extern void mca_stop_timer(tMCA_CCB* p_ccb);
 
 /* l2c functions */
-extern uint16_t mca_l2c_open_req(BD_ADDR bd_addr, uint16_t PSM,
+extern uint16_t mca_l2c_open_req(const RawAddress& bd_addr, uint16_t PSM,
                                  const tMCA_CHNL_CFG* p_chnl_cfg);
 
 /* callback function declarations */
-extern void mca_l2c_cconn_ind_cback(BD_ADDR bd_addr, uint16_t lcid,
+extern void mca_l2c_cconn_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
                                     uint16_t psm, uint8_t id);
-extern void mca_l2c_dconn_ind_cback(BD_ADDR bd_addr, uint16_t lcid,
+extern void mca_l2c_dconn_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
                                     uint16_t psm, uint8_t id);
 extern void mca_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result);
 extern void mca_l2c_config_cfm_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
diff --git a/stack/mcap/mca_l2c.cc b/stack/mcap/mca_l2c.cc
index fc08776..78a17ae 100644
--- a/stack/mcap/mca_l2c.cc
+++ b/stack/mcap/mca_l2c.cc
@@ -66,7 +66,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void mca_sec_check_complete_term(BD_ADDR bd_addr,
+static void mca_sec_check_complete_term(const RawAddress* bd_addr,
                                         UNUSED_ATTR tBT_TRANSPORT transport,
                                         void* p_ref_data, uint8_t res) {
   tMCA_TC_TBL* p_tbl = (tMCA_TC_TBL*)p_ref_data;
@@ -85,7 +85,7 @@
     ertm_info.fcr_rx_buf_size = MCA_FCR_RX_BUF_SIZE;
     ertm_info.fcr_tx_buf_size = MCA_FCR_TX_BUF_SIZE;
     /* Send response to the L2CAP layer. */
-    L2CA_ErtmConnectRsp(bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK,
+    L2CA_ErtmConnectRsp(*bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK,
                         L2CAP_CONN_OK, &ertm_info);
 
     /* transition to configuration state */
@@ -95,7 +95,7 @@
     mca_set_cfg_by_tbl(&cfg, p_tbl);
     L2CA_ConfigReq(p_tbl->lcid, &cfg);
   } else {
-    L2CA_ConnectRsp(bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_SECURITY_BLOCK,
+    L2CA_ConnectRsp(*bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_SECURITY_BLOCK,
                     L2CAP_CONN_OK);
     mca_tc_close_ind(p_tbl, L2CAP_CONN_SECURITY_BLOCK);
   }
@@ -111,7 +111,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void mca_sec_check_complete_orig(UNUSED_ATTR BD_ADDR bd_addr,
+static void mca_sec_check_complete_orig(UNUSED_ATTR const RawAddress* bd_addr,
                                         UNUSED_ATTR tBT_TRANSPORT transport,
                                         void* p_ref_data, uint8_t res) {
   tMCA_TC_TBL* p_tbl = (tMCA_TC_TBL*)p_ref_data;
@@ -140,8 +140,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void mca_l2c_cconn_ind_cback(BD_ADDR bd_addr, uint16_t lcid, uint16_t psm,
-                             uint8_t id) {
+void mca_l2c_cconn_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
+                             uint16_t psm, uint8_t id) {
   tMCA_HANDLE handle = mca_handle_by_cpsm(psm);
   tMCA_CCB* p_ccb;
   tMCA_TC_TBL* p_tbl = NULL;
@@ -213,8 +213,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void mca_l2c_dconn_ind_cback(BD_ADDR bd_addr, uint16_t lcid, uint16_t psm,
-                             uint8_t id) {
+void mca_l2c_dconn_ind_cback(const RawAddress& bd_addr, uint16_t lcid,
+                             uint16_t psm, uint8_t id) {
   tMCA_HANDLE handle = mca_handle_by_dpsm(psm);
   tMCA_CCB* p_ccb;
   tMCA_DCB* p_dcb;
@@ -515,7 +515,7 @@
  * Returns          void.
  *
  ******************************************************************************/
-uint16_t mca_l2c_open_req(BD_ADDR bd_addr, uint16_t psm,
+uint16_t mca_l2c_open_req(const RawAddress& bd_addr, uint16_t psm,
                           const tMCA_CHNL_CFG* p_chnl_cfg) {
   tL2CAP_ERTM_INFO ertm_info;
 
diff --git a/stack/mcap/mca_main.cc b/stack/mcap/mca_main.cc
index 9f9dbaf..1cc8e75 100644
--- a/stack/mcap/mca_main.cc
+++ b/stack/mcap/mca_main.cc
@@ -272,11 +272,6 @@
 void mca_tc_close_ind(tMCA_TC_TBL* p_tbl, uint16_t reason) {
   tMCA_CCB* p_ccb;
   tMCA_DCB* p_dcb;
-  tMCA_CLOSE close;
-
-  close.param = MCA_ACP;
-  close.reason = reason;
-  close.lcid = p_tbl->lcid;
 
   MCA_TRACE_DEBUG("%s() - tcid: %d, cb_idx:%d, old: %d", __func__, p_tbl->tcid,
                   p_tbl->cb_idx, p_tbl->state);
@@ -284,22 +279,30 @@
   /* Check if the transport channel is in use */
   if (p_tbl->state == MCA_TC_ST_UNUSED) return;
 
+  tMCA_CLOSE close;
+
+  close.param = MCA_ACP;
+  close.reason = reason;
+  close.lcid = p_tbl->lcid;
+
   /* clear mca_tc_tbl entry */
   if (p_tbl->cfg_flags & MCA_L2C_CFG_DISCN_INT) close.param = MCA_INT;
   p_tbl->cfg_flags = 0;
   p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
 
-  /* if control channel, notify ccb that channel close */
+  /* if control channel, notify ccb of the channel close */
   if (p_tbl->tcid == MCA_CTRL_TCID) {
     p_ccb = mca_ccb_by_hdl((tMCA_CL)p_tbl->cb_idx);
-    mca_ccb_event(p_ccb, MCA_CCB_LL_CLOSE_EVT, (tMCA_CCB_EVT*)&close);
-  }
-  /* notify dcb that channel close */
-  else {
-    /* look up dcb  */
+    tMCA_CCB_EVT mca_ccb_evt;
+    mca_ccb_evt.close = close;
+    mca_ccb_event(p_ccb, MCA_CCB_LL_CLOSE_EVT, &mca_ccb_evt);
+  } else {
+    /* notify dcb of the channel close */
     p_dcb = mca_dcb_by_hdl(p_tbl->cb_idx);
     if (p_dcb != NULL) {
-      mca_dcb_event(p_dcb, MCA_DCB_TC_CLOSE_EVT, (tMCA_DCB_EVT*)&close);
+      tMCA_DCB_EVT mca_dcb_evt;
+      mca_dcb_evt.close = close;
+      mca_dcb_event(p_dcb, MCA_DCB_TC_CLOSE_EVT, &mca_dcb_evt);
     }
   }
   p_tbl->state = MCA_TC_ST_UNUSED;
@@ -334,20 +337,21 @@
     open.param = MCA_ACP;
   }
 
-  /* if control channel, notify ccb that channel open */
+  /* if control channel, notify ccb that the channel is open */
   if (p_tbl->tcid == MCA_CTRL_TCID) {
     p_ccb = mca_ccb_by_hdl((tMCA_CL)p_tbl->cb_idx);
-
-    mca_ccb_event(p_ccb, MCA_CCB_LL_OPEN_EVT, (tMCA_CCB_EVT*)&open);
-  }
-  /* must be data channel, notify dcb that channel open */
-  else {
-    /* look up dcb */
+    tMCA_CCB_EVT mca_ccb_evt;
+    mca_ccb_evt.open = open;
+    mca_ccb_event(p_ccb, MCA_CCB_LL_OPEN_EVT, &mca_ccb_evt);
+  } else {
+    /* must be data channel, notify dcb that the channel is open */
     p_dcb = mca_dcb_by_hdl(p_tbl->cb_idx);
 
     /* put lcid in event data */
     if (p_dcb != NULL) {
-      mca_dcb_event(p_dcb, MCA_DCB_TC_OPEN_EVT, (tMCA_DCB_EVT*)&open);
+      tMCA_DCB_EVT mca_dcb_evt;
+      mca_dcb_evt.open = open;
+      mca_dcb_event(p_dcb, MCA_DCB_TC_OPEN_EVT, &mca_dcb_evt);
     }
   }
 }
@@ -376,14 +380,16 @@
   /* if control channel, notify ccb of congestion */
   if (p_tbl->tcid == MCA_CTRL_TCID) {
     p_ccb = mca_ccb_by_hdl((tMCA_CL)p_tbl->cb_idx);
-    mca_ccb_event(p_ccb, MCA_CCB_LL_CONG_EVT, (tMCA_CCB_EVT*)&is_congested);
-  }
-  /* notify dcb that channel open */
-  else {
-    /* look up dcb by cb_idx */
+    tMCA_CCB_EVT mca_ccb_evt;
+    mca_ccb_evt.llcong = is_congested;
+    mca_ccb_event(p_ccb, MCA_CCB_LL_CONG_EVT, &mca_ccb_evt);
+  } else {
+    /* notify dcb that channel open */
     p_dcb = mca_dcb_by_hdl(p_tbl->cb_idx);
     if (p_dcb != NULL) {
-      mca_dcb_event(p_dcb, MCA_DCB_TC_CONG_EVT, (tMCA_DCB_EVT*)&is_congested);
+      tMCA_DCB_EVT mca_dcb_evt;
+      mca_dcb_evt.llcong = is_congested;
+      mca_dcb_event(p_dcb, MCA_DCB_TC_CONG_EVT, &mca_dcb_evt);
     }
   }
 }
diff --git a/stack/pan/pan_api.cc b/stack/pan/pan_api.cc
index 997d7c9..a36793c 100644
--- a/stack/pan/pan_api.cc
+++ b/stack/pan/pan_api.cc
@@ -24,6 +24,7 @@
  *****************************************************************************/
 
 #include "pan_api.h"
+#include <base/logging.h>
 #include <string.h>
 #include "bnep_api.h"
 #include "bt_common.h"
@@ -169,7 +170,7 @@
     bta_sys_add_uuid(UUID_SERVCLASS_NAP);
   }
   /* If the NAP role is already active and now being cleared delete the record
-     */
+   */
   else if (pan_cb.role & PAN_ROLE_NAP_SERVER) {
     if (pan_cb.pan_nap_sdp_handle != 0) {
       SDP_DeleteRecord(pan_cb.pan_nap_sdp_handle);
@@ -221,7 +222,7 @@
     bta_sys_add_uuid(UUID_SERVCLASS_PANU);
   }
   /* If the PANU role is already active and now being cleared delete the record
-     */
+   */
   else if (pan_cb.role & PAN_ROLE_CLIENT) {
     if (pan_cb.pan_user_sdp_handle != 0) {
       SDP_DeleteRecord(pan_cb.pan_user_sdp_handle);
@@ -263,8 +264,8 @@
  *                                     allowed at that point of time
  *
  ******************************************************************************/
-tPAN_RESULT PAN_Connect(BD_ADDR rem_bda, uint8_t src_role, uint8_t dst_role,
-                        uint16_t* handle) {
+tPAN_RESULT PAN_Connect(const RawAddress& rem_bda, uint8_t src_role,
+                        uint8_t dst_role, uint16_t* handle) {
   tPAN_CONN* pcb;
   tBNEP_RESULT result;
   tBT_UUID src_uuid, dst_uuid;
@@ -350,8 +351,7 @@
   }
   BTM_SetOutService(rem_bda, BTM_SEC_SERVICE_BNEP_PANU, mx_chan_id);
 
-  PAN_TRACE_API("PAN_Connect() for BD Addr %x.%x.%x.%x.%x.%x", rem_bda[0],
-                rem_bda[1], rem_bda[2], rem_bda[3], rem_bda[4], rem_bda[5]);
+  VLOG(0) << __func__ << " for BD Addr: " << rem_bda;
   if (pcb->con_state == PAN_STATE_IDLE) {
     pan_cb.num_conns++;
   } else if (pcb->con_state == PAN_STATE_CONNECTED) {
@@ -447,9 +447,9 @@
  *                                           there is an error in sending data
  *
  ******************************************************************************/
-tPAN_RESULT PAN_Write(uint16_t handle, BD_ADDR dst, BD_ADDR src,
-                      uint16_t protocol, uint8_t* p_data, uint16_t len,
-                      bool ext) {
+tPAN_RESULT PAN_Write(uint16_t handle, const RawAddress& dst,
+                      const RawAddress& src, uint16_t protocol, uint8_t* p_data,
+                      uint16_t len, bool ext) {
   if (pan_cb.role == PAN_ROLE_INACTIVE || !pan_cb.num_conns) {
     PAN_TRACE_ERROR("%s PAN is not active, data write failed.", __func__);
     return PAN_FAILURE;
@@ -459,11 +459,11 @@
   // a copy of the packet for each connection. We can save one extra copy
   // by fast-pathing here and calling BNEP_Write instead of placing the packet
   // in a BT_HDR buffer, calling BNEP_Write, and then freeing the buffer.
-  if (dst[0] & 0x01) {
+  if (dst.address[0] & 0x01) {
     int i;
     for (i = 0; i < MAX_PAN_CONNS; ++i) {
       if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED)
-        BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
+        BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src, ext);
     }
     return PAN_SUCCESS;
   }
@@ -500,8 +500,9 @@
  *                                           there is an error in sending data
  *
  ******************************************************************************/
-tPAN_RESULT PAN_WriteBuf(uint16_t handle, BD_ADDR dst, BD_ADDR src,
-                         uint16_t protocol, BT_HDR* p_buf, bool ext) {
+tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst,
+                         const RawAddress& src, uint16_t protocol,
+                         BT_HDR* p_buf, bool ext) {
   tPAN_CONN* pcb;
   uint16_t i;
   tBNEP_RESULT result;
@@ -513,11 +514,11 @@
   }
 
   /* Check if it is broadcast or multicast packet */
-  if (dst[0] & 0x01) {
+  if (dst.address[0] & 0x01) {
     uint8_t* data = (uint8_t*)p_buf + sizeof(BT_HDR) + p_buf->offset;
     for (i = 0; i < MAX_PAN_CONNS; ++i) {
       if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED)
-        BNEP_Write(pan_cb.pcb[i].handle, dst, data, p_buf->len, protocol, src,
+        BNEP_Write(pan_cb.pcb[i].handle, dst, data, p_buf->len, protocol, &src,
                    ext);
     }
     osi_free(p_buf);
@@ -540,7 +541,7 @@
     }
 
     result =
-        BNEP_WriteBuf(pan_cb.pcb[i].handle, dst, p_buf, protocol, src, ext);
+        BNEP_WriteBuf(pan_cb.pcb[i].handle, dst, p_buf, protocol, &src, ext);
     if (result == BNEP_IGNORE_CMD) {
       PAN_TRACE_DEBUG("PAN ignored data write for PANU connection");
       return result;
@@ -567,7 +568,7 @@
     return PAN_FAILURE;
   }
 
-  result = BNEP_WriteBuf(pcb->handle, dst, p_buf, protocol, src, ext);
+  result = BNEP_WriteBuf(pcb->handle, dst, p_buf, protocol, &src, ext);
   if (result == BNEP_IGNORE_CMD) {
     PAN_TRACE_DEBUG("PAN ignored data buf write to PANU");
     return result;
diff --git a/stack/pan/pan_int.h b/stack/pan/pan_int.h
index b9cd343..27fe666 100644
--- a/stack/pan/pan_int.h
+++ b/stack/pan/pan_int.h
@@ -30,7 +30,7 @@
 /*
  * This role is used to shutdown the profile. Used internally
  * Applications should call PAN_Deregister to shutdown the profile
-*/
+ */
 #define PAN_ROLE_INACTIVE 0
 
 /* Protocols supported by the host internal stack, are registered with SDP */
@@ -40,7 +40,7 @@
 #define PAN_PROFILE_VERSION 0x0100 /* Version 1.00 */
 
 /* Define the PAN Connection Control Block
-*/
+ */
 typedef struct {
 #define PAN_STATE_IDLE 0
 #define PAN_STATE_CONN_START 1
@@ -51,7 +51,7 @@
   uint8_t con_flags;
 
   uint16_t handle;
-  BD_ADDR rem_bda;
+  RawAddress rem_bda;
 
   uint16_t bad_pkts_rcvd;
   uint16_t src_uuid;
@@ -64,7 +64,7 @@
 } tPAN_CONN;
 
 /*  The main PAN control block
-*/
+ */
 typedef struct {
   uint8_t role;
   uint8_t active_role;
@@ -92,21 +92,22 @@
 } tPAN_CB;
 
 /* Global PAN data
-*/
+ */
 extern tPAN_CB pan_cb;
 
 /******************************************************************************/
 extern void pan_register_with_bnep(void);
-extern void pan_conn_ind_cb(uint16_t handle, BD_ADDR p_bda,
+extern void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda,
                             tBT_UUID* remote_uuid, tBT_UUID* local_uuid,
                             bool is_role_change);
-extern void pan_connect_state_cb(uint16_t handle, BD_ADDR rem_bda,
+extern void pan_connect_state_cb(uint16_t handle, const RawAddress& rem_bda,
                                  tBNEP_RESULT result, bool is_role_change);
-extern void pan_data_ind_cb(uint16_t handle, uint8_t* src, uint8_t* dst,
-                            uint16_t protocol, uint8_t* p_data, uint16_t len,
-                            bool fw_ext_present);
-extern void pan_data_buf_ind_cb(uint16_t handle, uint8_t* src, uint8_t* dst,
-                                uint16_t protocol, BT_HDR* p_buf, bool ext);
+extern void pan_data_ind_cb(uint16_t handle, const RawAddress& src,
+                            const RawAddress& dst, uint16_t protocol,
+                            uint8_t* p_data, uint16_t len, bool fw_ext_present);
+extern void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src,
+                                const RawAddress& dst, uint16_t protocol,
+                                BT_HDR* p_buf, bool ext);
 extern void pan_tx_data_flow_cb(uint16_t handle, tBNEP_RESULT event);
 void pan_proto_filt_ind_cb(uint16_t handle, bool indication,
                            tBNEP_RESULT result, uint16_t num_filters,
@@ -116,9 +117,9 @@
                            uint8_t* p_filters);
 extern uint32_t pan_register_with_sdp(uint16_t uuid, uint8_t sec_mask,
                                       const char* p_name, const char* p_desc);
-extern tPAN_CONN* pan_allocate_pcb(BD_ADDR p_bda, uint16_t handle);
+extern tPAN_CONN* pan_allocate_pcb(const RawAddress& p_bda, uint16_t handle);
 extern tPAN_CONN* pan_get_pcb_by_handle(uint16_t handle);
-extern tPAN_CONN* pan_get_pcb_by_addr(BD_ADDR p_bda);
+extern tPAN_CONN* pan_get_pcb_by_addr(const RawAddress& p_bda);
 extern void pan_close_all_connections(void);
 extern void pan_release_pcb(tPAN_CONN* p_pcb);
 extern void pan_dump_status(void);
diff --git a/stack/pan/pan_main.cc b/stack/pan/pan_main.cc
index 01e1ea4..d7cd27b 100644
--- a/stack/pan/pan_main.cc
+++ b/stack/pan/pan_main.cc
@@ -89,8 +89,9 @@
  * Returns          none
  *
  ******************************************************************************/
-void pan_conn_ind_cb(uint16_t handle, BD_ADDR p_bda, tBT_UUID* remote_uuid,
-                     tBT_UUID* local_uuid, bool is_role_change) {
+void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda,
+                     tBT_UUID* remote_uuid, tBT_UUID* local_uuid,
+                     bool is_role_change) {
   tPAN_CONN* pcb;
   uint8_t req_role;
   bool wrong_uuid;
@@ -346,7 +347,8 @@
  * Returns          none
  *
  ******************************************************************************/
-void pan_connect_state_cb(uint16_t handle, UNUSED_ATTR BD_ADDR rem_bda,
+void pan_connect_state_cb(uint16_t handle,
+                          UNUSED_ATTR const RawAddress& rem_bda,
                           tBNEP_RESULT result, bool is_role_change) {
   tPAN_CONN* pcb;
   uint8_t peer_role;
@@ -445,9 +447,9 @@
  * Returns          none
  *
  ******************************************************************************/
-void pan_data_ind_cb(uint16_t handle, uint8_t* src, uint8_t* dst,
-                     uint16_t protocol, uint8_t* p_data, uint16_t len,
-                     bool ext) {
+void pan_data_ind_cb(uint16_t handle, const RawAddress& src,
+                     const RawAddress& dst, uint16_t protocol, uint8_t* p_data,
+                     uint16_t len, bool ext) {
   tPAN_CONN* pcb;
   uint16_t i;
   bool forward;
@@ -477,14 +479,14 @@
   }
 
   /* Check if it is broadcast packet */
-  if (dst[0] & 0x01) {
+  if (dst.address[0] & 0x01) {
     PAN_TRACE_DEBUG("PAN received broadcast packet on handle %d, src uuid 0x%x",
                     handle, pcb->src_uuid);
     for (i = 0; i < MAX_PAN_CONNS; i++) {
       if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
           pan_cb.pcb[i].handle != handle &&
           pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
-        BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
+        BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src, ext);
       }
     }
 
@@ -499,8 +501,8 @@
   for (i = 0; i < MAX_PAN_CONNS; i++) {
     if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
         pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
-      if (memcmp(pan_cb.pcb[i].rem_bda, dst, BD_ADDR_LEN) == 0) {
-        BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext);
+      if (pan_cb.pcb[i].rem_bda == dst) {
+        BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src, ext);
         return;
       }
     }
@@ -539,8 +541,9 @@
  * Returns          none
  *
  ******************************************************************************/
-void pan_data_buf_ind_cb(uint16_t handle, uint8_t* src, uint8_t* dst,
-                         uint16_t protocol, BT_HDR* p_buf, bool ext) {
+void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src,
+                         const RawAddress& dst, uint16_t protocol,
+                         BT_HDR* p_buf, bool ext) {
   tPAN_CONN *pcb, *dst_pcb;
   tBNEP_RESULT result;
   uint16_t i, len;
@@ -576,7 +579,7 @@
 
   /* Check if it is broadcast or multicast packet */
   if (pcb->src_uuid != UUID_SERVCLASS_PANU) {
-    if (dst[0] & 0x01) {
+    if (dst.address[0] & 0x01) {
       PAN_TRACE_DEBUG(
           "PAN received broadcast packet on handle %d, src uuid 0x%x", handle,
           pcb->src_uuid);
@@ -584,7 +587,7 @@
         if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED &&
             pan_cb.pcb[i].handle != handle &&
             pcb->src_uuid == pan_cb.pcb[i].src_uuid) {
-          BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src,
+          BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src,
                      ext);
         }
       }
@@ -609,7 +612,7 @@
           __func__, dst_pcb->handle, len);
 
       result =
-          BNEP_Write(dst_pcb->handle, dst, p_data, len, protocol, src, ext);
+          BNEP_Write(dst_pcb->handle, dst, p_data, len, protocol, &src, ext);
       if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD)
         PAN_TRACE_ERROR("Failed to write data for PAN connection handle %d",
                         dst_pcb->handle);
@@ -637,10 +640,10 @@
  * Function         pan_proto_filt_ind_cb
  *
  * Description      This function is registered with BNEP to receive tx data
- *					flow status
+ *          flow status
  *
  * Parameters:      handle      - handle for the connection
- *					event       - flow status
+ *          event       - flow status
  *
  * Returns          none
  *
diff --git a/stack/pan/pan_utils.cc b/stack/pan/pan_utils.cc
index 7f75135..b2eed2d 100644
--- a/stack/pan/pan_utils.cc
+++ b/stack/pan/pan_utils.cc
@@ -23,6 +23,7 @@
  *
  *****************************************************************************/
 
+#include <base/logging.h>
 #include <stdio.h>
 #include <string.h>
 #include "bnep_api.h"
@@ -44,7 +45,7 @@
     0x19, 0x00, 0x0F, /* UUID for BNEP - 0x000F */
     0x09, 0x01,
     0x00, /* BNEP specific parameter 0 -- Version of BNEP = version 1 = 0x0001
-             */
+           */
     0x35,
     0x06, /* BNEP specific parameter 1 -- Supported network packet type list */
     0x09, 0x08, 0x00, /* network packet type IPv4 = 0x0800 */
@@ -174,7 +175,7 @@
  * Returns
  *
  ******************************************************************************/
-tPAN_CONN* pan_allocate_pcb(BD_ADDR p_bda, uint16_t handle) {
+tPAN_CONN* pan_allocate_pcb(const RawAddress& p_bda, uint16_t handle) {
   uint16_t i;
 
   for (i = 0; i < MAX_PAN_CONNS; i++) {
@@ -185,14 +186,14 @@
 
   for (i = 0; i < MAX_PAN_CONNS; i++) {
     if (pan_cb.pcb[i].con_state != PAN_STATE_IDLE &&
-        memcmp(pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN) == 0)
+        pan_cb.pcb[i].rem_bda == p_bda)
       return NULL;
   }
 
   for (i = 0; i < MAX_PAN_CONNS; i++) {
     if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE) {
       memset(&(pan_cb.pcb[i]), 0, sizeof(tPAN_CONN));
-      memcpy(pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN);
+      pan_cb.pcb[i].rem_bda = p_bda;
       pan_cb.pcb[i].handle = handle;
       return &(pan_cb.pcb[i]);
     }
@@ -230,18 +231,17 @@
  * Returns
  *
  ******************************************************************************/
-tPAN_CONN* pan_get_pcb_by_addr(BD_ADDR p_bda) {
+tPAN_CONN* pan_get_pcb_by_addr(const RawAddress& p_bda) {
   uint16_t i;
 
   for (i = 0; i < MAX_PAN_CONNS; i++) {
     if (pan_cb.pcb[i].con_state == PAN_STATE_IDLE) continue;
 
-    if (memcmp(pan_cb.pcb[i].rem_bda, p_bda, BD_ADDR_LEN) == 0)
-      return &(pan_cb.pcb[i]);
+    if (pan_cb.pcb[i].rem_bda == p_bda) return &(pan_cb.pcb[i]);
 
     /*
     if (pan_cb.pcb[i].mfilter_present &&
-        (memcmp (p_bda, pan_cb.pcb[i].multi_cast_bridge, BD_ADDR_LEN) == 0))
+        p_bda == pan_cb.pcb[i].multi_cast_bridge)
         return &(pan_cb.pcb[i]);
     */
   }
@@ -301,21 +301,15 @@
 void pan_dump_status(void) {
 #if (PAN_SUPPORTS_DEBUG_DUMP == TRUE)
   uint16_t i;
-  char buff[200];
   tPAN_CONN* p_pcb;
 
   PAN_TRACE_DEBUG("PAN role %x, active role %d, num_conns %d", pan_cb.role,
                   pan_cb.active_role, pan_cb.num_conns);
 
   for (i = 0, p_pcb = pan_cb.pcb; i < MAX_PAN_CONNS; i++, p_pcb++) {
-    snprintf(buff, sizeof(buff),
-             "%d state %d, handle %d, src 0x%x, dst 0x%x, BD %x.%x.%x.%x.%x.%x",
-             i, p_pcb->con_state, p_pcb->handle, p_pcb->src_uuid,
-             p_pcb->dst_uuid, p_pcb->rem_bda[0], p_pcb->rem_bda[1],
-             p_pcb->rem_bda[2], p_pcb->rem_bda[3], p_pcb->rem_bda[4],
-             p_pcb->rem_bda[5]);
-
-    PAN_TRACE_DEBUG(buff);
+    VLOG(1) << +i << " state:" << p_pcb->con_state
+            << ", handle:" << p_pcb->handle << ", src" << p_pcb->src_uuid
+            << ", BD:" << p_pcb->rem_bda;
   }
 #endif
 }
diff --git a/stack/rfcomm/port_api.cc b/stack/rfcomm/port_api.cc
index de4cf0b..808b567 100644
--- a/stack/rfcomm/port_api.cc
+++ b/stack/rfcomm/port_api.cc
@@ -24,6 +24,7 @@
 
 #define LOG_TAG "bt_port_api"
 
+#include <base/logging.h>
 #include <string.h>
 
 #include "osi/include/log.h"
@@ -94,7 +95,7 @@
  *                                 the peer device (client).
  *                  is_server    - true if requesting application is a server
  *                  mtu          - Maximum frame size the application can accept
- *                  bd_addr      - BD_ADDR of the peer (client)
+ *                  bd_addr      - address of the peer (client)
  *                  mask         - specifies events to be enabled.  A value
  *                                 of zero disables all events.
  *                  p_handle     - OUT pointer to the handle.
@@ -112,17 +113,14 @@
  *
  ******************************************************************************/
 int RFCOMM_CreateConnection(uint16_t uuid, uint8_t scn, bool is_server,
-                            uint16_t mtu, BD_ADDR bd_addr, uint16_t* p_handle,
-                            tPORT_CALLBACK* p_mgmt_cb) {
+                            uint16_t mtu, const RawAddress& bd_addr,
+                            uint16_t* p_handle, tPORT_CALLBACK* p_mgmt_cb) {
   tPORT* p_port;
-  int i;
   uint8_t dlci;
   tRFC_MCB* p_mcb = port_find_mcb(bd_addr);
   uint16_t rfcomm_mtu;
 
-  RFCOMM_TRACE_API(
-      "RFCOMM_CreateConnection()  BDA: %02x-%02x-%02x-%02x-%02x-%02x",
-      bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
+  VLOG(0) << __func__ << " BDA: " << bd_addr;
 
   *p_handle = 0;
 
@@ -228,7 +226,7 @@
 
   p_port->p_mgmt_callback = p_mgmt_cb;
 
-  for (i = 0; i < BD_ADDR_LEN; i++) p_port->bd_addr[i] = bd_addr[i];
+  p_port->bd_addr = bd_addr;
 
   /* If this is not initiator of the connection need to just wait */
   if (p_port->is_server) {
@@ -482,7 +480,8 @@
  *                  p_lcid     - OUT L2CAP's LCID
  *
  ******************************************************************************/
-int PORT_CheckConnection(uint16_t handle, BD_ADDR bd_addr, uint16_t* p_lcid) {
+int PORT_CheckConnection(uint16_t handle, RawAddress& bd_addr,
+                         uint16_t* p_lcid) {
   tPORT* p_port;
 
   RFCOMM_TRACE_API("PORT_CheckConnection() handle:%d", handle);
@@ -503,7 +502,7 @@
     return (PORT_LINE_ERR);
   }
 
-  memcpy(bd_addr, p_port->rfc.p_mcb->bd_addr, BD_ADDR_LEN);
+  bd_addr = p_port->rfc.p_mcb->bd_addr;
   if (p_lcid) *p_lcid = p_port->rfc.p_mcb->lcid;
 
   return (PORT_SUCCESS);
@@ -520,7 +519,7 @@
  *                  bd_addr    - bd_addr of the peer
  *
  ******************************************************************************/
-bool PORT_IsOpening(BD_ADDR bd_addr) {
+bool PORT_IsOpening(RawAddress& bd_addr) {
   uint8_t xx, yy;
   tRFC_MCB* p_mcb = NULL;
   tPORT* p_port;
@@ -530,7 +529,7 @@
   for (xx = 0; xx < MAX_BD_CONNECTIONS; xx++) {
     if ((rfc_cb.port.rfc_mcb[xx].state > RFC_MX_STATE_IDLE) &&
         (rfc_cb.port.rfc_mcb[xx].state < RFC_MX_STATE_CONNECTED)) {
-      memcpy(bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
+      bd_addr = rfc_cb.port.rfc_mcb[xx].bd_addr;
       return true;
     }
 
@@ -549,7 +548,7 @@
       if ((!found_port) ||
           (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) {
         /* Port is not established yet. */
-        memcpy(bd_addr, rfc_cb.port.rfc_mcb[xx].bd_addr, BD_ADDR_LEN);
+        bd_addr = rfc_cb.port.rfc_mcb[xx].bd_addr;
         return true;
       }
     }
diff --git a/stack/rfcomm/port_int.h b/stack/rfcomm/port_int.h
index 8534e30..018a9fa 100644
--- a/stack/rfcomm/port_int.h
+++ b/stack/rfcomm/port_int.h
@@ -92,7 +92,7 @@
   fixed_queue_t* cmd_q; /* Queue for command messages on this mux */
   uint8_t port_inx[RFCOMM_MAX_DLCI + 1]; /* Array for quick access to  */
                                          /* tPORT based on dlci        */
-  BD_ADDR bd_addr;                       /* BD ADDR of the peer if initiator */
+  RawAddress bd_addr;                    /* BD ADDR of the peer if initiator */
   uint16_t lcid;                         /* Local cid used for this channel */
   uint16_t peer_l2cap_mtu; /* Max frame that can be sent to peer L2CAP */
   uint8_t state;           /* Current multiplexer channel state */
@@ -152,7 +152,7 @@
   uint8_t scn;   /* Service channel number */
   uint16_t uuid; /* Service UUID */
 
-  BD_ADDR bd_addr; /* BD ADDR of the device for the multiplexer channel */
+  RawAddress bd_addr; /* BD ADDR of the device for the multiplexer channel */
   bool is_server;  /* true if the server application */
   uint8_t dlci;    /* DLCI of the connection */
 
@@ -215,14 +215,14 @@
 /*
  * Functions provided by the port_utils.cc
 */
-extern tPORT* port_allocate_port(uint8_t dlci, BD_ADDR bd_addr);
+extern tPORT* port_allocate_port(uint8_t dlci, const RawAddress& bd_addr);
 extern void port_set_defaults(tPORT* p_port);
 extern void port_select_mtu(tPORT* p_port);
 extern void port_release_port(tPORT* p_port);
 extern tPORT* port_find_mcb_dlci_port(tRFC_MCB* p_mcb, uint8_t dlci);
-extern tRFC_MCB* port_find_mcb(BD_ADDR bd_addr);
+extern tRFC_MCB* port_find_mcb(const RawAddress& bd_addr);
 extern tPORT* port_find_dlci_port(uint8_t dlci);
-extern tPORT* port_find_port(uint8_t dlci, BD_ADDR bd_addr);
+extern tPORT* port_find_port(uint8_t dlci, const RawAddress& bd_addr);
 extern uint32_t port_get_signal_changes(tPORT* p_port, uint8_t old_signals,
                                         uint8_t signal);
 extern uint32_t port_flow_control_user(tPORT* p_port);
diff --git a/stack/rfcomm/port_rfc.cc b/stack/rfcomm/port_rfc.cc
index eb80fed..f4e84ae 100644
--- a/stack/rfcomm/port_rfc.cc
+++ b/stack/rfcomm/port_rfc.cc
@@ -22,6 +22,7 @@
  *  communications
  *
  ******************************************************************************/
+#include <base/logging.h>
 #include <string.h>
 
 #include "osi/include/mutex.h"
@@ -292,7 +293,7 @@
     p_mcb->port_inx[dlci] = p_port->inx;
   }
 
-  memcpy(p_port->bd_addr, p_mcb->bd_addr, BD_ADDR_LEN);
+  p_port->bd_addr = p_mcb->bd_addr;
 
   /* Connection is up and we know local and remote features, select MTU */
   port_select_mtu(p_port);
@@ -371,6 +372,8 @@
     /* This is illegal-- negotiation fails. */
     if ((PORT_FC_DEFAULT == PORT_FC_TS710) &&
         (cl == RFCOMM_PN_CONV_LAYER_CBFC_R)) {
+      RFCOMM_TRACE_WARNING("%s, negotiation fails, index=%d", __func__,
+                           p_port->inx);
       rfc_send_disc(p_mcb, p_port->dlci);
       rfc_port_closed(p_port);
       return;
@@ -420,10 +423,7 @@
   RFCOMM_TRACE_DEBUG(
       "PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", p_mcb, dlci,
       mtu, p_port);
-  RFCOMM_TRACE_DEBUG(
-      "PORT_DlcEstablishInd p_mcb addr:%02x:%02x:%02x:%02x:%02x:%02x",
-      p_mcb->bd_addr[0], p_mcb->bd_addr[1], p_mcb->bd_addr[2],
-      p_mcb->bd_addr[3], p_mcb->bd_addr[4], p_mcb->bd_addr[5]);
+  VLOG(1) << __func__ << " p_mcb addr:" << p_mcb->bd_addr;
 
   if (!p_port) {
     /* This can be a first request for this port */
@@ -942,7 +942,7 @@
  *
  * Function         port_rfc_closed
  *
- * Description      This function when RFCOMM side of port is closed
+ * Description      Called when RFCOMM port is closed
  *
  ******************************************************************************/
 void port_rfc_closed(tPORT* p_port, uint8_t res) {
@@ -951,8 +951,8 @@
   tRFC_MCB* p_mcb = p_port->rfc.p_mcb;
 
   if ((p_port->state == PORT_STATE_OPENING) && (p_port->is_server)) {
-    /* The servr side has not been informed that connection is up, ignore */
-    RFCOMM_TRACE_EVENT("port_rfc_closed in OPENING state ignored");
+    /* The server side was not informed that connection is up, ignore */
+    RFCOMM_TRACE_WARNING("port_rfc_closed in OPENING state ignored");
 
     rfc_port_timer_stop(p_port);
     p_port->rfc.state = RFC_STATE_CLOSED;
@@ -987,8 +987,6 @@
 
     if (p_port->ev_mask & PORT_EV_CONNECT_ERR) events |= PORT_EV_CONNECT_ERR;
   }
-  RFCOMM_TRACE_EVENT("port_rfc_closed state:%d sending events:%x",
-                     p_port->state, events);
 
   if ((p_port->p_callback != NULL) && events)
     p_port->p_callback(events, p_port->inx);
@@ -997,8 +995,11 @@
 
   p_port->rfc.state = RFC_STATE_CLOSED;
 
-  RFCOMM_TRACE_WARNING("%s RFCOMM connection in state %d closed: %s (res: %d)",
-                       __func__, p_port->state, PORT_GetResultString(res), res);
+  RFCOMM_TRACE_WARNING(
+      "%s: RFCOMM connection closed, index=%d, state=%d reason=%s[%d], "
+      "UUID=%04X, bd_addr=%s, is_server=%d",
+      __func__, p_port->inx, p_port->state, PORT_GetResultString(res), res,
+      p_port->uuid, p_port->bd_addr.ToString().c_str(), p_port->is_server);
 
   port_release_port(p_port);
 }
diff --git a/stack/rfcomm/port_utils.cc b/stack/rfcomm/port_utils.cc
index 32fabec..1390e60 100644
--- a/stack/rfcomm/port_utils.cc
+++ b/stack/rfcomm/port_utils.cc
@@ -21,6 +21,7 @@
  *  Port Emulation entity utilities
  *
  ******************************************************************************/
+#include <base/logging.h>
 #include <string.h>
 
 #include "osi/include/mutex.h"
@@ -59,7 +60,7 @@
  * Returns          Pointer to the PORT or NULL if not found
  *
  ******************************************************************************/
-tPORT* port_allocate_port(uint8_t dlci, BD_ADDR bd_addr) {
+tPORT* port_allocate_port(uint8_t dlci, const RawAddress& bd_addr) {
   tPORT* p_port = &rfc_cb.port.port[0];
   uint8_t xx, yy;
 
@@ -80,14 +81,11 @@
       rfc_cb.rfc.last_port = yy;
 
       p_port->dlci = dlci;
-      memcpy(p_port->bd_addr, bd_addr, BD_ADDR_LEN);
+      p_port->bd_addr = bd_addr;
 
       RFCOMM_TRACE_DEBUG("rfc_cb.port.port[%d]:%p allocated, last_port:%d", yy,
                          p_port, rfc_cb.rfc.last_port);
-      RFCOMM_TRACE_DEBUG(
-          "port_allocate_port:bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-          bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-          bd_addr[5]);
+      VLOG(1) << __func__ << ": bd_addr:" << bd_addr;
       return (p_port);
     }
   }
@@ -260,7 +258,7 @@
       if (p_port->is_server) p_port->dlci &= 0xfe;
 
       p_port->local_ctrl.modem_signal = p_port->default_signal_state;
-      memcpy(p_port->bd_addr, BT_BD_ANY, BD_ADDR_LEN);
+      p_port->bd_addr = RawAddress::kAny;
     } else {
       RFCOMM_TRACE_DEBUG("%s Clean-up handle: %d", __func__, p_port->inx);
       alarm_free(p_port->rfc.port_timer);
@@ -274,29 +272,24 @@
  * Function         port_find_mcb
  *
  * Description      This function checks if connection exists to device with
- *                  the BD_ADDR.
+ *                  the address.
  *
  ******************************************************************************/
-tRFC_MCB* port_find_mcb(BD_ADDR bd_addr) {
+tRFC_MCB* port_find_mcb(const RawAddress& bd_addr) {
   int i;
 
   for (i = 0; i < MAX_BD_CONNECTIONS; i++) {
     if ((rfc_cb.port.rfc_mcb[i].state != RFC_MX_STATE_IDLE) &&
-        !memcmp(rfc_cb.port.rfc_mcb[i].bd_addr, bd_addr, BD_ADDR_LEN)) {
+        rfc_cb.port.rfc_mcb[i].bd_addr == bd_addr) {
       /* Multiplexer channel found do not change anything */
-      RFCOMM_TRACE_DEBUG(
-          "port_find_mcb: found  bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-          bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
-          bd_addr[5]);
+      VLOG(1) << __func__ << ": found bd_addr:" << bd_addr;
       RFCOMM_TRACE_DEBUG(
           "port_find_mcb: rfc_cb.port.rfc_mcb:index:%d, %p, lcid:%d", i,
           &rfc_cb.port.rfc_mcb[i], rfc_cb.port.rfc_mcb[i].lcid);
       return (&rfc_cb.port.rfc_mcb[i]);
     }
   }
-  RFCOMM_TRACE_DEBUG(
-      "port_find_mcb: not found, bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-      bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
+  VLOG(1) << __func__ << ": not found, bd_addr:" << bd_addr;
   return (NULL);
 }
 
@@ -361,19 +354,19 @@
  *
  * Function         port_find_port
  *
- * Description      Find port with DLCI, BD_ADDR
+ * Description      Find port with DLCI, address
  *
  * Returns          Pointer to the PORT or NULL if not found
  *
  ******************************************************************************/
-tPORT* port_find_port(uint8_t dlci, BD_ADDR bd_addr) {
+tPORT* port_find_port(uint8_t dlci, const RawAddress& bd_addr) {
   uint16_t i;
   tPORT* p_port;
 
   for (i = 0; i < MAX_RFC_PORTS; i++) {
     p_port = &rfc_cb.port.port[i];
     if (p_port->in_use && (p_port->dlci == dlci) &&
-        !memcmp(p_port->bd_addr, bd_addr, BD_ADDR_LEN)) {
+        p_port->bd_addr == bd_addr) {
       return (p_port);
     }
   }
diff --git a/stack/rfcomm/rfc_int.h b/stack/rfcomm/rfc_int.h
index 2505595..93da38a 100644
--- a/stack/rfcomm/rfc_int.h
+++ b/stack/rfcomm/rfc_int.h
@@ -295,7 +295,8 @@
 /*
  * Functions provided by the rfc_utils.cc
 */
-tRFC_MCB* rfc_alloc_multiplexer_channel(BD_ADDR bd_addr, bool is_initiator);
+tRFC_MCB* rfc_alloc_multiplexer_channel(const RawAddress& bd_addr,
+                                        bool is_initiator);
 extern void rfc_release_multiplexer_channel(tRFC_MCB* p_rfc_mcb);
 extern void rfc_timer_start(tRFC_MCB* p_rfc_mcb, uint16_t timeout);
 extern void rfc_timer_stop(tRFC_MCB* p_rfc_mcb);
@@ -308,8 +309,9 @@
 extern void rfc_save_lcid_mcb(tRFC_MCB* p_rfc_mcb, uint16_t lcid);
 extern void rfc_check_mcb_active(tRFC_MCB* p_mcb);
 extern void rfc_port_closed(tPORT* p_port);
-extern void rfc_sec_check_complete(BD_ADDR bd_addr, tBT_TRANSPORT transport,
-                                   void* p_ref_data, uint8_t res);
+extern void rfc_sec_check_complete(const RawAddress* bd_addr,
+                                   tBT_TRANSPORT transport, void* p_ref_data,
+                                   uint8_t res);
 extern void rfc_inc_credit(tPORT* p_port, uint8_t credit);
 extern void rfc_dec_credit(tPORT* p_port);
 extern void rfc_check_send_cmd(tRFC_MCB* p_mcb, BT_HDR* p_buf);
diff --git a/stack/rfcomm/rfc_l2cap_if.cc b/stack/rfcomm/rfc_l2cap_if.cc
index 85be99b..f90f8da 100644
--- a/stack/rfcomm/rfc_l2cap_if.cc
+++ b/stack/rfcomm/rfc_l2cap_if.cc
@@ -40,13 +40,13 @@
 /*
  * Define Callback functions to be called by L2CAP
 */
-static void RFCOMM_ConnectInd(BD_ADDR bd_addr, uint16_t lcid, uint16_t psm,
-                              uint8_t id);
+static void RFCOMM_ConnectInd(const RawAddress& bd_addr, uint16_t lcid,
+                              uint16_t psm, uint8_t id);
 static void RFCOMM_ConnectCnf(uint16_t lcid, uint16_t err);
 static void RFCOMM_ConfigInd(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
 static void RFCOMM_ConfigCnf(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
 static void RFCOMM_DisconnectInd(uint16_t lcid, bool is_clear);
-static void RFCOMM_QoSViolationInd(UNUSED_ATTR BD_ADDR bd_addr);
+static void RFCOMM_QoSViolationInd(UNUSED_ATTR const RawAddress& bd_addr);
 static void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf);
 static void RFCOMM_CongestionStatusInd(uint16_t lcid, bool is_congested);
 
@@ -85,8 +85,8 @@
  *                  block and dispatch the event to it.
  *
  ******************************************************************************/
-void RFCOMM_ConnectInd(BD_ADDR bd_addr, uint16_t lcid, UNUSED_ATTR uint16_t psm,
-                       uint8_t id) {
+void RFCOMM_ConnectInd(const RawAddress& bd_addr, uint16_t lcid,
+                       UNUSED_ATTR uint16_t psm, uint8_t id) {
   tRFC_MCB* p_mcb = rfc_alloc_multiplexer_channel(bd_addr, false);
 
   if ((p_mcb) && (p_mcb->state != RFC_MX_STATE_IDLE)) {
@@ -246,7 +246,7 @@
  *                  FSM.
  *
  ******************************************************************************/
-void RFCOMM_QoSViolationInd(UNUSED_ATTR BD_ADDR bd_addr) {}
+void RFCOMM_QoSViolationInd(UNUSED_ATTR const RawAddress& bd_addr) {}
 
 /*******************************************************************************
  *
diff --git a/stack/rfcomm/rfc_port_fsm.cc b/stack/rfcomm/rfc_port_fsm.cc
index dfe4b04..5157a75 100644
--- a/stack/rfcomm/rfc_port_fsm.cc
+++ b/stack/rfcomm/rfc_port_fsm.cc
@@ -143,6 +143,7 @@
       return;
 
     case RFC_EVENT_DM:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_DM, index=%d", __func__, p_port->inx);
       rfc_port_closed(p_port);
       return;
 
@@ -192,6 +193,8 @@
       return;
 
     case RFC_EVENT_CLEAR:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_CLEAR, index=%d", __func__,
+                           p_port->inx);
       rfc_port_closed(p_port);
       return;
 
@@ -207,6 +210,7 @@
       return;
 
     case RFC_EVENT_DM:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_DM, index=%d", __func__, p_port->inx);
       p_port->rfc.p_mcb->is_disc_initiator = true;
       PORT_DlcEstablishCnf(p_port->rfc.p_mcb, p_port->dlci,
                            p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
@@ -214,6 +218,8 @@
       return;
 
     case RFC_EVENT_DISC:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_DISC, index=%d", __func__,
+                           p_port->inx);
       rfc_send_ua(p_port->rfc.p_mcb, p_port->dlci);
       PORT_DlcEstablishCnf(p_port->rfc.p_mcb, p_port->dlci,
                            p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR);
@@ -244,7 +250,7 @@
  *
  * Description      This function handles events for the port in the
  *                  WAIT_SEC_CHECK state.  SABME has been received from the
- *                  peer and Security Manager verifes BD_ADDR, before we can
+ *                  peer and Security Manager verifes address, before we can
  *                  send ESTABLISH_IND to the Port entity
  *
  * Returns          void
@@ -275,6 +281,8 @@
       return;
 
     case RFC_EVENT_CLEAR:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_CLEAR, index=%d", __func__,
+                           p_port->inx);
       btm_sec_abort_access_req(p_port->rfc.p_mcb->bd_addr);
       rfc_port_closed(p_port);
       return;
@@ -330,6 +338,8 @@
   switch (event) {
     case RFC_EVENT_SEC_COMPLETE:
       if (*((uint8_t*)p_data) != BTM_SUCCESS) {
+        RFCOMM_TRACE_ERROR("%s, RFC_EVENT_SEC_COMPLETE, index=%d, result=%d",
+                           __func__, event, p_port->inx, *((uint8_t*)p_data));
         p_port->rfc.p_mcb->is_disc_initiator = true;
         PORT_DlcEstablishCnf(p_port->rfc.p_mcb, p_port->dlci, 0,
                              RFCOMM_SECURITY_ERR);
@@ -348,6 +358,8 @@
       return;
 
     case RFC_EVENT_CLOSE:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_CLOSE, index=%d", __func__,
+                           p_port->inx);
       btm_sec_abort_access_req(p_port->rfc.p_mcb->bd_addr);
       rfc_port_closed(p_port);
       return;
@@ -390,6 +402,8 @@
       return;
 
     case RFC_EVENT_CLEAR:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_CLEAR, index=%d", __func__,
+                           p_port->inx);
       rfc_port_closed(p_port);
       return;
 
@@ -421,6 +435,7 @@
       return;
 
     case RFC_EVENT_DM:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_DM, index=%d", __func__, p_port->inx);
       PORT_DlcReleaseInd(p_port->rfc.p_mcb, p_port->dlci);
       rfc_port_closed(p_port);
       return;
@@ -468,6 +483,8 @@
       return;
 
     case RFC_EVENT_CLEAR:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_CLEAR, index=%d", __func__, event,
+                           p_port->inx);
       rfc_port_closed(p_port);
       return;
 
@@ -480,6 +497,8 @@
     /* Case falls through */
 
     case RFC_EVENT_DM:
+      RFCOMM_TRACE_WARNING("%s, RFC_EVENT_DM|RFC_EVENT_UA[%d], index=%d",
+                           __func__, event, p_port->inx);
       rfc_port_closed(p_port);
       return;
 
@@ -497,6 +516,8 @@
       return;
 
     case RFC_EVENT_TIMEOUT:
+      RFCOMM_TRACE_ERROR("%s, RFC_EVENT_TIMEOUT, index=%d", __func__,
+                         p_port->inx);
       rfc_port_closed(p_port);
       return;
   }
diff --git a/stack/rfcomm/rfc_utils.cc b/stack/rfcomm/rfc_utils.cc
index bad58f3..baf9aa0 100644
--- a/stack/rfcomm/rfc_utils.cc
+++ b/stack/rfcomm/rfc_utils.cc
@@ -38,8 +38,6 @@
 
 #include <string.h>
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*******************************************************************************
  *
  * Function         rfc_calc_fcs
@@ -129,15 +127,14 @@
  * Function         rfc_alloc_multiplexer_channel
  *
  * Description      This function returns existing or new control block for
- *                  the BD_ADDR.
+ *                  the address.
  *
  ******************************************************************************/
-tRFC_MCB* rfc_alloc_multiplexer_channel(BD_ADDR bd_addr, bool is_initiator) {
+tRFC_MCB* rfc_alloc_multiplexer_channel(const RawAddress& bd_addr,
+                                        bool is_initiator) {
   int i, j;
   tRFC_MCB* p_mcb = NULL;
-  RFCOMM_TRACE_DEBUG(
-      "rfc_alloc_multiplexer_channel: bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-      bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
+  VLOG(1) << __func__ << ": bd_addr:" << bd_addr;
   RFCOMM_TRACE_DEBUG("rfc_alloc_multiplexer_channel:is_initiator:%d",
                      is_initiator);
 
@@ -145,14 +142,11 @@
     RFCOMM_TRACE_DEBUG(
         "rfc_alloc_multiplexer_channel rfc_cb.port.rfc_mcb[%d].state:%d", i,
         rfc_cb.port.rfc_mcb[i].state);
-    RFCOMM_TRACE_DEBUG(
-        "(rfc_cb.port.rfc_mcb[i].bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
-        rfc_cb.port.rfc_mcb[i].bd_addr[0], rfc_cb.port.rfc_mcb[i].bd_addr[1],
-        rfc_cb.port.rfc_mcb[i].bd_addr[2], rfc_cb.port.rfc_mcb[i].bd_addr[3],
-        rfc_cb.port.rfc_mcb[i].bd_addr[4], rfc_cb.port.rfc_mcb[i].bd_addr[5]);
+    VLOG(1) << "(rfc_cb.port.rfc_mcb[i].bd_addr:"
+            << rfc_cb.port.rfc_mcb[i].bd_addr;
 
     if ((rfc_cb.port.rfc_mcb[i].state != RFC_MX_STATE_IDLE) &&
-        (!memcmp(rfc_cb.port.rfc_mcb[i].bd_addr, bd_addr, BD_ADDR_LEN))) {
+        rfc_cb.port.rfc_mcb[i].bd_addr == bd_addr) {
       /* Multiplexer channel found do not change anything */
       /* If there was an inactivity timer running stop it now */
       if (rfc_cb.port.rfc_mcb[i].state == RFC_MX_STATE_CONNECTED)
@@ -175,7 +169,7 @@
       alarm_free(p_mcb->mcb_timer);
       fixed_queue_free(p_mcb->cmd_q, NULL);
       memset(p_mcb, 0, sizeof(tRFC_MCB));
-      memcpy(p_mcb->bd_addr, bd_addr, BD_ADDR_LEN);
+      p_mcb->bd_addr = bd_addr;
       RFCOMM_TRACE_DEBUG(
           "rfc_alloc_multiplexer_channel:is_initiator:%d, create new p_mcb:%p, "
           "index:%d",
@@ -232,8 +226,8 @@
   RFCOMM_TRACE_EVENT("%s - timeout:%d seconds", __func__, timeout);
 
   period_ms_t interval_ms = timeout * 1000;
-  alarm_set_on_queue(p_mcb->mcb_timer, interval_ms, rfcomm_mcb_timer_timeout,
-                     p_mcb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_mcb->mcb_timer, interval_ms, rfcomm_mcb_timer_timeout,
+                     p_mcb);
 }
 
 /*******************************************************************************
@@ -260,9 +254,8 @@
   RFCOMM_TRACE_EVENT("%s - timeout:%d seconds", __func__, timeout);
 
   period_ms_t interval_ms = timeout * 1000;
-  alarm_set_on_queue(p_port->rfc.port_timer, interval_ms,
-                     rfcomm_port_timer_timeout, p_port,
-                     btu_general_alarm_queue);
+  alarm_set_on_mloop(p_port->rfc.port_timer, interval_ms,
+                     rfcomm_port_timer_timeout, p_port);
 }
 
 /*******************************************************************************
@@ -328,7 +321,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void rfc_sec_check_complete(UNUSED_ATTR BD_ADDR bd_addr,
+void rfc_sec_check_complete(UNUSED_ATTR const RawAddress* bd_addr,
                             UNUSED_ATTR tBT_TRANSPORT transport,
                             void* p_ref_data, uint8_t res) {
   tPORT* p_port = (tPORT*)p_ref_data;
@@ -355,11 +348,7 @@
  ******************************************************************************/
 void rfc_port_closed(tPORT* p_port) {
   tRFC_MCB* p_mcb = p_port->rfc.p_mcb;
-
-  RFCOMM_TRACE_DEBUG("rfc_port_closed");
-
   rfc_port_timer_stop(p_port);
-
   p_port->rfc.state = RFC_STATE_CLOSED;
 
   /* If multiplexer channel was up mark it as down */
diff --git a/stack/sdp/sdp_api.cc b/stack/sdp/sdp_api.cc
index b9cdb53..c89eca5 100644
--- a/stack/sdp/sdp_api.cc
+++ b/stack/sdp/sdp_api.cc
@@ -129,7 +129,8 @@
  * Returns          true if discovery started, false if failed.
  *
  ******************************************************************************/
-bool SDP_ServiceSearchRequest(uint8_t* p_bd_addr, tSDP_DISCOVERY_DB* p_db,
+bool SDP_ServiceSearchRequest(const RawAddress& p_bd_addr,
+                              tSDP_DISCOVERY_DB* p_db,
                               tSDP_DISC_CMPL_CB* p_cb) {
   tCONN_CB* p_ccb;
 
@@ -159,7 +160,7 @@
  * Returns          true if discovery started, false if failed.
  *
  ******************************************************************************/
-bool SDP_ServiceSearchAttributeRequest(uint8_t* p_bd_addr,
+bool SDP_ServiceSearchAttributeRequest(const RawAddress& p_bd_addr,
                                        tSDP_DISCOVERY_DB* p_db,
                                        tSDP_DISC_CMPL_CB* p_cb) {
   tCONN_CB* p_ccb;
@@ -191,7 +192,7 @@
  * Returns          true if discovery started, false if failed.
  *
  ******************************************************************************/
-bool SDP_ServiceSearchAttributeRequest2(uint8_t* p_bd_addr,
+bool SDP_ServiceSearchAttributeRequest2(const RawAddress& p_bd_addr,
                                         tSDP_DISCOVERY_DB* p_db,
                                         tSDP_DISC_CMPL_CB2* p_cb2,
                                         void* user_data) {
@@ -212,9 +213,6 @@
   return (true);
 }
 
-void SDP_SetIdleTimeout(UNUSED_ATTR BD_ADDR addr,
-                        UNUSED_ATTR uint16_t timeout) {}
-
 /*******************************************************************************
  *
  * Function         SDP_FindAttributeInDb
@@ -823,8 +821,9 @@
  * Returns          SDP_SUCCESS if query started successfully, else error
  *
  ******************************************************************************/
-uint16_t SDP_DiDiscover(BD_ADDR remote_device, tSDP_DISCOVERY_DB* p_db,
-                        uint32_t len, tSDP_DISC_CMPL_CB* p_cb) {
+uint16_t SDP_DiDiscover(const RawAddress& remote_device,
+                        tSDP_DISCOVERY_DB* p_db, uint32_t len,
+                        tSDP_DISC_CMPL_CB* p_cb) {
   uint16_t result = SDP_DI_DISC_FAILED;
   uint16_t num_uuids = 1;
   uint16_t di_uuid = UUID_SERVCLASS_PNP_INFORMATION;
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index 8239d55..dcacda8 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -51,7 +51,8 @@
 static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
                                             uint8_t* p_reply_end);
 static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end);
-static tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db, BD_ADDR p_bda);
+static tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db,
+                                 const RawAddress& p_bda);
 static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db,
                          tSDP_DISC_REC* p_rec, uint16_t attr_id,
                          tSDP_DISC_ATTR* p_parent_attr, uint8_t nest_level);
@@ -59,8 +60,6 @@
 /* Safety check in case we go crazy */
 #define MAX_NEST_LEVELS 5
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /*******************************************************************************
  *
  * Function         sdpu_build_uuid_seq
@@ -86,15 +85,18 @@
 
   /* Now, loop through and put in all the UUID(s) */
   for (xx = 0; xx < num_uuids; xx++, p_uuid_list++) {
-    if (p_uuid_list->len == 2) {
+    if (p_uuid_list->len == LEN_UUID_16) {
       UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES);
       UINT16_TO_BE_STREAM(p_out, p_uuid_list->uu.uuid16);
-    } else if (p_uuid_list->len == 4) {
+    } else if (p_uuid_list->len == LEN_UUID_32) {
       UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
       UINT32_TO_BE_STREAM(p_out, p_uuid_list->uu.uuid32);
-    } else {
+    } else if (p_uuid_list->len == LEN_UUID_128) {
       UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
       ARRAY_TO_BE_STREAM(p_out, p_uuid_list->uu.uuid128, p_uuid_list->len);
+    } else {
+      SDP_TRACE_ERROR("SDP: Passed UUID has invalid length %x",
+                      p_uuid_list->len);
     }
   }
 
@@ -171,8 +173,8 @@
   L2CA_DataWrite(p_ccb->connection_id, p_cmd);
 
   /* Start inactivity timer */
-  alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
-                     sdp_conn_timer_timeout, p_ccb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
+                     sdp_conn_timer_timeout, p_ccb);
 }
 
 /*******************************************************************************
@@ -535,8 +537,8 @@
     L2CA_DataWrite(p_ccb->connection_id, p_msg);
 
     /* Start inactivity timer */
-    alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
-                       sdp_conn_timer_timeout, p_ccb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
+                       sdp_conn_timer_timeout, p_ccb);
   } else {
     sdp_disconnect(p_ccb, SDP_SUCCESS);
     return;
@@ -684,8 +686,8 @@
     L2CA_DataWrite(p_ccb->connection_id, p_msg);
 
     /* Start inactivity timer */
-    alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
-                       sdp_conn_timer_timeout, p_ccb, btu_general_alarm_queue);
+    alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
+                       sdp_conn_timer_timeout, p_ccb);
 
     return;
   }
@@ -810,7 +812,7 @@
  * Returns          pointer to next byte in data stream
  *
  ******************************************************************************/
-tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db, BD_ADDR p_bda) {
+tSDP_DISC_REC* add_record(tSDP_DISCOVERY_DB* p_db, const RawAddress& p_bda) {
   tSDP_DISC_REC* p_rec;
 
   /* See if there is enough space in the database */
@@ -823,7 +825,7 @@
   p_rec->p_first_attr = NULL;
   p_rec->p_next_rec = NULL;
 
-  memcpy(p_rec->remote_bd_addr, p_bda, BD_ADDR_LEN);
+  p_rec->remote_bd_addr = p_bda;
 
   /* Add the record to the end of chain */
   if (!p_db->p_first_rec)
diff --git a/stack/sdp/sdp_main.cc b/stack/sdp/sdp_main.cc
index 0235203..8f72aaa 100644
--- a/stack/sdp/sdp_main.cc
+++ b/stack/sdp/sdp_main.cc
@@ -42,8 +42,6 @@
 #include "sdp_api.h"
 #include "sdpint.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /******************************************************************************/
 /*                     G L O B A L      S D P       D A T A                   */
 /******************************************************************************/
@@ -52,7 +50,7 @@
 /******************************************************************************/
 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /******************************************************************************/
-static void sdp_connect_ind(BD_ADDR bd_addr, uint16_t l2cap_cid,
+static void sdp_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid,
                             UNUSED_ATTR uint16_t psm, uint8_t l2cap_id);
 static void sdp_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
 static void sdp_config_cfm(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg);
@@ -166,7 +164,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void sdp_connect_ind(BD_ADDR bd_addr, uint16_t l2cap_cid,
+static void sdp_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid,
                             UNUSED_ATTR uint16_t psm, uint8_t l2cap_id) {
 #if (SDP_SERVER_ENABLED == TRUE)
   tCONN_CB* p_ccb;
@@ -179,7 +177,7 @@
   p_ccb->con_state = SDP_STATE_CFG_SETUP;
 
   /* Save the BD Address and Channel ID. */
-  memcpy(&p_ccb->device_address[0], bd_addr, sizeof(BD_ADDR));
+  p_ccb->device_address = bd_addr;
   p_ccb->connection_id = l2cap_cid;
 
   /* Send response to the L2CAP layer. */
@@ -370,9 +368,8 @@
       sdp_disc_connected(p_ccb);
     } else {
       /* Start inactivity timer */
-      alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
-                         sdp_conn_timer_timeout, p_ccb,
-                         btu_general_alarm_queue);
+      alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
+                         sdp_conn_timer_timeout, p_ccb);
     }
   }
 }
@@ -411,9 +408,8 @@
         sdp_disc_connected(p_ccb);
       } else {
         /* Start inactivity timer */
-        alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
-                           sdp_conn_timer_timeout, p_ccb,
-                           btu_general_alarm_queue);
+        alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
+                           sdp_conn_timer_timeout, p_ccb);
       }
     }
   } else {
@@ -516,7 +512,7 @@
  * Returns          void
  *
  ******************************************************************************/
-tCONN_CB* sdp_conn_originate(uint8_t* p_bd_addr) {
+tCONN_CB* sdp_conn_originate(const RawAddress& p_bd_addr) {
   tCONN_CB* p_ccb;
   uint16_t cid;
 
@@ -533,7 +529,8 @@
   p_ccb->con_flags |= SDP_FLAGS_IS_ORIG;
 
   /* Save the BD Address and Channel ID. */
-  memcpy(&p_ccb->device_address[0], p_bd_addr, sizeof(BD_ADDR));
+  p_ccb->device_address = p_bd_addr;
+  ;
 
   /* Transition to the next appropriate state, waiting for connection confirm.
    */
diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc
index 94c56d9..510b8dc 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -43,8 +43,6 @@
 
 #if (SDP_SERVER_ENABLED == TRUE)
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 /* Maximum number of bytes to reserve out of SDP MTU for response data */
 #define SDP_MAX_SERVICE_RSPHDR_LEN 12
 #define SDP_MAX_SERVATTR_RSPHDR_LEN 10
@@ -121,8 +119,8 @@
   uint16_t trans_num, param_len;
 
   /* Start inactivity timer */
-  alarm_set_on_queue(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
-                     sdp_conn_timer_timeout, p_ccb, btu_general_alarm_queue);
+  alarm_set_on_mloop(p_ccb->sdp_conn_timer, SDP_INACT_TIMEOUT_MS,
+                     sdp_conn_timer_timeout, p_ccb);
 
   if (p_req + sizeof(pdu_id) + sizeof(trans_num) > p_req_end) {
     android_errorWriteLog(0x534e4554, "69384124");
diff --git a/stack/sdp/sdpint.h b/stack/sdp/sdpint.h
index 2c9252f..203fcd2 100644
--- a/stack/sdp/sdpint.h
+++ b/stack/sdp/sdpint.h
@@ -165,7 +165,7 @@
 #define SDP_FLAGS_MY_CFG_DONE 0x04
   uint8_t con_flags;
 
-  BD_ADDR device_address;
+  RawAddress device_address;
   alarm_t* sdp_conn_timer;
   uint16_t rem_mtu_size;
   uint16_t connection_id;
@@ -242,7 +242,7 @@
 extern void sdp_conn_rcv_l2e_data(BT_HDR* p_msg);
 extern void sdp_conn_timer_timeout(void* data);
 
-extern tCONN_CB* sdp_conn_originate(uint8_t* p_bd_addr);
+extern tCONN_CB* sdp_conn_originate(const RawAddress& p_bd_addr);
 
 /* Functions provided by sdp_utils.cc
 */
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index d85ef34..513a05e 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -26,15 +26,13 @@
 #include "stack/smp/smp_int.h"
 #include "utils/include/bt_utils.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 #define SMP_KEY_DIST_TYPE_MAX 4
 
 const tSMP_ACT smp_distribute_act[] = {smp_generate_ltk, smp_send_id_info,
                                        smp_generate_csrk,
                                        smp_set_derive_link_key};
 
-static bool lmp_version_below(BD_ADDR bda, uint8_t version) {
+static bool lmp_version_below(const RawAddress& bda, uint8_t version) {
   tACL_CONN* acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE);
   if (acl == NULL || acl->lmp_version == 0) {
     SMP_TRACE_WARNING("%s cannot retrieve LMP version...", __func__);
@@ -155,8 +153,8 @@
           }
 
           SMP_TRACE_WARNING(
-              "rcvd auth_req: 0x%02x, io_cap: %d \
-                        loc_oob_flag: %d loc_enc_size: %d,"
+              "rcvd auth_req: 0x%02x, io_cap: %d "
+              "loc_oob_flag: %d loc_enc_size: %d, "
               "local_i_key: 0x%02x, local_r_key: 0x%02x",
               p_cb->loc_auth_req, p_cb->local_io_capability, p_cb->loc_oob_flag,
               p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key);
@@ -171,12 +169,16 @@
           if (!(p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) ||
               lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_4_2) ||
               interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS,
-                                 (const bt_bdaddr_t*)&p_cb->pairing_bda)) {
+                                 (const RawAddress*)&p_cb->pairing_bda)) {
             p_cb->loc_auth_req &= ~SMP_KP_SUPPORT_BIT;
             p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
             p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
           }
 
+          if (lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_5_0)) {
+            p_cb->loc_auth_req &= ~SMP_H7_SUPPORT_BIT;
+          }
+
           SMP_TRACE_WARNING(
               "set auth_req: 0x%02x, local_i_key: 0x%02x, local_r_key: 0x%02x",
               p_cb->loc_auth_req, p_cb->local_i_key, p_cb->local_r_key);
@@ -194,8 +196,8 @@
           p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
 
           SMP_TRACE_WARNING(
-              "for SMP over BR max_key_size: 0x%02x,\
-                        local_i_key: 0x%02x, local_r_key: 0x%02x, p_cb->loc_auth_req: 0x%02x",
+              "for SMP over BR max_key_size: 0x%02x, local_i_key: 0x%02x, "
+              "local_r_key: 0x%02x, p_cb->loc_auth_req: 0x%02x",
               p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key,
               p_cb->loc_auth_req);
 
@@ -210,7 +212,7 @@
     smp_sm_event(p_cb, SMP_DISCARD_SEC_REQ_EVT, NULL);
   }
 
-  SMP_TRACE_DEBUG("%s return", __func__);
+  SMP_TRACE_DEBUG("%s: return", __func__);
 }
 
 /*******************************************************************************
@@ -221,7 +223,7 @@
   p_cb->status = *(uint8_t*)p_data;
   p_cb->failure = *(uint8_t*)p_data;
 
-  SMP_TRACE_DEBUG("%s status=%d failure=%d ", __func__, p_cb->status,
+  SMP_TRACE_DEBUG("%s: status=%d failure=%d ", __func__, p_cb->status,
                   p_cb->failure);
 
   if (p_cb->status <= SMP_MAX_FAIL_RSN_PER_SPEC &&
@@ -334,7 +336,7 @@
 void smp_send_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
   tBTM_LE_KEY_VALUE le_key;
 
-  SMP_TRACE_DEBUG("%s p_cb->loc_enc_size = %d", __func__, p_cb->loc_enc_size);
+  SMP_TRACE_DEBUG("%s: p_cb->loc_enc_size = %d", __func__, p_cb->loc_enc_size);
   smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, false);
 
   smp_send_cmd(SMP_OPCODE_ENCRYPT_INFO, p_cb);
@@ -414,17 +416,17 @@
   tBTM_BLE_SEC_REQ_ACT sec_req_act;
   uint8_t reason;
 
-  SMP_TRACE_DEBUG("%s auth_req=0x%x", __func__, auth_req);
+  SMP_TRACE_DEBUG("%s: auth_req=0x%x", __func__, auth_req);
 
   p_cb->cb_evt = 0;
 
   btm_ble_link_sec_check(p_cb->pairing_bda, auth_req, &sec_req_act);
 
-  SMP_TRACE_DEBUG("%s sec_req_act=0x%x", __func__, sec_req_act);
+  SMP_TRACE_DEBUG("%s: sec_req_act=0x%x", __func__, sec_req_act);
 
   switch (sec_req_act) {
     case BTM_BLE_SEC_REQ_ACT_ENCRYPT:
-      SMP_TRACE_DEBUG("%s BTM_BLE_SEC_REQ_ACT_ENCRYPT", __func__);
+      SMP_TRACE_DEBUG("%s: BTM_BLE_SEC_REQ_ACT_ENCRYPT", __func__);
       smp_sm_event(p_cb, SMP_ENC_REQ_EVT, NULL);
       break;
 
@@ -493,7 +495,7 @@
   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
 
   SMP_TRACE_DEBUG("%s", __func__);
-  /* erase all keys if it is slave proc pairing req*/
+  /* erase all keys if it is slave proc pairing req */
   if (p_dev_rec && (p_cb->role == HCI_ROLE_SLAVE))
     btm_sec_clear_ble_keys(p_dev_rec);
 
@@ -534,7 +536,7 @@
            (p_cb->selected_association_model ==
             SMP_MODEL_SEC_CONN_JUSTWORKS))) {
         SMP_TRACE_ERROR(
-            "%s pairing failed - slave requires secure connection only mode",
+            "%s: pairing failed - slave requires secure connection only mode",
             __func__);
         reason = SMP_PAIR_AUTH_FAIL;
         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
@@ -555,8 +557,8 @@
         (!(p_cb->le_secure_connections_mode_is_used) ||
          (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) {
       SMP_TRACE_ERROR(
-          "Master requires secure connection only mode \
-                but it can't be provided -> Master fails pairing");
+          "Master requires secure connection only mode "
+          "but it can't be provided -> Master fails pairing");
       reason = SMP_PAIR_AUTH_FAIL;
       smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
       return;
@@ -775,8 +777,8 @@
     p_dev_rec->new_encryption_key_is_p256 = false;
     /* shortcut to skip Security Grant step */
     p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT;
-  } else /* Master receives pairing response */
-  {
+  } else {
+    /* Master receives pairing response */
     SMP_TRACE_DEBUG(
         "%s master rcvs valid PAIRING RESPONSE."
         " Supposed to move to key distribution phase. ",
@@ -798,9 +800,8 @@
   SMP_TRACE_DEBUG("%s", __func__);
   if (res != SMP_SUCCESS) {
     smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, p_data);
-  } else /*otherwise, start pairing */
-  {
-    /* send IO request callback */
+  } else {
+    /* otherwise, start pairing; send IO request callback */
     p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT;
   }
 }
@@ -813,10 +814,8 @@
 void smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
   uint8_t reason = SMP_SUCCESS;
 
-  SMP_TRACE_DEBUG(
-      "%s rcvs i_keys=0x%x r_keys=0x%x "
-      "(i-initiator r-responder)",
-      __func__, p_cb->local_i_key, p_cb->local_r_key);
+  SMP_TRACE_DEBUG("%s rcvs i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
+                  __func__, p_cb->local_i_key, p_cb->local_r_key);
 
   /* In LE SC mode LK field is ignored when BR/EDR transport is used */
   p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
@@ -836,8 +835,7 @@
   SMP_TRACE_DEBUG("%s: use h7 = %d", __func__, p_cb->key_derivation_h7_used);
 
   SMP_TRACE_DEBUG(
-      "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x "
-      "(i-initiator r-responder)",
+      "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
       __func__, p_cb->local_i_key, p_cb->local_r_key);
 
   if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) ||
@@ -971,7 +969,7 @@
   /* to use as BD_ADDR for lk derived from ltk */
   p_cb->id_addr_rcvd = true;
   p_cb->id_addr_type = pid_key.pid_key.addr_type;
-  memcpy(p_cb->id_addr, pid_key.pid_key.static_addr, BD_ADDR_LEN);
+  p_cb->id_addr = pid_key.pid_key.static_addr;
 
   /* store the ID key from peer device */
   if ((p_cb->peer_auth_req & SMP_AUTH_BOND) &&
@@ -992,9 +990,12 @@
 
   /* save CSRK to security record */
   le_key.pcsrk_key.sec_level = p_cb->sec_level;
-  maybe_non_aligned_memcpy(le_key.pcsrk_key.csrk, p_data,
-                           BT_OCTET16_LEN);    /* get peer CSRK */
-  le_key.pcsrk_key.counter = 0;                          /* initialize the peer counter */
+
+  /* get peer CSRK */
+  maybe_non_aligned_memcpy(le_key.pcsrk_key.csrk, p_data, BT_OCTET16_LEN);
+
+  /* initialize the peer counter */
+  le_key.pcsrk_key.counter = 0;
 
   if ((p_cb->peer_auth_req & SMP_AUTH_BOND) &&
       (p_cb->loc_auth_req & SMP_AUTH_BOND))
@@ -1099,8 +1100,7 @@
   uint8_t reason = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
 
   SMP_TRACE_DEBUG(
-      "%s rcvs enc_enable=%d i_keys=0x%x r_keys=0x%x "
-      "(i-initiator r-responder)",
+      "%s rcvs enc_enable=%d i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
       __func__, enc_enable, p_cb->local_i_key, p_cb->local_r_key);
   if (enc_enable == 1) {
     if (p_cb->le_secure_connections_mode_is_used) {
@@ -1127,8 +1127,7 @@
       p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
     }
     SMP_TRACE_DEBUG(
-        "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x "
-        "(i-initiator r-responder)",
+        "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
         __func__, p_cb->local_i_key, p_cb->local_r_key);
 
     if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) ||
@@ -1201,9 +1200,9 @@
          */
         if (!alarm_is_scheduled(p_cb->delayed_auth_timer_ent)) {
           SMP_TRACE_DEBUG("%s delaying auth complete.", __func__);
-          alarm_set_on_queue(
-              p_cb->delayed_auth_timer_ent, SMP_DELAYED_AUTH_TIMEOUT_MS,
-              smp_delayed_auth_complete_timeout, NULL, btu_general_alarm_queue);
+          alarm_set_on_mloop(p_cb->delayed_auth_timer_ent,
+                             SMP_DELAYED_AUTH_TIMEOUT_MS,
+                             smp_delayed_auth_complete_timeout, NULL);
         }
       } else {
         p_cb->wait_for_authorization_complete = true;
@@ -1326,8 +1325,8 @@
         (!(p_cb->le_secure_connections_mode_is_used) ||
          (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) {
       SMP_TRACE_ERROR(
-          "Slave requires secure connection only mode \
-                              but it can't be provided -> Slave fails pairing");
+          "Slave requires secure connection only mode "
+          "but it can't be provided -> Slave fails pairing");
       smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
       return;
     }
@@ -1506,8 +1505,8 @@
           /* slave commitment is already received, send local nonce, wait for
            * remote nonce*/
           SMP_TRACE_DEBUG(
-              "master in assoc mode = %d \
-                    already rcvd slave commitment - race condition",
+              "master in assoc mode = %d "
+              "already rcvd slave commitment - race condition",
               p_cb->selected_association_model);
           p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM;
           smp_send_rand(p_cb, NULL);
@@ -1859,15 +1858,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void smp_link_encrypted(BD_ADDR bda, uint8_t encr_enable) {
+void smp_link_encrypted(const RawAddress& bda, uint8_t encr_enable) {
   tSMP_CB* p_cb = &smp_cb;
 
-  SMP_TRACE_DEBUG("%s encr_enable=%d", __func__, encr_enable);
+  SMP_TRACE_DEBUG("%s: encr_enable=%d", __func__, encr_enable);
 
-  if (memcmp(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN) == 0) {
-    /* encryption completed with STK, remmeber the key size now, could be
-    * overwite
-    *  when key exchange happens                                        */
+  if (smp_cb.pairing_bda == bda) {
+    /* encryption completed with STK, remember the key size now, could be
+     * overwritten when key exchange happens                                 */
     if (p_cb->loc_enc_size != 0 && encr_enable) {
       /* update the link encryption key size if a SMP pairing just performed */
       btm_ble_update_sec_key_size(bda, p_cb->loc_enc_size);
@@ -1887,19 +1885,16 @@
  * Returns          void
  *
  ******************************************************************************/
-bool smp_proc_ltk_request(BD_ADDR bda) {
+bool smp_proc_ltk_request(const RawAddress& bda) {
   SMP_TRACE_DEBUG("%s state = %d", __func__, smp_cb.state);
   bool match = false;
 
-  if (!memcmp(bda, smp_cb.pairing_bda, BD_ADDR_LEN)) {
+  if (bda == smp_cb.pairing_bda) {
     match = true;
   } else {
-    BD_ADDR dummy_bda = {0};
     tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda);
-    if (p_dev_rec != NULL &&
-        0 == memcmp(p_dev_rec->ble.pseudo_addr, smp_cb.pairing_bda,
-                    BD_ADDR_LEN) &&
-        0 != memcmp(p_dev_rec->ble.pseudo_addr, dummy_bda, BD_ADDR_LEN)) {
+    if (p_dev_rec != NULL && p_dev_rec->ble.pseudo_addr == smp_cb.pairing_bda &&
+        p_dev_rec->ble.pseudo_addr != RawAddress::kEmpty) {
       match = true;
     }
   }
@@ -1978,7 +1973,7 @@
  *
  * Description      This function is called to process BR/EDR LK:
  *                  - to derive SMP LTK from BR/EDR LK;
-*8                  - to save SMP LTK.
+ *                  - to save SMP LTK.
  *
  * Returns          void
  *
@@ -1988,7 +1983,7 @@
 
   SMP_TRACE_DEBUG("%s", __func__);
   if (!smp_calculate_long_term_key_from_link_key(p_cb)) {
-    SMP_TRACE_ERROR("%s failed", __func__);
+    SMP_TRACE_ERROR("%s: failed", __func__);
     smp_sm_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
     return;
   }
diff --git a/stack/smp/smp_api.cc b/stack/smp/smp_api.cc
index ae9b8ab..f6a87dd 100644
--- a/stack/smp/smp_api.cc
+++ b/stack/smp/smp_api.cc
@@ -22,6 +22,7 @@
  *  applications that can run over an SMP.
  *
  ******************************************************************************/
+#include <base/logging.h>
 #include <string.h>
 
 #include "bt_target.h"
@@ -129,7 +130,7 @@
  * Returns          None
  *
  ******************************************************************************/
-tSMP_STATUS SMP_Pair(BD_ADDR bd_addr) {
+tSMP_STATUS SMP_Pair(const RawAddress& bd_addr) {
   tSMP_CB* p_cb = &smp_cb;
   uint8_t status = SMP_PAIR_INTERNAL_ERR;
 
@@ -141,8 +142,7 @@
     return SMP_BUSY;
   } else {
     p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
-
-    memcpy(p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
+    p_cb->pairing_bda = bd_addr;
 
     if (!L2CA_ConnectFixedChnl(L2CAP_SMP_CID, bd_addr)) {
       SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __func__);
@@ -167,7 +167,7 @@
  *                  failure.
  *
  ******************************************************************************/
-tSMP_STATUS SMP_BR_PairWith(BD_ADDR bd_addr) {
+tSMP_STATUS SMP_BR_PairWith(const RawAddress& bd_addr) {
   tSMP_CB* p_cb = &smp_cb;
   uint8_t status = SMP_PAIR_INTERNAL_ERR;
 
@@ -183,8 +183,7 @@
   p_cb->role = HCI_ROLE_MASTER;
   p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
   p_cb->smp_over_br = true;
-
-  memcpy(p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
+  p_cb->pairing_bda = bd_addr;
 
   if (!L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, bd_addr)) {
     SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __func__);
@@ -206,7 +205,7 @@
  * Returns          true - Pairining is cancelled
  *
  ******************************************************************************/
-bool SMP_PairCancel(BD_ADDR bd_addr) {
+bool SMP_PairCancel(const RawAddress& bd_addr) {
   tSMP_CB* p_cb = &smp_cb;
   uint8_t err_code = SMP_PAIR_FAIL_UNKNOWN;
   bool status = false;
@@ -218,8 +217,7 @@
 
   BTM_TRACE_EVENT("SMP_CancelPair state=%d flag=0x%x ", p_cb->state,
                   p_cb->flags);
-  if ((p_cb->state != SMP_STATE_IDLE) &&
-      (!memcmp(p_cb->pairing_bda, bd_addr, BD_ADDR_LEN))) {
+  if (p_cb->state != SMP_STATE_IDLE && p_cb->pairing_bda == bd_addr) {
     p_cb->is_pair_cancel = true;
     SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown");
     smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code);
@@ -242,13 +240,12 @@
  * Returns          None
  *
  ******************************************************************************/
-void SMP_SecurityGrant(BD_ADDR bd_addr, uint8_t res) {
+void SMP_SecurityGrant(const RawAddress& bd_addr, uint8_t res) {
   SMP_TRACE_EVENT("SMP_SecurityGrant ");
 
   if (smp_cb.smp_over_br) {
     if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
-        smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
-        memcmp(smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN)) {
+        smp_cb.cb_evt != SMP_SEC_REQUEST_EVT || smp_cb.pairing_bda != bd_addr) {
       return;
     }
 
@@ -260,8 +257,7 @@
   }
 
   if (smp_cb.state != SMP_STATE_WAIT_APP_RSP ||
-      smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
-      memcmp(smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
+      smp_cb.cb_evt != SMP_SEC_REQUEST_EVT || smp_cb.pairing_bda != bd_addr)
     return;
   /* clear the SMP_SEC_REQUEST_EVT event after get grant */
   /* avoid generate duplicate pair request */
@@ -284,7 +280,8 @@
  *                            BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
  *
  ******************************************************************************/
-void SMP_PasskeyReply(BD_ADDR bd_addr, uint8_t res, uint32_t passkey) {
+void SMP_PasskeyReply(const RawAddress& bd_addr, uint8_t res,
+                      uint32_t passkey) {
   tSMP_CB* p_cb = &smp_cb;
   uint8_t failure = SMP_PASSKEY_ENTRY_FAIL;
 
@@ -296,7 +293,7 @@
     return;
   }
 
-  if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
+  if (bd_addr != p_cb->pairing_bda) {
     SMP_TRACE_ERROR("SMP_PasskeyReply() - Wrong BD Addr");
     return;
   }
@@ -335,7 +332,7 @@
  *                  res          - comparison result SMP_SUCCESS if success
  *
  ******************************************************************************/
-void SMP_ConfirmReply(BD_ADDR bd_addr, uint8_t res) {
+void SMP_ConfirmReply(const RawAddress& bd_addr, uint8_t res) {
   tSMP_CB* p_cb = &smp_cb;
   uint8_t failure = SMP_NUMERIC_COMPAR_FAIL;
 
@@ -347,7 +344,7 @@
     return;
   }
 
-  if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
+  if (bd_addr != p_cb->pairing_bda) {
     SMP_TRACE_ERROR("%s() - Wrong BD Addr", __func__);
     return;
   }
@@ -378,7 +375,7 @@
  *                  p_data      - simple pairing Randomizer  C.
  *
  ******************************************************************************/
-void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, uint8_t len,
+void SMP_OobDataReply(const RawAddress& bd_addr, tSMP_STATUS res, uint8_t len,
                       uint8_t* p_data) {
   tSMP_CB* p_cb = &smp_cb;
   uint8_t failure = SMP_OOB_FAIL;
@@ -500,12 +497,12 @@
  *                 value        Keypress notification parameter value
  *
  ******************************************************************************/
-void SMP_KeypressNotification(BD_ADDR bd_addr, uint8_t value) {
+void SMP_KeypressNotification(const RawAddress& bd_addr, uint8_t value) {
   tSMP_CB* p_cb = &smp_cb;
 
   SMP_TRACE_EVENT("%s: Value: %d", __func__, value);
 
-  if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0) {
+  if (bd_addr != p_cb->pairing_bda) {
     SMP_TRACE_ERROR("%s() - Wrong BD Addr", __func__);
     return;
   }
@@ -545,20 +542,15 @@
  ******************************************************************************/
 bool SMP_CreateLocalSecureConnectionsOobData(tBLE_BD_ADDR* addr_to_send_to) {
   tSMP_CB* p_cb = &smp_cb;
-  uint8_t* bd_addr;
 
   if (addr_to_send_to == NULL) {
     SMP_TRACE_ERROR("%s addr_to_send_to is not provided", __func__);
     return false;
   }
 
-  bd_addr = addr_to_send_to->bda;
-
-  SMP_TRACE_EVENT(
-      "%s addr type: %u,  BDA: %08x%04x,  state: %u, br_state: %u", __func__,
-      addr_to_send_to->type,
-      (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
-      (bd_addr[4] << 8) + bd_addr[5], p_cb->state, p_cb->br_state);
+  VLOG(2) << __func__ << " addr type:" << +addr_to_send_to->type
+          << ", BDA:" << addr_to_send_to->bda << ", state:" << p_cb->state
+          << ", br_state: " << p_cb->br_state;
 
   if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br)) {
     SMP_TRACE_WARNING(
diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h
index ed22968..fc8717f 100644
--- a/stack/smp/smp_int.h
+++ b/stack/smp/smp_int.h
@@ -248,7 +248,7 @@
 #define SMP_ECNCRPYT_STATUS HCI_SUCCESS
 
 typedef struct {
-  BD_ADDR bd_addr;
+  RawAddress bd_addr;
   BT_HDR* p_copy;
 } tSMP_REQ_Q_ENTRY;
 
@@ -257,12 +257,12 @@
   tSMP_CALLBACK* p_callback;
   alarm_t* smp_rsp_timer_ent;
   uint8_t trace_level;
-  BD_ADDR pairing_bda;
+  RawAddress pairing_bda;
   tSMP_STATE state;
   bool derive_lk;
   bool id_addr_rcvd;
   tBLE_ADDR_TYPE id_addr_type;
-  BD_ADDR id_addr;
+  RawAddress id_addr;
   bool smp_over_br;
   tSMP_BR_STATE br_state; /* if SMP over BR/ERD has priority over SMP */
   uint8_t failure;
@@ -321,7 +321,7 @@
   uint16_t ediv;
   BT_OCTET8 enc_rand;
   uint8_t addr_type;
-  BD_ADDR local_bda;
+  RawAddress local_bda;
   bool is_pair_cancel;
   bool discard_sec_req;
   uint8_t rcvd_cmd_code;
@@ -464,7 +464,7 @@
 
 /* smp_l2c */
 extern void smp_l2cap_if_init(void);
-extern void smp_data_ind(BD_ADDR bd_addr, BT_HDR* p_buf);
+extern void smp_data_ind(const RawAddress& bd_addr, BT_HDR* p_buf);
 
 /* smp_util.cc */
 extern bool smp_send_cmd(uint8_t cmd_code, tSMP_CB* p_cb);
@@ -479,7 +479,7 @@
 extern bool smp_encrypt_data(uint8_t* key, uint8_t key_len, uint8_t* plain_text,
                              uint8_t pt_len, tSMP_ENC* p_out);
 extern bool smp_command_has_invalid_parameters(tSMP_CB* p_cb);
-extern void smp_reject_unexpected_pairing_command(BD_ADDR bd_addr);
+extern void smp_reject_unexpected_pairing_command(const RawAddress& bd_addr);
 extern tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB* p_cb);
 extern void smp_reverse_array(uint8_t* arr, uint8_t len);
 extern uint8_t smp_calculate_random_input(uint8_t* random, uint8_t round);
diff --git a/stack/smp/smp_keys.cc b/stack/smp/smp_keys.cc
index fb77c77..06e4d87 100644
--- a/stack/smp/smp_keys.cc
+++ b/stack/smp/smp_keys.cc
@@ -393,7 +393,8 @@
  * Returns          void
  *
  ******************************************************************************/
-void smp_gen_p2_4_confirm(tSMP_CB* p_cb, BD_ADDR remote_bda, BT_OCTET16 p2) {
+void smp_gen_p2_4_confirm(tSMP_CB* p_cb, const RawAddress& remote_bda,
+                          BT_OCTET16 p2) {
   SMP_TRACE_DEBUG("%s", __func__);
   uint8_t* p = (uint8_t*)p2;
   /* 32-bit Padding */
@@ -424,7 +425,7 @@
 tSMP_STATUS smp_calculate_comfirm(tSMP_CB* p_cb, BT_OCTET16 rand,
                                   tSMP_ENC* output) {
   SMP_TRACE_DEBUG("%s", __func__);
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBLE_ADDR_TYPE remote_bd_addr_type = 0;
   /* get remote connection specific bluetooth address */
   if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, remote_bda,
@@ -886,8 +887,8 @@
     case SMP_MODEL_SEC_CONN_NUM_COMP:
       if (p_cb->role == HCI_ROLE_MASTER)
         SMP_TRACE_WARNING(
-            "local commitment calc on master is not expected \
-                                    for Just Works/Numeric Comparison models");
+            "local commitment calc on master is not expected "
+            "for Just Works/Numeric Comparison models");
       smp_calculate_f4(p_cb->loc_publ_key.x, p_cb->peer_publ_key.x, p_cb->rand,
                        0, p_cb->commitment);
       break;
@@ -933,8 +934,8 @@
     case SMP_MODEL_SEC_CONN_NUM_COMP:
       if (p_cb->role == HCI_ROLE_SLAVE)
         SMP_TRACE_WARNING(
-            "peer commitment calc on slave is not expected \
-                for Just Works/Numeric Comparison models");
+            "peer commitment calc on slave is not expected "
+            "for Just Works/Numeric Comparison models");
       smp_calculate_f4(p_cb->peer_publ_key.x, p_cb->loc_publ_key.x, p_cb->rrand,
                        0, output_buf);
       break;
@@ -1632,7 +1633,7 @@
  ******************************************************************************/
 bool smp_calculate_link_key_from_long_term_key(tSMP_CB* p_cb) {
   tBTM_SEC_DEV_REC* p_dev_rec;
-  BD_ADDR bda_for_lk;
+  RawAddress bda_for_lk;
   tBLE_ADDR_TYPE conn_addr_type;
   BT_OCTET16 salt = {0x31, 0x70, 0x6D, 0x74, 0x00, 0x00, 0x00, 0x00,
                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -1642,7 +1643,7 @@
   if (p_cb->id_addr_rcvd && p_cb->id_addr_type == BLE_ADDR_PUBLIC) {
     SMP_TRACE_DEBUG(
         "Use rcvd identity address as BD_ADDR of LK rcvd identity address");
-    memcpy(bda_for_lk, p_cb->id_addr, BD_ADDR_LEN);
+    bda_for_lk = p_cb->id_addr;
   } else if ((BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, bda_for_lk,
                                            &conn_addr_type)) &&
              conn_addr_type == BLE_ADDR_PUBLIC) {
diff --git a/stack/smp/smp_l2c.cc b/stack/smp/smp_l2c.cc
index 98ac52d..6111f10 100644
--- a/stack/smp/smp_l2c.cc
+++ b/stack/smp/smp_l2c.cc
@@ -30,19 +30,18 @@
 
 #include "smp_int.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 static void smp_tx_complete_callback(uint16_t cid, uint16_t num_pkt);
 
-static void smp_connect_callback(uint16_t channel, BD_ADDR bd_addr,
+static void smp_connect_callback(uint16_t channel, const RawAddress& bd_addr,
                                  bool connected, uint16_t reason,
                                  tBT_TRANSPORT transport);
-static void smp_data_received(uint16_t channel, BD_ADDR bd_addr, BT_HDR* p_buf);
+static void smp_data_received(uint16_t channel, const RawAddress& bd_addr,
+                              BT_HDR* p_buf);
 
-static void smp_br_connect_callback(uint16_t channel, BD_ADDR bd_addr,
+static void smp_br_connect_callback(uint16_t channel, const RawAddress& bd_addr,
                                     bool connected, uint16_t reason,
                                     tBT_TRANSPORT transport);
-static void smp_br_data_received(uint16_t channel, BD_ADDR bd_addr,
+static void smp_br_data_received(uint16_t channel, const RawAddress& bd_addr,
                                  BT_HDR* p_buf);
 
 /*******************************************************************************
@@ -89,25 +88,19 @@
  *                      connected (conn = true)/disconnected (conn = false).
  *
  ******************************************************************************/
-static void smp_connect_callback(uint16_t channel, BD_ADDR bd_addr,
+static void smp_connect_callback(uint16_t channel, const RawAddress& bd_addr,
                                  bool connected, uint16_t reason,
                                  tBT_TRANSPORT transport) {
   tSMP_CB* p_cb = &smp_cb;
   tSMP_INT_DATA int_data;
-  BD_ADDR dummy_bda = {0};
 
   SMP_TRACE_EVENT("SMDBG l2c %s", __func__);
 
-  if (transport == BT_TRANSPORT_BR_EDR ||
-      memcmp(bd_addr, dummy_bda, BD_ADDR_LEN) == 0)
-    return;
+  if (transport == BT_TRANSPORT_BR_EDR || bd_addr.IsEmpty()) return;
 
-  if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) == 0) {
-    SMP_TRACE_EVENT("%s()  for pairing BDA: %08x%04x  Event: %s", __func__,
-                    (bd_addr[0] << 24) + (bd_addr[1] << 16) +
-                        (bd_addr[2] << 8) + bd_addr[3],
-                    (bd_addr[4] << 8) + bd_addr[5],
-                    (connected) ? "connected" : "disconnected");
+  if (bd_addr == p_cb->pairing_bda) {
+    VLOG(2) << __func__ << " for pairing BDA: " << bd_addr
+            << " Event: " << ((connected) ? "connected" : "disconnected");
 
     if (connected) {
       if (!p_cb->connect_initialized) {
@@ -140,7 +133,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void smp_data_received(uint16_t channel, BD_ADDR bd_addr,
+static void smp_data_received(uint16_t channel, const RawAddress& bd_addr,
                               BT_HDR* p_buf) {
   tSMP_CB* p_cb = &smp_cb;
   uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
@@ -162,8 +155,8 @@
         (p_cb->br_state == SMP_BR_STATE_IDLE) &&
         !(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) {
       p_cb->role = L2CA_GetBleConnRole(bd_addr);
-      memcpy(&p_cb->pairing_bda[0], bd_addr, BD_ADDR_LEN);
-    } else if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN)) {
+      p_cb->pairing_bda = bd_addr;
+    } else if (bd_addr != p_cb->pairing_bda) {
       osi_free(p_buf);
       smp_reject_unexpected_pairing_command(bd_addr);
       return;
@@ -172,9 +165,9 @@
      * SM */
   }
 
-  if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN) == 0) {
-    alarm_set_on_queue(p_cb->smp_rsp_timer_ent, SMP_WAIT_FOR_RSP_TIMEOUT_MS,
-                       smp_rsp_timeout, NULL, btu_general_alarm_queue);
+  if (bd_addr == p_cb->pairing_bda) {
+    alarm_set_on_mloop(p_cb->smp_rsp_timer_ent, SMP_WAIT_FOR_RSP_TIMEOUT_MS,
+                       smp_rsp_timeout, NULL);
 
     if (cmd == SMP_OPCODE_CONFIRM) {
       SMP_TRACE_DEBUG(
@@ -229,7 +222,7 @@
  *                      connected (conn = true)/disconnected (conn = false).
  *
  ******************************************************************************/
-static void smp_br_connect_callback(uint16_t channel, BD_ADDR bd_addr,
+static void smp_br_connect_callback(uint16_t channel, const RawAddress& bd_addr,
                                     bool connected, uint16_t reason,
                                     tBT_TRANSPORT transport) {
   tSMP_CB* p_cb = &smp_cb;
@@ -243,13 +236,10 @@
     return;
   }
 
-  if (!(memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) == 0)) return;
+  if (bd_addr != p_cb->pairing_bda) return;
 
-  SMP_TRACE_EVENT(
-      "%s for pairing BDA: %08x%04x  Event: %s", __func__,
-      (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3],
-      (bd_addr[4] << 8) + bd_addr[5],
-      (connected) ? "connected" : "disconnected");
+  VLOG(1) << __func__ << " for pairing BDA: " << bd_addr
+          << " Event: " << ((connected) ? "connected" : "disconnected");
 
   if (connected) {
     if (!p_cb->connect_initialized) {
@@ -277,7 +267,7 @@
  * Returns          void
  *
  ******************************************************************************/
-static void smp_br_data_received(uint16_t channel, BD_ADDR bd_addr,
+static void smp_br_data_received(uint16_t channel, const RawAddress& bd_addr,
                                  BT_HDR* p_buf) {
   tSMP_CB* p_cb = &smp_cb;
   uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
@@ -299,8 +289,8 @@
         (p_cb->br_state == SMP_BR_STATE_IDLE)) {
       p_cb->role = HCI_ROLE_SLAVE;
       p_cb->smp_over_br = true;
-      memcpy(&p_cb->pairing_bda[0], bd_addr, BD_ADDR_LEN);
-    } else if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN)) {
+      p_cb->pairing_bda = bd_addr;
+    } else if (bd_addr != p_cb->pairing_bda) {
       osi_free(p_buf);
       smp_reject_unexpected_pairing_command(bd_addr);
       return;
@@ -308,9 +298,9 @@
     /* else, out of state pairing request received, passed into State Machine */
   }
 
-  if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN) == 0) {
-    alarm_set_on_queue(p_cb->smp_rsp_timer_ent, SMP_WAIT_FOR_RSP_TIMEOUT_MS,
-                       smp_rsp_timeout, NULL, btu_general_alarm_queue);
+  if (bd_addr == p_cb->pairing_bda) {
+    alarm_set_on_mloop(p_cb->smp_rsp_timer_ent, SMP_WAIT_FOR_RSP_TIMEOUT_MS,
+                       smp_rsp_timeout, NULL);
 
     p_cb->rcvd_cmd_code = cmd;
     p_cb->rcvd_cmd_len = (uint8_t)p_buf->len;
diff --git a/stack/smp/smp_utils.cc b/stack/smp/smp_utils.cc
index 026b98c..f2d578d 100644
--- a/stack/smp/smp_utils.cc
+++ b/stack/smp/smp_utils.cc
@@ -36,8 +36,6 @@
 #include "osi/include/osi.h"
 #include "smp_int.h"
 
-extern fixed_queue_t* btu_general_alarm_queue;
-
 #define SMP_PAIRING_REQ_SIZE 7
 #define SMP_CONFIRM_CMD_SIZE (BT_OCTET16_LEN + 1)
 #define SMP_RAND_CMD_SIZE (BT_OCTET16_LEN + 1)
@@ -303,7 +301,7 @@
  * Description      Send message to L2CAP.
  *
  ******************************************************************************/
-bool smp_send_msg_to_L2CAP(BD_ADDR rem_bda, BT_HDR* p_toL2CAP) {
+bool smp_send_msg_to_L2CAP(const RawAddress& rem_bda, BT_HDR* p_toL2CAP) {
   uint16_t l2cap_ret;
   uint16_t fixed_cid = L2CAP_SMP_CID;
 
@@ -342,8 +340,8 @@
 
     if (p_buf != NULL && smp_send_msg_to_L2CAP(p_cb->pairing_bda, p_buf)) {
       sent = true;
-      alarm_set_on_queue(p_cb->smp_rsp_timer_ent, SMP_WAIT_FOR_RSP_TIMEOUT_MS,
-                         smp_rsp_timeout, NULL, btu_general_alarm_queue);
+      alarm_set_on_mloop(p_cb->smp_rsp_timer_ent, SMP_WAIT_FOR_RSP_TIMEOUT_MS,
+                         smp_rsp_timeout, NULL);
     }
   }
 
@@ -580,7 +578,7 @@
   p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
   UINT8_TO_STREAM(p, SMP_OPCODE_ID_ADDR);
   UINT8_TO_STREAM(p, 0);
-  BDADDR_TO_STREAM(p, controller_get_interface()->get_address()->address);
+  BDADDR_TO_STREAM(p, *controller_get_interface()->get_address());
 
   p_buf->offset = L2CAP_MIN_OFFSET;
   p_buf->len = SMP_ID_ADDR_SIZE;
@@ -917,7 +915,6 @@
 void smp_proc_pairing_cmpl(tSMP_CB* p_cb) {
   tSMP_EVT_DATA evt_data = {0};
   tSMP_CALLBACK* p_callback = p_cb->p_callback;
-  BD_ADDR pairing_bda;
 
   SMP_TRACE_DEBUG("smp_proc_pairing_cmpl ");
 
@@ -933,7 +930,7 @@
   SMP_TRACE_DEBUG("send SMP_COMPLT_EVT reason=0x%0x sec_level=0x%0x",
                   evt_data.cmplt.reason, evt_data.cmplt.sec_level);
 
-  memcpy(pairing_bda, p_cb->pairing_bda, BD_ADDR_LEN);
+  RawAddress pairing_bda = p_cb->pairing_bda;
 
   smp_reset_control_value(p_cb);
 
@@ -995,8 +992,8 @@
 
   if (p_cb->rcvd_cmd_len != smp_cmd_size_per_spec[cmd_code]) {
     SMP_TRACE_WARNING(
-        "Rcvd from the peer cmd 0x%02x with invalid length\
-            0x%02x (per spec the length is 0x%02x).",
+        "Rcvd from the peer cmd 0x%02x with invalid length "
+        "0x%02x (per spec the length is 0x%02x).",
         cmd_code, p_cb->rcvd_cmd_len, smp_cmd_size_per_spec[cmd_code]);
     return false;
   }
@@ -1030,24 +1027,24 @@
 
   if (io_caps >= BTM_IO_CAP_MAX) {
     SMP_TRACE_WARNING(
-        "Rcvd from the peer cmd 0x%02x with IO Capabilty \
-            value (0x%02x) out of range).",
+        "Rcvd from the peer cmd 0x%02x with IO Capability "
+        "value (0x%02x) out of range).",
         p_cb->rcvd_cmd_code, io_caps);
     return false;
   }
 
   if (!((oob_flag == SMP_OOB_NONE) || (oob_flag == SMP_OOB_PRESENT))) {
     SMP_TRACE_WARNING(
-        "Rcvd from the peer cmd 0x%02x with OOB data flag value \
-            (0x%02x) out of range).",
+        "Rcvd from the peer cmd 0x%02x with OOB data flag value "
+        "(0x%02x) out of range).",
         p_cb->rcvd_cmd_code, oob_flag);
     return false;
   }
 
   if (!((bond_flag == SMP_AUTH_NO_BOND) || (bond_flag == SMP_AUTH_BOND))) {
     SMP_TRACE_WARNING(
-        "Rcvd from the peer cmd 0x%02x with Bonding_Flags value (0x%02x)\
-                           out of range).",
+        "Rcvd from the peer cmd 0x%02x with Bonding_Flags value (0x%02x) "
+        "out of range).",
         p_cb->rcvd_cmd_code, bond_flag);
     return false;
   }
@@ -1055,8 +1052,8 @@
   if ((enc_size < SMP_ENCR_KEY_SIZE_MIN) ||
       (enc_size > SMP_ENCR_KEY_SIZE_MAX)) {
     SMP_TRACE_WARNING(
-        "Rcvd from the peer cmd 0x%02x with Maximum Encryption \
-            Key value (0x%02x) out of range).",
+        "Rcvd from the peer cmd 0x%02x with Maximum Encryption "
+        "Key value (0x%02x) out of range).",
         p_cb->rcvd_cmd_code, enc_size);
     return false;
   }
@@ -1080,8 +1077,8 @@
 
   if (keypress_notification >= BTM_SP_KEY_OUT_OF_RANGE) {
     SMP_TRACE_WARNING(
-        "Rcvd from the peer cmd 0x%02x with Pairing Keypress \
-            Notification value (0x%02x) out of range).",
+        "Rcvd from the peer cmd 0x%02x with Pairing Keypress "
+        "Notification value (0x%02x) out of range).",
         p_cb->rcvd_cmd_code, keypress_notification);
     return false;
   }
@@ -1121,7 +1118,7 @@
  * Returns          void
  *
  ******************************************************************************/
-void smp_reject_unexpected_pairing_command(BD_ADDR bd_addr) {
+void smp_reject_unexpected_pairing_command(const RawAddress& bd_addr) {
   uint8_t* p;
   BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_PAIR_FAIL_SIZE +
                                       L2CAP_MIN_OFFSET);
@@ -1354,7 +1351,7 @@
  ******************************************************************************/
 void smp_collect_local_ble_address(uint8_t* le_addr, tSMP_CB* p_cb) {
   tBLE_ADDR_TYPE addr_type = 0;
-  BD_ADDR bda;
+  RawAddress bda;
   uint8_t* p = le_addr;
 
   SMP_TRACE_DEBUG("%s", __func__);
@@ -1376,7 +1373,7 @@
  ******************************************************************************/
 void smp_collect_peer_ble_address(uint8_t* le_addr, tSMP_CB* p_cb) {
   tBLE_ADDR_TYPE addr_type = 0;
-  BD_ADDR bda;
+  RawAddress bda;
   uint8_t* p = le_addr;
 
   SMP_TRACE_DEBUG("%s", __func__);
diff --git a/stack/srvc/srvc_battery.cc b/stack/srvc/srvc_battery.cc
index 7600f9d..2d9fe18 100644
--- a/stack/srvc/srvc_battery.cc
+++ b/stack/srvc/srvc_battery.cc
@@ -74,7 +74,7 @@
   for (i = 0; i < BA_MAX_INT_NUM; i++, p_inst++) {
     /* read battery level */
     if (handle == p_inst->clt_cfg_hdl) {
-      memcpy(cfg.remote_bda, srvc_eng_cb.clcb[clcb_idx].bda, BD_ADDR_LEN);
+      cfg.remote_bda = srvc_eng_cb.clcb[clcb_idx].bda;
       STREAM_TO_UINT16(cfg.clt_cfg, p);
 
       if (p_inst->p_cback) {
@@ -177,7 +177,7 @@
   tBA_INST* p_inst;
 
   if (battery_cb.inst_id == BA_MAX_INT_NUM) {
-    GATT_TRACE_ERROR("MAX battery service has been reached");
+    LOG(ERROR) << "MAX battery service has been reached";
     return 0;
   }
 
@@ -235,7 +235,7 @@
 
   if (status != GATT_SUCCESS) {
     battery_cb.inst_id--;
-    GATT_TRACE_ERROR("%s: Failed to add battery servuce!", __func__);
+    LOG(ERROR) << __func__ << " Failed to add battery servuce!";
   }
 
   battery_cb.inst_id++;
@@ -334,7 +334,8 @@
  * Description      Send battery level notification
  *
  ******************************************************************************/
-void Battery_Notify(uint8_t app_id, BD_ADDR remote_bda, uint8_t battery_level) {
+void Battery_Notify(uint8_t app_id, const RawAddress& remote_bda,
+                    uint8_t battery_level) {
   tBA_INST* p_inst = &battery_cb.battery_inst[0];
   uint8_t i = 0;
 
@@ -356,7 +357,7 @@
  * Returns          void
  *
  ******************************************************************************/
-bool Battery_ReadBatteryLevel(UNUSED_ATTR BD_ADDR peer_bda) {
+bool Battery_ReadBatteryLevel(const RawAddress&) {
   /* to be implemented */
   return true;
 }
diff --git a/stack/srvc/srvc_dis.cc b/stack/srvc/srvc_dis.cc
index b149c3f..85de4b4 100644
--- a/stack/srvc/srvc_dis.cc
+++ b/stack/srvc/srvc_dis.cc
@@ -28,6 +28,7 @@
 #include "srvc_dis_int.h"
 #include "srvc_eng_int.h"
 
+using base::StringPrintf;
 #define DIS_MAX_NUM_INC_SVR 0
 #define DIS_MAX_CHAR_NUM 9
 #define DIS_MAX_ATTR_NUM (DIS_MAX_CHAR_NUM * 2 + DIS_MAX_NUM_INC_SVR + 1)
@@ -167,7 +168,8 @@
             p_value->len -= offset;
             pp += offset;
             ARRAY_TO_STREAM(p, pp, p_value->len);
-            GATT_TRACE_EVENT("GATT_UUID_MANU_NAME len=0x%04x", p_value->len);
+            VLOG(1) << "GATT_UUID_MANU_NAME len=0x" << std::hex
+                    << +p_value->len;
           }
           break;
 
@@ -243,8 +245,8 @@
       if (GATTC_Read(conn_id, GATT_READ_BY_TYPE, &param) == GATT_SUCCESS)
         return true;
 
-      GATT_TRACE_ERROR("Read DISInfo: 0x%04x GATT_Read Failed",
-                       param.service.uuid.uu.uuid16);
+      LOG(ERROR) << "Read DISInfo: 0x" << std::hex
+                 << param.service.uuid.uu.uuid16 << "GATT_Read Failed";
     }
 
     dis_cb.dis_read_uuid_idx++;
@@ -270,10 +272,9 @@
   uint8_t *pp = NULL, *p_str;
   uint16_t conn_id = p_clcb->conn_id;
 
-  GATT_TRACE_EVENT(
-      "dis_c_cmpl_cback() - op_code: 0x%02x  status: 0x%02x  \
-                        read_type: 0x%04x",
-      op, status, read_type);
+  VLOG(1) << __func__
+          << StringPrintf("op_code: 0x%02x  status: 0x%02x read_type: 0x%04x",
+                          op, status, read_type);
 
   if (op != GATTC_OPTYPE_READ) return;
 
@@ -282,7 +283,7 @@
 
     switch (read_type) {
       case GATT_UUID_SYSTEM_ID:
-        GATT_TRACE_EVENT("DIS_ATTR_SYS_ID_BIT");
+        VLOG(1) << "DIS_ATTR_SYS_ID_BIT";
         if (p_data->att_value.len == DIS_SYSTEM_ID_SIZE) {
           p_clcb->dis_value.attr_mask |= DIS_ATTR_SYS_ID_BIT;
           /* save system ID*/
@@ -341,7 +342,7 @@
   tGATT_STATUS status;
 
   if (dis_cb.enabled) {
-    GATT_TRACE_ERROR("DIS already initalized");
+    LOG(ERROR) << "DIS already initalized";
     return DIS_SUCCESS;
   }
 
@@ -372,7 +373,7 @@
   status = GATTS_AddService(srvc_eng_cb.gatt_if, service,
                             sizeof(service) / sizeof(btgatt_db_element_t));
   if (status != GATT_SERVICE_STARTED) {
-    GATT_TRACE_ERROR("Can not create service, DIS_Init failed!");
+    LOG(ERROR) << "Can not create service, DIS_Init failed!";
     return GATT_ERROR;
   }
 
@@ -382,8 +383,9 @@
   for (int i = 0; i < DIS_MAX_CHAR_NUM; i++) {
     dis_cb.dis_attr[i].handle = service[i + 1].attribute_handle;
 
-    GATT_TRACE_DEBUG("%s:  handle of new attribute 0x%04 = x%d", __func__,
-                     dis_cb.dis_attr[i].uuid, dis_cb.dis_attr[i].handle);
+    VLOG(1) << StringPrintf("%s:  handle of new attribute 0x%04x = %d",
+                            __func__, dis_cb.dis_attr[i].uuid,
+                            dis_cb.dis_attr[i].handle);
   }
 
   dis_cb.enabled = true;
@@ -437,7 +439,7 @@
  * Returns          void
  *
  ******************************************************************************/
-bool DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK* p_cback,
+bool DIS_ReadDISInfo(const RawAddress& peer_bda, tDIS_READ_CBACK* p_cback,
                      tDIS_ATTR_MASK mask) {
   uint16_t conn_id;
 
@@ -455,11 +457,9 @@
 
   dis_cb.request_mask = mask;
 
-  GATT_TRACE_EVENT("DIS_ReadDISInfo() - BDA: %08x%04x  cl_read_uuid: 0x%04x",
-                   (peer_bda[0] << 24) + (peer_bda[1] << 16) +
-                       (peer_bda[2] << 8) + peer_bda[3],
-                   (peer_bda[4] << 8) + peer_bda[5],
-                   dis_attr_uuid[dis_cb.dis_read_uuid_idx]);
+  VLOG(1) << __func__ << " BDA: " << peer_bda
+          << StringPrintf(" cl_read_uuid: 0x%04x",
+                          dis_attr_uuid[dis_cb.dis_read_uuid_idx]);
 
   GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id,
                             BT_TRANSPORT_LE);
diff --git a/stack/srvc/srvc_eng.cc b/stack/srvc/srvc_eng.cc
index 568b66e..f054f67 100644
--- a/stack/srvc/srvc_eng.cc
+++ b/stack/srvc/srvc_eng.cc
@@ -26,11 +26,12 @@
 #include "srvc_battery_int.h"
 #include "srvc_dis_int.h"
 
+using base::StringPrintf;
 static void srvc_eng_s_request_cback(uint16_t conn_id, uint32_t trans_id,
                                      uint8_t op_code, tGATTS_DATA* p_data);
-static void srvc_eng_connect_cback(UNUSED_ATTR tGATT_IF gatt_if, BD_ADDR bda,
-                                   uint16_t conn_id, bool connected,
-                                   tGATT_DISCONN_REASON reason,
+static void srvc_eng_connect_cback(UNUSED_ATTR tGATT_IF gatt_if,
+                                   const RawAddress& bda, uint16_t conn_id,
+                                   bool connected, tGATT_DISCONN_REASON reason,
                                    tBT_TRANSPORT transport);
 static void srvc_eng_c_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op,
                                   tGATT_STATUS status,
@@ -65,14 +66,13 @@
  * Returns          total number of clcb found.
  *
  ******************************************************************************/
-uint16_t srvc_eng_find_conn_id_by_bd_addr(BD_ADDR bda) {
+uint16_t srvc_eng_find_conn_id_by_bd_addr(const RawAddress& bda) {
   uint8_t i_clcb;
   tSRVC_CLCB* p_clcb = NULL;
 
   for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS;
        i_clcb++, p_clcb++) {
-    if (p_clcb->in_use && p_clcb->connected &&
-        !memcmp(p_clcb->bda, bda, BD_ADDR_LEN)) {
+    if (p_clcb->in_use && p_clcb->connected && p_clcb->bda == bda) {
       return p_clcb->conn_id;
     }
   }
@@ -89,14 +89,13 @@
  * Returns          Pointer to the found link conenction control block.
  *
  ******************************************************************************/
-tSRVC_CLCB* srvc_eng_find_clcb_by_bd_addr(BD_ADDR bda) {
+tSRVC_CLCB* srvc_eng_find_clcb_by_bd_addr(const RawAddress& bda) {
   uint8_t i_clcb;
   tSRVC_CLCB* p_clcb = NULL;
 
   for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS;
        i_clcb++, p_clcb++) {
-    if (p_clcb->in_use && p_clcb->connected &&
-        !memcmp(p_clcb->bda, bda, BD_ADDR_LEN)) {
+    if (p_clcb->in_use && p_clcb->connected && p_clcb->bda == bda) {
       return p_clcb;
     }
   }
@@ -157,7 +156,7 @@
  *                  block.
  *
  ******************************************************************************/
-tSRVC_CLCB* srvc_eng_clcb_alloc(uint16_t conn_id, BD_ADDR bda) {
+tSRVC_CLCB* srvc_eng_clcb_alloc(uint16_t conn_id, const RawAddress& bda) {
   uint8_t i_clcb = 0;
   tSRVC_CLCB* p_clcb = NULL;
 
@@ -167,7 +166,7 @@
       p_clcb->in_use = true;
       p_clcb->conn_id = conn_id;
       p_clcb->connected = true;
-      memcpy(p_clcb->bda, bda, BD_ADDR_LEN);
+      p_clcb->bda = bda;
       break;
     }
   }
@@ -259,7 +258,8 @@
   uint8_t act = SRVC_ACT_IGNORE;
   uint8_t clcb_idx = srvc_eng_find_clcb_idx_by_conn_id(conn_id);
 
-  GATT_TRACE_EVENT("srvc_eng_s_request_cback : recv type (0x%02x)", type);
+  VLOG(1) << StringPrintf("srvc_eng_s_request_cback : recv type (0x%02x)",
+                          type);
 
   memset(&rsp_msg, 0, sizeof(tGATTS_RSP));
 
@@ -280,15 +280,16 @@
       break;
 
     case GATTS_REQ_TYPE_WRITE_EXEC:
-      GATT_TRACE_EVENT("Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD");
+      VLOG(1) << "Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD";
       break;
 
     case GATTS_REQ_TYPE_MTU:
-      GATT_TRACE_EVENT("Get MTU exchange new mtu size: %d", p_data->mtu);
+      VLOG(1) << "Get MTU exchange new mtu size: " << p_data->mtu;
       break;
 
     default:
-      GATT_TRACE_EVENT("Unknown/unexpected LE GAP ATT request: 0x%02x", type);
+      VLOG(1) << StringPrintf("Unknown/unexpected LE GAP ATT request: 0x%02x",
+                              type);
       break;
   }
 
@@ -311,11 +312,11 @@
                                   tGATT_CL_COMPLETE* p_data) {
   tSRVC_CLCB* p_clcb = srvc_eng_find_clcb_by_conn_id(conn_id);
 
-  GATT_TRACE_EVENT("srvc_eng_c_cmpl_cback() - op_code: 0x%02x  status: 0x%02x ",
-                   op, status);
+  VLOG(1) << StringPrintf(
+      "srvc_eng_c_cmpl_cback() - op_code: 0x%02x  status: 0x%02x ", op, status);
 
   if (p_clcb == NULL) {
-    GATT_TRACE_ERROR("srvc_eng_c_cmpl_cback received for unknown connection");
+    LOG(ERROR) << __func__ << " received for unknown connection";
     return;
   }
 
@@ -332,19 +333,17 @@
  * Returns          void
  *
  ******************************************************************************/
-static void srvc_eng_connect_cback(UNUSED_ATTR tGATT_IF gatt_if, BD_ADDR bda,
-                                   uint16_t conn_id, bool connected,
-                                   tGATT_DISCONN_REASON reason,
+static void srvc_eng_connect_cback(UNUSED_ATTR tGATT_IF gatt_if,
+                                   const RawAddress& bda, uint16_t conn_id,
+                                   bool connected, tGATT_DISCONN_REASON reason,
                                    UNUSED_ATTR tBT_TRANSPORT transport) {
-  GATT_TRACE_EVENT(
-      "srvc_eng_connect_cback: from %08x%04x connected:%d conn_id=%d reason = "
-      "0x%04x",
-      (bda[0] << 24) + (bda[1] << 16) + (bda[2] << 8) + bda[3],
-      (bda[4] << 8) + bda[5], connected, conn_id, reason);
+  VLOG(1) << __func__ << ": from " << bda
+          << StringPrintf(" connected:%d conn_id=%d reason = 0x%04x", connected,
+                          conn_id, reason);
 
   if (connected) {
     if (srvc_eng_clcb_alloc(conn_id, bda) == NULL) {
-      GATT_TRACE_ERROR("srvc_eng_connect_cback: no_resource");
+      LOG(ERROR) << __func__ << "srvc_eng_connect_cback: no_resource";
       return;
     }
   } else {
@@ -360,7 +359,7 @@
  * Returns          void
  *
  ******************************************************************************/
-bool srvc_eng_request_channel(BD_ADDR remote_bda, uint8_t srvc_id) {
+bool srvc_eng_request_channel(const RawAddress& remote_bda, uint8_t srvc_id) {
   bool set = true;
   tSRVC_CLCB* p_clcb = srvc_eng_find_clcb_by_bd_addr(remote_bda);
 
@@ -386,7 +385,7 @@
   tSRVC_CLCB* p_clcb = srvc_eng_find_clcb_by_conn_id(conn_id);
 
   if (p_clcb == NULL) {
-    GATT_TRACE_ERROR("%s: invalid connection id %d", __func__, conn_id);
+    LOG(ERROR) << __func__ << ": invalid connection id " << conn_id;
     return;
   }
 
@@ -406,7 +405,7 @@
   tBT_UUID app_uuid = {LEN_UUID_16, {UUID_SERVCLASS_DEVICE_INFO}};
 
   if (srvc_eng_cb.enabled) {
-    GATT_TRACE_ERROR("DIS already initalized");
+    LOG(ERROR) << "DIS already initalized";
   } else {
     memset(&srvc_eng_cb, 0, sizeof(tSRVC_ENG_CB));
 
@@ -414,7 +413,7 @@
     srvc_eng_cb.gatt_if = GATT_Register(&app_uuid, &srvc_gatt_cback);
     GATT_StartIf(srvc_eng_cb.gatt_if);
 
-    GATT_TRACE_DEBUG("Srvc_Init:  gatt_if=%d  ", srvc_eng_cb.gatt_if);
+    VLOG(1) << "Srvc_Init:  gatt_if=" << +srvc_eng_cb.gatt_if;
 
     srvc_eng_cb.enabled = true;
     dis_cb.dis_read_uuid_idx = 0xff;
@@ -430,7 +429,7 @@
     srvc_eng_cb.clcb[clcb_idx].trans_id = 0;
   }
 }
-void srvc_sr_notify(BD_ADDR remote_bda, uint16_t handle, uint16_t len,
+void srvc_sr_notify(const RawAddress& remote_bda, uint16_t handle, uint16_t len,
                     uint8_t* p_value) {
   uint16_t conn_id = srvc_eng_find_conn_id_by_bd_addr(remote_bda);
 
diff --git a/stack/srvc/srvc_eng_int.h b/stack/srvc/srvc_eng_int.h
index 3362748..7608355 100644
--- a/stack/srvc/srvc_eng_int.h
+++ b/stack/srvc/srvc_eng_int.h
@@ -37,7 +37,7 @@
   bool in_use;
   uint16_t conn_id;
   bool connected;
-  BD_ADDR bda;
+  RawAddress bda;
   uint32_t trans_id;
   uint8_t cur_srvc_id;
 
@@ -57,13 +57,14 @@
 extern tSRVC_ENG_CB srvc_eng_cb;
 
 extern tSRVC_CLCB* srvc_eng_find_clcb_by_conn_id(uint16_t conn_id);
-extern tSRVC_CLCB* srvc_eng_find_clcb_by_bd_addr(BD_ADDR bda);
-extern uint16_t srvc_eng_find_conn_id_by_bd_addr(BD_ADDR bda);
+extern tSRVC_CLCB* srvc_eng_find_clcb_by_bd_addr(const RawAddress& bda);
+extern uint16_t srvc_eng_find_conn_id_by_bd_addr(const RawAddress& bda);
 
 extern void srvc_eng_release_channel(uint16_t conn_id);
-extern bool srvc_eng_request_channel(BD_ADDR remote_bda, uint8_t srvc_id);
+extern bool srvc_eng_request_channel(const RawAddress& remote_bda,
+                                     uint8_t srvc_id);
 extern void srvc_sr_rsp(uint8_t clcb_idx, tGATT_STATUS st, tGATTS_RSP* p_rsp);
-extern void srvc_sr_notify(BD_ADDR remote_bda, uint16_t handle, uint16_t len,
-                           uint8_t* p_value);
+extern void srvc_sr_notify(const RawAddress& remote_bda, uint16_t handle,
+                           uint16_t len, uint8_t* p_value);
 
 #endif
diff --git a/stack/test/ad_parser_unittest.cc b/stack/test/ad_parser_unittest.cc
index ab6df56..643ed34 100644
--- a/stack/test/ad_parser_unittest.cc
+++ b/stack/test/ad_parser_unittest.cc
@@ -76,6 +76,33 @@
       0xa,  0x32,  0x39, 0x3a, 0x65, 0x32, 0x05, 0x12, 0x50, 0x00, 0x50,
       0x00, 0x02,  0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   EXPECT_TRUE(AdvertiseDataParser::IsValid(data3));
+
+  // Test Quirk for Traxxas (bad name length, should be 0x11 is 0x14)
+  const std::vector<uint8_t> data4{0x14, 0x09, 0x54, 0x52, 0x58, 0x20,
+                                   0x42, 0x4C, 0x45, 0x05, 0x12, 0x60,
+                                   0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00};
+  EXPECT_TRUE(AdvertiseDataParser::IsValid(data4));
+
+  // Test Quirk for Traxxas (bad name length, should be 0x11 is 0x14)
+  const std::vector<uint8_t> data5{0x14, 0x09, 0x54, 0x51, 0x69, 0x20,
+                                   0x42, 0x4C, 0x45, 0x05, 0x12, 0x64,
+                                   0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00};
+  EXPECT_TRUE(AdvertiseDataParser::IsValid(data5));
+
+  // Test Quirk for Traxxas (bad name length, should be 0x11 is 0x14)
+  const std::vector<uint8_t> data6{0x14, 0x09, 0x54, 0x51, 0x69, 0x20,
+                                   0x42, 0x4C, 0x45, 0x05, 0x12, 0x60,
+                                   0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00};
+  EXPECT_TRUE(AdvertiseDataParser::IsValid(data6));
+
+  // Test Quirk for Traxxas (bad length, should be 0x11 is 0x14)
+  // scan response glued after advertise data
+  const std::vector<uint8_t> data7{
+      0x02, 0x01, 0x06, 0x11, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x64, 0xB1, 0x73, 0x41, 0xE7, 0xF3, 0xC4, 0xB4, 0x80,
+      0x08, 0x14, 0x09, 0x54, 0x51, 0x69, 0x20, 0x42, 0x4C, 0x45,
+      0x05, 0x12, 0x60, 0x00, 0xE8, 0x03, 0x02, 0x0A, 0x00};
+  EXPECT_TRUE(AdvertiseDataParser::IsValid(data7));
 }
 
 TEST(AdvertiseDataParserTest, GetFieldByType) {
diff --git a/stack/test/ble_advertiser_test.cc b/stack/test/ble_advertiser_test.cc
index 222bace..4f389e4 100644
--- a/stack/test/ble_advertiser_test.cc
+++ b/stack/test/ble_advertiser_test.cc
@@ -16,6 +16,7 @@
  *
  ******************************************************************************/
 
+#include <array>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -23,15 +24,19 @@
 #include "stack/btm/ble_advertiser_hci_interface.h"
 #include "stack/include/ble_advertiser.h"
 
-using ::testing::_;
 using ::testing::Args;
+using ::testing::Contains;
 using ::testing::ElementsAreArray;
 using ::testing::Exactly;
+using ::testing::Field;
 using ::testing::IsEmpty;
 using ::testing::SaveArg;
+using ::testing::SizeIs;
+using ::testing::_;
 using base::Bind;
 using status_cb = BleAdvertiserHciInterface::status_cb;
 using parameters_cb = BleAdvertiserHciInterface::parameters_cb;
+using SetEnableData = BleAdvertiserHciInterface::SetEnableData;
 
 const int num_adv_instances = 16;
 
@@ -50,7 +55,8 @@
 void btm_ble_update_dmt_flag_bits(uint8_t* flag_value,
                                   const uint16_t connect_mode,
                                   const uint16_t disc_mode) {}
-void btm_acl_update_conn_addr(uint8_t conn_handle, BD_ADDR address) {}
+void btm_acl_update_conn_addr(uint16_t conn_handle, const RawAddress& address) {
+}
 void btm_gen_resolvable_private_addr(base::Callback<void(uint8_t[8])> cb) {
   uint8_t fake_rand[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   cb.Run(fake_rand);
@@ -58,8 +64,8 @@
 
 alarm_callback_t last_alarm_cb = nullptr;
 void* last_alarm_data = nullptr;
-void alarm_set_on_queue(alarm_t* alarm, period_ms_t interval_ms,
-                        alarm_callback_t cb, void* data, fixed_queue_t* queue) {
+void alarm_set_on_mloop(alarm_t* alarm, period_ms_t interval_ms,
+                        alarm_callback_t cb, void* data) {
   last_alarm_cb = cb;
   last_alarm_data = data;
 }
@@ -69,7 +75,6 @@
 alarm_t* alarm_new(const char* name) { return nullptr; }
 void alarm_free(alarm_t* alarm) {}
 const controller_t* controller_get_interface() { return nullptr; }
-fixed_queue_t* btu_general_alarm_queue = nullptr;
 
 namespace {
 void DoNothing(uint8_t) {}
@@ -101,8 +106,8 @@
                void(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t*, status_cb));
   MOCK_METHOD6(SetScanResponseData,
                void(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t*, status_cb));
-  MOCK_METHOD3(SetRandomAddress, void(uint8_t, BD_ADDR, status_cb));
-  MOCK_METHOD5(Enable, void(uint8_t, uint8_t, uint16_t, uint8_t, status_cb));
+  MOCK_METHOD3(SetRandomAddress, void(uint8_t, const RawAddress&, status_cb));
+  MOCK_METHOD3(Enable, void(uint8_t, std::vector<SetEnableData>, status_cb));
   MOCK_METHOD5(SetPeriodicAdvertisingParameters,
                void(uint8_t, uint16_t, uint16_t, uint16_t, status_cb));
   MOCK_METHOD5(SetPeriodicAdvertisingData,
@@ -113,14 +118,14 @@
 
   MOCK_METHOD9(SetParameters1,
                void(uint8_t, uint16_t, uint32_t, uint32_t, uint8_t, uint8_t,
-                    BD_ADDR, uint8_t, BD_ADDR));
+                    const RawAddress&, uint8_t, const RawAddress&));
   MOCK_METHOD8(SetParameters2, void(uint8_t, int8_t, uint8_t, uint8_t, uint8_t,
                                     uint8_t, uint8_t, parameters_cb));
 
   void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
                      uint32_t adv_int_max, uint8_t channel_map,
-                     uint8_t own_address_type, BD_ADDR own_address,
-                     uint8_t peer_address_type, BD_ADDR peer_address,
+                     uint8_t own_address_type, const RawAddress& own_address,
+                     uint8_t peer_address_type, const RawAddress& peer_address,
                      uint8_t filter_policy, int8_t tx_power,
                      uint8_t primary_phy, uint8_t secondary_max_skip,
                      uint8_t secondary_phy, uint8_t advertising_sid,
@@ -240,8 +245,9 @@
       .Times(1)
       .WillOnce(SaveArg<7>(&set_params_cb));
   BleAdvertisingManager::Get()->SetParameters(
-      advertiser_id, &params, Bind(&BleAdvertisingManagerTest::SetParametersCb,
-                                   base::Unretained(this)));
+      advertiser_id, &params,
+      Bind(&BleAdvertisingManagerTest::SetParametersCb,
+           base::Unretained(this)));
   ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
 
   // we are a truly gracious fake controller, let the command succeed!
@@ -261,9 +267,13 @@
   EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, set_data_status);
 
   status_cb enable_cb;
-  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, advertiser_id, _, _, _))
+  EXPECT_CALL(*hci_mock,
+              Enable(0x01 /* enable */,
+                     AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                     advertiser_id))),
+                     _))
       .Times(1)
-      .WillOnce(SaveArg<4>(&enable_cb));
+      .WillOnce(SaveArg<2>(&enable_cb));
   BleAdvertisingManager::Get()->Enable(
       advertiser_id, true,
       Bind(&BleAdvertisingManagerTest::EnableCb, base::Unretained(this)), 0, 0,
@@ -275,9 +285,13 @@
 
   /* fake controller should be advertising */
 
-  EXPECT_CALL(*hci_mock, Enable(0x00 /* disable */, advertiser_id, _, _, _))
+  EXPECT_CALL(*hci_mock,
+              Enable(0x00 /* disable */,
+                     AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                     advertiser_id))),
+                     _))
       .Times(1)
-      .WillOnce(SaveArg<4>(&enable_cb));
+      .WillOnce(SaveArg<2>(&enable_cb));
   status_cb remove_cb;
   EXPECT_CALL(*hci_mock, RemoveAdvertisingSet(_, _))
       .Times(1)
@@ -308,8 +322,9 @@
       .Times(1)
       .WillOnce(SaveArg<7>(&set_params_cb));
   BleAdvertisingManager::Get()->SetParameters(
-      advertiser_id, &params, Bind(&BleAdvertisingManagerTest::SetParametersCb,
-                                   base::Unretained(this)));
+      advertiser_id, &params,
+      Bind(&BleAdvertisingManagerTest::SetParametersCb,
+           base::Unretained(this)));
   ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
 
   // let the set parameters command succeed!
@@ -357,8 +372,9 @@
       .Times(1)
       .WillOnce(SaveArg<7>(&set_params_cb));
   BleAdvertisingManager::Get()->SetParameters(
-      advertiser_id, &params, Bind(&BleAdvertisingManagerTest::SetParametersCb,
-                                   base::Unretained(this)));
+      advertiser_id, &params,
+      Bind(&BleAdvertisingManagerTest::SetParametersCb,
+           base::Unretained(this)));
   ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
 
   // let the set parameters command succeed!
@@ -389,23 +405,37 @@
   EXPECT_EQ(0, reg_inst_id);
 
   uint8_t advertiser_id = reg_inst_id;
-
   status_cb enable_cb;
-  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, advertiser_id, _, _, _))
+  EXPECT_CALL(*hci_mock,
+              Enable(0x01 /* enable */,
+                     AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                     advertiser_id))),
+                     _))
       .Times(1)
-      .WillOnce(SaveArg<4>(&enable_cb));
-  BleAdvertisingManager::Get()->OnAdvertisingSetTerminated(advertiser_id, 0x00,
-                                                           0x05, 0x00);
+      .WillOnce(SaveArg<2>(&enable_cb));
+  BleAdvertisingManager::Get()->Enable(advertiser_id, true, Bind(DoNothing), 0,
+                                       0, Bind(DoNothing));
+  enable_cb.Run(0);
   ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
 
+  EXPECT_CALL(*hci_mock,
+              Enable(0x01 /* enable */,
+                     AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                     advertiser_id))),
+                     _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&enable_cb));
+  BleAdvertisingManager::Get()->OnAdvertisingSetTerminated(advertiser_id, 0x00,
+                                                           0x01ed, 0x00);
   enable_cb.Run(0);
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
 }
 
 /* Make sure that instance is not reenabled if it's already disabled */
 TEST_F(BleAdvertisingManagerTest, test_reenabling_disabled_instance) {
   uint8_t advertiser_id = 1;  // any unregistered value
 
-  EXPECT_CALL(*hci_mock, Enable(_, _, _, _, _)).Times(Exactly(0));
+  EXPECT_CALL(*hci_mock, Enable(_, _, _)).Times(Exactly(0));
   BleAdvertisingManager::Get()->OnAdvertisingSetTerminated(advertiser_id, 0x00,
                                                            0x05, 0x00);
   ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
@@ -439,9 +469,9 @@
   EXPECT_CALL(*hci_mock, SetScanResponseData(_, _, _, _, _, _))
       .Times(1)
       .WillOnce(SaveArg<5>(&set_scan_resp_data_cb));
-  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _, _, _))
+  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _))
       .Times(1)
-      .WillOnce(SaveArg<4>(&enable_cb));
+      .WillOnce(SaveArg<2>(&enable_cb));
 
   BleAdvertisingManager::Get()->StartAdvertisingSet(
       Bind(&BleAdvertisingManagerTest::StartAdvertisingSetCb,
@@ -465,9 +495,13 @@
 
   // Disable advertiser
   status_cb disable_cb;
-  EXPECT_CALL(*hci_mock, Enable(0x00 /* disable */, advertiser_id, _, _, _))
+  EXPECT_CALL(*hci_mock,
+              Enable(0x00 /* disable */,
+                     AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                     advertiser_id))),
+                     _))
       .Times(1)
-      .WillOnce(SaveArg<4>(&disable_cb));
+      .WillOnce(SaveArg<2>(&disable_cb));
   status_cb remove_cb;
   EXPECT_CALL(*hci_mock, RemoveAdvertisingSet(advertiser_id, _))
       .Times(1)
@@ -500,8 +534,9 @@
       .Times(Exactly(0));
 
   BleAdvertisingManager::Get()->StartAdvertising(
-      advertiser_id, Bind(&BleAdvertisingManagerTest::StartAdvertisingCb,
-                          base::Unretained(this)),
+      advertiser_id,
+      Bind(&BleAdvertisingManagerTest::StartAdvertisingCb,
+           base::Unretained(this)),
       &params, adv_data, scan_resp, 0, base::Callback<void(uint8_t)>());
   ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
 
@@ -677,9 +712,16 @@
   EXPECT_CALL(*hci_mock, SetScanResponseData(_, _, _, _, _, _))
       .Times(1)
       .WillOnce(SaveArg<5>(&set_scan_resp_data_cb));
-  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _, maxExtAdvEvents, _))
+  EXPECT_CALL(
+      *hci_mock,
+      Enable(
+          0x01 /* enable */,
+          AllOf(SizeIs(1),
+                Contains(Field(&SetEnableData::max_extended_advertising_events,
+                               maxExtAdvEvents))),
+          _))
       .Times(1)
-      .WillOnce(SaveArg<4>(&enable_cb));
+      .WillOnce(SaveArg<2>(&enable_cb));
 
   BleAdvertisingManager::Get()->StartAdvertisingSet(
       Bind(&BleAdvertisingManagerTest::StartAdvertisingSetCb,
@@ -715,9 +757,16 @@
   EXPECT_CALL(*hci_mock, SetRandomAddress(_, _, _))
       .Times(1)
       .WillOnce(SaveArg<2>(&set_address_cb));
-  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _, maxExtAdvEvents, _))
+  EXPECT_CALL(
+      *hci_mock,
+      Enable(
+          0x01 /* enable */,
+          AllOf(SizeIs(1),
+                Contains(Field(&SetEnableData::max_extended_advertising_events,
+                               maxExtAdvEvents))),
+          _))
       .Times(1)
-      .WillOnce(SaveArg<4>(&enable_cb));
+      .WillOnce(SaveArg<2>(&enable_cb));
   BleAdvertisingManager::Get()->Enable(
       advertiser_id, true,
       Bind(&BleAdvertisingManagerTest::EnableCb, base::Unretained(this)), 0,
@@ -728,9 +777,13 @@
 
   // Disable advertiser
   status_cb disable_cb;
-  EXPECT_CALL(*hci_mock, Enable(0x00 /* disable */, advertiser_id, _, _, _))
+  EXPECT_CALL(*hci_mock,
+              Enable(0x00 /* disable */,
+                     AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                     advertiser_id))),
+                     _))
       .Times(1)
-      .WillOnce(SaveArg<4>(&disable_cb));
+      .WillOnce(SaveArg<2>(&disable_cb));
   status_cb remove_cb;
   EXPECT_CALL(*hci_mock, RemoveAdvertisingSet(advertiser_id, _))
       .Times(1)
@@ -741,3 +794,282 @@
   disable_cb.Run(0);
   remove_cb.Run(0);
 }
+
+/* This test makes sure that periodic advertising is stopped before
+ * unregistering the advertiser, if it was enabled. */
+TEST_F(BleAdvertisingManagerTest, test_periodic_adv_disable_on_unregister) {
+  std::vector<uint8_t> adv_data;
+  std::vector<uint8_t> scan_resp;
+  tBTM_BLE_ADV_PARAMS params;
+  params.advertising_event_properties = 0x1 /* connectable */;
+  tBLE_PERIODIC_ADV_PARAMS periodic_params;
+  periodic_params.enable = true;  // enable periodic advertising
+  std::vector<uint8_t> periodic_data;
+
+  parameters_cb set_params_cb;
+  status_cb set_address_cb;
+  status_cb set_data_cb;
+  status_cb set_scan_resp_data_cb;
+  status_cb enable_cb;
+  status_cb set_periodic_params_cb;
+  status_cb set_periodic_data_cb;
+  status_cb set_periodic_enable_cb;
+  EXPECT_CALL(*hci_mock, SetParameters1(_, _, _, _, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(*hci_mock, SetParameters2(_, _, _, _, _, _, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<7>(&set_params_cb));
+  EXPECT_CALL(*hci_mock, SetRandomAddress(_, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&set_address_cb));
+  EXPECT_CALL(*hci_mock, SetAdvertisingData(_, _, _, _, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<5>(&set_data_cb));
+  EXPECT_CALL(*hci_mock, SetScanResponseData(_, _, _, _, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<5>(&set_scan_resp_data_cb));
+  EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingParameters(_, _, _, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<4>(&set_periodic_params_cb));
+  EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingData(_, _, _, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<4>(&set_periodic_data_cb));
+  EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingEnable(0x01 /* enable */, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&set_periodic_enable_cb));
+  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&enable_cb));
+
+  BleAdvertisingManager::Get()->StartAdvertisingSet(
+      Bind(&BleAdvertisingManagerTest::StartAdvertisingSetCb,
+           base::Unretained(this)),
+      &params, adv_data, scan_resp, &periodic_params, periodic_data,
+      0 /* duration */, 0 /* maxExtAdvEvents */, Bind(DoNothing2));
+
+  // we are a truly gracious fake controller, let the commands succeed!
+  int selected_tx_power = -15;
+  set_params_cb.Run(0, selected_tx_power);
+  set_address_cb.Run(0);
+  set_data_cb.Run(0);
+  set_scan_resp_data_cb.Run(0);
+  set_periodic_params_cb.Run(0);
+  set_periodic_data_cb.Run(0);
+  set_periodic_enable_cb.Run(0);
+  enable_cb.Run(0);
+  EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, start_advertising_set_status);
+  EXPECT_EQ(selected_tx_power, start_advertising_set_tx_power);
+  int advertiser_id = start_advertising_set_advertiser_id;
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+
+  // ... advertising ...
+
+  // Unregister advertiser - should disable periodic advertising
+  status_cb disable_cb;
+  EXPECT_CALL(*hci_mock,
+              Enable(0x00 /* disable */,
+                     AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                     advertiser_id))),
+                     _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&disable_cb));
+  status_cb disable_periodic_cb;
+  EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingEnable(0x00 /* disable */,
+                                                      advertiser_id, _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&disable_periodic_cb));
+  status_cb remove_cb;
+  EXPECT_CALL(*hci_mock, RemoveAdvertisingSet(advertiser_id, _))
+      .Times(1)
+      .WillOnce(SaveArg<1>(&remove_cb));
+  BleAdvertisingManager::Get()->Unregister(advertiser_id);
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+
+  disable_cb.Run(0);
+  disable_periodic_cb.Run(0);
+  remove_cb.Run(0);
+}
+
+TEST_F(BleAdvertisingManagerTest, test_suspend_resume) {
+  for (int i = 0; i < 10; i++) {
+    BleAdvertisingManager::Get()->RegisterAdvertiser(Bind(
+        &BleAdvertisingManagerTest::RegistrationCb, base::Unretained(this)));
+    EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, reg_status);
+    EXPECT_EQ(i, reg_inst_id);
+  }
+
+  std::array<int, 3> enabled = {{1, 3, 9}};
+
+  for (int advertiser_id : enabled) {
+    status_cb enable_cb;
+    EXPECT_CALL(*hci_mock,
+                Enable(0x01 /* enable */,
+                       AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                       advertiser_id))),
+                       _))
+        .Times(1)
+        .WillOnce(SaveArg<2>(&enable_cb));
+    BleAdvertisingManager::Get()->Enable(
+        advertiser_id, true,
+        Bind(&BleAdvertisingManagerTest::EnableCb, base::Unretained(this)), 0,
+        0, base::Callback<void(uint8_t)>());
+    enable_cb.Run(0);
+    ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+  }
+
+  // we have some advertisers registered, three advertising.
+
+  // Call to Suspend() should disable all running advertisers
+  status_cb disable_cb;
+  EXPECT_CALL(
+      *hci_mock,
+      Enable(0x00 /* disable */,
+             AllOf(SizeIs(3), Contains(Field(&SetEnableData::handle, 1)),
+                   Contains(Field(&SetEnableData::handle, 3)),
+                   Contains(Field(&SetEnableData::handle, 9))),
+             _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&disable_cb));
+
+  BleAdvertisingManager::Get()->Suspend();
+
+  disable_cb.Run(0);
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+
+  // Call to Resume() should re-enable advertisers
+  status_cb enable_cb;
+  EXPECT_CALL(
+      *hci_mock,
+      Enable(0x01 /* enable */,
+             AllOf(SizeIs(3), Contains(Field(&SetEnableData::handle, 1)),
+                   Contains(Field(&SetEnableData::handle, 3)),
+                   Contains(Field(&SetEnableData::handle, 9))),
+             _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&enable_cb));
+
+  BleAdvertisingManager::Get()->Resume();
+
+  enable_cb.Run(0);
+
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+}
+
+/* This test makes sure that conectable advertisment with timeout will get it's
+ * duration and maxExtAdvEvents updated, when it's terminated due to incoming
+ * connection.*/
+TEST_F(BleAdvertisingManagerTest, test_duration_update_during_timeout) {
+  std::vector<uint8_t> adv_data;
+  std::vector<uint8_t> scan_resp;
+  tBTM_BLE_ADV_PARAMS params;
+  params.advertising_event_properties = 0x1 /* connectable */;
+  params.adv_int_min = params.adv_int_max = 0xA0 /* 100ms */;
+  tBLE_PERIODIC_ADV_PARAMS periodic_params;
+  periodic_params.enable = false;
+  std::vector<uint8_t> periodic_data;
+
+  uint8_t maxExtAdvEvents = 50;
+  uint16_t duration = 500 /* 5s */;
+
+  parameters_cb set_params_cb;
+  status_cb set_address_cb;
+  status_cb set_data_cb;
+  status_cb set_scan_resp_data_cb;
+  status_cb enable_cb;
+  EXPECT_CALL(*hci_mock, SetParameters1(_, _, _, _, _, _, _, _, _)).Times(1);
+  EXPECT_CALL(*hci_mock, SetParameters2(_, _, _, _, _, _, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<7>(&set_params_cb));
+  EXPECT_CALL(*hci_mock, SetRandomAddress(_, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&set_address_cb));
+  EXPECT_CALL(*hci_mock, SetAdvertisingData(_, _, _, _, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<5>(&set_data_cb));
+  EXPECT_CALL(*hci_mock, SetScanResponseData(_, _, _, _, _, _))
+      .Times(1)
+      .WillOnce(SaveArg<5>(&set_scan_resp_data_cb));
+  EXPECT_CALL(
+      *hci_mock,
+      Enable(0x01 /* enable */,
+             AllOf(SizeIs(1),
+                   Contains(AllOf(
+                       Field(&SetEnableData::max_extended_advertising_events,
+                             maxExtAdvEvents),
+                       Field(&SetEnableData::duration, duration)))),
+             _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&enable_cb));
+
+  BleAdvertisingManager::Get()->StartAdvertisingSet(
+      Bind(&BleAdvertisingManagerTest::StartAdvertisingSetCb,
+           base::Unretained(this)),
+      &params, adv_data, scan_resp, &periodic_params, periodic_data, duration,
+      maxExtAdvEvents, Bind(DoNothing2));
+
+  // we are a truly gracious fake controller, let the commands succeed!
+  int selected_tx_power = -15;
+  set_params_cb.Run(0, selected_tx_power);
+  set_address_cb.Run(0);
+  set_data_cb.Run(0);
+  set_scan_resp_data_cb.Run(0);
+  enable_cb.Run(0);
+  EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, start_advertising_set_status);
+  EXPECT_EQ(selected_tx_power, start_advertising_set_tx_power);
+  int advertiser_id = start_advertising_set_advertiser_id;
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+
+  // ... advertising ...
+
+  sleep(1);
+
+  std::vector<SetEnableData> setEnableData;
+  // Set terminated because we received connect request! Should trigger
+  // re-enabling of the set
+  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _))
+      .Times(1)
+      .WillOnce(DoAll(SaveArg<1>(&setEnableData), SaveArg<2>(&enable_cb)));
+
+  BleAdvertisingManager::Get()->OnAdvertisingSetTerminated(
+      0x00 /* Advertising successfully ended with a connection being created */,
+      advertiser_id, 0x01fe /* conn_handle*/, 20 /* completed ExtAdvEvents */);
+  enable_cb.Run(0);
+
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+
+  uint16_t new_duration = setEnableData[0].duration;
+  uint8_t new_extAdvEvents = setEnableData[0].max_extended_advertising_events;
+
+  // Sleep is not super-accurate, so assume the recomputed timeouts are around
+  // 4s +/- 100ms
+  EXPECT_NEAR((duration - new_duration), 100 /*4s */, 10);
+  EXPECT_NEAR((maxExtAdvEvents - new_extAdvEvents), 10, 1);
+
+  // Disable advertiser
+  status_cb disable_cb;
+  EXPECT_CALL(*hci_mock,
+              Enable(0x00 /* disable */,
+                     AllOf(SizeIs(1), Contains(Field(&SetEnableData::handle,
+                                                     advertiser_id))),
+                     _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&disable_cb));
+  status_cb remove_cb;
+  EXPECT_CALL(*hci_mock, RemoveAdvertisingSet(advertiser_id, _))
+      .Times(1)
+      .WillOnce(SaveArg<1>(&remove_cb));
+  BleAdvertisingManager::Get()->Unregister(advertiser_id);
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+
+  disable_cb.Run(0);
+  remove_cb.Run(0);
+}
+
+extern void testRecomputeTimeout1();
+extern void testRecomputeTimeout2();
+extern void testRecomputeTimeout3();
+
+TEST_F(BleAdvertisingManagerTest, test_recompute_timeout) {
+  testRecomputeTimeout1();
+  testRecomputeTimeout2();
+  testRecomputeTimeout3();
+}
\ No newline at end of file
diff --git a/stack/test/stack_btu_test.cc b/stack/test/stack_btu_test.cc
index 9d72509..49dc52e 100644
--- a/stack/test/stack_btu_test.cc
+++ b/stack/test/stack_btu_test.cc
@@ -83,7 +83,6 @@
 void module_clean_up(module_t const*){};
 
 thread_t* bt_workqueue_thread;
-fixed_queue_t* btu_general_alarm_queue;
 
 class BtuMessageLoopTest : public testing::Test {
  public:
@@ -93,7 +92,6 @@
   virtual void SetUp() {
     // Initialize alarms to prevent btu_task_shut_down from crashing
     alarm_new("test alarm");
-    btu_general_alarm_queue = fixed_queue_new(SIZE_MAX);
     bt_workqueue_thread = thread_new("test alarm thread");
 
     // btu_task_start_up calls btif_transfer_context to let the stack know
diff --git a/stack/test/stack_smp_test.cc b/stack/test/stack_smp_test.cc
index 04b472d..2391012 100644
--- a/stack/test/stack_smp_test.cc
+++ b/stack/test/stack_smp_test.cc
@@ -55,19 +55,19 @@
  */
 
 // Set remote bda to 0xB1B2B3B4B5B6
-bool BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr,
+bool BTM_ReadRemoteConnectionAddr(const RawAddress& pseudo_addr,
+                                  RawAddress& conn_addr,
                                   tBLE_ADDR_TYPE* p_addr_type) {
-  const uint8_t local_bda[] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6};
-  memcpy(conn_addr, local_bda, sizeof(local_bda));
+  conn_addr = RawAddress({0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6});
   *p_addr_type = 0x00;
   return true;
 }
 
 // Set local_bda to 0xA1A2A3A4A5A6
-void BTM_ReadConnectionAddr(BD_ADDR remote_bda, BD_ADDR local_conn_addr,
+void BTM_ReadConnectionAddr(const RawAddress& remote_bda,
+                            RawAddress& local_conn_addr,
                             tBLE_ADDR_TYPE* p_addr_type) {
-  const uint8_t local_bda[] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6};
-  memcpy(local_conn_addr, local_bda, sizeof(local_bda));
+  local_conn_addr = RawAddress({0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6});
   *p_addr_type = 0x01;
 }
 
@@ -84,7 +84,7 @@
                                  tBLE_ADDR_TYPE remote_bd_addr_type,
                                  BT_OCTET16 p1);
 
-extern void smp_gen_p2_4_confirm(tSMP_CB* p_cb, BD_ADDR remote_bda,
+extern void smp_gen_p2_4_confirm(tSMP_CB* p_cb, const RawAddress& remote_bda,
                                  BT_OCTET16 p2);
 
 extern tSMP_STATUS smp_calculate_comfirm(tSMP_CB* p_cb, BT_OCTET16 rand,
@@ -170,7 +170,7 @@
 // Test smp_gen_p2_4_confirm function implementation
 TEST_F(SmpCalculateConfirmTest, test_smp_gen_p2_4_confirm_as_master) {
   BT_OCTET16 p2;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBLE_ADDR_TYPE remote_bd_addr_type = 0;
   BTM_ReadRemoteConnectionAddr(p_cb_.pairing_bda, remote_bda,
                                &remote_bd_addr_type);
@@ -186,7 +186,7 @@
 // Test smp_gen_p1_4_confirm and SMP_Encrypt function implementation
 TEST_F(SmpCalculateConfirmTest, test_SMP_Encrypt_as_master) {
   BT_OCTET16 p1;
-  BD_ADDR remote_bda;
+  RawAddress remote_bda;
   tBLE_ADDR_TYPE remote_bd_addr_type = 0;
   BTM_ReadRemoteConnectionAddr(p_cb_.pairing_bda, remote_bda,
                                &remote_bd_addr_type);
@@ -224,4 +224,4 @@
   dump_uint128_reverse(output.param_buf, confirm_str);
   ASSERT_THAT(confirm_str, StrEq(expected_confirm_str));
 }
-}
+}  // namespace testing
diff --git a/test/rootcanal/Android.bp b/test/rootcanal/Android.bp
index d7438a0..d5a6b9f 100644
--- a/test/rootcanal/Android.bp
+++ b/test/rootcanal/Android.bp
@@ -45,6 +45,7 @@
         "android.hardware.bluetooth-async",
         "android.hardware.bluetooth-hci",
         "libbt-rootcanal",
+        "libbluetooth-types",
     ],
     include_dirs: [
         "system/bt",
diff --git a/test/run_unit_tests.sh b/test/run_unit_tests.sh
index 9df3d47..ab9ecc2 100755
--- a/test/run_unit_tests.sh
+++ b/test/run_unit_tests.sh
@@ -14,6 +14,7 @@
   net_test_stack_multi_adv
   net_test_stack_ad_parser
   net_test_stack_smp
+  net_test_types
   net_test_btu_message_loop
   net_test_osi
   performance_test
diff --git a/test/suite/BUILD.gn b/test/suite/BUILD.gn
index e413eb0..d481000 100644
--- a/test/suite/BUILD.gn
+++ b/test/suite/BUILD.gn
@@ -31,6 +31,7 @@
     "//main:bluetooth.default",
     "//service:service",
     "//service:service_unittests",
+    "//types:types_unittests",
     "//third_party/libchrome:base",
     "//osi",
     "//third_party/googletest:gtest_main",
diff --git a/test/suite/adapter/adapter_unittest.cc b/test/suite/adapter/adapter_unittest.cc
index f53de32..730ac5a 100644
--- a/test/suite/adapter/adapter_unittest.cc
+++ b/test/suite/adapter/adapter_unittest.cc
@@ -151,7 +151,7 @@
   EXPECT_EQ(GetState(), BT_STATE_OFF)
       << "Test should be run with Adapter disabled";
 
-  bt_bdaddr_t bdaddr = {{0x22, 0x22, 0x22, 0x22, 0x22, 0x22}};
+  RawAddress bdaddr = {{0x22, 0x22, 0x22, 0x22, 0x22, 0x22}};
 
   for (int i = 0; i < kTestRepeatCount; ++i) {
     EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
diff --git a/test/suite/adapter/bluetooth_test.cc b/test/suite/adapter/bluetooth_test.cc
index eb4afd5..dcb95d1 100644
--- a/test/suite/adapter/bluetooth_test.cc
+++ b/test/suite/adapter/bluetooth_test.cc
@@ -18,7 +18,6 @@
 
 #include "adapter/bluetooth_test.h"
 #include <mutex>
-#include "btcore/include/bdaddr.h"
 #include "btcore/include/property.h"
 
 namespace {
@@ -89,9 +88,9 @@
   return nullptr;
 }
 
-bt_property_t* BluetoothTest::GetRemoteDeviceProperty(const bt_bdaddr_t* addr,
+bt_property_t* BluetoothTest::GetRemoteDeviceProperty(const RawAddress* addr,
                                                       bt_property_type_t type) {
-  if (!bdaddr_equals(&curr_remote_device_, addr)) return nullptr;
+  if (curr_remote_device_ != *addr) return nullptr;
 
   for (int i = 0; i < remote_device_properties_changed_count_; i++) {
     if (remote_device_last_changed_properties_[i].type == type) {
@@ -129,10 +128,10 @@
 
 // callback
 void BluetoothTest::RemoteDevicePropertiesCallback(bt_status_t status,
-                                                   bt_bdaddr_t* remote_bd_addr,
+                                                   RawAddress* remote_bd_addr,
                                                    int num_properties,
                                                    bt_property_t* properties) {
-  bdaddr_copy(&curr_remote_device_, remote_bd_addr);
+  curr_remote_device_ = *remote_bd_addr;
   property_free_array(remote_device_last_changed_properties_,
                       remote_device_properties_changed_count_);
   remote_device_last_changed_properties_ =
diff --git a/test/suite/adapter/bluetooth_test.h b/test/suite/adapter/bluetooth_test.h
index 2c12aff..52b8518 100644
--- a/test/suite/adapter/bluetooth_test.h
+++ b/test/suite/adapter/bluetooth_test.h
@@ -55,7 +55,7 @@
   bt_property_t* GetProperty(bt_property_type_t type);
 
   // Get the value of a specific remote device property
-  bt_property_t* GetRemoteDeviceProperty(const bt_bdaddr_t* addr,
+  bt_property_t* GetRemoteDeviceProperty(const RawAddress* addr,
                                          bt_property_type_t type);
 
   // Get the current discovery state
@@ -83,7 +83,7 @@
 
   // A callback that is called when the remote device's property changes
   void RemoteDevicePropertiesCallback(bt_status_t status,
-                                      bt_bdaddr_t* remote_bd_addr,
+                                      RawAddress* remote_bd_addr,
                                       int num_properties,
                                       bt_property_t* properties) override;
 
@@ -107,7 +107,7 @@
   bt_state_t state_;
   int properties_changed_count_;
   bt_property_t* last_changed_properties_;
-  bt_bdaddr_t curr_remote_device_;
+  RawAddress curr_remote_device_;
   int remote_device_properties_changed_count_;
   bt_property_t* remote_device_last_changed_properties_;
   bt_discovery_state_t discovery_state_;
diff --git a/test/suite/gatt/gatt_test.cc b/test/suite/gatt/gatt_test.cc
index 2ea43cf..8f3ff61 100644
--- a/test/suite/gatt/gatt_test.cc
+++ b/test/suite/gatt/gatt_test.cc
@@ -18,7 +18,6 @@
 
 #include "gatt/gatt_test.h"
 #include "adapter/bluetooth_test.h"
-#include "btcore/include/bdaddr.h"
 
 namespace bttest {
 
@@ -99,8 +98,8 @@
 }
 
 void GattTest::ScanResultCallback(
-    bluetooth::hal::BluetoothGattInterface* /* unused */,
-    const bt_bdaddr_t& bda, int rssi, std::vector<uint8_t> adv_data) {
+    bluetooth::hal::BluetoothGattInterface* /* unused */, const RawAddress& bda,
+    int rssi, std::vector<uint8_t> adv_data) {
   semaphore_post(scan_result_callback_sem_);
 }
 
diff --git a/test/suite/gatt/gatt_test.h b/test/suite/gatt/gatt_test.h
index cdf532c..29e0c24 100644
--- a/test/suite/gatt/gatt_test.h
+++ b/test/suite/gatt/gatt_test.h
@@ -61,7 +61,7 @@
       bluetooth::hal::BluetoothGattInterface* /* unused */, int status,
       int clientIf, const bt_uuid_t& app_uuid) override;
   void ScanResultCallback(bluetooth::hal::BluetoothGattInterface* /* unused */,
-                          const bt_bdaddr_t& bda, int rssi,
+                          const RawAddress& bda, int rssi,
                           std::vector<uint8_t> adv_data) override;
 
   // bluetooth::hal::BluetoothGattInterface::ServerObserver overrides
diff --git a/test/suite/gatt/gatt_unittest.cc b/test/suite/gatt/gatt_unittest.cc
index c216d6e..bc4c29e 100644
--- a/test/suite/gatt/gatt_unittest.cc
+++ b/test/suite/gatt/gatt_unittest.cc
@@ -41,7 +41,7 @@
   // Registers gatt client.
   bt_uuid_t gatt_client_uuid;
   create_random_uuid(&gatt_client_uuid, DEFAULT_RANDOM_SEED);
-  gatt_client_interface()->register_client(&gatt_client_uuid);
+  gatt_client_interface()->register_client(gatt_client_uuid);
   semaphore_wait(register_client_callback_sem_);
   EXPECT_TRUE(status() == BT_STATUS_SUCCESS)
       << "Error registering GATT client app callback.";
@@ -54,7 +54,7 @@
   // Registers gatt server.
   bt_uuid_t gatt_server_uuid;
   create_random_uuid(&gatt_server_uuid, DEFAULT_RANDOM_SEED);
-  gatt_server_interface()->register_server(&gatt_server_uuid);
+  gatt_server_interface()->register_server(gatt_server_uuid);
   semaphore_wait(register_server_callback_sem_);
   EXPECT_TRUE(status() == BT_STATUS_SUCCESS)
       << "Error registering GATT server app callback.";
@@ -67,7 +67,7 @@
   // Registers gatt server.
   bt_uuid_t gatt_server_uuid;
   create_random_uuid(&gatt_server_uuid, DEFAULT_RANDOM_SEED);
-  gatt_server_interface()->register_server(&gatt_server_uuid);
+  gatt_server_interface()->register_server(gatt_server_uuid);
   semaphore_wait(register_server_callback_sem_);
   EXPECT_TRUE(status() == BT_STATUS_SUCCESS)
       << "Error registering GATT server app callback.";
diff --git a/test/suite/rfcomm/rfcomm_test.cc b/test/suite/rfcomm/rfcomm_test.cc
index adde7ce..194320d 100644
--- a/test/suite/rfcomm/rfcomm_test.cc
+++ b/test/suite/rfcomm/rfcomm_test.cc
@@ -19,7 +19,6 @@
 #include "rfcomm/rfcomm_test.h"
 #include "adapter/bluetooth_test.h"
 
-#include "btcore/include/bdaddr.h"
 #include "btcore/include/uuid.h"
 
 namespace bttest {
@@ -40,16 +39,15 @@
   ASSERT_NE(socket_interface_, nullptr);
 
   // Find a bonded device that supports HFP
-  string_to_bdaddr("00:00:00:00:00:00", &bt_remote_bdaddr_);
+  bt_remote_bdaddr_ = RawAddress::kEmpty;
   char value[1280];
 
   bt_property_t* bonded_devices_prop =
       GetProperty(BT_PROPERTY_ADAPTER_BONDED_DEVICES);
-  bt_bdaddr_t* devices = (bt_bdaddr_t*)bonded_devices_prop->val;
-  int num_bonded_devices = bonded_devices_prop->len / sizeof(bt_bdaddr_t);
+  RawAddress* devices = (RawAddress*)bonded_devices_prop->val;
+  int num_bonded_devices = bonded_devices_prop->len / sizeof(RawAddress);
 
-  for (int i = 0; i < num_bonded_devices && bdaddr_is_empty(&bt_remote_bdaddr_);
-       i++) {
+  for (int i = 0; i < num_bonded_devices && bt_remote_bdaddr_.IsEmpty(); i++) {
     ClearSemaphore(remote_device_properties_callback_sem_);
     bt_interface()->get_remote_device_property(&devices[i], BT_PROPERTY_UUIDS);
     semaphore_wait(remote_device_properties_callback_sem_);
@@ -63,13 +61,13 @@
     for (int j = 0; j < num_uuids; j++) {
       uuid_to_string(&uuids[j], (uuid_string_t*)value);
       if (!memcmp(uuids + j, &HFP_UUID, sizeof(bt_uuid_t))) {
-        bdaddr_copy(&bt_remote_bdaddr_, devices + i);
+        bt_remote_bdaddr_ = *(devices + i);
         break;
       }
     }
   }
 
-  ASSERT_FALSE(bdaddr_is_empty(&bt_remote_bdaddr_))
+  ASSERT_FALSE(bt_remote_bdaddr_.IsEmpty())
       << "Could not find paired device that supports HFP";
 }
 
diff --git a/test/suite/rfcomm/rfcomm_test.h b/test/suite/rfcomm/rfcomm_test.h
index 662fdb1..03d2730 100644
--- a/test/suite/rfcomm/rfcomm_test.h
+++ b/test/suite/rfcomm/rfcomm_test.h
@@ -36,7 +36,7 @@
   // TearDown cleans up the Bluetooth and RFCOMM interfaces
   virtual void TearDown();
 
-  bt_bdaddr_t bt_remote_bdaddr_;
+  RawAddress bt_remote_bdaddr_;
 
   static const bt_uuid_t HFP_UUID;
 
diff --git a/test/suite/rfcomm/rfcomm_unittest.cc b/test/suite/rfcomm/rfcomm_unittest.cc
index b81f781..eabe73c 100644
--- a/test/suite/rfcomm/rfcomm_unittest.cc
+++ b/test/suite/rfcomm/rfcomm_unittest.cc
@@ -19,8 +19,6 @@
 #include "adapter/bluetooth_test.h"
 #include "rfcomm/rfcomm_test.h"
 
-#include "btcore/include/bdaddr.h"
-
 #include <sys/socket.h>
 #include <unistd.h>
 
@@ -51,7 +49,7 @@
   EXPECT_TRUE(len == sizeof(signal))
       << "Connection signal not read from RFCOMM socket. Bytes read: " << len;
 
-  EXPECT_TRUE(!memcmp(&signal.bd_addr, &bt_remote_bdaddr_, sizeof(bt_bdaddr_t)))
+  EXPECT_TRUE(signal.bd_addr == bt_remote_bdaddr_)
       << "Connected to a different bdaddr than expected.";
   EXPECT_TRUE(channel == signal.channel)
       << "Inconsistent channels returned: " << channel << " and "
@@ -101,8 +99,7 @@
       signal_fail++;
     }
 
-    EXPECT_TRUE(
-        !memcmp(&signal.bd_addr, &bt_remote_bdaddr_, sizeof(bt_bdaddr_t)))
+    EXPECT_TRUE(signal.bd_addr == bt_remote_bdaddr_)
         << "Connected to a different bdaddr than expected.";
     EXPECT_TRUE(channel == signal.channel)
         << "Inconsistent channels returned: " << channel << " and "
diff --git a/tools/bdtool/adapter.c b/tools/bdtool/adapter.c
index 70b1b70..c7067fc 100644
--- a/tools/bdtool/adapter.c
+++ b/tools/bdtool/adapter.c
@@ -18,7 +18,6 @@
 
 #include "support/adapter.h"
 #include "base.h"
-#include "btcore/include/bdaddr.h"
 #include "btcore/include/property.h"
 #include "support/callbacks.h"
 
@@ -58,7 +57,7 @@
 bt_bond_state_t adapter_get_bond_state() { return bond_state; }
 
 // callback
-void acl_state_changed(bt_status_t status, bt_bdaddr_t* remote_bd_addr,
+void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
                        bt_acl_state_t state) {
   acl_state = state;
   CALLBACK_RET();
@@ -81,7 +80,7 @@
 }
 
 // callback
-void bond_state_changed(bt_status_t status, bt_bdaddr_t* bdaddr,
+void bond_state_changed(bt_status_t status, RawAddress* bdaddr,
                         bt_bond_state_t state) {
   char buf[18];
   bond_state = state;
@@ -138,7 +137,7 @@
 }
 
 // callback
-void remote_device_properties(bt_status_t status, bt_bdaddr_t* bdaddr,
+void remote_device_properties(bt_status_t status, RawAddress* bdaddr,
                               int num_properties, bt_property_t* properties) {
   char buf[18];
   fprintf(stdout, "Device found bdaddr:%s num_properties:%d\n",
@@ -150,9 +149,8 @@
 }
 
 // callback
-void ssp_request(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name,
-                 uint32_t cod, bt_ssp_variant_t pairing_variant,
-                 uint32_t pass_key) {
+void ssp_request(RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
+                 bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
   char* pairing_variant_name = "Unknown";
 
   switch (pairing_variant) {
@@ -199,7 +197,7 @@
 
       case BT_PROPERTY_BDADDR: {
         char buf[18];
-        const bt_bdaddr_t* addr = property_as_addr(property);
+        const RawAddress* addr = property_as_addr(property);
         if (addr)
           fprintf(stdout, " addr:%s\n",
                   bdaddr_to_string(addr, buf, sizeof(buf)));
diff --git a/tools/bdtool/bdtool.c b/tools/bdtool/bdtool.c
index f25cf24..d37d3d3 100644
--- a/tools/bdtool/bdtool.c
+++ b/tools/bdtool/bdtool.c
@@ -21,7 +21,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 
-#include "btcore/include/bdaddr.h"
 #include "btcore/include/property.h"
 #include "osi/include/osi.h"
 #include "test/suite/support/callbacks.h"
@@ -36,7 +35,7 @@
 
 const bt_interface_t* bt_interface;
 
-bt_bdaddr_t bt_remote_bdaddr;
+RawAddress bt_remote_bdaddr;
 
 static int f_verbose;
 static bool discover = false;
diff --git a/tools/mcap_tool/BUILD.gn b/tools/mcap_tool/BUILD.gn
index a5fef31..a3f18eb 100644
--- a/tools/mcap_tool/BUILD.gn
+++ b/tools/mcap_tool/BUILD.gn
@@ -39,5 +39,6 @@
     "//btcore",
     "//osi",
     "//third_party/libchrome:base",
+    "//types",
   ]
 }
diff --git a/tools/mcap_tool/mcap_test_app.cc b/tools/mcap_tool/mcap_test_app.cc
index 29e50dc..f0c1b4f 100644
--- a/tools/mcap_tool/mcap_test_app.cc
+++ b/tools/mcap_tool/mcap_test_app.cc
@@ -52,19 +52,14 @@
 }
 
 static void print_mcap_event(const tMCA_DISCONNECT_IND* mcap_disconnect_ind) {
-  bdstr_t bd_addr_str;
   printf("%s: peer_bd_addr=%s,l2cap_disconnect_reason=0x%04x\n", __func__,
-         bdaddr_to_string((bt_bdaddr_t*)mcap_disconnect_ind->bd_addr,
-                          bd_addr_str, sizeof(bd_addr_str)),
+         mcap_disconnect_ind->bd_addr.ToString().c_str(),
          mcap_disconnect_ind->reason);
 }
 
 static void print_mcap_event(const tMCA_CONNECT_IND* mcap_connect_ind) {
-  bdstr_t bd_addr_str;
   printf("%s: peer_bd_addr=%s, peer_mtu=%d \n", __func__,
-         bdaddr_to_string((bt_bdaddr_t*)mcap_connect_ind->bd_addr, bd_addr_str,
-                          sizeof(bd_addr_str)),
-         mcap_connect_ind->mtu);
+         mcap_connect_ind->bd_addr.ToString().c_str(), mcap_connect_ind->mtu);
 }
 
 static void print_mcap_event(const tMCA_RSP_EVT* mcap_rsp) {
@@ -137,7 +132,7 @@
 
 bool McapTestApp::Registered() { return _mcap_handle > 0; }
 
-bool McapTestApp::ConnectMcl(const bt_bdaddr_t& bd_addr, uint16_t ctrl_psm,
+bool McapTestApp::ConnectMcl(const RawAddress& bd_addr, uint16_t ctrl_psm,
                              uint16_t sec_mask) {
   if (!Registered()) {
     LOG(ERROR) << "Application not registered";
@@ -169,9 +164,9 @@
 
 uint8_t McapTestApp::GetHandle() { return _mcap_handle; }
 
-McapMcl* McapTestApp::FindMclByPeerAddress(const bt_bdaddr_t& bd_addr) {
+McapMcl* McapTestApp::FindMclByPeerAddress(const RawAddress& bd_addr) {
   for (McapMcl& mcl : _mcl_list) {
-    if (bdaddr_equals(&mcl.GetPeerAddress(), &bd_addr)) {
+    if (mcl.GetPeerAddress() == bd_addr) {
       return &mcl;
     }
   }
@@ -431,7 +426,7 @@
       // Called when MCA_ConnectReq succeeded
       print_mcap_event(&p_data->connect_ind);
       LOG(INFO) << "Received MCL handle " << (int)mcl;
-      bt_bdaddr_t bd_addr = *((bt_bdaddr_t*)p_data->connect_ind.bd_addr);
+      RawAddress bd_addr = p_data->connect_ind.bd_addr;
       mcap_mcl = FindMclByPeerAddress(bd_addr);
       if (!mcap_mcl) {
         LOG(INFO) << "Creating new MCL for ID " << (int)mcl;
@@ -450,20 +445,14 @@
     case MCA_DISCONNECT_IND_EVT: {
       // Called when MCA_ConnectReq failed or MCA_DisconnectReq succeeded
       print_mcap_event(&p_data->disconnect_ind);
-      bt_bdaddr_t bd_addr = *((bt_bdaddr_t*)p_data->disconnect_ind.bd_addr);
+      RawAddress bd_addr = p_data->disconnect_ind.bd_addr;
       mcap_mcl = FindMclByPeerAddress(bd_addr);
       if (!mcap_mcl) {
-        bdstr_t bd_addr_str;
-        LOG(ERROR) << "No MCL for BD addr "
-                   << bdaddr_to_string(&bd_addr, bd_addr_str,
-                                       sizeof(bd_addr_str));
+        LOG(ERROR) << "No MCL for BD addr " << bd_addr;
         break;
       }
       if (!mcap_mcl->IsConnected()) {
-        bdstr_t bd_addr_str;
-        LOG(WARNING) << "MCL for " << bdaddr_to_string(&bd_addr, bd_addr_str,
-                                                       sizeof(bd_addr_str))
-                     << " is already disconnected";
+        LOG(WARNING) << "MCL for " << bd_addr << " is already disconnected";
       }
       mcap_mcl->SetHandle(0);
       mcap_mcl->SetMtu(0);
diff --git a/tools/mcap_tool/mcap_test_app.h b/tools/mcap_tool/mcap_test_app.h
index 23dfa37..691b1f6 100644
--- a/tools/mcap_tool/mcap_test_app.h
+++ b/tools/mcap_tool/mcap_test_app.h
@@ -24,7 +24,6 @@
 
 #include <base/logging.h>
 
-#include "bdaddr.h"
 #include "mca_api.h"
 
 #include "mcap_test_mcl.h"
@@ -71,7 +70,7 @@
    * @param sec_mask Security mask
    * @return True on success
    */
-  bool ConnectMcl(const bt_bdaddr_t& bd_addr, uint16_t ctrl_psm,
+  bool ConnectMcl(const RawAddress& bd_addr, uint16_t ctrl_psm,
                   uint16_t sec_mask);
   /**
    * Create MCAP Data End Point
@@ -84,7 +83,7 @@
                   tMCA_DATA_CBACK* data_callback);
   // Simple methods that are self-explanatory
   uint8_t GetHandle();
-  McapMcl* FindMclByPeerAddress(const bt_bdaddr_t& bd_addr);
+  McapMcl* FindMclByPeerAddress(const RawAddress& bd_addr);
   McapMcl* FindMclByHandle(tMCA_CL mcl_handle);
   McapMdep* FindMdepByHandle(tMCA_DEP mdep_handle);
   void RemoveMclByHandle(tMCA_CL mcl_handle);
diff --git a/tools/mcap_tool/mcap_test_mcl.cc b/tools/mcap_tool/mcap_test_mcl.cc
index 8842c04..629350a 100644
--- a/tools/mcap_tool/mcap_test_mcl.cc
+++ b/tools/mcap_tool/mcap_test_mcl.cc
@@ -17,7 +17,6 @@
 
 #include <base/logging.h>
 
-#include "bdaddr.h"
 #include "mca_api.h"
 #include "mca_defs.h"
 #include "mcap_test_mcl.h"
@@ -25,7 +24,7 @@
 namespace SYSTEM_BT_TOOLS_MCAP_TOOL {
 
 McapMcl::McapMcl(btmcap_test_interface_t* mcap_test_interface,
-                 tMCA_HANDLE mcap_handle, const bt_bdaddr_t& peer_bd_addr)
+                 tMCA_HANDLE mcap_handle, const RawAddress& peer_bd_addr)
     : _mdl_list() {
   _mcap_handle = mcap_handle;
   _mcap_test_interface = mcap_test_interface;
@@ -35,7 +34,7 @@
 
 bool McapMcl::Connect(uint16_t ctrl_psm, uint16_t sec_mask) {
   tMCA_RESULT ret = _mcap_test_interface->connect_mcl(
-      _mcap_handle, _peer_bd_addr.address, ctrl_psm, sec_mask);
+      _mcap_handle, _peer_bd_addr, ctrl_psm, sec_mask);
   LOG_IF(INFO, ret != MCA_SUCCESS) << "ret=" << (int)ret;
   return ret == MCA_SUCCESS;
 }
@@ -134,7 +133,7 @@
   return ret == MCA_SUCCESS;
 }
 
-bt_bdaddr_t& McapMcl::GetPeerAddress() { return _peer_bd_addr; }
+RawAddress& McapMcl::GetPeerAddress() { return _peer_bd_addr; }
 
 void McapMcl::SetHandle(tMCA_CL handle) { _mcl_handle = handle; }
 
diff --git a/tools/mcap_tool/mcap_test_mcl.h b/tools/mcap_tool/mcap_test_mcl.h
index 2d71ee6..01a8aa6 100644
--- a/tools/mcap_tool/mcap_test_mcl.h
+++ b/tools/mcap_tool/mcap_test_mcl.h
@@ -17,7 +17,6 @@
 
 #include <vector>
 
-#include "bdaddr.h"
 #include "mca_api.h"
 #include "mcap_test_mdl.h"
 
@@ -32,7 +31,7 @@
    * @param peer_bd_addr Peer Bluetooth MAC address
    */
   McapMcl(btmcap_test_interface_t* mcap_test_interface, tMCA_HANDLE mcap_handle,
-          const bt_bdaddr_t& peer_bd_addr);
+          const RawAddress& peer_bd_addr);
   /**
    * Connect this MCL's control channel
    * @param ctrl_psm Control channel L2CAP PSM
@@ -101,7 +100,7 @@
    */
   bool DeleteMdl(uint16_t mdl_id);
   // Simple methods that are self-explanatory
-  bt_bdaddr_t& GetPeerAddress();
+  RawAddress& GetPeerAddress();
   void SetHandle(tMCA_CL handle);
   tMCA_CL GetHandle() const;
   void SetMtu(uint16_t mtu);
@@ -120,7 +119,7 @@
   // Initialized during start up
   btmcap_test_interface_t* _mcap_test_interface;
   tMCA_HANDLE _mcap_handle;
-  bt_bdaddr_t _peer_bd_addr;
+  RawAddress _peer_bd_addr;
   std::vector<McapMdl> _mdl_list;
 
   // Initialized later
diff --git a/tools/mcap_tool/mcap_tool.cc b/tools/mcap_tool/mcap_tool.cc
index c7abd55..fad3378 100644
--- a/tools/mcap_tool/mcap_tool.cc
+++ b/tools/mcap_tool/mcap_tool.cc
@@ -48,7 +48,6 @@
 #endif
 #include <base/logging.h>
 
-#include "bdaddr.h"
 #include "bt_types.h"
 #include "l2c_api.h"
 #include "mca_api.h"
@@ -424,8 +423,7 @@
 
 static void adapter_properties_changed(bt_status_t status, int num_properties,
                                        bt_property_t* properties) {
-  bt_bdaddr_t bd_addr;
-  bdstr_t bd_addr_str;
+  RawAddress bd_addr;
   if (!properties) {
     printf("properties is null\n");
     return;
@@ -434,8 +432,7 @@
     case BT_PROPERTY_BDADDR:
       memcpy(bd_addr.address, properties->val,
              MIN((size_t)properties->len, sizeof(bd_addr)));
-      bdaddr_to_string(&bd_addr, bd_addr_str, sizeof(bd_addr_str));
-      LOG(INFO) << "Local Bd Addr = " << bd_addr_str;
+      LOG(INFO) << "Local Bd Addr = " << bd_addr;
       break;
     default:
       break;
@@ -448,7 +445,7 @@
             << (state == BT_DISCOVERY_STOPPED ? "STOPPED" : "STARTED");
 }
 
-static void pin_request_cb(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name,
+static void pin_request_cb(RawAddress* remote_bd_addr, bt_bdname_t* bd_name,
                            uint32_t cod, bool min_16_digit) {
   bt_pin_code_t pincode = {{0x31, 0x32, 0x33, 0x34}};
 
@@ -458,7 +455,7 @@
   }
 }
 
-static void ssp_request_cb(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name,
+static void ssp_request_cb(RawAddress* remote_bd_addr, bt_bdname_t* bd_name,
                            uint32_t cod, bt_ssp_variant_t pairing_variant,
                            uint32_t pass_key) {
   LOG(INFO) << __func__ << ": device_name:" << bd_name->name
@@ -472,19 +469,18 @@
 }
 
 static void bond_state_changed_cb(bt_status_t status,
-                                  bt_bdaddr_t* remote_bd_addr,
+                                  RawAddress* remote_bd_addr,
                                   bt_bond_state_t state) {
   LOG(INFO) << "Bond State Changed = " << state;
   global_pair_state = state;
 }
 
-static void acl_state_changed(bt_status_t status, bt_bdaddr_t* remote_bd_addr,
+static void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
                               bt_acl_state_t state) {
-  bdstr_t bd_addr_str;
-  bdaddr_to_string(remote_bd_addr, bd_addr_str, sizeof(bd_addr_str));
-  LOG(INFO) << __func__ << ": remote_bd_addr=" << bd_addr_str << ", acl status="
-            << (state == BT_ACL_STATE_CONNECTED ? "ACL Connected"
-                                                : "ACL Disconnected");
+  LOG(INFO) << __func__ << ": remote_bd_addr=" << *remote_bd_addr
+            << ", acl status=" << (state == BT_ACL_STATE_CONNECTED
+                                       ? "ACL Connected"
+                                       : "ACL Disconnected");
 }
 
 static void dut_mode_recv(uint16_t opcode, uint8_t* buf, uint8_t len) {
@@ -680,8 +676,8 @@
 static void do_mcap_connect_mcl(char* p) {
   char buf[64];
   get_str(&p, buf);  // arg1
-  bt_bdaddr_t bd_addr;
-  bool valid_bd_addr = string_to_bdaddr(buf, &bd_addr);
+  RawAddress bd_addr;
+  bool valid_bd_addr = RawAddress::FromString(buf, bd_addr);
   uint16_t ctrl_psm = get_hex(&p, 0);  // arg2
   uint16_t sec_mask = get_int(&p, 0);  // arg3
   printf("%s: mcap_handle=%d, ctrl_psm=0x%04x, secMask=0x%04x, bd_addr=%s\n",
@@ -697,8 +693,8 @@
 static void do_mcap_disconnect_mcl(char* p) {
   char buf[64];
   get_str(&p, buf);  // arg1
-  bt_bdaddr_t bd_addr;
-  bool valid_bd_addr = string_to_bdaddr(buf, &bd_addr);
+  RawAddress bd_addr;
+  bool valid_bd_addr = RawAddress::FromString(buf, bd_addr);
   printf("%s: bd_addr=%s\n", __func__, buf);
   if (!valid_bd_addr) {
     printf("%s: Invalid Parameters\n", __func__);
@@ -716,8 +712,8 @@
 static void do_mcap_create_mdl(char* p) {
   char buf[64];
   get_str(&p, buf);  // arg1
-  bt_bdaddr_t bd_addr;
-  bool valid_bd_addr = string_to_bdaddr(buf, &bd_addr);
+  RawAddress bd_addr;
+  bool valid_bd_addr = RawAddress::FromString(buf, bd_addr);
   uint16_t mdep_handle = get_int(&p, 0);  // arg2
   uint16_t data_psm = get_hex(&p, 0);     // arg3
   uint16_t mdl_id = get_int(&p, 0);       // arg4
@@ -746,8 +742,8 @@
 static void do_mcap_data_channel_config(char* p) {
   char buf[64];
   get_str(&p, buf);  // arg1
-  bt_bdaddr_t bd_addr;
-  bool valid_bd_addr = string_to_bdaddr(buf, &bd_addr);
+  RawAddress bd_addr;
+  bool valid_bd_addr = RawAddress::FromString(buf, bd_addr);
   printf("%s: bd_addr=%s\n", __func__, buf);
   if (!valid_bd_addr) {
     printf("%s: Invalid Parameters\n", __func__);
@@ -765,8 +761,8 @@
 static void do_mcap_abort_mdl(char* p) {
   char buf[64];
   get_str(&p, buf);  // arg1
-  bt_bdaddr_t bd_addr;
-  bool valid_bd_addr = string_to_bdaddr(buf, &bd_addr);
+  RawAddress bd_addr;
+  bool valid_bd_addr = RawAddress::FromString(buf, bd_addr);
   printf("%s: bd_addr=%s\n", __func__, buf);
   if (!valid_bd_addr) {
     printf("%s: Invalid Parameters\n", __func__);
@@ -784,8 +780,8 @@
 static void do_mcap_delete_mdl(char* p) {
   char buf[64];
   get_str(&p, buf);  // arg1
-  bt_bdaddr_t bd_addr;
-  bool valid_bd_addr = string_to_bdaddr(buf, &bd_addr);
+  RawAddress bd_addr;
+  bool valid_bd_addr = RawAddress::FromString(buf, bd_addr);
   uint16_t mdl_id = get_int(&p, 0);  // arg2
   printf("%s: bd_addr=%s, mdl_id=%d\n", __func__, buf, mdl_id);
   if (!valid_bd_addr) {
@@ -804,8 +800,8 @@
 static void do_mcap_close_mdl(char* p) {
   char buf[64];
   get_str(&p, buf);  // arg1
-  bt_bdaddr_t bd_addr;
-  bool valid_bd_addr = string_to_bdaddr(buf, &bd_addr);
+  RawAddress bd_addr;
+  bool valid_bd_addr = RawAddress::FromString(buf, bd_addr);
   uint16_t mdl_id = get_int(&p, 0);  // arg2
   printf("%s: bd_addr=%s, mdl_id=%d\n", __func__, buf, mdl_id);
   if (!valid_bd_addr || !mdl_id) {
@@ -829,8 +825,8 @@
 static void do_mcap_reconnect_mdl(char* p) {
   char buf[64];
   get_str(&p, buf);  // arg1
-  bt_bdaddr_t bd_addr;
-  bool valid_bd_addr = string_to_bdaddr(buf, &bd_addr);
+  RawAddress bd_addr;
+  bool valid_bd_addr = RawAddress::FromString(buf, bd_addr);
   uint16_t data_psm = get_hex(&p, 0);  // arg1
   uint16_t mdl_id = get_int(&p, 0);    // arg2
   printf("%s: data_psm=0x%04x, mdl_id=%d\n", __func__, data_psm, mdl_id);
@@ -853,8 +849,8 @@
 }
 
 static void do_pairing(char* p) {
-  bt_bdaddr_t bd_addr;
-  if (!string_to_bdaddr(p, &bd_addr)) {
+  RawAddress bd_addr;
+  if (!RawAddress::FromString(p, bd_addr)) {
     LOG(ERROR) << "Invalid Bluetooth address " << p;
     return;
   }
diff --git a/types/Android.bp b/types/Android.bp
new file mode 100644
index 0000000..cd7d96b
--- /dev/null
+++ b/types/Android.bp
@@ -0,0 +1,26 @@
+// Bluetooth types
+cc_library_static {
+    name: "libbluetooth-types",
+    vendor_available: true,
+    defaults: ["fluoride_types_defaults"],
+    cflags: [
+        /* we export all classes, so change default visibility, instead of having EXPORT_SYMBOL on each class*/
+        "-fvisibility=default",
+    ],
+    host_supported: true,
+    srcs: [
+        "raw_address.cc",
+    ],
+    export_include_dirs: ["./"],
+}
+
+// ========================================================
+cc_test {
+    name: "net_test_types",
+    test_suites: ["device-tests"],
+    defaults: ["fluoride_defaults"],
+    host_supported: true,
+    srcs: [
+        "test/raw_address_unittest.cc",
+    ],
+}
diff --git a/types/BUILD.gn b/types/BUILD.gn
new file mode 100644
index 0000000..6b18806
--- /dev/null
+++ b/types/BUILD.gn
@@ -0,0 +1,59 @@
+#
+#  Copyright (C) 2017 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.
+#
+
+static_library("types") {
+  cflags = [
+     "-fvisibility=default",
+  ]
+
+  sources = [
+    "raw_address.cc",
+  ]
+
+  include_dirs = [
+    "//",
+  ]
+
+  deps = [
+    "//third_party/libchrome:base",
+  ]
+}
+
+executable("types_unittests") {
+  testonly = true
+  sources = [
+    "test/raw_address_unittest.cc",
+  ]
+
+  include_dirs = [
+    "//",
+  ]
+
+  libs = [
+     "-ldl",
+     "-lpthread",
+     "-lresolv",
+     "-lrt",
+     "-lz",
+     "-latomic",
+  ]
+
+  deps = [
+    "//types",
+    "//third_party/googletest:gmock_main",
+    "//third_party/libchrome:base",
+  ]
+}
diff --git a/types/raw_address.cc b/types/raw_address.cc
new file mode 100644
index 0000000..22c1081
--- /dev/null
+++ b/types/raw_address.cc
@@ -0,0 +1,68 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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 "raw_address.h"
+
+#include <base/strings/string_split.h>
+#include <base/strings/stringprintf.h>
+#include <stdint.h>
+#include <algorithm>
+#include <vector>
+
+static_assert(sizeof(RawAddress) == 6, "RawAddress must be 6 bytes long!");
+
+const RawAddress RawAddress::kAny{{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
+const RawAddress RawAddress::kEmpty{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
+RawAddress::RawAddress(const uint8_t (&addr)[6]) {
+  std::copy(addr, addr + kLength, address);
+};
+
+std::string RawAddress::ToString() const {
+  return base::StringPrintf("%02x:%02x:%02x:%02x:%02x:%02x", address[0],
+                            address[1], address[2], address[3], address[4],
+                            address[5]);
+}
+
+bool RawAddress::FromString(const std::string& from, RawAddress& to) {
+  RawAddress new_addr;
+  if (from.length() != 17) return false;
+
+  std::vector<std::string> byte_tokens =
+      base::SplitString(from, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+
+  if (byte_tokens.size() != 6) return false;
+
+  for (int i = 0; i < 6; i++) {
+    const auto& token = byte_tokens[i];
+
+    if (token.length() != 2) return false;
+
+    char* temp = nullptr;
+    new_addr.address[i] = strtol(token.c_str(), &temp, 16);
+    if (*temp != '\0') return false;
+  }
+
+  to = new_addr;
+  return true;
+}
+
+bool RawAddress::IsValidAddress(const std::string& address) {
+  RawAddress tmp;
+  return RawAddress::FromString(address, tmp);
+}
diff --git a/types/raw_address.h b/types/raw_address.h
new file mode 100644
index 0000000..0b42c04
--- /dev/null
+++ b/types/raw_address.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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
+
+#include <string>
+
+/** Bluetooth Address */
+class RawAddress final {
+ public:
+  static constexpr unsigned int kLength = 6;
+
+  uint8_t address[kLength];
+
+  RawAddress() = default;
+  RawAddress(const uint8_t (&addr)[6]);
+
+  bool operator<(const RawAddress& rhs) const {
+    return (std::memcmp(address, rhs.address, sizeof(address)) < 0);
+  }
+  bool operator==(const RawAddress& rhs) const {
+    return (std::memcmp(address, rhs.address, sizeof(address)) == 0);
+  }
+  bool operator>(const RawAddress& rhs) const { return (rhs < *this); }
+  bool operator<=(const RawAddress& rhs) const { return !(*this > rhs); }
+  bool operator>=(const RawAddress& rhs) const { return !(*this < rhs); }
+  bool operator!=(const RawAddress& rhs) const { return !(*this == rhs); }
+
+  bool IsEmpty() const { return *this == kEmpty; }
+
+  std::string ToString() const;
+
+  // Converts |string| to RawAddress and places it in |to|. If |from| does
+  // not represent a Bluetooth address, |to| is not modified and this function
+  // returns false. Otherwise, it returns true.
+  static bool FromString(const std::string& from, RawAddress& to);
+
+  static bool IsValidAddress(const std::string& address);
+
+  static const RawAddress kEmpty;  // 00:00:00:00:00:00
+  static const RawAddress kAny;    // FF:FF:FF:FF:FF:FF
+};
+
+inline std::ostream& operator<<(std::ostream& os, const RawAddress& a) {
+  os << a.ToString();
+  return os;
+}
diff --git a/types/test/raw_address_unittest.cc b/types/test/raw_address_unittest.cc
new file mode 100644
index 0000000..dcfab85
--- /dev/null
+++ b/types/test/raw_address_unittest.cc
@@ -0,0 +1,155 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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 <gtest/gtest.h>
+
+#include "raw_address.h"
+
+static const char* test_addr = "12:34:56:78:9a:bc";
+static const char* test_addr2 = "cb:a9:87:65:43:21";
+
+TEST(RawAddressUnittest, test_is_empty) {
+  RawAddress empty;
+  RawAddress::FromString("00:00:00:00:00:00", empty);
+  ASSERT_TRUE(empty.IsEmpty());
+
+  RawAddress not_empty;
+  RawAddress::FromString("00:00:00:00:00:01", not_empty);
+  ASSERT_FALSE(not_empty.IsEmpty());
+}
+
+TEST(RawAddressUnittest, test_to_from_str) {
+  RawAddress bdaddr;
+  RawAddress::FromString(test_addr, bdaddr);
+
+  ASSERT_EQ(0x12, bdaddr.address[0]);
+  ASSERT_EQ(0x34, bdaddr.address[1]);
+  ASSERT_EQ(0x56, bdaddr.address[2]);
+  ASSERT_EQ(0x78, bdaddr.address[3]);
+  ASSERT_EQ(0x9A, bdaddr.address[4]);
+  ASSERT_EQ(0xBC, bdaddr.address[5]);
+
+  std::string ret = bdaddr.ToString();
+
+  ASSERT_STREQ(test_addr, ret.c_str());
+}
+
+TEST(RawAddressTest, test_equals) {
+  RawAddress bdaddr1;
+  RawAddress bdaddr2;
+  RawAddress bdaddr3;
+  RawAddress::FromString(test_addr, bdaddr1);
+  RawAddress::FromString(test_addr, bdaddr2);
+  EXPECT_TRUE(bdaddr1 == bdaddr2);
+  EXPECT_FALSE(bdaddr1 != bdaddr2);
+  EXPECT_TRUE(bdaddr1 == bdaddr1);
+  EXPECT_FALSE(bdaddr1 != bdaddr1);
+
+  RawAddress::FromString(test_addr2, bdaddr3);
+  EXPECT_FALSE(bdaddr2 == bdaddr3);
+  EXPECT_TRUE(bdaddr2 != bdaddr3);
+}
+
+TEST(RawAddressTest, test_less_than) {
+  RawAddress bdaddr1;
+  RawAddress bdaddr2;
+  RawAddress bdaddr3;
+  RawAddress::FromString(test_addr, bdaddr1);
+  RawAddress::FromString(test_addr, bdaddr2);
+  EXPECT_FALSE(bdaddr1 < bdaddr2);
+  EXPECT_FALSE(bdaddr1 < bdaddr1);
+
+  RawAddress::FromString(test_addr2, bdaddr3);
+  EXPECT_TRUE(bdaddr2 < bdaddr3);
+  EXPECT_FALSE(bdaddr3 < bdaddr2);
+}
+
+TEST(RawAddressTest, test_more_than) {
+  RawAddress bdaddr1;
+  RawAddress bdaddr2;
+  RawAddress bdaddr3;
+  RawAddress::FromString(test_addr, bdaddr1);
+  RawAddress::FromString(test_addr, bdaddr2);
+  EXPECT_FALSE(bdaddr1 > bdaddr2);
+  EXPECT_FALSE(bdaddr1 > bdaddr1);
+
+  RawAddress::FromString(test_addr2, bdaddr3);
+  EXPECT_FALSE(bdaddr2 > bdaddr3);
+  EXPECT_TRUE(bdaddr3 > bdaddr2);
+}
+
+TEST(RawAddressTest, test_less_than_or_equal) {
+  RawAddress bdaddr1;
+  RawAddress bdaddr2;
+  RawAddress bdaddr3;
+  RawAddress::FromString(test_addr, bdaddr1);
+  RawAddress::FromString(test_addr, bdaddr2);
+  EXPECT_TRUE(bdaddr1 <= bdaddr2);
+  EXPECT_TRUE(bdaddr1 <= bdaddr1);
+
+  RawAddress::FromString(test_addr2, bdaddr3);
+  EXPECT_TRUE(bdaddr2 <= bdaddr3);
+  EXPECT_FALSE(bdaddr3 <= bdaddr2);
+}
+
+TEST(RawAddressTest, test_more_than_or_equal) {
+  RawAddress bdaddr1;
+  RawAddress bdaddr2;
+  RawAddress bdaddr3;
+  RawAddress::FromString(test_addr, bdaddr1);
+  RawAddress::FromString(test_addr, bdaddr2);
+  EXPECT_TRUE(bdaddr1 >= bdaddr2);
+  EXPECT_TRUE(bdaddr1 >= bdaddr1);
+
+  RawAddress::FromString(test_addr2, bdaddr3);
+  EXPECT_FALSE(bdaddr2 >= bdaddr3);
+  EXPECT_TRUE(bdaddr3 >= bdaddr2);
+}
+
+TEST(RawAddressTest, test_copy) {
+  RawAddress bdaddr1;
+  RawAddress bdaddr2;
+  RawAddress::FromString(test_addr, bdaddr1);
+  bdaddr2 = bdaddr1;
+
+  EXPECT_TRUE(bdaddr1 == bdaddr2);
+}
+
+TEST(RawAddressTest, IsValidAddress) {
+  EXPECT_FALSE(RawAddress::IsValidAddress(""));
+  EXPECT_FALSE(RawAddress::IsValidAddress("000000000000"));
+  EXPECT_FALSE(RawAddress::IsValidAddress("00:00:00:00:0000"));
+  EXPECT_FALSE(RawAddress::IsValidAddress("00:00:00:00:00:0"));
+  EXPECT_FALSE(RawAddress::IsValidAddress("00:00:00:00:00:0;"));
+  EXPECT_TRUE(RawAddress::IsValidAddress("00:00:00:00:00:00"));
+  EXPECT_TRUE(RawAddress::IsValidAddress("AB:cd:00:00:00:00"));
+  EXPECT_FALSE(RawAddress::IsValidAddress("aB:cD:eF:Gh:iJ:Kl"));
+}
+
+TEST(RawAddressTest, BdAddrFromString) {
+  RawAddress addr;
+  memset(&addr, 0, sizeof(addr));
+
+  EXPECT_TRUE(RawAddress::FromString("00:00:00:00:00:00", addr));
+  const RawAddress result0 = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+  EXPECT_EQ(0, memcmp(&addr, &result0, sizeof(addr)));
+
+  EXPECT_TRUE(RawAddress::FromString("ab:01:4C:d5:21:9f", addr));
+  const RawAddress result1 = {{0xab, 0x01, 0x4c, 0xd5, 0x21, 0x9f}};
+  EXPECT_EQ(0, memcmp(&addr, &result1, sizeof(addr)));
+}
diff --git a/udrv/ulinux/uipc.cc b/udrv/ulinux/uipc.cc
index a524a36..4f7d126 100644
--- a/udrv/ulinux/uipc.cc
+++ b/udrv/ulinux/uipc.cc
@@ -293,7 +293,7 @@
     }
 
     if (uipc_main.ch[ch_id].fd < 0) {
-      BTIF_TRACE_ERROR("FAILED TO ACCEPT CH %d (%s)", ch_id, strerror(errno));
+      BTIF_TRACE_ERROR("FAILED TO ACCEPT CH %d", ch_id);
       return -1;
     }
 
diff --git a/vendor_libs/Android.bp b/vendor_libs/Android.bp
index 07dde0f..a509209 100644
--- a/vendor_libs/Android.bp
+++ b/vendor_libs/Android.bp
@@ -1,3 +1,4 @@
 subdirs = [
     "test_vendor_lib",
+    "linux",
 ]
diff --git a/vendor_libs/linux/Android.bp b/vendor_libs/linux/Android.bp
new file mode 100644
index 0000000..058140e
--- /dev/null
+++ b/vendor_libs/linux/Android.bp
@@ -0,0 +1,3 @@
+subdirs = [
+    "interface",
+]
diff --git a/vendor_libs/linux/Android.mk b/vendor_libs/linux/Android.mk
deleted file mode 100644
index 30a7389..0000000
--- a/vendor_libs/linux/Android.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-#  Copyright (C) 2015 Intel Corporation
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at:
-#
-#  http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-ifeq ($(BOARD_HAVE_BLUETOOTH_LINUX), true)
-
-# libbt-vendor shared library for target
-# ========================================================
-include $(CLEAR_VARS)
-
-LOCAL_CPP_EXTENSION := .cc
-
-LOCAL_SRC_FILES := \
-        bt_vendor_linux.cc
-
-LOCAL_C_INCLUDES := \
-        $(LOCAL_PATH)/../../
-
-LOCAL_SHARED_LIBRARIES := \
-        liblog \
-        libcutils
-
-LOCAL_STATIC_LIBRARIES := libosi
-
-LOCAL_MODULE := libbt-vendor
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_CFLAGS += $(test-vendor_CFLAGS)
-LOCAL_CONLYFLAGS += $(test-vendor_CONLYFLAGS)
-
-include $(BUILD_SHARED_LIBRARY)
-
-endif  # BOARD_HAVE_BLUETOOTH_LINUX
diff --git a/vendor_libs/linux/bt_vendor_linux.cc b/vendor_libs/linux/bt_vendor_linux.cc
deleted file mode 100644
index 5270eab..0000000
--- a/vendor_libs/linux/bt_vendor_linux.cc
+++ /dev/null
@@ -1,411 +0,0 @@
-/**********************************************************************
- *
- *  Copyright (C) 2015 Intel Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- *  implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- **********************************************************************/
-
-#define LOG_TAG "bt_vendor"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-
-#include "hci/include/bt_vendor_lib.h"
-#include "osi/include/compat.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h"
-#include "osi/include/properties.h"
-
-#define BTPROTO_HCI 1
-#define HCI_CHANNEL_USER 1
-#define HCI_CHANNEL_CONTROL 3
-#define HCI_DEV_NONE 0xffff
-
-#define RFKILL_TYPE_BLUETOOTH 2
-#define RFKILL_OP_CHANGE_ALL 3
-
-#define MGMT_OP_INDEX_LIST 0x0003
-#define MGMT_EV_INDEX_ADDED 0x0004
-#define MGMT_EV_COMMAND_COMP 0x0001
-#define MGMT_EV_SIZE_MAX 1024
-#define MGMT_EV_POLL_TIMEOUT 3000 /* 3000ms */
-
-#define IOCTL_HCIDEVDOWN _IOW('H', 202, int)
-
-struct sockaddr_hci {
-  sa_family_t hci_family;
-  unsigned short hci_dev;
-  unsigned short hci_channel;
-};
-
-struct rfkill_event {
-  uint32_t idx;
-  uint8_t type;
-  uint8_t op;
-  uint8_t soft, hard;
-} __attribute__((packed));
-
-struct mgmt_pkt {
-  uint16_t opcode;
-  uint16_t index;
-  uint16_t len;
-  uint8_t data[MGMT_EV_SIZE_MAX];
-} __attribute__((packed));
-
-struct mgmt_event_read_index {
-  uint16_t cc_opcode;
-  uint8_t status;
-  uint16_t num_intf;
-  uint16_t index[0];
-} __attribute__((packed));
-
-static const bt_vendor_callbacks_t* bt_vendor_callbacks;
-static unsigned char bt_vendor_local_bdaddr[6];
-static int bt_vendor_fd = -1;
-static int hci_interface;
-static int rfkill_en;
-static int bt_hwcfg_en;
-
-static int bt_vendor_init(const bt_vendor_callbacks_t* p_cb,
-                          unsigned char* local_bdaddr) {
-  char prop_value[PROPERTY_VALUE_MAX];
-
-  LOG_INFO(LOG_TAG, "%s", __func__);
-
-  if (p_cb == NULL) {
-    LOG_ERROR(LOG_TAG, "init failed with no user callbacks!");
-    return -1;
-  }
-
-  bt_vendor_callbacks = p_cb;
-
-  memcpy(bt_vendor_local_bdaddr, local_bdaddr, sizeof(bt_vendor_local_bdaddr));
-
-  osi_property_get("bluetooth.interface", prop_value, "0");
-
-  errno = 0;
-  if (memcmp(prop_value, "hci", 3))
-    hci_interface = strtol(prop_value, NULL, 10);
-  else
-    hci_interface = strtol(prop_value + 3, NULL, 10);
-  if (errno) hci_interface = 0;
-
-  LOG_INFO(LOG_TAG, "Using interface hci%d", hci_interface);
-
-  osi_property_get("bluetooth.rfkill", prop_value, "0");
-
-  rfkill_en = atoi(prop_value);
-  if (rfkill_en) LOG_INFO(LOG_TAG, "RFKILL enabled");
-
-  bt_hwcfg_en =
-      osi_property_get("bluetooth.hwcfg", prop_value, NULL) > 0 ? 1 : 0;
-  if (bt_hwcfg_en) LOG_INFO(LOG_TAG, "HWCFG enabled");
-
-  return 0;
-}
-
-static int bt_vendor_hw_cfg(int stop) {
-  if (!bt_hwcfg_en) return 0;
-
-  if (stop) {
-    if (osi_property_set("bluetooth.hwcfg", "stop") < 0) {
-      LOG_ERROR(LOG_TAG, "%s cannot stop btcfg service via prop", __func__);
-      return 1;
-    }
-  } else {
-    if (osi_property_set("bluetooth.hwcfg", "start") < 0) {
-      LOG_ERROR(LOG_TAG, "%s cannot start btcfg service via prop", __func__);
-      return 1;
-    }
-  }
-  return 0;
-}
-
-static int bt_vendor_wait_hcidev(void) {
-  struct sockaddr_hci addr;
-  struct pollfd fds[1];
-  struct mgmt_pkt ev;
-  int fd;
-  int ret = 0;
-
-  LOG_INFO(LOG_TAG, "%s", __func__);
-
-  fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
-  if (fd < 0) {
-    LOG_ERROR(LOG_TAG, "Bluetooth socket error: %s", strerror(errno));
-    return -1;
-  }
-
-  memset(&addr, 0, sizeof(addr));
-  addr.hci_family = AF_BLUETOOTH;
-  addr.hci_dev = HCI_DEV_NONE;
-  addr.hci_channel = HCI_CHANNEL_CONTROL;
-
-  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
-    LOG_ERROR(LOG_TAG, "HCI Channel Control: %s", strerror(errno));
-    close(fd);
-    return -1;
-  }
-
-  fds[0].fd = fd;
-  fds[0].events = POLLIN;
-
-  /* Read Controller Index List Command */
-  ev.opcode = MGMT_OP_INDEX_LIST;
-  ev.index = HCI_DEV_NONE;
-  ev.len = 0;
-
-  ssize_t wrote;
-  OSI_NO_INTR(wrote = write(fd, &ev, 6));
-  if (wrote != 6) {
-    LOG_ERROR(LOG_TAG, "Unable to write mgmt command: %s", strerror(errno));
-    ret = -1;
-    goto end;
-  }
-
-  while (1) {
-    int n;
-    OSI_NO_INTR(n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT));
-    if (n == -1) {
-      LOG_ERROR(LOG_TAG, "Poll error: %s", strerror(errno));
-      ret = -1;
-      break;
-    } else if (n == 0) {
-      LOG_ERROR(LOG_TAG, "Timeout, no HCI device detected");
-      ret = -1;
-      break;
-    }
-
-    if (fds[0].revents & POLLIN) {
-      OSI_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
-      if (n < 0) {
-        LOG_ERROR(LOG_TAG, "Error reading control channel: %s",
-                  strerror(errno));
-        ret = -1;
-        break;
-      }
-
-      if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
-        goto end;
-      } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
-        struct mgmt_event_read_index* cc;
-        int i;
-
-        cc = (struct mgmt_event_read_index*)ev.data;
-
-        if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue;
-
-        for (i = 0; i < cc->num_intf; i++) {
-          if (cc->index[i] == hci_interface) goto end;
-        }
-      }
-    }
-  }
-
-end:
-  close(fd);
-  return ret;
-}
-
-static int bt_vendor_open(void* param) {
-  int(*fd_array)[] = (int(*)[])param;
-  int fd;
-
-  LOG_INFO(LOG_TAG, "%s", __func__);
-
-  fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
-  if (fd < 0) {
-    LOG_ERROR(LOG_TAG, "socket create error %s", strerror(errno));
-    return -1;
-  }
-
-  (*fd_array)[CH_CMD] = fd;
-  (*fd_array)[CH_EVT] = fd;
-  (*fd_array)[CH_ACL_OUT] = fd;
-  (*fd_array)[CH_ACL_IN] = fd;
-
-  bt_vendor_fd = fd;
-
-  LOG_INFO(LOG_TAG, "%s returning %d", __func__, bt_vendor_fd);
-
-  return 1;
-}
-
-static int bt_vendor_close(void* param) {
-  (void)(param);
-
-  LOG_INFO(LOG_TAG, "%s", __func__);
-
-  if (bt_vendor_fd != -1) {
-    close(bt_vendor_fd);
-    bt_vendor_fd = -1;
-  }
-
-  return 0;
-}
-
-static int bt_vendor_rfkill(int block) {
-  struct rfkill_event event;
-  int fd;
-
-  LOG_INFO(LOG_TAG, "%s", __func__);
-
-  fd = open("/dev/rfkill", O_WRONLY);
-  if (fd < 0) {
-    LOG_ERROR(LOG_TAG, "Unable to open /dev/rfkill");
-    return -1;
-  }
-
-  memset(&event, 0, sizeof(struct rfkill_event));
-  event.op = RFKILL_OP_CHANGE_ALL;
-  event.type = RFKILL_TYPE_BLUETOOTH;
-  event.hard = block;
-  event.soft = block;
-
-  ssize_t len;
-  OSI_NO_INTR(len = write(fd, &event, sizeof(event)));
-  if (len < 0) {
-    LOG_ERROR(LOG_TAG, "Failed to change rfkill state");
-    close(fd);
-    return 1;
-  }
-
-  close(fd);
-  return 0;
-}
-
-/* TODO: fw config should thread the device waiting and return immedialty */
-static void bt_vendor_fw_cfg(void) {
-  struct sockaddr_hci addr;
-  int fd = bt_vendor_fd;
-
-  LOG_INFO(LOG_TAG, "%s", __func__);
-
-  if (fd == -1) {
-    LOG_ERROR(LOG_TAG, "bt_vendor_fd: %s", strerror(EBADF));
-    goto failure;
-  }
-
-  memset(&addr, 0, sizeof(addr));
-  addr.hci_family = AF_BLUETOOTH;
-  addr.hci_dev = hci_interface;
-  addr.hci_channel = HCI_CHANNEL_USER;
-
-  if (bt_vendor_wait_hcidev()) {
-    LOG_ERROR(LOG_TAG, "HCI interface (%d) not found", hci_interface);
-    goto failure;
-  }
-
-  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
-    LOG_ERROR(LOG_TAG, "socket bind error %s", strerror(errno));
-    goto failure;
-  }
-
-  LOG_INFO(LOG_TAG, "HCI device ready");
-
-  bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
-
-  return;
-
-failure:
-  LOG_ERROR(LOG_TAG, "Hardware Config Error");
-  bt_vendor_callbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
-}
-
-static int bt_vendor_op(bt_vendor_opcode_t opcode, void* param) {
-  int retval = 0;
-
-  LOG_INFO(LOG_TAG, "%s op %d", __func__, opcode);
-
-  switch (opcode) {
-    case BT_VND_OP_POWER_CTRL:
-      if (!rfkill_en || !param) break;
-
-      if (*((int*)param) == BT_VND_PWR_ON) {
-        retval = bt_vendor_rfkill(0);
-        if (!retval) retval = bt_vendor_hw_cfg(0);
-      } else {
-        retval = bt_vendor_hw_cfg(1);
-        if (!retval) retval = bt_vendor_rfkill(1);
-      }
-
-      break;
-
-    case BT_VND_OP_FW_CFG:
-      bt_vendor_fw_cfg();
-      break;
-
-    case BT_VND_OP_SCO_CFG:
-      bt_vendor_callbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
-      break;
-
-    case BT_VND_OP_USERIAL_OPEN:
-      retval = bt_vendor_open(param);
-      break;
-
-    case BT_VND_OP_USERIAL_CLOSE:
-      retval = bt_vendor_close(param);
-      break;
-
-    case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
-      *((uint32_t*)param) = 3000;
-      retval = 0;
-      break;
-
-    case BT_VND_OP_LPM_SET_MODE:
-      bt_vendor_callbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
-      break;
-
-    case BT_VND_OP_LPM_WAKE_SET_STATE:
-      break;
-
-    case BT_VND_OP_SET_AUDIO_STATE:
-      bt_vendor_callbacks->audio_state_cb(BT_VND_OP_RESULT_SUCCESS);
-      break;
-
-    case BT_VND_OP_EPILOG:
-      bt_vendor_callbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
-      break;
-
-    case BT_VND_OP_A2DP_OFFLOAD_START:
-      break;
-
-    case BT_VND_OP_A2DP_OFFLOAD_STOP:
-      break;
-  }
-
-  LOG_INFO(LOG_TAG, "%s op %d retval %d", __func__, opcode, retval);
-
-  return retval;
-}
-
-static void bt_vendor_cleanup(void) {
-  LOG_INFO(LOG_TAG, "%s", __func__);
-
-  bt_vendor_callbacks = NULL;
-}
-
-EXPORT_SYMBOL const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
-    sizeof(bt_vendor_interface_t), bt_vendor_init, bt_vendor_op,
-    bt_vendor_cleanup,
-};
diff --git a/vendor_libs/linux/interface/Android.bp b/vendor_libs/linux/interface/Android.bp
new file mode 100644
index 0000000..56baf9e
--- /dev/null
+++ b/vendor_libs/linux/interface/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2017 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.
+
+cc_binary {
+    name: "android.hardware.bluetooth@1.0-service.btlinux",
+    proprietary: true,
+    relative_install_path: "hw",
+    srcs: [
+        "hci_packetizer.cc",
+        "h4_protocol.cc",
+        "bluetooth_hci.cc",
+        "async_fd_watcher.cc",
+        "service.cc"
+    ],
+    shared_libs: [
+        "android.hardware.bluetooth@1.0",
+        "libbase",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    conlyflags: [
+        "-std=c99",
+    ],
+    init_rc: ["android.hardware.bluetooth@1.0-service.btlinux.rc"],
+}
+
diff --git a/vendor_libs/linux/interface/android.hardware.bluetooth@1.0-service.btlinux.rc b/vendor_libs/linux/interface/android.hardware.bluetooth@1.0-service.btlinux.rc
new file mode 100644
index 0000000..36fbc2c
--- /dev/null
+++ b/vendor_libs/linux/interface/android.hardware.bluetooth@1.0-service.btlinux.rc
@@ -0,0 +1,5 @@
+service btlinux-1.0 /vendor/bin/hw/android.hardware.bluetooth@1.0-service.btlinux
+    class hal
+    user bluetooth
+    group bluetooth net_admin net_bt_admin
+    capabilities NET_ADMIN
diff --git a/vendor_libs/linux/interface/async_fd_watcher.cc b/vendor_libs/linux/interface/async_fd_watcher.cc
new file mode 100644
index 0000000..ef4a959
--- /dev/null
+++ b/vendor_libs/linux/interface/async_fd_watcher.cc
@@ -0,0 +1,188 @@
+//
+// Copyright 2016 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 "async_fd_watcher.h"
+
+#include <algorithm>
+#include <atomic>
+#include <condition_variable>
+#include <log/log.h>
+#include <map>
+#include <mutex>
+#include <thread>
+#include <vector>
+#include "fcntl.h"
+#include "sys/select.h"
+#include "unistd.h"
+
+static const int INVALID_FD = -1;
+static const int BT_RT_PRIORITY = 1;
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace async {
+
+int AsyncFdWatcher::WatchFdForNonBlockingReads(
+    int file_descriptor, const ReadCallback& on_read_fd_ready_callback) {
+  // Add file descriptor and callback
+  {
+    std::unique_lock<std::mutex> guard(internal_mutex_);
+    watched_fds_[file_descriptor] = on_read_fd_ready_callback;
+  }
+
+  // Start the thread if not started yet
+  return tryStartThread();
+}
+
+int AsyncFdWatcher::ConfigureTimeout(
+    const std::chrono::milliseconds timeout,
+    const TimeoutCallback& on_timeout_callback) {
+  // Add timeout and callback
+  {
+    std::unique_lock<std::mutex> guard(timeout_mutex_);
+    timeout_cb_ = on_timeout_callback;
+    timeout_ms_ = timeout;
+  }
+
+  notifyThread();
+  return 0;
+}
+
+void AsyncFdWatcher::StopWatchingFileDescriptors() { stopThread(); }
+
+AsyncFdWatcher::~AsyncFdWatcher() {}
+
+// Make sure to call this with at least one file descriptor ready to be
+// watched upon or the thread routine will return immediately
+int AsyncFdWatcher::tryStartThread() {
+  if (std::atomic_exchange(&running_, true)) return 0;
+
+  // Set up the communication channel
+  int pipe_fds[2];
+  if (pipe2(pipe_fds, O_NONBLOCK)) return -1;
+
+  notification_listen_fd_ = pipe_fds[0];
+  notification_write_fd_ = pipe_fds[1];
+
+  thread_ = std::thread([this]() { ThreadRoutine(); });
+  if (!thread_.joinable()) return -1;
+
+  return 0;
+}
+
+int AsyncFdWatcher::stopThread() {
+  if (!std::atomic_exchange(&running_, false)) return 0;
+
+  notifyThread();
+  if (std::this_thread::get_id() != thread_.get_id()) {
+    thread_.join();
+  }
+
+  {
+    std::unique_lock<std::mutex> guard(internal_mutex_);
+    watched_fds_.clear();
+  }
+
+  {
+    std::unique_lock<std::mutex> guard(timeout_mutex_);
+    timeout_cb_ = nullptr;
+  }
+
+  return 0;
+}
+
+int AsyncFdWatcher::notifyThread() {
+  uint8_t buffer[] = {0};
+  if (TEMP_FAILURE_RETRY(write(notification_write_fd_, &buffer, 1)) < 0) {
+    return -1;
+  }
+  return 0;
+}
+
+void AsyncFdWatcher::ThreadRoutine() {
+
+  // Make watching thread RT.
+  struct sched_param rt_params;
+  rt_params.sched_priority = BT_RT_PRIORITY;
+  if (sched_setscheduler(gettid(), SCHED_FIFO, &rt_params)) {
+    ALOGE("%s unable to set SCHED_FIFO for pid %d, tid %d, error %s", __func__,
+          getpid(), gettid(), strerror(errno));
+  }
+
+  while (running_) {
+    fd_set read_fds;
+    FD_ZERO(&read_fds);
+    FD_SET(notification_listen_fd_, &read_fds);
+    int max_read_fd = INVALID_FD;
+    for (auto& it : watched_fds_) {
+      FD_SET(it.first, &read_fds);
+      max_read_fd = std::max(max_read_fd, it.first);
+    }
+
+    struct timeval timeout;
+    struct timeval* timeout_ptr = NULL;
+    if (timeout_ms_ > std::chrono::milliseconds(0)) {
+      timeout.tv_sec = timeout_ms_.count() / 1000;
+      timeout.tv_usec = (timeout_ms_.count() % 1000) * 1000;
+      timeout_ptr = &timeout;
+    }
+
+    // Wait until there is data available to read on some FD.
+    int nfds = std::max(notification_listen_fd_, max_read_fd);
+    int retval = select(nfds + 1, &read_fds, NULL, NULL, timeout_ptr);
+
+    // There was some error.
+    if (retval < 0) continue;
+
+    // Timeout.
+    if (retval == 0) {
+      // Allow the timeout callback to modify the timeout.
+      TimeoutCallback saved_cb;
+      {
+        std::unique_lock<std::mutex> guard(timeout_mutex_);
+        if (timeout_ms_ > std::chrono::milliseconds(0))
+          saved_cb = timeout_cb_;
+      }
+      if (saved_cb != nullptr)
+        saved_cb();
+      continue;
+    }
+
+    // Read data from the notification FD.
+    if (FD_ISSET(notification_listen_fd_, &read_fds)) {
+      char buffer[] = {0};
+      TEMP_FAILURE_RETRY(read(notification_listen_fd_, buffer, 1));
+      continue;
+    }
+
+    // Invoke the data ready callbacks if appropriate.
+    {
+      // Hold the mutex to make sure that the callbacks are still valid.
+      std::unique_lock<std::mutex> guard(internal_mutex_);
+      for (auto& it : watched_fds_) {
+        if (FD_ISSET(it.first, &read_fds)) {
+        it.second(it.first);
+        }
+      }
+    }
+  }
+}
+
+} // namespace async
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/vendor_libs/linux/interface/async_fd_watcher.h b/vendor_libs/linux/interface/async_fd_watcher.h
new file mode 100644
index 0000000..358cbc3
--- /dev/null
+++ b/vendor_libs/linux/interface/async_fd_watcher.h
@@ -0,0 +1,67 @@
+//
+// Copyright 2016 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
+
+#include <map>
+#include <mutex>
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace async {
+
+using ReadCallback = std::function<void(int)>;
+using TimeoutCallback = std::function<void(void)>;
+
+class AsyncFdWatcher {
+ public:
+  AsyncFdWatcher() = default;
+  ~AsyncFdWatcher();
+
+  int WatchFdForNonBlockingReads(int file_descriptor,
+                                 const ReadCallback& on_read_fd_ready_callback);
+  int ConfigureTimeout(const std::chrono::milliseconds timeout,
+                       const TimeoutCallback& on_timeout_callback);
+  void StopWatchingFileDescriptors();
+
+ private:
+  AsyncFdWatcher(const AsyncFdWatcher&) = delete;
+  AsyncFdWatcher& operator=(const AsyncFdWatcher&) = delete;
+
+  int tryStartThread();
+  int stopThread();
+  int notifyThread();
+  void ThreadRoutine();
+
+  std::atomic_bool running_{false};
+  std::thread thread_;
+  std::mutex internal_mutex_;
+  std::mutex timeout_mutex_;
+
+  std::map<int, ReadCallback> watched_fds_;
+  int notification_listen_fd_;
+  int notification_write_fd_;
+  TimeoutCallback timeout_cb_;
+  std::chrono::milliseconds timeout_ms_;
+};
+
+
+} // namespace async
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/vendor_libs/linux/interface/bluetooth_hci.cc b/vendor_libs/linux/interface/bluetooth_hci.cc
new file mode 100644
index 0000000..8507f7a
--- /dev/null
+++ b/vendor_libs/linux/interface/bluetooth_hci.cc
@@ -0,0 +1,344 @@
+//
+// Copyright 2016 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.
+//
+
+#define LOG_TAG "android.hardware.bluetooth@1.0-btlinux"
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/socket.h>
+
+#include <utils/Log.h>
+
+#include "bluetooth_hci.h"
+
+#define BTPROTO_HCI 1
+
+#define HCI_CHANNEL_USER 1
+#define HCI_CHANNEL_CONTROL 3
+#define HCI_DEV_NONE 0xffff
+
+/* reference from <kernel>/include/net/bluetooth/mgmt.h */
+#define MGMT_OP_INDEX_LIST 0x0003
+#define MGMT_EV_INDEX_ADDED 0x0004
+#define MGMT_EV_COMMAND_COMP 0x0001
+#define MGMT_EV_SIZE_MAX 1024
+#define MGMT_EV_POLL_TIMEOUT 3000 /* 3000ms */
+#define WRITE_NO_INTR(fn) \
+  do {                  \
+  } while ((fn) == -1 && errno == EINTR)
+
+struct sockaddr_hci {
+    sa_family_t hci_family;
+    unsigned short hci_dev;
+    unsigned short hci_channel;
+};
+
+struct mgmt_pkt {
+    uint16_t opcode;
+    uint16_t index;
+    uint16_t len;
+    uint8_t data[MGMT_EV_SIZE_MAX];
+} __attribute__((packed));
+
+struct mgmt_event_read_index {
+    uint16_t cc_opcode;
+    uint8_t status;
+    uint16_t num_intf;
+    uint16_t index[0];
+  } __attribute__((packed));
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace btlinux {
+
+int BluetoothHci::openBtHci() {
+
+  ALOGI( "%s", __func__);
+
+  int hci_interface = 0;
+  rfkill_state_ = NULL;
+  rfKill(1);
+
+  int fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+  if (fd < 0) {
+    ALOGE( "Bluetooth socket error: %s", strerror(errno));
+    return -1;
+  }
+  bt_soc_fd_ = fd;
+
+  if (waitHciDev(hci_interface)) {
+    ALOGE( "HCI interface (%d) not found", hci_interface);
+    ::close(fd);
+    return -1;
+  }
+  struct sockaddr_hci addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.hci_family = AF_BLUETOOTH;
+  addr.hci_dev = hci_interface;
+  addr.hci_channel = HCI_CHANNEL_USER;
+  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+    ALOGE( "HCI Channel Control: %s", strerror(errno));
+    ::close(fd);
+    return -1;
+  }
+  ALOGI( "HCI device ready");
+  return fd;
+}
+
+void BluetoothHci::closeBtHci() {
+  if (bt_soc_fd_ != -1) {
+    ::close(bt_soc_fd_);
+    bt_soc_fd_ = -1;
+  }
+  rfKill(0);
+  free(rfkill_state_);
+}
+
+int BluetoothHci::waitHciDev(int hci_interface) {
+  struct sockaddr_hci addr;
+  struct pollfd fds[1];
+  struct mgmt_pkt ev;
+  int fd;
+  int ret = 0;
+
+  ALOGI( "%s", __func__);
+  fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+  if (fd < 0) {
+    ALOGE( "Bluetooth socket error: %s", strerror(errno));
+    return -1;
+  }
+  memset(&addr, 0, sizeof(addr));
+  addr.hci_family = AF_BLUETOOTH;
+  addr.hci_dev = HCI_DEV_NONE;
+  addr.hci_channel = HCI_CHANNEL_CONTROL;
+  if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+    ALOGE( "HCI Channel Control: %s", strerror(errno));
+    ret = -1;
+    goto end;
+  }
+
+  fds[0].fd = fd;
+  fds[0].events = POLLIN;
+
+  /* Read Controller Index List Command */
+  ev.opcode = MGMT_OP_INDEX_LIST;
+  ev.index = HCI_DEV_NONE;
+  ev.len = 0;
+
+  ssize_t wrote;
+  WRITE_NO_INTR(wrote = write(fd, &ev, 6));
+  if (wrote != 6) {
+    ALOGE( "Unable to write mgmt command: %s", strerror(errno));
+    ret = -1;
+    goto end;
+  }
+  /* validate mentioned hci interface is present and registered with sock system */
+  while (1) {
+    int n;
+    WRITE_NO_INTR(n = poll(fds, 1, MGMT_EV_POLL_TIMEOUT));
+    if (n == -1) {
+      ALOGE( "Poll error: %s", strerror(errno));
+      ret = -1;
+      break;
+    } else if (n == 0) {
+      ALOGE( "Timeout, no HCI device detected");
+      ret = -1;
+      break;
+    }
+
+    if (fds[0].revents & POLLIN) {
+      WRITE_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt)));
+      if (n < 0) {
+        ALOGE( "Error reading control channel: %s",
+                  strerror(errno));
+        ret = -1;
+        break;
+      }
+
+      if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) {
+        goto end;
+      } else if (ev.opcode == MGMT_EV_COMMAND_COMP) {
+        struct mgmt_event_read_index* cc;
+        int i;
+
+        cc = (struct mgmt_event_read_index*)ev.data;
+
+        if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue;
+
+        for (i = 0; i < cc->num_intf; i++) {
+          if (cc->index[i] == hci_interface) goto end;
+        }
+      }
+    }
+  }
+
+end:
+  ::close(fd);
+  return ret;
+}
+
+int BluetoothHci::findRfKill() {
+    char rfkill_type[64];
+    char type[16];
+    int fd, size, i;
+    for(i = 0; rfkill_state_ == NULL; i++)
+    {
+        snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i);
+        if ((fd = open(rfkill_type, O_RDONLY)) < 0)
+        {
+            ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno);
+            return -1;
+        }
+
+        size = read(fd, &type, sizeof(type));
+        ::close(fd);
+
+        if ((size >= 9) && !memcmp(type, "bluetooth", 9))
+        {
+            ::asprintf(&rfkill_state_, "/sys/class/rfkill/rfkill%d/state", i);
+            break;
+        }
+    }
+    return 0;
+}
+
+int BluetoothHci::rfKill(int block) {
+  int fd;
+  char on = (block)?'1':'0';
+  if (findRfKill() != 0) return 0;
+
+  fd = open(rfkill_state_, O_WRONLY);
+  if (fd < 0) {
+    ALOGE( "Unable to open /dev/rfkill");
+    return -1;
+  }
+  ssize_t len;
+  WRITE_NO_INTR(len = write(fd, &on, 1));
+  if (len < 0) {
+    ALOGE( "Failed to change rfkill state");
+    ::close(fd);
+    return -1;
+  }
+  ::close(fd);
+  return 0;
+}
+
+class BluetoothDeathRecipient : public hidl_death_recipient {
+ public:
+  BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
+
+  virtual void serviceDied(
+      uint64_t /*cookie*/,
+      const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+    ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
+    has_died_ = true;
+    mHci->close();
+  }
+  sp<IBluetoothHci> mHci;
+  bool getHasDied() const { return has_died_; }
+  void setHasDied(bool has_died) { has_died_ = has_died; }
+
+ private:
+  bool has_died_;
+};
+
+BluetoothHci::BluetoothHci()
+    : death_recipient_(new BluetoothDeathRecipient(this)) {}
+
+Return<void> BluetoothHci::initialize(
+    const ::android::sp<IBluetoothHciCallbacks>& cb) {
+  ALOGI("BluetoothHci::initialize()");
+  if (cb == nullptr) {
+    ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
+    return Void();
+  }
+
+  death_recipient_->setHasDied(false);
+  cb->linkToDeath(death_recipient_, 0);
+  int hci_fd = openBtHci();
+  auto hidl_status = cb->initializationComplete(
+          hci_fd > 0 ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
+  if (!hidl_status.isOk()) {
+      ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
+  }
+  hci::H4Protocol* h4_hci = new hci::H4Protocol(
+      hci_fd,
+      [cb](const hidl_vec<uint8_t>& packet) { cb->hciEventReceived(packet); },
+      [cb](const hidl_vec<uint8_t>& packet) { cb->aclDataReceived(packet); },
+      [cb](const hidl_vec<uint8_t>& packet) { cb->scoDataReceived(packet); });
+
+  fd_watcher_.WatchFdForNonBlockingReads(
+          hci_fd, [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
+  hci_handle_ = h4_hci;
+
+  unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
+    if (death_recipient->getHasDied())
+      ALOGI("Skipping unlink call, service died.");
+    else
+      cb->unlinkToDeath(death_recipient);
+  };
+
+  return Void();
+}
+
+Return<void> BluetoothHci::close() {
+  ALOGI("BluetoothHci::close()");
+  unlink_cb_(death_recipient_);
+  fd_watcher_.StopWatchingFileDescriptors();
+
+  if (hci_handle_ != nullptr) {
+    delete hci_handle_;
+    hci_handle_ = nullptr;
+  }
+  closeBtHci();
+  return Void();
+}
+
+Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& command) {
+  sendDataToController(HCI_DATA_TYPE_COMMAND, command);
+  return Void();
+}
+
+Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& data) {
+  sendDataToController(HCI_DATA_TYPE_ACL, data);
+  return Void();
+}
+
+Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) {
+  sendDataToController(HCI_DATA_TYPE_SCO, data);
+  return Void();
+}
+
+void BluetoothHci::sendDataToController(const uint8_t type,
+                                        const hidl_vec<uint8_t>& data) {
+  hci_handle_->Send(type, data.data(), data.size());
+}
+
+IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
+  return new BluetoothHci();
+}
+
+}  // namespace btlinux
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/vendor_libs/linux/interface/bluetooth_hci.h b/vendor_libs/linux/interface/bluetooth_hci.h
new file mode 100644
index 0000000..5dc1c0a
--- /dev/null
+++ b/vendor_libs/linux/interface/bluetooth_hci.h
@@ -0,0 +1,78 @@
+//
+// Copyright 2016 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.
+//
+
+#ifndef HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
+#define HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
+
+#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+
+#include <hidl/MQDescriptor.h>
+
+#include "async_fd_watcher.h"
+#include "h4_protocol.h"
+#include "hci_internals.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace btlinux {
+
+using ::android::hardware::Return;
+using ::android::hardware::hidl_vec;
+
+class BluetoothDeathRecipient;
+
+class BluetoothHci : public IBluetoothHci {
+ public:
+  BluetoothHci();
+  Return<void> initialize(
+      const ::android::sp<IBluetoothHciCallbacks>& cb) override;
+  Return<void> sendHciCommand(const hidl_vec<uint8_t>& packet) override;
+  Return<void> sendAclData(const hidl_vec<uint8_t>& data) override;
+  Return<void> sendScoData(const hidl_vec<uint8_t>& data) override;
+  Return<void> close() override;
+
+ private:
+  async::AsyncFdWatcher fd_watcher_;
+  hci::H4Protocol* hci_handle_;
+  int bt_soc_fd_;
+  char *rfkill_state_;
+
+  const uint8_t HCI_DATA_TYPE_COMMAND = 1;
+  const uint8_t HCI_DATA_TYPE_ACL = 2;
+  const uint8_t HCI_DATA_TYPE_SCO = 3;
+
+  int waitHciDev(int hci_interface);
+  int findRfKill(void);
+  int rfKill(int block);
+  int openBtHci(void);
+  void closeBtHci(void);
+
+  void sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data);
+  ::android::sp<BluetoothDeathRecipient> death_recipient_;
+  std::function<void(sp<BluetoothDeathRecipient>&)> unlink_cb_;
+};
+
+extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
+
+}  // namespace btlinux
+}  // namespace V1_0
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
diff --git a/vendor_libs/linux/interface/h4_protocol.cc b/vendor_libs/linux/interface/h4_protocol.cc
new file mode 100644
index 0000000..e7acff4
--- /dev/null
+++ b/vendor_libs/linux/interface/h4_protocol.cc
@@ -0,0 +1,106 @@
+//
+// Copyright 2017 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 "h4_protocol.h"
+
+#define LOG_TAG "android.hardware.bluetooth-hci-h4"
+#include <android-base/logging.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/uio.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace hci {
+
+size_t H4Protocol::Send(uint8_t type, const uint8_t* data, size_t length) {
+    /* For HCI communication over USB dongle, multiple write results in
+     * response timeout as driver expect type + data at once to process
+     * the command, so using "writev"(for atomicity) here.
+     */
+    struct iovec iov[2];
+    ssize_t ret = 0;
+    iov[0].iov_base = &type;
+    iov[0].iov_len = sizeof(type);
+    iov[1].iov_base = (void *)data;
+    iov[1].iov_len = length;
+    while (1) {
+        ret = TEMP_FAILURE_RETRY(writev(uart_fd_, iov, 2));
+        if (ret == -1) {
+            if (errno == EAGAIN) {
+                ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
+                continue;
+            }
+        } else if (ret == 0) {
+            // Nothing written :(
+            ALOGE("%s zero bytes written - something went wrong...", __func__);
+            break;
+        }
+        break;
+    }
+    return ret;
+}
+
+void H4Protocol::OnPacketReady() {
+  switch (hci_packet_type_) {
+    case HCI_PACKET_TYPE_EVENT:
+      event_cb_(hci_packetizer_.GetPacket());
+      break;
+    case HCI_PACKET_TYPE_ACL_DATA:
+      acl_cb_(hci_packetizer_.GetPacket());
+      break;
+    case HCI_PACKET_TYPE_SCO_DATA:
+      sco_cb_(hci_packetizer_.GetPacket());
+      break;
+    default: {
+      bool bad_packet_type = true;
+      CHECK(!bad_packet_type);
+    }
+  }
+  // Get ready for the next type byte.
+  hci_packet_type_ = HCI_PACKET_TYPE_UNKNOWN;
+}
+
+void H4Protocol::OnDataReady(int fd) {
+    if (hci_packet_type_ == HCI_PACKET_TYPE_UNKNOWN) {
+        /**
+         * read full buffer. ACL max length is 2 bytes, and SCO max length is 2
+         * byte. so taking 64K as buffer length.
+         * Question : Why to read in single chunk rather than multiple reads,
+         * which can give parameter length arriving in response ?
+         * Answer: The multiple reads does not work with BT USB dongle. At least
+         * with Bluetooth 2.0 supported USB dongle. After first read, either
+         * firmware/kernel (do not know who is responsible - inputs ??) driver
+         * discard the whole message and successive read results in forever
+         * blocking loop. - Is there any other way to make it work with multiple
+         * reads, do not know yet (it can eliminate need of this function) ?
+         * Reading in single shot gives expected response.
+         */
+        const size_t max_plen = 64*1024;
+        hidl_vec<uint8_t> tpkt;
+        tpkt.resize(max_plen);
+        size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, tpkt.data(), max_plen));
+        hci_packet_type_ = static_cast<HciPacketType>(tpkt.data()[0]);
+        hci_packetizer_.CbHciPacket(tpkt.data()+1, bytes_read-1);
+    }
+}
+
+}  // namespace hci
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/vendor_libs/linux/interface/h4_protocol.h b/vendor_libs/linux/interface/h4_protocol.h
new file mode 100644
index 0000000..612b0db
--- /dev/null
+++ b/vendor_libs/linux/interface/h4_protocol.h
@@ -0,0 +1,63 @@
+//
+// Copyright 2017 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
+
+#include <hidl/HidlSupport.h>
+
+#include "async_fd_watcher.h"
+#include "hci_internals.h"
+#include "hci_packetizer.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace hci {
+
+using ::android::hardware::hidl_vec;
+using PacketReadCallback = std::function<void(const hidl_vec<uint8_t>&)>;
+
+class H4Protocol {
+ public:
+  H4Protocol(int fd, PacketReadCallback event_cb, PacketReadCallback acl_cb,
+             PacketReadCallback sco_cb)
+      : uart_fd_(fd),
+        event_cb_(event_cb),
+        acl_cb_(acl_cb),
+        sco_cb_(sco_cb),
+        hci_packetizer_([this]() { OnPacketReady(); }) {}
+
+  size_t Send(uint8_t type, const uint8_t* data, size_t length);
+
+  void OnPacketReady();
+
+  void OnDataReady(int fd);
+
+ private:
+  int uart_fd_;
+
+  PacketReadCallback event_cb_;
+  PacketReadCallback acl_cb_;
+  PacketReadCallback sco_cb_;
+
+  HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN};
+  HciPacketizer hci_packetizer_;
+};
+
+}  // namespace hci
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/vendor_libs/linux/interface/hci_internals.h b/vendor_libs/linux/interface/hci_internals.h
new file mode 100644
index 0000000..1e1f300
--- /dev/null
+++ b/vendor_libs/linux/interface/hci_internals.h
@@ -0,0 +1,49 @@
+//
+// Copyright 2016 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
+
+#include <stdlib.h>
+
+// HCI UART transport packet types (Volume 4, Part A, 2)
+enum HciPacketType {
+  HCI_PACKET_TYPE_UNKNOWN = 0,
+  HCI_PACKET_TYPE_COMMAND = 1,
+  HCI_PACKET_TYPE_ACL_DATA = 2,
+  HCI_PACKET_TYPE_SCO_DATA = 3,
+  HCI_PACKET_TYPE_EVENT = 4
+};
+
+// 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1)
+const size_t HCI_COMMAND_PREAMBLE_SIZE = 3;
+const size_t HCI_LENGTH_OFFSET_CMD = 2;
+
+// 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.2)
+const size_t HCI_ACL_PREAMBLE_SIZE = 4;
+const size_t HCI_LENGTH_OFFSET_ACL = 2;
+
+// 2 bytes for handle, 1 byte for data length (Volume 2, Part E, 5.4.3)
+const size_t HCI_SCO_PREAMBLE_SIZE = 3;
+const size_t HCI_LENGTH_OFFSET_SCO = 2;
+
+// 1 byte for event code, 1 byte for parameter length (Volume 2, Part E, 5.4.4)
+const size_t HCI_EVENT_PREAMBLE_SIZE = 2;
+const size_t HCI_LENGTH_OFFSET_EVT = 1;
+
+const size_t HCI_PREAMBLE_SIZE_MAX = HCI_ACL_PREAMBLE_SIZE;
+
+// Event codes (Volume 2, Part E, 7.7.14)
+const uint8_t HCI_COMMAND_COMPLETE_EVENT = 0x0E;
diff --git a/vendor_libs/linux/interface/hci_packetizer.cc b/vendor_libs/linux/interface/hci_packetizer.cc
new file mode 100644
index 0000000..0c0a979
--- /dev/null
+++ b/vendor_libs/linux/interface/hci_packetizer.cc
@@ -0,0 +1,96 @@
+//
+// Copyright 2017 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_packetizer.h"
+
+#define LOG_TAG "android.hardware.bluetooth.hci_packetizer"
+#include <android-base/logging.h>
+#include <utils/Log.h>
+
+#include <dlfcn.h>
+#include <fcntl.h>
+
+namespace {
+
+const size_t preamble_size_for_type[] = {
+    0, HCI_COMMAND_PREAMBLE_SIZE, HCI_ACL_PREAMBLE_SIZE, HCI_SCO_PREAMBLE_SIZE,
+    HCI_EVENT_PREAMBLE_SIZE};
+const size_t packet_length_offset_for_type[] = {
+    0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO,
+    HCI_LENGTH_OFFSET_EVT};
+
+size_t HciGetPacketLengthForType(HciPacketType type, const uint8_t* preamble) {
+  size_t offset = packet_length_offset_for_type[type];
+  if (type != HCI_PACKET_TYPE_ACL_DATA) return preamble[offset];
+  return (((preamble[offset + 1]) << 8) | preamble[offset]);
+}
+
+}  // namespace
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace hci {
+
+const hidl_vec<uint8_t>& HciPacketizer::GetPacket() const { return packet_; }
+
+void HciPacketizer::CbHciPacket(uint8_t *data, size_t len) {
+    packet_.setToExternal(data, len);
+    packet_ready_cb_();
+}
+
+void HciPacketizer::OnDataReady(int fd, HciPacketType packet_type) {
+  switch (state_) {
+    case HCI_PREAMBLE: {
+      size_t bytes_read = TEMP_FAILURE_RETRY(
+          read(fd, preamble_ + bytes_read_,
+               preamble_size_for_type[packet_type] - bytes_read_));
+      CHECK(bytes_read > 0);
+      bytes_read_ += bytes_read;
+      if (bytes_read_ == preamble_size_for_type[packet_type]) {
+        size_t packet_length =
+            HciGetPacketLengthForType(packet_type, preamble_);
+        packet_.resize(preamble_size_for_type[packet_type] + packet_length);
+        memcpy(packet_.data(), preamble_, preamble_size_for_type[packet_type]);
+        bytes_remaining_ = packet_length;
+        state_ = HCI_PAYLOAD;
+        bytes_read_ = 0;
+      }
+      break;
+    }
+
+    case HCI_PAYLOAD: {
+      size_t bytes_read = TEMP_FAILURE_RETRY(read(
+          fd,
+          packet_.data() + preamble_size_for_type[packet_type] + bytes_read_,
+          bytes_remaining_));
+      CHECK(bytes_read > 0);
+      bytes_remaining_ -= bytes_read;
+      bytes_read_ += bytes_read;
+      if (bytes_remaining_ == 0) {
+        packet_ready_cb_();
+        state_ = HCI_PREAMBLE;
+        bytes_read_ = 0;
+      }
+      break;
+    }
+  }
+}
+
+}  // namespace hci
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/vendor_libs/linux/interface/hci_packetizer.h b/vendor_libs/linux/interface/hci_packetizer.h
new file mode 100644
index 0000000..06de70f
--- /dev/null
+++ b/vendor_libs/linux/interface/hci_packetizer.h
@@ -0,0 +1,54 @@
+//
+// Copyright 2017 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
+
+#include <functional>
+
+#include <hidl/HidlSupport.h>
+
+#include "hci_internals.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace hci {
+
+using ::android::hardware::hidl_vec;
+using HciPacketReadyCallback = std::function<void(void)>;
+
+class HciPacketizer {
+ public:
+  HciPacketizer(HciPacketReadyCallback packet_cb)
+      : packet_ready_cb_(packet_cb){};
+  void OnDataReady(int fd, HciPacketType packet_type);
+  void CbHciPacket(uint8_t* data, size_t length);
+  const hidl_vec<uint8_t>& GetPacket() const;
+
+ protected:
+  enum State { HCI_PREAMBLE, HCI_PAYLOAD };
+  State state_{HCI_PREAMBLE};
+  uint8_t preamble_[HCI_PREAMBLE_SIZE_MAX];
+  hidl_vec<uint8_t> packet_;
+  size_t bytes_remaining_{0};
+  size_t bytes_read_{0};
+  HciPacketReadyCallback packet_ready_cb_;
+};
+
+}  // namespace hci
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
diff --git a/vendor_libs/linux/interface/service.cc b/vendor_libs/linux/interface/service.cc
new file mode 100644
index 0000000..fac9ce0
--- /dev/null
+++ b/vendor_libs/linux/interface/service.cc
@@ -0,0 +1,40 @@
+//
+// Copyright 2017 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.
+//
+
+#define LOG_TAG "android.hardware.bluetooth@1.0-service.btlinux"
+
+#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/Log.h>
+
+#include "bluetooth_hci.h"
+
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
+using ::android::hardware::bluetooth::V1_0::btlinux::BluetoothHci;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::sp;
+
+int main(int /* argc */, char** /* argv */) {
+  sp<IBluetoothHci> bluetooth = new BluetoothHci;
+  configureRpcThreadpool(1, true);
+  android::status_t status = bluetooth->registerAsService();
+  if (status == android::OK)
+    joinRpcThreadpool();
+  else
+    ALOGE("Could not register as a service!");
+}
diff --git a/vendor_libs/linux/sepolicy/file_contexts b/vendor_libs/linux/sepolicy/file_contexts
new file mode 100644
index 0000000..4300140
--- /dev/null
+++ b/vendor_libs/linux/sepolicy/file_contexts
@@ -0,0 +1,2 @@
+/sys/class/rfkill/rfkill[0-9]/state    u:object_r:sysfs_bluetooth_writable:s0
+/system/vendor/bin/hw/android\.hardware\.bluetooth@1\.0-service\.btlinux    u:object_r:hal_bluetooth_btlinux_exec:s0
diff --git a/vendor_libs/linux/sepolicy/hal_bluetooth_btlinux.te b/vendor_libs/linux/sepolicy/hal_bluetooth_btlinux.te
new file mode 100644
index 0000000..32349b9
--- /dev/null
+++ b/vendor_libs/linux/sepolicy/hal_bluetooth_btlinux.te
@@ -0,0 +1,8 @@
+type hal_bluetooth_btlinux, domain;
+type hal_bluetooth_btlinux_exec, exec_type, file_type;
+
+hal_server_domain(hal_bluetooth_btlinux, hal_bluetooth)
+init_daemon_domain(hal_bluetooth_btlinux)
+
+allow hal_bluetooth_btlinux self:socket { create bind read write };
+allow hal_bluetooth_btlinux self:bluetooth_socket { create bind read write };
diff --git a/vendor_libs/test_vendor_lib/Android.bp b/vendor_libs/test_vendor_lib/Android.bp
index 17be042..18498ed 100644
--- a/vendor_libs/test_vendor_lib/Android.bp
+++ b/vendor_libs/test_vendor_lib/Android.bp
@@ -24,6 +24,9 @@
         "include",
     ],
     export_include_dirs: ["include"],
+    header_libs: [
+        "libhardware_headers",
+    ],
     include_dirs: [
         "system/bt",
         "system/bt/utils/include",
@@ -36,6 +39,9 @@
         "libchrome",
         "liblog",
     ],
+    static_libs: [
+        "libbluetooth-types",
+    ]
 }
 
 // test-vendor unit tests for host
@@ -49,9 +55,13 @@
         "src/event_packet.cc",
         "src/packet.cc",
         "src/packet_stream.cc",
+        "src/l2cap_packet.cc",
+        "src/l2cap_sdu.cc",
         "test/async_manager_unittest.cc",
         "test/bt_address_unittest.cc",
         "test/packet_stream_unittest.cc",
+        "test/l2cap_test.cc",
+        "test/l2cap_sdu_test.cc",
     ],
     local_include_dirs: [
         "include",
@@ -66,6 +76,9 @@
         "liblog",
         "libchrome",
     ],
+    static_libs: [
+        "libbluetooth-types",
+    ],
     cflags: [
         "-fvisibility=hidden",
         "-Wall",
diff --git a/vendor_libs/test_vendor_lib/include/async_manager.h b/vendor_libs/test_vendor_lib/include/async_manager.h
index 6ee8c0b..6eaddcd 100644
--- a/vendor_libs/test_vendor_lib/include/async_manager.h
+++ b/vendor_libs/test_vendor_lib/include/async_manager.h
@@ -8,8 +8,6 @@
 #include "errno.h"
 #include "stdio.h"
 
-#include "osi/include/log.h"
-
 #include <chrono>
 #include <functional>
 #include <memory>
diff --git a/vendor_libs/test_vendor_lib/include/l2cap_packet.h b/vendor_libs/test_vendor_lib/include/l2cap_packet.h
new file mode 100644
index 0000000..6c95539
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/include/l2cap_packet.h
@@ -0,0 +1,80 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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.
+ *
+ ******************************************************************************/
+#pragma once
+
+#include <cmath>
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "l2cap_sdu.h"
+
+namespace test_vendor_lib {
+
+const int kSduHeaderLength = 4;
+
+class L2capPacket {
+ public:
+  // Returns an assembled L2cap object if successful, nullptr if failure.
+  static std::unique_ptr<L2capPacket> assemble(
+      const std::vector<L2capSdu>& sdu_packet);
+
+  // Construct a vector of just the L2CAP payload. This essentially
+  // will remove the L2CAP header from the private member variable.
+  // TODO: Remove this in favor of custom iterators.
+  std::vector<uint8_t> get_l2cap_payload() const;
+
+  uint16_t get_l2cap_cid() const;
+
+  // Returns a fragmented vector of L2capSdu objects if successful
+  // Returns an empty vector of L2capSdu objects if unsuccessful
+  std::vector<L2capSdu> fragment(uint16_t maximum_sdu_size, uint8_t txseq,
+                                 uint8_t reqseq) const;
+
+ private:
+  L2capPacket() = default;
+
+  // Entire L2CAP packet: length, CID, and payload in that order.
+  std::vector<uint8_t> l2cap_packet_;
+
+  // Returns an iterator to the beginning of the L2CAP payload on success.
+  std::vector<uint8_t>::const_iterator get_l2cap_payload_begin() const;
+
+  DISALLOW_COPY_AND_ASSIGN(L2capPacket);
+
+  // Returns an iterator to the end of the L2CAP payload.
+  std::vector<uint8_t>::const_iterator get_l2cap_payload_end() const;
+
+  // Helper functions for fragmenting.
+  static void set_sdu_header_length(std::vector<uint8_t>& sdu, uint16_t length);
+
+  static void set_total_sdu_length(std::vector<uint8_t>& sdu,
+                                   uint16_t total_sdu_length);
+
+  static void set_sdu_cid(std::vector<uint8_t>& sdu, uint16_t cid);
+
+  static void set_sdu_control_bytes(std::vector<uint8_t>& sdu, uint8_t txseq,
+                                    uint8_t reqseq);
+
+  bool check_l2cap_packet() const;
+
+};  // L2capPacket
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/l2cap_sdu.h b/vendor_libs/test_vendor_lib/include/l2cap_sdu.h
new file mode 100644
index 0000000..8a8c591
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/include/l2cap_sdu.h
@@ -0,0 +1,133 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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.
+ *
+ ******************************************************************************/
+#pragma once
+#include <cstdint>
+#include <iterator>
+#include <vector>
+
+namespace test_vendor_lib {
+
+// Abstract representation of an SDU packet that contains an L2CAP
+// payload. This class is meant to be used in collaboration with
+// the L2cap class defined in l2cap.h. For example, an SDU packet
+// may look as follows:
+//
+// vector<uint8_t> sdu = {0x04, 0x00, 0x48, 0x00, 0x04, 0x00, 0xab,
+//                       0xcd, 0x78, 0x56}
+//
+// The first two bytes (in little endian) should be read as 0x0004
+// and is the length of the payload of the SDU packet.
+//
+// The next two bytes (also in little endian) are the channel ID
+// and should be read as 0x0048. These should remain the same for
+// any number of SDUs that are a part of the same packet stream.
+//
+// Following the CID bytes, are the total length bytes. Since this
+// SDU only requires a single packet, the length here is the same
+// as the length in the first two bytes of the packet. Again stored
+// in little endian.
+//
+// Next comes the two control bytes. These begin the L2CAP payload
+// of the SDU packet; however, they will not be added to the L2CAP
+// packet that is being constructed in the assemble function that
+// will be creating an L2CAP packet from a stream of L2capSdu
+// objects.
+//
+// The final two bytes are the frame check sequence that should be
+// calculated from the start of the vector to the end of the
+// payload.
+//
+// Thus, calling assemble on this example would create a
+// zero-length L2CAP packet because the information payload of the
+// L2CAP packet will not include either of the control or FCS
+// bytes.
+//
+class L2capSdu {
+ public:
+  // Returns a completed L2capSdu object.
+  L2capSdu(std::vector<uint8_t> create_from);
+
+  static L2capSdu L2capSduBuilder(std::vector<uint8_t> create_from);
+
+  // TODO: Remove this when the move to L2capSdu* is done
+  L2capSdu& operator=(L2capSdu obj1) {
+    sdu_data_.clear();
+
+    sdu_data_ = obj1.sdu_data_;
+
+    return *this;
+  }
+
+  // Get a vector iterator that points to the first byte of the
+  // L2CAP payload within an SDU. The offset parameter will be the
+  // number of bytes that are in the SDU header. This should always
+  // be 6 bytes with the exception being the first SDU of a stream
+  // of SDU packets where the first SDU packet will have an extra
+  // two bytes and the offset should be 8 bytes.
+  std::vector<uint8_t>::const_iterator get_payload_begin(
+      const unsigned int offset) const;
+
+  // Get a vector iterator that points to the last bytes of the
+  // L2CAP payload within an SDU packet. There is no offset
+  // parameter for this function because there will always be two
+  // FCS bytes and nothing else at the end of each SDU.
+  std::vector<uint8_t>::const_iterator get_payload_end() const;
+
+  // Get the FCS bytes from the end of the L2CAP payload of an SDU
+  // packet.
+  uint16_t get_fcs() const;
+
+  uint16_t get_payload_length() const;
+
+  uint16_t calculate_fcs() const;
+
+  // Get the two control bytes that begin the L2CAP payload. These
+  // bytes will contain information such as the Segmentation and
+  // Reassembly bits, and the TxSeq/ReqSeq numbers.
+  uint16_t get_controls() const;
+
+  uint16_t get_total_l2cap_length() const;
+
+  size_t get_vector_size() const;
+
+  uint16_t get_channel_id() const;
+
+  // Returns true if the SDU control sequence for Segmentation and
+  // Reassembly is 00b, false otherwise.
+  static bool is_complete_l2cap(const L2capSdu& sdu);
+
+  // Returns true if the SDU control sequence for Segmentation and
+  // Reassembly is 01b, false otherwise.
+  static bool is_starting_sdu(const L2capSdu& sdu);
+
+  // Returns true if the SDU control sequence for Segmentation and
+  // Reasembly is 10b, false otherwise.
+  static bool is_ending_sdu(const L2capSdu& sdu);
+
+ private:
+  // This is the SDU packet in bytes.
+  std::vector<uint8_t> sdu_data_;
+
+  // Table for precalculated lfsr values.
+  static const uint16_t lfsr_table_[256];
+
+  uint16_t convert_from_little_endian(const unsigned int starting_index) const;
+
+};  // L2capSdu
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/l2cap_test_packets.h b/vendor_libs/test_vendor_lib/include/l2cap_test_packets.h
new file mode 100644
index 0000000..b0d5238
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/include/l2cap_test_packets.h
@@ -0,0 +1,1446 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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.
+ *
+ ******************************************************************************/
+#pragma once
+#include <cstdint>
+#include <vector>
+namespace {
+
+// Complete SDUs that should always assemble.
+std::vector<std::vector<uint8_t> > good_sdu = {
+    {0x0c, 0x00, 0x47, 0x00, 0x02, 0x41, 0x12, 0x00, 0x00, 0x01, 0x02, 0x03,
+     0x04, 0x05, 0xeb, 0x0f},
+
+    {0x0a, 0x00, 0x47, 0x00, 0x04, 0xc1, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+     0x5a, 0x8a},
+
+    {0x0a, 0x00, 0x47, 0x00, 0x06, 0x81, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+     0x68, 0x1e}};
+
+// The complete L2CAP packet that should be created by calling assemble on the
+// good_sdu vector.
+std::vector<uint8_t> good_l2cap_packet = {
+    0x12, 0x00, 0x47, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+    0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11};
+
+// SDUs that are missing a payload.
+std::vector<std::vector<uint8_t> > empty_sdu_payload = {
+    {0x06, 0x00, 0x47, 0x00, 0x02, 0x41, 0x00, 0x00, 0xde, 0xf1},
+
+    {0x04, 0x00, 0x47, 0x00, 0x04, 0x81, 0xd7, 0x90}};
+
+// The l2cap packet that should be created by calling assemble on the
+// empty_sdu_payload vector.
+std::vector<uint8_t> empty_l2cap_payload = {0x00, 0x00, 0x47, 0x00};
+
+// SDUs that have all of the control bytes set to be the start of the SDU.
+std::vector<std::vector<uint8_t> > all_first_packet = {
+    {0x0c, 0x00, 0x47, 0x00, 0x02, 0x41, 0x18, 0x00, 0x00, 0x01, 0x02, 0x03,
+     0x04, 0x05, 0x6b, 0x70},
+
+    {0x0c, 0x00, 0x47, 0x00, 0x02, 0x41, 0x18, 0x00, 0x00, 0x01, 0x02, 0x03,
+     0x04, 0x05, 0x6b, 0x70},
+
+    {0x0c, 0x00, 0x47, 0x00, 0x02, 0x41, 0x18, 0x00, 0x00, 0x01, 0x02, 0x03,
+     0x04, 0x05, 0x6b, 0x70}};
+
+// A complete L2CAP packet that has not been segmented.
+std::vector<std::vector<uint8_t> > one_sdu = {{0x0b, 0x00, 0x47, 0x00, 0x02,
+                                               0x00, 0x01, 0x02, 0x03, 0x04,
+                                               0x05, 0x06, 0x07, 0x4a, 0x2f}};
+
+// l2cap_test_packet_[1-9] are SDUs that were extracted from snoop logs.
+std::vector<uint8_t> l2cap_test_packet_1 = {
+    0xf8, 0x03, 0x47, 0x00, 0x02, 0x41, 0x95, 0x1f, 0x02, 0x1f, 0x95, 0xcb,
+    0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x33, 0x00, 0x49, 0x00, 0x4d, 0x00,
+    0x47, 0x00, 0x5f, 0x00, 0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x37, 0x00,
+    0x30, 0x00, 0x36, 0x00, 0x30, 0x00, 0x36, 0x00, 0x5f, 0x00, 0x31, 0x00,
+    0x35, 0x00, 0x34, 0x00, 0x33, 0x00, 0x33, 0x00, 0x38, 0x00, 0x2e, 0x00,
+    0x6a, 0x00, 0x70, 0x00, 0x67, 0x00, 0x00, 0x42, 0x00, 0x0e, 0x69, 0x6d,
+    0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0x00, 0xc3, 0x00, 0x12,
+    0x30, 0x03, 0x97, 0x01, 0x48, 0x1f, 0x45, 0xff, 0xd8, 0xff, 0xe0, 0x00,
+    0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x00, 0xff, 0xe1, 0x2b, 0x18, 0x45, 0x78, 0x69, 0x66, 0x00,
+    0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x01,
+    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0c, 0xc0, 0x01,
+    0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x90, 0x01,
+    0x0f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x4c, 0x47, 0x45, 0x00, 0x01,
+    0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x9e, 0x01,
+    0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
+    0x1a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x01,
+    0x1b, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae, 0x01,
+    0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01,
+    0x31, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb6, 0x01,
+    0x32, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xbd, 0x02,
+    0x13, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x87,
+    0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x00,
+    0x00, 0x02, 0x78, 0x4e, 0x65, 0x78, 0x75, 0x73, 0x20, 0x35, 0x00, 0x00,
+    0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00,
+    0x00, 0x00, 0x01, 0x50, 0x69, 0x63, 0x61, 0x73, 0x61, 0x00, 0x32, 0x30,
+    0x31, 0x37, 0x3a, 0x30, 0x36, 0x3a, 0x30, 0x36, 0x20, 0x31, 0x35, 0x3a,
+    0x34, 0x33, 0x3a, 0x33, 0x38, 0x00, 0x00, 0x00, 0x15, 0x82, 0x9a, 0x00,
+    0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xd4, 0x82, 0x9d, 0x00,
+    0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xdc, 0x88, 0x27, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x01, 0x02, 0x1f, 0x00, 0x00, 0x90, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x32, 0x32, 0x30, 0x90, 0x03, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x01, 0xe4, 0x90, 0x04, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x01, 0xf8, 0x91, 0x01, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x00, 0x92, 0x01, 0x00,
+    0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x0c, 0x92, 0x02, 0x00,
+    0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x14, 0x92, 0x09, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x92, 0x0a, 0x00,
+    0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x1c, 0x92, 0x90, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x24, 0x92, 0x91, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x2b, 0x92, 0x92, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x02, 0x32, 0xa0, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x31, 0x30, 0x30, 0xa0, 0x01, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, 0x00,
+    0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x0a, 0xa0, 0x03, 0x00,
+    0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x77, 0xa0, 0x05, 0x00,
+    0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x5a, 0xa4, 0x03, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x20, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0xfc, 0x8c, 0xb2, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x00,
+    0xf0, 0x00, 0x00, 0x00, 0x64, 0x32, 0x30, 0x31, 0x37, 0x3a, 0x30, 0x36,
+    0x3a, 0x30, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34, 0x33, 0x3a, 0x33, 0x38,
+    0x00, 0x32, 0x30, 0x31, 0x37, 0x3a, 0x30, 0x36, 0x3a, 0x30, 0x36, 0x20,
+    0x31, 0x35, 0x3a, 0x34, 0x33, 0x3a, 0x33, 0x38, 0x00, 0xff, 0xff, 0xfe,
+    0x16, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
+    0x64, 0x00, 0x00, 0x0f, 0x82, 0x00, 0x00, 0x03, 0xe8, 0x39, 0x39, 0x39,
+    0x37, 0x32, 0x39, 0x00, 0x39, 0x39, 0x39, 0x37, 0x32, 0x39, 0x00, 0x39,
+    0x39, 0x39, 0x37, 0x32, 0x39, 0x00, 0x31, 0x30, 0x61, 0x66, 0x39, 0x37,
+    0x31, 0x37, 0x63, 0x31, 0x30, 0x36, 0x36, 0x33, 0x65, 0x62, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x04, 0x52, 0x39, 0x38, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x04, 0x30, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01,
+    0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x01,
+    0x1a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xc6, 0x01,
+    0x1b, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xce, 0x01,
+    0x28, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02,
+    0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xd6, 0x02,
+    0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x28, 0x39, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0xff, 0xd8, 0xff, 0xe0, 0x00,
+    0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00,
+    0x01, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x05, 0x03, 0x04, 0x04,
+    0x04, 0x03, 0x05, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c,
+    0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09, 0x0c, 0x11, 0x0f,
+    0x12, 0x12, 0x11, 0x0f, 0x11, 0x11, 0x13, 0x16, 0x1c, 0x17, 0x13, 0x14,
+    0x1a, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1a, 0x1d, 0x1d, 0x1f, 0x1f,
+    0x1f, 0x13, 0x17, 0x22, 0x24, 0x22, 0x1e, 0x24, 0x1c, 0x1e, 0x1f, 0x1e,
+    0xff, 0xdb, 0x00, 0x43, 0x01, 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0e,
+    0x08, 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+    0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+    0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+    0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+    0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0xff, 0xc0, 0x00,
+    0x11, 0x08, 0x00, 0x78, 0x00, 0xa0, 0x03, 0x01, 0x22, 0x00, 0xaa, 0x72};
+
+std::vector<uint8_t> l2cap_test_packet_2 = {
+    0xf6, 0x03, 0x47, 0x00, 0x04, 0xc1, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
+    0xff, 0xc4, 0x00, 0x1c, 0x00, 0x00, 0x03, 0x00, 0x03, 0x01, 0x01, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07,
+    0x00, 0x04, 0x08, 0x03, 0x02, 0x01, 0xff, 0xc4, 0x00, 0x40, 0x10, 0x00,
+    0x01, 0x03, 0x02, 0x05, 0x02, 0x04, 0x04, 0x04, 0x03, 0x06, 0x04, 0x07,
+    0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x00, 0x06, 0x12,
+    0x21, 0x31, 0x07, 0x41, 0x13, 0x22, 0x51, 0x61, 0x14, 0x32, 0x71, 0x81,
+    0x08, 0x42, 0x91, 0xa1, 0x15, 0x16, 0xc1, 0x23, 0x52, 0x62, 0x82, 0xb1,
+    0xe1, 0x24, 0x43, 0x72, 0xf0, 0x17, 0x25, 0x33, 0x92, 0xb2, 0xd1, 0xd2,
+    0xff, 0xc4, 0x00, 0x1c, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07,
+    0x04, 0x03, 0x00, 0x02, 0x08, 0x01, 0xff, 0xc4, 0x00, 0x37, 0x11, 0x00,
+    0x01, 0x02, 0x04, 0x04, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0x11, 0x06, 0x21,
+    0x31, 0x41, 0x12, 0x51, 0x71, 0x13, 0x22, 0x61, 0x81, 0x91, 0xa1, 0x07,
+    0xb1, 0xc1, 0xf0, 0x14, 0x42, 0xd1, 0xe1, 0xf1, 0x15, 0x24, 0x32, 0x82,
+    0x33, 0x52, 0x72, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11,
+    0x03, 0x11, 0x00, 0x3f, 0x00, 0xb1, 0x31, 0x2c, 0x2d, 0xd8, 0xd2, 0xda,
+    0x43, 0x26, 0x4a, 0x99, 0x1e, 0x15, 0x98, 0x2e, 0x2f, 0x51, 0x49, 0x0b,
+    0x03, 0x70, 0x90, 0x6c, 0x9f, 0x4d, 0xb7, 0xf5, 0xc3, 0x0b, 0x4f, 0x09,
+    0x1f, 0x08, 0xa5, 0x95, 0xb6, 0xb7, 0x50, 0x4e, 0x95, 0xab, 0xe4, 0xbf,
+    0x2a, 0xb1, 0x17, 0xb8, 0xb1, 0xde, 0xdd, 0xf1, 0x34, 0xa1, 0x3b, 0x25,
+    0xb6, 0x5d, 0x67, 0xe2, 0xda, 0x5b, 0xeb, 0x49, 0xf0, 0xd2, 0x83, 0xe1,
+    0xa9, 0x37, 0xbe, 0x91, 0x72, 0xab, 0x5f, 0x73, 0x7f, 0xb6, 0x1d, 0x28,
+    0xf0, 0xdf, 0xf1, 0x9b, 0x05, 0x2e, 0x20, 0x32, 0xd8, 0x64, 0x23, 0x52,
+    0x4a, 0x9c, 0xb7, 0x2b, 0x52, 0x8d, 0xd5, 0xe9, 0xe5, 0xdb, 0x83, 0xea,
+    0x30, 0x09, 0x75, 0x86, 0x25, 0xec, 0x1e, 0x58, 0x4d, 0xf9, 0x90, 0x20,
+    0x87, 0x60, 0x4e, 0x91, 0xb2, 0xc3, 0x72, 0x63, 0xcd, 0x40, 0x76, 0x63,
+    0xd2, 0x5b, 0x4a, 0x75, 0x04, 0x20, 0x06, 0xf9, 0xdb, 0xcd, 0xdc, 0x83,
+    0xe9, 0x6b, 0xec, 0x0d, 0xf1, 0xba, 0x5f, 0x76, 0xe9, 0x50, 0x43, 0x65,
+    0xd9, 0x05, 0x21, 0x08, 0xf2, 0x92, 0x94, 0x05, 0x73, 0x72, 0x48, 0x20,
+    0x5c, 0xaa, 0xf8, 0xf8, 0xa9, 0x34, 0x97, 0xe4, 0x3e, 0xc7, 0xc4, 0x80,
+    0x95, 0x90, 0x90, 0x9d, 0x1a, 0x94, 0x8b, 0xd8, 0x6d, 0xb5, 0x80, 0xef,
+    0xf7, 0xc7, 0xeb, 0x14, 0xb7, 0xdb, 0x79, 0x45, 0x2f, 0xb6, 0x50, 0x55,
+    0x7b, 0x96, 0x86, 0xb4, 0xf1, 0xc2, 0xaf, 0x7e, 0xc3, 0x7c, 0x65, 0x77,
+    0x15, 0x52, 0x98, 0x36, 0x53, 0xc3, 0xca, 0xe7, 0xe5, 0x78, 0xf0, 0xb0,
+    0xb3, 0x99, 0x11, 0xae, 0xa6, 0xd8, 0x91, 0x2c, 0x38, 0x3c, 0x37, 0xb4,
+    0x36, 0xa6, 0x99, 0xd2, 0xb2, 0xb0, 0xda, 0x01, 0x04, 0xea, 0x24, 0x8d,
+    0xcd, 0xb6, 0xfa, 0x63, 0x62, 0x92, 0xdb, 0x2c, 0xb8, 0xcb, 0x29, 0x7d,
+    0x97, 0x94, 0x5b, 0x53, 0xa0, 0x22, 0xfa, 0x02, 0x52, 0x52, 0x35, 0x12,
+    0x2f, 0x71, 0x7b, 0x72, 0x77, 0xe0, 0x63, 0xc2, 0xb9, 0x43, 0xa9, 0x39,
+    0x09, 0xc8, 0xd0, 0x1f, 0x6d, 0x95, 0xbb, 0xa5, 0x7f, 0x10, 0xfa, 0x3c,
+    0x5d, 0xf5, 0x58, 0x24, 0x20, 0x5b, 0x51, 0x3c, 0x58, 0x9b, 0x5a, 0xf7,
+    0xbd, 0xf1, 0x2f, 0xcd, 0x94, 0x9c, 0xff, 0x00, 0x4a, 0x94, 0xe4, 0xba,
+    0x8e, 0x60, 0xa8, 0xba, 0xc0, 0x05, 0x1a, 0xe2, 0x47, 0x09, 0x09, 0x4f,
+    0xa6, 0x94, 0x8b, 0xa7, 0xd8, 0x0f, 0xb6, 0x0a, 0xd3, 0xaa, 0x54, 0xe9,
+    0xe5, 0xa1, 0x29, 0x98, 0x4a, 0x4a, 0xb4, 0x0a, 0xba, 0x6f, 0x9d, 0xb7,
+    0x16, 0xbf, 0x21, 0x7b, 0x9d, 0x84, 0x0d, 0xa8, 0x4c, 0xb9, 0x26, 0xd9,
+    0x73, 0xb2, 0x52, 0xc0, 0xff, 0x00, 0xa8, 0x07, 0xda, 0xf7, 0xeb, 0x95,
+    0x84, 0x55, 0xdb, 0x4c, 0x26, 0xa4, 0x3e, 0xdb, 0x0b, 0x2e, 0xcb, 0x91,
+    0x24, 0xbe, 0xa2, 0x2c, 0x08, 0x52, 0x86, 0xca, 0xb7, 0x17, 0x00, 0x58,
+    0xed, 0x72, 0x0e, 0xf8, 0xf8, 0x7e, 0x6c, 0x28, 0xce, 0x3a, 0xc3, 0x25,
+    0x90, 0x88, 0xc9, 0xd4, 0xe9, 0x71, 0xc0, 0x09, 0x52, 0x85, 0xed, 0xa8,
+    0xf7, 0xbd, 0xff, 0x00, 0x4d, 0x86, 0x39, 0x96, 0xa7, 0xd4, 0x6a, 0x63,
+    0x28, 0x5b, 0x1f, 0xce, 0x33, 0xf5, 0x36, 0x0a, 0x5c, 0x49, 0x75, 0x6b,
+    0x70, 0xab, 0x8b, 0x8b, 0x91, 0x63, 0x6b, 0x6d, 0x6e, 0xd8, 0x00, 0xee,
+    0x76, 0xca, 0xce, 0x27, 0xc6, 0x6a, 0x8b, 0x32, 0x78, 0x69, 0x3f, 0xda,
+    0x3a, 0xa6, 0xca, 0x89, 0xb7, 0x2a, 0x3b, 0x9f, 0x7c, 0x37, 0xff, 0x00,
+    0x41, 0x69, 0x1f, 0xf2, 0xbe, 0x07, 0xa7, 0xd4, 0x88, 0x54, 0x18, 0xaa,
+    0x61, 0xcf, 0xf8, 0xa4, 0xd6, 0x7a, 0xe5, 0xf3, 0x1f, 0xac, 0x75, 0x8c,
+    0x0c, 0xc3, 0x02, 0xa3, 0x50, 0x6a, 0x9c, 0xc5, 0x62, 0x92, 0xe4, 0xa7,
+    0x10, 0xb6, 0xbe, 0x1d, 0xb9, 0x2d, 0xad, 0x00, 0x80, 0x3f, 0x2f, 0xcc,
+    0xb5, 0x0b, 0x1e, 0x2c, 0x07, 0xb9, 0xc7, 0xae, 0x68, 0x96, 0xa4, 0xd2,
+    0xcb, 0x31, 0x25, 0x29, 0x72, 0x00, 0x0d, 0x96, 0xda, 0xec, 0x9b, 0xf7,
+    0xb0, 0xd8, 0xf7, 0xda, 0xc7, 0xb6, 0x21, 0x79, 0x22, 0x3d, 0x1e, 0xbf,
+    0x45, 0x8b, 0x3c, 0xd3, 0x95, 0x11, 0xb9, 0x26, 0xf1, 0x5c, 0x69, 0x65,
+    0xa7, 0x10, 0xa0, 0xe6, 0x84, 0x9d, 0xb7, 0x1e, 0x71, 0x89, 0xac, 0x0a,
+    0x9d, 0x56, 0x8f, 0x38, 0x48, 0x8d, 0x52, 0x9d, 0x0d, 0x65, 0xc2, 0x54,
+    0xeb, 0x2e, 0xa9, 0x0a, 0x55, 0x8d, 0x89, 0xe7, 0x7e, 0xfc, 0xe0, 0x0d,
+    0x79, 0xb6, 0xe9, 0x8a, 0x42, 0x50, 0x4a, 0x82, 0xc6, 0xbf, 0xa4, 0x51,
+    0xbe, 0x1b, 0xc8, 0x2b, 0x18, 0x35, 0x32, 0xe3, 0x87, 0xb2, 0x53, 0x2a,
+    0x09, 0xe1, 0xd6, 0xe4, 0x8b, 0xe6, 0x76, 0xf4, 0x31, 0xd6, 0x31, 0x67,
+    0x66, 0x00, 0xda, 0x90, 0x22, 0xc6, 0x79, 0xb4, 0x20, 0xa1, 0x6f, 0xbc,
+    0x0a, 0x41, 0x09, 0xf3, 0x6b, 0x09, 0x37, 0xb0, 0x36, 0xdc, 0x12, 0x4e,
+    0xd8, 0x11, 0x51, 0x7f, 0xf8, 0xed, 0x5a, 0x1c, 0x88, 0x35, 0x04, 0xa5,
+    0xc8, 0x4d, 0x2d, 0x4d, 0xa9, 0xc8, 0xd6, 0x6b, 0x52, 0x87, 0x99, 0x4a,
+    0xb8, 0xdc, 0x93, 0xc0, 0x06, 0xdc, 0xe2, 0x21, 0x13, 0xa9, 0xd9, 0xb0,
+    0xb1, 0xe1, 0x4a, 0xaf, 0x3a, 0xe9, 0x4a, 0xb5, 0x21, 0x6e, 0xb0, 0x85,
+    0x9f, 0x6b, 0xa8, 0x6f, 0x7f, 0xb6, 0x35, 0xe2, 0xf5, 0x37, 0x37, 0xca,
+    0x7c, 0x35, 0x51, 0xaf, 0xae, 0x13, 0x00, 0xfc, 0xed, 0x46, 0xd7, 0x71,
+    0xfe, 0x22, 0x0d, 0xc7, 0xe8, 0x70, 0x10, 0xcf, 0xb0, 0x53, 0x61, 0x73,
+    0xe9, 0xfa, 0xc3, 0xcc, 0xc6, 0x09, 0x7a, 0x50, 0x15, 0x29, 0x1c, 0x5f,
+    0xf9, 0xb9, 0xfa, 0x67, 0xe5, 0x68, 0xe8, 0x7a, 0x34, 0x17, 0x60, 0x34,
+    0xa0, 0x66, 0x53, 0xdb, 0x53, 0x84, 0xea, 0x5b, 0x67, 0x4d, 0xfd, 0xfc,
+    0xbe, 0xfb, 0xf3, 0xbf, 0xd3, 0x6c, 0x7d, 0x66, 0x57, 0x5b};
+
+std::vector<uint8_t> l2cap_test_packet_3 = {
+    0xf6, 0x03, 0x47, 0x00, 0x06, 0xc1, 0x87, 0xeb, 0x74, 0xf8, 0xb1, 0xe1,
+    0xd2, 0xc4, 0x35, 0x49, 0x90, 0xcb, 0xae, 0xc3, 0x73, 0x7d, 0x3a, 0x90,
+    0x9b, 0x90, 0x45, 0xed, 0xbd, 0xf6, 0x3c, 0x0e, 0x6d, 0x89, 0xa6, 0x46,
+    0x89, 0x56, 0xac, 0x4b, 0x81, 0x35, 0xac, 0xdc, 0xfd, 0x56, 0x31, 0x7d,
+    0x2a, 0x29, 0x60, 0x0b, 0x25, 0x49, 0x58, 0xd9, 0xc0, 0x07, 0x96, 0xe3,
+    0xb1, 0xb6, 0xd8, 0xac, 0xe7, 0xb4, 0x45, 0x6a, 0xaf, 0x4b, 0x43, 0x4a,
+    0x6d, 0x25, 0xa9, 0x32, 0x11, 0xa1, 0x24, 0x5d, 0x29, 0x53, 0x5b, 0x6d,
+    0xd8, 0x5c, 0x60, 0xad, 0x29, 0x4d, 0xcc, 0x38, 0x3b, 0xb6, 0x00, 0x8d,
+    0x77, 0x85, 0xb9, 0x96, 0x19, 0x49, 0x52, 0x10, 0x9c, 0xc2, 0x54, 0x73,
+    0x1a, 0x10, 0x92, 0x47, 0xbd, 0xa2, 0x1c, 0x9f, 0xfc, 0x40, 0x7a, 0x32,
+    0x5f, 0x97, 0x99, 0x1d, 0x52, 0xdb, 0x36, 0x11, 0x92, 0xe2, 0x90, 0xd3,
+    0x62, 0xdc, 0x0d, 0x24, 0x11, 0xb1, 0xc2, 0xfd, 0x5a, 0x5e, 0x60, 0x42,
+    0x2c, 0xfc, 0x07, 0x18, 0x75, 0x2a, 0xba, 0x26, 0x21, 0xe5, 0x3f, 0x63,
+    0xfd, 0xe4, 0xa9, 0x47, 0xca, 0x46, 0xe3, 0x71, 0xdf, 0x19, 0xd6, 0x3a,
+    0xd5, 0x5e, 0x91, 0x0d, 0x2f, 0xc1, 0x21, 0x94, 0x29, 0xd7, 0x2e, 0x15,
+    0x65, 0x05, 0x5b, 0x4e, 0xe4, 0x7d, 0xf8, 0x38, 0x0b, 0x42, 0xea, 0x69,
+    0x30, 0x9b, 0x6a, 0xb9, 0x4b, 0x43, 0xe1, 0xb0, 0x12, 0x1d, 0x8e, 0x7c,
+    0x32, 0x8f, 0xb7, 0x6f, 0xb6, 0x28, 0xcb, 0x99, 0x92, 0x95, 0x74, 0x36,
+    0xa0, 0x94, 0xa8, 0x8b, 0x8c, 0xac, 0x39, 0x74, 0x88, 0xa6, 0x1f, 0xc4,
+    0x18, 0xbd, 0x12, 0x9f, 0x8e, 0x67, 0x85, 0xe6, 0xd4, 0x4d, 0xd2, 0x6d,
+    0x71, 0x6d, 0x6d, 0x98, 0x3e, 0x40, 0xf9, 0x40, 0xf9, 0x19, 0x9a, 0xad,
+    0xe3, 0x3b, 0x11, 0x6e, 0xca, 0xa9, 0x6b, 0x56, 0x8d, 0x72, 0x5c, 0x4a,
+    0xad, 0x7b, 0x0b, 0x24, 0xe9, 0x3a, 0x71, 0xf7, 0x97, 0xaa, 0x19, 0x86,
+    0x65, 0x52, 0x24, 0x66, 0xe9, 0x0d, 0xb7, 0xe3, 0x38, 0x1b, 0x49, 0x44,
+    0x50, 0xab, 0x82, 0xab, 0x5e, 0xc4, 0x6f, 0x6c, 0x35, 0xb3, 0x4b, 0xcb,
+    0x79, 0x89, 0xe4, 0xce, 0xa6, 0x26, 0x6c, 0x69, 0x5a, 0x82, 0x95, 0x29,
+    0x2b, 0x52, 0x1d, 0x41, 0x3b, 0x8b, 0x91, 0xda, 0xc3, 0x6d, 0x88, 0xd8,
+    0xe1, 0x93, 0x2f, 0xcf, 0xab, 0xe5, 0x7c, 0xc7, 0x4d, 0x46, 0x60, 0x97,
+    0x0e, 0x75, 0x31, 0xe9, 0x08, 0x69, 0x12, 0x8c, 0x60, 0x87, 0xda, 0xf4,
+    0xbe, 0x8b, 0x05, 0x0f, 0xb0, 0x3d, 0xf1, 0x8a, 0x64, 0xd5, 0x5a, 0x1c,
+    0x52, 0xae, 0x24, 0xa0, 0x67, 0x6b, 0x01, 0xfc, 0xfa, 0xc3, 0x75, 0x33,
+    0xe2, 0x63, 0x4f, 0xbc, 0x99, 0x57, 0xd2, 0x59, 0x73, 0x4e, 0x12, 0x32,
+    0xbf, 0xcf, 0xd6, 0x06, 0xf5, 0x01, 0xd9, 0x74, 0xac, 0xba, 0xdb, 0x2f,
+    0x33, 0x1d, 0xba, 0x85, 0x36, 0xae, 0xe4, 0x77, 0x5d, 0x61, 0xad, 0x96,
+    0x0b, 0x63, 0x70, 0x07, 0xfd, 0x37, 0xb6, 0x1f, 0xba, 0x4b, 0x5b, 0x95,
+    0x3f, 0x2b, 0xc1, 0x44, 0xc7, 0x1e, 0x96, 0x02, 0x8d, 0xca, 0x9b, 0xb2,
+    0x94, 0x41, 0x24, 0x12, 0x2f, 0xcd, 0xec, 0x37, 0xe7, 0xdf, 0x13, 0xbe,
+    0xb2, 0x54, 0x4c, 0xba, 0xce, 0x60, 0x5c, 0x25, 0x87, 0xe9, 0xee, 0x4a,
+    0x6e, 0x49, 0xf0, 0xd3, 0x72, 0x95, 0x29, 0x24, 0x03, 0xa8, 0x1d, 0xb9,
+    0x3b, 0x7b, 0x7b, 0x60, 0xef, 0x43, 0x5d, 0x29, 0x88, 0xdb, 0x8b, 0x72,
+    0x33, 0x65, 0x5e, 0x25, 0xee, 0x17, 0x7b, 0x10, 0x05, 0xac, 0x0d, 0x89,
+    0xdb, 0x83, 0x85, 0x8c, 0x5a, 0x78, 0x66, 0x9a, 0x58, 0xdd, 0x20, 0x9f,
+    0x3b, 0x9f, 0xac, 0x3b, 0xd5, 0xdb, 0xb9, 0x4a, 0xd5, 0xa9, 0x00, 0xfb,
+    0x40, 0xac, 0xbf, 0x98, 0xbe, 0x31, 0x9a, 0xab, 0x73, 0x42, 0xde, 0x80,
+    0xc7, 0x87, 0xa9, 0x2b, 0x6c, 0x10, 0xe0, 0x28, 0xbe, 0xe0, 0xec, 0x47,
+    0xa7, 0xfb, 0x62, 0x9b, 0x94, 0x9a, 0xa9, 0xd6, 0x72, 0xa8, 0x95, 0x90,
+    0x33, 0x73, 0x72, 0xd6, 0x86, 0x2e, 0x69, 0x92, 0xbc, 0xcb, 0x61, 0x76,
+    0xf9, 0x52, 0x54, 0x6f, 0xa7, 0xd8, 0x92, 0x3d, 0x14, 0x31, 0x03, 0x76,
+    0x3b, 0x4d, 0xe4, 0xcc, 0xcd, 0x23, 0x58, 0xbb, 0x8d, 0xa2, 0xe9, 0x04,
+    0xd9, 0x20, 0x04, 0x8d, 0xbd, 0x76, 0xc4, 0xf3, 0x2a, 0x55, 0x33, 0x44,
+    0x4c, 0xf6, 0x22, 0xe5, 0x27, 0xa6, 0xae, 0xa2, 0xe4, 0xa0, 0x96, 0x44,
+    0x72, 0x6e, 0x0d, 0x85, 0xcd, 0x87, 0x6b, 0x5e, 0xff, 0x00, 0xbe, 0x3d,
+    0xa6, 0x9a, 0x94, 0x98, 0xa7, 0xcb, 0x4a, 0x4c, 0xb4, 0x16, 0x14, 0x9b,
+    0xe6, 0x01, 0xcf, 0x2d, 0xb5, 0xdf, 0x50, 0x41, 0x89, 0x54, 0x8c, 0xa3,
+    0xc2, 0xa1, 0x3d, 0x50, 0x65, 0xee, 0x12, 0x85, 0x81, 0x62, 0x6c, 0x2d,
+    0x62, 0x49, 0xdc, 0x65, 0x6d, 0xd2, 0x44, 0x5c, 0x1e, 0xcf, 0x3d, 0x5a,
+    0x62, 0xa4, 0xe5, 0x3e, 0xa5, 0x50, 0xa7, 0xd2, 0xdd, 0x49, 0xd2, 0x84,
+    0xbc, 0xd6, 0x95, 0x39, 0xcd, 0x82, 0x6f, 0x7b, 0xf1, 0xce, 0xe0, 0x7a,
+    0xe1, 0x83, 0x20, 0xbf, 0xd4, 0x0a, 0xad, 0x42, 0x4b, 0xd5, 0x6c, 0xe0,
+    0xf1, 0x66, 0x24, 0xe6, 0xee, 0xcb, 0x6d, 0x20, 0x02, 0x9b, 0x82, 0x52,
+    0xab, 0x0f, 0x4d, 0x88, 0xf7, 0xc1, 0x8c, 0xd5, 0x2e, 0x8a, 0x7a, 0x5d,
+    0x4e, 0x8b, 0x5b, 0x8e, 0xd2, 0xab, 0x06, 0xea, 0x50, 0x6d, 0x3b, 0xa1,
+    0xb2, 0xa3, 0xa0, 0x58, 0x7f, 0xcc, 0x50, 0xb5, 0x80, 0xdc, 0x83, 0xbe,
+    0x24, 0xbd, 0x36, 0xcc, 0x33, 0xb2, 0xcd, 0x54, 0x25, 0x42, 0x4a, 0x5a,
+    0x2e, 0x02, 0x96, 0xdc, 0x90, 0x4a, 0x55, 0x7d, 0x89, 0xb7, 0x04, 0x81,
+    0xff, 0x00, 0xd6, 0xf8, 0x54, 0xad, 0xe1, 0x4a, 0x6d, 0x38, 0x07, 0x19,
+    0x69, 0x20, 0x1b, 0xe4, 0x52, 0x2f, 0x96, 0xe0, 0xf2, 0x3b, 0x7d, 0x61,
+    0xaf, 0x0d, 0x62, 0x79, 0x8a, 0xb0, 0x52, 0x1c, 0x02, 0xe9, 0x09, 0xcc,
+    0x68, 0x4a, 0x85, 0xed, 0xa7, 0xf9, 0x0d, 0xc7, 0x8e, 0xd1, 0xd8, 0x64,
+    0xff, 0x00, 0xc5, 0xb4, 0xd3, 0x68, 0x05, 0x28, 0x0a, 0x5a, 0x92, 0x4f,
+    0xe5, 0x4b, 0x97, 0xb7, 0xe8, 0x71, 0x1a, 0xab, 0xfe, 0x21, 0x29, 0xd4,
+    0x7e, 0xa5, 0xce, 0xca, 0x35, 0xea, 0x64, 0x91, 0x09, 0x01, 0x05, 0x12,
+    0xda, 0x40, 0x50, 0x4e, 0xa1, 0xdd, 0x3c, 0xd8, 0x7a, 0xef, 0x8a, 0xc5,
+    0x36, 0xa9, 0x0e, 0x44, 0x84, 0xe8, 0x73, 0xfb, 0x59, 0x2c, 0x29, 0x4d,
+    0xa7, 0xbf, 0x65, 0x7f, 0xa1, 0xc7, 0x13, 0xf5, 0x06, 0x9b, 0x52, 0xac,
+    0xfe, 0x20, 0x6a, 0x90, 0x20, 0x45, 0x91, 0x2a, 0x5b, 0x8b, 0x6d, 0xb6,
+    0x19, 0x6c, 0x5d, 0x4b, 0xb2, 0x78, 0x1f, 0xbe, 0xfc, 0x0c, 0x21, 0x61,
+    0xb9, 0x66, 0xa7, 0xdb, 0xb3, 0xa7, 0x44, 0x2b, 0x43, 0x6b, 0x10, 0xb4,
+    0x81, 0xec, 0x77, 0xb8, 0xcc, 0xc1, 0xa7, 0xf8, 0x99, 0x48, 0x36, 0xce,
+    0xe0, 0x67, 0xc8, 0x85, 0x1f, 0xa6, 0xa2, 0x3a, 0x3b, 0x33, 0xe4, 0x8c,
+    0x85, 0xd4, 0x46, 0xda, 0xae, 0x52, 0xc4, 0x07, 0x64, 0x2e, 0xc0, 0x49,
+    0x61, 0x00, 0x2b, 0xe8, 0xbb, 0x6f, 0xbe, 0x14, 0xab, 0xb9, 0x30, 0x50,
+    0x22, 0xff, 0x00, 0x0f, 0xfe, 0x13, 0x18, 0x7c, 0x72, 0x96, 0xc0, 0x90,
+    0x41, 0x29, 0x41, 0x50, 0xb0, 0xbf, 0x1e, 0x5e, 0x76, 0xdb, 0xdc, 0xfa,
+    0xb5, 0xf4, 0xeb, 0x24, 0x53, 0x7a, 0x71, 0x45, 0x44, 0xe6};
+
+std::vector<uint8_t> l2cap_test_packet_4 = {
+    0xf6, 0x03, 0x47, 0x00, 0x08, 0xc1, 0x7a, 0xa1, 0x5b, 0xa8, 0x32, 0x89,
+    0xd3, 0x96, 0xda, 0xa5, 0x25, 0xb5, 0xf9, 0x1b, 0x08, 0x3a, 0x92, 0x80,
+    0x7f, 0x32, 0xb5, 0x5a, 0xea, 0xf6, 0xb0, 0xbe, 0x06, 0x75, 0x3e, 0xa9,
+    0x5a, 0xce, 0x51, 0xa1, 0xc3, 0xa7, 0xb0, 0x61, 0xc5, 0x5c, 0x80, 0x59,
+    0x52, 0x8d, 0x9c, 0x58, 0x48, 0x24, 0x1b, 0x7e, 0x54, 0xef, 0xdf, 0x72,
+    0x71, 0xda, 0x98, 0xf4, 0xe8, 0x9f, 0xec, 0xa5, 0x9d, 0x2e, 0x32, 0x35,
+    0xb8, 0xc8, 0x78, 0x03, 0xe9, 0xa6, 0xa7, 0x6b, 0x46, 0x87, 0xc3, 0x45,
+    0xae, 0x35, 0xa4, 0x5f, 0x9e, 0xff, 0x00, 0xbf, 0xa6, 0x9b, 0xc2, 0xfc,
+    0xa9, 0xf1, 0x13, 0x97, 0xbc, 0x4a, 0x32, 0x2e, 0xd4, 0x0b, 0xb4, 0xa0,
+    0x11, 0xa7, 0xcc, 0xd3, 0x89, 0x52, 0x94, 0x94, 0x8b, 0x00, 0x2f, 0x72,
+    0x3d, 0xb1, 0x36, 0xeb, 0x1c, 0x07, 0x28, 0xd3, 0x6b, 0xb4, 0xc9, 0x4e,
+    0x15, 0x25, 0x82, 0xb5, 0x31, 0xa4, 0xdd, 0x29, 0x4a, 0x9c, 0x43, 0xa9,
+    0x23, 0xfc, 0xaa, 0xfd, 0xf1, 0xbb, 0x2e, 0x55, 0x6a, 0x87, 0x1a, 0xbc,
+    0x89, 0x20, 0x29, 0x69, 0x63, 0x5a, 0x52, 0xb0, 0x6c, 0x51, 0xa1, 0x40,
+    0xf1, 0xea, 0x06, 0x06, 0x67, 0xc9, 0x92, 0x33, 0x14, 0x36, 0xe4, 0xcb,
+    0x5f, 0x8a, 0xec, 0x9a, 0x6c, 0x7b, 0xab, 0x48, 0x04, 0xff, 0x00, 0x62,
+    0x11, 0xfb, 0x14, 0xe2, 0xb3, 0x88, 0x78, 0x7f, 0x01, 0x26, 0xb3, 0xa8,
+    0x03, 0xe9, 0xfa, 0x46, 0x4f, 0x85, 0x0c, 0x3c, 0xa9, 0xba, 0xd4, 0xba,
+    0x45, 0xc2, 0xc5, 0xc5, 0xb5, 0xe2, 0xb1, 0xb7, 0xce, 0xde, 0x71, 0x36,
+    0xa6, 0x4b, 0xaa, 0xbf, 0x20, 0x98, 0xaf, 0x68, 0x69, 0xb4, 0xdf, 0x4d,
+    0xb6, 0xb0, 0xf6, 0xe4, 0x93, 0x87, 0x95, 0xaa, 0x38, 0xa5, 0x44, 0x4a,
+    0x81, 0xf8, 0xd4, 0xeb, 0x32, 0x1d, 0x1b, 0x21, 0x49, 0x36, 0x29, 0xb0,
+    0xf5, 0x1b, 0xdc, 0xfd, 0x30, 0x0f, 0x2d, 0xd1, 0xd3, 0x0d, 0xa6, 0xde,
+    0xa8, 0xb8, 0x12, 0xb0, 0x2f, 0x60, 0x0a, 0x83, 0x7b, 0x6f, 0x6b, 0x72,
+    0xac, 0x36, 0xd2, 0xa8, 0x46, 0xbb, 0x1e, 0x4c, 0xa8, 0x92, 0x22, 0xa0,
+    0x34, 0xc9, 0x71, 0xa6, 0x0b, 0xa1, 0x4a, 0x3d, 0xbc, 0xd6, 0x3b, 0x2b,
+    0x93, 0x7e, 0x01, 0xdb, 0x9c, 0x28, 0x4c, 0xad, 0x2e, 0x2a, 0xc8, 0x02,
+    0xdc, 0xe2, 0xc1, 0x46, 0x2f, 0x50, 0x25, 0x7f, 0x11, 0x50, 0x75, 0x5c,
+    0x4a, 0xff, 0x00, 0x16, 0xef, 0xa7, 0x5b, 0xe9, 0xd3, 0x6d, 0xf3, 0xc8,
+    0x6e, 0xf4, 0xff, 0x00, 0x3d, 0x4c, 0xca, 0xf9, 0x88, 0x7c, 0x2c, 0x1d,
+    0x46, 0x63, 0x29, 0x6c, 0xa4, 0x27, 0x40, 0xb2, 0x38, 0x59, 0xf5, 0x27,
+    0x7f, 0xd7, 0x1d, 0x08, 0xce, 0x65, 0x6e, 0xa7, 0x54, 0xa7, 0x4f, 0xac,
+    0xa6, 0x3c, 0x79, 0x29, 0x7e, 0x13, 0xc8, 0x49, 0x50, 0x05, 0x45, 0xd0,
+    0xa4, 0xad, 0x36, 0xfc, 0xdc, 0x03, 0x8e, 0x7d, 0x32, 0xa0, 0x57, 0xa9,
+    0x52, 0x6a, 0xeb, 0x52, 0x19, 0xaa, 0x46, 0x8a, 0x52, 0x96, 0xb4, 0x24,
+    0x2d, 0xc2, 0x15, 0xdf, 0xe8, 0x07, 0x1c, 0x91, 0xfa, 0x63, 0xa0, 0xf3,
+    0x25, 0x39, 0x0e, 0x51, 0x29, 0x12, 0xc2, 0x59, 0xb3, 0x52, 0x60, 0x91,
+    0x74, 0x0b, 0xdb, 0xc3, 0x3d, 0xff, 0x00, 0x4c, 0x14, 0xa5, 0x29, 0x69,
+    0x70, 0x24, 0x69, 0xcb, 0xce, 0x13, 0xa6, 0xa7, 0x45, 0x49, 0xf7, 0x5d,
+    0x75, 0x20, 0x29, 0x79, 0x65, 0xb0, 0xd2, 0xde, 0x62, 0x21, 0xff, 0x00,
+    0x88, 0xf6, 0x9b, 0xa9, 0x52, 0x2a, 0xb2, 0xa1, 0x21, 0x6d, 0x21, 0x55,
+    0x37, 0x96, 0xce, 0xa1, 0xa4, 0xe8, 0x52, 0xc1, 0xbe, 0x9e, 0xc2, 0xd7,
+    0xdb, 0x12, 0x9e, 0x9c, 0xd2, 0xe6, 0xd5, 0x5f, 0x31, 0xe1, 0x34, 0xeb,
+    0xce, 0xa9, 0x77, 0x5a, 0x95, 0xe6, 0x48, 0x48, 0x16, 0x25, 0x46, 0xf6,
+    0x03, 0x91, 0x8b, 0xa6, 0x64, 0xa0, 0x53, 0xb3, 0x35, 0x3e, 0x43, 0x55,
+    0x17, 0x8b, 0x4d, 0x25, 0xe2, 0xe2, 0x8a, 0x57, 0xa7, 0x6b, 0x9b, 0x8b,
+    0x8c, 0x20, 0x55, 0xf3, 0xad, 0x03, 0x2c, 0x43, 0x5e, 0x5a, 0xca, 0x8c,
+    0xc6, 0x6e, 0xc7, 0x77, 0xd1, 0x65, 0x24, 0x2b, 0xde, 0xff, 0x00, 0x3e,
+    0x29, 0x53, 0xb4, 0xa6, 0x9e, 0x71, 0x2f, 0xbc, 0xab, 0x21, 0x09, 0x00,
+    0xff, 0x00, 0x3f, 0x66, 0x3e, 0x6d, 0xa0, 0xe2, 0x09, 0xa6, 0xd8, 0x5c,
+    0x8c, 0x8b, 0x65, 0x4f, 0x95, 0xa8, 0xdf, 0xf2, 0xa4, 0x13, 0xaf, 0xcf,
+    0x28, 0x6c, 0x8e, 0xec, 0x2c, 0xa7, 0x0d, 0x98, 0xad, 0x3d, 0xfc, 0x46,
+    0xa5, 0x21, 0x21, 0xa4, 0x45, 0x8e, 0x92, 0x55, 0xb7, 0x01, 0x29, 0xf4,
+    0xdc, 0xf9, 0x8f, 0xfa, 0x63, 0xe2, 0xa1, 0x42, 0xcc, 0xf5, 0x67, 0x04,
+    0xfa, 0xac, 0x96, 0xd8, 0x75, 0x2b, 0x40, 0x6a, 0x1b, 0x67, 0x59, 0x66,
+    0xff, 0x00, 0x4f, 0x99, 0x7f, 0xb0, 0xf7, 0xc0, 0x8c, 0x9b, 0x51, 0xa7,
+    0x46, 0xa6, 0xaa, 0x5c, 0xe9, 0xaf, 0x3d, 0x52, 0x99, 0xaf, 0xc5, 0x74,
+    0x2e, 0xca, 0x52, 0x38, 0xb1, 0x3f, 0x30, 0x16, 0xbe, 0xc2, 0xc3, 0x7c,
+    0x51, 0x1e, 0xcd, 0xd4, 0xc5, 0x25, 0xa8, 0xca, 0x9d, 0x09, 0x98, 0xcd,
+    0xa5, 0xb6, 0x8a, 0x84, 0x93, 0xad, 0x56, 0x1c, 0x9b, 0x26, 0xfe, 0xbb,
+    0x8e, 0x6f, 0x85, 0xaa, 0x96, 0x21, 0x2a, 0x4f, 0xe1, 0xa4, 0xc7, 0x0a,
+    0x34, 0xbe, 0xe7, 0xa7, 0x21, 0xef, 0x0e, 0x94, 0x6c, 0x22, 0xdc, 0xab,
+    0x9f, 0x8d, 0x9d, 0x3d, 0xac, 0xc1, 0xcc, 0x93, 0x98, 0x1d, 0x07, 0x84,
+    0x44, 0x73, 0x33, 0xd3, 0xe9, 0x30, 0x26, 0x95, 0xbb, 0xe3, 0x04, 0xb6,
+    0x94, 0x3e, 0x82, 0x2d, 0x72, 0x97, 0x08, 0xbe, 0xde, 0x84, 0x1c, 0x51,
+    0xba, 0x0d, 0x3d, 0x72, 0x29, 0x25, 0x6c, 0x48, 0x5b, 0x5a, 0x96, 0x97,
+    0x2e, 0xa2, 0x12, 0x1b, 0x00, 0x8b, 0xf3, 0x7b, 0xdf, 0xb6, 0x17, 0xb3,
+    0x4c, 0x5a, 0x6d, 0x43, 0x2d, 0x66, 0x37, 0x20, 0xba, 0x99, 0x29, 0x44,
+    0x67, 0x9c, 0x2e, 0x24, 0x6c, 0x56, 0x97, 0x8a, 0xbf, 0xf8, 0xd8, 0xfd,
+    0xf1, 0xf5, 0xf8, 0x7d, 0x6c, 0x38, 0x66, 0x43, 0x4a, 0x1d, 0xf0, 0x8b,
+    0xc1, 0xd0, 0x7c, 0x3b, 0xa5, 0x28, 0xd3, 0x7b, 0x0b, 0x5f, 0xbe, 0xd6,
+    0x27, 0x1e, 0x63, 0x04, 0x36, 0x4b, 0x2e, 0xb7, 0xba, 0x47, 0xb4, 0x3e,
+    0xcf, 0xa5, 0x60, 0xa0, 0xab, 0x74, 0x88, 0x1f, 0x4d, 0x6a, 0x75, 0x5a,
+    0x85, 0x98, 0xe0, 0xb0, 0x94, 0x95, 0x49, 0x75, 0xb6, 0xc0, 0xe6, 0xc0,
+    0x5a, 0xdb, 0xfa, 0x5b, 0x9c, 0x13, 0xc9, 0xf5, 0xea, 0x5f, 0x4b, 0xa2,
+    0x4c, 0xa8, 0xc4, 0x9e, 0xc2, 0x6b, 0x13, 0x9b, 0x51, 0x54, 0x94, 0xb4,
+    0x16, 0xea, 0x49, 0x04, 0x14, 0xb6, 0x54, 0x3c, 0xa9, 0x17, 0xed, 0xb9,
+    0x3e, 0x98, 0x0f, 0x42, 0x62, 0xa9, 0x22, 0x74, 0xb8, 0x14, 0xe9, 0x11,
+    0x23, 0xc7, 0x92, 0xe0, 0x52, 0xca, 0x95, 0xa0, 0x71, 0x62, 0x9d, 0x86,
+    0xff, 0x00, 0x41, 0x6b, 0xf0, 0x4e, 0x08, 0x37, 0xd1, 0x25, 0x57, 0x67,
+    0x99, 0x55, 0x4c, 0xd8, 0xb5, 0xb8, 0xad, 0x92, 0x94, 0x37, 0xa7, 0x48,
+    0xec, 0x07, 0x60, 0x31, 0x96, 0x6b, 0x15, 0x52, 0x29, 0xf2, 0xad, 0x05,
+    0xaa, 0xee, 0x84, 0x81, 0xa1, 0x36, 0xc8, 0x5e, 0xff, 0x00, 0x7e, 0xd1,
+    0x3c, 0x6b, 0x0b, 0x55, 0xa7, 0x66, 0x5e, 0xba, 0xb8, 0x18, 0x52, 0xf8,
+    0xb2, 0x20, 0x15, 0x1d, 0xb3, 0xfb, 0xf3, 0x3a, 0xb0, 0x21};
+
+std::vector<uint8_t> l2cap_test_packet_5 = {
+    0xf6, 0x03, 0x47, 0x00, 0x0a, 0xc1, 0x0a, 0x8d, 0x2e, 0xa1, 0x99, 0xd9,
+    0x12, 0x98, 0xab, 0x13, 0x50, 0x64, 0x87, 0x9b, 0xf1, 0x1c, 0xb0, 0x48,
+    0xd4, 0x76, 0x1f, 0xdd, 0x1e, 0xa7, 0xe8, 0x37, 0xbe, 0x1b, 0xe9, 0x35,
+    0x68, 0x53, 0x99, 0x55, 0x32, 0x7c, 0x66, 0x51, 0x53, 0x41, 0x0e, 0x3c,
+    0xeb, 0x29, 0x1e, 0x1b, 0x8d, 0x95, 0x69, 0x0b, 0xd8, 0xec, 0x49, 0x3f,
+    0x4d, 0xb0, 0x73, 0x2e, 0xf4, 0x5f, 0x24, 0xd0, 0x90, 0xbf, 0x8e, 0xcd,
+    0x32, 0x8b, 0x65, 0x43, 0xc4, 0x02, 0x62, 0x12, 0x92, 0x47, 0xaf, 0x9a,
+    0xe7, 0xe9, 0x86, 0x58, 0x39, 0x6b, 0xa3, 0x14, 0x79, 0xc9, 0x9a, 0xe5,
+    0x4a, 0x13, 0xb2, 0xda, 0x01, 0x21, 0xc7, 0x65, 0xeb, 0xb0, 0x1c, 0x6c,
+    0x4e, 0x9b, 0x62, 0x73, 0x52, 0xc5, 0xcd, 0x4d, 0x3a, 0x57, 0xc2, 0xb5,
+    0x93, 0xc9, 0x3f, 0xc6, 0x50, 0xf7, 0x23, 0x4e, 0x44, 0xab, 0x61, 0xb6,
+    0x80, 0x00, 0x6c, 0x9f, 0xd8, 0x6b, 0xce, 0x1b, 0x24, 0x43, 0x99, 0x1a,
+    0x65, 0x00, 0x38, 0xb5, 0x29, 0x25, 0xa5, 0xb4, 0xbb, 0x7a, 0xea, 0x40,
+    0xfe, 0x98, 0xf0, 0xae, 0xcd, 0xc9, 0x3d, 0x32, 0x7a, 0xa7, 0x99, 0x24,
+    0x31, 0x09, 0x35, 0x49, 0x48, 0x4a, 0x65, 0xc9, 0x2b, 0x25, 0xd2, 0x81,
+    0xc2, 0x4a, 0xbf, 0x28, 0x3f, 0xdc, 0x4e, 0xe4, 0xf3, 0x7c, 0x22, 0x75,
+    0xaf, 0xad, 0x59, 0x7e, 0x9b, 0x0e, 0x9f, 0x13, 0x2c, 0x4c, 0x6e, 0x6c,
+    0xf2, 0xfa, 0x34, 0xe8, 0x21, 0xd0, 0x11, 0xbe, 0xa2, 0x42, 0x4d, 0xf7,
+    0xd8, 0x0e, 0x09, 0x3c, 0x71, 0x88, 0xd6, 0x70, 0xcd, 0x31, 0xf3, 0x25,
+    0x41, 0x2e, 0xd5, 0x68, 0x95, 0x29, 0xe9, 0x4a, 0x8a, 0xc3, 0x0b, 0x49,
+    0x4a, 0x50, 0xa3, 0xed, 0xdc, 0xf6, 0xb9, 0xdf, 0x18, 0xf0, 0xa6, 0x0d,
+    0xa8, 0x55, 0x07, 0x6a, 0xb5, 0x76, 0x4d, 0xd8, 0x85, 0x0c, 0xee, 0x41,
+    0x37, 0xb5, 0xad, 0xa1, 0xf1, 0xcb, 0x2d, 0xe3, 0xde, 0xa9, 0x5b, 0x6a,
+    0x59, 0x09, 0x41, 0x69, 0x4e, 0x2f, 0x50, 0x00, 0x16, 0xbe, 0xd7, 0x37,
+    0xca, 0xc3, 0x61, 0x99, 0xbe, 0xd0, 0xe3, 0x37, 0xac, 0xc9, 0xcd, 0xb9,
+    0x8d, 0x72, 0x65, 0xca, 0x8d, 0x1a, 0x9f, 0x1d, 0xc0, 0x98, 0xa8, 0x20,
+    0x0d, 0x42, 0xe4, 0x03, 0x63, 0xb8, 0x16, 0x37, 0xb7, 0x3f, 0xd0, 0x3d,
+    0x2b, 0xa9, 0x52, 0xa8, 0xb5, 0x1b, 0xc2, 0x9e, 0xa9, 0x3e, 0x0a, 0xac,
+    0xea, 0x96, 0x92, 0xef, 0x8e, 0x02, 0x48, 0xb6, 0xc3, 0x6d, 0xcf, 0x3e,
+    0xc3, 0x1e, 0x39, 0x2a, 0x3c, 0x19, 0xad, 0x95, 0x46, 0xc8, 0xae, 0xb0,
+    0x11, 0x75, 0x17, 0x9d, 0x6d, 0x94, 0x22, 0xd7, 0xb5, 0xb5, 0x38, 0x40,
+    0xf6, 0xe4, 0x9f, 0x6c, 0x13, 0x55, 0x4e, 0xbe, 0x89, 0x0e, 0xb1, 0x0b,
+    0x25, 0x25, 0xf0, 0xcb, 0xab, 0x6c, 0x3a, 0xd8, 0x6d, 0x68, 0x5d, 0xb7,
+    0xd8, 0xa4, 0xd8, 0xd8, 0x11, 0x72, 0x0d, 0xb1, 0x5d, 0x63, 0x05, 0xca,
+    0xa1, 0x29, 0x42, 0x5c, 0xb0, 0x1a, 0x00, 0x3f, 0x7b, 0xf9, 0x98, 0x4a,
+    0xfe, 0xb9, 0x5b, 0x71, 0xc2, 0x96, 0xa4, 0x14, 0xa2, 0x79, 0xe5, 0x97,
+    0x90, 0xb5, 0xba, 0x46, 0xf3, 0x75, 0x37, 0x73, 0x65, 0x1e, 0xb1, 0x53,
+    0x96, 0xd2, 0x51, 0x25, 0xe8, 0x2a, 0x43, 0x89, 0x4b, 0x6a, 0x4e, 0xe1,
+    0xb2, 0x01, 0x37, 0xee, 0x7f, 0x7b, 0x13, 0x8d, 0x2a, 0xad, 0x06, 0xac,
+    0xed, 0x0f, 0x2f, 0xcd, 0x85, 0x49, 0x95, 0x22, 0x3b, 0xb4, 0xb6, 0x42,
+    0x5c, 0x61, 0xa5, 0x2c, 0x13, 0xa4, 0x13, 0x7b, 0x0d, 0x8d, 0xcf, 0x7c,
+    0x7d, 0x48, 0x77, 0xa8, 0xd2, 0xe9, 0xef, 0xf8, 0x39, 0x6d, 0x2c, 0xc7,
+    0x28, 0x50, 0x71, 0x20, 0x04, 0xdd, 0x36, 0xdc, 0x12, 0x2e, 0x78, 0xf4,
+    0xdf, 0x1e, 0x1d, 0x31, 0xce, 0x99, 0xaa, 0x9b, 0x96, 0xc5, 0x39, 0xfa,
+    0xb5, 0x3a, 0x0e, 0x95, 0xa9, 0xa6, 0x93, 0xf1, 0x0a, 0x42, 0x96, 0x80,
+    0x4d, 0xb5, 0x24, 0x0b, 0x0b, 0x5e, 0xc0, 0x92, 0x36, 0x03, 0x1a, 0xeb,
+    0xf4, 0xd0, 0xe4, 0xa3, 0x52, 0xa8, 0x24, 0xf0, 0xee, 0x6c, 0x32, 0x1c,
+    0xc9, 0xb0, 0x83, 0x38, 0x0e, 0x7a, 0xa5, 0x86, 0x2a, 0x53, 0x35, 0x2a,
+    0x8b, 0x25, 0x01, 0xdd, 0x12, 0x02, 0x95, 0x9f, 0x44, 0x82, 0x72, 0x19,
+    0xe9, 0x68, 0x13, 0x23, 0x20, 0x67, 0x9a, 0xa2, 0xd2, 0x5a, 0xa5, 0xaa,
+    0x24, 0x72, 0x6c, 0x16, 0xf1, 0xd3, 0x72, 0x76, 0x16, 0xc3, 0x36, 0x42,
+    0xe9, 0x8e, 0x68, 0xa5, 0x3a, 0xec, 0x31, 0x5e, 0xa2, 0x35, 0x2a, 0x45,
+    0x99, 0x0d, 0xf8, 0xda, 0x9c, 0x4a, 0xb7, 0x16, 0x00, 0x7e, 0x6d, 0xef,
+    0xf5, 0x03, 0x04, 0x17, 0x54, 0xcc, 0x09, 0x74, 0x3e, 0xac, 0xcd, 0x1d,
+    0x85, 0x83, 0xa8, 0x29, 0x0b, 0x2a, 0x50, 0xf7, 0x1e, 0x71, 0x8d, 0x79,
+    0xf9, 0x8e, 0xb7, 0xf0, 0x4e, 0xd3, 0x0e, 0x64, 0x68, 0xb6, 0xe5, 0xd0,
+    0xa9, 0xa1, 0xd8, 0xed, 0xad, 0x77, 0x37, 0x2a, 0xb6, 0x92, 0xb2, 0x77,
+    0x3c, 0xaa, 0xfe, 0xf8, 0x0a, 0xde, 0x16, 0x9c, 0x29, 0xe0, 0x20, 0x01,
+    0xd4, 0x7d, 0x2f, 0x05, 0x2a, 0xbf, 0x13, 0xe8, 0x73, 0x93, 0x05, 0xd2,
+    0x54, 0xe2, 0x8f, 0x81, 0x00, 0x0f, 0x00, 0x48, 0x19, 0x72, 0xd4, 0xc1,
+    0x8c, 0xbf, 0xd0, 0xc9, 0x10, 0xa5, 0x2e, 0x54, 0x9c, 0xe1, 0x19, 0x84,
+    0xa9, 0x65, 0x4a, 0x07, 0x65, 0x13, 0xde, 0xfa, 0xad, 0x7d, 0xfd, 0x71,
+    0x4a, 0xcf, 0x79, 0x96, 0x83, 0x46, 0xca, 0xb1, 0x62, 0xbb, 0x5c, 0x8b,
+    0x29, 0xf8, 0xcf, 0x32, 0xe2, 0xfc, 0x35, 0x02, 0x43, 0x6d, 0x24, 0xdd,
+    0x4a, 0xb6, 0xc3, 0xf2, 0x8d, 0xf9, 0x27, 0x10, 0x77, 0x17, 0x45, 0xf1,
+    0x94, 0x26, 0x66, 0xb9, 0x4f, 0xac, 0x9e, 0x4a, 0x91, 0x73, 0xf7, 0xb1,
+    0xc7, 0xb5, 0x7b, 0x2a, 0x51, 0x6a, 0x79, 0x3e, 0x5c, 0xc8, 0x95, 0x19,
+    0xcf, 0xa9, 0xa4, 0xeb, 0xb2, 0x9f, 0x51, 0x06, 0xde, 0xa3, 0x83, 0x82,
+    0xac, 0xe1, 0xa9, 0x86, 0x7b, 0xe9, 0x29, 0xe2, 0xea, 0x4f, 0xd2, 0x03,
+    0x2f, 0xe2, 0x75, 0x19, 0xa7, 0x12, 0x7b, 0x27, 0x2d, 0x71, 0x6e, 0xe8,
+    0x02, 0xfb, 0x5c, 0xdc, 0x9b, 0x40, 0x2c, 0xcf, 0x57, 0xa5, 0xc9, 0x6e,
+    0x75, 0x35, 0x55, 0xa5, 0xb1, 0x19, 0xc7, 0x54, 0x7c, 0x26, 0x93, 0x7b,
+    0x79, 0x89, 0xb0, 0x3b, 0x6d, 0x85, 0x08, 0xd4, 0x6c, 0xa4, 0xf4, 0x84,
+    0x80, 0x9a, 0x9c, 0x85, 0x13, 0x62, 0xb2, 0xda, 0x95, 0xfa, 0x01, 0x8e,
+    0x87, 0x43, 0xf1, 0x29, 0x61, 0x8a, 0x76, 0x5c, 0xc9, 0xf4, 0x09, 0x50,
+    0x62, 0x46, 0x6c, 0x27, 0xc6, 0x6c, 0xba, 0xe3, 0xde, 0x51, 0xa9, 0x45,
+    0x77, 0xe4, 0x9b, 0xf0, 0x0f, 0xdf, 0x18, 0xff, 0x00, 0x54, 0x59, 0xa4,
+    0x7f, 0x66, 0x3a, 0x74, 0xc4, 0x37, 0x00, 0xf9, 0xda, 0x4a, 0x54, 0x01,
+    0xf6, 0xf2, 0x7f, 0xa8, 0x18, 0x2d, 0x3f, 0x3d, 0x34, 0x5b, 0x4a, 0x9e,
+    0x65, 0x27, 0xc8, 0x9b, 0x75, 0x17, 0xfa, 0x43, 0xf4, 0xae, 0x1a, 0x69,
+    0x94, 0x87, 0x99, 0x96, 0x48, 0x0b, 0xef, 0x1b, 0x01, 0xbe, 0xe7, 0x33,
+    0x6f, 0x41, 0x12, 0x68, 0xb9, 0x4d, 0x86, 0x23, 0x7c, 0x44, 0x6a, 0x0d,
+    0x5a, 0x53, 0x62, 0xca, 0xf2, 0xc5, 0x74, 0x5c, 0x7d, 0x54, 0x9b, 0x71,
+    0xef, 0x82, 0xf0, 0x32, 0x95, 0x69, 0x6f, 0x29, 0x11, 0xb2, 0x24, 0x97,
+    0xd2, 0x4d, 0xd2, 0x5f, 0x6c, 0xa4, 0xe9, 0x3c, 0x96, 0xae};
+
+std::vector<uint8_t> l2cap_test_packet_6 = {
+    0xf6, 0x03, 0x47, 0x00, 0x0c, 0xc1, 0x5c, 0x0b, 0x8c, 0x33, 0x2b, 0xac,
+    0x14, 0x79, 0x95, 0x37, 0x6a, 0x2b, 0xca, 0x2e, 0xbb, 0x31, 0x0b, 0x4b,
+    0x8a, 0x2a, 0x71, 0xd2, 0x02, 0xbb, 0x10, 0x92, 0x42, 0x47, 0x1c, 0x01,
+    0x82, 0x8b, 0xeb, 0x4e, 0x66, 0x76, 0x58, 0x71, 0x14, 0xe9, 0x11, 0x12,
+    0xf0, 0xd4, 0x35, 0x35, 0x74, 0xda, 0xc3, 0x72, 0x49, 0x36, 0xda, 0xdc,
+    0xe1, 0x69, 0x58, 0x8d, 0x6d, 0x9e, 0xe8, 0x48, 0xe8, 0x91, 0x1d, 0x84,
+    0xc2, 0x19, 0x3c, 0x29, 0x09, 0x1e, 0x9f, 0x40, 0x60, 0x2b, 0x99, 0x1f,
+    0xa9, 0x12, 0x68, 0x52, 0xa0, 0xc4, 0xa0, 0xc3, 0xa7, 0x46, 0x76, 0x3a,
+    0xdb, 0x5a, 0x02, 0x14, 0x14, 0xa4, 0x11, 0xba, 0x45, 0xc5, 0x85, 0xfd,
+    0x70, 0x13, 0xa5, 0xd9, 0x39, 0xd8, 0xcb, 0xf0, 0x5a, 0x9d, 0x32, 0x9a,
+    0xea, 0xd6, 0x59, 0x90, 0x1a, 0x59, 0x2a, 0x4a, 0xfd, 0x2c, 0x38, 0xb5,
+    0xb1, 0xd1, 0x7d, 0x1c, 0xcd, 0x33, 0xb3, 0x35, 0x0d, 0xea, 0x9c, 0x97,
+    0x94, 0xb2, 0xd4, 0xa2, 0xc3, 0x8d, 0xad, 0x20, 0x8b, 0x69, 0x06, 0xe0,
+    0x81, 0xf5, 0x18, 0x8b, 0xe7, 0x5f, 0x8a, 0xa4, 0x75, 0x36, 0xac, 0x23,
+    0xad, 0x49, 0x40, 0x9e, 0x56, 0x50, 0xa2, 0x40, 0x20, 0x80, 0x47, 0x18,
+    0x15, 0x58, 0x9f, 0x76, 0x71, 0xa4, 0xba, 0xb5, 0x5c, 0x79, 0x0f, 0xbd,
+    0x20, 0x7c, 0xea, 0xbf, 0x11, 0x72, 0x75, 0x1f, 0x28, 0x97, 0x3a, 0xc5,
+    0x52, 0xb5, 0x29, 0x70, 0x68, 0xb2, 0xdc, 0x8f, 0x31, 0x0d, 0x97, 0x95,
+    0xe1, 0x91, 0x7d, 0xd4, 0x76, 0xbd, 0xf6, 0xb5, 0xb9, 0xde, 0xfb, 0x61,
+    0x36, 0xb9, 0xfc, 0xcf, 0x47, 0x7c, 0xb5, 0x57, 0x7e, 0xb3, 0xc6, 0xea,
+    0x4c, 0x85, 0x14, 0x1f, 0xdf, 0x0d, 0x9d, 0x3b, 0x8f, 0x36, 0x99, 0x9b,
+    0xeb, 0x4b, 0x1a, 0x89, 0x6a, 0x31, 0xb1, 0x4f, 0x3a, 0x49, 0x2b, 0xb8,
+    0x27, 0xd8, 0x7e, 0xa7, 0x1e, 0x39, 0x6b, 0xa9, 0x5f, 0x1c, 0xfb, 0xb1,
+    0x6b, 0xd1, 0x14, 0xe2, 0x5c, 0x73, 0x50, 0x79, 0xb4, 0xa5, 0x6a, 0x48,
+    0x1c, 0x02, 0x95, 0x6c, 0xa0, 0x2f, 0xc6, 0x1b, 0xa9, 0x32, 0xf2, 0x32,
+    0xf2, 0x4d, 0xad, 0x49, 0x4f, 0x12, 0xaf, 0x9a, 0x80, 0x39, 0xf9, 0xe9,
+    0x12, 0x49, 0xfa, 0xa5, 0x4c, 0x4f, 0xbc, 0x86, 0x87, 0x1b, 0x68, 0xb6,
+    0x40, 0xd8, 0x8b, 0xf2, 0x84, 0x96, 0xaa, 0xce, 0xc8, 0x64, 0xc4, 0x65,
+    0x87, 0x54, 0xca, 0xc5, 0x94, 0x84, 0xb2, 0x92, 0x55, 0xbd, 0xcf, 0x98,
+    0xdc, 0xfe, 0xf8, 0xd9, 0x4b, 0xae, 0x34, 0x14, 0xf2, 0xe8, 0x0c, 0x21,
+    0x29, 0xdc, 0xf8, 0x82, 0xc7, 0xf4, 0xbe, 0x2a, 0xa7, 0x28, 0xb1, 0x2d,
+    0x46, 0xab, 0x95, 0xaa, 0x10, 0x52, 0xf2, 0x95, 0xe2, 0xa5, 0xa4, 0x37,
+    0x76, 0xaf, 0x6e, 0x34, 0x9d, 0xc7, 0xaf, 0xd7, 0x08, 0x35, 0x18, 0xf2,
+    0x20, 0xd4, 0x16, 0xc5, 0x5d, 0x2a, 0x65, 0xf0, 0x8b, 0x8f, 0x35, 0xc1,
+    0xed, 0xa8, 0x11, 0xee, 0x38, 0xc7, 0x5a, 0x85, 0x4e, 0xa9, 0x4f, 0x1c,
+    0x69, 0x42, 0x78, 0x79, 0x81, 0xf7, 0x6f, 0x94, 0x68, 0xa3, 0xcc, 0x53,
+    0x6a, 0xaa, 0x2d, 0xa5, 0x44, 0x2f, 0x74, 0x9b, 0x83, 0xe3, 0xd6, 0x19,
+    0xfa, 0x3f, 0x06, 0x8b, 0x5b, 0xcf, 0xf4, 0x09, 0x4f, 0xc0, 0x43, 0x5e,
+    0x12, 0x1d, 0x79, 0x2d, 0xa1, 0x45, 0x20, 0xba, 0x84, 0x9d, 0x17, 0x23,
+    0x7b, 0x03, 0x63, 0xf6, 0xb6, 0x3a, 0x0e, 0xbb, 0xd3, 0xa6, 0x44, 0x24,
+    0x0c, 0xbd, 0x3d, 0xba, 0x6c, 0xb2, 0xd8, 0x21, 0xb5, 0x30, 0x85, 0xa1,
+    0x47, 0xd4, 0x02, 0x2e, 0x2f, 0xed, 0x8e, 0x7e, 0xfc, 0x3c, 0x32, 0xb7,
+    0xb3, 0xe5, 0x27, 0x72, 0xa4, 0x21, 0x52, 0x75, 0x90, 0x3e, 0x54, 0xe8,
+    0x51, 0xfe, 0x98, 0x6c, 0xfc, 0x47, 0xe7, 0xdc, 0xd7, 0x94, 0xb3, 0xed,
+    0x1d, 0xda, 0x05, 0x5d, 0x71, 0xdb, 0x11, 0x0a, 0x8b, 0x7a, 0x02, 0x9b,
+    0x76, 0xe4, 0x6c, 0xb4, 0x91, 0xb8, 0xed, 0x89, 0xee, 0x39, 0x99, 0xaa,
+    0xb9, 0x88, 0xd8, 0x44, 0x8b, 0xe5, 0xb2, 0x5a, 0x0a, 0xf0, 0xdf, 0x23,
+    0xcf, 0x6d, 0x61, 0xef, 0x0d, 0x38, 0xdc, 0x9d, 0x35, 0xc5, 0x9f, 0xca,
+    0xb2, 0x0e, 0xe6, 0xd7, 0x00, 0x7c, 0xe0, 0x1f, 0x50, 0x8f, 0x55, 0xf2,
+    0xa3, 0xaa, 0x45, 0x4a, 0x04, 0x79, 0xb0, 0x55, 0xb8, 0x91, 0x19, 0x8d,
+    0x4d, 0xaa, 0xde, 0xa3, 0x80, 0x47, 0xd3, 0x09, 0xea, 0xae, 0xf5, 0x11,
+    0x6d, 0xa5, 0xc7, 0x1c, 0x99, 0x15, 0xbd, 0x65, 0x01, 0x49, 0x8b, 0xa0,
+    0x6a, 0xb5, 0xf4, 0x8b, 0x27, 0x9d, 0x8f, 0xe9, 0x8b, 0x87, 0x4c, 0xba,
+    0xd9, 0x4b, 0xce, 0x4d, 0xff, 0x00, 0x07, 0xcc, 0x94, 0x71, 0x16, 0x72,
+    0x80, 0x05, 0x6d, 0x5d, 0x71, 0xdd, 0x27, 0x61, 0x71, 0xc8, 0x37, 0x3d,
+    0xef, 0xcf, 0x38, 0x79, 0x9f, 0x93, 0x8c, 0x58, 0x4e, 0xd4, 0x68, 0xf2,
+    0x4b, 0x4c, 0xdb, 0x53, 0x8c, 0x2c, 0x6a, 0x09, 0x23, 0x6f, 0x29, 0x3b,
+    0x8f, 0x4f, 0xbe, 0x04, 0x9c, 0x77, 0x52, 0x92, 0x58, 0x97, 0xa9, 0xdd,
+    0x2a, 0xe6, 0x0e, 0x47, 0xd2, 0x0e, 0x25, 0x2e, 0x4c, 0x27, 0x8d, 0xa7,
+    0x8d, 0x8e, 0xd7, 0xb7, 0x95, 0xf5, 0xf5, 0xf5, 0x89, 0x1f, 0x47, 0xa4,
+    0x67, 0x06, 0x27, 0x4a, 0x35, 0xc7, 0x25, 0x86, 0xd4, 0xd1, 0x08, 0xf1,
+    0x52, 0x52, 0x1c, 0xba, 0x55, 0x71, 0xbf, 0xd0, 0x1f, 0xbe, 0x00, 0xaf,
+    0x5c, 0xa8, 0x5a, 0x94, 0x10, 0x5a, 0x84, 0xcb, 0x81, 0x5c, 0x27, 0x48,
+    0xf1, 0xd4, 0x3e, 0xe4, 0x95, 0x7b, 0x9f, 0xd3, 0x14, 0x2f, 0xe6, 0xaa,
+    0x6d, 0x4d, 0x6c, 0xd3, 0xdb, 0x42, 0x5a, 0x79, 0x32, 0x1d, 0x2a, 0x4a,
+    0x2e, 0x92, 0x2c, 0x40, 0xb6, 0xae, 0x49, 0xb0, 0xb9, 0x3e, 0xf8, 0x47,
+    0xcc, 0xb4, 0xc3, 0x4a, 0x6d, 0x6b, 0x2e, 0x25, 0xc2, 0xe4, 0xa7, 0xc1,
+    0x08, 0xb8, 0x03, 0x4b, 0xa4, 0xff, 0x00, 0xa1, 0x18, 0x6f, 0xa9, 0xce,
+    0x2e, 0x6a, 0x8a, 0xda, 0x9c, 0x37, 0x25, 0x47, 0xdb, 0xf9, 0x87, 0x1c,
+    0x20, 0xa3, 0xda, 0x25, 0xc3, 0x9a, 0x80, 0x56, 0xb9, 0x9d, 0xb7, 0x85,
+    0x77, 0xe9, 0xb4, 0xfa, 0xab, 0x28, 0x11, 0xe7, 0x2e, 0x39, 0x24, 0x85,
+    0xad, 0x06, 0xc1, 0x06, 0xfe, 0xd7, 0xfb, 0xed, 0x82, 0x39, 0x17, 0x2c,
+    0xd0, 0xd9, 0x9e, 0xf4, 0x3c, 0xcf, 0x54, 0x5f, 0x88, 0xbb, 0x18, 0x8b,
+    0x5b, 0xc4, 0xb6, 0xbd, 0xf9, 0x0a, 0x1d, 0xfd, 0xb6, 0xf4, 0xb6, 0x25,
+    0x94, 0xb9, 0x92, 0x62, 0x49, 0x75, 0xd8, 0xce, 0xa9, 0xb5, 0x29, 0xc5,
+    0x6d, 0x7d, 0xb9, 0x3b, 0x1c, 0x51, 0x28, 0x4e, 0x48, 0xaa, 0xd2, 0x5e,
+    0x79, 0xf8, 0xbe, 0x46, 0x52, 0x95, 0x2c, 0x84, 0xdd, 0x04, 0x15, 0x69,
+    0xe7, 0xd6, 0xfd, 0xb0, 0x15, 0xd3, 0x31, 0x2c, 0x9b, 0x71, 0x92, 0x9e,
+    0xb0, 0x2a, 0x5d, 0x9a, 0x26, 0x2b, 0x50, 0x2a, 0x68, 0x31, 0x30, 0xad,
+    0xc0, 0x04, 0x28, 0xfb, 0x67, 0xd7, 0x3f, 0x13, 0x15, 0xe8, 0x99, 0x07,
+    0x2d, 0x48, 0x6d, 0x0d, 0xc5, 0x61, 0x12, 0xdc, 0x5b, 0x6e, 0x5d, 0xa5,
+    0x2f, 0xec, 0x13, 0xb8, 0x3c, 0x1b, 0x0d, 0xf7, 0xbd, 0xce, 0x05, 0xc1,
+    0xa4, 0x39, 0x43, 0xca, 0x15, 0x0a, 0x3b, 0xad, 0x84, 0x2e, 0x3b, 0x6f,
+    0xb4, 0x42, 0x56, 0x5c, 0x06, 0xc5, 0x44, 0x79, 0xac, 0x2e, 0x34, 0xdb,
+    0x7b, 0x0c, 0x2b, 0x65, 0x9a, 0xcd, 0x47, 0x2d, 0x54, 0x92};
+
+std::vector<uint8_t> l2cap_test_packet_7 = {
+    0xf6, 0x03, 0x47, 0x00, 0x0e, 0xc1, 0xa0, 0xaa, 0x33, 0xea, 0x72, 0x1b,
+    0xab, 0xb2, 0xa3, 0xea, 0x1a, 0xae, 0x3c, 0xd7, 0x07, 0xe6, 0xb5, 0xff,
+    0x00, 0xec, 0x61, 0xd2, 0x7e, 0x67, 0x6b, 0x30, 0x49, 0x9a, 0xb0, 0x9f,
+    0x04, 0x2c, 0x36, 0x1f, 0xb6, 0xc0, 0x21, 0x68, 0x20, 0x8d, 0xb8, 0xb5,
+    0xb0, 0xc7, 0x84, 0x66, 0x82, 0xa7, 0x14, 0x39, 0xa4, 0xfd, 0x22, 0x3f,
+    0xf1, 0x5f, 0x0e, 0xcc, 0x52, 0x24, 0xd0, 0xdb, 0x80, 0x1b, 0x2d, 0x26,
+    0xe3, 0x96, 0x63, 0xe7, 0x1a, 0xf4, 0xf9, 0xb2, 0xe3, 0xe5, 0xb9, 0x2f,
+    0xb6, 0x99, 0x09, 0x53, 0x71, 0xf4, 0x25, 0xc4, 0x70, 0x8b, 0x2b, 0x7b,
+    0xff, 0x00, 0x97, 0xd3, 0x08, 0x59, 0x5f, 0xab, 0x71, 0xd2, 0xa5, 0xc5,
+    0xae, 0x53, 0x64, 0x25, 0xbd, 0x56, 0xf8, 0x86, 0x5e, 0x2a, 0x5a, 0x2c,
+    0x6f, 0x7b, 0x1e, 0x37, 0xdf, 0x6c, 0x58, 0xd2, 0xdd, 0x2e, 0xa5, 0xd2,
+    0x9a, 0x1f, 0xf0, 0xc2, 0xcf, 0xc5, 0xae, 0x0b, 0xc2, 0x62, 0x19, 0xf9,
+    0x8d, 0xd3, 0xb2, 0x96, 0x3e, 0xa9, 0xef, 0x8e, 0x46, 0x7d, 0x6b, 0x8b,
+    0x52, 0x93, 0x09, 0xc4, 0x95, 0xa1, 0x0f, 0xad, 0x36, 0x1c, 0xde, 0xe4,
+    0x6d, 0x83, 0x75, 0x4a, 0x93, 0xe8, 0x29, 0x71, 0xbc, 0xb6, 0x3e, 0x36,
+    0x8a, 0x83, 0xd5, 0xe9, 0x96, 0x29, 0xb2, 0x4e, 0xb2, 0x78, 0x41, 0x4d,
+    0x88, 0x23, 0x5b, 0x00, 0x05, 0xf7, 0xd8, 0xe9, 0x1d, 0x04, 0xec, 0xac,
+    0xbb, 0x9a, 0xa0, 0xae, 0x45, 0x3a, 0xb4, 0x15, 0x2d, 0xb2, 0x16, 0xd1,
+    0x69, 0x94, 0xb6, 0xf2, 0x8d, 0xff, 0x00, 0x38, 0xb5, 0x96, 0x07, 0x3c,
+    0x5f, 0x1f, 0x12, 0x8e, 0x69, 0x0d, 0x33, 0x26, 0xa0, 0x83, 0x52, 0x84,
+    0x96, 0xf4, 0x78, 0x91, 0xd0, 0x94, 0x92, 0x9b, 0x8f, 0x99, 0x36, 0xb1,
+    0xe3, 0x8d, 0xb0, 0x1f, 0xa4, 0x19, 0x3e, 0x7c, 0x69, 0x10, 0xf3, 0x0b,
+    0x8c, 0x7c, 0x38, 0x68, 0x97, 0x63, 0xb0, 0xf1, 0xf3, 0xba, 0x46, 0xe0,
+    0x1e, 0x39, 0xf4, 0xed, 0x83, 0x15, 0xac, 0xf6, 0xed, 0x26, 0x24, 0x88,
+    0x34, 0x94, 0xaf, 0xc6, 0xd4, 0x4b, 0xcb, 0x6d, 0x37, 0xd1, 0x7d, 0xac,
+    0x3d, 0xf9, 0xdb, 0x9c, 0x63, 0x5c, 0x8c, 0xac, 0xcc, 0xa9, 0x76, 0x75,
+    0x01, 0xbe, 0x56, 0xca, 0xfe, 0x50, 0xc0, 0xd2, 0x18, 0x9a, 0x94, 0x33,
+    0x33, 0xcd, 0x04, 0x11, 0xbd, 0xed, 0x97, 0x80, 0xd7, 0xa0, 0xb1, 0x31,
+    0x7b, 0xe9, 0x12, 0xe8, 0xec, 0xe5, 0x1b, 0xd3, 0x65, 0x25, 0x2b, 0x7e,
+    0x38, 0x94, 0xb2, 0xa5, 0x15, 0x0b, 0x8d, 0x8d, 0xc6, 0xd6, 0x20, 0x1d,
+    0xc0, 0xe0, 0x8c, 0x47, 0xfa, 0xd7, 0x35, 0x11, 0x33, 0xed, 0x55, 0xe7,
+    0x8b, 0x6a, 0xd4, 0x84, 0xb8, 0x46, 0xab, 0x0b, 0x80, 0x47, 0xef, 0x6c,
+    0x6c, 0xf4, 0x0a, 0x53, 0xf3, 0xe4, 0xd4, 0x59, 0xbc, 0x86, 0x5b, 0x4c,
+    0x72, 0xd8, 0x4b, 0xbb, 0x06, 0xf5, 0x21, 0x57, 0x1f, 0x5b, 0x81, 0x7c,
+    0x2a, 0x7e, 0x26, 0x9b, 0x7e, 0x36, 0x64, 0x8b, 0xe6, 0x4b, 0xa8, 0x98,
+    0xd2, 0x3c, 0xac, 0x82, 0xa2, 0xa0, 0x9b, 0x77, 0x23, 0x6d, 0xf7, 0xc2,
+    0x83, 0xbc, 0x0b, 0x68, 0x34, 0x9d, 0x02, 0xb2, 0xe9, 0x09, 0xce, 0x80,
+    0x86, 0x94, 0xb4, 0x1b, 0x8b, 0x9d, 0x75, 0xb5, 0xf2, 0x8d, 0x18, 0x68,
+    0x47, 0xf3, 0x58, 0x60, 0x04, 0x24, 0x96, 0x46, 0xab, 0xaa, 0xdb, 0x59,
+    0x69, 0x23, 0x7e, 0xe4, 0xf6, 0x18, 0x8c, 0x65, 0x88, 0x92, 0xe5, 0xd7,
+    0xfe, 0x12, 0x23, 0x0b, 0x79, 0xd5, 0x28, 0xa7, 0x4a, 0x47, 0xbf, 0xed,
+    0x8b, 0x58, 0x8b, 0x1d, 0x59, 0xe9, 0xb6, 0xd6, 0xa0, 0xd2, 0x1c, 0x80,
+    0x95, 0x6c, 0x6c, 0x51, 0xe6, 0x26, 0xff, 0x00, 0x6e, 0x70, 0x0e, 0xa7,
+    0x99, 0x72, 0xbe, 0x49, 0x79, 0xf6, 0x29, 0x30, 0x99, 0x9c, 0xe3, 0xaa,
+    0xd6, 0xe0, 0x4a, 0x8a, 0x75, 0x2b, 0x7b, 0x82, 0x46, 0xf6, 0x3d, 0xc6,
+    0x1e, 0xa4, 0xe4, 0x91, 0x35, 0x4c, 0x61, 0x4e, 0x2a, 0xc9, 0x48, 0x37,
+    0xf5, 0x88, 0xd4, 0xe4, 0xeb, 0xb2, 0xb5, 0x59, 0x86, 0xd8, 0x41, 0x5a,
+    0xd4, 0x13, 0x6e, 0x43, 0x5c, 0xc9, 0xf3, 0x86, 0x4c, 0xb5, 0x16, 0x9f,
+    0x93, 0x61, 0x8a, 0x85, 0x46, 0xa4, 0xc7, 0x8e, 0xa4, 0xa8, 0x2d, 0x09,
+    0x57, 0x97, 0x56, 0xdb, 0x7b, 0x9d, 0xb0, 0xbd, 0x9d, 0x69, 0xd5, 0x4c,
+    0xc7, 0x25, 0xea, 0xab, 0x2c, 0x06, 0xda, 0x6e, 0x3a, 0xec, 0x93, 0xf3,
+    0x2a, 0xf6, 0x55, 0xcd, 0xb8, 0xe0, 0x58, 0x5c, 0xfb, 0xde, 0xf8, 0x9b,
+    0xe6, 0x0c, 0xd3, 0x2b, 0x30, 0xd5, 0x05, 0x4a, 0xa4, 0xab, 0xbf, 0xa9,
+    0x21, 0x0d, 0x36, 0x90, 0x96, 0x9a, 0x48, 0xb5, 0x92, 0x00, 0x1e, 0x82,
+    0xd8, 0x7d, 0x9d, 0xd4, 0x5a, 0x62, 0xe8, 0x72, 0x22, 0xc7, 0x6d, 0xe5,
+    0x3a, 0xe4, 0x52, 0xd0, 0x48, 0x05, 0x37, 0x51, 0xb0, 0xd4, 0x3d, 0x3b,
+    0xfe, 0xd8, 0xc7, 0x51, 0x9f, 0x79, 0xf6, 0x44, 0xac, 0x93, 0x47, 0x83,
+    0xa1, 0x37, 0xb7, 0xdf, 0x58, 0xdf, 0x45, 0xa1, 0xa1, 0x89, 0x83, 0x3f,
+    0x38, 0xbe, 0x27, 0x8f, 0x90, 0x17, 0xe5, 0x19, 0xf8, 0x7e, 0xa9, 0x7f,
+    0x0c, 0xcf, 0x74, 0xe6, 0x41, 0x4a, 0xd2, 0xeb, 0xce, 0xb3, 0xa8, 0xde,
+    0xe0, 0x68, 0x5e, 0xff, 0x00, 0xed, 0x86, 0xef, 0xc4, 0xae, 0x57, 0xad,
+    0x66, 0x9c, 0xf5, 0x96, 0xa9, 0x99, 0x7a, 0x9d, 0x22, 0xa3, 0x2d, 0xe8,
+    0xaa, 0x40, 0x08, 0x48, 0x09, 0x16, 0x37, 0x25, 0x44, 0xec, 0x91, 0x6d,
+    0xee, 0x48, 0x18, 0x40, 0xe9, 0x72, 0x97, 0x1f, 0x38, 0xd0, 0xe4, 0x4c,
+    0x01, 0x82, 0xed, 0x49, 0xc4, 0x5d, 0xc5, 0x00, 0x2e, 0xa4, 0xe9, 0x1b,
+    0xf1, 0xc9, 0xb6, 0x3a, 0x7f, 0x38, 0x67, 0x5a, 0x2e, 0x59, 0xa6, 0xa5,
+    0xe0, 0x17, 0x2e, 0xa6, 0xb8, 0xfa, 0x52, 0xdb, 0x00, 0xd8, 0x26, 0xfb,
+    0x6b, 0x20, 0x5c, 0xef, 0xc2, 0x45, 0xf0, 0x93, 0x8e, 0x17, 0x35, 0x2b,
+    0x5d, 0x93, 0x71, 0x96, 0x8a, 0xd6, 0x59, 0x02, 0xde, 0x3d, 0xe1, 0xed,
+    0xbc, 0x50, 0xb0, 0xeb, 0x0d, 0xcd, 0x53, 0xdf, 0x6c, 0x1d, 0x56, 0x6f,
+    0xe5, 0x63, 0xf4, 0x85, 0xbe, 0x94, 0xf4, 0x72, 0x85, 0xd3, 0xd8, 0x08,
+    0xcc, 0xb9, 0x96, 0x4b, 0x33, 0xab, 0x2c, 0xd8, 0x87, 0x41, 0xbc, 0x68,
+    0x8b, 0xec, 0x1b, 0x07, 0xff, 0x00, 0x51, 0x63, 0xfb, 0xdd, 0xbb, 0x0e,
+    0xf8, 0xdb, 0xcc, 0xd9, 0xc6, 0x7d, 0x6e, 0x97, 0x22, 0x99, 0x97, 0xdc,
+    0x30, 0xd2, 0xa6, 0xd4, 0x18, 0x23, 0xe7, 0x70, 0xff, 0x00, 0x7d, 0x44,
+    0xf0, 0x2f, 0xe9, 0xbd, 0xed, 0xef, 0x88, 0x96, 0x6e, 0xcd, 0xdd, 0x45,
+    0xce, 0x15, 0x44, 0x29, 0xea, 0x7c, 0xe4, 0x42, 0x6a, 0xe1, 0xa6, 0x49,
+    0x08, 0xda, 0xe7, 0x7b, 0x5f, 0xcb, 0x7f, 0x41, 0xe9, 0xdf, 0x07, 0xa9,
+    0xaf, 0xe7, 0x01, 0x14, 0xb6, 0xb8, 0x4d, 0x0f, 0x11, 0x21, 0x09, 0x40,
+    0x76, 0xe5, 0x24, 0xef, 0x60, 0x07, 0xdf, 0x6c, 0x0f, 0x6b, 0x07, 0xd4,
+    0xa6, 0xdd, 0x13, 0x53, 0xa8, 0x2b, 0x5e, 0xc2, 0xdd, 0xd4, 0xf4, 0x82,
+    0xcd, 0x87, 0x52, 0x9e, 0xce, 0x55, 0xb2, 0x40, 0xde, 0xc7, 0xda, 0xff,
+    0x00, 0x3f, 0xe6, 0x14, 0xb2, 0x2c, 0x09, 0x51, 0x33, 0x8c, 0x66, 0x96,
+    0xe1, 0x7d, 0xc5, 0x2d, 0xc4, 0x94, 0x29, 0xcb, 0xf9, 0x86, 0xc6, 0xe4,
+    0x5e, 0xdd, 0xf0, 0x56, 0x6c, 0xc9, 0x93, 0x95, 0xfa, 0xf6};
+
+std::vector<uint8_t> l2cap_test_packet_8 = {
+    0xf6, 0x03, 0x47, 0x00, 0x10, 0xc1, 0x53, 0x69, 0x65, 0xc7, 0x52, 0xcc,
+    0xa7, 0x94, 0x02, 0xd5, 0xa8, 0xa0, 0x6b, 0xde, 0xde, 0xbd, 0xbf, 0x4c,
+    0x39, 0xe4, 0xec, 0x9f, 0x57, 0x77, 0x33, 0x35, 0x50, 0x9f, 0x4e, 0x44,
+    0x25, 0x34, 0xab, 0xa5, 0xd0, 0x8d, 0x3a, 0x81, 0xd8, 0x85, 0x71, 0xc7,
+    0x37, 0xe4, 0x93, 0x84, 0x99, 0x2f, 0xb0, 0xd5, 0x72, 0xae, 0x88, 0xe8,
+    0x7a, 0x4a, 0xdb, 0x98, 0xf0, 0x75, 0x09, 0x68, 0x9d, 0x0a, 0xd5, 0xb0,
+    0xbf, 0x1b, 0xdb, 0x0e, 0x75, 0x19, 0x29, 0x84, 0x51, 0xd0, 0x85, 0xa0,
+    0xf1, 0xf1, 0xde, 0xdb, 0xd8, 0x8f, 0xda, 0x1b, 0xb0, 0xc3, 0x8c, 0xc8,
+    0x9f, 0xee, 0x94, 0x1b, 0x04, 0x2b, 0xfc, 0x8d, 0xb6, 0x1b, 0x9e, 0x86,
+    0x13, 0x32, 0xee, 0x51, 0x95, 0x26, 0x62, 0x97, 0x2b, 0xca, 0x85, 0x38,
+    0x74, 0x36, 0x8d, 0xd4, 0xab, 0x9d, 0xbe, 0x98, 0x69, 0xa8, 0xfc, 0x0d,
+    0x1c, 0x22, 0x1c, 0x55, 0x32, 0x08, 0x1b, 0xa5, 0x0e, 0x6a, 0x08, 0xf5,
+    0x04, 0x8e, 0x4f, 0x7d, 0xb1, 0xf9, 0x3a, 0x8f, 0x99, 0xea, 0x68, 0x4a,
+    0x63, 0xc8, 0x85, 0x01, 0xbe, 0x74, 0x97, 0x81, 0xd3, 0x7f, 0x5b, 0x72,
+    0x71, 0xa3, 0x1b, 0xa7, 0x33, 0x18, 0x92, 0xdb, 0x95, 0x3a, 0xd3, 0x84,
+    0xba, 0x82, 0xa1, 0xe0, 0x46, 0x71, 0x6a, 0x29, 0xe3, 0xb0, 0x36, 0xc6,
+    0x54, 0xe1, 0xea, 0x8c, 0xd0, 0x0b, 0x75, 0x36, 0x1c, 0xb2, 0x10, 0xa0,
+    0xf7, 0xc4, 0x6c, 0x37, 0x86, 0xc1, 0x96, 0xa4, 0x1e, 0x35, 0x0c, 0x8a,
+    0xc8, 0xb9, 0x3d, 0x32, 0xf6, 0xc8, 0x43, 0x2e, 0x4d, 0x99, 0x97, 0xd4,
+    0x5c, 0x4d, 0x69, 0x97, 0x3c, 0x55, 0x0b, 0xa6, 0x42, 0xaf, 0x66, 0xc6,
+    0x92, 0x6c, 0x12, 0x0d, 0xbe, 0xfe, 0xbd, 0xf0, 0xcf, 0x05, 0xa8, 0x4e,
+    0xd6, 0x27, 0x1a, 0x5b, 0xc8, 0x2c, 0x08, 0x8d, 0x82, 0xb6, 0x55, 0x70,
+    0xa5, 0x00, 0xaf, 0x5e, 0xdb, 0xe1, 0x61, 0x8e, 0x9b, 0x44, 0x0a, 0x68,
+    0xbd, 0x5a, 0x7d, 0x69, 0x28, 0x05, 0x2a, 0x5a, 0xc8, 0xf2, 0xfa, 0x7b,
+    0x7d, 0x30, 0xdd, 0x95, 0xa9, 0x54, 0xbc, 0xb6, 0xc4, 0x8b, 0xcf, 0x69,
+    0x48, 0x5f, 0x9c, 0xf9, 0x49, 0x3b, 0x0b, 0x6e, 0x7b, 0xe1, 0x86, 0x83,
+    0x40, 0x98, 0x91, 0x9b, 0x0f, 0x39, 0x60, 0x90, 0x0e, 0xf1, 0x1b, 0xc6,
+    0xf8, 0xe6, 0x56, 0xbb, 0x28, 0xa4, 0xa5, 0x4a, 0x53, 0x84, 0x8d, 0x41,
+    0xd8, 0xc6, 0x8e, 0x49, 0x2b, 0xfe, 0x58, 0xa4, 0x2c, 0x3a, 0xb4, 0x07,
+    0x1a, 0x2d, 0x2e, 0xcb, 0x29, 0xbe, 0x95, 0x91, 0xcf, 0xf9, 0x86, 0x34,
+    0x1b, 0xc8, 0xf4, 0x8c, 0xaf, 0x5e, 0x7b, 0x30, 0xd7, 0x5a, 0x69, 0xe4,
+    0x15, 0xf8, 0x89, 0x2e, 0x3a, 0x34, 0x81, 0xea, 0x07, 0xae, 0x0e, 0xf4,
+    0xc1, 0xba, 0x5d, 0x63, 0xa7, 0xae, 0xc4, 0x55, 0x72, 0x1c, 0x19, 0xf0,
+    0x66, 0x38, 0x02, 0x5f, 0x41, 0xf9, 0x54, 0x41, 0x1c, 0x6f, 0x6f, 0x70,
+    0x0e, 0xe2, 0xc7, 0x1e, 0x95, 0x1c, 0xa7, 0x95, 0x6a, 0x8f, 0x78, 0x99,
+    0xa7, 0x38, 0xbb, 0x31, 0x60, 0xec, 0xdc, 0x55, 0x04, 0xb2, 0x91, 0xed,
+    0xab, 0x73, 0xf5, 0x23, 0x1e, 0xf3, 0x75, 0x49, 0x44, 0x23, 0x3e, 0xf2,
+    0x92, 0x4d, 0x87, 0x99, 0xce, 0x3e, 0x82, 0xa0, 0x54, 0x25, 0x95, 0x47,
+    0x96, 0xed, 0x52, 0x14, 0xb4, 0x0c, 0xae, 0x0e, 0x47, 0x63, 0x7d, 0xad,
+    0x7f, 0x13, 0xf3, 0x08, 0x59, 0xa7, 0xa9, 0x90, 0xe7, 0xd4, 0x3f, 0x87,
+    0xd3, 0xd6, 0x44, 0x73, 0xb1, 0x7d, 0x46, 0xca, 0xb7, 0x64, 0x8b, 0x7c,
+    0xa3, 0x8d, 0x86, 0xe7, 0xb9, 0xed, 0x80, 0xd4, 0x1a, 0xac, 0x04, 0xb8,
+    0xe1, 0x71, 0x0b, 0xd2, 0xb7, 0x09, 0xdc, 0xdf, 0x49, 0xdf, 0x6b, 0x1f,
+    0xad, 0xcf, 0xed, 0x8a, 0xe2, 0x32, 0x5e, 0x40, 0x85, 0x1d, 0x89, 0x14,
+    0xa8, 0x54, 0xea, 0xb8, 0x52, 0x94, 0x1c, 0x0f, 0x4f, 0x53, 0x3e, 0x1f,
+    0xf7, 0x46, 0xc8, 0x37, 0x36, 0xbd, 0xed, 0xc6, 0x18, 0xa9, 0xf4, 0xfe,
+    0x9a, 0xa6, 0x12, 0x14, 0xfd, 0x0c, 0x31, 0x25, 0x0a, 0x21, 0xe6, 0x58,
+    0x43, 0xce, 0x83, 0xb6, 0xc5, 0x2e, 0x5b, 0x71, 0xfa, 0x61, 0x36, 0xa1,
+    0x3e, 0x26, 0x94, 0x4b, 0xae, 0x0f, 0x33, 0x18, 0x26, 0x3b, 0x79, 0xb7,
+    0x4a, 0x9e, 0x70, 0x78, 0x00, 0x32, 0x1e, 0xa7, 0xde, 0x37, 0x7a, 0x17,
+    0xe0, 0x3b, 0x48, 0x42, 0x53, 0xe0, 0x3a, 0xfb, 0xa9, 0x5b, 0xee, 0x29,
+    0xa1, 0xc9, 0x06, 0xc7, 0x9e, 0xc0, 0x5b, 0x02, 0x7f, 0x12, 0x50, 0xd2,
+    0xdd, 0x7e, 0x93, 0x25, 0x20, 0x05, 0x29, 0x82, 0x90, 0x37, 0xb1, 0xb1,
+    0x1e, 0x9f, 0x43, 0x86, 0xaa, 0x5d, 0x7f, 0x25, 0x51, 0x5d, 0x0b, 0xa7,
+    0x50, 0xaa, 0x37, 0x00, 0x68, 0x09, 0x69, 0x66, 0xc3, 0xef, 0x84, 0xbe,
+    0xa7, 0xe6, 0x98, 0xb9, 0xb2, 0xbf, 0x16, 0x33, 0x50, 0x64, 0xc2, 0xf8,
+    0x26, 0xff, 0x00, 0xe7, 0x24, 0xa5, 0x4a, 0x4f, 0xae, 0xe3, 0x8d, 0xf9,
+    0xe3, 0x6c, 0x60, 0x4b, 0x8c, 0xf6, 0x25, 0x01, 0x60, 0xaa, 0xf7, 0xc8,
+    0xc6, 0x57, 0x18, 0xec, 0x90, 0x45, 0xf2, 0xf1, 0xb7, 0xca, 0xe6, 0x24,
+    0x3d, 0x41, 0x97, 0x21, 0x1f, 0x0d, 0xf0, 0x4e, 0xa2, 0x3c, 0xc7, 0x96,
+    0x4e, 0xa5, 0x10, 0x0f, 0x86, 0x05, 0x92, 0x8b, 0x9f, 0xca, 0x76, 0xfd,
+    0x31, 0x3c, 0x10, 0xaa, 0xae, 0xbe, 0xaf, 0xfc, 0xad, 0x97, 0x97, 0x7d,
+    0xce, 0x92, 0xa3, 0xfa, 0xe2, 0xae, 0x8a, 0x4c, 0x1a, 0xef, 0x50, 0x69,
+    0x54, 0x9a, 0x83, 0xc9, 0x62, 0x3f, 0xc0, 0xba, 0xf1, 0x71, 0x36, 0x3a,
+    0x52, 0x3e, 0x5d, 0xcf, 0xa0, 0x37, 0xbe, 0x07, 0xe6, 0x8c, 0x85, 0x9a,
+    0xe3, 0xcf, 0x28, 0xc9, 0xd5, 0x29, 0xb5, 0x66, 0x42, 0x43, 0x88, 0x44,
+    0x72, 0xa2, 0xbd, 0x2a, 0xbd, 0xb9, 0xdd, 0x5c, 0x1b, 0x73, 0xf5, 0xc5,
+    0x33, 0x0d, 0xb6, 0xf3, 0x34, 0xd0, 0xe7, 0x19, 0xb1, 0xb9, 0x00, 0x01,
+    0x90, 0xb9, 0x1a, 0xab, 0x2f, 0x28, 0x57, 0x55, 0x29, 0xb7, 0xc2, 0xa6,
+    0x0a, 0x49, 0xd8, 0xdb, 0x5c, 0xa0, 0x05, 0x1f, 0x29, 0x54, 0xdd, 0xa7,
+    0xa9, 0xe7, 0xe3, 0x53, 0xa2, 0x10, 0x9b, 0xb7, 0xe2, 0x4f, 0x09, 0x2e,
+    0x0b, 0x5e, 0xe0, 0x04, 0x2a, 0xff, 0x00, 0xb6, 0x3c, 0x19, 0xcb, 0xd9,
+    0xd9, 0x45, 0x3f, 0x0d, 0x47, 0x8e, 0x9d, 0x48, 0x4a, 0xbc, 0xa5, 0x2a,
+    0xb5, 0xc6, 0xd7, 0xb9, 0x36, 0x3e, 0xd8, 0x0e, 0x89, 0x59, 0xb5, 0x89,
+    0x4b, 0x82, 0xa9, 0x72, 0xe3, 0xb8, 0x83, 0x65, 0x24, 0xf9, 0x74, 0x9f,
+    0x43, 0xb6, 0xc7, 0xeb, 0x82, 0xb4, 0xea, 0x6e, 0x75, 0x9e, 0xca, 0xa5,
+    0x36, 0xed, 0x49, 0xc4, 0xa1, 0x5a, 0x54, 0x52, 0x6f, 0xc7, 0x3c, 0x63,
+    0x43, 0xb8, 0xa9, 0xa6, 0xcf, 0x0a, 0x8a, 0xc5, 0xbf, 0xf3, 0xf7, 0xe8,
+    0x04, 0x71, 0x6e, 0x9f, 0x4a, 0x51, 0xcd, 0x0b, 0x3d, 0x48, 0xfa, 0xde,
+    0x33, 0x30, 0xe5, 0xec, 0xe9, 0x12, 0x9a, 0x89, 0xd5, 0x86, 0x99, 0x6a,
+    0x34, 0x75, 0x78, 0x88, 0xd4, 0x05, 0x8a, 0x86, 0xe1, 0x36, 0xb7, 0x7b,
+    0x7d, 0x31, 0xeb, 0x53, 0xa8, 0x67, 0xc8, 0x49, 0x65, 0x6e, 0x39, 0x22,
+    0x13, 0x2a, 0x17, 0x65, 0x41, 0xb5, 0xb4, 0x9b, 0x13, 0xdb, 0x55, 0x88,
+    0x1b, 0xf7, 0xc3, 0xfd, 0x0e, 0x44, 0xc7, 0xa8, 0x2c, 0xc1, 0xac, 0x34,
+    0x92, 0xb6, 0x27, 0xc7, 0x6d, 0x68, 0x51, 0xb8, 0xa4, 0x1d};
+
+std::vector<uint8_t> l2cap_test_packet_9 = {0x09, 0x00, 0x47, 0x00, 0x12,
+                                            0x81, 0x3c, 0x1d, 0xc7, 0x62,
+                                            0x45, 0x1a, 0x78};
+
+// complete_l2cap_packet is the l2cap packet that should be created when
+// assemble is called on a vector<L2capSdu*> that contains the previous 9 test
+// packets.
+std::vector<uint8_t> complete_l2cap_packet = {
+    0x95, 0x1f, 0x47, 0x00, 0x02, 0x1f, 0x95, 0xcb, 0x00, 0x00, 0x00, 0x01,
+    0x01, 0x00, 0x33, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x47, 0x00, 0x5f, 0x00,
+    0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x37, 0x00, 0x30, 0x00, 0x36, 0x00,
+    0x30, 0x00, 0x36, 0x00, 0x5f, 0x00, 0x31, 0x00, 0x35, 0x00, 0x34, 0x00,
+    0x33, 0x00, 0x33, 0x00, 0x38, 0x00, 0x2e, 0x00, 0x6a, 0x00, 0x70, 0x00,
+    0x67, 0x00, 0x00, 0x42, 0x00, 0x0e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
+    0x6a, 0x70, 0x65, 0x67, 0x00, 0xc3, 0x00, 0x12, 0x30, 0x03, 0x97, 0x01,
+    0x48, 0x1f, 0x45, 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49,
+    0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff,
+    0xe1, 0x2b, 0x18, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4d, 0x4d, 0x00,
+    0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x0c, 0xc0, 0x01, 0x01, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x90, 0x01, 0x0f, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x04, 0x4c, 0x47, 0x45, 0x00, 0x01, 0x10, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x9e, 0x01, 0x12, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x05, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x01, 0x1b, 0x00, 0x05, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae, 0x01, 0x28, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x31, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb6, 0x01, 0x32, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xbd, 0x02, 0x13, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x87, 0x69, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x02, 0x78, 0x4e,
+    0x65, 0x78, 0x75, 0x73, 0x20, 0x35, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x50,
+    0x69, 0x63, 0x61, 0x73, 0x61, 0x00, 0x32, 0x30, 0x31, 0x37, 0x3a, 0x30,
+    0x36, 0x3a, 0x30, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34, 0x33, 0x3a, 0x33,
+    0x38, 0x00, 0x00, 0x00, 0x15, 0x82, 0x9a, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x01, 0xd4, 0x82, 0x9d, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x01, 0xdc, 0x88, 0x27, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x01, 0x02, 0x1f, 0x00, 0x00, 0x90, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x04, 0x30, 0x32, 0x32, 0x30, 0x90, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x01, 0xe4, 0x90, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x01, 0xf8, 0x91, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x04, 0x01, 0x02, 0x03, 0x00, 0x92, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x02, 0x0c, 0x92, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x02, 0x14, 0x92, 0x09, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x92, 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x02, 0x1c, 0x92, 0x90, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x02, 0x24, 0x92, 0x91, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x02, 0x2b, 0x92, 0x92, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x07, 0x00, 0x00, 0x02, 0x32, 0xa0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+    0x04, 0x30, 0x31, 0x30, 0x30, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x0a, 0x0a, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x07, 0x77, 0xa0, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x02, 0x5a, 0xa4, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x21, 0x00, 0x00, 0x02, 0x39, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x8c,
+    0xb2, 0x3b, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
+    0x64, 0x32, 0x30, 0x31, 0x37, 0x3a, 0x30, 0x36, 0x3a, 0x30, 0x36, 0x20,
+    0x31, 0x35, 0x3a, 0x34, 0x33, 0x3a, 0x33, 0x38, 0x00, 0x32, 0x30, 0x31,
+    0x37, 0x3a, 0x30, 0x36, 0x3a, 0x30, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34,
+    0x33, 0x3a, 0x33, 0x38, 0x00, 0xff, 0xff, 0xfe, 0x16, 0x00, 0x00, 0x00,
+    0x64, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x0f,
+    0x82, 0x00, 0x00, 0x03, 0xe8, 0x39, 0x39, 0x39, 0x37, 0x32, 0x39, 0x00,
+    0x39, 0x39, 0x39, 0x37, 0x32, 0x39, 0x00, 0x39, 0x39, 0x39, 0x37, 0x32,
+    0x39, 0x00, 0x31, 0x30, 0x61, 0x66, 0x39, 0x37, 0x31, 0x37, 0x63, 0x31,
+    0x30, 0x36, 0x36, 0x33, 0x65, 0x62, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00,
+    0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x52, 0x39, 0x38,
+    0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x30, 0x31, 0x30,
+    0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x01, 0x1a, 0x00, 0x05, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xc6, 0x01, 0x1b, 0x00, 0x05, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xce, 0x01, 0x28, 0x00, 0x03, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xd6, 0x02, 0x02, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x28, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00,
+    0x00, 0x00, 0x01, 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49,
+    0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff,
+    0xdb, 0x00, 0x43, 0x00, 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04,
+    0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08, 0x07, 0x07, 0x07,
+    0x07, 0x0f, 0x0b, 0x0b, 0x09, 0x0c, 0x11, 0x0f, 0x12, 0x12, 0x11, 0x0f,
+    0x11, 0x11, 0x13, 0x16, 0x1c, 0x17, 0x13, 0x14, 0x1a, 0x15, 0x11, 0x11,
+    0x18, 0x21, 0x18, 0x1a, 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22,
+    0x24, 0x22, 0x1e, 0x24, 0x1c, 0x1e, 0x1f, 0x1e, 0xff, 0xdb, 0x00, 0x43,
+    0x01, 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0e, 0x08, 0x08, 0x0e, 0x1e,
+    0x14, 0x11, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+    0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+    0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+    0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+    0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x78,
+    0x00, 0xa0, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
+    0xff, 0xc4, 0x00, 0x1c, 0x00, 0x00, 0x03, 0x00, 0x03, 0x01, 0x01, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07,
+    0x00, 0x04, 0x08, 0x03, 0x02, 0x01, 0xff, 0xc4, 0x00, 0x40, 0x10, 0x00,
+    0x01, 0x03, 0x02, 0x05, 0x02, 0x04, 0x04, 0x04, 0x03, 0x06, 0x04, 0x07,
+    0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x00, 0x06, 0x12,
+    0x21, 0x31, 0x07, 0x41, 0x13, 0x22, 0x51, 0x61, 0x14, 0x32, 0x71, 0x81,
+    0x08, 0x42, 0x91, 0xa1, 0x15, 0x16, 0xc1, 0x23, 0x52, 0x62, 0x82, 0xb1,
+    0xe1, 0x24, 0x43, 0x72, 0xf0, 0x17, 0x25, 0x33, 0x92, 0xb2, 0xd1, 0xd2,
+    0xff, 0xc4, 0x00, 0x1c, 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07,
+    0x04, 0x03, 0x00, 0x02, 0x08, 0x01, 0xff, 0xc4, 0x00, 0x37, 0x11, 0x00,
+    0x01, 0x02, 0x04, 0x04, 0x03, 0x06, 0x04, 0x05, 0x04, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0x11, 0x06, 0x21,
+    0x31, 0x41, 0x12, 0x51, 0x71, 0x13, 0x22, 0x61, 0x81, 0x91, 0xa1, 0x07,
+    0xb1, 0xc1, 0xf0, 0x14, 0x42, 0xd1, 0xe1, 0xf1, 0x15, 0x24, 0x32, 0x82,
+    0x33, 0x52, 0x72, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11,
+    0x03, 0x11, 0x00, 0x3f, 0x00, 0xb1, 0x31, 0x2c, 0x2d, 0xd8, 0xd2, 0xda,
+    0x43, 0x26, 0x4a, 0x99, 0x1e, 0x15, 0x98, 0x2e, 0x2f, 0x51, 0x49, 0x0b,
+    0x03, 0x70, 0x90, 0x6c, 0x9f, 0x4d, 0xb7, 0xf5, 0xc3, 0x0b, 0x4f, 0x09,
+    0x1f, 0x08, 0xa5, 0x95, 0xb6, 0xb7, 0x50, 0x4e, 0x95, 0xab, 0xe4, 0xbf,
+    0x2a, 0xb1, 0x17, 0xb8, 0xb1, 0xde, 0xdd, 0xf1, 0x34, 0xa1, 0x3b, 0x25,
+    0xb6, 0x5d, 0x67, 0xe2, 0xda, 0x5b, 0xeb, 0x49, 0xf0, 0xd2, 0x83, 0xe1,
+    0xa9, 0x37, 0xbe, 0x91, 0x72, 0xab, 0x5f, 0x73, 0x7f, 0xb6, 0x1d, 0x28,
+    0xf0, 0xdf, 0xf1, 0x9b, 0x05, 0x2e, 0x20, 0x32, 0xd8, 0x64, 0x23, 0x52,
+    0x4a, 0x9c, 0xb7, 0x2b, 0x52, 0x8d, 0xd5, 0xe9, 0xe5, 0xdb, 0x83, 0xea,
+    0x30, 0x09, 0x75, 0x86, 0x25, 0xec, 0x1e, 0x58, 0x4d, 0xf9, 0x90, 0x20,
+    0x87, 0x60, 0x4e, 0x91, 0xb2, 0xc3, 0x72, 0x63, 0xcd, 0x40, 0x76, 0x63,
+    0xd2, 0x5b, 0x4a, 0x75, 0x04, 0x20, 0x06, 0xf9, 0xdb, 0xcd, 0xdc, 0x83,
+    0xe9, 0x6b, 0xec, 0x0d, 0xf1, 0xba, 0x5f, 0x76, 0xe9, 0x50, 0x43, 0x65,
+    0xd9, 0x05, 0x21, 0x08, 0xf2, 0x92, 0x94, 0x05, 0x73, 0x72, 0x48, 0x20,
+    0x5c, 0xaa, 0xf8, 0xf8, 0xa9, 0x34, 0x97, 0xe4, 0x3e, 0xc7, 0xc4, 0x80,
+    0x95, 0x90, 0x90, 0x9d, 0x1a, 0x94, 0x8b, 0xd8, 0x6d, 0xb5, 0x80, 0xef,
+    0xf7, 0xc7, 0xeb, 0x14, 0xb7, 0xdb, 0x79, 0x45, 0x2f, 0xb6, 0x50, 0x55,
+    0x7b, 0x96, 0x86, 0xb4, 0xf1, 0xc2, 0xaf, 0x7e, 0xc3, 0x7c, 0x65, 0x77,
+    0x15, 0x52, 0x98, 0x36, 0x53, 0xc3, 0xca, 0xe7, 0xe5, 0x78, 0xf0, 0xb0,
+    0xb3, 0x99, 0x11, 0xae, 0xa6, 0xd8, 0x91, 0x2c, 0x38, 0x3c, 0x37, 0xb4,
+    0x36, 0xa6, 0x99, 0xd2, 0xb2, 0xb0, 0xda, 0x01, 0x04, 0xea, 0x24, 0x8d,
+    0xcd, 0xb6, 0xfa, 0x63, 0x62, 0x92, 0xdb, 0x2c, 0xb8, 0xcb, 0x29, 0x7d,
+    0x97, 0x94, 0x5b, 0x53, 0xa0, 0x22, 0xfa, 0x02, 0x52, 0x52, 0x35, 0x12,
+    0x2f, 0x71, 0x7b, 0x72, 0x77, 0xe0, 0x63, 0xc2, 0xb9, 0x43, 0xa9, 0x39,
+    0x09, 0xc8, 0xd0, 0x1f, 0x6d, 0x95, 0xbb, 0xa5, 0x7f, 0x10, 0xfa, 0x3c,
+    0x5d, 0xf5, 0x58, 0x24, 0x20, 0x5b, 0x51, 0x3c, 0x58, 0x9b, 0x5a, 0xf7,
+    0xbd, 0xf1, 0x2f, 0xcd, 0x94, 0x9c, 0xff, 0x00, 0x4a, 0x94, 0xe4, 0xba,
+    0x8e, 0x60, 0xa8, 0xba, 0xc0, 0x05, 0x1a, 0xe2, 0x47, 0x09, 0x09, 0x4f,
+    0xa6, 0x94, 0x8b, 0xa7, 0xd8, 0x0f, 0xb6, 0x0a, 0xd3, 0xaa, 0x54, 0xe9,
+    0xe5, 0xa1, 0x29, 0x98, 0x4a, 0x4a, 0xb4, 0x0a, 0xba, 0x6f, 0x9d, 0xb7,
+    0x16, 0xbf, 0x21, 0x7b, 0x9d, 0x84, 0x0d, 0xa8, 0x4c, 0xb9, 0x26, 0xd9,
+    0x73, 0xb2, 0x52, 0xc0, 0xff, 0x00, 0xa8, 0x07, 0xda, 0xf7, 0xeb, 0x95,
+    0x84, 0x55, 0xdb, 0x4c, 0x26, 0xa4, 0x3e, 0xdb, 0x0b, 0x2e, 0xcb, 0x91,
+    0x24, 0xbe, 0xa2, 0x2c, 0x08, 0x52, 0x86, 0xca, 0xb7, 0x17, 0x00, 0x58,
+    0xed, 0x72, 0x0e, 0xf8, 0xf8, 0x7e, 0x6c, 0x28, 0xce, 0x3a, 0xc3, 0x25,
+    0x90, 0x88, 0xc9, 0xd4, 0xe9, 0x71, 0xc0, 0x09, 0x52, 0x85, 0xed, 0xa8,
+    0xf7, 0xbd, 0xff, 0x00, 0x4d, 0x86, 0x39, 0x96, 0xa7, 0xd4, 0x6a, 0x63,
+    0x28, 0x5b, 0x1f, 0xce, 0x33, 0xf5, 0x36, 0x0a, 0x5c, 0x49, 0x75, 0x6b,
+    0x70, 0xab, 0x8b, 0x8b, 0x91, 0x63, 0x6b, 0x6d, 0x6e, 0xd8, 0x00, 0xee,
+    0x76, 0xca, 0xce, 0x27, 0xc6, 0x6a, 0x8b, 0x32, 0x78, 0x69, 0x3f, 0xda,
+    0x3a, 0xa6, 0xca, 0x89, 0xb7, 0x2a, 0x3b, 0x9f, 0x7c, 0x37, 0xff, 0x00,
+    0x41, 0x69, 0x1f, 0xf2, 0xbe, 0x07, 0xa7, 0xd4, 0x88, 0x54, 0x18, 0xaa,
+    0x61, 0xcf, 0xf8, 0xa4, 0xd6, 0x7a, 0xe5, 0xf3, 0x1f, 0xac, 0x75, 0x8c,
+    0x0c, 0xc3, 0x02, 0xa3, 0x50, 0x6a, 0x9c, 0xc5, 0x62, 0x92, 0xe4, 0xa7,
+    0x10, 0xb6, 0xbe, 0x1d, 0xb9, 0x2d, 0xad, 0x00, 0x80, 0x3f, 0x2f, 0xcc,
+    0xb5, 0x0b, 0x1e, 0x2c, 0x07, 0xb9, 0xc7, 0xae, 0x68, 0x96, 0xa4, 0xd2,
+    0xcb, 0x31, 0x25, 0x29, 0x72, 0x00, 0x0d, 0x96, 0xda, 0xec, 0x9b, 0xf7,
+    0xb0, 0xd8, 0xf7, 0xda, 0xc7, 0xb6, 0x21, 0x79, 0x22, 0x3d, 0x1e, 0xbf,
+    0x45, 0x8b, 0x3c, 0xd3, 0x95, 0x11, 0xb9, 0x26, 0xf1, 0x5c, 0x69, 0x65,
+    0xa7, 0x10, 0xa0, 0xe6, 0x84, 0x9d, 0xb7, 0x1e, 0x71, 0x89, 0xac, 0x0a,
+    0x9d, 0x56, 0x8f, 0x38, 0x48, 0x8d, 0x52, 0x9d, 0x0d, 0x65, 0xc2, 0x54,
+    0xeb, 0x2e, 0xa9, 0x0a, 0x55, 0x8d, 0x89, 0xe7, 0x7e, 0xfc, 0xe0, 0x0d,
+    0x79, 0xb6, 0xe9, 0x8a, 0x42, 0x50, 0x4a, 0x82, 0xc6, 0xbf, 0xa4, 0x51,
+    0xbe, 0x1b, 0xc8, 0x2b, 0x18, 0x35, 0x32, 0xe3, 0x87, 0xb2, 0x53, 0x2a,
+    0x09, 0xe1, 0xd6, 0xe4, 0x8b, 0xe6, 0x76, 0xf4, 0x31, 0xd6, 0x31, 0x67,
+    0x66, 0x00, 0xda, 0x90, 0x22, 0xc6, 0x79, 0xb4, 0x20, 0xa1, 0x6f, 0xbc,
+    0x0a, 0x41, 0x09, 0xf3, 0x6b, 0x09, 0x37, 0xb0, 0x36, 0xdc, 0x12, 0x4e,
+    0xd8, 0x11, 0x51, 0x7f, 0xf8, 0xed, 0x5a, 0x1c, 0x88, 0x35, 0x04, 0xa5,
+    0xc8, 0x4d, 0x2d, 0x4d, 0xa9, 0xc8, 0xd6, 0x6b, 0x52, 0x87, 0x99, 0x4a,
+    0xb8, 0xdc, 0x93, 0xc0, 0x06, 0xdc, 0xe2, 0x21, 0x13, 0xa9, 0xd9, 0xb0,
+    0xb1, 0xe1, 0x4a, 0xaf, 0x3a, 0xe9, 0x4a, 0xb5, 0x21, 0x6e, 0xb0, 0x85,
+    0x9f, 0x6b, 0xa8, 0x6f, 0x7f, 0xb6, 0x35, 0xe2, 0xf5, 0x37, 0x37, 0xca,
+    0x7c, 0x35, 0x51, 0xaf, 0xae, 0x13, 0x00, 0xfc, 0xed, 0x46, 0xd7, 0x71,
+    0xfe, 0x22, 0x0d, 0xc7, 0xe8, 0x70, 0x10, 0xcf, 0xb0, 0x53, 0x61, 0x73,
+    0xe9, 0xfa, 0xc3, 0xcc, 0xc6, 0x09, 0x7a, 0x50, 0x15, 0x29, 0x1c, 0x5f,
+    0xf9, 0xb9, 0xfa, 0x67, 0xe5, 0x68, 0xe8, 0x7a, 0x34, 0x17, 0x60, 0x34,
+    0xa0, 0x66, 0x53, 0xdb, 0x53, 0x84, 0xea, 0x5b, 0x67, 0x4d, 0xfd, 0xfc,
+    0xbe, 0xfb, 0xf3, 0xbf, 0xd3, 0x6c, 0x7d, 0x66, 0x87, 0xeb, 0x74, 0xf8,
+    0xb1, 0xe1, 0xd2, 0xc4, 0x35, 0x49, 0x90, 0xcb, 0xae, 0xc3, 0x73, 0x7d,
+    0x3a, 0x90, 0x9b, 0x90, 0x45, 0xed, 0xbd, 0xf6, 0x3c, 0x0e, 0x6d, 0x89,
+    0xa6, 0x46, 0x89, 0x56, 0xac, 0x4b, 0x81, 0x35, 0xac, 0xdc, 0xfd, 0x56,
+    0x31, 0x7d, 0x2a, 0x29, 0x60, 0x0b, 0x25, 0x49, 0x58, 0xd9, 0xc0, 0x07,
+    0x96, 0xe3, 0xb1, 0xb6, 0xd8, 0xac, 0xe7, 0xb4, 0x45, 0x6a, 0xaf, 0x4b,
+    0x43, 0x4a, 0x6d, 0x25, 0xa9, 0x32, 0x11, 0xa1, 0x24, 0x5d, 0x29, 0x53,
+    0x5b, 0x6d, 0xd8, 0x5c, 0x60, 0xad, 0x29, 0x4d, 0xcc, 0x38, 0x3b, 0xb6,
+    0x00, 0x8d, 0x77, 0x85, 0xb9, 0x96, 0x19, 0x49, 0x52, 0x10, 0x9c, 0xc2,
+    0x54, 0x73, 0x1a, 0x10, 0x92, 0x47, 0xbd, 0xa2, 0x1c, 0x9f, 0xfc, 0x40,
+    0x7a, 0x32, 0x5f, 0x97, 0x99, 0x1d, 0x52, 0xdb, 0x36, 0x11, 0x92, 0xe2,
+    0x90, 0xd3, 0x62, 0xdc, 0x0d, 0x24, 0x11, 0xb1, 0xc2, 0xfd, 0x5a, 0x5e,
+    0x60, 0x42, 0x2c, 0xfc, 0x07, 0x18, 0x75, 0x2a, 0xba, 0x26, 0x21, 0xe5,
+    0x3f, 0x63, 0xfd, 0xe4, 0xa9, 0x47, 0xca, 0x46, 0xe3, 0x71, 0xdf, 0x19,
+    0xd6, 0x3a, 0xd5, 0x5e, 0x91, 0x0d, 0x2f, 0xc1, 0x21, 0x94, 0x29, 0xd7,
+    0x2e, 0x15, 0x65, 0x05, 0x5b, 0x4e, 0xe4, 0x7d, 0xf8, 0x38, 0x0b, 0x42,
+    0xea, 0x69, 0x30, 0x9b, 0x6a, 0xb9, 0x4b, 0x43, 0xe1, 0xb0, 0x12, 0x1d,
+    0x8e, 0x7c, 0x32, 0x8f, 0xb7, 0x6f, 0xb6, 0x28, 0xcb, 0x99, 0x92, 0x95,
+    0x74, 0x36, 0xa0, 0x94, 0xa8, 0x8b, 0x8c, 0xac, 0x39, 0x74, 0x88, 0xa6,
+    0x1f, 0xc4, 0x18, 0xbd, 0x12, 0x9f, 0x8e, 0x67, 0x85, 0xe6, 0xd4, 0x4d,
+    0xd2, 0x6d, 0x71, 0x6d, 0x6d, 0x98, 0x3e, 0x40, 0xf9, 0x40, 0xf9, 0x19,
+    0x9a, 0xad, 0xe3, 0x3b, 0x11, 0x6e, 0xca, 0xa9, 0x6b, 0x56, 0x8d, 0x72,
+    0x5c, 0x4a, 0xad, 0x7b, 0x0b, 0x24, 0xe9, 0x3a, 0x71, 0xf7, 0x97, 0xaa,
+    0x19, 0x86, 0x65, 0x52, 0x24, 0x66, 0xe9, 0x0d, 0xb7, 0xe3, 0x38, 0x1b,
+    0x49, 0x44, 0x50, 0xab, 0x82, 0xab, 0x5e, 0xc4, 0x6f, 0x6c, 0x35, 0xb3,
+    0x4b, 0xcb, 0x79, 0x89, 0xe4, 0xce, 0xa6, 0x26, 0x6c, 0x69, 0x5a, 0x82,
+    0x95, 0x29, 0x2b, 0x52, 0x1d, 0x41, 0x3b, 0x8b, 0x91, 0xda, 0xc3, 0x6d,
+    0x88, 0xd8, 0xe1, 0x93, 0x2f, 0xcf, 0xab, 0xe5, 0x7c, 0xc7, 0x4d, 0x46,
+    0x60, 0x97, 0x0e, 0x75, 0x31, 0xe9, 0x08, 0x69, 0x12, 0x8c, 0x60, 0x87,
+    0xda, 0xf4, 0xbe, 0x8b, 0x05, 0x0f, 0xb0, 0x3d, 0xf1, 0x8a, 0x64, 0xd5,
+    0x5a, 0x1c, 0x52, 0xae, 0x24, 0xa0, 0x67, 0x6b, 0x01, 0xfc, 0xfa, 0xc3,
+    0x75, 0x33, 0xe2, 0x63, 0x4f, 0xbc, 0x99, 0x57, 0xd2, 0x59, 0x73, 0x4e,
+    0x12, 0x32, 0xbf, 0xcf, 0xd6, 0x06, 0xf5, 0x01, 0xd9, 0x74, 0xac, 0xba,
+    0xdb, 0x2f, 0x33, 0x1d, 0xba, 0x85, 0x36, 0xae, 0xe4, 0x77, 0x5d, 0x61,
+    0xad, 0x96, 0x0b, 0x63, 0x70, 0x07, 0xfd, 0x37, 0xb6, 0x1f, 0xba, 0x4b,
+    0x5b, 0x95, 0x3f, 0x2b, 0xc1, 0x44, 0xc7, 0x1e, 0x96, 0x02, 0x8d, 0xca,
+    0x9b, 0xb2, 0x94, 0x41, 0x24, 0x12, 0x2f, 0xcd, 0xec, 0x37, 0xe7, 0xdf,
+    0x13, 0xbe, 0xb2, 0x54, 0x4c, 0xba, 0xce, 0x60, 0x5c, 0x25, 0x87, 0xe9,
+    0xee, 0x4a, 0x6e, 0x49, 0xf0, 0xd3, 0x72, 0x95, 0x29, 0x24, 0x03, 0xa8,
+    0x1d, 0xb9, 0x3b, 0x7b, 0x7b, 0x60, 0xef, 0x43, 0x5d, 0x29, 0x88, 0xdb,
+    0x8b, 0x72, 0x33, 0x65, 0x5e, 0x25, 0xee, 0x17, 0x7b, 0x10, 0x05, 0xac,
+    0x0d, 0x89, 0xdb, 0x83, 0x85, 0x8c, 0x5a, 0x78, 0x66, 0x9a, 0x58, 0xdd,
+    0x20, 0x9f, 0x3b, 0x9f, 0xac, 0x3b, 0xd5, 0xdb, 0xb9, 0x4a, 0xd5, 0xa9,
+    0x00, 0xfb, 0x40, 0xac, 0xbf, 0x98, 0xbe, 0x31, 0x9a, 0xab, 0x73, 0x42,
+    0xde, 0x80, 0xc7, 0x87, 0xa9, 0x2b, 0x6c, 0x10, 0xe0, 0x28, 0xbe, 0xe0,
+    0xec, 0x47, 0xa7, 0xfb, 0x62, 0x9b, 0x94, 0x9a, 0xa9, 0xd6, 0x72, 0xa8,
+    0x95, 0x90, 0x33, 0x73, 0x72, 0xd6, 0x86, 0x2e, 0x69, 0x92, 0xbc, 0xcb,
+    0x61, 0x76, 0xf9, 0x52, 0x54, 0x6f, 0xa7, 0xd8, 0x92, 0x3d, 0x14, 0x31,
+    0x03, 0x76, 0x3b, 0x4d, 0xe4, 0xcc, 0xcd, 0x23, 0x58, 0xbb, 0x8d, 0xa2,
+    0xe9, 0x04, 0xd9, 0x20, 0x04, 0x8d, 0xbd, 0x76, 0xc4, 0xf3, 0x2a, 0x55,
+    0x33, 0x44, 0x4c, 0xf6, 0x22, 0xe5, 0x27, 0xa6, 0xae, 0xa2, 0xe4, 0xa0,
+    0x96, 0x44, 0x72, 0x6e, 0x0d, 0x85, 0xcd, 0x87, 0x6b, 0x5e, 0xff, 0x00,
+    0xbe, 0x3d, 0xa6, 0x9a, 0x94, 0x98, 0xa7, 0xcb, 0x4a, 0x4c, 0xb4, 0x16,
+    0x14, 0x9b, 0xe6, 0x01, 0xcf, 0x2d, 0xb5, 0xdf, 0x50, 0x41, 0x89, 0x54,
+    0x8c, 0xa3, 0xc2, 0xa1, 0x3d, 0x50, 0x65, 0xee, 0x12, 0x85, 0x81, 0x62,
+    0x6c, 0x2d, 0x62, 0x49, 0xdc, 0x65, 0x6d, 0xd2, 0x44, 0x5c, 0x1e, 0xcf,
+    0x3d, 0x5a, 0x62, 0xa4, 0xe5, 0x3e, 0xa5, 0x50, 0xa7, 0xd2, 0xdd, 0x49,
+    0xd2, 0x84, 0xbc, 0xd6, 0x95, 0x39, 0xcd, 0x82, 0x6f, 0x7b, 0xf1, 0xce,
+    0xe0, 0x7a, 0xe1, 0x83, 0x20, 0xbf, 0xd4, 0x0a, 0xad, 0x42, 0x4b, 0xd5,
+    0x6c, 0xe0, 0xf1, 0x66, 0x24, 0xe6, 0xee, 0xcb, 0x6d, 0x20, 0x02, 0x9b,
+    0x82, 0x52, 0xab, 0x0f, 0x4d, 0x88, 0xf7, 0xc1, 0x8c, 0xd5, 0x2e, 0x8a,
+    0x7a, 0x5d, 0x4e, 0x8b, 0x5b, 0x8e, 0xd2, 0xab, 0x06, 0xea, 0x50, 0x6d,
+    0x3b, 0xa1, 0xb2, 0xa3, 0xa0, 0x58, 0x7f, 0xcc, 0x50, 0xb5, 0x80, 0xdc,
+    0x83, 0xbe, 0x24, 0xbd, 0x36, 0xcc, 0x33, 0xb2, 0xcd, 0x54, 0x25, 0x42,
+    0x4a, 0x5a, 0x2e, 0x02, 0x96, 0xdc, 0x90, 0x4a, 0x55, 0x7d, 0x89, 0xb7,
+    0x04, 0x81, 0xff, 0x00, 0xd6, 0xf8, 0x54, 0xad, 0xe1, 0x4a, 0x6d, 0x38,
+    0x07, 0x19, 0x69, 0x20, 0x1b, 0xe4, 0x52, 0x2f, 0x96, 0xe0, 0xf2, 0x3b,
+    0x7d, 0x61, 0xaf, 0x0d, 0x62, 0x79, 0x8a, 0xb0, 0x52, 0x1c, 0x02, 0xe9,
+    0x09, 0xcc, 0x68, 0x4a, 0x85, 0xed, 0xa7, 0xf9, 0x0d, 0xc7, 0x8e, 0xd1,
+    0xd8, 0x64, 0xff, 0x00, 0xc5, 0xb4, 0xd3, 0x68, 0x05, 0x28, 0x0a, 0x5a,
+    0x92, 0x4f, 0xe5, 0x4b, 0x97, 0xb7, 0xe8, 0x71, 0x1a, 0xab, 0xfe, 0x21,
+    0x29, 0xd4, 0x7e, 0xa5, 0xce, 0xca, 0x35, 0xea, 0x64, 0x91, 0x09, 0x01,
+    0x05, 0x12, 0xda, 0x40, 0x50, 0x4e, 0xa1, 0xdd, 0x3c, 0xd8, 0x7a, 0xef,
+    0x8a, 0xc5, 0x36, 0xa9, 0x0e, 0x44, 0x84, 0xe8, 0x73, 0xfb, 0x59, 0x2c,
+    0x29, 0x4d, 0xa7, 0xbf, 0x65, 0x7f, 0xa1, 0xc7, 0x13, 0xf5, 0x06, 0x9b,
+    0x52, 0xac, 0xfe, 0x20, 0x6a, 0x90, 0x20, 0x45, 0x91, 0x2a, 0x5b, 0x8b,
+    0x6d, 0xb6, 0x19, 0x6c, 0x5d, 0x4b, 0xb2, 0x78, 0x1f, 0xbe, 0xfc, 0x0c,
+    0x21, 0x61, 0xb9, 0x66, 0xa7, 0xdb, 0xb3, 0xa7, 0x44, 0x2b, 0x43, 0x6b,
+    0x10, 0xb4, 0x81, 0xec, 0x77, 0xb8, 0xcc, 0xc1, 0xa7, 0xf8, 0x99, 0x48,
+    0x36, 0xce, 0xe0, 0x67, 0xc8, 0x85, 0x1f, 0xa6, 0xa2, 0x3a, 0x3b, 0x33,
+    0xe4, 0x8c, 0x85, 0xd4, 0x46, 0xda, 0xae, 0x52, 0xc4, 0x07, 0x64, 0x2e,
+    0xc0, 0x49, 0x61, 0x00, 0x2b, 0xe8, 0xbb, 0x6f, 0xbe, 0x14, 0xab, 0xb9,
+    0x30, 0x50, 0x22, 0xff, 0x00, 0x0f, 0xfe, 0x13, 0x18, 0x7c, 0x72, 0x96,
+    0xc0, 0x90, 0x41, 0x29, 0x41, 0x50, 0xb0, 0xbf, 0x1e, 0x5e, 0x76, 0xdb,
+    0xdc, 0xfa, 0xb5, 0xf4, 0xeb, 0x24, 0x53, 0x7a, 0x71, 0x45, 0x7a, 0xa1,
+    0x5b, 0xa8, 0x32, 0x89, 0xd3, 0x96, 0xda, 0xa5, 0x25, 0xb5, 0xf9, 0x1b,
+    0x08, 0x3a, 0x92, 0x80, 0x7f, 0x32, 0xb5, 0x5a, 0xea, 0xf6, 0xb0, 0xbe,
+    0x06, 0x75, 0x3e, 0xa9, 0x5a, 0xce, 0x51, 0xa1, 0xc3, 0xa7, 0xb0, 0x61,
+    0xc5, 0x5c, 0x80, 0x59, 0x52, 0x8d, 0x9c, 0x58, 0x48, 0x24, 0x1b, 0x7e,
+    0x54, 0xef, 0xdf, 0x72, 0x71, 0xda, 0x98, 0xf4, 0xe8, 0x9f, 0xec, 0xa5,
+    0x9d, 0x2e, 0x32, 0x35, 0xb8, 0xc8, 0x78, 0x03, 0xe9, 0xa6, 0xa7, 0x6b,
+    0x46, 0x87, 0xc3, 0x45, 0xae, 0x35, 0xa4, 0x5f, 0x9e, 0xff, 0x00, 0xbf,
+    0xa6, 0x9b, 0xc2, 0xfc, 0xa9, 0xf1, 0x13, 0x97, 0xbc, 0x4a, 0x32, 0x2e,
+    0xd4, 0x0b, 0xb4, 0xa0, 0x11, 0xa7, 0xcc, 0xd3, 0x89, 0x52, 0x94, 0x94,
+    0x8b, 0x00, 0x2f, 0x72, 0x3d, 0xb1, 0x36, 0xeb, 0x1c, 0x07, 0x28, 0xd3,
+    0x6b, 0xb4, 0xc9, 0x4e, 0x15, 0x25, 0x82, 0xb5, 0x31, 0xa4, 0xdd, 0x29,
+    0x4a, 0x9c, 0x43, 0xa9, 0x23, 0xfc, 0xaa, 0xfd, 0xf1, 0xbb, 0x2e, 0x55,
+    0x6a, 0x87, 0x1a, 0xbc, 0x89, 0x20, 0x29, 0x69, 0x63, 0x5a, 0x52, 0xb0,
+    0x6c, 0x51, 0xa1, 0x40, 0xf1, 0xea, 0x06, 0x06, 0x67, 0xc9, 0x92, 0x33,
+    0x14, 0x36, 0xe4, 0xcb, 0x5f, 0x8a, 0xec, 0x9a, 0x6c, 0x7b, 0xab, 0x48,
+    0x04, 0xff, 0x00, 0x62, 0x11, 0xfb, 0x14, 0xe2, 0xb3, 0x88, 0x78, 0x7f,
+    0x01, 0x26, 0xb3, 0xa8, 0x03, 0xe9, 0xfa, 0x46, 0x4f, 0x85, 0x0c, 0x3c,
+    0xa9, 0xba, 0xd4, 0xba, 0x45, 0xc2, 0xc5, 0xc5, 0xb5, 0xe2, 0xb1, 0xb7,
+    0xce, 0xde, 0x71, 0x36, 0xa6, 0x4b, 0xaa, 0xbf, 0x20, 0x98, 0xaf, 0x68,
+    0x69, 0xb4, 0xdf, 0x4d, 0xb6, 0xb0, 0xf6, 0xe4, 0x93, 0x87, 0x95, 0xaa,
+    0x38, 0xa5, 0x44, 0x4a, 0x81, 0xf8, 0xd4, 0xeb, 0x32, 0x1d, 0x1b, 0x21,
+    0x49, 0x36, 0x29, 0xb0, 0xf5, 0x1b, 0xdc, 0xfd, 0x30, 0x0f, 0x2d, 0xd1,
+    0xd3, 0x0d, 0xa6, 0xde, 0xa8, 0xb8, 0x12, 0xb0, 0x2f, 0x60, 0x0a, 0x83,
+    0x7b, 0x6f, 0x6b, 0x72, 0xac, 0x36, 0xd2, 0xa8, 0x46, 0xbb, 0x1e, 0x4c,
+    0xa8, 0x92, 0x22, 0xa0, 0x34, 0xc9, 0x71, 0xa6, 0x0b, 0xa1, 0x4a, 0x3d,
+    0xbc, 0xd6, 0x3b, 0x2b, 0x93, 0x7e, 0x01, 0xdb, 0x9c, 0x28, 0x4c, 0xad,
+    0x2e, 0x2a, 0xc8, 0x02, 0xdc, 0xe2, 0xc1, 0x46, 0x2f, 0x50, 0x25, 0x7f,
+    0x11, 0x50, 0x75, 0x5c, 0x4a, 0xff, 0x00, 0x16, 0xef, 0xa7, 0x5b, 0xe9,
+    0xd3, 0x6d, 0xf3, 0xc8, 0x6e, 0xf4, 0xff, 0x00, 0x3d, 0x4c, 0xca, 0xf9,
+    0x88, 0x7c, 0x2c, 0x1d, 0x46, 0x63, 0x29, 0x6c, 0xa4, 0x27, 0x40, 0xb2,
+    0x38, 0x59, 0xf5, 0x27, 0x7f, 0xd7, 0x1d, 0x08, 0xce, 0x65, 0x6e, 0xa7,
+    0x54, 0xa7, 0x4f, 0xac, 0xa6, 0x3c, 0x79, 0x29, 0x7e, 0x13, 0xc8, 0x49,
+    0x50, 0x05, 0x45, 0xd0, 0xa4, 0xad, 0x36, 0xfc, 0xdc, 0x03, 0x8e, 0x7d,
+    0x32, 0xa0, 0x57, 0xa9, 0x52, 0x6a, 0xeb, 0x52, 0x19, 0xaa, 0x46, 0x8a,
+    0x52, 0x96, 0xb4, 0x24, 0x2d, 0xc2, 0x15, 0xdf, 0xe8, 0x07, 0x1c, 0x91,
+    0xfa, 0x63, 0xa0, 0xf3, 0x25, 0x39, 0x0e, 0x51, 0x29, 0x12, 0xc2, 0x59,
+    0xb3, 0x52, 0x60, 0x91, 0x74, 0x0b, 0xdb, 0xc3, 0x3d, 0xff, 0x00, 0x4c,
+    0x14, 0xa5, 0x29, 0x69, 0x70, 0x24, 0x69, 0xcb, 0xce, 0x13, 0xa6, 0xa7,
+    0x45, 0x49, 0xf7, 0x5d, 0x75, 0x20, 0x29, 0x79, 0x65, 0xb0, 0xd2, 0xde,
+    0x62, 0x21, 0xff, 0x00, 0x88, 0xf6, 0x9b, 0xa9, 0x52, 0x2a, 0xb2, 0xa1,
+    0x21, 0x6d, 0x21, 0x55, 0x37, 0x96, 0xce, 0xa1, 0xa4, 0xe8, 0x52, 0xc1,
+    0xbe, 0x9e, 0xc2, 0xd7, 0xdb, 0x12, 0x9e, 0x9c, 0xd2, 0xe6, 0xd5, 0x5f,
+    0x31, 0xe1, 0x34, 0xeb, 0xce, 0xa9, 0x77, 0x5a, 0x95, 0xe6, 0x48, 0x48,
+    0x16, 0x25, 0x46, 0xf6, 0x03, 0x91, 0x8b, 0xa6, 0x64, 0xa0, 0x53, 0xb3,
+    0x35, 0x3e, 0x43, 0x55, 0x17, 0x8b, 0x4d, 0x25, 0xe2, 0xe2, 0x8a, 0x57,
+    0xa7, 0x6b, 0x9b, 0x8b, 0x8c, 0x20, 0x55, 0xf3, 0xad, 0x03, 0x2c, 0x43,
+    0x5e, 0x5a, 0xca, 0x8c, 0xc6, 0x6e, 0xc7, 0x77, 0xd1, 0x65, 0x24, 0x2b,
+    0xde, 0xff, 0x00, 0x3e, 0x29, 0x53, 0xb4, 0xa6, 0x9e, 0x71, 0x2f, 0xbc,
+    0xab, 0x21, 0x09, 0x00, 0xff, 0x00, 0x3f, 0x66, 0x3e, 0x6d, 0xa0, 0xe2,
+    0x09, 0xa6, 0xd8, 0x5c, 0x8c, 0x8b, 0x65, 0x4f, 0x95, 0xa8, 0xdf, 0xf2,
+    0xa4, 0x13, 0xaf, 0xcf, 0x28, 0x6c, 0x8e, 0xec, 0x2c, 0xa7, 0x0d, 0x98,
+    0xad, 0x3d, 0xfc, 0x46, 0xa5, 0x21, 0x21, 0xa4, 0x45, 0x8e, 0x92, 0x55,
+    0xb7, 0x01, 0x29, 0xf4, 0xdc, 0xf9, 0x8f, 0xfa, 0x63, 0xe2, 0xa1, 0x42,
+    0xcc, 0xf5, 0x67, 0x04, 0xfa, 0xac, 0x96, 0xd8, 0x75, 0x2b, 0x40, 0x6a,
+    0x1b, 0x67, 0x59, 0x66, 0xff, 0x00, 0x4f, 0x99, 0x7f, 0xb0, 0xf7, 0xc0,
+    0x8c, 0x9b, 0x51, 0xa7, 0x46, 0xa6, 0xaa, 0x5c, 0xe9, 0xaf, 0x3d, 0x52,
+    0x99, 0xaf, 0xc5, 0x74, 0x2e, 0xca, 0x52, 0x38, 0xb1, 0x3f, 0x30, 0x16,
+    0xbe, 0xc2, 0xc3, 0x7c, 0x51, 0x1e, 0xcd, 0xd4, 0xc5, 0x25, 0xa8, 0xca,
+    0x9d, 0x09, 0x98, 0xcd, 0xa5, 0xb6, 0x8a, 0x84, 0x93, 0xad, 0x56, 0x1c,
+    0x9b, 0x26, 0xfe, 0xbb, 0x8e, 0x6f, 0x85, 0xaa, 0x96, 0x21, 0x2a, 0x4f,
+    0xe1, 0xa4, 0xc7, 0x0a, 0x34, 0xbe, 0xe7, 0xa7, 0x21, 0xef, 0x0e, 0x94,
+    0x6c, 0x22, 0xdc, 0xab, 0x9f, 0x8d, 0x9d, 0x3d, 0xac, 0xc1, 0xcc, 0x93,
+    0x98, 0x1d, 0x07, 0x84, 0x44, 0x73, 0x33, 0xd3, 0xe9, 0x30, 0x26, 0x95,
+    0xbb, 0xe3, 0x04, 0xb6, 0x94, 0x3e, 0x82, 0x2d, 0x72, 0x97, 0x08, 0xbe,
+    0xde, 0x84, 0x1c, 0x51, 0xba, 0x0d, 0x3d, 0x72, 0x29, 0x25, 0x6c, 0x48,
+    0x5b, 0x5a, 0x96, 0x97, 0x2e, 0xa2, 0x12, 0x1b, 0x00, 0x8b, 0xf3, 0x7b,
+    0xdf, 0xb6, 0x17, 0xb3, 0x4c, 0x5a, 0x6d, 0x43, 0x2d, 0x66, 0x37, 0x20,
+    0xba, 0x99, 0x29, 0x44, 0x67, 0x9c, 0x2e, 0x24, 0x6c, 0x56, 0x97, 0x8a,
+    0xbf, 0xf8, 0xd8, 0xfd, 0xf1, 0xf5, 0xf8, 0x7d, 0x6c, 0x38, 0x66, 0x43,
+    0x4a, 0x1d, 0xf0, 0x8b, 0xc1, 0xd0, 0x7c, 0x3b, 0xa5, 0x28, 0xd3, 0x7b,
+    0x0b, 0x5f, 0xbe, 0xd6, 0x27, 0x1e, 0x63, 0x04, 0x36, 0x4b, 0x2e, 0xb7,
+    0xba, 0x47, 0xb4, 0x3e, 0xcf, 0xa5, 0x60, 0xa0, 0xab, 0x74, 0x88, 0x1f,
+    0x4d, 0x6a, 0x75, 0x5a, 0x85, 0x98, 0xe0, 0xb0, 0x94, 0x95, 0x49, 0x75,
+    0xb6, 0xc0, 0xe6, 0xc0, 0x5a, 0xdb, 0xfa, 0x5b, 0x9c, 0x13, 0xc9, 0xf5,
+    0xea, 0x5f, 0x4b, 0xa2, 0x4c, 0xa8, 0xc4, 0x9e, 0xc2, 0x6b, 0x13, 0x9b,
+    0x51, 0x54, 0x94, 0xb4, 0x16, 0xea, 0x49, 0x04, 0x14, 0xb6, 0x54, 0x3c,
+    0xa9, 0x17, 0xed, 0xb9, 0x3e, 0x98, 0x0f, 0x42, 0x62, 0xa9, 0x22, 0x74,
+    0xb8, 0x14, 0xe9, 0x11, 0x23, 0xc7, 0x92, 0xe0, 0x52, 0xca, 0x95, 0xa0,
+    0x71, 0x62, 0x9d, 0x86, 0xff, 0x00, 0x41, 0x6b, 0xf0, 0x4e, 0x08, 0x37,
+    0xd1, 0x25, 0x57, 0x67, 0x99, 0x55, 0x4c, 0xd8, 0xb5, 0xb8, 0xad, 0x92,
+    0x94, 0x37, 0xa7, 0x48, 0xec, 0x07, 0x60, 0x31, 0x96, 0x6b, 0x15, 0x52,
+    0x29, 0xf2, 0xad, 0x05, 0xaa, 0xee, 0x84, 0x81, 0xa1, 0x36, 0xc8, 0x5e,
+    0xff, 0x00, 0x7e, 0xd1, 0x3c, 0x6b, 0x0b, 0x55, 0xa7, 0x66, 0x5e, 0xba,
+    0xb8, 0x18, 0x52, 0xf8, 0xb2, 0x20, 0x15, 0x1d, 0xb3, 0xfb, 0xf3, 0x3a,
+    0x0a, 0x8d, 0x2e, 0xa1, 0x99, 0xd9, 0x12, 0x98, 0xab, 0x13, 0x50, 0x64,
+    0x87, 0x9b, 0xf1, 0x1c, 0xb0, 0x48, 0xd4, 0x76, 0x1f, 0xdd, 0x1e, 0xa7,
+    0xe8, 0x37, 0xbe, 0x1b, 0xe9, 0x35, 0x68, 0x53, 0x99, 0x55, 0x32, 0x7c,
+    0x66, 0x51, 0x53, 0x41, 0x0e, 0x3c, 0xeb, 0x29, 0x1e, 0x1b, 0x8d, 0x95,
+    0x69, 0x0b, 0xd8, 0xec, 0x49, 0x3f, 0x4d, 0xb0, 0x73, 0x2e, 0xf4, 0x5f,
+    0x24, 0xd0, 0x90, 0xbf, 0x8e, 0xcd, 0x32, 0x8b, 0x65, 0x43, 0xc4, 0x02,
+    0x62, 0x12, 0x92, 0x47, 0xaf, 0x9a, 0xe7, 0xe9, 0x86, 0x58, 0x39, 0x6b,
+    0xa3, 0x14, 0x79, 0xc9, 0x9a, 0xe5, 0x4a, 0x13, 0xb2, 0xda, 0x01, 0x21,
+    0xc7, 0x65, 0xeb, 0xb0, 0x1c, 0x6c, 0x4e, 0x9b, 0x62, 0x73, 0x52, 0xc5,
+    0xcd, 0x4d, 0x3a, 0x57, 0xc2, 0xb5, 0x93, 0xc9, 0x3f, 0xc6, 0x50, 0xf7,
+    0x23, 0x4e, 0x44, 0xab, 0x61, 0xb6, 0x80, 0x00, 0x6c, 0x9f, 0xd8, 0x6b,
+    0xce, 0x1b, 0x24, 0x43, 0x99, 0x1a, 0x65, 0x00, 0x38, 0xb5, 0x29, 0x25,
+    0xa5, 0xb4, 0xbb, 0x7a, 0xea, 0x40, 0xfe, 0x98, 0xf0, 0xae, 0xcd, 0xc9,
+    0x3d, 0x32, 0x7a, 0xa7, 0x99, 0x24, 0x31, 0x09, 0x35, 0x49, 0x48, 0x4a,
+    0x65, 0xc9, 0x2b, 0x25, 0xd2, 0x81, 0xc2, 0x4a, 0xbf, 0x28, 0x3f, 0xdc,
+    0x4e, 0xe4, 0xf3, 0x7c, 0x22, 0x75, 0xaf, 0xad, 0x59, 0x7e, 0x9b, 0x0e,
+    0x9f, 0x13, 0x2c, 0x4c, 0x6e, 0x6c, 0xf2, 0xfa, 0x34, 0xe8, 0x21, 0xd0,
+    0x11, 0xbe, 0xa2, 0x42, 0x4d, 0xf7, 0xd8, 0x0e, 0x09, 0x3c, 0x71, 0x88,
+    0xd6, 0x70, 0xcd, 0x31, 0xf3, 0x25, 0x41, 0x2e, 0xd5, 0x68, 0x95, 0x29,
+    0xe9, 0x4a, 0x8a, 0xc3, 0x0b, 0x49, 0x4a, 0x50, 0xa3, 0xed, 0xdc, 0xf6,
+    0xb9, 0xdf, 0x18, 0xf0, 0xa6, 0x0d, 0xa8, 0x55, 0x07, 0x6a, 0xb5, 0x76,
+    0x4d, 0xd8, 0x85, 0x0c, 0xee, 0x41, 0x37, 0xb5, 0xad, 0xa1, 0xf1, 0xcb,
+    0x2d, 0xe3, 0xde, 0xa9, 0x5b, 0x6a, 0x59, 0x09, 0x41, 0x69, 0x4e, 0x2f,
+    0x50, 0x00, 0x16, 0xbe, 0xd7, 0x37, 0xca, 0xc3, 0x61, 0x99, 0xbe, 0xd0,
+    0xe3, 0x37, 0xac, 0xc9, 0xcd, 0xb9, 0x8d, 0x72, 0x65, 0xca, 0x8d, 0x1a,
+    0x9f, 0x1d, 0xc0, 0x98, 0xa8, 0x20, 0x0d, 0x42, 0xe4, 0x03, 0x63, 0xb8,
+    0x16, 0x37, 0xb7, 0x3f, 0xd0, 0x3d, 0x2b, 0xa9, 0x52, 0xa8, 0xb5, 0x1b,
+    0xc2, 0x9e, 0xa9, 0x3e, 0x0a, 0xac, 0xea, 0x96, 0x92, 0xef, 0x8e, 0x02,
+    0x48, 0xb6, 0xc3, 0x6d, 0xcf, 0x3e, 0xc3, 0x1e, 0x39, 0x2a, 0x3c, 0x19,
+    0xad, 0x95, 0x46, 0xc8, 0xae, 0xb0, 0x11, 0x75, 0x17, 0x9d, 0x6d, 0x94,
+    0x22, 0xd7, 0xb5, 0xb5, 0x38, 0x40, 0xf6, 0xe4, 0x9f, 0x6c, 0x13, 0x55,
+    0x4e, 0xbe, 0x89, 0x0e, 0xb1, 0x0b, 0x25, 0x25, 0xf0, 0xcb, 0xab, 0x6c,
+    0x3a, 0xd8, 0x6d, 0x68, 0x5d, 0xb7, 0xd8, 0xa4, 0xd8, 0xd8, 0x11, 0x72,
+    0x0d, 0xb1, 0x5d, 0x63, 0x05, 0xca, 0xa1, 0x29, 0x42, 0x5c, 0xb0, 0x1a,
+    0x00, 0x3f, 0x7b, 0xf9, 0x98, 0x4a, 0xfe, 0xb9, 0x5b, 0x71, 0xc2, 0x96,
+    0xa4, 0x14, 0xa2, 0x79, 0xe5, 0x97, 0x90, 0xb5, 0xba, 0x46, 0xf3, 0x75,
+    0x37, 0x73, 0x65, 0x1e, 0xb1, 0x53, 0x96, 0xd2, 0x51, 0x25, 0xe8, 0x2a,
+    0x43, 0x89, 0x4b, 0x6a, 0x4e, 0xe1, 0xb2, 0x01, 0x37, 0xee, 0x7f, 0x7b,
+    0x13, 0x8d, 0x2a, 0xad, 0x06, 0xac, 0xed, 0x0f, 0x2f, 0xcd, 0x85, 0x49,
+    0x95, 0x22, 0x3b, 0xb4, 0xb6, 0x42, 0x5c, 0x61, 0xa5, 0x2c, 0x13, 0xa4,
+    0x13, 0x7b, 0x0d, 0x8d, 0xcf, 0x7c, 0x7d, 0x48, 0x77, 0xa8, 0xd2, 0xe9,
+    0xef, 0xf8, 0x39, 0x6d, 0x2c, 0xc7, 0x28, 0x50, 0x71, 0x20, 0x04, 0xdd,
+    0x36, 0xdc, 0x12, 0x2e, 0x78, 0xf4, 0xdf, 0x1e, 0x1d, 0x31, 0xce, 0x99,
+    0xaa, 0x9b, 0x96, 0xc5, 0x39, 0xfa, 0xb5, 0x3a, 0x0e, 0x95, 0xa9, 0xa6,
+    0x93, 0xf1, 0x0a, 0x42, 0x96, 0x80, 0x4d, 0xb5, 0x24, 0x0b, 0x0b, 0x5e,
+    0xc0, 0x92, 0x36, 0x03, 0x1a, 0xeb, 0xf4, 0xd0, 0xe4, 0xa3, 0x52, 0xa8,
+    0x24, 0xf0, 0xee, 0x6c, 0x32, 0x1c, 0xc9, 0xb0, 0x83, 0x38, 0x0e, 0x7a,
+    0xa5, 0x86, 0x2a, 0x53, 0x35, 0x2a, 0x8b, 0x25, 0x01, 0xdd, 0x12, 0x02,
+    0x95, 0x9f, 0x44, 0x82, 0x72, 0x19, 0xe9, 0x68, 0x13, 0x23, 0x20, 0x67,
+    0x9a, 0xa2, 0xd2, 0x5a, 0xa5, 0xaa, 0x24, 0x72, 0x6c, 0x16, 0xf1, 0xd3,
+    0x72, 0x76, 0x16, 0xc3, 0x36, 0x42, 0xe9, 0x8e, 0x68, 0xa5, 0x3a, 0xec,
+    0x31, 0x5e, 0xa2, 0x35, 0x2a, 0x45, 0x99, 0x0d, 0xf8, 0xda, 0x9c, 0x4a,
+    0xb7, 0x16, 0x00, 0x7e, 0x6d, 0xef, 0xf5, 0x03, 0x04, 0x17, 0x54, 0xcc,
+    0x09, 0x74, 0x3e, 0xac, 0xcd, 0x1d, 0x85, 0x83, 0xa8, 0x29, 0x0b, 0x2a,
+    0x50, 0xf7, 0x1e, 0x71, 0x8d, 0x79, 0xf9, 0x8e, 0xb7, 0xf0, 0x4e, 0xd3,
+    0x0e, 0x64, 0x68, 0xb6, 0xe5, 0xd0, 0xa9, 0xa1, 0xd8, 0xed, 0xad, 0x77,
+    0x37, 0x2a, 0xb6, 0x92, 0xb2, 0x77, 0x3c, 0xaa, 0xfe, 0xf8, 0x0a, 0xde,
+    0x16, 0x9c, 0x29, 0xe0, 0x20, 0x01, 0xd4, 0x7d, 0x2f, 0x05, 0x2a, 0xbf,
+    0x13, 0xe8, 0x73, 0x93, 0x05, 0xd2, 0x54, 0xe2, 0x8f, 0x81, 0x00, 0x0f,
+    0x00, 0x48, 0x19, 0x72, 0xd4, 0xc1, 0x8c, 0xbf, 0xd0, 0xc9, 0x10, 0xa5,
+    0x2e, 0x54, 0x9c, 0xe1, 0x19, 0x84, 0xa9, 0x65, 0x4a, 0x07, 0x65, 0x13,
+    0xde, 0xfa, 0xad, 0x7d, 0xfd, 0x71, 0x4a, 0xcf, 0x79, 0x96, 0x83, 0x46,
+    0xca, 0xb1, 0x62, 0xbb, 0x5c, 0x8b, 0x29, 0xf8, 0xcf, 0x32, 0xe2, 0xfc,
+    0x35, 0x02, 0x43, 0x6d, 0x24, 0xdd, 0x4a, 0xb6, 0xc3, 0xf2, 0x8d, 0xf9,
+    0x27, 0x10, 0x77, 0x17, 0x45, 0xf1, 0x94, 0x26, 0x66, 0xb9, 0x4f, 0xac,
+    0x9e, 0x4a, 0x91, 0x73, 0xf7, 0xb1, 0xc7, 0xb5, 0x7b, 0x2a, 0x51, 0x6a,
+    0x79, 0x3e, 0x5c, 0xc8, 0x95, 0x19, 0xcf, 0xa9, 0xa4, 0xeb, 0xb2, 0x9f,
+    0x51, 0x06, 0xde, 0xa3, 0x83, 0x82, 0xac, 0xe1, 0xa9, 0x86, 0x7b, 0xe9,
+    0x29, 0xe2, 0xea, 0x4f, 0xd2, 0x03, 0x2f, 0xe2, 0x75, 0x19, 0xa7, 0x12,
+    0x7b, 0x27, 0x2d, 0x71, 0x6e, 0xe8, 0x02, 0xfb, 0x5c, 0xdc, 0x9b, 0x40,
+    0x2c, 0xcf, 0x57, 0xa5, 0xc9, 0x6e, 0x75, 0x35, 0x55, 0xa5, 0xb1, 0x19,
+    0xc7, 0x54, 0x7c, 0x26, 0x93, 0x7b, 0x79, 0x89, 0xb0, 0x3b, 0x6d, 0x85,
+    0x08, 0xd4, 0x6c, 0xa4, 0xf4, 0x84, 0x80, 0x9a, 0x9c, 0x85, 0x13, 0x62,
+    0xb2, 0xda, 0x95, 0xfa, 0x01, 0x8e, 0x87, 0x43, 0xf1, 0x29, 0x61, 0x8a,
+    0x76, 0x5c, 0xc9, 0xf4, 0x09, 0x50, 0x62, 0x46, 0x6c, 0x27, 0xc6, 0x6c,
+    0xba, 0xe3, 0xde, 0x51, 0xa9, 0x45, 0x77, 0xe4, 0x9b, 0xf0, 0x0f, 0xdf,
+    0x18, 0xff, 0x00, 0x54, 0x59, 0xa4, 0x7f, 0x66, 0x3a, 0x74, 0xc4, 0x37,
+    0x00, 0xf9, 0xda, 0x4a, 0x54, 0x01, 0xf6, 0xf2, 0x7f, 0xa8, 0x18, 0x2d,
+    0x3f, 0x3d, 0x34, 0x5b, 0x4a, 0x9e, 0x65, 0x27, 0xc8, 0x9b, 0x75, 0x17,
+    0xfa, 0x43, 0xf4, 0xae, 0x1a, 0x69, 0x94, 0x87, 0x99, 0x96, 0x48, 0x0b,
+    0xef, 0x1b, 0x01, 0xbe, 0xe7, 0x33, 0x6f, 0x41, 0x12, 0x68, 0xb9, 0x4d,
+    0x86, 0x23, 0x7c, 0x44, 0x6a, 0x0d, 0x5a, 0x53, 0x62, 0xca, 0xf2, 0xc5,
+    0x74, 0x5c, 0x7d, 0x54, 0x9b, 0x71, 0xef, 0x82, 0xf0, 0x32, 0x95, 0x69,
+    0x6f, 0x29, 0x11, 0xb2, 0x24, 0x97, 0xd2, 0x4d, 0xd2, 0x5f, 0x6c, 0xa4,
+    0xe9, 0x3c, 0x5c, 0x0b, 0x8c, 0x33, 0x2b, 0xac, 0x14, 0x79, 0x95, 0x37,
+    0x6a, 0x2b, 0xca, 0x2e, 0xbb, 0x31, 0x0b, 0x4b, 0x8a, 0x2a, 0x71, 0xd2,
+    0x02, 0xbb, 0x10, 0x92, 0x42, 0x47, 0x1c, 0x01, 0x82, 0x8b, 0xeb, 0x4e,
+    0x66, 0x76, 0x58, 0x71, 0x14, 0xe9, 0x11, 0x12, 0xf0, 0xd4, 0x35, 0x35,
+    0x74, 0xda, 0xc3, 0x72, 0x49, 0x36, 0xda, 0xdc, 0xe1, 0x69, 0x58, 0x8d,
+    0x6d, 0x9e, 0xe8, 0x48, 0xe8, 0x91, 0x1d, 0x84, 0xc2, 0x19, 0x3c, 0x29,
+    0x09, 0x1e, 0x9f, 0x40, 0x60, 0x2b, 0x99, 0x1f, 0xa9, 0x12, 0x68, 0x52,
+    0xa0, 0xc4, 0xa0, 0xc3, 0xa7, 0x46, 0x76, 0x3a, 0xdb, 0x5a, 0x02, 0x14,
+    0x14, 0xa4, 0x11, 0xba, 0x45, 0xc5, 0x85, 0xfd, 0x70, 0x13, 0xa5, 0xd9,
+    0x39, 0xd8, 0xcb, 0xf0, 0x5a, 0x9d, 0x32, 0x9a, 0xea, 0xd6, 0x59, 0x90,
+    0x1a, 0x59, 0x2a, 0x4a, 0xfd, 0x2c, 0x38, 0xb5, 0xb1, 0xd1, 0x7d, 0x1c,
+    0xcd, 0x33, 0xb3, 0x35, 0x0d, 0xea, 0x9c, 0x97, 0x94, 0xb2, 0xd4, 0xa2,
+    0xc3, 0x8d, 0xad, 0x20, 0x8b, 0x69, 0x06, 0xe0, 0x81, 0xf5, 0x18, 0x8b,
+    0xe7, 0x5f, 0x8a, 0xa4, 0x75, 0x36, 0xac, 0x23, 0xad, 0x49, 0x40, 0x9e,
+    0x56, 0x50, 0xa2, 0x40, 0x20, 0x80, 0x47, 0x18, 0x15, 0x58, 0x9f, 0x76,
+    0x71, 0xa4, 0xba, 0xb5, 0x5c, 0x79, 0x0f, 0xbd, 0x20, 0x7c, 0xea, 0xbf,
+    0x11, 0x72, 0x75, 0x1f, 0x28, 0x97, 0x3a, 0xc5, 0x52, 0xb5, 0x29, 0x70,
+    0x68, 0xb2, 0xdc, 0x8f, 0x31, 0x0d, 0x97, 0x95, 0xe1, 0x91, 0x7d, 0xd4,
+    0x76, 0xbd, 0xf6, 0xb5, 0xb9, 0xde, 0xfb, 0x61, 0x36, 0xb9, 0xfc, 0xcf,
+    0x47, 0x7c, 0xb5, 0x57, 0x7e, 0xb3, 0xc6, 0xea, 0x4c, 0x85, 0x14, 0x1f,
+    0xdf, 0x0d, 0x9d, 0x3b, 0x8f, 0x36, 0x99, 0x9b, 0xeb, 0x4b, 0x1a, 0x89,
+    0x6a, 0x31, 0xb1, 0x4f, 0x3a, 0x49, 0x2b, 0xb8, 0x27, 0xd8, 0x7e, 0xa7,
+    0x1e, 0x39, 0x6b, 0xa9, 0x5f, 0x1c, 0xfb, 0xb1, 0x6b, 0xd1, 0x14, 0xe2,
+    0x5c, 0x73, 0x50, 0x79, 0xb4, 0xa5, 0x6a, 0x48, 0x1c, 0x02, 0x95, 0x6c,
+    0xa0, 0x2f, 0xc6, 0x1b, 0xa9, 0x32, 0xf2, 0x32, 0xf2, 0x4d, 0xad, 0x49,
+    0x4f, 0x12, 0xaf, 0x9a, 0x80, 0x39, 0xf9, 0xe9, 0x12, 0x49, 0xfa, 0xa5,
+    0x4c, 0x4f, 0xbc, 0x86, 0x87, 0x1b, 0x68, 0xb6, 0x40, 0xd8, 0x8b, 0xf2,
+    0x84, 0x96, 0xaa, 0xce, 0xc8, 0x64, 0xc4, 0x65, 0x87, 0x54, 0xca, 0xc5,
+    0x94, 0x84, 0xb2, 0x92, 0x55, 0xbd, 0xcf, 0x98, 0xdc, 0xfe, 0xf8, 0xd9,
+    0x4b, 0xae, 0x34, 0x14, 0xf2, 0xe8, 0x0c, 0x21, 0x29, 0xdc, 0xf8, 0x82,
+    0xc7, 0xf4, 0xbe, 0x2a, 0xa7, 0x28, 0xb1, 0x2d, 0x46, 0xab, 0x95, 0xaa,
+    0x10, 0x52, 0xf2, 0x95, 0xe2, 0xa5, 0xa4, 0x37, 0x76, 0xaf, 0x6e, 0x34,
+    0x9d, 0xc7, 0xaf, 0xd7, 0x08, 0x35, 0x18, 0xf2, 0x20, 0xd4, 0x16, 0xc5,
+    0x5d, 0x2a, 0x65, 0xf0, 0x8b, 0x8f, 0x35, 0xc1, 0xed, 0xa8, 0x11, 0xee,
+    0x38, 0xc7, 0x5a, 0x85, 0x4e, 0xa9, 0x4f, 0x1c, 0x69, 0x42, 0x78, 0x79,
+    0x81, 0xf7, 0x6f, 0x94, 0x68, 0xa3, 0xcc, 0x53, 0x6a, 0xaa, 0x2d, 0xa5,
+    0x44, 0x2f, 0x74, 0x9b, 0x83, 0xe3, 0xd6, 0x19, 0xfa, 0x3f, 0x06, 0x8b,
+    0x5b, 0xcf, 0xf4, 0x09, 0x4f, 0xc0, 0x43, 0x5e, 0x12, 0x1d, 0x79, 0x2d,
+    0xa1, 0x45, 0x20, 0xba, 0x84, 0x9d, 0x17, 0x23, 0x7b, 0x03, 0x63, 0xf6,
+    0xb6, 0x3a, 0x0e, 0xbb, 0xd3, 0xa6, 0x44, 0x24, 0x0c, 0xbd, 0x3d, 0xba,
+    0x6c, 0xb2, 0xd8, 0x21, 0xb5, 0x30, 0x85, 0xa1, 0x47, 0xd4, 0x02, 0x2e,
+    0x2f, 0xed, 0x8e, 0x7e, 0xfc, 0x3c, 0x32, 0xb7, 0xb3, 0xe5, 0x27, 0x72,
+    0xa4, 0x21, 0x52, 0x75, 0x90, 0x3e, 0x54, 0xe8, 0x51, 0xfe, 0x98, 0x6c,
+    0xfc, 0x47, 0xe7, 0xdc, 0xd7, 0x94, 0xb3, 0xed, 0x1d, 0xda, 0x05, 0x5d,
+    0x71, 0xdb, 0x11, 0x0a, 0x8b, 0x7a, 0x02, 0x9b, 0x76, 0xe4, 0x6c, 0xb4,
+    0x91, 0xb8, 0xed, 0x89, 0xee, 0x39, 0x99, 0xaa, 0xb9, 0x88, 0xd8, 0x44,
+    0x8b, 0xe5, 0xb2, 0x5a, 0x0a, 0xf0, 0xdf, 0x23, 0xcf, 0x6d, 0x61, 0xef,
+    0x0d, 0x38, 0xdc, 0x9d, 0x35, 0xc5, 0x9f, 0xca, 0xb2, 0x0e, 0xe6, 0xd7,
+    0x00, 0x7c, 0xe0, 0x1f, 0x50, 0x8f, 0x55, 0xf2, 0xa3, 0xaa, 0x45, 0x4a,
+    0x04, 0x79, 0xb0, 0x55, 0xb8, 0x91, 0x19, 0x8d, 0x4d, 0xaa, 0xde, 0xa3,
+    0x80, 0x47, 0xd3, 0x09, 0xea, 0xae, 0xf5, 0x11, 0x6d, 0xa5, 0xc7, 0x1c,
+    0x99, 0x15, 0xbd, 0x65, 0x01, 0x49, 0x8b, 0xa0, 0x6a, 0xb5, 0xf4, 0x8b,
+    0x27, 0x9d, 0x8f, 0xe9, 0x8b, 0x87, 0x4c, 0xba, 0xd9, 0x4b, 0xce, 0x4d,
+    0xff, 0x00, 0x07, 0xcc, 0x94, 0x71, 0x16, 0x72, 0x80, 0x05, 0x6d, 0x5d,
+    0x71, 0xdd, 0x27, 0x61, 0x71, 0xc8, 0x37, 0x3d, 0xef, 0xcf, 0x38, 0x79,
+    0x9f, 0x93, 0x8c, 0x58, 0x4e, 0xd4, 0x68, 0xf2, 0x4b, 0x4c, 0xdb, 0x53,
+    0x8c, 0x2c, 0x6a, 0x09, 0x23, 0x6f, 0x29, 0x3b, 0x8f, 0x4f, 0xbe, 0x04,
+    0x9c, 0x77, 0x52, 0x92, 0x58, 0x97, 0xa9, 0xdd, 0x2a, 0xe6, 0x0e, 0x47,
+    0xd2, 0x0e, 0x25, 0x2e, 0x4c, 0x27, 0x8d, 0xa7, 0x8d, 0x8e, 0xd7, 0xb7,
+    0x95, 0xf5, 0xf5, 0xf5, 0x89, 0x1f, 0x47, 0xa4, 0x67, 0x06, 0x27, 0x4a,
+    0x35, 0xc7, 0x25, 0x86, 0xd4, 0xd1, 0x08, 0xf1, 0x52, 0x52, 0x1c, 0xba,
+    0x55, 0x71, 0xbf, 0xd0, 0x1f, 0xbe, 0x00, 0xaf, 0x5c, 0xa8, 0x5a, 0x94,
+    0x10, 0x5a, 0x84, 0xcb, 0x81, 0x5c, 0x27, 0x48, 0xf1, 0xd4, 0x3e, 0xe4,
+    0x95, 0x7b, 0x9f, 0xd3, 0x14, 0x2f, 0xe6, 0xaa, 0x6d, 0x4d, 0x6c, 0xd3,
+    0xdb, 0x42, 0x5a, 0x79, 0x32, 0x1d, 0x2a, 0x4a, 0x2e, 0x92, 0x2c, 0x40,
+    0xb6, 0xae, 0x49, 0xb0, 0xb9, 0x3e, 0xf8, 0x47, 0xcc, 0xb4, 0xc3, 0x4a,
+    0x6d, 0x6b, 0x2e, 0x25, 0xc2, 0xe4, 0xa7, 0xc1, 0x08, 0xb8, 0x03, 0x4b,
+    0xa4, 0xff, 0x00, 0xa1, 0x18, 0x6f, 0xa9, 0xce, 0x2e, 0x6a, 0x8a, 0xda,
+    0x9c, 0x37, 0x25, 0x47, 0xdb, 0xf9, 0x87, 0x1c, 0x20, 0xa3, 0xda, 0x25,
+    0xc3, 0x9a, 0x80, 0x56, 0xb9, 0x9d, 0xb7, 0x85, 0x77, 0xe9, 0xb4, 0xfa,
+    0xab, 0x28, 0x11, 0xe7, 0x2e, 0x39, 0x24, 0x85, 0xad, 0x06, 0xc1, 0x06,
+    0xfe, 0xd7, 0xfb, 0xed, 0x82, 0x39, 0x17, 0x2c, 0xd0, 0xd9, 0x9e, 0xf4,
+    0x3c, 0xcf, 0x54, 0x5f, 0x88, 0xbb, 0x18, 0x8b, 0x5b, 0xc4, 0xb6, 0xbd,
+    0xf9, 0x0a, 0x1d, 0xfd, 0xb6, 0xf4, 0xb6, 0x25, 0x94, 0xb9, 0x92, 0x62,
+    0x49, 0x75, 0xd8, 0xce, 0xa9, 0xb5, 0x29, 0xc5, 0x6d, 0x7d, 0xb9, 0x3b,
+    0x1c, 0x51, 0x28, 0x4e, 0x48, 0xaa, 0xd2, 0x5e, 0x79, 0xf8, 0xbe, 0x46,
+    0x52, 0x95, 0x2c, 0x84, 0xdd, 0x04, 0x15, 0x69, 0xe7, 0xd6, 0xfd, 0xb0,
+    0x15, 0xd3, 0x31, 0x2c, 0x9b, 0x71, 0x92, 0x9e, 0xb0, 0x2a, 0x5d, 0x9a,
+    0x26, 0x2b, 0x50, 0x2a, 0x68, 0x31, 0x30, 0xad, 0xc0, 0x04, 0x28, 0xfb,
+    0x67, 0xd7, 0x3f, 0x13, 0x15, 0xe8, 0x99, 0x07, 0x2d, 0x48, 0x6d, 0x0d,
+    0xc5, 0x61, 0x12, 0xdc, 0x5b, 0x6e, 0x5d, 0xa5, 0x2f, 0xec, 0x13, 0xb8,
+    0x3c, 0x1b, 0x0d, 0xf7, 0xbd, 0xce, 0x05, 0xc1, 0xa4, 0x39, 0x43, 0xca,
+    0x15, 0x0a, 0x3b, 0xad, 0x84, 0x2e, 0x3b, 0x6f, 0xb4, 0x42, 0x56, 0x5c,
+    0x06, 0xc5, 0x44, 0x79, 0xac, 0x2e, 0x34, 0xdb, 0x7b, 0x0c, 0x2b, 0x65,
+    0x9a, 0xcd, 0x47, 0x2d, 0xa0, 0xaa, 0x33, 0xea, 0x72, 0x1b, 0xab, 0xb2,
+    0xa3, 0xea, 0x1a, 0xae, 0x3c, 0xd7, 0x07, 0xe6, 0xb5, 0xff, 0x00, 0xec,
+    0x61, 0xd2, 0x7e, 0x67, 0x6b, 0x30, 0x49, 0x9a, 0xb0, 0x9f, 0x04, 0x2c,
+    0x36, 0x1f, 0xb6, 0xc0, 0x21, 0x68, 0x20, 0x8d, 0xb8, 0xb5, 0xb0, 0xc7,
+    0x84, 0x66, 0x82, 0xa7, 0x14, 0x39, 0xa4, 0xfd, 0x22, 0x3f, 0xf1, 0x5f,
+    0x0e, 0xcc, 0x52, 0x24, 0xd0, 0xdb, 0x80, 0x1b, 0x2d, 0x26, 0xe3, 0x96,
+    0x63, 0xe7, 0x1a, 0xf4, 0xf9, 0xb2, 0xe3, 0xe5, 0xb9, 0x2f, 0xb6, 0x99,
+    0x09, 0x53, 0x71, 0xf4, 0x25, 0xc4, 0x70, 0x8b, 0x2b, 0x7b, 0xff, 0x00,
+    0x97, 0xd3, 0x08, 0x59, 0x5f, 0xab, 0x71, 0xd2, 0xa5, 0xc5, 0xae, 0x53,
+    0x64, 0x25, 0xbd, 0x56, 0xf8, 0x86, 0x5e, 0x2a, 0x5a, 0x2c, 0x6f, 0x7b,
+    0x1e, 0x37, 0xdf, 0x6c, 0x58, 0xd2, 0xdd, 0x2e, 0xa5, 0xd2, 0x9a, 0x1f,
+    0xf0, 0xc2, 0xcf, 0xc5, 0xae, 0x0b, 0xc2, 0x62, 0x19, 0xf9, 0x8d, 0xd3,
+    0xb2, 0x96, 0x3e, 0xa9, 0xef, 0x8e, 0x46, 0x7d, 0x6b, 0x8b, 0x52, 0x93,
+    0x09, 0xc4, 0x95, 0xa1, 0x0f, 0xad, 0x36, 0x1c, 0xde, 0xe4, 0x6d, 0x83,
+    0x75, 0x4a, 0x93, 0xe8, 0x29, 0x71, 0xbc, 0xb6, 0x3e, 0x36, 0x8a, 0x83,
+    0xd5, 0xe9, 0x96, 0x29, 0xb2, 0x4e, 0xb2, 0x78, 0x41, 0x4d, 0x88, 0x23,
+    0x5b, 0x00, 0x05, 0xf7, 0xd8, 0xe9, 0x1d, 0x04, 0xec, 0xac, 0xbb, 0x9a,
+    0xa0, 0xae, 0x45, 0x3a, 0xb4, 0x15, 0x2d, 0xb2, 0x16, 0xd1, 0x69, 0x94,
+    0xb6, 0xf2, 0x8d, 0xff, 0x00, 0x38, 0xb5, 0x96, 0x07, 0x3c, 0x5f, 0x1f,
+    0x12, 0x8e, 0x69, 0x0d, 0x33, 0x26, 0xa0, 0x83, 0x52, 0x84, 0x96, 0xf4,
+    0x78, 0x91, 0xd0, 0x94, 0x92, 0x9b, 0x8f, 0x99, 0x36, 0xb1, 0xe3, 0x8d,
+    0xb0, 0x1f, 0xa4, 0x19, 0x3e, 0x7c, 0x69, 0x10, 0xf3, 0x0b, 0x8c, 0x7c,
+    0x38, 0x68, 0x97, 0x63, 0xb0, 0xf1, 0xf3, 0xba, 0x46, 0xe0, 0x1e, 0x39,
+    0xf4, 0xed, 0x83, 0x15, 0xac, 0xf6, 0xed, 0x26, 0x24, 0x88, 0x34, 0x94,
+    0xaf, 0xc6, 0xd4, 0x4b, 0xcb, 0x6d, 0x37, 0xd1, 0x7d, 0xac, 0x3d, 0xf9,
+    0xdb, 0x9c, 0x63, 0x5c, 0x8c, 0xac, 0xcc, 0xa9, 0x76, 0x75, 0x01, 0xbe,
+    0x56, 0xca, 0xfe, 0x50, 0xc0, 0xd2, 0x18, 0x9a, 0x94, 0x33, 0x33, 0xcd,
+    0x04, 0x11, 0xbd, 0xed, 0x97, 0x80, 0xd7, 0xa0, 0xb1, 0x31, 0x7b, 0xe9,
+    0x12, 0xe8, 0xec, 0xe5, 0x1b, 0xd3, 0x65, 0x25, 0x2b, 0x7e, 0x38, 0x94,
+    0xb2, 0xa5, 0x15, 0x0b, 0x8d, 0x8d, 0xc6, 0xd6, 0x20, 0x1d, 0xc0, 0xe0,
+    0x8c, 0x47, 0xfa, 0xd7, 0x35, 0x11, 0x33, 0xed, 0x55, 0xe7, 0x8b, 0x6a,
+    0xd4, 0x84, 0xb8, 0x46, 0xab, 0x0b, 0x80, 0x47, 0xef, 0x6c, 0x6c, 0xf4,
+    0x0a, 0x53, 0xf3, 0xe4, 0xd4, 0x59, 0xbc, 0x86, 0x5b, 0x4c, 0x72, 0xd8,
+    0x4b, 0xbb, 0x06, 0xf5, 0x21, 0x57, 0x1f, 0x5b, 0x81, 0x7c, 0x2a, 0x7e,
+    0x26, 0x9b, 0x7e, 0x36, 0x64, 0x8b, 0xe6, 0x4b, 0xa8, 0x98, 0xd2, 0x3c,
+    0xac, 0x82, 0xa2, 0xa0, 0x9b, 0x77, 0x23, 0x6d, 0xf7, 0xc2, 0x83, 0xbc,
+    0x0b, 0x68, 0x34, 0x9d, 0x02, 0xb2, 0xe9, 0x09, 0xce, 0x80, 0x86, 0x94,
+    0xb4, 0x1b, 0x8b, 0x9d, 0x75, 0xb5, 0xf2, 0x8d, 0x18, 0x68, 0x47, 0xf3,
+    0x58, 0x60, 0x04, 0x24, 0x96, 0x46, 0xab, 0xaa, 0xdb, 0x59, 0x69, 0x23,
+    0x7e, 0xe4, 0xf6, 0x18, 0x8c, 0x65, 0x88, 0x92, 0xe5, 0xd7, 0xfe, 0x12,
+    0x23, 0x0b, 0x79, 0xd5, 0x28, 0xa7, 0x4a, 0x47, 0xbf, 0xed, 0x8b, 0x58,
+    0x8b, 0x1d, 0x59, 0xe9, 0xb6, 0xd6, 0xa0, 0xd2, 0x1c, 0x80, 0x95, 0x6c,
+    0x6c, 0x51, 0xe6, 0x26, 0xff, 0x00, 0x6e, 0x70, 0x0e, 0xa7, 0x99, 0x72,
+    0xbe, 0x49, 0x79, 0xf6, 0x29, 0x30, 0x99, 0x9c, 0xe3, 0xaa, 0xd6, 0xe0,
+    0x4a, 0x8a, 0x75, 0x2b, 0x7b, 0x82, 0x46, 0xf6, 0x3d, 0xc6, 0x1e, 0xa4,
+    0xe4, 0x91, 0x35, 0x4c, 0x61, 0x4e, 0x2a, 0xc9, 0x48, 0x37, 0xf5, 0x88,
+    0xd4, 0xe4, 0xeb, 0xb2, 0xb5, 0x59, 0x86, 0xd8, 0x41, 0x5a, 0xd4, 0x13,
+    0x6e, 0x43, 0x5c, 0xc9, 0xf3, 0x86, 0x4c, 0xb5, 0x16, 0x9f, 0x93, 0x61,
+    0x8a, 0x85, 0x46, 0xa4, 0xc7, 0x8e, 0xa4, 0xa8, 0x2d, 0x09, 0x57, 0x97,
+    0x56, 0xdb, 0x7b, 0x9d, 0xb0, 0xbd, 0x9d, 0x69, 0xd5, 0x4c, 0xc7, 0x25,
+    0xea, 0xab, 0x2c, 0x06, 0xda, 0x6e, 0x3a, 0xec, 0x93, 0xf3, 0x2a, 0xf6,
+    0x55, 0xcd, 0xb8, 0xe0, 0x58, 0x5c, 0xfb, 0xde, 0xf8, 0x9b, 0xe6, 0x0c,
+    0xd3, 0x2b, 0x30, 0xd5, 0x05, 0x4a, 0xa4, 0xab, 0xbf, 0xa9, 0x21, 0x0d,
+    0x36, 0x90, 0x96, 0x9a, 0x48, 0xb5, 0x92, 0x00, 0x1e, 0x82, 0xd8, 0x7d,
+    0x9d, 0xd4, 0x5a, 0x62, 0xe8, 0x72, 0x22, 0xc7, 0x6d, 0xe5, 0x3a, 0xe4,
+    0x52, 0xd0, 0x48, 0x05, 0x37, 0x51, 0xb0, 0xd4, 0x3d, 0x3b, 0xfe, 0xd8,
+    0xc7, 0x51, 0x9f, 0x79, 0xf6, 0x44, 0xac, 0x93, 0x47, 0x83, 0xa1, 0x37,
+    0xb7, 0xdf, 0x58, 0xdf, 0x45, 0xa1, 0xa1, 0x89, 0x83, 0x3f, 0x38, 0xbe,
+    0x27, 0x8f, 0x90, 0x17, 0xe5, 0x19, 0xf8, 0x7e, 0xa9, 0x7f, 0x0c, 0xcf,
+    0x74, 0xe6, 0x41, 0x4a, 0xd2, 0xeb, 0xce, 0xb3, 0xa8, 0xde, 0xe0, 0x68,
+    0x5e, 0xff, 0x00, 0xed, 0x86, 0xef, 0xc4, 0xae, 0x57, 0xad, 0x66, 0x9c,
+    0xf5, 0x96, 0xa9, 0x99, 0x7a, 0x9d, 0x22, 0xa3, 0x2d, 0xe8, 0xaa, 0x40,
+    0x08, 0x48, 0x09, 0x16, 0x37, 0x25, 0x44, 0xec, 0x91, 0x6d, 0xee, 0x48,
+    0x18, 0x40, 0xe9, 0x72, 0x97, 0x1f, 0x38, 0xd0, 0xe4, 0x4c, 0x01, 0x82,
+    0xed, 0x49, 0xc4, 0x5d, 0xc5, 0x00, 0x2e, 0xa4, 0xe9, 0x1b, 0xf1, 0xc9,
+    0xb6, 0x3a, 0x7f, 0x38, 0x67, 0x5a, 0x2e, 0x59, 0xa6, 0xa5, 0xe0, 0x17,
+    0x2e, 0xa6, 0xb8, 0xfa, 0x52, 0xdb, 0x00, 0xd8, 0x26, 0xfb, 0x6b, 0x20,
+    0x5c, 0xef, 0xc2, 0x45, 0xf0, 0x93, 0x8e, 0x17, 0x35, 0x2b, 0x5d, 0x93,
+    0x71, 0x96, 0x8a, 0xd6, 0x59, 0x02, 0xde, 0x3d, 0xe1, 0xed, 0xbc, 0x50,
+    0xb0, 0xeb, 0x0d, 0xcd, 0x53, 0xdf, 0x6c, 0x1d, 0x56, 0x6f, 0xe5, 0x63,
+    0xf4, 0x85, 0xbe, 0x94, 0xf4, 0x72, 0x85, 0xd3, 0xd8, 0x08, 0xcc, 0xb9,
+    0x96, 0x4b, 0x33, 0xab, 0x2c, 0xd8, 0x87, 0x41, 0xbc, 0x68, 0x8b, 0xec,
+    0x1b, 0x07, 0xff, 0x00, 0x51, 0x63, 0xfb, 0xdd, 0xbb, 0x0e, 0xf8, 0xdb,
+    0xcc, 0xd9, 0xc6, 0x7d, 0x6e, 0x97, 0x22, 0x99, 0x97, 0xdc, 0x30, 0xd2,
+    0xa6, 0xd4, 0x18, 0x23, 0xe7, 0x70, 0xff, 0x00, 0x7d, 0x44, 0xf0, 0x2f,
+    0xe9, 0xbd, 0xed, 0xef, 0x88, 0x96, 0x6e, 0xcd, 0xdd, 0x45, 0xce, 0x15,
+    0x44, 0x29, 0xea, 0x7c, 0xe4, 0x42, 0x6a, 0xe1, 0xa6, 0x49, 0x08, 0xda,
+    0xe7, 0x7b, 0x5f, 0xcb, 0x7f, 0x41, 0xe9, 0xdf, 0x07, 0xa9, 0xaf, 0xe7,
+    0x01, 0x14, 0xb6, 0xb8, 0x4d, 0x0f, 0x11, 0x21, 0x09, 0x40, 0x76, 0xe5,
+    0x24, 0xef, 0x60, 0x07, 0xdf, 0x6c, 0x0f, 0x6b, 0x07, 0xd4, 0xa6, 0xdd,
+    0x13, 0x53, 0xa8, 0x2b, 0x5e, 0xc2, 0xdd, 0xd4, 0xf4, 0x82, 0xcd, 0x87,
+    0x52, 0x9e, 0xce, 0x55, 0xb2, 0x40, 0xde, 0xc7, 0xda, 0xff, 0x00, 0x3f,
+    0xe6, 0x14, 0xb2, 0x2c, 0x09, 0x51, 0x33, 0x8c, 0x66, 0x96, 0xe1, 0x7d,
+    0xc5, 0x2d, 0xc4, 0x94, 0x29, 0xcb, 0xf9, 0x86, 0xc6, 0xe4, 0x5e, 0xdd,
+    0xf0, 0x56, 0x6c, 0xc9, 0x93, 0x95, 0x53, 0x69, 0x65, 0xc7, 0x52, 0xcc,
+    0xa7, 0x94, 0x02, 0xd5, 0xa8, 0xa0, 0x6b, 0xde, 0xde, 0xbd, 0xbf, 0x4c,
+    0x39, 0xe4, 0xec, 0x9f, 0x57, 0x77, 0x33, 0x35, 0x50, 0x9f, 0x4e, 0x44,
+    0x25, 0x34, 0xab, 0xa5, 0xd0, 0x8d, 0x3a, 0x81, 0xd8, 0x85, 0x71, 0xc7,
+    0x37, 0xe4, 0x93, 0x84, 0x99, 0x2f, 0xb0, 0xd5, 0x72, 0xae, 0x88, 0xe8,
+    0x7a, 0x4a, 0xdb, 0x98, 0xf0, 0x75, 0x09, 0x68, 0x9d, 0x0a, 0xd5, 0xb0,
+    0xbf, 0x1b, 0xdb, 0x0e, 0x75, 0x19, 0x29, 0x84, 0x51, 0xd0, 0x85, 0xa0,
+    0xf1, 0xf1, 0xde, 0xdb, 0xd8, 0x8f, 0xda, 0x1b, 0xb0, 0xc3, 0x8c, 0xc8,
+    0x9f, 0xee, 0x94, 0x1b, 0x04, 0x2b, 0xfc, 0x8d, 0xb6, 0x1b, 0x9e, 0x86,
+    0x13, 0x32, 0xee, 0x51, 0x95, 0x26, 0x62, 0x97, 0x2b, 0xca, 0x85, 0x38,
+    0x74, 0x36, 0x8d, 0xd4, 0xab, 0x9d, 0xbe, 0x98, 0x69, 0xa8, 0xfc, 0x0d,
+    0x1c, 0x22, 0x1c, 0x55, 0x32, 0x08, 0x1b, 0xa5, 0x0e, 0x6a, 0x08, 0xf5,
+    0x04, 0x8e, 0x4f, 0x7d, 0xb1, 0xf9, 0x3a, 0x8f, 0x99, 0xea, 0x68, 0x4a,
+    0x63, 0xc8, 0x85, 0x01, 0xbe, 0x74, 0x97, 0x81, 0xd3, 0x7f, 0x5b, 0x72,
+    0x71, 0xa3, 0x1b, 0xa7, 0x33, 0x18, 0x92, 0xdb, 0x95, 0x3a, 0xd3, 0x84,
+    0xba, 0x82, 0xa1, 0xe0, 0x46, 0x71, 0x6a, 0x29, 0xe3, 0xb0, 0x36, 0xc6,
+    0x54, 0xe1, 0xea, 0x8c, 0xd0, 0x0b, 0x75, 0x36, 0x1c, 0xb2, 0x10, 0xa0,
+    0xf7, 0xc4, 0x6c, 0x37, 0x86, 0xc1, 0x96, 0xa4, 0x1e, 0x35, 0x0c, 0x8a,
+    0xc8, 0xb9, 0x3d, 0x32, 0xf6, 0xc8, 0x43, 0x2e, 0x4d, 0x99, 0x97, 0xd4,
+    0x5c, 0x4d, 0x69, 0x97, 0x3c, 0x55, 0x0b, 0xa6, 0x42, 0xaf, 0x66, 0xc6,
+    0x92, 0x6c, 0x12, 0x0d, 0xbe, 0xfe, 0xbd, 0xf0, 0xcf, 0x05, 0xa8, 0x4e,
+    0xd6, 0x27, 0x1a, 0x5b, 0xc8, 0x2c, 0x08, 0x8d, 0x82, 0xb6, 0x55, 0x70,
+    0xa5, 0x00, 0xaf, 0x5e, 0xdb, 0xe1, 0x61, 0x8e, 0x9b, 0x44, 0x0a, 0x68,
+    0xbd, 0x5a, 0x7d, 0x69, 0x28, 0x05, 0x2a, 0x5a, 0xc8, 0xf2, 0xfa, 0x7b,
+    0x7d, 0x30, 0xdd, 0x95, 0xa9, 0x54, 0xbc, 0xb6, 0xc4, 0x8b, 0xcf, 0x69,
+    0x48, 0x5f, 0x9c, 0xf9, 0x49, 0x3b, 0x0b, 0x6e, 0x7b, 0xe1, 0x86, 0x83,
+    0x40, 0x98, 0x91, 0x9b, 0x0f, 0x39, 0x60, 0x90, 0x0e, 0xf1, 0x1b, 0xc6,
+    0xf8, 0xe6, 0x56, 0xbb, 0x28, 0xa4, 0xa5, 0x4a, 0x53, 0x84, 0x8d, 0x41,
+    0xd8, 0xc6, 0x8e, 0x49, 0x2b, 0xfe, 0x58, 0xa4, 0x2c, 0x3a, 0xb4, 0x07,
+    0x1a, 0x2d, 0x2e, 0xcb, 0x29, 0xbe, 0x95, 0x91, 0xcf, 0xf9, 0x86, 0x34,
+    0x1b, 0xc8, 0xf4, 0x8c, 0xaf, 0x5e, 0x7b, 0x30, 0xd7, 0x5a, 0x69, 0xe4,
+    0x15, 0xf8, 0x89, 0x2e, 0x3a, 0x34, 0x81, 0xea, 0x07, 0xae, 0x0e, 0xf4,
+    0xc1, 0xba, 0x5d, 0x63, 0xa7, 0xae, 0xc4, 0x55, 0x72, 0x1c, 0x19, 0xf0,
+    0x66, 0x38, 0x02, 0x5f, 0x41, 0xf9, 0x54, 0x41, 0x1c, 0x6f, 0x6f, 0x70,
+    0x0e, 0xe2, 0xc7, 0x1e, 0x95, 0x1c, 0xa7, 0x95, 0x6a, 0x8f, 0x78, 0x99,
+    0xa7, 0x38, 0xbb, 0x31, 0x60, 0xec, 0xdc, 0x55, 0x04, 0xb2, 0x91, 0xed,
+    0xab, 0x73, 0xf5, 0x23, 0x1e, 0xf3, 0x75, 0x49, 0x44, 0x23, 0x3e, 0xf2,
+    0x92, 0x4d, 0x87, 0x99, 0xce, 0x3e, 0x82, 0xa0, 0x54, 0x25, 0x95, 0x47,
+    0x96, 0xed, 0x52, 0x14, 0xb4, 0x0c, 0xae, 0x0e, 0x47, 0x63, 0x7d, 0xad,
+    0x7f, 0x13, 0xf3, 0x08, 0x59, 0xa7, 0xa9, 0x90, 0xe7, 0xd4, 0x3f, 0x87,
+    0xd3, 0xd6, 0x44, 0x73, 0xb1, 0x7d, 0x46, 0xca, 0xb7, 0x64, 0x8b, 0x7c,
+    0xa3, 0x8d, 0x86, 0xe7, 0xb9, 0xed, 0x80, 0xd4, 0x1a, 0xac, 0x04, 0xb8,
+    0xe1, 0x71, 0x0b, 0xd2, 0xb7, 0x09, 0xdc, 0xdf, 0x49, 0xdf, 0x6b, 0x1f,
+    0xad, 0xcf, 0xed, 0x8a, 0xe2, 0x32, 0x5e, 0x40, 0x85, 0x1d, 0x89, 0x14,
+    0xa8, 0x54, 0xea, 0xb8, 0x52, 0x94, 0x1c, 0x0f, 0x4f, 0x53, 0x3e, 0x1f,
+    0xf7, 0x46, 0xc8, 0x37, 0x36, 0xbd, 0xed, 0xc6, 0x18, 0xa9, 0xf4, 0xfe,
+    0x9a, 0xa6, 0x12, 0x14, 0xfd, 0x0c, 0x31, 0x25, 0x0a, 0x21, 0xe6, 0x58,
+    0x43, 0xce, 0x83, 0xb6, 0xc5, 0x2e, 0x5b, 0x71, 0xfa, 0x61, 0x36, 0xa1,
+    0x3e, 0x26, 0x94, 0x4b, 0xae, 0x0f, 0x33, 0x18, 0x26, 0x3b, 0x79, 0xb7,
+    0x4a, 0x9e, 0x70, 0x78, 0x00, 0x32, 0x1e, 0xa7, 0xde, 0x37, 0x7a, 0x17,
+    0xe0, 0x3b, 0x48, 0x42, 0x53, 0xe0, 0x3a, 0xfb, 0xa9, 0x5b, 0xee, 0x29,
+    0xa1, 0xc9, 0x06, 0xc7, 0x9e, 0xc0, 0x5b, 0x02, 0x7f, 0x12, 0x50, 0xd2,
+    0xdd, 0x7e, 0x93, 0x25, 0x20, 0x05, 0x29, 0x82, 0x90, 0x37, 0xb1, 0xb1,
+    0x1e, 0x9f, 0x43, 0x86, 0xaa, 0x5d, 0x7f, 0x25, 0x51, 0x5d, 0x0b, 0xa7,
+    0x50, 0xaa, 0x37, 0x00, 0x68, 0x09, 0x69, 0x66, 0xc3, 0xef, 0x84, 0xbe,
+    0xa7, 0xe6, 0x98, 0xb9, 0xb2, 0xbf, 0x16, 0x33, 0x50, 0x64, 0xc2, 0xf8,
+    0x26, 0xff, 0x00, 0xe7, 0x24, 0xa5, 0x4a, 0x4f, 0xae, 0xe3, 0x8d, 0xf9,
+    0xe3, 0x6c, 0x60, 0x4b, 0x8c, 0xf6, 0x25, 0x01, 0x60, 0xaa, 0xf7, 0xc8,
+    0xc6, 0x57, 0x18, 0xec, 0x90, 0x45, 0xf2, 0xf1, 0xb7, 0xca, 0xe6, 0x24,
+    0x3d, 0x41, 0x97, 0x21, 0x1f, 0x0d, 0xf0, 0x4e, 0xa2, 0x3c, 0xc7, 0x96,
+    0x4e, 0xa5, 0x10, 0x0f, 0x86, 0x05, 0x92, 0x8b, 0x9f, 0xca, 0x76, 0xfd,
+    0x31, 0x3c, 0x10, 0xaa, 0xae, 0xbe, 0xaf, 0xfc, 0xad, 0x97, 0x97, 0x7d,
+    0xce, 0x92, 0xa3, 0xfa, 0xe2, 0xae, 0x8a, 0x4c, 0x1a, 0xef, 0x50, 0x69,
+    0x54, 0x9a, 0x83, 0xc9, 0x62, 0x3f, 0xc0, 0xba, 0xf1, 0x71, 0x36, 0x3a,
+    0x52, 0x3e, 0x5d, 0xcf, 0xa0, 0x37, 0xbe, 0x07, 0xe6, 0x8c, 0x85, 0x9a,
+    0xe3, 0xcf, 0x28, 0xc9, 0xd5, 0x29, 0xb5, 0x66, 0x42, 0x43, 0x88, 0x44,
+    0x72, 0xa2, 0xbd, 0x2a, 0xbd, 0xb9, 0xdd, 0x5c, 0x1b, 0x73, 0xf5, 0xc5,
+    0x33, 0x0d, 0xb6, 0xf3, 0x34, 0xd0, 0xe7, 0x19, 0xb1, 0xb9, 0x00, 0x01,
+    0x90, 0xb9, 0x1a, 0xab, 0x2f, 0x28, 0x57, 0x55, 0x29, 0xb7, 0xc2, 0xa6,
+    0x0a, 0x49, 0xd8, 0xdb, 0x5c, 0xa0, 0x05, 0x1f, 0x29, 0x54, 0xdd, 0xa7,
+    0xa9, 0xe7, 0xe3, 0x53, 0xa2, 0x10, 0x9b, 0xb7, 0xe2, 0x4f, 0x09, 0x2e,
+    0x0b, 0x5e, 0xe0, 0x04, 0x2a, 0xff, 0x00, 0xb6, 0x3c, 0x19, 0xcb, 0xd9,
+    0xd9, 0x45, 0x3f, 0x0d, 0x47, 0x8e, 0x9d, 0x48, 0x4a, 0xbc, 0xa5, 0x2a,
+    0xb5, 0xc6, 0xd7, 0xb9, 0x36, 0x3e, 0xd8, 0x0e, 0x89, 0x59, 0xb5, 0x89,
+    0x4b, 0x82, 0xa9, 0x72, 0xe3, 0xb8, 0x83, 0x65, 0x24, 0xf9, 0x74, 0x9f,
+    0x43, 0xb6, 0xc7, 0xeb, 0x82, 0xb4, 0xea, 0x6e, 0x75, 0x9e, 0xca, 0xa5,
+    0x36, 0xed, 0x49, 0xc4, 0xa1, 0x5a, 0x54, 0x52, 0x6f, 0xc7, 0x3c, 0x63,
+    0x43, 0xb8, 0xa9, 0xa6, 0xcf, 0x0a, 0x8a, 0xc5, 0xbf, 0xf3, 0xf7, 0xe8,
+    0x04, 0x71, 0x6e, 0x9f, 0x4a, 0x51, 0xcd, 0x0b, 0x3d, 0x48, 0xfa, 0xde,
+    0x33, 0x30, 0xe5, 0xec, 0xe9, 0x12, 0x9a, 0x89, 0xd5, 0x86, 0x99, 0x6a,
+    0x34, 0x75, 0x78, 0x88, 0xd4, 0x05, 0x8a, 0x86, 0xe1, 0x36, 0xb7, 0x7b,
+    0x7d, 0x31, 0xeb, 0x53, 0xa8, 0x67, 0xc8, 0x49, 0x65, 0x6e, 0x39, 0x22,
+    0x13, 0x2a, 0x17, 0x65, 0x41, 0xb5, 0xb4, 0x9b, 0x13, 0xdb, 0x55, 0x88,
+    0x1b, 0xf7, 0xc3, 0xfd, 0x0e, 0x44, 0xc7, 0xa8, 0x2c, 0xc1, 0xac, 0x34,
+    0x92, 0xb6, 0x27, 0xc7, 0x6d, 0x68, 0x51, 0xb8, 0x3c, 0x1d, 0xc7, 0x62,
+    0x45};
+}  // namespace
diff --git a/vendor_libs/test_vendor_lib/src/async_manager.cc b/vendor_libs/test_vendor_lib/src/async_manager.cc
index 423fc72..355f647 100644
--- a/vendor_libs/test_vendor_lib/src/async_manager.cc
+++ b/vendor_libs/test_vendor_lib/src/async_manager.cc
@@ -18,6 +18,8 @@
 
 #include "async_manager.h"
 
+#include "osi/include/log.h"
+
 #include <algorithm>
 #include <atomic>
 #include <condition_variable>
diff --git a/vendor_libs/test_vendor_lib/src/l2cap_packet.cc b/vendor_libs/test_vendor_lib/src/l2cap_packet.cc
new file mode 100644
index 0000000..652f3c0
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/src/l2cap_packet.cc
@@ -0,0 +1,320 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "l2cap_packet"
+
+#include "l2cap_packet.h"
+
+#include <algorithm>
+
+#include "osi/include/log.h"
+
+namespace test_vendor_lib {
+
+const int kL2capHeaderLength = 4;
+const uint16_t kSduTxSeqBits = 0x007E;
+const int kSduStandardHeaderLength = 6;
+const int kSduFirstHeaderLength = 8;
+const uint8_t kSduFirstReqseq = 0x40;
+const uint8_t kSduContinuationReqseq = 0xC0;
+const uint8_t kSduEndReqseq = 0x80;
+
+std::unique_ptr<L2capPacket> L2capPacket::assemble(
+    const std::vector<L2capSdu>& sdu_packets) {
+  std::unique_ptr<L2capPacket> built_l2cap_packet(new L2capPacket());
+  uint16_t l2cap_payload_length = 0;
+  uint16_t first_packet_channel_id = 0;
+  uint16_t total_expected_l2cap_length;
+  uint8_t txseq_start;
+
+  if (sdu_packets.size() == 0) {
+    LOG_DEBUG(LOG_TAG, "%s: No SDU received.", __func__);
+    return nullptr;
+  }
+  if (sdu_packets.size() == 1 && !L2capSdu::is_complete_l2cap(sdu_packets[0])) {
+    LOG_DEBUG(LOG_TAG, "%s: Unsegmented SDU has incorrect SAR bits.", __func__);
+    return nullptr;
+  }
+
+  first_packet_channel_id = sdu_packets[0].get_channel_id();
+
+  built_l2cap_packet->l2cap_packet_.resize(kL2capHeaderLength);
+
+  for (size_t i = 0; i < sdu_packets.size(); i++) {
+    uint16_t payload_length = sdu_packets[i].get_payload_length();
+
+    // TODO(jruthe): Remove these checks when ACL packets have been
+    // implemented. Once those are done, that will be the only way to create
+    // L2capSdu objects and these checks will be moved there instead.
+    //
+    // Check the integrity of the packet length, if it is zero, it is invalid.
+    // The maximum size of a single, segmented L2CAP payload is 1016 bytes.
+    if ((payload_length <= 0) ||
+        (payload_length != sdu_packets[i].get_vector_size() - 4)) {
+      LOG_DEBUG(LOG_TAG, "%s: SDU payload length incorrect.", __func__);
+      return nullptr;
+    }
+
+    uint16_t fcs_check = sdu_packets[i].get_fcs();
+
+    if (sdu_packets[i].calculate_fcs() != fcs_check) {
+      LOG_DEBUG(LOG_TAG, "%s: SDU fcs is incorrect.", __func__);
+      return nullptr;
+    }
+
+    uint16_t controls = sdu_packets[i].get_controls();
+
+    if (sdu_packets[i].get_channel_id() != first_packet_channel_id) {
+      LOG_DEBUG(LOG_TAG, "%s: SDU CID does not match expected.", __func__);
+      return nullptr;
+    }
+
+    if (i == 0) txseq_start = controls & kSduTxSeqBits;
+
+    // Bluetooth Specification version 4.2 volume 3 part A 3.3.2:
+    // If there is only a single SDU, the first two bits of the control must be
+    // set to 00b, representing an unsegmented SDU. If the SDU is segmented,
+    // there is a begin and an end. The first segment must have the first two
+    // control bits set to 01b and the ending segment must have them set to 10b.
+    // Meanwhile all segments in between the start and end must have the bits
+    // set to 11b.
+    uint16_t starting_index;
+    uint8_t txseq = controls & kSduTxSeqBits;
+    if (sdu_packets.size() > 1 && i == 0 &&
+        !L2capSdu::is_starting_sdu(sdu_packets[i])) {
+      LOG_DEBUG(LOG_TAG, "%s: First segmented SDU has incorrect SAR bits.",
+                __func__);
+      return nullptr;
+    }
+    if (i != 0 && L2capSdu::is_starting_sdu(sdu_packets[i])) {
+      LOG_DEBUG(LOG_TAG,
+                "%s: SAR bits set to first segmented SDU on "
+                "non-starting SDU.",
+                __func__);
+      return nullptr;
+    }
+    if (txseq != (txseq_start + (static_cast<uint8_t>(i) << 1))) {
+      LOG_DEBUG(LOG_TAG, "%s: TxSeq incorrect.", __func__);
+      return nullptr;
+    }
+    if (sdu_packets.size() > 1 && i == sdu_packets.size() - 1 &&
+        !L2capSdu::is_ending_sdu(sdu_packets[i])) {
+      LOG_DEBUG(LOG_TAG, "%s: Final segmented SDU has incorrect SAR bits.",
+                __func__);
+      return nullptr;
+    }
+
+    // Subtract the control and fcs from every SDU payload length.
+    l2cap_payload_length += (payload_length - 4);
+
+    if (L2capSdu::is_starting_sdu(sdu_packets[i])) {
+      starting_index = kSduFirstHeaderLength;
+      total_expected_l2cap_length = sdu_packets[i].get_total_l2cap_length();
+
+      // Subtract the additional two bytes from the first packet of a segmented
+      // SDU.
+      l2cap_payload_length -= 2;
+    } else {
+      starting_index = kSduStandardHeaderLength;
+    }
+
+    auto payload_begin = sdu_packets[i].get_payload_begin(starting_index);
+    auto payload_end = sdu_packets[i].get_payload_end();
+
+    built_l2cap_packet->l2cap_packet_.insert(
+        built_l2cap_packet->l2cap_packet_.end(), payload_begin, payload_end);
+  }
+
+  if (l2cap_payload_length != total_expected_l2cap_length &&
+      sdu_packets.size() > 1) {
+    LOG_DEBUG(LOG_TAG, "%s: Total expected L2CAP payload length incorrect.",
+              __func__);
+    return nullptr;
+  }
+
+  built_l2cap_packet->l2cap_packet_[0] = l2cap_payload_length & 0xFF;
+  built_l2cap_packet->l2cap_packet_[1] = (l2cap_payload_length & 0xFF00) >> 8;
+  built_l2cap_packet->l2cap_packet_[2] = first_packet_channel_id & 0xFF;
+  built_l2cap_packet->l2cap_packet_[3] =
+      (first_packet_channel_id & 0xFF00) >> 8;
+
+  return built_l2cap_packet;
+}  // Assemble
+
+std::vector<uint8_t> L2capPacket::get_l2cap_payload() const {
+  std::vector<uint8_t> payload_sub_vector;
+  payload_sub_vector.clear();
+
+  auto begin_payload_iter = get_l2cap_payload_begin();
+  payload_sub_vector.insert(payload_sub_vector.end(), begin_payload_iter,
+                            l2cap_packet_.end());
+
+  return payload_sub_vector;
+}
+
+uint16_t L2capPacket::get_l2cap_cid() const {
+  return ((l2cap_packet_[3] << 8) | l2cap_packet_[2]);
+}
+
+std::vector<uint8_t>::const_iterator L2capPacket::get_l2cap_payload_begin()
+    const {
+  return std::next(l2cap_packet_.begin(), kSduHeaderLength);
+}
+
+std::vector<uint8_t>::const_iterator L2capPacket::get_l2cap_payload_end()
+    const {
+  return l2cap_packet_.end();
+}
+
+std::vector<L2capSdu> L2capPacket::fragment(uint16_t maximum_sdu_size,
+                                            uint8_t txseq,
+                                            uint8_t reqseq) const {
+  std::vector<L2capSdu> sdu;
+  if (!check_l2cap_packet()) return sdu;
+
+  std::vector<uint8_t> current_sdu;
+
+  auto current_iter = get_l2cap_payload_begin();
+  auto end_iter = get_l2cap_payload_end();
+
+  size_t number_of_packets = ceil((l2cap_packet_.size() - kL2capHeaderLength) /
+                                  static_cast<float>(maximum_sdu_size));
+
+  if (number_of_packets == 0) {
+    current_sdu.resize(kSduStandardHeaderLength);
+
+    set_sdu_header_length(current_sdu, kL2capHeaderLength);
+
+    set_sdu_cid(current_sdu, get_l2cap_cid());
+
+    reqseq = (reqseq & 0xF0) >> 4;
+    set_sdu_control_bytes(current_sdu, txseq, reqseq);
+
+    sdu.push_back(L2capSdu::L2capSduBuilder(current_sdu));
+
+    return sdu;
+  }
+
+  uint16_t header_length = 0x0000;
+
+  if (number_of_packets == 1) {
+    current_sdu.clear();
+    current_sdu.resize(kSduStandardHeaderLength);
+
+    header_length = ((l2cap_packet_[1] & 0xFF) << 8) | l2cap_packet_[0];
+    header_length += kL2capHeaderLength;
+    set_sdu_header_length(current_sdu, header_length);
+
+    set_sdu_cid(current_sdu, get_l2cap_cid());
+
+    set_sdu_control_bytes(current_sdu, txseq, 0x00);
+
+    current_sdu.insert(current_sdu.end(), current_iter, end_iter);
+
+    sdu.push_back(L2capSdu::L2capSduBuilder(current_sdu));
+
+    return sdu;
+  }
+
+  auto next_iter =
+      std::next(current_iter, maximum_sdu_size - (kSduFirstHeaderLength + 2));
+
+  sdu.reserve(number_of_packets);
+  sdu.clear();
+
+  for (size_t i = 0; i <= number_of_packets; i++) {
+    if (i == 0) {
+      current_sdu.resize(kSduFirstHeaderLength);
+
+      header_length = maximum_sdu_size - kL2capHeaderLength;
+
+      reqseq = reqseq | kSduFirstReqseq;
+
+      set_total_sdu_length(current_sdu, l2cap_packet_.size() - 4);
+    } else {
+      current_sdu.resize(kSduStandardHeaderLength);
+
+      header_length = (next_iter - current_iter) + kL2capHeaderLength;
+
+      reqseq = reqseq & 0x0F;
+
+      if (i < number_of_packets) {
+        reqseq |= kSduContinuationReqseq;
+      } else {
+        reqseq |= kSduEndReqseq;
+      }
+    }
+    set_sdu_header_length(current_sdu, header_length);
+
+    set_sdu_cid(current_sdu, get_l2cap_cid());
+
+    set_sdu_control_bytes(current_sdu, txseq, reqseq);
+    txseq += 2;
+
+    // Txseq has a maximum of 0x3F. If it exceeds that, it restarts at 0x00.
+    if (txseq > 0x3F) txseq = 0x00;
+
+    current_sdu.insert(current_sdu.end(), current_iter, next_iter);
+
+    current_iter = next_iter;
+
+    next_iter =
+        std::next(current_iter, maximum_sdu_size - kSduFirstHeaderLength);
+
+    if (next_iter > end_iter) {
+      next_iter = end_iter;
+    }
+
+    sdu.push_back(L2capSdu::L2capSduBuilder(std::move(current_sdu)));
+  }
+
+  return sdu;
+}  // fragment
+
+void L2capPacket::set_sdu_header_length(std::vector<uint8_t>& sdu,
+                                        uint16_t length) {
+  sdu[0] = length & 0xFF;
+  sdu[1] = (length & 0xFF00) >> 8;
+}
+
+void L2capPacket::set_total_sdu_length(std::vector<uint8_t>& sdu,
+                                       uint16_t total_sdu_length) {
+  sdu[6] = total_sdu_length & 0xFF;
+  sdu[7] = (total_sdu_length & 0xFF00) >> 8;
+}
+
+void L2capPacket::set_sdu_cid(std::vector<uint8_t>& sdu, uint16_t cid) {
+  sdu[2] = cid & 0xFF;
+  sdu[3] = (cid & 0xFF00) >> 8;
+}
+
+void L2capPacket::set_sdu_control_bytes(std::vector<uint8_t>& sdu,
+                                        uint8_t txseq, uint8_t reqseq) {
+  sdu[4] = txseq;
+  sdu[5] = reqseq;
+}
+
+bool L2capPacket::check_l2cap_packet() const {
+  uint16_t payload_length = ((l2cap_packet_[1] & 0xFF) << 8) | l2cap_packet_[0];
+
+  if (l2cap_packet_.size() < 4) return false;
+  if (payload_length != (l2cap_packet_.size() - 4)) return false;
+
+  return true;
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/src/l2cap_sdu.cc b/vendor_libs/test_vendor_lib/src/l2cap_sdu.cc
new file mode 100644
index 0000000..e44d241
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/src/l2cap_sdu.cc
@@ -0,0 +1,147 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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 "l2cap_sdu.h"
+
+#include <base/logging.h>
+
+namespace test_vendor_lib {
+
+const uint16_t kSduSarBits = 0xe000;
+
+// Define the LFSR table of precalculated values defined by the
+// Bluetooth specification version 4.2 volume 3 part A section 3.3.5.
+const uint16_t L2capSdu::lfsr_table_[256] = {
+    0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601,
+    0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0,
+    0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81,
+    0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941,
+    0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01,
+    0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0,
+    0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081,
+    0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+    0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00,
+    0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0,
+    0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981,
+    0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41,
+    0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700,
+    0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0,
+    0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281,
+    0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+    0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01,
+    0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1,
+    0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80,
+    0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541,
+    0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101,
+    0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0,
+    0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481,
+    0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+    0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801,
+    0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1,
+    0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581,
+    0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341,
+    0x4100, 0x81c1, 0x8081, 0x4040,
+};  // lfsr_table
+
+L2capSdu::L2capSdu(std::vector<uint8_t> create_from) {
+  sdu_data_ = std::move(create_from);
+}
+
+L2capSdu L2capSdu::L2capSduBuilder(std::vector<uint8_t> create_from) {
+  L2capSdu packet(std::move(create_from));
+
+  packet.sdu_data_.resize(packet.sdu_data_.size() + 2, 0x00);
+
+  uint16_t fcs = packet.calculate_fcs();
+
+  packet.sdu_data_[packet.sdu_data_.size() - 2] = fcs & 0xFF;
+  packet.sdu_data_[packet.sdu_data_.size() - 1] = (fcs & 0xFF00) >> 8;
+
+  return packet;
+}
+
+std::vector<uint8_t>::const_iterator L2capSdu::get_payload_begin(
+    const unsigned int offset) const {
+  return std::next(sdu_data_.begin(), offset);
+}
+
+std::vector<uint8_t>::const_iterator L2capSdu::get_payload_end() const {
+  return std::prev(sdu_data_.end(), 2);
+}
+
+uint16_t L2capSdu::convert_from_little_endian(
+    const unsigned int starting_index) const {
+  uint16_t convert = sdu_data_[starting_index + 1];
+  convert = convert << 8;
+  convert = convert | sdu_data_[starting_index];
+
+  return convert;
+}
+
+uint16_t L2capSdu::calculate_fcs() const {
+  // Starting state as directed by Bluetooth specification version 4.2 volume 3
+  // part A 3.3.5.
+  uint16_t lfsr = 0x0000;
+
+  for (size_t i = 0; i < sdu_data_.size() - 2; i++) {
+    uint8_t current_byte = sdu_data_[i];
+    lfsr = ((lfsr >> 8) & 0xff) ^ lfsr_table_[(lfsr & 0xff) ^ current_byte];
+  }
+  return lfsr;
+}
+
+uint16_t L2capSdu::get_payload_length() const {
+  return convert_from_little_endian(0);
+}
+
+uint16_t L2capSdu::get_fcs() const {
+  return convert_from_little_endian(sdu_data_.size() - 2);
+}
+
+uint16_t L2capSdu::get_controls() const {
+  return convert_from_little_endian(4);
+}
+
+uint16_t L2capSdu::get_total_l2cap_length() const {
+  return convert_from_little_endian(6);
+}
+
+uint16_t L2capSdu::get_channel_id() const {
+  return convert_from_little_endian(2);
+}
+
+size_t L2capSdu::get_vector_size() const { return sdu_data_.size(); }
+
+bool L2capSdu::is_complete_l2cap(const L2capSdu& sdu) {
+  uint16_t sar_bits = (sdu.get_controls() & kSduSarBits);
+
+  return (sar_bits == 0x0000);
+}
+
+bool L2capSdu::is_starting_sdu(const L2capSdu& sdu) {
+  uint16_t sar_bits = (sdu.get_controls() & kSduSarBits);
+
+  return (sar_bits == 0x4000);
+}
+
+bool L2capSdu::is_ending_sdu(const L2capSdu& sdu) {
+  uint16_t sar_bits = (sdu.get_controls() & kSduSarBits);
+
+  return (sar_bits == 0x8000);
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/test/l2cap_sdu_test.cc b/vendor_libs/test_vendor_lib/test/l2cap_sdu_test.cc
new file mode 100644
index 0000000..7d63f45
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/test/l2cap_sdu_test.cc
@@ -0,0 +1,119 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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 "l2cap_sdu.h"
+#include <gtest/gtest.h>
+#include "l2cap_test_packets.h"
+using std::vector;
+
+namespace test_vendor_lib {
+
+L2capSdu packet_1(l2cap_test_packet_1);
+L2capSdu packet_2(l2cap_test_packet_2);
+L2capSdu packet_3(l2cap_test_packet_3);
+L2capSdu packet_4(l2cap_test_packet_4);
+L2capSdu packet_5(l2cap_test_packet_5);
+L2capSdu packet_6(l2cap_test_packet_6);
+L2capSdu packet_7(l2cap_test_packet_7);
+L2capSdu packet_8(l2cap_test_packet_8);
+L2capSdu packet_9(l2cap_test_packet_9);
+
+class L2capSduTest : public ::testing::Test {
+ public:
+  L2capSduTest(){};
+
+  ~L2capSduTest() = default;
+
+};  // L2capSduTest
+
+TEST_F(L2capSduTest, getFcsTest) {
+  EXPECT_EQ(0x72aa, packet_1.get_fcs());
+  EXPECT_EQ(0x5b57, packet_2.get_fcs());
+  EXPECT_EQ(0xe644, packet_3.get_fcs());
+  EXPECT_EQ(0x21b0, packet_4.get_fcs());
+  EXPECT_EQ(0xae96, packet_5.get_fcs());
+  EXPECT_EQ(0x9254, packet_6.get_fcs());
+  EXPECT_EQ(0xf6fa, packet_7.get_fcs());
+  EXPECT_EQ(0x1da4, packet_8.get_fcs());
+  EXPECT_EQ(0x781a, packet_9.get_fcs());
+}
+
+TEST_F(L2capSduTest, getPayloadLengthTest) {
+  EXPECT_EQ(l2cap_test_packet_1.size() - 4, packet_1.get_payload_length());
+  EXPECT_EQ(l2cap_test_packet_2.size() - 4, packet_2.get_payload_length());
+  EXPECT_EQ(l2cap_test_packet_3.size() - 4, packet_3.get_payload_length());
+  EXPECT_EQ(l2cap_test_packet_4.size() - 4, packet_4.get_payload_length());
+  EXPECT_EQ(l2cap_test_packet_5.size() - 4, packet_5.get_payload_length());
+  EXPECT_EQ(l2cap_test_packet_6.size() - 4, packet_6.get_payload_length());
+  EXPECT_EQ(l2cap_test_packet_7.size() - 4, packet_7.get_payload_length());
+  EXPECT_EQ(l2cap_test_packet_8.size() - 4, packet_8.get_payload_length());
+  EXPECT_EQ(l2cap_test_packet_9.size() - 4, packet_9.get_payload_length());
+}
+
+TEST_F(L2capSduTest, calculateFcsTest) {
+  EXPECT_EQ(0x72aa, packet_1.calculate_fcs());
+  EXPECT_EQ(0x5b57, packet_2.calculate_fcs());
+  EXPECT_EQ(0xe644, packet_3.calculate_fcs());
+  EXPECT_EQ(0x21b0, packet_4.calculate_fcs());
+  EXPECT_EQ(0xae96, packet_5.calculate_fcs());
+  EXPECT_EQ(0x9254, packet_6.calculate_fcs());
+  EXPECT_EQ(0xf6fa, packet_7.calculate_fcs());
+  EXPECT_EQ(0x1da4, packet_8.calculate_fcs());
+  EXPECT_EQ(0x781a, packet_9.calculate_fcs());
+}
+
+TEST_F(L2capSduTest, getControlsTest) {
+  EXPECT_EQ(0x4102, packet_1.get_controls());
+  EXPECT_EQ(0xc104, packet_2.get_controls());
+  EXPECT_EQ(0xc106, packet_3.get_controls());
+  EXPECT_EQ(0xc108, packet_4.get_controls());
+  EXPECT_EQ(0xc10a, packet_5.get_controls());
+  EXPECT_EQ(0xc10c, packet_6.get_controls());
+  EXPECT_EQ(0xc10e, packet_7.get_controls());
+  EXPECT_EQ(0xc110, packet_8.get_controls());
+  EXPECT_EQ(0x8112, packet_9.get_controls());
+}
+
+TEST_F(L2capSduTest, getTotalLengthTest) {
+  EXPECT_EQ(0x1f95, packet_1.get_total_l2cap_length());
+}
+
+TEST_F(L2capSduTest, getVectorSizeTest) {
+  EXPECT_EQ(l2cap_test_packet_1.size(), packet_1.get_vector_size());
+  EXPECT_EQ(l2cap_test_packet_2.size(), packet_2.get_vector_size());
+  EXPECT_EQ(l2cap_test_packet_3.size(), packet_3.get_vector_size());
+  EXPECT_EQ(l2cap_test_packet_4.size(), packet_4.get_vector_size());
+  EXPECT_EQ(l2cap_test_packet_5.size(), packet_5.get_vector_size());
+  EXPECT_EQ(l2cap_test_packet_6.size(), packet_6.get_vector_size());
+  EXPECT_EQ(l2cap_test_packet_7.size(), packet_7.get_vector_size());
+  EXPECT_EQ(l2cap_test_packet_8.size(), packet_8.get_vector_size());
+  EXPECT_EQ(l2cap_test_packet_9.size(), packet_9.get_vector_size());
+}
+
+TEST_F(L2capSduTest, getCidTest) {
+  EXPECT_EQ(0x0047, packet_1.get_channel_id());
+  EXPECT_EQ(0x0047, packet_2.get_channel_id());
+  EXPECT_EQ(0x0047, packet_3.get_channel_id());
+  EXPECT_EQ(0x0047, packet_4.get_channel_id());
+  EXPECT_EQ(0x0047, packet_5.get_channel_id());
+  EXPECT_EQ(0x0047, packet_6.get_channel_id());
+  EXPECT_EQ(0x0047, packet_7.get_channel_id());
+  EXPECT_EQ(0x0047, packet_8.get_channel_id());
+  EXPECT_EQ(0x0047, packet_9.get_channel_id());
+}
+
+}  // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/test/l2cap_test.cc b/vendor_libs/test_vendor_lib/test/l2cap_test.cc
new file mode 100644
index 0000000..d35e78f
--- /dev/null
+++ b/vendor_libs/test_vendor_lib/test/l2cap_test.cc
@@ -0,0 +1,535 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2017 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 "l2cap_packet.h"
+#include "l2cap_test_packets.h"
+
+#include <gtest/gtest.h>
+#include <memory>
+
+using std::unique_ptr;
+using std::vector;
+
+namespace test_vendor_lib {
+
+class L2capTest : public ::testing::Test {
+ public:
+  L2capTest() {}
+
+  void compare_packets(vector<uint8_t>& complete_packet,
+                       vector<uint8_t>& assembled_packet) {
+    ASSERT_EQ(complete_packet.size() - 4, assembled_packet.size());
+
+    for (size_t i = 0; i < assembled_packet.size(); i++) {
+      ASSERT_EQ(complete_packet[i + 4], assembled_packet[i]);
+    }
+  }
+
+  L2capSdu update_fcs(vector<uint8_t> sdu) {
+    sdu.resize(sdu.size() - 2);
+
+    return L2capSdu::L2capSduBuilder(sdu);
+  }
+
+  void compare_fragmented_packets(vector<uint8_t>& expected,
+                                  vector<uint8_t>& received) {
+    ASSERT_EQ(expected.size(), received.size());
+
+    for (size_t i = 0; i < expected.size(); i++) {
+      ASSERT_EQ(expected[i], received[i]);
+    }
+  }
+
+  ~L2capTest() = default;
+};
+
+TEST_F(L2capTest, assembleGoodPackets) {
+  vector<L2capSdu> test_packet;
+  vector<uint8_t> assembled_payload;
+
+  // Test 1: Pass correct packets.
+  test_packet.push_back(L2capSdu(good_sdu[0]));
+  test_packet.push_back(L2capSdu(good_sdu[1]));
+  test_packet.push_back(L2capSdu(good_sdu[2]));
+
+  unique_ptr<L2capPacket> test_1 = L2capPacket::assemble(test_packet);
+  ASSERT_NE(test_1, nullptr);
+
+  assembled_payload = test_1->get_l2cap_payload();
+
+  compare_packets(good_l2cap_packet, assembled_payload);
+
+  assembled_payload.clear();
+  test_packet.clear();
+
+  test_packet.push_back(L2capSdu(l2cap_test_packet_1));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_2));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_3));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_4));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_5));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_6));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_7));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_8));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_9));
+
+  test_1 = L2capPacket::assemble(test_packet);
+  ASSERT_NE(test_1, nullptr);
+
+  assembled_payload = test_1->get_l2cap_payload();
+  compare_packets(complete_l2cap_packet, assembled_payload);
+
+  assembled_payload.clear();
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleOutofOrderPackets) {
+  vector<L2capSdu> test_packet;
+
+  // Test 2: Pass out of order packets.
+  test_packet.push_back(L2capSdu(good_sdu[1]));
+  test_packet.push_back(L2capSdu(good_sdu[0]));
+  test_packet.push_back(L2capSdu(good_sdu[2]));
+
+  unique_ptr<L2capPacket> test_2 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_2, nullptr);
+
+  test_packet.clear();
+
+  test_packet.push_back(L2capSdu(l2cap_test_packet_1));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_3));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_2));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_6));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_5));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_4));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_8));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_7));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_9));
+
+  test_2 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_2, nullptr);
+
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleBadControlBytes) {
+  vector<L2capSdu> test_packet;
+
+  // Test 3: Pass packets missing the finished control bytes.
+  test_packet.push_back(L2capSdu(good_sdu[0]));
+  test_packet.push_back(L2capSdu(good_sdu[1]));
+
+  unique_ptr<L2capPacket> test_3 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_3, nullptr);
+
+  test_packet.clear();
+
+  test_packet.push_back(L2capSdu(l2cap_test_packet_1));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_2));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_3));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_4));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_5));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_6));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_7));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_8));
+
+  test_3 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_3, nullptr);
+
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleBadFCS) {
+  vector<L2capSdu> test_packet;
+
+  // Test 4: Pass packets with incorrect frame check sequences.
+  test_packet.push_back(L2capSdu(good_sdu[0]));
+  good_sdu[1][good_sdu[1].size() - 1]++;
+  test_packet.push_back(L2capSdu(good_sdu[1]));
+  good_sdu[1][good_sdu[1].size() - 1]--;
+  test_packet.push_back(L2capSdu(good_sdu[2]));
+
+  unique_ptr<L2capPacket> test_4 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_4, nullptr);
+
+  test_packet.clear();
+
+  test_packet.push_back(L2capSdu(l2cap_test_packet_1));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_2));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_3));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_4));
+  l2cap_test_packet_5[l2cap_test_packet_5.size() - 1]++;
+  test_packet.push_back(L2capSdu(l2cap_test_packet_5));
+  l2cap_test_packet_5[l2cap_test_packet_5.size() - 1]--;
+  test_packet.push_back(L2capSdu(l2cap_test_packet_6));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_7));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_8));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_9));
+
+  test_4 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_4, nullptr);
+
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleEmptyPayload) {
+  vector<L2capSdu> test_packet;
+  vector<uint8_t> assembled_payload;
+
+  // Test 5: Pass a packet with an empty payload.
+  test_packet.push_back(L2capSdu(empty_sdu_payload[0]));
+  test_packet.push_back(L2capSdu(empty_sdu_payload[1]));
+
+  unique_ptr<L2capPacket> test_5 = L2capPacket::assemble(test_packet);
+  ASSERT_NE(test_5, nullptr);
+
+  EXPECT_EQ(test_5->get_l2cap_cid(), 0x0047);
+  assembled_payload = test_5->get_l2cap_payload();
+  compare_packets(empty_l2cap_payload, assembled_payload);
+
+  assembled_payload.clear();
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleAllStartingControlError) {
+  vector<L2capSdu> test_packet;
+
+  // Test 6: Pass a SDU with all the control bytes set to as the starting bytes.
+  test_packet.push_back(L2capSdu(all_first_packet[0]));
+  test_packet.push_back(L2capSdu(all_first_packet[1]));
+  test_packet.push_back(L2capSdu(all_first_packet[2]));
+
+  unique_ptr<L2capPacket> test_6 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_6, nullptr);
+
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleBadCID) {
+  vector<L2capSdu> test_packet;
+
+  // Test 7: Pass SDUs with mixed channel ids.
+  test_packet.push_back(L2capSdu(good_sdu[0]));
+  good_sdu[1][2]++;
+  test_packet.push_back(update_fcs(good_sdu[1]));
+  good_sdu[1][2]--;
+  test_packet.push_back(L2capSdu(good_sdu[2]));
+
+  unique_ptr<L2capPacket> test_7 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_7, nullptr);
+
+  test_packet.clear();
+
+  test_packet.push_back(L2capSdu(l2cap_test_packet_1));
+  l2cap_test_packet_2[2]++;
+  test_packet.push_back(update_fcs(l2cap_test_packet_2));
+  l2cap_test_packet_2[2]--;
+  test_packet.push_back(L2capSdu(l2cap_test_packet_3));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_4));
+  l2cap_test_packet_5[2]++;
+  test_packet.push_back(update_fcs(l2cap_test_packet_5));
+  l2cap_test_packet_5[2]--;
+  test_packet.push_back(L2capSdu(l2cap_test_packet_6));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_7));
+  l2cap_test_packet_8[2]--;
+  test_packet.push_back(update_fcs(l2cap_test_packet_8));
+  l2cap_test_packet_8[2]++;
+  test_packet.push_back(L2capSdu(l2cap_test_packet_9));
+
+  test_7 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_7, nullptr);
+
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleUnsegmentedSDU) {
+  vector<L2capSdu> test_packet;
+
+  // Test 8: Pass a complete l2cap packet.
+  test_packet.push_back(L2capSdu(one_sdu[0]));
+
+  unique_ptr<L2capPacket> test_8 = L2capPacket::assemble(test_packet);
+  EXPECT_NE(test_8, nullptr);
+
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleBadTxSeq) {
+  vector<L2capSdu> test_packet;
+
+  // Test 9: Pass SDUs with incorrect TxSeq.
+  good_sdu[0][4] += 4;
+  test_packet.push_back(update_fcs(good_sdu[0]));
+  good_sdu[0][4] -= 4;
+  test_packet.push_back(L2capSdu(good_sdu[1]));
+  test_packet.push_back(L2capSdu(good_sdu[2]));
+
+  unique_ptr<L2capPacket> test_9 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_9, nullptr);
+
+  test_packet.clear();
+}
+
+TEST_F(L2capTest, assembleBadTotalSDULength) {
+  vector<L2capSdu> test_packet;
+
+  // Test 10: Pass SDUs with an incorrect total SDU length
+  good_sdu[0][7]++;
+  test_packet.push_back(update_fcs(good_sdu[0]));
+  good_sdu[0][7]--;
+  test_packet.push_back(L2capSdu(good_sdu[1]));
+  test_packet.push_back(L2capSdu(good_sdu[2]));
+
+  unique_ptr<L2capPacket> test_10 = L2capPacket::assemble(test_packet);
+  EXPECT_EQ(test_10, nullptr);
+
+  test_packet.clear();
+
+  l2cap_test_packet_1[6]++;
+  test_packet.push_back(update_fcs(l2cap_test_packet_1));
+  l2cap_test_packet_1[6]--;
+  test_packet.push_back(L2capSdu(l2cap_test_packet_2));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_3));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_4));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_5));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_6));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_7));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_8));
+  test_packet.push_back(L2capSdu(l2cap_test_packet_9));
+
+  test_10 = L2capPacket::assemble(test_packet);
+
+  EXPECT_EQ(test_10, nullptr);
+
+  test_packet.clear();
+}
+
+// Begin Fragment Test1
+TEST_F(L2capTest, fragmentSmallSegmentTest) {
+  std::vector<L2capSdu> sdu;
+  std::unique_ptr<L2capPacket> l2cap_expected;
+  std::unique_ptr<L2capPacket> l2cap_received;
+
+  sdu.push_back(L2capSdu(good_sdu[0]));
+  sdu.push_back(L2capSdu(good_sdu[1]));
+  sdu.push_back(L2capSdu(good_sdu[2]));
+
+  l2cap_expected = L2capPacket::assemble(sdu);
+
+  sdu.clear();
+
+  // Test1: Small segments
+  sdu = l2cap_expected->fragment(16, 0x02, 0x41);
+
+  l2cap_received = L2capPacket::assemble(sdu);
+  ASSERT_NE(l2cap_received, nullptr)
+      << "packet reassembly failed after fragment" << std::endl
+      << "Test1: Small Segment request" << std::endl
+      << "sdu used: good_sdu" << std::endl
+      << "function call: fragment(16, 0x02, 0x41)" << std::endl;
+
+  std::vector<uint8_t> small_seg_expected = l2cap_expected->get_l2cap_payload();
+  std::vector<uint8_t> small_seg_received = l2cap_received->get_l2cap_payload();
+
+  compare_fragmented_packets(small_seg_expected, small_seg_received);
+
+  sdu.clear();
+  l2cap_expected.reset(nullptr);
+  l2cap_received.reset(nullptr);
+}  // End Fragment Test1
+
+// Begin Fragment Test2
+TEST_F(L2capTest, fragmentLargeSegmentTest) {
+  std::vector<L2capSdu> sdu;
+  std::unique_ptr<L2capPacket> l2cap_expected;
+  std::unique_ptr<L2capPacket> l2cap_received;
+
+  sdu.push_back(L2capSdu(l2cap_test_packet_1));
+  sdu.push_back(L2capSdu(l2cap_test_packet_2));
+  sdu.push_back(L2capSdu(l2cap_test_packet_3));
+  sdu.push_back(L2capSdu(l2cap_test_packet_4));
+  sdu.push_back(L2capSdu(l2cap_test_packet_5));
+  sdu.push_back(L2capSdu(l2cap_test_packet_6));
+  sdu.push_back(L2capSdu(l2cap_test_packet_7));
+  sdu.push_back(L2capSdu(l2cap_test_packet_8));
+  sdu.push_back(L2capSdu(l2cap_test_packet_9));
+
+  l2cap_expected = L2capPacket::assemble(sdu);
+
+  sdu.clear();
+
+  // Test2: Large Segments
+  sdu = l2cap_expected->fragment(1024, 0x02, 0x41);
+
+  l2cap_received = L2capPacket::assemble(sdu);
+  ASSERT_NE(l2cap_received, nullptr)
+      << "packet reassembly failed after fragment" << std::endl
+      << "Test2: Large Segment request" << std::endl
+      << "sdu used: l2cap_test_packet[1-9]" << std::endl
+      << "function call: fragment(1024, 0x02, 0x41)" << std::endl;
+
+  std::vector<uint8_t> large_seg_expected = l2cap_expected->get_l2cap_payload();
+  std::vector<uint8_t> large_seg_received = l2cap_received->get_l2cap_payload();
+
+  compare_fragmented_packets(large_seg_expected, large_seg_received);
+
+  sdu.clear();
+  l2cap_expected.reset(nullptr);
+  l2cap_received.reset(nullptr);
+}  // End Fragment Test2
+
+// Begin Fragment Test3
+TEST_F(L2capTest, fragmentTxSeqTest) {
+  std::vector<L2capSdu> sdu;
+  std::unique_ptr<L2capPacket> l2cap_expected;
+  std::unique_ptr<L2capPacket> l2cap_received;
+
+  sdu.push_back(L2capSdu(good_sdu[0]));
+  sdu.push_back(L2capSdu(good_sdu[1]));
+  sdu.push_back(L2capSdu(good_sdu[2]));
+
+  l2cap_expected = L2capPacket::assemble(sdu);
+
+  sdu.clear();
+
+  // Test3: Non-zero starting TxSeq
+  sdu = l2cap_expected->fragment(24, 0x08, 0x41);
+
+  l2cap_received = L2capPacket::assemble(sdu);
+  ASSERT_NE(l2cap_received, nullptr)
+      << "packet reassembly failed after fragment" << std::endl
+      << "Test3: Non-zero starting TxSeq" << std::endl
+      << "sdu used: good_sdu" << std::endl
+      << "function call: fragment(24, 0x08, 0x41)" << std::endl;
+
+  std::vector<uint8_t> txseq_expected = l2cap_expected->get_l2cap_payload();
+  std::vector<uint8_t> txseq_received = l2cap_received->get_l2cap_payload();
+
+  compare_fragmented_packets(txseq_expected, txseq_received);
+
+  sdu.clear();
+  l2cap_expected.reset(nullptr);
+  l2cap_received.reset(nullptr);
+}  // End Fragment Test3
+
+// Begin Fragment Test4
+TEST_F(L2capTest, fragmentPayloadTest) {
+  std::vector<L2capSdu> sdu;
+  std::unique_ptr<L2capPacket> l2cap_expected;
+  std::unique_ptr<L2capPacket> l2cap_received;
+
+  sdu.push_back(L2capSdu(empty_sdu_payload[0]));
+  sdu.push_back(L2capSdu(empty_sdu_payload[1]));
+
+  l2cap_expected = L2capPacket::assemble(sdu);
+
+  sdu.clear();
+
+  // Test4: Packet with no payload
+  sdu = l2cap_expected->fragment(16, 0x02, 0x41);
+
+  l2cap_received = L2capPacket::assemble(sdu);
+  ASSERT_NE(l2cap_received, nullptr)
+      << "packet reassembly failed after fragment" << std::endl
+      << "Test4: Packet with no payload" << std::endl
+      << "sdu used: empty_sdu_payload" << std::endl
+      << "function call: fragment(16, 0x02, 0x41)" << std::endl;
+
+  std::vector<uint8_t> empty_expected = l2cap_expected->get_l2cap_payload();
+  std::vector<uint8_t> empty_received = l2cap_received->get_l2cap_payload();
+
+  compare_fragmented_packets(empty_expected, empty_received);
+
+  sdu.clear();
+  l2cap_expected.reset(nullptr);
+  l2cap_received.reset(nullptr);
+}  // End Fragment Test4
+
+// Begin Fragment Test5
+TEST_F(L2capTest, fragmentSegmentSizeTest) {
+  std::vector<L2capSdu> sdu;
+  std::unique_ptr<L2capPacket> l2cap_expected;
+  std::unique_ptr<L2capPacket> l2cap_received;
+
+  sdu.push_back(L2capSdu(good_sdu[0]));
+  sdu.push_back(L2capSdu(good_sdu[1]));
+  sdu.push_back(L2capSdu(good_sdu[2]));
+
+  l2cap_expected = L2capPacket::assemble(sdu);
+
+  sdu.clear();
+
+  // Test5: Larger segment size than packet size
+  sdu = l2cap_expected->fragment(256, 0x02, 0x41);
+
+  l2cap_received = L2capPacket::assemble(sdu);
+  ASSERT_NE(l2cap_received, nullptr)
+      << "packet reassembly failed after fragment" << std::endl
+      << "Test5: Segment size > Payload" << std::endl
+      << "sdu used: good_sdu" << std::endl
+      << "function call: fragment(256, 0x02, 0x41)" << std::endl;
+
+  std::vector<uint8_t> big_segs_exp = l2cap_expected->get_l2cap_payload();
+  std::vector<uint8_t> big_segs_rcvd = l2cap_received->get_l2cap_payload();
+
+  compare_fragmented_packets(big_segs_exp, big_segs_rcvd);
+
+  sdu.clear();
+  l2cap_expected.reset(nullptr);
+  l2cap_received.reset(nullptr);
+}  // End Fragment Test5
+
+// Begin Fragment Test6
+TEST_F(L2capTest, fragmentSegmentSizeTest2) {
+  std::vector<L2capSdu> sdu;
+  std::unique_ptr<L2capPacket> l2cap_expected;
+  std::unique_ptr<L2capPacket> l2cap_received;
+
+  sdu.push_back(L2capSdu(l2cap_test_packet_1));
+  sdu.push_back(L2capSdu(l2cap_test_packet_2));
+  sdu.push_back(L2capSdu(l2cap_test_packet_3));
+  sdu.push_back(L2capSdu(l2cap_test_packet_4));
+  sdu.push_back(L2capSdu(l2cap_test_packet_5));
+  sdu.push_back(L2capSdu(l2cap_test_packet_6));
+  sdu.push_back(L2capSdu(l2cap_test_packet_7));
+  sdu.push_back(L2capSdu(l2cap_test_packet_8));
+  sdu.push_back(L2capSdu(l2cap_test_packet_9));
+
+  l2cap_expected = L2capPacket::assemble(sdu);
+  sdu.clear();
+
+  // Test6: Small segment size on large packet.
+  sdu = l2cap_expected->fragment(512, 0x02, 0x41);
+
+  l2cap_received = L2capPacket::assemble(sdu);
+  ASSERT_NE(l2cap_received, nullptr)
+      << "packet reassembly failed after fragment" << std::endl
+      << "Test6: Small Segment request on large packet" << std::endl
+      << "sdu used: l2cap_test_packet_[1-9]" << std::endl
+      << "function call: fragment(64, 0x02, 0x41)" << std::endl;
+
+  std::vector<uint8_t> small_segs_exp = l2cap_expected->get_l2cap_payload();
+  std::vector<uint8_t> small_segs_rcvd = l2cap_received->get_l2cap_payload();
+
+  compare_fragmented_packets(small_segs_exp, small_segs_rcvd);
+
+  sdu.clear();
+  l2cap_expected.reset(nullptr);
+  l2cap_received.reset(nullptr);
+}  // End Fragment Test6
+
+}  // namespace test_vendor_lib