Merge "rust: Update to syn-2"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index a3778c8..a676392 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -155,9 +155,6 @@
       "name": "net_test_eatt"
     },
     {
-      "name": "net_test_hci_fragmenter_native"
-    },
-    {
       "name": "net_test_main_shim"
     },
     {
@@ -369,9 +366,6 @@
       "name": "net_test_eatt"
     },
     {
-      "name": "net_test_hci_fragmenter_native"
-    },
-    {
       "name": "net_test_main_shim"
     },
     {
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index 382a61e..131a4aa 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -1991,6 +1991,12 @@
 
             Object[] args = generateArgs(arg);
 
+            if (!(args[0] instanceof String)) {
+                Log.w(TAG, "Incorrect type of Android AT command!");
+                mNativeInterface.atResponseCode(device, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
+                return true;
+            }
+
             String type = (String) args[0];
 
             if (type.equals(BluetoothSinkAudioPolicy.HFP_SET_SINK_AUDIO_POLICY_ID)) {
diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
index b630783..35010f0 100644
--- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
@@ -2246,11 +2246,19 @@
          *  2. remote device supports audio policy
          */
         if (getForceSetAudioPolicyProperty()) {
-            setAudioPolicy(new BluetoothSinkAudioPolicy.Builder(mHsClientAudioPolicy)
-                    .setCallEstablishPolicy(establishPolicy)
-                    .setActiveDevicePolicyAfterConnection(getConnectingTimePolicyProperty())
-                    .setInBandRingtonePolicy(getInBandRingtonePolicyProperty())
-                    .build());
+            // set call establish policy and connecting policy to POLICY_ALLOWED if allowed=true,
+            // otherwise set them to the default values
+            int connectingTimePolicy =
+                    allowed
+                            ? BluetoothSinkAudioPolicy.POLICY_ALLOWED
+                            : getConnectingTimePolicyProperty();
+
+            setAudioPolicy(
+                    new BluetoothSinkAudioPolicy.Builder(mHsClientAudioPolicy)
+                            .setCallEstablishPolicy(establishPolicy)
+                            .setActiveDevicePolicyAfterConnection(connectingTimePolicy)
+                            .setInBandRingtonePolicy(getInBandRingtonePolicyProperty())
+                            .build());
         } else {
             setAudioPolicy(new BluetoothSinkAudioPolicy.Builder(mHsClientAudioPolicy)
                 .setCallEstablishPolicy(establishPolicy).build());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java
index 2a96489..632bdb3 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java
@@ -48,7 +48,6 @@
 import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.bluetooth.R;
 import com.android.bluetooth.TestUtils;
 import com.android.bluetooth.btservice.AdapterService;
 import com.android.bluetooth.btservice.storage.DatabaseManager;
@@ -56,7 +55,6 @@
 import org.hamcrest.core.IsInstanceOf;
 import org.junit.After;
 import org.junit.Assert;
-import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -1442,22 +1440,40 @@
     @Test
     public void testCheckAndProcessAndroidAt() {
         // Commands that will be handled
+        int counter_ok = 0;
+        int counter_error = 0;
         Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt(
             "+ANDROID=?" , mTestDevice));
-        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).atResponseCode(
-                mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_ok))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
         Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt(
             "+ANDROID=SINKAUDIOPOLICY,1,1,1" , mTestDevice));
-        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).atResponseCode(
-                mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_ok))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
         Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt(
             "+ANDROID=SINKAUDIOPOLICY,100,100,100" , mTestDevice));
-        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(3)).atResponseCode(
-                mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_ok))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
         Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt(
             "+ANDROID=SINKAUDIOPOLICY,1,2,3,4,5" , mTestDevice));
-        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).atResponseCode(
-                mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_error))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
+        Assert.assertTrue(mHeadsetStateMachine.checkAndProcessAndroidAt("+ANDROID=1", mTestDevice));
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_error))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
+        Assert.assertTrue(
+                mHeadsetStateMachine.checkAndProcessAndroidAt("+ANDROID=1,2", mTestDevice));
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_error))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
+        Assert.assertTrue(
+                mHeadsetStateMachine.checkAndProcessAndroidAt("+ANDROID=1,2,3", mTestDevice));
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_error))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
+        Assert.assertTrue(
+                mHeadsetStateMachine.checkAndProcessAndroidAt(
+                        "+ANDROID=1,2,3,4,5,6,7", mTestDevice));
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(++counter_error))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
 
         // Commands with correct format but will not be handled
         Assert.assertFalse(mHeadsetStateMachine.checkAndProcessAndroidAt(
@@ -1474,10 +1490,10 @@
             "RANDOM FORMAT" , mTestDevice));
 
         // Check no any AT result was sent for the failed ones
-        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(3)).atResponseCode(
-                mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
-        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).atResponseCode(
-                mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(counter_ok))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_OK, 0);
+        verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(counter_error))
+                .atResponseCode(mTestDevice, HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
     }
 
     @Test
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java
index bfda3f7..e377201 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java
@@ -16,10 +16,7 @@
 
 package com.android.bluetooth.hfpclient;
 
-import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
-import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
 import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
-import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING;
 
 import static com.android.bluetooth.hfpclient.HeadsetClientStateMachine.AT_OK;
 import static com.android.bluetooth.hfpclient.HeadsetClientStateMachine.ENTER_PRIVATE_MODE;
@@ -58,16 +55,13 @@
 
 import com.android.bluetooth.R;
 import com.android.bluetooth.TestUtils;
-import com.android.bluetooth.Utils;
 import com.android.bluetooth.btservice.AdapterService;
 import com.android.bluetooth.hfp.HeadsetService;
-import com.android.bluetooth.hfp.HeadsetStackEvent;
 
 import org.hamcrest.core.AllOf;
 import org.hamcrest.core.IsInstanceOf;
 import org.junit.After;
 import org.junit.Assert;
-import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -935,7 +929,7 @@
         // Expect: Should send +ANDROID=SINKAUDIOPOLICY,1,2,1 to remote
         mHeadsetClientStateMachine.setForceSetAudioPolicyProperty(true);
         mHeadsetClientStateMachine.setAudioRouteAllowed(true);
-        verify(mNativeInterface).sendAndroidAt(mTestDevice, "+ANDROID=SINKAUDIOPOLICY,1,2,1");
+        verify(mNativeInterface).sendAndroidAt(mTestDevice, "+ANDROID=SINKAUDIOPOLICY,1,1,1");
     }
 
     @Test
diff --git a/android/pandora/mmi2grpc/mmi2grpc/opp.py b/android/pandora/mmi2grpc/mmi2grpc/opp.py
index 2a474ec..4f0bd3c 100644
--- a/android/pandora/mmi2grpc/mmi2grpc/opp.py
+++ b/android/pandora/mmi2grpc/mmi2grpc/opp.py
@@ -122,7 +122,7 @@
         Take action to create an rfcomm channel for an OBEX connection.
         """
 
-        self._android.SendFile()
+        self._android.SendFile('PTS')
 
         return "OK"
 
@@ -132,7 +132,7 @@
         Take action to create an l2cap channel for an OBEX connection.
         """
 
-        self._android.SendFile()
+        self._android.SendFile('PTS')
 
         return "OK"
 
diff --git a/android/pandora/server/src/com/android/pandora/AndroidInternal.kt b/android/pandora/server/src/com/android/pandora/AndroidInternal.kt
index 6f2fd32..1119acb 100644
--- a/android/pandora/server/src/com/android/pandora/AndroidInternal.kt
+++ b/android/pandora/server/src/com/android/pandora/AndroidInternal.kt
@@ -58,7 +58,10 @@
   private val INCOMING_FILE_TITLE = "Incoming file"
   private val INCOMING_FILE_WAIT_TIMEOUT = 2000L
 
-  private val BT_DEVICE_SELECT_WAIT_TIMEOUT = 3000L
+  // PTS does not configure the Extended Inquiry Response with the
+  // device name; the device will be found after the Inquiry Timeout
+  // (12.8sec) has elapsed.
+  private val BT_DEVICE_SELECT_WAIT_TIMEOUT = 20000L
   private val IMAGE_FILE_NAME = "OPP_TEST_IMAGE.bmp"
 
   private val bluetoothManager = context.getSystemService(BluetoothManager::class.java)!!
@@ -141,18 +144,15 @@
     }
   }
 
-  override fun sendFile(request: Empty, responseObserver: StreamObserver<Empty>) {
+  override fun sendFile(request: SendFileRequest, responseObserver: StreamObserver<Empty>) {
     grpcUnary<Empty>(scope, responseObserver) {
       initiateSendFile(getImageId(IMAGE_FILE_NAME), "image/bmp")
-      waitAndSelectBluetoothDevice()
+      waitAndSelectBluetoothDevice(request.name)
       Empty.getDefaultInstance()
     }
   }
 
-  override fun sendPing(
-    request: SendPingRequest,
-    responseObserver: StreamObserver<Empty>
-  ) {
+  override fun sendPing(request: SendPingRequest, responseObserver: StreamObserver<Empty>) {
     grpcUnary<Empty>(scope, responseObserver) {
       val pingStatus =
         Runtime.getRuntime().exec("ping -I bt-pan -c 1 ${request.ipAddress}").waitFor()
@@ -160,12 +160,10 @@
     }
   }
 
-  suspend private fun waitAndSelectBluetoothDevice() {
+  suspend private fun waitAndSelectBluetoothDevice(name: String) {
     var selectJob =
       scope.async {
-        device
-          .wait(Until.findObject(By.textContains("Cuttlefish")), BT_DEVICE_SELECT_WAIT_TIMEOUT)
-          .click()
+        device.wait(Until.findObject(By.textContains(name)), BT_DEVICE_SELECT_WAIT_TIMEOUT).click()
       }
     selectJob.await()
   }
diff --git a/android/pandora/test/Android.bp b/android/pandora/test/Android.bp
index 5fd5e30..1d73c36 100644
--- a/android/pandora/test/Android.bp
+++ b/android/pandora/test/Android.bp
@@ -20,9 +20,8 @@
     name: "avatar",
     main: "main.py",
     srcs: [
-        "*_test.py",
-        "example.py",
-        "main.py",
+        "*.py",
+        ":avatar-cases",
     ],
     libs: [
         "bumble_services_experimental-python",
diff --git a/android/pandora/test/asha_test.py b/android/pandora/test/asha_test.py
index 0eeabc4..24332e2 100644
--- a/android/pandora/test/asha_test.py
+++ b/android/pandora/test/asha_test.py
@@ -18,7 +18,8 @@
 import grpc
 import logging
 
-from avatar import BumblePandoraDevice, PandoraDevice, PandoraDevices, asynchronous, bumble_server
+from avatar import BumblePandoraDevice, PandoraDevice, PandoraDevices, asynchronous
+from bumble import pandora as bumble_server
 from bumble.gatt import GATT_ASHA_SERVICE
 from bumble.pairing import PairingDelegate
 from bumble_experimental.asha import AshaGattService, AshaService
@@ -48,7 +49,7 @@
     RIGHT = 1
 
 
-class ASHATest(base_test.BaseTestClass):  # type: ignore[misc]
+class AshaTest(base_test.BaseTestClass):  # type: ignore[misc]
     devices: Optional[PandoraDevices] = None
 
     # pandora devices.
diff --git a/android/pandora/test/avatar.sh b/android/pandora/test/avatar.sh
index 69f6cca..688ee1c 100755
--- a/android/pandora/test/avatar.sh
+++ b/android/pandora/test/avatar.sh
@@ -24,10 +24,9 @@
 _BT_ROOT="${ANDROID_BUILD_TOP}/packages/modules/Bluetooth"
 _TEST_ROOT="${_BT_ROOT}/android/pandora/test"
 _PY_SOURCES=(
-  "${ANDROID_BUILD_TOP}/external/pandora/avatar/"{avatar,examples}
+  "${ANDROID_BUILD_TOP}/external/pandora/avatar/"{avatar,cases}
   "${_BT_ROOT}/pandora/server/bumble_experimental"
-  "${_TEST_ROOT}/"*_test.py
-  "${_TEST_ROOT}/main.py"
+  "${_TEST_ROOT}/"*.py
 )
 
 _PANDORA_PYTHON_PATHS=(
diff --git a/android/pandora/test/classic_ssp_test.py b/android/pandora/test/classic_ssp_test.py
deleted file mode 100644
index 0b1335f..0000000
--- a/android/pandora/test/classic_ssp_test.py
+++ /dev/null
@@ -1,330 +0,0 @@
-# Copyright 2023 Google LLC
-#
-# 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
-#
-#     https://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.
-
-import asyncio
-import avatar
-import itertools
-import logging
-
-from avatar import BumblePandoraDevice, PandoraDevice, PandoraDevices
-from bumble.hci import HCI_CENTRAL_ROLE, HCI_PERIPHERAL_ROLE
-from bumble.pairing import PairingDelegate
-from mobly import base_test, signals, test_runner
-from mobly.asserts import assert_equal  # type: ignore
-from mobly.asserts import assert_in  # type: ignore
-from mobly.asserts import assert_is_not_none  # type: ignore
-from mobly.asserts import fail  # type: ignore
-from pandora.host_pb2 import Connection
-from pandora.security_pb2 import LEVEL2, PairingEventAnswer, SecureResponse, SecurityLevel, WaitSecurityResponse
-from typing import Callable, Coroutine, Optional, Tuple
-
-ALL_ROLES = (HCI_CENTRAL_ROLE, HCI_PERIPHERAL_ROLE)
-ALL_IO_CAPABILITIES = (
-    None,
-    PairingDelegate.DISPLAY_OUTPUT_ONLY,
-    PairingDelegate.DISPLAY_OUTPUT_AND_YES_NO_INPUT,
-    PairingDelegate.KEYBOARD_INPUT_ONLY,
-    PairingDelegate.NO_OUTPUT_NO_INPUT,
-    PairingDelegate.DISPLAY_OUTPUT_AND_KEYBOARD_INPUT,
-)
-
-
-class ClassicSspTest(base_test.BaseTestClass):  # type: ignore[misc]
-    '''
-    This class aim to test SSP (Secure Simple Pairing) on Classic
-    Bluetooth devices.
-    '''
-
-    devices: Optional[PandoraDevices] = None
-
-    # pandora devices.
-    dut: PandoraDevice
-    ref: PandoraDevice
-
-    @avatar.asynchronous
-    async def setup_class(self) -> None:
-        self.devices = PandoraDevices(self)
-        self.dut, self.ref, *_ = self.devices
-
-        # Enable BR/EDR mode and SSP for Bumble devices.
-        for device in self.devices:
-            if isinstance(device, BumblePandoraDevice):
-                device.config.setdefault('classic_enabled', True)
-                device.config.setdefault('classic_ssp_enabled', True)
-                device.config.setdefault(
-                    'server',
-                    {
-                        'io_capability': 'display_output_and_yes_no_input',
-                    },
-                )
-
-        await asyncio.gather(self.dut.reset(), self.ref.reset())
-
-    def teardown_class(self) -> None:
-        if self.devices:
-            self.devices.stop_all()
-
-    @avatar.asynchronous
-    async def setup_test(self) -> None:  # pytype: disable=wrong-arg-types
-        await asyncio.gather(self.dut.reset(), self.ref.reset())
-
-    @avatar.parameterized(*itertools.product(ALL_IO_CAPABILITIES, ALL_ROLES))  # type: ignore[misc]
-    @avatar.asynchronous
-    async def test_success_initiate_connection_initiate_pairing(
-        self,
-        ref_io_capability: Optional[PairingDelegate.IoCapability],
-        ref_role: Optional[int],
-    ) -> None:
-        # Override REF IO capability if supported.
-        set_io_capability(self.ref, ref_io_capability)
-
-        # Connection/pairing task.
-        async def connect_and_pair() -> Tuple[SecureResponse, WaitSecurityResponse]:
-            dut_ref, ref_dut = await make_classic_connection(self.dut, self.ref)
-            if ref_role is not None:
-                await role_switch(self.ref, ref_dut, ref_role)
-            return await authenticate(self.dut, dut_ref, self.ref, ref_dut, LEVEL2)
-
-        # Handle pairing.
-        initiator_pairing, acceptor_pairing = await handle_pairing(
-            self.dut,
-            self.ref,
-            connect_and_pair,
-        )
-
-        # Assert success.
-        assert_equal(initiator_pairing.result_variant(), 'success')
-        assert_equal(acceptor_pairing.result_variant(), 'success')
-
-    @avatar.parameterized(*itertools.product(ALL_IO_CAPABILITIES, ALL_ROLES))  # type: ignore[misc]
-    @avatar.asynchronous
-    async def test_success_initiate_connection_accept_pairing(
-        self,
-        ref_io_capability: Optional[PairingDelegate.IoCapability],
-        ref_role: Optional[int],
-    ) -> None:
-        if not isinstance(self.dut, BumblePandoraDevice):
-            raise signals.TestSkip('TODO: Fix rootcanal when both AOSP and Bumble trigger the auth.')
-
-        # Override REF IO capability if supported.
-        set_io_capability(self.ref, ref_io_capability)
-
-        # Connection/pairing task.
-        async def connect_and_pair() -> Tuple[SecureResponse, WaitSecurityResponse]:
-            dut_ref, ref_dut = await make_classic_connection(self.dut, self.ref)
-            if ref_role is not None:
-                await role_switch(self.ref, ref_dut, ref_role)
-            return await authenticate(self.ref, ref_dut, self.dut, dut_ref, LEVEL2)
-
-        # Handle pairing.
-        initiator_pairing, acceptor_pairing = await handle_pairing(
-            self.dut,
-            self.ref,
-            connect_and_pair,
-        )
-
-        # Assert success.
-        assert_equal(initiator_pairing.result_variant(), 'success')
-        assert_equal(acceptor_pairing.result_variant(), 'success')
-
-    @avatar.parameterized(*itertools.product(ALL_IO_CAPABILITIES, ALL_ROLES))  # type: ignore[misc]
-    @avatar.asynchronous
-    async def test_success_accept_connection_initiate_pairing(
-        self,
-        ref_io_capability: Optional[PairingDelegate.IoCapability],
-        ref_role: Optional[int],
-    ) -> None:
-        # Override REF IO capability if supported.
-        set_io_capability(self.ref, ref_io_capability)
-
-        # Connection/pairing task.
-        async def connect_and_pair() -> Tuple[SecureResponse, WaitSecurityResponse]:
-            ref_dut, dut_ref = await make_classic_connection(self.ref, self.dut)
-            if ref_role is not None:
-                await role_switch(self.ref, ref_dut, ref_role)
-            return await authenticate(self.dut, dut_ref, self.ref, ref_dut, LEVEL2)
-
-        # Handle pairing.
-        initiator_pairing, acceptor_pairing = await handle_pairing(
-            self.dut,
-            self.ref,
-            connect_and_pair,
-        )
-
-        # Assert success.
-        assert_equal(initiator_pairing.result_variant(), 'success')
-        assert_equal(acceptor_pairing.result_variant(), 'success')
-
-    @avatar.parameterized(*itertools.product(ALL_IO_CAPABILITIES, ALL_ROLES))  # type: ignore[misc]
-    @avatar.asynchronous
-    async def test_success_accept_connection_accept_pairing(
-        self,
-        ref_io_capability: Optional[PairingDelegate.IoCapability],
-        ref_role: Optional[int],
-    ) -> None:
-        # Override REF IO capability if supported.
-        set_io_capability(self.ref, ref_io_capability)
-
-        # Connection/pairing task.
-        async def connect_and_pair() -> Tuple[SecureResponse, WaitSecurityResponse]:
-            ref_dut, dut_ref = await make_classic_connection(self.ref, self.dut)
-            if ref_role is not None:
-                await role_switch(self.ref, ref_dut, ref_role)
-            return await authenticate(self.ref, ref_dut, self.dut, dut_ref, LEVEL2)
-
-        # Handle pairing.
-        initiator_pairing, acceptor_pairing = await handle_pairing(
-            self.dut,
-            self.ref,
-            connect_and_pair,
-        )
-
-        # Assert success.
-        assert_equal(initiator_pairing.result_variant(), 'success')
-        assert_equal(acceptor_pairing.result_variant(), 'success')
-
-
-def set_io_capability(device: PandoraDevice, io_capability: Optional[PairingDelegate.IoCapability]) -> None:
-    if io_capability is None:
-        return
-    if isinstance(device, BumblePandoraDevice):
-        # Override Bumble reference device default IO capability.
-        device.server_config.io_capability = io_capability
-    else:
-        raise signals.TestSkip('Unable to override IO capability on non Bumble device.')
-
-
-# Connection task.
-async def make_classic_connection(initiator: PandoraDevice, acceptor: PandoraDevice) -> Tuple[Connection, Connection]:
-    '''Connect two device and returns both connection tokens.'''
-
-    (connect, wait_connection) = await asyncio.gather(
-        initiator.aio.host.Connect(address=acceptor.address),
-        acceptor.aio.host.WaitConnection(address=initiator.address),
-    )
-
-    # Assert connection are successful.
-    assert_equal(connect.result_variant(), 'connection')
-    assert_equal(wait_connection.result_variant(), 'connection')
-    assert_is_not_none(connect.connection)
-    assert_is_not_none(wait_connection.connection)
-    assert connect.connection and wait_connection.connection
-
-    # Returns connections.
-    return connect.connection, wait_connection.connection
-
-
-# Pairing task.
-async def authenticate(
-    initiator: PandoraDevice,
-    initiator_connection: Connection,
-    acceptor: PandoraDevice,
-    acceptor_connection: Connection,
-    security_level: SecurityLevel,
-) -> Tuple[SecureResponse, WaitSecurityResponse]:
-    '''Pair two device and returns both pairing responses.'''
-
-    return await asyncio.gather(
-        initiator.aio.security.Secure(connection=initiator_connection, classic=security_level),
-        acceptor.aio.security.WaitSecurity(connection=acceptor_connection, classic=security_level),
-    )
-
-
-# Role switch task.
-async def role_switch(
-    device: PandoraDevice,
-    connection: Connection,
-    role: int,
-) -> None:
-    '''Switch role if supported.'''
-
-    if not isinstance(device, BumblePandoraDevice):
-        return
-
-    connection_handle = int.from_bytes(connection.cookie.value, 'big')
-    bumble_connection = device.device.lookup_connection(connection_handle)
-    assert_is_not_none(bumble_connection)
-    assert bumble_connection
-
-    if bumble_connection.role != role:
-        device.log.info(f"Role switch to: {'`CENTRAL`' if role == HCI_CENTRAL_ROLE else '`PERIPHERAL`'}")
-        await bumble_connection.switch_role(role)
-
-
-# Handle pairing events task.
-async def handle_pairing(
-    dut: PandoraDevice,
-    ref: PandoraDevice,
-    connect_and_pair: Callable[[], Coroutine[None, None, Tuple[SecureResponse, WaitSecurityResponse]]],
-    confirm: Callable[[bool], bool] = lambda x: x,
-    passkey: Callable[[int], int] = lambda x: x,
-) -> Tuple[SecureResponse, WaitSecurityResponse]:
-
-    # Listen for pairing event on bot DUT and REF.
-    dut_pairing, ref_pairing = dut.aio.security.OnPairing(), ref.aio.security.OnPairing()
-
-    # Start connection/pairing.
-    connect_and_pair_task = asyncio.create_task(connect_and_pair())
-
-    try:
-        dut_ev = await asyncio.wait_for(anext(dut_pairing), timeout=25.0)
-        dut.log.info(f'DUT pairing event: {dut_ev.method_variant()}')
-
-        ref_ev = await asyncio.wait_for(anext(ref_pairing), timeout=3.0)
-        ref.log.info(f'REF pairing event: {ref_ev.method_variant()}')
-
-        if dut_ev.method_variant() in ('numeric_comparison', 'just_works'):
-            assert_in(ref_ev.method_variant(), ('numeric_comparison', 'just_works'))
-            confirm_res = True
-            if dut_ev.method_variant() == 'numeric_comparison' and ref_ev.method_variant() == 'numeric_comparison':
-                confirm_res = ref_ev.numeric_comparison == dut_ev.numeric_comparison
-            confirm_res = confirm(confirm_res)
-            dut_pairing.send_nowait(PairingEventAnswer(event=dut_ev, confirm=confirm_res))
-            ref_pairing.send_nowait(PairingEventAnswer(event=ref_ev, confirm=confirm_res))
-
-        elif dut_ev.method_variant() == 'passkey_entry_notification':
-            assert_equal(ref_ev.method_variant(), 'passkey_entry_request')
-            assert_is_not_none(dut_ev.passkey_entry_notification)
-            assert dut_ev.passkey_entry_notification is not None
-            passkey_res = passkey(dut_ev.passkey_entry_notification)
-            ref_pairing.send_nowait(PairingEventAnswer(event=ref_ev, passkey=passkey_res))
-
-        elif dut_ev.method_variant() == 'passkey_entry_request':
-            assert_equal(ref_ev.method_variant(), 'passkey_entry_notification')
-            assert_is_not_none(ref_ev.passkey_entry_notification)
-            assert ref_ev.passkey_entry_notification is not None
-            passkey_res = passkey(ref_ev.passkey_entry_notification)
-            dut_pairing.send_nowait(PairingEventAnswer(event=dut_ev, passkey=passkey_res))
-
-        else:
-            fail("")
-
-    except (asyncio.CancelledError, asyncio.TimeoutError):
-        logging.exception('Pairing timed-out.')
-
-    finally:
-
-        try:
-            (secure, wait_security) = await asyncio.wait_for(connect_and_pair_task, 15.0)
-            logging.info(f'Pairing result: {secure.result_variant()}/{wait_security.result_variant()}')
-            return secure, wait_security
-
-        finally:
-            dut_pairing.cancel()
-            ref_pairing.cancel()
-
-
-if __name__ == '__main__':
-    logging.basicConfig(level=logging.DEBUG)
-    test_runner.main()  # type: ignore
diff --git a/android/pandora/test/example.py b/android/pandora/test/example.py
deleted file mode 120000
index 27ac5be..0000000
--- a/android/pandora/test/example.py
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../external/pandora/avatar/examples/example.py
\ No newline at end of file
diff --git a/android/pandora/test/gatt_test.py b/android/pandora/test/gatt_test.py
index 156e27b..df8b912 100644
--- a/android/pandora/test/gatt_test.py
+++ b/android/pandora/test/gatt_test.py
@@ -16,7 +16,8 @@
 import avatar
 import logging
 
-from avatar import BumblePandoraDevice, PandoraDevice, PandoraDevices, bumble_server
+from avatar import BumblePandoraDevice, PandoraDevice, PandoraDevices
+from bumble import pandora as bumble_server
 from bumble.gatt import Characteristic, Service
 from bumble.pairing import PairingConfig
 from bumble_experimental.gatt import GATTService
diff --git a/android/pandora/test/le_advertising_test.py b/android/pandora/test/le_advertising_test.py
deleted file mode 100644
index cb7f6eb..0000000
--- a/android/pandora/test/le_advertising_test.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright 2022 Google LLC
-#
-# 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
-#
-#     https://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.
-
-import asyncio
-import enum
-import logging
-import random
-
-from avatar import PandoraDevice, PandoraDevices, asynchronous, parameterized
-from mobly import base_test, test_runner
-from mobly.asserts import assert_equal  # type: ignore
-from mobly.asserts import assert_false  # type: ignore
-from mobly.asserts import assert_true  # type: ignore
-from pandora.host_pb2 import PUBLIC, DataTypes
-from typing import Any, Dict, Optional
-
-
-class AdvertisingEventProperties(enum.IntEnum):
-    ADV_IND = 0x13
-    ADV_DIRECT_IND = 0x15
-    ADV_SCAN_IND = 0x12
-    ADV_NONCONN_IND = 0x10
-
-    CONNECTABLE = 0x01
-    SCANNABLE = 0x02
-    DIRECTED = 0x04
-    LEGACY = 0x10
-    ANONYMOUS = 0x20
-
-
-class LeAdvertisingTest(base_test.BaseTestClass):  # type: ignore[misc]
-    """Suite of tests designed to validate that Android correctly reports
-    all kinds of advertising events to the user application."""
-
-    devices: Optional[PandoraDevices] = None
-    dut: PandoraDevice
-    ref: PandoraDevice
-
-    def setup_class(self) -> None:
-        self.devices = PandoraDevices(self)
-        dut, ref, *_ = self.devices
-        self.dut, self.ref = dut, ref
-
-    def teardown_class(self) -> None:
-        if self.devices:
-            self.devices.stop_all()
-
-    @asynchronous
-    async def setup_test(self) -> None:
-        await asyncio.gather(self.dut.reset(), self.ref.reset())
-
-    @parameterized(
-        (AdvertisingEventProperties.ADV_IND, 0),
-        (AdvertisingEventProperties.ADV_IND, 31),
-        (AdvertisingEventProperties.ADV_DIRECT_IND, 0),
-        (AdvertisingEventProperties.ADV_SCAN_IND, 0),
-        (AdvertisingEventProperties.ADV_SCAN_IND, 31),
-        (AdvertisingEventProperties.ADV_NONCONN_IND, 0),
-        (AdvertisingEventProperties.ADV_NONCONN_IND, 31),
-    )  # type: ignore[misc]
-    def test_legacy_advertising_parameters(
-        self, advertising_event_properties: AdvertisingEventProperties, advertising_data_length: int
-    ) -> None:
-        # Advertise from the Ref device with the specified legacy advertising
-        # event properties. Use the manufacturer specific data to pad the advertising data to the
-        # desired length. The scan response data must always be provided when
-        # scannable but it is defaulted.
-        connectable = (advertising_event_properties & AdvertisingEventProperties.CONNECTABLE) != 0
-        scannable = (advertising_event_properties & AdvertisingEventProperties.SCANNABLE) != 0
-        directed = (advertising_event_properties & AdvertisingEventProperties.DIRECTED) != 0
-
-        manufacturer_specific_data_length = max(0, advertising_data_length - 5)  # Flags (3) + LV (2)
-        manufacturer_specific_data = bytes([random.randint(1, 255) for _ in range(manufacturer_specific_data_length)])
-        advertising_data = (
-            DataTypes(manufacturer_specific_data=manufacturer_specific_data) if advertising_data_length > 0 else None
-        )
-
-        scan_response_data = DataTypes() if scannable else None
-        target = self.dut.address if directed else None
-
-        advertiser = self.ref.host.Advertise(
-            legacy=True,
-            connectable=connectable,
-            data=advertising_data,  # type: ignore[arg-type]
-            scan_response_data=scan_response_data,  # type: ignore[arg-type]
-            public=target,
-            own_address_type=PUBLIC,
-        )
-        scanner = self.dut.host.Scan(legacy=False, passive=False)
-
-        report = next((x for x in scanner if x.public == self.ref.address))
-
-        scanner.cancel()
-        advertiser.cancel()
-
-        assert_true(report.legacy, msg='expected legacy advertising report')
-        assert_equal(report.connectable, connectable)
-        # TODO: scannable is not set by the android server
-        # assert_equal(report.scannable, scannable)
-        # TODO: direct_address is not set by the android server
-        assert_equal(report.data.manufacturer_specific_data, manufacturer_specific_data)
-        assert_false(report.truncated, msg='expected non-truncated advertising report')
-
-    @parameterized(
-        (dict(incomplete_service_class_uuids16=["183A", "181F"]),),
-        # (dict(complete_service_class_uuids16=["183A", "181F"]),),
-        (dict(incomplete_service_class_uuids32=["FFFF183A", "FFFF181F"]),),
-        # (dict(complete_service_class_uuids32=["FFFF183A", "FFFF181F"]),),
-        (dict(incomplete_service_class_uuids128=["FFFF181F-FFFF-1000-8000-00805F9B34FB"]),),
-        # (dict(complete_service_class_uuids128=["FFFF183A-FFFF-1000-8000-00805F9B34FB"]),),
-        (dict(shortened_local_name="avatar"),),
-        (dict(complete_local_name="avatar_the_last_test_blender"),),
-        (dict(tx_power_level=20),),
-        (dict(class_of_device=0x40680),),
-        (dict(peripheral_connection_interval_min=0x0006, peripheral_connection_interval_max=0x0C80),),
-        (dict(service_solicitation_uuids16=["183A", "181F"]),),
-        (dict(service_solicitation_uuids32=["FFFF183A", "FFFF181F"]),),
-        (dict(service_solicitation_uuids128=["FFFF183A-FFFF-1000-8000-00805F9B34FB"]),),
-        (dict(service_data_uuid16={"183A": bytes([1, 2, 3, 4])}),),
-        (dict(service_data_uuid32={"FFFF183A": bytes([1, 2, 3, 4])}),),
-        (dict(service_data_uuid128={"FFFF181F-FFFF-1000-8000-00805F9B34FB": bytes([1, 2, 3, 4])}),),
-        # (dict(public_target_addresses=[bytes([1, 2, 3, 4, 5, 6]),
-        #                                   bytes([6, 5, 2, 4, 3, 1])]),),
-        # (dict(random_target_addresses=[bytes([1, 2, 3, 4, 5, 6]),
-        #                                   bytes([6, 5, 2, 4, 3, 1])]),),
-        (dict(appearance=0x0591),),
-        (dict(advertising_interval=0x1000),),
-        # (dict(advertising_interval=0x100000),),
-        (dict(uri="https://www.google.com"),),
-        (dict(le_supported_features=bytes([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0x9F])),),
-        (dict(manufacturer_specific_data=bytes([0, 1, 2, 3, 4])),),
-        # (dict(le_discoverability_mode=DISCOVERABLE_GENERAL),),
-    )  # type: ignore[misc]
-    def test_advertising_data_types(self, advertising_data: Dict[str, Any]) -> None:
-        # Advertise from the Ref device with the specified advertising data.
-        # Validate that the Ref generates the correct advertising data,
-        # and that the dut presents the correct advertising data in the scan
-        # result.
-        advertiser = self.ref.host.Advertise(
-            legacy=True,
-            connectable=True,
-            data=DataTypes(**advertising_data),
-            own_address_type=PUBLIC,
-        )
-        scanner = self.dut.host.Scan(legacy=False, passive=False)
-
-        report = next((x for x in scanner if x.public == self.ref.address))
-
-        scanner.cancel()
-        advertiser.cancel()
-
-        assert_true(report.legacy, msg='expected legacy advertising report')
-        assert_equal(report.connectable, True)
-        for (key, value) in advertising_data.items():  # type: ignore [misc]
-            assert_equal(getattr(report.data, key), value)  # type: ignore [misc]
-        assert_false(report.truncated, msg='expected non-truncated advertising report')
-
-
-if __name__ == '__main__':
-    logging.basicConfig(level=logging.DEBUG)
-    test_runner.main()  # type: ignore
diff --git a/android/pandora/test/main.py b/android/pandora/test/main.py
index d963e31..f1a27ab 100644
--- a/android/pandora/test/main.py
+++ b/android/pandora/test/main.py
@@ -13,21 +13,23 @@
 
 _BUMBLE_BTSNOOP_FMT = 'bumble_btsnoop_{pid}_{instance}.log'
 
-# Import test modules.
+# Import test cases modules.
 import asha_test
-import classic_ssp_test
-import example
+import cases.host_test
+import cases.le_host_test
+import cases.le_security_test
+import cases.security_test
 import gatt_test
-import le_advertising_test
 import smp_test
 
 _TEST_CLASSES_LIST = [
-    example.ExampleTest,
-    asha_test.ASHATest,
-    gatt_test.GattTest,
-    le_advertising_test.LeAdvertisingTest,
+    cases.host_test.HostTest,
+    cases.le_host_test.LeHostTest,
+    cases.security_test.SecurityTest,
+    cases.le_security_test.LeSecurityTest,
     smp_test.SmpTest,
-    classic_ssp_test.ClassicSspTest,
+    gatt_test.GattTest,
+    asha_test.AshaTest,
 ]
 
 
diff --git a/framework/java/android/bluetooth/BluetoothHapClient.java b/framework/java/android/bluetooth/BluetoothHapClient.java
index 75665b4..f9ff308 100644
--- a/framework/java/android/bluetooth/BluetoothHapClient.java
+++ b/framework/java/android/bluetooth/BluetoothHapClient.java
@@ -88,11 +88,9 @@
                                 service.registerCallback(mCallback, mAttributionSource, recv);
                                 recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
                             }
-                        } catch (TimeoutException e) {
+                        } catch (RemoteException | TimeoutException e) {
                             Log.e(TAG, e.toString() + "\n"
                                     + Log.getStackTraceString(new Throwable()));
-                        } catch (RemoteException e) {
-                            throw e.rethrowFromSystemServer();
                         }
                     }
                 }
diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java
index af7e0fe..1f749be 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudio.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudio.java
@@ -91,10 +91,8 @@
                                 service.registerCallback(mCallback, mAttributionSource, recv);
                                 recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
                             }
-                        } catch (TimeoutException e) {
+                        } catch (RemoteException | TimeoutException e) {
                             Log.e(TAG, "Failed to register callback", e);
-                        } catch (RemoteException e) {
-                            throw e.rethrowFromSystemServer();
                         }
                     }
                 }
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcast.java b/framework/java/android/bluetooth/BluetoothLeBroadcast.java
index 89fb54e..d724335 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcast.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcast.java
@@ -194,11 +194,12 @@
                                 recv.awaitResultNoInterrupt(getSyncTimeout())
                                         .getValue(null);
                             }
-                        } catch (TimeoutException e) {
-                            Log.e(TAG, "onBluetoothServiceUp: Failed to register "
-                                    + "Le Broadcaster callback", e);
-                        } catch (RemoteException e) {
-                            throw e.rethrowFromSystemServer();
+                        } catch (RemoteException | TimeoutException e) {
+                            Log.e(
+                                    TAG,
+                                    "onServiceConnected: Failed to register "
+                                            + "Le Broadcaster callback",
+                                    e);
                         }
                     }
                 }
diff --git a/framework/java/android/bluetooth/BluetoothProfileConnector.java b/framework/java/android/bluetooth/BluetoothProfileConnector.java
index 8620ed6..7eaebcd 100644
--- a/framework/java/android/bluetooth/BluetoothProfileConnector.java
+++ b/framework/java/android/bluetooth/BluetoothProfileConnector.java
@@ -131,7 +131,7 @@
     private boolean doBind() {
         synchronized (mConnection) {
             if (mService == null) {
-                logDebug("Binding service...");
+                logDebug("Binding service for " + mContext.getPackageName());
                 mCloseGuard.open("doUnbind");
                 try {
                     return BluetoothAdapter.getDefaultAdapter().getBluetoothManager()
@@ -148,7 +148,7 @@
     private void doUnbind() {
         synchronized (mConnection) {
             if (mService != null) {
-                logDebug("Unbinding service...");
+                logDebug("Unbinding service for " + mContext.getPackageName());
                 mCloseGuard.close();
                 try {
                     BluetoothAdapter.getDefaultAdapter().getBluetoothManager()
diff --git a/framework/java/android/bluetooth/BluetoothUtils.java b/framework/java/android/bluetooth/BluetoothUtils.java
index 1167837..1eb59df 100644
--- a/framework/java/android/bluetooth/BluetoothUtils.java
+++ b/framework/java/android/bluetooth/BluetoothUtils.java
@@ -35,10 +35,8 @@
      */
     private BluetoothUtils() {}
 
-    /**
-     * Timeout value for synchronous binder call
-     */
-    private static final Duration SYNC_CALLS_TIMEOUT = Duration.ofSeconds(5);
+    /** Timeout value for synchronous binder call */
+    private static final Duration SYNC_CALLS_TIMEOUT = Duration.ofSeconds(3);
 
     /**
      * @return timeout value for synchronous binder call
diff --git a/pandora/interfaces/pandora_experimental/_android.proto b/pandora/interfaces/pandora_experimental/_android.proto
index 4c495ca..530e208 100644
--- a/pandora/interfaces/pandora_experimental/_android.proto
+++ b/pandora/interfaces/pandora_experimental/_android.proto
@@ -21,7 +21,8 @@
   // Accept incoming file
   rpc AcceptIncomingFile(google.protobuf.Empty) returns (google.protobuf.Empty);
   // Send file
-  rpc SendFile(google.protobuf.Empty) returns (google.protobuf.Empty);
+  rpc SendFile(SendFileRequest) returns (google.protobuf.Empty);
+
   // Send ping
   rpc SendPing(SendPingRequest) returns (google.protobuf.Empty);
 }
@@ -45,6 +46,11 @@
   AccessType access_type = 2;
 }
 
+message SendFileRequest {
+  // Peer Bluetooth Device name.
+  string name = 1;
+}
+
 // Internal representation of a Connection - not exposed to clients, included here
 // just for code-generation convenience. This is what we put in the Connection.cookie.
 message InternalConnectionRef {
@@ -55,4 +61,4 @@
 // Request for the `SendPing` rpc.
 message SendPingRequest {
   string ip_address = 1;
-}
\ No newline at end of file
+}
diff --git a/pandora/server/bumble_experimental/asha.py b/pandora/server/bumble_experimental/asha.py
index fab9100..8db1a56 100644
--- a/pandora/server/bumble_experimental/asha.py
+++ b/pandora/server/bumble_experimental/asha.py
@@ -17,7 +17,6 @@
 import logging
 import struct
 
-from avatar.bumble_server import utils
 from bumble.core import AdvertisingData
 from bumble.device import Connection, Connection as BumbleConnection, Device
 from bumble.gatt import (
@@ -32,6 +31,7 @@
     TemplateService,
 )
 from bumble.l2cap import Channel
+from bumble.pandora import utils
 from bumble.utils import AsyncRunner
 from google.protobuf.empty_pb2 import Empty  # pytype: disable=pyi-error
 from pandora_experimental.asha_grpc_aio import AshaServicer
diff --git a/pandora/server/bumble_experimental/gatt.py b/pandora/server/bumble_experimental/gatt.py
index 323a43e..adbb6dd 100644
--- a/pandora/server/bumble_experimental/gatt.py
+++ b/pandora/server/bumble_experimental/gatt.py
@@ -16,10 +16,10 @@
 import grpc
 import logging
 
-from avatar.bumble_server import utils
 from bumble.core import ProtocolError
 from bumble.device import Connection as BumbleConnection, Device, Peer
 from bumble.gatt_client import CharacteristicProxy, ServiceProxy
+from bumble.pandora import utils
 from pandora_experimental.gatt_grpc_aio import GATTServicer
 from pandora_experimental.gatt_pb2 import (
     SUCCESS,
diff --git a/service/src/com/android/server/bluetooth/BluetoothDeviceConfigChangeTracker.java b/service/src/com/android/server/bluetooth/BluetoothDeviceConfigChangeTracker.java
deleted file mode 100644
index a035338..0000000
--- a/service/src/com/android/server/bluetooth/BluetoothDeviceConfigChangeTracker.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2022 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.
- */
-
-package com.android.server.bluetooth;
-
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * The BluetoothDeviceConfigChangeTracker receives changes to the DeviceConfig for
- * NAMESPACE_BLUETOOTH, and determines whether we should queue a restart, if any Bluetooth-related
- * INIT_ flags have been changed.
- *
- * <p>The initialProperties should be fetched from the BLUETOOTH namespace in DeviceConfig
- */
-public final class BluetoothDeviceConfigChangeTracker {
-    private static final String TAG = "BluetoothDeviceConfigChangeTracker";
-
-    private final HashMap<String, String> mCurrFlags;
-
-    public BluetoothDeviceConfigChangeTracker(Properties initialProperties) {
-        mCurrFlags = getFlags(initialProperties);
-    }
-
-    /**
-     * Updates the instance state tracking the latest init flag values, and determines whether an
-     * init flag has changed (requiring a restart at some point)
-     */
-    public boolean shouldRestartWhenPropertiesUpdated(Properties newProperties) {
-        if (!newProperties.getNamespace().equals(DeviceConfig.NAMESPACE_BLUETOOTH)) {
-            return false;
-        }
-        ArrayList<String> flags = new ArrayList<>();
-        for (String name : newProperties.getKeyset()) {
-            flags.add(name + "='" + newProperties.getString(name, "") + "'");
-        }
-        Log.d(TAG, "shouldRestartWhenPropertiesUpdated: " + String.join(",", flags));
-        boolean shouldRestart = false;
-        for (String name : newProperties.getKeyset()) {
-            if (!isInitFlag(name)) {
-                continue;
-            }
-            var oldValue = mCurrFlags.get(name);
-            var newValue = newProperties.getString(name, "");
-            if (newValue.equals(oldValue)) {
-                continue;
-            }
-            Log.d(TAG, "Property " + name + " changed from " + oldValue + " -> " + newValue);
-            mCurrFlags.put(name, newValue);
-            shouldRestart = true;
-        }
-        return shouldRestart;
-    }
-
-    private HashMap<String, String> getFlags(Properties initialProperties) {
-        var out = new HashMap();
-        for (var name : initialProperties.getKeyset()) {
-            if (isInitFlag(name)) {
-                out.put(name, initialProperties.getString(name, ""));
-            }
-        }
-        return out;
-    }
-
-    private Boolean isInitFlag(String flagName) {
-        return flagName.startsWith("INIT_");
-    }
-}
diff --git a/service/src/com/android/server/bluetooth/BluetoothDeviceConfigListener.java b/service/src/com/android/server/bluetooth/BluetoothDeviceConfigListener.java
deleted file mode 100644
index 197ec46..0000000
--- a/service/src/com/android/server/bluetooth/BluetoothDeviceConfigListener.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.bluetooth;
-
-import android.provider.DeviceConfig;
-import android.util.Log;
-
-/**
- * The BluetoothDeviceConfigListener handles system device config change callback and checks
- * whether we need to inform BluetoothManagerService on this change.
- *
- * The information of device config change would not be passed to the BluetoothManagerService
- * when Bluetooth is on and Bluetooth is in one of the following situations:
- *   1. Bluetooth A2DP is connected.
- *   2. Bluetooth Hearing Aid profile is connected.
- */
-public class BluetoothDeviceConfigListener {
-    private static final String TAG = "BluetoothDeviceConfigListener";
-
-    private final BluetoothManagerService mService;
-    private final boolean mLogDebug;
-    private final BluetoothDeviceConfigChangeTracker mConfigChangeTracker;
-
-    BluetoothDeviceConfigListener(BluetoothManagerService service, boolean logDebug) {
-        mService = service;
-        mLogDebug = logDebug;
-        mConfigChangeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BLUETOOTH));
-        DeviceConfig.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_BLUETOOTH,
-                (Runnable r) -> r.run(),
-                mDeviceConfigChangedListener);
-    }
-
-    private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener =
-            new DeviceConfig.OnPropertiesChangedListener() {
-                @Override
-                public void onPropertiesChanged(DeviceConfig.Properties newProperties) {
-                    if (mConfigChangeTracker.shouldRestartWhenPropertiesUpdated(newProperties)) {
-                        Log.d(TAG, "Properties changed, enqueuing restart");
-                        mService.onInitFlagsChanged();
-                    } else {
-                        Log.d(TAG, "All properties unchanged, skipping restart");
-                    }
-                }
-            };
-}
diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
index 8fb2c32..958ebc0 100644
--- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
@@ -32,10 +32,7 @@
 import android.annotation.SuppressLint;
 import android.app.ActivityManager;
 import android.app.BroadcastOptions;
-import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothHearingAid;
-import android.bluetooth.BluetoothLeAudio;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothProtoEnums;
 import android.bluetooth.BluetoothStatusCodes;
@@ -72,13 +69,11 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.sysprop.BluetoothProperties;
-import android.text.TextUtils;
 import android.util.Log;
 import android.util.proto.ProtoOutputStream;
 
@@ -142,8 +137,6 @@
     private static final int ADD_PROXY_DELAY_MS = 100;
     // Delay for retrying enable and disable in msec
     private static final int ENABLE_DISABLE_DELAY_MS = 300;
-    private static final int DELAY_BEFORE_RESTART_DUE_TO_INIT_FLAGS_CHANGED_MS = 300;
-    private static final int DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS = 86400000;
 
     private static final int MESSAGE_ENABLE = 1;
     @VisibleForTesting
@@ -163,7 +156,6 @@
     private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
     private static final int MESSAGE_BIND_PROFILE_SERVICE = 401;
     private static final int MESSAGE_RESTORE_USER_SETTING = 500;
-    private static final int MESSAGE_INIT_FLAGS_CHANGED = 600;
 
     private static final int RESTORE_SETTING_TO_ON = 1;
     private static final int RESTORE_SETTING_TO_OFF = 0;
@@ -202,36 +194,37 @@
 
     // Locks are not provided for mName and mAddress.
     // They are accessed in handler or broadcast receiver, same thread context.
-    private String mAddress;
-    private String mName;
+    private String mAddress = null;
+    private String mName = null;
     private final ContentResolver mContentResolver;
-    private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
-    private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
-    private IBinder mBluetoothBinder;
+    private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks =
+            new RemoteCallbackList<IBluetoothManagerCallback>();
+    private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks =
+            new RemoteCallbackList<IBluetoothStateChangeCallback>();
+    private IBinder mBluetoothBinder = null;
     private final BluetoothServiceBinder mBinder;
 
     private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock();
-    @GuardedBy("mBluetoothLock")
-    private IBluetooth mBluetooth;
 
-    private IBluetoothGatt mBluetoothGatt;
-    private boolean mBinding;
-    private boolean mUnbinding;
+    @GuardedBy("mBluetoothLock")
+    private IBluetooth mBluetooth = null;
+
+    private IBluetoothGatt mBluetoothGatt = null;
+    private boolean mBinding = false;
+    private boolean mUnbinding = false;
     private List<Integer> mSupportedProfileList = new ArrayList<>();
 
     private BluetoothModeChangeHelper mBluetoothModeChangeHelper;
 
     private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
 
-    private BluetoothDeviceConfigListener mBluetoothDeviceConfigListener;
-
     private BluetoothNotificationManager mBluetoothNotificationManager;
 
     private BluetoothSatelliteModeListener mBluetoothSatelliteModeListener;
 
     // used inside handler thread
     private boolean mQuietEnable = false;
-    private boolean mEnable;
+    private boolean mEnable = false;
     private boolean mShutdownInProgress = false;
 
     private static String timeToLog(long timestamp) {
@@ -268,24 +261,25 @@
 
     private final LinkedList<ActiveLog> mActiveLogs = new LinkedList<>();
     private final LinkedList<Long> mCrashTimestamps = new LinkedList<>();
-    private int mCrashes;
+    private int mCrashes = 0;
     private long mLastEnabledTime;
 
     // configuration from external IBinder call which is used to
     // synchronize with broadcast receiver.
-    private boolean mQuietEnableExternal;
-    private boolean mEnableExternal;
+    private boolean mQuietEnableExternal = false;
+    private boolean mEnableExternal = false;
 
     // Map of apps registered to keep BLE scanning on.
     private Map<IBinder, ClientDeathRecipient> mBleApps =
             new ConcurrentHashMap<IBinder, ClientDeathRecipient>();
 
-    private int mState;
-    private final HandlerThread mBluetoothHandlerThread;
-    private final BluetoothHandler mHandler;
-    private int mErrorRecoveryRetryCounter;
+    private int mState = BluetoothAdapter.STATE_OFF;
+    private final HandlerThread mBluetoothHandlerThread =
+            BluetoothServerProxy.getInstance().createHandlerThread("BluetoothManagerService");
+    @VisibleForTesting private final BluetoothHandler mHandler;
+    private int mErrorRecoveryRetryCounter = 0;
 
-    private boolean mIsHearingAidProfileSupported;
+    private final boolean mIsHearingAidProfileSupported;
 
     // Save a ProfileServiceConnections object for each of the bound
     // bluetooth profile services
@@ -322,11 +316,6 @@
         }
     }
 
-    @VisibleForTesting
-    public void onInitFlagsChanged() {
-        // TODO(b/265386284)
-    }
-
     boolean onFactoryReset(AttributionSource source) {
         // Wait for stable state if bluetooth is temporary state.
         int state = getState();
@@ -601,17 +590,6 @@
                         mHandler.sendMessage(msg);
                     }
                 }
-            } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)
-                    || BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(action)
-                    || BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED.equals(action)) {
-                final int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
-                        BluetoothProfile.STATE_CONNECTED);
-                if (mHandler.hasMessages(MESSAGE_INIT_FLAGS_CHANGED)
-                        && state == BluetoothProfile.STATE_DISCONNECTED
-                        && !mBluetoothModeChangeHelper.isMediaProfileConnected()) {
-                    Log.i(TAG, "Device disconnected, reactivating pending flag changes");
-                    onInitFlagsChanged();
-                }
             } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
                 Log.i(TAG, "Device is shutting down.");
                 mShutdownInProgress = true;
@@ -641,32 +619,14 @@
                         "UserManager system service cannot be null");
 
         mBinder = new BluetoothServiceBinder(this, context, mUserManager);
-        mBluetoothHandlerThread = BluetoothServerProxy.getInstance()
-                .createHandlerThread("BluetoothManagerService");
         mBluetoothHandlerThread.start();
-
         mHandler = BluetoothServerProxy.getInstance().newBluetoothHandler(
                 new BluetoothHandler(mBluetoothHandlerThread.getLooper()));
 
-        mCrashes = 0;
-        mBluetooth = null;
-        mBluetoothBinder = null;
-        mBluetoothGatt = null;
-        mBinding = false;
-        mUnbinding = false;
-        mEnable = false;
-        mState = BluetoothAdapter.STATE_OFF;
-        mQuietEnableExternal = false;
-        mEnableExternal = false;
-        mAddress = null;
-        mName = null;
-        mErrorRecoveryRetryCounter = 0;
         mContentResolver = context.getContentResolver();
 
         // Observe BLE scan only mode settings change.
         registerForBleScanModeChange();
-        mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
-        mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
 
         mBluetoothNotificationManager = new BluetoothNotificationManager(mContext);
 
@@ -685,24 +645,10 @@
                             .orElse(isAshaEnabledByDefault);
         }
 
-        String value = SystemProperties.get(
-                "persist.sys.fflag.override.settings_bluetooth_hearing_aid");
-
-        if (!TextUtils.isEmpty(value)) {
-            boolean isHearingAidEnabled = Boolean.parseBoolean(value);
-            Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
-            if (isHearingAidEnabled && !mIsHearingAidProfileSupported) {
-                // Overwrite to enable support by FeatureFlag
-                mIsHearingAidProfileSupported = true;
-            }
-        }
-
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
         filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
         filter.addAction(Intent.ACTION_SETTING_RESTORED);
-        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
         filter.addAction(Intent.ACTION_SHUTDOWN);
         filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
         mContext.registerReceiver(mReceiver, filter);
@@ -1158,35 +1104,6 @@
         return mIsHearingAidProfileSupported;
     }
 
-    private boolean isDeviceProvisioned() {
-        return Settings.Global.getInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED,
-                0) != 0;
-    }
-
-    // Monitor change of BLE scan only mode settings.
-    private void registerForProvisioningStateChange() {
-        ContentObserver contentObserver = new ContentObserver(null) {
-            @Override
-            public void onChange(boolean selfChange) {
-                if (!isDeviceProvisioned()) {
-                    if (DBG) {
-                        Log.d(TAG, "DEVICE_PROVISIONED setting changed, but device is not "
-                                + "provisioned");
-                    }
-                    return;
-                }
-                if (mHandler.hasMessages(MESSAGE_INIT_FLAGS_CHANGED)) {
-                    Log.i(TAG, "Device provisioned, reactivating pending flag changes");
-                    onInitFlagsChanged();
-                }
-            }
-        };
-
-        mContentResolver.registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), false,
-                contentObserver);
-    }
-
     // Monitor change of BLE scan only mode settings.
     private void registerForBleScanModeChange() {
         ContentObserver contentObserver = new ContentObserver(null) {
@@ -1658,8 +1575,6 @@
         if (mBluetoothAirplaneModeListener != null) {
             mBluetoothAirplaneModeListener.start(mBluetoothModeChangeHelper);
         }
-        registerForProvisioningStateChange();
-        mBluetoothDeviceConfigListener = new BluetoothDeviceConfigListener(this, DBG);
         loadApmEnhancementStateFromResource();
     }
 
@@ -1671,9 +1586,7 @@
         mBluetoothModeChangeHelper = bluetoothModeChangeHelper;
     }
 
-    /**
-     * Load whether APM Enhancement feature should be enabled from overlay
-     */
+    /** Load whether APM Enhancement feature should be enabled from overlay */
     @VisibleForTesting
     void loadApmEnhancementStateFromResource() {
         String btPackageName = mBluetoothModeChangeHelper.getBluetoothPackageName();
@@ -1682,20 +1595,21 @@
             return;
         }
         try {
-            Resources resources = mContext.getPackageManager()
-                    .getResourcesForApplication(btPackageName);
-            int apmEnhancement = resources.getIdentifier("config_bluetooth_apm_enhancement_enabled",
-                    "bool", btPackageName);
-            Settings.Global.putInt(mContext.getContentResolver(),
-                    APM_ENHANCEMENT, resources.getBoolean(apmEnhancement) ? 1 : 0);
+            Resources resources =
+                    mContext.getPackageManager().getResourcesForApplication(btPackageName);
+            int apmEnhancement =
+                    resources.getIdentifier(
+                            "config_bluetooth_apm_enhancement_enabled", "bool", btPackageName);
+            Settings.Global.putInt(
+                    mContext.getContentResolver(),
+                    APM_ENHANCEMENT,
+                    resources.getBoolean(apmEnhancement) ? 1 : 0);
         } catch (Exception e) {
             Log.e(TAG, "Unable to set whether APM enhancement should be enabled");
         }
     }
 
-    /**
-     * Called when switching to a different foreground user.
-     */
+    /** Called when switching to a different foreground user. */
     void handleSwitchUser(UserHandle userHandle) {
         if (DBG) {
             Log.d(TAG, "User " + userHandle + " switched");
@@ -1712,8 +1626,8 @@
     }
 
     /**
-     * This class manages the clients connected to a given ProfileService
-     * and maintains the connection with that service.
+     * This class manages the clients connected to a given ProfileService and maintains the
+     * connection with that service.
      */
     private final class ProfileServiceConnections
             implements ServiceConnection, IBinder.DeathRecipient {
@@ -2545,36 +2459,6 @@
                     }
                     break;
                 }
-                case MESSAGE_INIT_FLAGS_CHANGED: {
-                    if (DBG) {
-                        Log.d(TAG, "MESSAGE_INIT_FLAGS_CHANGED");
-                    }
-                    mHandler.removeMessages(MESSAGE_INIT_FLAGS_CHANGED);
-                    if (mBluetoothModeChangeHelper.isMediaProfileConnected()) {
-                        Log.i(TAG, "Delaying MESSAGE_INIT_FLAGS_CHANGED by "
-                                + DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS
-                                + " ms due to existing connections");
-                        mHandler.sendEmptyMessageDelayed(
-                                MESSAGE_INIT_FLAGS_CHANGED,
-                                DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS);
-                        break;
-                    }
-                    if (!isDeviceProvisioned()) {
-                        Log.i(TAG, "Delaying MESSAGE_INIT_FLAGS_CHANGED by "
-                                + DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS
-                                +  "ms because device is not provisioned");
-                        mHandler.sendEmptyMessageDelayed(
-                                MESSAGE_INIT_FLAGS_CHANGED,
-                                DELAY_FOR_RETRY_INIT_FLAG_CHECK_MS);
-                        break;
-                    }
-                    if (mBluetooth != null && isEnabled()) {
-                        Log.i(TAG, "Restarting Bluetooth due to init flag change");
-                        restartForReason(
-                                BluetoothProtoEnums.ENABLE_DISABLE_REASON_INIT_FLAGS_CHANGED);
-                    }
-                    break;
-                }
             }
         }
 
diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothDeviceConfigChangeTrackerTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothDeviceConfigChangeTrackerTest.java
deleted file mode 100644
index 9eaffc1..0000000
--- a/service/tests/src/com/android/server/bluetooth/BluetoothDeviceConfigChangeTrackerTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2022 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.
- */
-
-package com.android.server.bluetooth;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class BluetoothDeviceConfigChangeTrackerTest {
-    @Test
-    public void testNoProperties() {
-        BluetoothDeviceConfigChangeTracker changeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH).build());
-
-        boolean shouldRestart =
-                changeTracker.shouldRestartWhenPropertiesUpdated(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH).build());
-
-        assertThat(shouldRestart).isFalse();
-    }
-
-    @Test
-    public void testNewFlag() {
-        BluetoothDeviceConfigChangeTracker changeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_a", "true")
-                                .build());
-
-        boolean shouldRestart =
-                changeTracker.shouldRestartWhenPropertiesUpdated(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_a", "true")
-                                .setString("INIT_b", "true")
-                                .build());
-
-        assertThat(shouldRestart).isTrue();
-    }
-
-    @Test
-    public void testChangedFlag() {
-        BluetoothDeviceConfigChangeTracker changeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_a", "true")
-                                .build());
-
-        boolean shouldRestart =
-                changeTracker.shouldRestartWhenPropertiesUpdated(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_a", "false")
-                                .build());
-
-        assertThat(shouldRestart).isTrue();
-    }
-
-    @Test
-    public void testUnchangedInitFlag() {
-        BluetoothDeviceConfigChangeTracker changeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_a", "true")
-                                .build());
-
-        boolean shouldRestart =
-                changeTracker.shouldRestartWhenPropertiesUpdated(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_a", "true")
-                                .build());
-
-        assertThat(shouldRestart).isFalse();
-    }
-
-    @Test
-    public void testRepeatedChangeInitFlag() {
-        BluetoothDeviceConfigChangeTracker changeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH).build());
-
-        changeTracker.shouldRestartWhenPropertiesUpdated(
-                new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                        .setString("INIT_a", "true")
-                        .build());
-
-        boolean shouldRestart =
-                changeTracker.shouldRestartWhenPropertiesUpdated(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_a", "true")
-                                .build());
-
-        assertThat(shouldRestart).isFalse();
-    }
-
-    @Test
-    public void testWrongNamespace() {
-        BluetoothDeviceConfigChangeTracker changeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH).build());
-
-        boolean shouldRestart =
-                changeTracker.shouldRestartWhenPropertiesUpdated(
-                        new Properties.Builder("another_namespace")
-                                .setString("INIT_a", "true")
-                                .build());
-
-        assertThat(shouldRestart).isFalse();
-    }
-
-    @Test
-    public void testSkipProperty() {
-        BluetoothDeviceConfigChangeTracker changeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_a", "true")
-                                .setString("INIT_b", "false")
-                                .build());
-
-        boolean shouldRestart =
-                changeTracker.shouldRestartWhenPropertiesUpdated(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("INIT_b", "false")
-                                .build());
-
-        assertThat(shouldRestart).isFalse();
-    }
-
-    @Test
-    public void testNonInitFlag() {
-        BluetoothDeviceConfigChangeTracker changeTracker =
-                new BluetoothDeviceConfigChangeTracker(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("a", "true")
-                                .build());
-
-        boolean shouldRestart =
-                changeTracker.shouldRestartWhenPropertiesUpdated(
-                        new Properties.Builder(DeviceConfig.NAMESPACE_BLUETOOTH)
-                                .setString("a", "false")
-                                .build());
-
-        assertThat(shouldRestart).isFalse();
-    }
-}
diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
index a8eb5a1..c802683 100644
--- a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
+++ b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
@@ -49,17 +49,17 @@
     static int sTimeout = 3000;
     BluetoothManagerService mManagerService;
     Context mContext;
-    @Mock
-    BluetoothServerProxy mBluetoothServerProxy;
-    @Mock
-    BluetoothManagerService.BluetoothHandler mHandler;
+    @Mock BluetoothServerProxy mBluetoothServerProxy;
+    @Mock BluetoothManagerService.BluetoothHandler mHandler;
     HandlerThread mHandlerThread;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(new ContextWrapper(
-                InstrumentationRegistry.getInstrumentation().getTargetContext()));
+        mContext =
+                spy(
+                        new ContextWrapper(
+                                InstrumentationRegistry.getInstrumentation().getTargetContext()));
         mHandlerThread = new HandlerThread("BluetoothManagerServiceTest");
     }
 
@@ -69,8 +69,9 @@
     }
 
     private void createBluetoothManagerService() {
-        doReturn(mock(Intent.class)).when(mContext).registerReceiverForAllUsers(any(), any(),
-                eq(null), eq(null));
+        doReturn(mock(Intent.class))
+                .when(mContext)
+                .registerReceiverForAllUsers(any(), any(), eq(null), eq(null));
         BluetoothServerProxy.setInstanceForTesting(mBluetoothServerProxy);
         // Mock the handler to avoid handle message & to terminate the thread after
         // test
@@ -78,10 +79,12 @@
         doReturn(mHandler).when(mBluetoothServerProxy).newBluetoothHandler(any());
 
         // Mock these functions so security errors won't throw
-        doReturn("name").when(mBluetoothServerProxy).settingsSecureGetString(any(),
-                eq(Settings.Secure.BLUETOOTH_NAME));
-        doReturn("00:11:22:33:44:55").when(mBluetoothServerProxy).settingsSecureGetString(any(),
-                eq(Settings.Secure.BLUETOOTH_ADDRESS));
+        doReturn("name")
+                .when(mBluetoothServerProxy)
+                .settingsSecureGetString(any(), eq(Settings.Secure.BLUETOOTH_NAME));
+        doReturn("00:11:22:33:44:55")
+                .when(mBluetoothServerProxy)
+                .settingsSecureGetString(any(), eq(Settings.Secure.BLUETOOTH_ADDRESS));
         mManagerService = new BluetoothManagerService(mContext);
     }
 
@@ -91,10 +94,12 @@
         // Spy UserManager so we can mimic the case when restriction settings changed
         UserManager userManager = mock(UserManager.class);
         doReturn(userManager).when(mContext).getSystemService(UserManager.class);
-        doReturn(true).when(userManager).hasUserRestrictionForUser(
-                eq(UserManager.DISALLOW_BLUETOOTH), any());
-        doReturn(false).when(userManager).hasUserRestrictionForUser(
-                eq(UserManager.DISALLOW_BLUETOOTH_SHARING), any());
+        doReturn(true)
+                .when(userManager)
+                .hasUserRestrictionForUser(eq(UserManager.DISALLOW_BLUETOOTH), any());
+        doReturn(false)
+                .when(userManager)
+                .hasUserRestrictionForUser(eq(UserManager.DISALLOW_BLUETOOTH_SHARING), any());
         createBluetoothManagerService();
 
         // Check if disable message sent once for system user only
@@ -102,13 +107,13 @@
 
         // test run on user -1, should not turning Bluetooth off
         mManagerService.onUserRestrictionsChanged(UserHandle.CURRENT);
-        verify(mBluetoothServerProxy, timeout(sTimeout).times(0)).handlerSendWhatMessage(mHandler,
-                BluetoothManagerService.MESSAGE_DISABLE);
+        verify(mBluetoothServerProxy, timeout(sTimeout).times(0))
+                .handlerSendWhatMessage(mHandler, BluetoothManagerService.MESSAGE_DISABLE);
 
         // called from SYSTEM user, should try to toggle Bluetooth off
         mManagerService.onUserRestrictionsChanged(UserHandle.SYSTEM);
-        verify(mBluetoothServerProxy, timeout(sTimeout)).handlerSendWhatMessage(mHandler,
-                BluetoothManagerService.MESSAGE_DISABLE);
+        verify(mBluetoothServerProxy, timeout(sTimeout))
+                .handlerSendWhatMessage(mHandler, BluetoothManagerService.MESSAGE_DISABLE);
     }
 
     @Test
@@ -117,14 +122,17 @@
         mManagerService.setBluetoothModeChangeHelper(new BluetoothModeChangeHelper(mContext));
 
         // Change the apm enhancement enabled value to 0
-        Settings.Global.putInt(mContext.getContentResolver(),
-                "apm_enhancement_enabled", 0);
-        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
-                "apm_enhancement_enabled",  0)).isEqualTo(0);
+        Settings.Global.putInt(mContext.getContentResolver(), "apm_enhancement_enabled", 0);
+        assertThat(
+                        Settings.Global.getInt(
+                                mContext.getContentResolver(), "apm_enhancement_enabled", 0))
+                .isEqualTo(0);
 
         // Confirm that apm enhancement enabled value has been updated to 1
         mManagerService.loadApmEnhancementStateFromResource();
-        assertThat(Settings.Global.getInt(mContext.getContentResolver(),
-                "apm_enhancement_enabled",  0)).isEqualTo(1);
+        assertThat(
+                        Settings.Global.getInt(
+                                mContext.getContentResolver(), "apm_enhancement_enabled", 0))
+                .isEqualTo(1);
     }
 }
diff --git a/system/blueberry/tests/sl4a_sl4a/gatt/gatt_connect_test.py b/system/blueberry/tests/sl4a_sl4a/gatt/gatt_connect_test.py
index db91860..2fc1025 100644
--- a/system/blueberry/tests/sl4a_sl4a/gatt/gatt_connect_test.py
+++ b/system/blueberry/tests/sl4a_sl4a/gatt/gatt_connect_test.py
@@ -63,6 +63,10 @@
     default_timeout = 10
     default_discovery_timeout = 3
 
+    ADDR_TYPE_PUBLIC = 0
+    ADDR_TYPE_RPA = 1
+    ADDR_TYPE_NRPA = 2
+
     def setup_class(self):
         super().setup_class()
         self.central = self.dut
@@ -265,7 +269,7 @@
         self.gatt_server_list.append(gatt_server)
         autoconnect = False
         mac_address, adv_callback, scan_callback = (get_mac_address_of_generic_advertisement(
-            self.central, self.peripheral))
+            self.central, self.peripheral, self.ADDR_TYPE_PUBLIC))
         self.adv_instances.append(adv_callback)
         self.central.log.info("Discovered BLE advertisement, connecting GATT with autoConnect={}".format(autoconnect))
         try:
@@ -292,8 +296,9 @@
             return
         autoconnect = True
         self.central.log.info("Connecting GATT with autoConnect={}".format(autoconnect))
-        bluetooth_gatt = self.central.sl4a.gattClientConnectGatt(
-            gatt_callback, mac_address, autoconnect, GattTransport.TRANSPORT_AUTO, False, GattPhyMask.PHY_LE_1M_MASK)
+        bluetooth_gatt = self.central.sl4a.gattClientConnectGatt(gatt_callback, mac_address, autoconnect,
+                                                                 GattTransport.TRANSPORT_LE, False,
+                                                                 GattPhyMask.PHY_LE_1M_MASK)
         self.central.log.info("Waiting for GATt to become connected")
         self.bluetooth_gatt_list.append(bluetooth_gatt)
         expected_event = GattCallbackString.GATT_CONN_CHANGE.format(gatt_callback)
@@ -344,8 +349,11 @@
             self.central, self.peripheral))
         # Make GATT connection 1
         try:
-            bluetooth_gatt_1, gatt_callback_1 = setup_gatt_connection(
-                self.central, mac_address, False, transport=GattTransport.TRANSPORT_AUTO, opportunistic=False)
+            bluetooth_gatt_1, gatt_callback_1 = setup_gatt_connection(self.central,
+                                                                      mac_address,
+                                                                      False,
+                                                                      transport=GattTransport.TRANSPORT_AUTO,
+                                                                      opportunistic=False)
             self.central.sl4a.bleStopBleScan(scan_callback)
             self.adv_instances.append(adv_callback)
             self.bluetooth_gatt_list.append(bluetooth_gatt_1)
@@ -355,8 +363,11 @@
             return
         # Make GATT connection 2
         try:
-            bluetooth_gatt_2, gatt_callback_2 = setup_gatt_connection(
-                self.central, mac_address, False, transport=GattTransport.TRANSPORT_AUTO, opportunistic=True)
+            bluetooth_gatt_2, gatt_callback_2 = setup_gatt_connection(self.central,
+                                                                      mac_address,
+                                                                      False,
+                                                                      transport=GattTransport.TRANSPORT_AUTO,
+                                                                      opportunistic=True)
             self.bluetooth_gatt_list.append(bluetooth_gatt_2)
         except GattTestUtilsError as err:
             logging.error(err)
@@ -378,96 +389,6 @@
         if bluetooth_gatt_2 in self.bluetooth_gatt_list:
             self.bluetooth_gatt_list.remove(bluetooth_gatt_2)
 
-    @test_tracker_info(uuid='1e01838e-c4de-4720-9adf-9e0419378226')
-    def test_gatt_request_min_mtu(self):
-        """Test GATT connection over LE and exercise MTU sizes.
-
-          Test establishing a gatt connection between a GATT server and GATT
-          client. Request an MTU size that matches the correct minimum size.
-
-          Steps:
-            1. Start a generic advertisement.
-            2. Start a generic scanner.
-            3. Find the advertisement and extract the mac address.
-            4. Stop the first scanner.
-            5. Create a GATT connection between the scanner and advertiser.
-            6. From the scanner (client) request MTU size change to the
-            minimum value.
-            7. Find the MTU changed event on the client.
-            8. Disconnect the GATT connection.
-
-          Expected Result:
-            Verify that a connection was established and the MTU value found
-            matches the expected MTU value.
-
-          Returns:
-            Pass if True
-            Fail if False
-
-          TAGS: LE, Advertising, Filtering, Scanning, GATT, MTU
-          Priority: 0
-          """
-        gatt_server_cb = self.peripheral.sl4a.gattServerCreateGattServerCallback()
-        gatt_server = self.peripheral.sl4a.gattServerOpenGattServer(gatt_server_cb)
-        self.gatt_server_list.append(gatt_server)
-        try:
-            bluetooth_gatt, gatt_callback, adv_callback = (orchestrate_gatt_connection(self.central, self.peripheral))
-            self.bluetooth_gatt_list.append(bluetooth_gatt)
-        except GattTestUtilsError as err:
-            logging.error(err)
-            asserts.fail("Failed to connect to GATT, error: {}".format(err))
-            return
-        self.adv_instances.append(adv_callback)
-        expected_mtu = GattMtuSize.MIN
-        self.central.sl4a.gattClientRequestMtu(bluetooth_gatt, expected_mtu)
-        assertThat(self._verify_mtu_changed_on_client_and_server(expected_mtu, gatt_callback, gatt_server_cb)).isTrue()
-        assertThat(self._orchestrate_gatt_disconnection(bluetooth_gatt, gatt_callback)).isTrue()
-
-    @test_tracker_info(uuid='c1fa3a2d-fb47-47db-bdd1-458928cd6a5f')
-    def test_gatt_request_max_mtu(self):
-        """Test GATT connection over LE and exercise MTU sizes.
-
-          Test establishing a gatt connection between a GATT server and GATT
-          client. Request an MTU size that matches the correct maximum size.
-
-          Steps:
-            1. Start a generic advertisement.
-            2. Start a generic scanner.
-            3. Find the advertisement and extract the mac address.
-            4. Stop the first scanner.
-            5. Create a GATT connection between the scanner and advertiser.
-            6. From the scanner (client) request MTU size change to the
-            maximum value.
-            7. Find the MTU changed event on the client.
-            8. Disconnect the GATT connection.
-
-          Expected Result:
-            Verify that a connection was established and the MTU value found
-            matches the expected MTU value.
-
-          Returns:
-            Pass if True
-            Fail if False
-
-          TAGS: LE, Advertising, Filtering, Scanning, GATT, MTU
-          Priority: 0
-          """
-        gatt_server_cb = self.peripheral.sl4a.gattServerCreateGattServerCallback()
-        gatt_server = self.peripheral.sl4a.gattServerOpenGattServer(gatt_server_cb)
-        self.gatt_server_list.append(gatt_server)
-        try:
-            bluetooth_gatt, gatt_callback, adv_callback = (orchestrate_gatt_connection(self.central, self.peripheral))
-            self.bluetooth_gatt_list.append(bluetooth_gatt)
-        except GattTestUtilsError as err:
-            logging.error(err)
-            asserts.fail("Failed to connect to GATT, error: {}".format(err))
-            return
-        self.adv_instances.append(adv_callback)
-        expected_mtu = GattMtuSize.MAX
-        self.central.sl4a.gattClientRequestMtu(bluetooth_gatt, expected_mtu)
-        assertThat(self._verify_mtu_changed_on_client_and_server(expected_mtu, gatt_callback, gatt_server_cb)).isTrue()
-        assertThat(self._orchestrate_gatt_disconnection(bluetooth_gatt, gatt_callback)).isTrue()
-
     @test_tracker_info(uuid='4416d483-dec3-46cb-8038-4d82620f873a')
     def test_gatt_request_out_of_bounds_mtu(self):
         """Test GATT connection over LE and exercise an out of bound MTU size.
@@ -933,7 +854,8 @@
         conn_cen_devices = self.central.sl4a.bluetoothGetConnectedLeDevices(BluetoothProfile.GATT)
         conn_per_devices = self.peripheral.sl4a.bluetoothGetConnectedLeDevices(BluetoothProfile.GATT_SERVER)
         target_name = self.peripheral.sl4a.bluetoothGetLocalName()
-        error_message = ("Connected device {} not found in list of connected " "devices {}")
+        error_message = ("Connected device {} not found in list of connected "
+                         "devices {}")
         if not any(d['name'] == target_name for d in conn_cen_devices):
             logging.error(error_message.format(target_name, conn_cen_devices))
             asserts.fail(error_message.format(target_name, conn_cen_devices))
diff --git a/system/blueberry/tests/sl4a_sl4a/gatt/gatt_connect_with_irk_test.py b/system/blueberry/tests/sl4a_sl4a/gatt/gatt_connect_with_irk_test.py
index eab98fe..eb96468 100644
--- a/system/blueberry/tests/sl4a_sl4a/gatt/gatt_connect_with_irk_test.py
+++ b/system/blueberry/tests/sl4a_sl4a/gatt/gatt_connect_with_irk_test.py
@@ -111,8 +111,8 @@
 
         # Set up SL4A DUT side to scan
         addr_type = ble_address_types["public"]
-        logging.info("Start scanning for PUBLIC_ADDRESS %s with address type %d and IRK %s" % (cert_public_address,
-                                                                                               addr_type, irk))
+        logging.info("Start scanning for PUBLIC_ADDRESS %s with address type %d and IRK %s" %
+                     (cert_public_address, addr_type, irk))
         self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency'])
         self.dut.sl4a.bleSetScanSettingsLegacy(False)
         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a)
@@ -129,8 +129,7 @@
         assertThat(mac_address).isNotNone()
         logging.info("Filter advertisement with address {}".format(mac_address))
 
-        # Stop scanning and try to connect GATT
-        self.dut.sl4a.bleStopBleScan(scan_callback)
+        # Try to connect GATT
         gatt_callback = self.dut.sl4a.gattCreateGattCallback()
         bluetooth_gatt = self.dut.sl4a.gattClientConnectGatt(gatt_callback, mac_address, False,
                                                              GattTransport.TRANSPORT_LE, False, None)
@@ -142,6 +141,7 @@
 
         # Test over
         self.cert.sl4a.bleStopBleAdvertising(advertise_callback)
+        self.dut.sl4a.bleStopBleScan(scan_callback)
 
 
 if __name__ == '__main__':
diff --git a/system/blueberry/tests/sl4a_sl4a/security/irk_rotation_test.py b/system/blueberry/tests/sl4a_sl4a/security/irk_rotation_test.py
index 9061f13..40ab025 100644
--- a/system/blueberry/tests/sl4a_sl4a/security/irk_rotation_test.py
+++ b/system/blueberry/tests/sl4a_sl4a/security/irk_rotation_test.py
@@ -90,7 +90,7 @@
 
         return address, irk
 
-    def test_le_reconnect_after_irk_rotation_cert_privacy_enabled(self):
+    def __test_le_reconnect_after_irk_rotation_cert_privacy_enabled(self):
         self._test_le_reconnect_after_irk_rotation(True)
 
     def test_le_reconnect_after_irk_rotation_cert_privacy_disabled(self):
diff --git a/system/blueberry/utils/bt_test_utils.py b/system/blueberry/utils/bt_test_utils.py
index c1948e7..414be14 100644
--- a/system/blueberry/utils/bt_test_utils.py
+++ b/system/blueberry/utils/bt_test_utils.py
@@ -206,12 +206,13 @@
     wf.close()
 
 
-def get_mac_address_of_generic_advertisement(scan_device, adv_device):
+def get_mac_address_of_generic_advertisement(scan_device, adv_device, adv_addr_type=None):
     """Start generic advertisement and get it's mac address by LE scanning.
 
     Args:
         scan_ad: The Android device to use as the scanner.
         adv_device: The Android device to use as the advertiser.
+        adv_addr_type: The address type for the advertiser (refer to AdvertiseSettings.java)
 
     Returns:
         mac_address: The mac address of the advertisement.
@@ -222,6 +223,10 @@
     adv_device.sl4a.bleSetAdvertiseSettingsAdvertiseMode(ble_advertise_settings_modes['low_latency'])
     adv_device.sl4a.bleSetAdvertiseSettingsIsConnectable(True)
     adv_device.sl4a.bleSetAdvertiseSettingsTxPowerLevel(ble_advertise_settings_tx_powers['high'])
+
+    if adv_addr_type is not None:
+        adv_device.sl4a.bleSetAdvertiseSettingsOwnAddressType(adv_addr_type)
+
     advertise_callback, advertise_data, advertise_settings = (generate_ble_advertise_objects(adv_device.sl4a))
     adv_device.sl4a.bleStartBleAdvertising(advertise_callback, advertise_data, advertise_settings)
     try:
diff --git a/system/bta/Android.bp b/system/bta/Android.bp
index d05fb13..26ca647 100644
--- a/system/bta/Android.bp
+++ b/system/bta/Android.bp
@@ -202,6 +202,7 @@
         ":LegacyStackSdp",
         ":TestCommonLogMsg",
         ":TestCommonMockFunctions",
+        ":TestFakeOsi",
         ":TestMockBtif",
         ":TestMockMainShim",
         ":TestMockStackBtm",
@@ -237,7 +238,6 @@
         "libchrome",
         "libcom.android.sysprop.bluetooth",
         "libgmock",
-        "libosi",
     ],
     data: [
         ":audio_set_configurations_bfbs",
@@ -302,16 +302,31 @@
         "BluetoothGeneratedPackets_h",
     ],
     srcs: [
+        ":LegacyStackSdp",
         ":OsiCompatSources",
         ":TestCommonLogMsg",
         ":TestCommonMainHandler",
         ":TestCommonMockFunctions",
+        ":TestFakeOsi",
         ":TestMockBtaSdp",
         ":TestMockBtif",
         ":TestMockDevice",
         ":TestMockMainShim",
-        ":TestMockOsi",
-        ":TestMockStack",
+        ":TestMockSrvcDis",
+        ":TestMockStackA2dp",
+        ":TestMockStackAcl",
+        ":TestMockStackAvct",
+        ":TestMockStackAvdt",
+        ":TestMockStackAvrc",
+        ":TestMockStackBtm",
+        ":TestMockStackCryptotoolbox",
+        ":TestMockStackGap",
+        ":TestMockStackGatt",
+        ":TestMockStackHid",
+        ":TestMockStackL2cap",
+        ":TestMockStackMetrics",
+        ":TestMockStackPan",
+        ":TestMockStackRfcomm",
         "ar/bta_ar.cc",
         "av/bta_av_aact.cc",
         "av/bta_av_act.cc",
@@ -356,6 +371,7 @@
         "sys/utl.cc",
         "test/bta_api_test.cc",
         "test/bta_av_test.cc",
+        "test/bta_dm_cust_uuid_test.cc",
         "test/bta_dm_test.cc",
         "test/bta_gatt_test.cc",
         "test/bta_hf_client_add_record_test.cc",
diff --git a/system/bta/ag/bta_ag_act.cc b/system/bta/ag/bta_ag_act.cc
index b8a8a24..25a7e53 100644
--- a/system/bta/ag/bta_ag_act.cc
+++ b/system/bta/ag/bta_ag_act.cc
@@ -40,8 +40,11 @@
 #include "osi/include/osi.h"  // UNUSED_ATTR
 #include "stack/include/l2c_api.h"
 #include "stack/include/port_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 /*****************************************************************************
  *  Constants
  ****************************************************************************/
@@ -880,7 +883,8 @@
                              UNUSED_ATTR const tBTA_AG_DATA& data) {
   /* Cancel SDP if it had been started. */
   if (p_scb->p_disc_db) {
-    SDP_CancelServiceSearch(p_scb->p_disc_db);
+    get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(
+        p_scb->p_disc_db);
     bta_ag_free_db(p_scb, tBTA_AG_DATA::kEmpty);
   }
 
diff --git a/system/bta/ag/bta_ag_sdp.cc b/system/bta/ag/bta_ag_sdp.cc
index 956335c..fa8b033 100644
--- a/system/bta/ag/bta_ag_sdp.cc
+++ b/system/bta/ag/bta_ag_sdp.cc
@@ -40,8 +40,10 @@
 #include "stack/include/btm_api.h"
 #include "stack/include/btu.h"  // do_in_main_thread
 #include "stack/include/port_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/bluetooth/uuid.h"
 
+using namespace bluetooth::legacy::stack::sdp;
 using bluetooth::Uuid;
 
 /* Number of protocol elements in protocol element list. */
@@ -155,14 +157,14 @@
   proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
   proto_elem_list[1].num_params = 1;
   proto_elem_list[1].params[0] = scn;
-  result &=
-      SDP_AddProtocolList(sdp_handle, BTA_AG_NUM_PROTO_ELEMS, proto_elem_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(
+      sdp_handle, BTA_AG_NUM_PROTO_ELEMS, proto_elem_list);
 
   /* add service class id list */
   svc_class_id_list[0] = service_uuid;
   svc_class_id_list[1] = UUID_SERVCLASS_GENERIC_AUDIO;
-  result &= SDP_AddServiceClassIdList(sdp_handle, BTA_AG_NUM_SVC_ELEMS,
-                                      svc_class_id_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
+      sdp_handle, BTA_AG_NUM_SVC_ELEMS, svc_class_id_list);
 
   /* add profile descriptor list */
   if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE) {
@@ -176,11 +178,12 @@
     profile_uuid = UUID_SERVCLASS_HEADSET;
     version = HSP_VERSION_1_2;
   }
-  result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
+      sdp_handle, profile_uuid, version);
 
   /* add service name */
   if (p_service_name != nullptr && p_service_name[0] != 0) {
-    result &= SDP_AddAttribute(
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
         sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
         (uint32_t)(strlen(p_service_name) + 1), (uint8_t*)p_service_name);
   }
@@ -188,8 +191,9 @@
   /* add features and network */
   if (service_uuid == UUID_SERVCLASS_AG_HANDSFREE) {
     network = (features & BTA_AG_FEAT_REJECT) ? 1 : 0;
-    result &= SDP_AddAttribute(sdp_handle, ATTR_ID_DATA_STORES_OR_NETWORK,
-                               UINT_DESC_TYPE, 1, &network);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        sdp_handle, ATTR_ID_DATA_STORES_OR_NETWORK, UINT_DESC_TYPE, 1,
+        &network);
 
     // check property for SWB support
     if (hfp_hal_interface::get_swb_supported()) {
@@ -206,13 +210,13 @@
     if (swb_supported) features |= BTA_AG_FEAT_SWB_SUPPORT;
 
     UINT16_TO_BE_FIELD(buf, features);
-    result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES,
-                               UINT_DESC_TYPE, 2, buf);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 2, buf);
   }
 
   /* add browse group list */
-  result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1,
-                                browse_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
+      sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
 
   return result;
 }
@@ -237,7 +241,8 @@
     if (services & 1) {
       /* add sdp record if not already registered */
       if (bta_ag_cb.profile[i].sdp_handle == 0) {
-        bta_ag_cb.profile[i].sdp_handle = SDP_CreateRecord();
+        bta_ag_cb.profile[i].sdp_handle =
+            get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
         bta_ag_cb.profile[i].scn = BTM_AllocateSCN();
         bta_ag_add_record(bta_ag_uuid[i], data.api_register.p_name[i],
                           bta_ag_cb.profile[i].scn, data.api_register.features,
@@ -284,7 +289,8 @@
     if (((services & 1) == 1) && ((others & 1) == 0)) {
       APPL_TRACE_DEBUG("bta_ag_del_records %d", i);
       if (bta_ag_cb.profile[i].sdp_handle != 0) {
-        SDP_DeleteRecord(bta_ag_cb.profile[i].sdp_handle);
+        get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+            bta_ag_cb.profile[i].sdp_handle);
         bta_ag_cb.profile[i].sdp_handle = 0;
       }
       BTM_FreeSCN(bta_ag_cb.profile[i].scn);
@@ -328,13 +334,15 @@
   /* loop through all records we found */
   while (true) {
     /* get next record; if none found, we're done */
-    p_rec = SDP_FindServiceInDb(p_scb->p_disc_db, uuid, p_rec);
+    p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(p_scb->p_disc_db,
+                                                               uuid, p_rec);
     if (p_rec == nullptr) {
       if (uuid == UUID_SERVCLASS_HEADSET_HS) {
         /* Search again in case the peer device uses the old HSP UUID */
         uuid = UUID_SERVCLASS_HEADSET;
         p_scb->peer_version = HSP_VERSION_1_0;
-        p_rec = SDP_FindServiceInDb(p_scb->p_disc_db, uuid, p_rec);
+        p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+            p_scb->p_disc_db, uuid, p_rec);
         if (p_rec == nullptr) {
           break;
         }
@@ -344,7 +352,8 @@
 
     /* get scn from proto desc list if initiator */
     if (p_scb->role == BTA_AG_INT) {
-      if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+      if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+              p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
         p_scb->peer_scn = (uint8_t)pe.params[0];
       } else {
         continue;
@@ -353,7 +362,8 @@
 
     /* get profile version (if failure, version parameter is not updated) */
     uint16_t peer_version = HFP_HSP_VERSION_UNKNOWN;
-    if (!SDP_FindProfileVersionInRec(p_rec, uuid, &peer_version)) {
+    if (!get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+            p_rec, uuid, &peer_version)) {
       APPL_TRACE_WARNING("%s: Get peer_version failed, using default 0x%04x",
                          __func__, p_scb->peer_version);
       peer_version = p_scb->peer_version;
@@ -373,7 +383,8 @@
         }
       }
       /* get features if HFP */
-      p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
+      p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+          p_rec, ATTR_ID_SUPPORTED_FEATURES);
       if (p_attr != nullptr) {
         /* Found attribute. Get value. */
         /* There might be race condition between SDP and BRSF.  */
@@ -415,8 +426,8 @@
       /* No peer version caching for HSP, use discovered one directly */
       p_scb->peer_version = peer_version;
       /* get features if HSP */
-      p_attr =
-          SDP_FindAttributeInRec(p_rec, ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL);
+      p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+          p_rec, ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL);
       if (p_attr != nullptr) {
         /* Remote volume control of HSP */
         if (p_attr->attr_value.v.u8)
@@ -506,9 +517,10 @@
   /* allocate buffer for sdp database */
   p_scb->p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_AG_DISC_BUF_SIZE);
   /* set up service discovery database; attr happens to be attr_list len */
-  if (SDP_InitDiscoveryDb(p_scb->p_disc_db, BTA_AG_DISC_BUF_SIZE, num_uuid,
-                          uuid_list, num_attr, attr_list)) {
-    if (SDP_ServiceSearchAttributeRequest(
+  if (get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+          p_scb->p_disc_db, BTA_AG_DISC_BUF_SIZE, num_uuid, uuid_list, num_attr,
+          attr_list)) {
+    if (get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest(
             p_scb->peer_addr, p_scb->p_disc_db,
             bta_ag_sdp_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1])) {
       return;
diff --git a/system/bta/ar/bta_ar.cc b/system/bta/ar/bta_ar.cc
index ea6108f..c122fc2 100644
--- a/system/bta/ar/bta_ar.cc
+++ b/system/bta/ar/bta_ar.cc
@@ -28,8 +28,11 @@
 #include "bta/sys/bta_sys.h"
 #include "stack/include/avct_api.h"
 #include "stack/include/avrc_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 /* AV control block */
 tBTA_AR_CB bta_ar_cb;
 
@@ -167,7 +170,8 @@
   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
     if (bta_ar_cb.sdp_tg_handle == 0) {
       bta_ar_cb.tg_registered = mask;
-      bta_ar_cb.sdp_tg_handle = SDP_CreateRecord();
+      bta_ar_cb.sdp_tg_handle =
+          get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
                      bta_ar_cb.sdp_tg_handle, browse_supported,
                      profile_version, 0);
@@ -180,7 +184,8 @@
     bta_ar_cb.ct_categories[mask - 1] = categories;
     categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
     if (bta_ar_cb.sdp_ct_handle == 0) {
-      bta_ar_cb.sdp_ct_handle = SDP_CreateRecord();
+      bta_ar_cb.sdp_ct_handle =
+          get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
       AVRC_AddRecord(service_uuid, service_name, provider_name, categories,
                      bta_ar_cb.sdp_ct_handle, browse_supported,
                      profile_version, 0);
@@ -190,8 +195,9 @@
        * Change supported categories on the second one */
       p = temp;
       UINT16_TO_BE_STREAM(p, categories);
-      SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
-                       UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
+      get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+          bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
+          (uint32_t)2, (uint8_t*)temp);
     }
   }
 }
@@ -214,7 +220,8 @@
   if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
     if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) {
       bta_ar_cb.tg_registered = 0;
-      SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle);
+      get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+          bta_ar_cb.sdp_tg_handle);
       bta_ar_cb.sdp_tg_handle = 0;
       bta_sys_remove_uuid(service_uuid);
     }
@@ -224,15 +231,17 @@
       categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
       if (!categories) {
         /* no CT is still registered - cleaup */
-        SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle);
+        get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+            bta_ar_cb.sdp_ct_handle);
         bta_ar_cb.sdp_ct_handle = 0;
         bta_sys_remove_uuid(service_uuid);
       } else {
         /* change supported categories to the remaning one */
         p = temp;
         UINT16_TO_BE_STREAM(p, categories);
-        SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES,
-                         UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
+        get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+            bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
+            (uint32_t)2, (uint8_t*)temp);
       }
     }
   }
diff --git a/system/bta/av/bta_av_act.cc b/system/bta/av/bta_av_act.cc
index 8711e6e..a2fbf43 100644
--- a/system/bta/av/bta_av_act.cc
+++ b/system/bta/av/bta_av_act.cc
@@ -40,8 +40,11 @@
 #include "stack/include/acl_api.h"
 #include "stack/include/bt_hdr.h"
 #include "stack/include/l2c_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 /*****************************************************************************
  *  Constants
  ****************************************************************************/
@@ -169,7 +172,7 @@
  ******************************************************************************/
 static void bta_av_del_sdp_rec(uint32_t* p_sdp_handle) {
   if (*p_sdp_handle != 0) {
-    SDP_DeleteRecord(*p_sdp_handle);
+    get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(*p_sdp_handle);
     *p_sdp_handle = 0;
   }
 }
@@ -1661,12 +1664,13 @@
   tSDP_DISC_REC* p_rec = NULL;
   uint16_t peer_rc_version = 0; /*Assuming Default peer version as 1.3*/
 
-  if ((p_rec = SDP_FindServiceInDb(
+  if ((p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
            p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL)) != NULL) {
-    if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
+    if ((get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
       /* get profile version (if failure, version parameter is not updated) */
-      SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL,
-                                  &peer_rc_version);
+      get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
     }
     if (peer_rc_version != 0)
       DEVICE_IOT_CONFIG_ADDR_SET_HEX_IF_GREATER(
@@ -1675,12 +1679,13 @@
   }
 
   peer_rc_version = 0;
-  if ((p_rec = SDP_FindServiceInDb(
+  if ((p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
            p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) != NULL) {
-    if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
+    if ((get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
       /* get profile version (if failure, version parameter is not updated) */
-      SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL,
-                                  &peer_rc_version);
+      get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
     }
     if (peer_rc_version != 0)
       DEVICE_IOT_CONFIG_ADDR_SET_HEX_IF_GREATER(
@@ -1711,28 +1716,30 @@
   /* loop through all records we found */
   while (true) {
     /* get next record; if none found, we're done */
-    p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, p_rec);
+    p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+        p_cb->p_disc_db, service_uuid, p_rec);
     if (p_rec == NULL) {
       break;
     }
 
-    if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) !=
-        NULL) {
+    if ((get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) != NULL) {
       /* find peer features */
-      if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL,
-                              NULL)) {
+      if (get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+              p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL)) {
         peer_features |= BTA_AV_FEAT_RCCT;
       }
-      if (SDP_FindServiceInDb(p_cb->p_disc_db,
-                              UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) {
+      if (get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+              p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) {
         peer_features |= BTA_AV_FEAT_RCTG;
       }
     }
 
-    if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
+    if ((get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
       /* get profile version (if failure, version parameter is not updated) */
-      SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL,
-                                  &peer_rc_version);
+      get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
       APPL_TRACE_DEBUG("%s: peer_rc_version 0x%x", __func__, peer_rc_version);
 
       if (peer_rc_version >= AVRC_REV_1_3)
@@ -1740,7 +1747,8 @@
 
       if (peer_rc_version >= AVRC_REV_1_4) {
         /* get supported categories */
-        p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
+        p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_SUPPORTED_FEATURES);
         if (p_attr != NULL) {
           categories = p_attr->attr_value.v.u16;
           if (categories & AVRC_SUPF_CT_CAT2)
@@ -1772,29 +1780,30 @@
   APPL_TRACE_DEBUG("%s: service_uuid:x%x", __func__, service_uuid);
 
   /* loop through all records we found */
-  tSDP_DISC_REC* p_rec =
-      SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, NULL);
+  tSDP_DISC_REC* p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+      p_cb->p_disc_db, service_uuid, NULL);
   while (p_rec) {
     APPL_TRACE_DEBUG("%s: found Service record for x%x", __func__,
                      service_uuid);
 
-    if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) !=
-        NULL) {
+    if ((get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) != NULL) {
       /* find peer features */
-      if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL,
-                              NULL)) {
+      if (get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+              p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL)) {
         peer_features |= BTA_AV_FEAT_RCCT;
       }
-      if (SDP_FindServiceInDb(p_cb->p_disc_db,
-                              UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) {
+      if (get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+              p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) {
         peer_features |= BTA_AV_FEAT_RCTG;
       }
     }
 
-    if ((SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
+    if ((get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
       /* get profile version (if failure, version parameter is not updated) */
       uint16_t peer_rc_version = 0;
-      bool val = SDP_FindProfileVersionInRec(
+      bool val = get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
           p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
       APPL_TRACE_DEBUG("%s: peer_rc_version for TG 0x%x, profile_found %d",
                        __func__, peer_rc_version, val);
@@ -1804,7 +1813,8 @@
 
       /* Get supported features */
       tSDP_DISC_ATTR* p_attr =
-          SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
+          get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+              p_rec, ATTR_ID_SUPPORTED_FEATURES);
       if (p_attr != NULL) {
         uint16_t categories = p_attr->attr_value.v.u16;
         /*
@@ -1831,7 +1841,8 @@
       }
     }
     /* get next record; if none found, we're done */
-    p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, p_rec);
+    p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+        p_cb->p_disc_db, service_uuid, p_rec);
   }
   APPL_TRACE_DEBUG("%s: peer_features:x%x", __func__, peer_features);
   return peer_features;
@@ -1852,12 +1863,12 @@
   APPL_TRACE_DEBUG("%s: searching for cover art psm", __func__);
   /* Cover Art L2CAP PSM is only available on a target device */
   tBTA_AV_CB* p_cb = &bta_av_cb;
-  tSDP_DISC_REC* p_rec =
-      SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET,
-          NULL);
+  tSDP_DISC_REC* p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+      p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL);
   while (p_rec) {
     tSDP_DISC_ATTR* p_attr =
-        (SDP_FindAttributeInRec(p_rec, ATTR_ID_ADDITION_PROTO_DESC_LISTS));
+        (get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_ADDITION_PROTO_DESC_LISTS));
     /*
      * If we have the Additional Protocol Description Lists attribute then we
      * specifically want the list that is an L2CAP protocol leading to OBEX.
@@ -1931,8 +1942,8 @@
       }
     }
     /* get next record; if none found, we're done */
-    p_rec = SDP_FindServiceInDb(p_cb->p_disc_db,
-        UUID_SERVCLASS_AV_REM_CTRL_TARGET, p_rec);
+    p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+        p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, p_rec);
   }
   /* L2CAP PSM range is 0x1000-0xFFFF so 0x0000 is safe default invalid */
   APPL_TRACE_DEBUG("%s: could not find a BIP psm", __func__);
@@ -2009,14 +2020,15 @@
 
     /* Change our features if the remote AVRCP version is 1.3 or less */
     tSDP_DISC_REC* p_rec = nullptr;
-    p_rec = SDP_FindServiceInDb(p_cb->p_disc_db,
-                                UUID_SERVCLASS_AV_REMOTE_CONTROL, p_rec);
+    p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+        p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, p_rec);
     if (p_rec != NULL &&
-        SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST) != NULL) {
+        get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_BT_PROFILE_DESC_LIST) != NULL) {
       /* get profile version (if failure, version parameter is not updated) */
       uint16_t peer_rc_version = 0xFFFF;  // Don't change the AVRCP version
-      SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL,
-                                  &peer_rc_version);
+      get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
       if (peer_rc_version <= AVRC_REV_1_3) {
         APPL_TRACE_DEBUG("%s: Using AVRCP 1.3 Capabilities with remote device",
                          __func__);
diff --git a/system/bta/av/bta_av_main.cc b/system/bta/av/bta_av_main.cc
index f646da3..3088c9b 100644
--- a/system/bta/av/bta_av_main.cc
+++ b/system/bta/av/bta_av_main.cc
@@ -24,6 +24,8 @@
 
 #define LOG_TAG "bt_bta_av"
 
+#include <base/logging.h>
+
 #include <cstdint>
 
 #include "bt_target.h"  // Must be first to define build configuration
@@ -41,10 +43,11 @@
 #include "stack/include/acl_api.h"
 #include "stack/include/bt_hdr.h"
 #include "stack/include/btm_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/hci_role.h"
 #include "types/raw_address.h"
 
-#include <base/logging.h>
+using namespace bluetooth::legacy::stack::sdp;
 
 /*****************************************************************************
  * Constants and types
@@ -143,11 +146,13 @@
       return;
     }
     if (bta_av_cb.sdp_a2dp_handle) {
-      SDP_DeleteRecord(bta_av_cb.sdp_a2dp_handle);
+      get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+          bta_av_cb.sdp_a2dp_handle);
       bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
     }
     if (bta_av_cb.sdp_a2dp_snk_handle) {
-      SDP_DeleteRecord(bta_av_cb.sdp_a2dp_snk_handle);
+      get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+          bta_av_cb.sdp_a2dp_snk_handle);
       bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SINK);
     }
     // deregister from AVDT
@@ -607,12 +612,14 @@
       bta_av_cb.sdp_a2dp_snk_handle = 0;
       if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
         /* create the SDP records on the 1st audio channel */
-        bta_av_cb.sdp_a2dp_handle = SDP_CreateRecord();
+        bta_av_cb.sdp_a2dp_handle =
+            get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
         A2DP_AddRecord(UUID_SERVCLASS_AUDIO_SOURCE, p_service_name, NULL,
                        A2DP_SUPF_PLAYER, bta_av_cb.sdp_a2dp_handle);
         bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
       } else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
-        bta_av_cb.sdp_a2dp_snk_handle = SDP_CreateRecord();
+        bta_av_cb.sdp_a2dp_snk_handle =
+            get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
         A2DP_AddRecord(UUID_SERVCLASS_AUDIO_SINK, p_service_name, NULL,
                        A2DP_SUPF_PLAYER, bta_av_cb.sdp_a2dp_snk_handle);
         bta_sys_add_uuid(UUID_SERVCLASS_AUDIO_SINK);
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index c39f948..0a709b9 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -76,6 +76,7 @@
 #include "gap_api.h"
 #endif
 
+using namespace bluetooth::legacy::stack::sdp;
 using bluetooth::Uuid;
 
 namespace {
@@ -1201,7 +1202,8 @@
 
 static void store_avrcp_profile_feature(tSDP_DISC_REC* sdp_rec) {
   tSDP_DISC_ATTR* p_attr =
-      SDP_FindAttributeInRec(sdp_rec, ATTR_ID_SUPPORTED_FEATURES);
+      get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+          sdp_rec, ATTR_ID_SUPPORTED_FEATURES);
   if (p_attr == NULL) {
     return;
   }
@@ -1240,17 +1242,18 @@
   }};
 
   for (const auto& audio_profile : audio_profiles) {
-    tSDP_DISC_REC* sdp_rec = SDP_FindServiceInDb(
+    tSDP_DISC_REC* sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
         bta_dm_search_cb.p_sdp_db, audio_profile.servclass_uuid, NULL);
     if (sdp_rec == NULL) continue;
 
-    if (SDP_FindAttributeInRec(sdp_rec, ATTR_ID_BT_PROFILE_DESC_LIST) == NULL)
+    if (get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            sdp_rec, ATTR_ID_BT_PROFILE_DESC_LIST) == NULL)
       continue;
 
     uint16_t profile_version = 0;
     /* get profile version (if failure, version parameter is not updated) */
-    SDP_FindProfileVersionInRec(sdp_rec, audio_profile.btprofile_uuid,
-                                &profile_version);
+    get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+        sdp_rec, audio_profile.btprofile_uuid, &profile_version);
     if (profile_version != 0) {
       if (btif_config_set_bin(sdp_rec->remote_bd_addr.ToString().c_str(),
                               audio_profile.profile_key,
@@ -1292,16 +1295,17 @@
     do {
       p_sdp_rec = NULL;
       if (bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1)) {
-        if (p_sdp_rec && SDP_FindProtocolListElemInRec(
-                             p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+        if (p_sdp_rec &&
+            get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+                p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
           bta_dm_search_cb.peer_scn = (uint8_t)pe.params[0];
           scn_found = true;
         }
       } else {
         service =
             bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
-        p_sdp_rec =
-            SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
+        p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+            bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
       }
       /* finished with BR/EDR services, now we check the result for GATT based
        * service UUID */
@@ -1312,11 +1316,12 @@
 
         do {
           /* find a service record, report it */
-          p_sdp_rec =
-              SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, 0, p_sdp_rec);
+          p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+              bta_dm_search_cb.p_sdp_db, 0, p_sdp_rec);
           if (p_sdp_rec) {
             Uuid service_uuid;
-            if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
+            if (get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec(
+                    p_sdp_rec, &service_uuid)) {
               gatt_uuids.push_back(service_uuid);
             }
           }
@@ -1370,12 +1375,14 @@
       p_sdp_rec = NULL;
       do {
         /* find a service record, report it */
-        p_sdp_rec =
-            SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
+        p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb_128bit(
+            bta_dm_search_cb.p_sdp_db, p_sdp_rec);
         if (p_sdp_rec) {
           // SDP_FindServiceUUIDInRec_128bit is used only once, refactor?
           Uuid temp_uuid;
-          if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
+          if (get_legacy_stack_sdp_api()
+                  ->record.SDP_FindServiceUUIDInRec_128bit(p_sdp_rec,
+                                                           &temp_uuid)) {
             uuid_list.push_back(temp_uuid);
           }
         }
@@ -1390,8 +1397,8 @@
 
 #if TARGET_FLOSS
     tSDP_DI_GET_RECORD di_record;
-    if (SDP_GetDiRecord(1, &di_record, bta_dm_search_cb.p_sdp_db) ==
-        SDP_SUCCESS) {
+    if (get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(
+            1, &di_record, bta_dm_search_cb.p_sdp_db) == SDP_SUCCESS) {
       tBTA_DM_SEARCH result;
       result.did_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
       result.did_res.vendor_id_src = di_record.rec.vendor_id_source;
@@ -1859,16 +1866,17 @@
       }
 
       LOG_INFO("%s search UUID = %s", __func__, uuid.ToString().c_str());
-      SDP_InitDiscoveryDb(bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1,
-                          &uuid, 0, NULL);
+      get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+          bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL);
 
       memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
       bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
 
       bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
 
-      if (!SDP_ServiceSearchAttributeRequest(bd_addr, bta_dm_search_cb.p_sdp_db,
-                                             &bta_dm_sdp_callback)) {
+      if (!get_legacy_stack_sdp_api()
+               ->service.SDP_ServiceSearchAttributeRequest(
+                   bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) {
         /*
          * If discovery is not successful with this device, then
          * proceed with the next one.
@@ -1877,12 +1885,14 @@
         bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
 
       } else {
+#ifndef TARGET_FLOSS
         if (uuid == Uuid::From16Bit(UUID_PROTOCOL_L2CAP)) {
           if (!is_sdp_pbap_pce_disabled(bd_addr)) {
             LOG_DEBUG("SDP search for PBAP Client ");
             BTA_SdpSearch(bd_addr, Uuid::From16Bit(UUID_SERVCLASS_PBAP_PCE));
           }
         }
+#endif
         bta_dm_search_cb.service_index++;
         return;
       }
@@ -2514,7 +2524,7 @@
 static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event,
                                    tBTM_SP_EVT_DATA* p_data) {
   tBTM_STATUS status = BTM_CMD_STARTED;
-  tBTA_DM_SEC sec_event;
+  tBTA_DM_SEC sec_event = {};
   tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
 
   APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
@@ -2559,10 +2569,19 @@
         break;
       }
 
+      // TODO PleaseFix: This assignment only works with event
+      // BTM_SP_KEY_NOTIF_EVT
       bta_dm_cb.num_val = sec_event.key_notif.passkey =
           p_data->key_notif.passkey;
 
       if (BTM_SP_CFM_REQ_EVT == event) {
+        /* Due to the switch case falling through below to
+           BTM_SP_KEY_NOTIF_EVT,
+           copy these values into key_notif from cfm_req */
+        sec_event.key_notif.bd_addr = p_data->cfm_req.bd_addr;
+        dev_class_copy(sec_event.key_notif.dev_class,
+                       p_data->cfm_req.dev_class);
+        bd_name_copy(sec_event.key_notif.bd_name, p_data->cfm_req.bd_name);
         /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
            call remote name request using values from cfm_req */
         if (p_data->cfm_req.bd_name[0] == 0) {
@@ -2573,23 +2592,20 @@
           bta_dm_cb.rmt_auth_req = sec_event.cfm_req.rmt_auth_req;
           bta_dm_cb.loc_auth_req = sec_event.cfm_req.loc_auth_req;
 
-          BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
-                                p_data->cfm_req.dev_class);
-          if ((BTM_ReadRemoteDeviceName(
-                  p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
-                  BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
-            return BTM_CMD_STARTED;
-          APPL_TRACE_WARNING(
-              " bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
-        } else {
-          /* Due to the switch case falling through below to
-             BTM_SP_KEY_NOTIF_EVT,
-             copy these values into key_notif from cfm_req */
-          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,
-                  (char*)p_data->cfm_req.bd_name, BD_NAME_LEN + 1);
+          dev_class_copy(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
+          {
+            const tBTM_STATUS btm_status = BTM_ReadRemoteDeviceName(
+                p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
+                BT_TRANSPORT_BR_EDR);
+            switch (btm_status) {
+              case BTM_CMD_STARTED:
+                return btm_status;
+              default:
+                // NOTE: This will issue callback on this failure path
+                LOG_WARN("Failed to start Remote Name Request btm_status:%s",
+                         btm_status_text(btm_status).c_str());
+            };
+          }
         }
       }
 
@@ -4781,6 +4797,12 @@
   return ::bta_dm_determine_discovery_transport(bd_addr);
 }
 
+tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data) {
+  return ::bta_dm_sp_cback(event, p_data);
+}
+
+void btm_set_local_io_caps(uint8_t io_caps) { ::btm_local_io_caps = io_caps; }
+
 }  // namespace testing
 }  // namespace legacy
 }  // namespace bluetooth
diff --git a/system/bta/dm/bta_dm_api.cc b/system/bta/dm/bta_dm_api.cc
index b8be10a..91c3c52 100644
--- a/system/bta/dm/bta_dm_api.cc
+++ b/system/bta/dm/bta_dm_api.cc
@@ -35,9 +35,12 @@
 #include "stack/include/btm_api.h"
 #include "stack/include/btm_client_interface.h"
 #include "stack/include/btu.h"  // do_in_main_thread
+#include "stack/include/sdp_api.h"
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 using bluetooth::Uuid;
 
 /*****************************************************************************
@@ -323,8 +326,8 @@
   tBTA_STATUS status = BTA_FAILURE;
 
   if (bta_dm_di_cb.di_num < BTA_DI_NUM_MAX) {
-    if (SDP_SetLocalDiRecord((tSDP_DI_RECORD*)p_device_info, p_handle) ==
-        SDP_SUCCESS) {
+    if (get_legacy_stack_sdp_api()->device_id.SDP_SetLocalDiRecord(
+            (tSDP_DI_RECORD*)p_device_info, p_handle) == SDP_SUCCESS) {
       if (!p_device_info->primary_record) {
         bta_dm_di_cb.di_handle[bta_dm_di_cb.di_num] = *p_handle;
         bta_dm_di_cb.di_num++;
diff --git a/system/bta/gatt/bta_gattc_cache.cc b/system/bta/gatt/bta_gattc_cache.cc
index cd0f64d..4fc81e2 100644
--- a/system/bta/gatt/bta_gattc_cache.cc
+++ b/system/bta/gatt/bta_gattc_cache.cc
@@ -41,9 +41,12 @@
 #include "osi/include/log.h"
 #include "stack/btm/btm_sec.h"
 #include "stack/include/gatt_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 using base::StringPrintf;
 using bluetooth::Uuid;
 using gatt::Characteristic;
@@ -368,14 +371,18 @@
 
   bool no_pending_disc = !p_srvc_cb->pending_discovery.InProgress();
 
-  tSDP_DISC_REC* p_sdp_rec = SDP_FindServiceInDb(cb_data->p_sdp_db, 0, nullptr);
+  tSDP_DISC_REC* p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+      cb_data->p_sdp_db, 0, nullptr);
   while (p_sdp_rec != nullptr) {
     /* find a service record, report it */
     Uuid service_uuid;
-    if (!SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) continue;
+    if (!get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec(
+            p_sdp_rec, &service_uuid))
+      continue;
 
     tSDP_PROTOCOL_ELEM pe;
-    if (!SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_ATT, &pe))
+    if (!get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+            p_sdp_rec, UUID_PROTOCOL_ATT, &pe))
       continue;
 
     uint16_t start_handle = (uint16_t)pe.params[0];
@@ -391,7 +398,8 @@
         !GATT_HANDLE_IS_VALID(end_handle)) {
       LOG(ERROR) << "invalid start_handle=" << loghex(start_handle)
                  << ", end_handle=" << loghex(end_handle);
-      p_sdp_rec = SDP_FindServiceInDb(cb_data->p_sdp_db, 0, p_sdp_rec);
+      p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+          cb_data->p_sdp_db, 0, p_sdp_rec);
       continue;
     }
 
@@ -399,7 +407,8 @@
     p_srvc_cb->pending_discovery.AddService(start_handle, end_handle,
                                             service_uuid, true);
 
-    p_sdp_rec = SDP_FindServiceInDb(cb_data->p_sdp_db, 0, p_sdp_rec);
+    p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+        cb_data->p_sdp_db, 0, p_sdp_rec);
   }
 
   // If discovery is already pending, no need to call
@@ -431,10 +440,10 @@
   attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
 
   Uuid uuid = Uuid::From16Bit(UUID_PROTOCOL_ATT);
-  SDP_InitDiscoveryDb(cb_data->p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1, &uuid,
-                      num_attrs, attr_list);
+  get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+      cb_data->p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1, &uuid, num_attrs, attr_list);
 
-  if (!SDP_ServiceSearchAttributeRequest2(
+  if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest2(
           p_server_cb->server_bda, cb_data->p_sdp_db, &bta_gattc_sdp_callback,
           const_cast<const void*>(static_cast<void*>(cb_data)))) {
     osi_free(cb_data);
diff --git a/system/bta/hd/bta_hd_act.cc b/system/bta/hd/bta_hd_act.cc
index 76fc8ec..4572f1c 100644
--- a/system/bta/hd/bta_hd_act.cc
+++ b/system/bta/hd/bta_hd_act.cc
@@ -38,8 +38,11 @@
 #include "osi/include/log.h"
 #include "stack/include/bt_hdr.h"
 #include "stack/include/hidd_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event,
                          uint32_t data, BT_HDR* pdata);
 
@@ -128,7 +131,7 @@
 
   /* Remove service record */
   if (bta_hd_cb.sdp_handle != 0) {
-    SDP_DeleteRecord(bta_hd_cb.sdp_handle);
+    get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(bta_hd_cb.sdp_handle);
     bta_sys_remove_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
   }
 
@@ -185,11 +188,11 @@
 
   /* Remove old record if for some reason it's already registered */
   if (bta_hd_cb.sdp_handle != 0) {
-    SDP_DeleteRecord(bta_hd_cb.sdp_handle);
+    get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(bta_hd_cb.sdp_handle);
   }
 
   bta_hd_cb.use_report_id = use_report_id;
-  bta_hd_cb.sdp_handle = SDP_CreateRecord();
+  bta_hd_cb.sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
   HID_DevAddRecord(bta_hd_cb.sdp_handle, p_app_data->name,
                    p_app_data->description, p_app_data->provider,
                    p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
@@ -233,7 +236,7 @@
   HID_DevSetIncomingPolicy(FALSE);
 
   if (bta_hd_cb.sdp_handle != 0) {
-    SDP_DeleteRecord(bta_hd_cb.sdp_handle);
+    get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(bta_hd_cb.sdp_handle);
   }
 
   bta_hd_cb.sdp_handle = 0;
diff --git a/system/bta/hf_client/bta_hf_client_main.cc b/system/bta/hf_client/bta_hf_client_main.cc
index cae5798..7ec2165 100644
--- a/system/bta/hf_client/bta_hf_client_main.cc
+++ b/system/bta/hf_client/bta_hf_client_main.cc
@@ -17,6 +17,8 @@
  *
  ******************************************************************************/
 
+#include <base/logging.h>
+
 #include <cstdint>
 #include <cstdio>
 
@@ -26,9 +28,10 @@
 #include "osi/include/osi.h"  // UNUSED_ATTR
 #include "stack/include/bt_hdr.h"
 #include "stack/include/btm_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/raw_address.h"
 
-#include <base/logging.h>
+using namespace bluetooth::legacy::stack::sdp;
 
 static const char* bta_hf_client_evt_str(uint16_t event);
 static const char* bta_hf_client_state_str(uint8_t state);
@@ -385,7 +388,8 @@
 
     /* Cancel SDP if it had been started. */
     if (client_cb->p_disc_db) {
-      (void)SDP_CancelServiceSearch(client_cb->p_disc_db);
+      get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(
+          client_cb->p_disc_db);
       osi_free_and_reset((void**)&client_cb->p_disc_db);
     }
 
diff --git a/system/bta/hf_client/bta_hf_client_rfc.cc b/system/bta/hf_client/bta_hf_client_rfc.cc
index 2999eb9..e9e73e5 100644
--- a/system/bta/hf_client/bta_hf_client_rfc.cc
+++ b/system/bta/hf_client/bta_hf_client_rfc.cc
@@ -35,6 +35,8 @@
 
 #include <base/logging.h>
 
+using namespace bluetooth::legacy::stack::sdp;
+
 /*******************************************************************************
  *
  * Function         bta_hf_client_port_cback
@@ -288,7 +290,8 @@
 
     /* Cancel SDP if it had been started. */
     if (client_cb->p_disc_db) {
-      (void)SDP_CancelServiceSearch(client_cb->p_disc_db);
+      (void)get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(
+          client_cb->p_disc_db);
       osi_free_and_reset((void**)&client_cb->p_disc_db);
     }
   }
diff --git a/system/bta/hf_client/bta_hf_client_sdp.cc b/system/bta/hf_client/bta_hf_client_sdp.cc
index e0ba984..1c84dca 100644
--- a/system/bta/hf_client/bta_hf_client_sdp.cc
+++ b/system/bta/hf_client/bta_hf_client_sdp.cc
@@ -35,10 +35,12 @@
 #include "stack/btm/btm_sec.h"
 #include "stack/include/btm_api.h"
 #include "stack/include/port_api.h"
+#include "stack/include/sdp_api.h"
 #include "stack/include/sdpdefs.h"
 #include "types/bluetooth/uuid.h"
 
 using bluetooth::Uuid;
+using namespace bluetooth::legacy::stack::sdp;
 
 /* Number of protocol elements in protocol element list. */
 #define BTA_HF_CLIENT_NUM_PROTO_ELEMS 2
@@ -84,7 +86,8 @@
  * Description      This function is called by a server application to add
  *                  HFP Client information to an SDP record.  Prior to
  *                  calling this function the application must call
- *                  SDP_CreateRecord() to create an SDP record.
+ *                  get_legacy_stack_sdp_api()->handle.SDP_CreateRecord() to
+ *                  create an SDP record.
  *
  * Returns          true if function execution succeeded,
  *                  false if function execution failed.
@@ -113,24 +116,25 @@
   proto_elem_list[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
   proto_elem_list[1].num_params = 1;
   proto_elem_list[1].params[0] = scn;
-  result &= SDP_AddProtocolList(sdp_handle, BTA_HF_CLIENT_NUM_PROTO_ELEMS,
-                                proto_elem_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(
+      sdp_handle, BTA_HF_CLIENT_NUM_PROTO_ELEMS, proto_elem_list);
 
   /* add service class id list */
   svc_class_id_list[0] = UUID_SERVCLASS_HF_HANDSFREE;
   svc_class_id_list[1] = UUID_SERVCLASS_GENERIC_AUDIO;
-  result &= SDP_AddServiceClassIdList(sdp_handle, BTA_HF_CLIENT_NUM_SVC_ELEMS,
-                                      svc_class_id_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
+      sdp_handle, BTA_HF_CLIENT_NUM_SVC_ELEMS, svc_class_id_list);
 
   /* add profile descriptor list */
   profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
   version = get_default_hfp_version();
 
-  result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
+      sdp_handle, profile_uuid, version);
 
   /* add service name */
   if (p_service_name != NULL && p_service_name[0] != 0) {
-    result &= SDP_AddAttribute(
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
         sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
         (uint32_t)(strlen(p_service_name) + 1), (uint8_t*)p_service_name);
   }
@@ -153,12 +157,12 @@
   if (features & BTA_HF_CLIENT_FEAT_CODEC) sdp_features |= 0x0020;
 
   UINT16_TO_BE_FIELD(buf, sdp_features);
-  result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES,
-                             UINT_DESC_TYPE, 2, buf);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+      sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, 2, buf);
 
   /* add browse group list */
-  result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1,
-                                browse_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
+      sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
 
   return result;
 }
@@ -177,7 +181,8 @@
                                  const char* p_service_name) {
   /* add sdp record if not already registered */
   if (client_cb_arr->sdp_handle == 0) {
-    client_cb_arr->sdp_handle = SDP_CreateRecord();
+    client_cb_arr->sdp_handle =
+        get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
     client_cb_arr->scn = BTM_AllocateSCN();
     bta_hf_client_add_record(p_service_name, client_cb_arr->scn,
                              client_cb_arr->features,
@@ -201,7 +206,7 @@
   APPL_TRACE_DEBUG("%s", __func__);
 
   if (client_cb->sdp_handle != 0) {
-    SDP_DeleteRecord(client_cb->sdp_handle);
+    get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(client_cb->sdp_handle);
     client_cb->sdp_handle = 0;
     BTM_FreeSCN(client_cb->scn);
     bta_sys_remove_uuid(UUID_SERVCLASS_HF_HANDSFREE);
@@ -229,15 +234,16 @@
   /* loop through all records we found */
   while (true) {
     /* get next record; if none found, we're done */
-    p_rec = SDP_FindServiceInDb(client_cb->p_disc_db,
-                                UUID_SERVCLASS_AG_HANDSFREE, p_rec);
+    p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+        client_cb->p_disc_db, UUID_SERVCLASS_AG_HANDSFREE, p_rec);
     if (p_rec == NULL) {
       break;
     }
 
     /* get scn from proto desc list if initiator */
     if (client_cb->role == BTA_HF_CLIENT_INT) {
-      if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+      if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+              p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
         client_cb->peer_scn = (uint8_t)pe.params[0];
       } else {
         continue;
@@ -245,11 +251,12 @@
     }
 
     /* get profile version (if failure, version parameter is not updated) */
-    SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_HF_HANDSFREE,
-                                &client_cb->peer_version);
+    get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+        p_rec, UUID_SERVCLASS_HF_HANDSFREE, &client_cb->peer_version);
 
     /* get features */
-    p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
+    p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+        p_rec, ATTR_ID_SUPPORTED_FEATURES);
     if (p_attr != NULL) {
       /* Found attribute. Get value. */
       /* There might be race condition between SDP and BRSF.  */
@@ -264,7 +271,8 @@
         }
 
         /* get network for ability to reject calls */
-        p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_NETWORK);
+        p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_NETWORK);
         if (p_attr != NULL) {
           if (p_attr->attr_value.v.u16 == 0x01) {
             client_cb->peer_features |= BTA_HF_CLIENT_PEER_REJECT;
@@ -323,14 +331,16 @@
   client_cb->p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
 
   /* set up service discovery database; attr happens to be attr_list len */
-  db_inited = SDP_InitDiscoveryDb(client_cb->p_disc_db, BT_DEFAULT_BUFFER_SIZE,
-                                  num_uuid, uuid_list, num_attr, attr_list);
+  db_inited = get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+      client_cb->p_disc_db, BT_DEFAULT_BUFFER_SIZE, num_uuid, uuid_list,
+      num_attr, attr_list);
 
   if (db_inited) {
     /*Service discovery not initiated */
-    db_inited = SDP_ServiceSearchAttributeRequest2(
-        client_cb->peer_addr, client_cb->p_disc_db, bta_hf_client_sdp_cback,
-        (void*)client_cb);
+    db_inited =
+        get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest2(
+            client_cb->peer_addr, client_cb->p_disc_db, bta_hf_client_sdp_cback,
+            (void*)client_cb);
   }
 
   if (!db_inited) {
diff --git a/system/bta/hh/bta_hh_act.cc b/system/bta/hh/bta_hh_act.cc
index c237534..6c3abd0 100644
--- a/system/bta/hh/bta_hh_act.cc
+++ b/system/bta/hh/bta_hh_act.cc
@@ -42,9 +42,12 @@
 #include "stack/include/bt_hdr.h"
 #include "stack/include/hiddefs.h"
 #include "stack/include/hidh_api.h"
+#include "stack/include/sdp_api.h"
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 /*****************************************************************************
  *  Constants
  ****************************************************************************/
@@ -274,9 +277,11 @@
   if (((result == SDP_SUCCESS) || (result == SDP_NO_RECS_MATCH)) &&
       (p_cb != NULL)) {
     if (result == SDP_SUCCESS &&
-        SDP_GetNumDiRecords(bta_hh_cb.p_disc_db) != 0) {
+        get_legacy_stack_sdp_api()->device_id.SDP_GetNumDiRecords(
+            bta_hh_cb.p_disc_db) != 0) {
       /* always update information with primary DI record */
-      if (SDP_GetDiRecord(1, &di_rec, bta_hh_cb.p_disc_db) == SDP_SUCCESS) {
+      if (get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(
+              1, &di_rec, bta_hh_cb.p_disc_db) == SDP_SUCCESS) {
         bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product,
                               di_rec.rec.version, 0, 0);
       }
@@ -324,9 +329,9 @@
         (tSDP_DISCOVERY_DB*)osi_malloc(p_bta_hh_cfg->sdp_db_size);
 
     /* Do DI discovery first */
-    if (SDP_DiDiscover(p_data->api_conn.bd_addr, bta_hh_cb.p_disc_db,
-                       p_bta_hh_cfg->sdp_db_size,
-                       bta_hh_di_sdp_cback) == SDP_SUCCESS) {
+    if (get_legacy_stack_sdp_api()->device_id.SDP_DiDiscover(
+            p_data->api_conn.bd_addr, bta_hh_cb.p_disc_db,
+            p_bta_hh_cfg->sdp_db_size, bta_hh_di_sdp_cback) == SDP_SUCCESS) {
       /* SDP search started successfully
        * Connection will be triggered at the end of successful SDP search
        */
@@ -942,8 +947,6 @@
   }
   /* otherwise report CLOSE/VC_UNPLUG event */
   else {
-    /* finaliza device driver */
-    bta_hh_co_close(p_cb->hid_handle, p_cb->app_id);
     /* inform role manager */
     bta_sys_conn_close(BTA_ID_HH, p_cb->app_id, p_cb->addr);
     /* update total conn number */
diff --git a/system/bta/hh/bta_hh_le.cc b/system/bta/hh/bta_hh_le.cc
index 6324f1f..11ea930 100644
--- a/system/bta/hh/bta_hh_le.cc
+++ b/system/bta/hh/bta_hh_le.cc
@@ -1679,8 +1679,7 @@
 
   /* deregister all notification */
   bta_hh_le_deregister_input_notif(p_cb);
-  /* finaliza device driver */
-  bta_hh_co_close(p_cb->hid_handle, p_cb->app_id);
+
   /* update total conn number */
   bta_hh_cb.cnt_num--;
 
diff --git a/system/bta/hh/bta_hh_utils.cc b/system/bta/hh/bta_hh_utils.cc
index ce4858c..ace7484 100644
--- a/system/bta/hh/bta_hh_utils.cc
+++ b/system/bta/hh/bta_hh_utils.cc
@@ -28,8 +28,11 @@
 #include "osi/include/osi.h"
 #include "stack/include/acl_api.h"
 #include "stack/include/btm_client_interface.h"
+#include "stack/include/sdp_api.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 /* if SSR max latency is not defined by remote device, set the default value
    as half of the link supervision timeout */
 #define BTA_HH_GET_DEF_SSR_MAX_LAT(x) ((x) >> 1)
@@ -308,7 +311,8 @@
 
   if (bta_hh_cb.p_disc_db) {
     /* Cancel SDP if it had been started. */
-    (void)SDP_CancelServiceSearch (bta_hh_cb.p_disc_db);
+    (void)get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(
+        bta_hh_cb.p_disc_db);
     osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
   }
 
diff --git a/system/bta/include/bta_hh_co.h b/system/bta/include/bta_hh_co.h
index 2814aaa..2ddaf68 100644
--- a/system/bta/include/bta_hh_co.h
+++ b/system/bta/include/bta_hh_co.h
@@ -70,18 +70,6 @@
 
 /*******************************************************************************
  *
- * Function         bta_hh_co_close
- *
- * Description      This callout function is executed by HH when connection is
- *                  closed, and device specific finalizatio nmay be needed.
- *
- * Returns          void.
- *
- ******************************************************************************/
-void bta_hh_co_close(uint8_t dev_handle, uint8_t app_id);
-
-/*******************************************************************************
- *
  * Function         bta_hh_co_set_rpt_rsp
  *
  * Description      This callout function is executed by HH when Set Report
diff --git a/system/bta/jv/bta_jv_act.cc b/system/bta/jv/bta_jv_act.cc
index d8d593d..532e980 100644
--- a/system/bta/jv/bta_jv_act.cc
+++ b/system/bta/jv/bta_jv_act.cc
@@ -45,6 +45,7 @@
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
 using bluetooth::Uuid;
 
 tBTA_JV_CB bta_jv_cb;
@@ -811,11 +812,12 @@
       tSDP_DISC_REC* p_sdp_rec = NULL;
       tSDP_PROTOCOL_ELEM pe;
       VLOG(2) << __func__ << ": bta_jv_cb.uuid=" << bta_jv_cb.uuid;
-      p_sdp_rec = SDP_FindServiceUUIDInDb(p_bta_jv_cfg->p_sdp_db,
-                                          bta_jv_cb.uuid, p_sdp_rec);
+      p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceUUIDInDb(
+          p_bta_jv_cfg->p_sdp_db, bta_jv_cb.uuid, p_sdp_rec);
       VLOG(2) << __func__ << ": p_sdp_rec=" << p_sdp_rec;
       if (p_sdp_rec &&
-          SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+          get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+              p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
         dcomp.scn = (uint8_t)pe.params[0];
         status = BTA_JV_SUCCESS;
       }
@@ -848,8 +850,9 @@
 
   /* init the database/set up the filter */
   VLOG(2) << __func__ << ": call SDP_InitDiscoveryDb, num_uuid=" << num_uuid;
-  SDP_InitDiscoveryDb(p_bta_jv_cfg->p_sdp_db, p_bta_jv_cfg->sdp_db_size,
-                      num_uuid, uuid_list, 0, NULL);
+  get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+      p_bta_jv_cfg->p_sdp_db, p_bta_jv_cfg->sdp_db_size, num_uuid, uuid_list, 0,
+      NULL);
 
   /* tell SDP to keep the raw data */
   p_bta_jv_cfg->p_sdp_db->raw_data = p_bta_jv_cfg->p_sdp_raw_data;
@@ -863,9 +866,9 @@
   uint32_t* rfcomm_slot_id_copy = (uint32_t*)osi_malloc(sizeof(uint32_t));
   *rfcomm_slot_id_copy = rfcomm_slot_id;
 
-  if (!SDP_ServiceSearchAttributeRequest2(bd_addr, p_bta_jv_cfg->p_sdp_db,
-                                          bta_jv_start_discovery_cback,
-                                          (void*)rfcomm_slot_id_copy)) {
+  if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest2(
+          bd_addr, p_bta_jv_cfg->p_sdp_db, bta_jv_start_discovery_cback,
+          (void*)rfcomm_slot_id_copy)) {
     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) {
@@ -895,7 +898,7 @@
 void bta_jv_delete_record(uint32_t handle) {
   if (handle) {
     /* this is a record created by btif layer*/
-    SDP_DeleteRecord(handle);
+    get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle);
   }
 }
 
diff --git a/system/bta/sdp/bta_sdp_act.cc b/system/bta/sdp/bta_sdp_act.cc
index f0f2291..4ac2d4c 100644
--- a/system/bta/sdp/bta_sdp_act.cc
+++ b/system/bta/sdp/bta_sdp_act.cc
@@ -35,6 +35,8 @@
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 static void bta_create_mns_sdp_record(bluetooth_sdp_record* record,
                                       tSDP_DISC_REC* p_rec) {
   tSDP_DISC_ATTR* p_attr;
@@ -48,28 +50,32 @@
   record->mns.hdr.profile_version = 0;
   record->mns.supported_features = 0x0000001F;  // default value if not found
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
   if (p_attr != NULL) {
     record->mns.supported_features = p_attr->attr_value.v.u32;
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SERVICE_NAME);
   if (p_attr != NULL) {
     record->mns.hdr.service_name_length =
         SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
     record->mns.hdr.service_name = (char*)p_attr->attr_value.v.array;
   }
 
-  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE,
-                                  &pversion)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion)) {
     record->mns.hdr.profile_version = pversion;
   }
 
-  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+          p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
     record->mns.hdr.rfcomm_channel_number = pe.params[0];
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_GOEP_L2CAP_PSM);
   if (p_attr != NULL) {
     record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16;
   }
@@ -91,38 +97,44 @@
   record->mas.supported_features = 0x0000001F;
   record->mas.supported_message_types = 0;
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_MAS_INSTANCE_ID);
   if (p_attr != NULL) {
     record->mas.mas_instance_id = p_attr->attr_value.v.u8;
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_MSG_TYPE);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SUPPORTED_MSG_TYPE);
   if (p_attr != NULL) {
     record->mas.supported_message_types = p_attr->attr_value.v.u8;
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES);
   if (p_attr != NULL) {
     record->mas.supported_features = p_attr->attr_value.v.u32;
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SERVICE_NAME);
   if (p_attr != NULL) {
     record->mas.hdr.service_name_length =
         SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
     record->mas.hdr.service_name = (char*)p_attr->attr_value.v.array;
   }
 
-  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE,
-                                  &pversion)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion)) {
     record->mas.hdr.profile_version = pversion;
   }
 
-  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+          p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
     record->mas.hdr.rfcomm_channel_number = pe.params[0];
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_GOEP_L2CAP_PSM);
   if (p_attr != NULL) {
     record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16;
   }
@@ -143,32 +155,37 @@
   record->pse.supported_features = 0x00000003;
   record->pse.supported_repositories = 0;
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_REPOSITORIES);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SUPPORTED_REPOSITORIES);
   if (p_attr != NULL) {
     record->pse.supported_repositories = p_attr->attr_value.v.u8;
   }
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES);
   if (p_attr != NULL) {
     record->pse.supported_features = p_attr->attr_value.v.u32;
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SERVICE_NAME);
   if (p_attr != NULL) {
     record->pse.hdr.service_name_length =
         SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
     record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array;
   }
 
-  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS,
-                                  &pversion)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_PHONE_ACCESS, &pversion)) {
     record->pse.hdr.profile_version = pversion;
   }
 
-  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+          p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
     record->pse.hdr.rfcomm_channel_number = pe.params[0];
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_GOEP_L2CAP_PSM);
   if (p_attr != NULL) {
     record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16;
   }
@@ -188,27 +205,31 @@
   record->ops.hdr.profile_version = 0;
   record->ops.supported_formats_list_len = 0;
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SERVICE_NAME);
   if (p_attr != NULL) {
     record->ops.hdr.service_name_length =
         SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
     record->ops.hdr.service_name = (char*)p_attr->attr_value.v.array;
   }
 
-  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH,
-                                  &pversion)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH, &pversion)) {
     record->ops.hdr.profile_version = pversion;
   }
 
-  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+          p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
     record->ops.hdr.rfcomm_channel_number = pe.params[0];
   }
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_GOEP_L2CAP_PSM);
   if (p_attr != NULL) {
     record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16;
   }
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST);
   if (p_attr != NULL) {
     /* Safety check - each entry should itself be a sequence */
     if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) {
@@ -272,18 +293,21 @@
   record->sap.hdr.l2cap_psm = -1;
   record->sap.hdr.profile_version = 0;
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SERVICE_NAME);
   if (p_attr != NULL) {
     record->sap.hdr.service_name_length =
         SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
     record->sap.hdr.service_name = (char*)p_attr->attr_value.v.array;
   }
 
-  if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_SAP, &pversion)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+          p_rec, UUID_SERVCLASS_SAP, &pversion)) {
     record->sap.hdr.profile_version = pversion;
   }
 
-  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+          p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
     record->sap.hdr.rfcomm_channel_number = pe.params[0];
   }
 }
@@ -302,40 +326,43 @@
   record->dip.hdr.l2cap_psm = -1;
   record->dip.hdr.profile_version = 0;
 
-  p_attr =
-      SDP_FindAttributeInRec(p_rec, ATTR_ID_SPECIFICATION_ID);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SPECIFICATION_ID);
   if (p_attr != nullptr)
     record->dip.spec_id = p_attr->attr_value.v.u16;
   else
     APPL_TRACE_ERROR("%s() ATTR_ID_SPECIFICATION_ID not found", __func__);
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_VENDOR_ID);
   if (p_attr != nullptr)
     record->dip.vendor = p_attr->attr_value.v.u16;
   else
     APPL_TRACE_ERROR("%s() ATTR_ID_VENDOR_ID not found", __func__);
 
-  p_attr =
-      SDP_FindAttributeInRec(p_rec, ATTR_ID_VENDOR_ID_SOURCE);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_VENDOR_ID_SOURCE);
   if (p_attr != nullptr)
     record->dip.vendor_id_source = p_attr->attr_value.v.u16;
   else
     APPL_TRACE_ERROR("%s() ATTR_ID_VENDOR_ID_SOURCE not found", __func__);
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_ID);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_PRODUCT_ID);
   if (p_attr != nullptr)
     record->dip.product = p_attr->attr_value.v.u16;
   else
     APPL_TRACE_ERROR("%s() ATTR_ID_PRODUCT_ID not found", __func__);
 
-  p_attr =
-      SDP_FindAttributeInRec(p_rec, ATTR_ID_PRODUCT_VERSION);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_PRODUCT_VERSION);
   if (p_attr != nullptr)
     record->dip.version = p_attr->attr_value.v.u16;
   else
     APPL_TRACE_ERROR("%s() ATTR_ID_PRODUCT_VERSION not found", __func__);
 
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PRIMARY_RECORD);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_PRIMARY_RECORD);
   if (p_attr != nullptr)
     record->dip.primary_record = !(!p_attr->attr_value.v.u8);
   else
@@ -355,7 +382,8 @@
   record->hdr.profile_version = -1;
 
   /* Try to extract a service name */
-  p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
+  p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+      p_rec, ATTR_ID_SERVICE_NAME);
   if (p_attr != NULL) {
     record->pse.hdr.service_name_length =
         SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
@@ -363,7 +391,8 @@
   }
 
   /* Try to extract an RFCOMM channel */
-  if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
+  if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+          p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
     record->pse.hdr.rfcomm_channel_number = pe.params[0];
   }
   record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
@@ -390,7 +419,8 @@
   if (result == SDP_SUCCESS || result == SDP_DB_FULL) {
     tSDP_DISC_REC* p_rec = NULL;
     do {
-      p_rec = SDP_FindServiceUUIDInDb(p_bta_sdp_cfg->p_sdp_db, uuid, p_rec);
+      p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceUUIDInDb(
+          p_bta_sdp_cfg->p_sdp_db, uuid, p_rec);
       /* generate the matching record data pointer */
       if (!p_rec) {
         APPL_TRACE_DEBUG("%s() - UUID not found", __func__);
@@ -419,8 +449,8 @@
         if (p_rec != NULL) {
           uint16_t peer_pce_version = 0;
 
-          SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS,
-                                      &peer_pce_version);
+          get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+              p_rec, UUID_SERVCLASS_PHONE_ACCESS, &peer_pce_version);
           if (peer_pce_version != 0) {
             btif_storage_set_pce_profile_version(p_rec->remote_bd_addr,
                                                  peer_pce_version);
@@ -513,14 +543,14 @@
   /* initialize the search for the uuid */
   APPL_TRACE_DEBUG("%s init discovery with UUID: %s", __func__,
                    uuid.ToString().c_str());
-  SDP_InitDiscoveryDb(p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1,
-                      &uuid, 0, NULL);
+  get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+      p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1, &uuid, 0, NULL);
 
   Uuid* bta_sdp_search_uuid = (Uuid*)osi_malloc(sizeof(Uuid));
   *bta_sdp_search_uuid = uuid;
-  if (!SDP_ServiceSearchAttributeRequest2(bd_addr, p_bta_sdp_cfg->p_sdp_db,
-                                          bta_sdp_search_cback,
-                                          (void*)bta_sdp_search_uuid)) {
+  if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest2(
+          bd_addr, p_bta_sdp_cfg->p_sdp_db, bta_sdp_search_cback,
+          (void*)bta_sdp_search_uuid)) {
     bta_sdp_cb.sdp_active = false;
 
     /* failed to start SDP. report the failure right away */
diff --git a/system/bta/test/bta_dm_cust_uuid_test.cc b/system/bta/test/bta_dm_cust_uuid_test.cc
index a0cdcb5..bae16a7 100644
--- a/system/bta/test/bta_dm_cust_uuid_test.cc
+++ b/system/bta/test/bta_dm_cust_uuid_test.cc
@@ -18,15 +18,22 @@
 
 #include <gtest/gtest.h>
 
+#include <memory>
+
 #include "bta/dm/bta_dm_int.h"
 #include "stack/include/bt_hdr.h"
+#include "test/fake/fake_osi.h"
 #include "types/bluetooth/uuid.h"
 
 using bluetooth::Uuid;
 
 class BtaCustUuid : public testing::Test {
  protected:
-  void SetUp() override { bta_dm_cb = {}; }
+  void SetUp() override {
+    fake_osi_ = std::make_unique<test::fake::FakeOsi>();
+    bta_dm_cb = {};
+  }
+  std::unique_ptr<test::fake::FakeOsi> fake_osi_;
 };
 
 namespace {
diff --git a/system/bta/test/bta_dm_test.cc b/system/bta/test/bta_dm_test.cc
index c46a297..a0f8345 100644
--- a/system/bta/test/bta_dm_test.cc
+++ b/system/bta/test/bta_dm_test.cc
@@ -16,9 +16,13 @@
 
 #include <base/functional/bind.h>
 #include <base/location.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 #include <chrono>
+#include <iostream>
+#include <memory>
+#include <string>
 
 #include "bta/dm/bta_dm_int.h"
 #include "bta/hf_client/bta_hf_client_int.h"
@@ -28,15 +32,20 @@
 #include "btif/include/stack_manager.h"
 #include "common/message_loop_thread.h"
 #include "osi/include/compat.h"
+#include "stack/include/bt_dev_class.h"
+#include "stack/include/bt_name.h"
 #include "stack/include/btm_status.h"
 #include "test/common/main_handler.h"
 #include "test/common/mock_functions.h"
+#include "test/fake/fake_osi.h"
 #include "test/mock/mock_osi_alarm.h"
 #include "test/mock/mock_osi_allocator.h"
 #include "test/mock/mock_stack_acl.h"
+#include "test/mock/mock_stack_btm_inq.h"
 #include "test/mock/mock_stack_btm_sec.h"
 
 using namespace std::chrono_literals;
+using ::testing::ElementsAre;
 
 extern struct btm_client_interface_t btm_client_interface;
 
@@ -48,12 +57,9 @@
 constexpr uint8_t kUnusedTimer = BTA_ID_MAX;
 const RawAddress kRawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
 const RawAddress kRawAddress2({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
-constexpr char kRemoteName[] = "TheRemoteName";
+const DEV_CLASS kDeviceClass = {0x11, 0x22, 0x33};
 
-const char* test_flags[] = {
-    "INIT_logging_debug_enabled_for_all=true",
-    nullptr,
-};
+constexpr char kRemoteName[] = "TheRemoteName";
 
 bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) { return true; }
 void bta_dm_search_sm_disable() { bta_sys_deregister(BTA_ID_DM_SEARCH); }
@@ -63,33 +69,11 @@
 
 }  // namespace
 
-struct alarm_t {
-  alarm_t(const char* name){};
-  int any_value;
-};
-
 class BtaDmTest : public testing::Test {
  protected:
   void SetUp() override {
     reset_mock_function_count_map();
-    bluetooth::common::InitFlags::Load(test_flags);
-    test::mock::osi_alarm::alarm_new.body = [](const char* name) -> alarm_t* {
-      return new alarm_t(name);
-    };
-    test::mock::osi_alarm::alarm_free.body = [](alarm_t* alarm) {
-      delete alarm;
-    };
-    test::mock::osi_allocator::osi_malloc.body = [](size_t size) {
-      return malloc(size);
-    };
-    test::mock::osi_allocator::osi_calloc.body = [](size_t size) {
-      return calloc(1UL, size);
-    };
-    test::mock::osi_allocator::osi_free.body = [](void* ptr) { free(ptr); };
-    test::mock::osi_allocator::osi_free_and_reset.body = [](void** ptr) {
-      free(*ptr);
-      *ptr = nullptr;
-    };
+    fake_osi_ = std::make_unique<test::fake::FakeOsi>();
 
     main_thread_start_up();
     post_on_bt_main([]() { LOG_INFO("Main thread started up"); });
@@ -108,14 +92,9 @@
     bta_dm_deinit_cb();
     post_on_bt_main([]() { LOG_INFO("Main thread shutting down"); });
     main_thread_shut_down();
-
-    test::mock::osi_alarm::alarm_new = {};
-    test::mock::osi_alarm::alarm_free = {};
-    test::mock::osi_allocator::osi_malloc = {};
-    test::mock::osi_allocator::osi_calloc = {};
-    test::mock::osi_allocator::osi_free = {};
-    test::mock::osi_allocator::osi_free_and_reset = {};
   }
+
+  std::unique_ptr<test::fake::FakeOsi> fake_osi_;
 };
 
 TEST_F(BtaDmTest, nop) {
@@ -250,6 +229,10 @@
 tBT_TRANSPORT bta_dm_determine_discovery_transport(
     const RawAddress& remote_bd_addr);
 
+void btm_set_local_io_caps(uint8_t io_caps);
+
+tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data);
+
 }  // namespace testing
 }  // namespace legacy
 }  // namespace bluetooth
@@ -540,3 +523,178 @@
   bta_dm_remote_name_cmpl(&msg);
   ASSERT_EQ(1, get_func_call_count("BTM_InqDbRead"));
 }
+
+TEST_F(BtaDmTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithName) {
+  constexpr uint32_t kNumVal = 1234;
+  static bool callback_sent = false;
+  static tBTA_DM_SP_CFM_REQ cfm_req{};
+  bta_dm_enable([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
+    callback_sent = true;
+    cfm_req = p_data->cfm_req;
+  });
+
+  bluetooth::legacy::testing::btm_set_local_io_caps(0xff);
+
+  tBTM_SP_EVT_DATA data = {
+      .cfm_req =
+          {
+              // tBTM_SP_CFM_REQ
+              .bd_addr = kRawAddress,
+              .dev_class = {},
+              .bd_name = {},
+              .num_val = kNumVal,
+              .just_works = false,
+              .loc_auth_req = BTM_AUTH_SP_YES,
+              .rmt_auth_req = BTM_AUTH_SP_YES,
+              .loc_io_caps = BTM_IO_CAP_NONE,
+              .rmt_io_caps = BTM_IO_CAP_NONE,
+          },
+  };
+  dev_class_copy(data.cfm_req.dev_class, kDeviceClass);
+  bd_name_copy(data.cfm_req.bd_name, kRemoteName);
+
+  ASSERT_EQ(btm_status_text(BTM_CMD_STARTED),
+            btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback(
+                BTM_SP_CFM_REQ_EVT, &data)));
+  ASSERT_EQ(kNumVal, bta_dm_cb.num_val);
+  ASSERT_TRUE(callback_sent);
+
+  ASSERT_EQ(kRawAddress, cfm_req.bd_addr);
+  ASSERT_THAT(cfm_req.dev_class,
+              ElementsAre(kDeviceClass[0], kDeviceClass[1], kDeviceClass[2]));
+  ASSERT_STREQ(kRemoteName, reinterpret_cast<const char*>(cfm_req.bd_name));
+  ASSERT_EQ(kNumVal, cfm_req.num_val);
+  ASSERT_EQ(false, cfm_req.just_works);
+  ASSERT_EQ(BTM_AUTH_SP_YES, cfm_req.loc_auth_req);
+  ASSERT_EQ(BTM_AUTH_SP_YES, cfm_req.rmt_auth_req);
+  ASSERT_EQ(BTM_IO_CAP_NONE, cfm_req.loc_io_caps);
+  ASSERT_EQ(BTM_IO_CAP_NONE, cfm_req.rmt_io_caps);
+}
+
+TEST_F(BtaDmTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithoutName_RNRSuccess) {
+  constexpr uint32_t kNumVal = 1234;
+  static bool callback_sent = false;
+  test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName.body =
+      [](const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb,
+         tBT_TRANSPORT transport) { return BTM_CMD_STARTED; };
+
+  static tBTA_DM_SP_CFM_REQ cfm_req{};
+  bta_dm_enable([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
+    callback_sent = true;
+    cfm_req = p_data->cfm_req;
+  });
+
+  bluetooth::legacy::testing::btm_set_local_io_caps(0xff);
+
+  tBTM_SP_EVT_DATA data = {
+      .cfm_req =
+          {
+              // tBTM_SP_CFM_REQ
+              .bd_addr = kRawAddress,
+              .dev_class = {},
+              .bd_name = {0},
+              .num_val = kNumVal,
+              .just_works = false,
+              .loc_auth_req = BTM_AUTH_SP_YES,
+              .rmt_auth_req = BTM_AUTH_SP_YES,
+              .loc_io_caps = BTM_IO_CAP_NONE,
+              .rmt_io_caps = BTM_IO_CAP_NONE,
+          },
+  };
+  dev_class_copy(data.cfm_req.dev_class, kDeviceClass);
+
+  ASSERT_EQ(btm_status_text(BTM_CMD_STARTED),
+            btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback(
+                BTM_SP_CFM_REQ_EVT, &data)));
+  ASSERT_EQ(kNumVal, bta_dm_cb.num_val);
+  ASSERT_FALSE(callback_sent);
+
+  test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName = {};
+}
+
+TEST_F(BtaDmTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithoutName_RNRFail) {
+  constexpr uint32_t kNumVal = 1234;
+  static bool callback_sent = false;
+  test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName.body =
+      [](const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb,
+         tBT_TRANSPORT transport) { return BTM_SUCCESS; };
+
+  static tBTA_DM_SP_CFM_REQ cfm_req{};
+  bta_dm_enable([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
+    callback_sent = true;
+    cfm_req = p_data->cfm_req;
+  });
+
+  bluetooth::legacy::testing::btm_set_local_io_caps(0xff);
+
+  tBTM_SP_EVT_DATA data = {
+      .cfm_req =
+          {
+              // tBTM_SP_CFM_REQ
+              .bd_addr = kRawAddress,
+              .dev_class = {},
+              .bd_name = {0},
+              .num_val = kNumVal,
+              .just_works = false,
+              .loc_auth_req = BTM_AUTH_SP_YES,
+              .rmt_auth_req = BTM_AUTH_SP_YES,
+              .loc_io_caps = BTM_IO_CAP_NONE,
+              .rmt_io_caps = BTM_IO_CAP_NONE,
+          },
+  };
+  dev_class_copy(data.cfm_req.dev_class, kDeviceClass);
+
+  ASSERT_EQ(btm_status_text(BTM_CMD_STARTED),
+            btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback(
+                BTM_SP_CFM_REQ_EVT, &data)));
+  ASSERT_EQ(kNumVal, bta_dm_cb.num_val);
+  ASSERT_TRUE(callback_sent);
+
+  ASSERT_EQ(kRawAddress, cfm_req.bd_addr);
+  ASSERT_THAT(cfm_req.dev_class,
+              ElementsAre(kDeviceClass[0], kDeviceClass[1], kDeviceClass[2]));
+  ASSERT_EQ(kNumVal, cfm_req.num_val);
+  ASSERT_EQ(false, cfm_req.just_works);
+  ASSERT_EQ(BTM_AUTH_SP_YES, cfm_req.loc_auth_req);
+  ASSERT_EQ(BTM_AUTH_SP_YES, cfm_req.rmt_auth_req);
+  ASSERT_EQ(BTM_IO_CAP_NONE, cfm_req.loc_io_caps);
+  ASSERT_EQ(BTM_IO_CAP_NONE, cfm_req.rmt_io_caps);
+
+  test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName = {};
+}
+
+TEST_F(BtaDmTest, bta_dm_sp_cback__BTM_SP_KEY_NOTIF_EVT) {
+  constexpr uint32_t kPassKey = 1234;
+  static bool callback_sent = false;
+  static tBTA_DM_SP_KEY_NOTIF key_notif{};
+  bta_dm_enable([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
+    callback_sent = true;
+    key_notif = p_data->key_notif;
+  });
+  bluetooth::legacy::testing::btm_set_local_io_caps(0xff);
+
+  tBTM_SP_EVT_DATA data = {
+      .key_notif =
+          {
+              // tBTM_SP_KEY_NOTIF
+              .bd_addr = kRawAddress,
+              .dev_class = {},
+              .bd_name = {},
+              .passkey = kPassKey,
+          },
+  };
+  dev_class_copy(data.key_notif.dev_class, kDeviceClass);
+  bd_name_copy(data.key_notif.bd_name, kRemoteName);
+
+  ASSERT_EQ(btm_status_text(BTM_CMD_STARTED),
+            btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback(
+                BTM_SP_KEY_NOTIF_EVT, &data)));
+  ASSERT_EQ(kPassKey, bta_dm_cb.num_val);
+  ASSERT_TRUE(callback_sent);
+
+  ASSERT_EQ(kRawAddress, key_notif.bd_addr);
+  ASSERT_THAT(key_notif.dev_class,
+              ElementsAre(kDeviceClass[0], kDeviceClass[1], kDeviceClass[2]));
+  ASSERT_STREQ(kRemoteName, reinterpret_cast<const char*>(key_notif.bd_name));
+  ASSERT_EQ(kPassKey, key_notif.passkey);
+}
diff --git a/system/bta/test/bta_hf_client_add_record_test.cc b/system/bta/test/bta_hf_client_add_record_test.cc
index 851315f..5af4668 100644
--- a/system/bta/test/bta_hf_client_add_record_test.cc
+++ b/system/bta/test/bta_hf_client_add_record_test.cc
@@ -19,19 +19,18 @@
 #include <base/logging.h>
 #include <gtest/gtest.h>
 
+#include <memory>
+
 #include "bta/hf_client/bta_hf_client_int.h"
 #include "bta/include/bta_hf_client_api.h"
-#include "types/bluetooth/uuid.h"
-
-static uint16_t gVersion;
+#include "test/fake/fake_osi.h"
 
 class BtaHfClientAddRecordTest : public ::testing::Test {
  protected:
-  void SetUp() override {
-    gVersion = 0;
-  }
+  void SetUp() override { fake_osi_ = std::make_unique<test::fake::FakeOsi>(); }
 
   void TearDown() override {}
+  std::unique_ptr<test::fake::FakeOsi> fake_osi_;
 };
 
 TEST_F(BtaHfClientAddRecordTest, test_hf_client_add_record) {
diff --git a/system/bta/test/bta_hf_client_test.cc b/system/bta/test/bta_hf_client_test.cc
index ca45b44..d92585c 100644
--- a/system/bta/test/bta_hf_client_test.cc
+++ b/system/bta/test/bta_hf_client_test.cc
@@ -18,9 +18,12 @@
 
 #include <gtest/gtest.h>
 
+#include <memory>
+
 #include "bta/hf_client/bta_hf_client_int.h"
 #include "bta/include/bta_hf_client_api.h"
 #include "common/message_loop_thread.h"
+#include "test/fake/fake_osi.h"
 #include "types/raw_address.h"
 
 namespace base {
@@ -37,10 +40,12 @@
 class BtaHfClientTest : public testing::Test {
  protected:
   void SetUp() override {
+    fake_osi_ = std::make_unique<test::fake::FakeOsi>();
     // Reset the memory block, this is the state on which the allocate handle
     // would start operating
     bta_hf_client_cb_arr_init();
   }
+  std::unique_ptr<test::fake::FakeOsi> fake_osi_;
 };
 
 // Test that when we can allocate a device on the block and then check
diff --git a/system/bta/test/bta_sdp_test.cc b/system/bta/test/bta_sdp_test.cc
index abc10db..d9ad012 100644
--- a/system/bta/test/bta_sdp_test.cc
+++ b/system/bta/test/bta_sdp_test.cc
@@ -18,39 +18,24 @@
 #include <gtest/gtest.h>
 #include <stdarg.h>
 
+#include <memory>
 #include <string>
 
 #include "bta/dm/bta_dm_int.h"
 #include "test/common/main_handler.h"
-#include "test/mock/mock_osi_alarm.h"
-#include "test/mock/mock_osi_allocator.h"
+#include "test/fake/fake_osi.h"
 #include "test/mock/mock_stack_gatt_api.h"
 
 void BTA_dm_on_hw_on();
 void BTA_dm_on_hw_off();
 
-struct alarm_t {
-  alarm_t(const char* name){};
-  int any_value;
-};
-
 class BtaSdpTest : public testing::Test {
  protected:
   void SetUp() override {
-    test::mock::osi_allocator::osi_calloc.body = [](size_t size) -> void* {
-      return calloc(1, size);
-    };
-    test::mock::osi_allocator::osi_free.body = [](void* ptr) { free(ptr); };
-    test::mock::osi_alarm::alarm_new.body = [](const char* name) -> alarm_t* {
-      return new alarm_t(name);
-    };
-    test::mock::osi_alarm::alarm_free.body = [](alarm_t* alarm) {
-      delete alarm;
-    };
+    fake_osi_ = std::make_unique<test::fake::FakeOsi>();
     test::mock::stack_gatt_api::GATT_Register.body =
         [](const bluetooth::Uuid& p_app_uuid128, const std::string name,
            tGATT_CBACK* p_cb_info, bool eatt_support) { return 5; };
-
     main_thread_start_up();
     sync_main_handler();
 
@@ -64,11 +49,8 @@
     main_thread_shut_down();
 
     test::mock::stack_gatt_api::GATT_Register = {};
-    test::mock::osi_allocator::osi_calloc = {};
-    test::mock::osi_allocator::osi_free = {};
-    test::mock::osi_alarm::alarm_new = {};
-    test::mock::osi_alarm::alarm_free = {};
   }
+  std::unique_ptr<test::fake::FakeOsi> fake_osi_;
 };
 
 class BtaSdpRegisteredTest : public BtaSdpTest {
diff --git a/system/bta/vc/vc.cc b/system/bta/vc/vc.cc
index 637f56e..0ace9f3 100644
--- a/system/bta/vc/vc.cc
+++ b/system/bta/vc/vc.cc
@@ -798,28 +798,6 @@
     StartQueueOperation();
   }
 
-  void ProceedVolumeOperation(int operation_id) {
-    auto op = find_if(ongoing_operations_.begin(), ongoing_operations_.end(),
-                      [operation_id](auto& operation) {
-                        return operation.operation_id_ == operation_id;
-                      });
-
-    DLOG(INFO) << __func__ << " operation_id: " << operation_id;
-
-    if (op == ongoing_operations_.end()) {
-      LOG(ERROR) << __func__
-                 << " Could not find operation_id: " << operation_id;
-      return;
-    }
-
-    DLOG(INFO) << __func__ << " procedure continued for operation_id: "
-               << op->operation_id_;
-
-    alarm_set_on_mloop(op->operation_timeout_, 3000, operation_callback,
-                       INT_TO_PTR(op->operation_id_));
-    devices_control_point_helper(op->devices_, op->opcode_, &(op->arguments_));
-  }
-
   void PrepareVolumeControlOperation(std::vector<RawAddress> devices,
                                      int group_id, bool is_autonomous,
                                      uint8_t opcode,
diff --git a/system/btif/co/bta_hh_co.cc b/system/btif/co/bta_hh_co.cc
index 1fb0668..1918f2f 100644
--- a/system/btif/co/bta_hh_co.cc
+++ b/system/btif/co/bta_hh_co.cc
@@ -48,10 +48,15 @@
 #define BTA_HH_CACHE_REPORT_VERSION 1
 #define THREAD_NORMAL_PRIORITY 0
 #define BT_HH_THREAD "bt_hh_thread"
+#define BTA_HH_UHID_POLL_PERIOD_MS 50
+/* Max number of polling interrupt allowed */
+#define BTA_HH_UHID_INTERRUPT_COUNT_MAX 100
 
 static const bthh_report_type_t map_rtype_uhid_hh[] = {
     BTHH_FEATURE_REPORT, BTHH_OUTPUT_REPORT, BTHH_INPUT_REPORT};
 
+static void* btif_hh_poll_event_thread(void* arg);
+
 void uhid_set_non_blocking(int fd) {
   int opts = fcntl(fd, F_GETFL);
   if (opts < 0)
@@ -265,6 +270,36 @@
   return thread_id;
 }
 
+/* Internal function to close the UHID driver*/
+static void uhid_fd_close(btif_hh_device_t* p_dev) {
+  if (p_dev->fd >= 0) {
+    struct uhid_event ev = {};
+    ev.type = UHID_DESTROY;
+    uhid_write(p_dev->fd, &ev);
+    LOG_DEBUG("Closing fd=%d, addr:%s", p_dev->fd,
+              ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr));
+    close(p_dev->fd);
+    p_dev->fd = -1;
+  }
+}
+
+/* Internal function to open the UHID driver*/
+static bool uhid_fd_open(btif_hh_device_t* p_dev) {
+  if (p_dev->fd < 0) {
+    p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC);
+    if (p_dev->fd < 0) {
+      LOG_ERROR("Failed to open uhid, err:%s", strerror(errno));
+      return false;
+    }
+  }
+
+  if (p_dev->hh_keep_polling == 0) {
+    p_dev->hh_keep_polling = 1;
+    p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, p_dev);
+  }
+  return true;
+}
+
 /*******************************************************************************
  *
  * Function btif_hh_poll_event_thread
@@ -277,20 +312,23 @@
 static void* btif_hh_poll_event_thread(void* arg) {
   btif_hh_device_t* p_dev = (btif_hh_device_t*)arg;
   struct pollfd pfds[1];
+  pid_t pid = gettid();
 
   // This thread is created by bt_main_thread with RT priority. Lower the thread
   // priority here since the tasks in this thread is not timing critical.
   struct sched_param sched_params;
   sched_params.sched_priority = THREAD_NORMAL_PRIORITY;
-  if (sched_setscheduler(gettid(), SCHED_OTHER, &sched_params)) {
-    APPL_TRACE_ERROR("%s: Failed to set thread priority to normal", __func__);
+  if (sched_setscheduler(pid, SCHED_OTHER, &sched_params)) {
+    LOG_ERROR("Failed to set thread priority to normal: %s", strerror(errno));
     p_dev->hh_poll_thread_id = -1;
+    p_dev->hh_keep_polling = 0;
+    uhid_fd_close(p_dev);
     return 0;
   }
-  p_dev->pid = gettid();
+
   pthread_setname_np(pthread_self(), BT_HH_THREAD);
   LOG_DEBUG("Host hid polling thread created name:%s pid:%d fd:%d",
-            BT_HH_THREAD, p_dev->pid, p_dev->fd);
+            BT_HH_THREAD, pid, p_dev->fd);
 
   pfds[0].fd = p_dev->fd;
   pfds[0].events = POLLIN;
@@ -300,40 +338,37 @@
 
   while (p_dev->hh_keep_polling) {
     int ret;
-    OSI_NO_INTR(ret = poll(pfds, 1, 50));
+    int counter = 0;
+
+    do {
+      if (counter++ > BTA_HH_UHID_INTERRUPT_COUNT_MAX) {
+        LOG_ERROR("Polling interrupted");
+        break;
+      }
+      ret = poll(pfds, 1, BTA_HH_UHID_POLL_PERIOD_MS);
+    } while (ret == -1 && errno == EINTR);
+
     if (ret < 0) {
-      APPL_TRACE_ERROR("%s: Cannot poll for fds: %s\n", __func__,
-                       strerror(errno));
+      LOG_ERROR("Cannot poll for fds: %s\n", strerror(errno));
       break;
     }
     if (pfds[0].revents & POLLIN) {
       APPL_TRACE_DEBUG("%s: POLLIN", __func__);
       ret = uhid_read_event(p_dev);
-      if (ret != 0) break;
+      if (ret != 0) {
+        LOG_ERROR("Unhandled UHID event");
+        break;
+      }
     }
   }
 
+  /* Todo: Disconnect if loop exited due to a failure */
+  LOG_INFO("Polling thread stopped for device %s",
+           ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr));
   p_dev->hh_poll_thread_id = -1;
-  p_dev->pid = -1;
-  return 0;
-}
-
-static inline void btif_hh_close_poll_thread(btif_hh_device_t* p_dev) {
-  APPL_TRACE_DEBUG("%s", __func__);
   p_dev->hh_keep_polling = 0;
-  if (p_dev->hh_poll_thread_id > 0)
-    pthread_join(p_dev->hh_poll_thread_id, NULL);
-
-  return;
-}
-
-void bta_hh_co_destroy(int fd) {
-  struct uhid_event ev;
-  memset(&ev, 0, sizeof(ev));
-  ev.type = UHID_DESTROY;
-  uhid_write(fd, &ev);
-  APPL_TRACE_DEBUG("%s: Closing fd=%d", __func__, fd);
-  close(fd);
+  uhid_fd_close(p_dev);
+  return 0;
 }
 
 int bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len) {
@@ -352,22 +387,6 @@
   return uhid_write(fd, &ev);
 }
 
-static bool uhid_fd_open(btif_hh_device_t* p_dev) {
-  if (p_dev->fd < 0) {
-    p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC);
-    if (p_dev->fd < 0) {
-      LOG_ERROR("Failed to open uhid, err:%s", strerror(errno));
-      return false;
-    }
-  }
-
-  if (p_dev->hh_keep_polling == 0) {
-    p_dev->hh_keep_polling = 1;
-    p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, p_dev);
-  }
-  return true;
-}
-
 /*******************************************************************************
  *
  * Function      bta_hh_co_open
@@ -455,43 +474,31 @@
  * Description   When connection is closed, this call-out function is executed
  *               by HH to do platform specific finalization.
  *
- * Parameters    dev_handle  - device handle
- *                  app_id      - application id
+ * Parameters    p_dev  - device
  *
- * Returns          void.
+ * Returns       void.
  ******************************************************************************/
-void bta_hh_co_close(uint8_t dev_handle, uint8_t app_id) {
-  uint32_t i;
-  btif_hh_device_t* p_dev = NULL;
+void bta_hh_co_close(btif_hh_device_t* p_dev) {
+  LOG_INFO("Closing device handle=%d, status=%d, address=%s", p_dev->dev_handle,
+           p_dev->dev_status, ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr));
 
-  APPL_TRACE_WARNING("%s: dev_handle = %d, app_id = %d", __func__, dev_handle,
-                     app_id);
-  if (dev_handle == BTA_HH_INVALID_HANDLE) {
-    APPL_TRACE_WARNING("%s: Oops, dev_handle (%d) is invalid...", __func__,
-                       dev_handle);
-    return;
-  }
-
-  for (i = 0; i < BTIF_HH_MAX_HID; i++) {
-    p_dev = &btif_hh_cb.devices[i];
-    fixed_queue_flush(p_dev->get_rpt_id_queue, osi_free);
-    fixed_queue_free(p_dev->get_rpt_id_queue, NULL);
-    p_dev->get_rpt_id_queue = NULL;
+  /* Clear the queues */
+  fixed_queue_flush(p_dev->get_rpt_id_queue, osi_free);
+  fixed_queue_free(p_dev->get_rpt_id_queue, NULL);
+  p_dev->get_rpt_id_queue = NULL;
 #if ENABLE_UHID_SET_REPORT
-    fixed_queue_flush(p_dev->set_rpt_id_queue, osi_free);
-    fixed_queue_free(p_dev->set_rpt_id_queue, nullptr);
-    p_dev->set_rpt_id_queue = nullptr;
+  fixed_queue_flush(p_dev->set_rpt_id_queue, osi_free);
+  fixed_queue_free(p_dev->set_rpt_id_queue, nullptr);
+  p_dev->set_rpt_id_queue = nullptr;
 #endif  // ENABLE_UHID_SET_REPORT
-    if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN &&
-        p_dev->dev_handle == dev_handle) {
-      APPL_TRACE_WARNING(
-          "%s: Found an existing device with the same handle "
-          "dev_status = %d, dev_handle =%d",
-          __func__, p_dev->dev_status, p_dev->dev_handle);
-      btif_hh_close_poll_thread(p_dev);
-      break;
-    }
+
+  /* Stop the polling thread */
+  p_dev->hh_keep_polling = 0;
+  if (p_dev->hh_poll_thread_id > 0) {
+    pthread_join(p_dev->hh_poll_thread_id, NULL);
   }
+  p_dev->hh_poll_thread_id = -1;
+  /* UHID file descriptor is closed by the polling thread */
 }
 
 /*******************************************************************************
diff --git a/system/btif/include/btif_hh.h b/system/btif/include/btif_hh.h
index c59fc66..d524687 100644
--- a/system/btif/include/btif_hh.h
+++ b/system/btif/include/btif_hh.h
@@ -97,7 +97,6 @@
   int fd;
   bool ready_for_data;
   pthread_t hh_poll_thread_id;
-  pid_t pid{-1};
   uint8_t hh_keep_polling;
   alarm_t* vup_timer;
   fixed_queue_t* get_rpt_id_queue;
diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc
index 451cee1..add6c4c 100644
--- a/system/btif/src/btif_hh.cc
+++ b/system/btif/src/btif_hh.cc
@@ -119,7 +119,7 @@
  ******************************************************************************/
 bool check_cod(const RawAddress* remote_bdaddr, uint32_t cod);
 bool check_cod_hid(const RawAddress* remote_bdaddr);
-void bta_hh_co_destroy(int fd);
+void bta_hh_co_close(btif_hh_device_t* p_dev);
 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,
@@ -528,13 +528,7 @@
     BTIF_TRACE_WARNING("%s: device_num = 0", __func__);
   }
 
-  p_dev->hh_keep_polling = 0;
-  p_dev->hh_poll_thread_id = -1;
-  BTIF_TRACE_DEBUG("%s: uhid fd = %d", __func__, p_dev->fd);
-  if (p_dev->fd >= 0) {
-    bta_hh_co_destroy(p_dev->fd);
-    p_dev->fd = -1;
-  }
+  bta_hh_co_close(p_dev);
 }
 
 bool btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest,
@@ -889,10 +883,7 @@
         btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED;
         p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED;
 
-        if (p_dev->fd >= 0) {
-          bta_hh_co_destroy(p_dev->fd);
-          p_dev->fd = -1;
-        }
+        bta_hh_co_close(p_dev);
         HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr),
                   p_dev->dev_status);
       } else {
@@ -1821,12 +1812,7 @@
     p_dev = &btif_hh_cb.devices[i];
     if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) {
       BTIF_TRACE_DEBUG("%s: Closing uhid fd = %d", __func__, p_dev->fd);
-      if (p_dev->fd >= 0) {
-        bta_hh_co_destroy(p_dev->fd);
-        p_dev->fd = -1;
-      }
-      p_dev->hh_keep_polling = 0;
-      p_dev->hh_poll_thread_id = -1;
+      bta_hh_co_close(p_dev);
     }
   }
 }
diff --git a/system/device/include/esco_parameters.h b/system/device/include/esco_parameters.h
index ed206b8..9096796 100644
--- a/system/device/include/esco_parameters.h
+++ b/system/device/include/esco_parameters.h
@@ -137,6 +137,8 @@
   esco_packet_types_t packet_types; /* Packet Types */
   esco_retransmission_effort_t
       retransmission_effort; /* 0x00-0x02, 0xFF don't care */
+  esco_coding_format_t
+      coding_format; /* Extra field to store codec when TX/RX is transparent */
 } enh_esco_params_t;
 
 // Get the enhanced eSCO configuration parameters for the provided |codec|
diff --git a/system/device/src/esco_parameters.cc b/system/device/src/esco_parameters.cc
index 48607e6..861dfd9 100644
--- a/system/device/src/esco_parameters.cc
+++ b/system/device/src/esco_parameters.cc
@@ -57,6 +57,7 @@
         .packet_types = (ESCO_PKT_TYPES_MASK_HV1 | ESCO_PKT_TYPES_MASK_HV2 |
                          ESCO_PKT_TYPES_MASK_HV3),
         .retransmission_effort = ESCO_RETRANSMISSION_OFF,
+        .coding_format = ESCO_CODING_FORMAT_CVSD,
     },
     // CVSD S3
     {
@@ -96,6 +97,7 @@
              ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 |
              ESCO_PKT_TYPES_MASK_NO_3_EV5),
         .retransmission_effort = ESCO_RETRANSMISSION_POWER,
+        .coding_format = ESCO_CODING_FORMAT_CVSD,
     },
     // CVSD S4
     {
@@ -135,6 +137,7 @@
              ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 |
              ESCO_PKT_TYPES_MASK_NO_3_EV5),
         .retransmission_effort = ESCO_RETRANSMISSION_QUALITY,
+        .coding_format = ESCO_CODING_FORMAT_CVSD,
     },
     // mSBC T1
     {
@@ -172,6 +175,7 @@
              ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5 |
              ESCO_PKT_TYPES_MASK_NO_2_EV3),
         .retransmission_effort = ESCO_RETRANSMISSION_QUALITY,
+        .coding_format = ESCO_CODING_FORMAT_MSBC,
     },
     // mSBC T2
     {
@@ -208,6 +212,7 @@
             (ESCO_PKT_TYPES_MASK_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 |
              ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5),
         .retransmission_effort = ESCO_RETRANSMISSION_QUALITY,
+        .coding_format = ESCO_CODING_FORMAT_MSBC,
     },
     // LC3 T1
     {
@@ -245,6 +250,7 @@
              ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5 |
              ESCO_PKT_TYPES_MASK_NO_2_EV3),
         .retransmission_effort = ESCO_RETRANSMISSION_QUALITY,
+        .coding_format = ESCO_CODING_FORMAT_LC3,
     },
     // LC3 T2
     {
@@ -281,6 +287,7 @@
             (ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 |
              ESCO_PKT_TYPES_MASK_NO_3_EV5),
         .retransmission_effort = ESCO_RETRANSMISSION_QUALITY,
+        .coding_format = ESCO_CODING_FORMAT_LC3,
     },
 };
 
diff --git a/system/gd/hci/acl_manager/connection_callbacks_mock.h b/system/gd/hci/acl_manager/connection_callbacks_mock.h
new file mode 100644
index 0000000..4f50b8a
--- /dev/null
+++ b/system/gd/hci/acl_manager/connection_callbacks_mock.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 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 <cstdint>
+#include <memory>
+
+#include "hci/acl_manager/connection_callbacks.h"
+#include "hci/hci_packets.h"
+
+namespace bluetooth {
+namespace hci {
+namespace acl_manager {
+
+class MockConnectionCallback : public ConnectionCallbacks {
+ public:
+  MOCK_METHOD(
+      void, OnConnectSuccess, (std::unique_ptr<ClassicAclConnection> connection), (override));
+  MOCK_METHOD(void, OnConnectRequest, (Address, ClassOfDevice), (override));
+  MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason, bool locally_initiated), (override));
+
+  MOCK_METHOD(void, HACK_OnEscoConnectRequest, (Address, ClassOfDevice), (override));
+  MOCK_METHOD(void, HACK_OnScoConnectRequest, (Address, ClassOfDevice), (override));
+};
+
+}  // namespace acl_manager
+}  // namespace hci
+}  // namespace bluetooth
diff --git a/system/gd/hci/acl_manager/connection_management_callbacks_mock.h b/system/gd/hci/acl_manager/connection_management_callbacks_mock.h
new file mode 100644
index 0000000..88ab212
--- /dev/null
+++ b/system/gd/hci/acl_manager/connection_management_callbacks_mock.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2023 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 <array>
+#include <cstdint>
+
+#include "hci/acl_manager/connection_management_callbacks.h"
+#include "hci/hci_packets.h"
+
+namespace bluetooth {
+namespace hci {
+namespace acl_manager {
+
+class MockConnectionManagementCallbacks : public ConnectionManagementCallbacks {
+ public:
+  MOCK_METHOD(void, OnConnectionPacketTypeChanged, (uint16_t packet_type), (override));
+  MOCK_METHOD(void, OnAuthenticationComplete, (ErrorCode hci_status), (override));
+  MOCK_METHOD(void, OnEncryptionChange, (EncryptionEnabled enabled)), (override);
+  MOCK_METHOD(void, OnChangeConnectionLinkKeyComplete, (), (override));
+  MOCK_METHOD(void, OnReadClockOffsetComplete, (uint16_t clock_offse), (override));
+  MOCK_METHOD(
+      void, OnModeChange, (ErrorCode status, Mode current_mode, uint16_t interval), (override));
+  MOCK_METHOD(
+      void,
+      OnSniffSubrating,
+      (ErrorCode status,
+       uint16_t maximum_transmit_latency,
+       uint16_t maximum_receive_latency,
+       uint16_t minimum_remote_timeout,
+       uint16_t minimum_local_timeout),
+      (override));
+  MOCK_METHOD(
+      void,
+      OnQosSetupComplete,
+      (ServiceType service_type,
+       uint32_t token_rate,
+       uint32_t peak_bandwidth,
+       uint32_t latency,
+       uint32_t delay_variation),
+      (override));
+  MOCK_METHOD(
+      void,
+      OnFlowSpecificationComplete,
+      (FlowDirection flow_direction,
+       ServiceType service_type,
+       uint32_t token_rate,
+       uint32_t token_bucket_size,
+       uint32_t peak_bandwidth,
+       uint32_t access_latency),
+      (override));
+  MOCK_METHOD(void, OnFlushOccurred, (), (override));
+  MOCK_METHOD(void, OnRoleDiscoveryComplete, (Role current_role), (override));
+  MOCK_METHOD(void, OnReadLinkPolicySettingsComplete, (uint16_t link_policy_settings), (override));
+  MOCK_METHOD(void, OnReadAutomaticFlushTimeoutComplete, (uint16_t flush_timeout), (override));
+  MOCK_METHOD(void, OnReadTransmitPowerLevelComplete, (uint8_t transmit_power_level), (override));
+  MOCK_METHOD(
+      void, OnReadLinkSupervisionTimeoutComplete, (uint16_t link_supervision_timeout), (override));
+  MOCK_METHOD(
+      void, OnReadFailedContactCounterComplete, (uint16_t failed_contact_counter), (override));
+  MOCK_METHOD(void, OnReadLinkQualityComplete, (uint8_t link_quality), (override));
+  MOCK_METHOD(
+      void,
+      OnReadAfhChannelMapComplete,
+      (AfhMode afh_mode, (std::array<uint8_t, 10>)afh_channel_map),
+      (override));
+  MOCK_METHOD(void, OnReadRssiComplete, (uint8_t rssi), (override));
+  MOCK_METHOD(void, OnReadClockComplete, (uint32_t clock, uint16_t accuracy), (override));
+  MOCK_METHOD(void, OnCentralLinkKeyComplete, (KeyFlag flag), (override));
+  MOCK_METHOD(void, OnRoleChange, (ErrorCode hci_status, Role new_role), (override));
+  MOCK_METHOD(void, OnDisconnection, (ErrorCode reason), (override));
+  MOCK_METHOD(
+      void,
+      OnReadRemoteVersionInformationComplete,
+      (ErrorCode hci_status, uint8_t lmp_version, uint16_t manufacturer_name, uint16_t sub_version),
+      (override));
+  MOCK_METHOD(void, OnReadRemoteSupportedFeaturesComplete, (uint64_t features), (override));
+  MOCK_METHOD(
+      void,
+      OnReadRemoteExtendedFeaturesComplete,
+      (uint8_t page_number, uint8_t max_page_number, uint64_t features),
+      (override));
+};
+
+}  // namespace acl_manager
+}  // namespace hci
+}  // namespace bluetooth
diff --git a/system/gd/hci/acl_manager_test.cc b/system/gd/hci/acl_manager_test.cc
index 2e1f82f..594fa62 100644
--- a/system/gd/hci/acl_manager_test.cc
+++ b/system/gd/hci/acl_manager_test.cc
@@ -25,40 +25,46 @@
 #include <map>
 
 #include "common/bind.h"
+#include "hci/acl_manager/connection_callbacks_mock.h"
+#include "hci/acl_manager/connection_management_callbacks_mock.h"
 #include "hci/acl_manager/le_connection_callbacks_mock.h"
 #include "hci/acl_manager/le_connection_management_callbacks_mock.h"
 #include "hci/address.h"
 #include "hci/class_of_device.h"
 #include "hci/controller.h"
+#include "hci/controller_mock.h"
 #include "hci/hci_layer.h"
 #include "hci/hci_layer_fake.h"
 #include "os/fake_timer/fake_timerfd.h"
 #include "os/thread.h"
 #include "packet/raw_builder.h"
 
+using bluetooth::common::BidiQueue;
+using bluetooth::common::BidiQueueEnd;
+using bluetooth::os::fake_timer::fake_timerfd_advance;
+using bluetooth::packet::kLittleEndian;
+using bluetooth::packet::PacketView;
+using bluetooth::packet::RawBuilder;
 using testing::_;
 
-namespace bluetooth {
-namespace hci {
-namespace acl_manager {
 namespace {
 
-using common::BidiQueue;
-using common::BidiQueueEnd;
-using os::fake_timer::fake_timerfd_advance;
-using packet::kLittleEndian;
-using packet::PacketView;
-using packet::RawBuilder;
-
 constexpr auto kTimeout = std::chrono::seconds(2);
 constexpr auto kShortTimeout = std::chrono::milliseconds(100);
+constexpr uint16_t kHciHandle = 123;
 constexpr uint16_t kScanIntervalFast = 0x0060;
 constexpr uint16_t kScanWindowFast = 0x0030;
 constexpr uint16_t kScanIntervalSlow = 0x0800;
 constexpr uint16_t kScanWindowSlow = 0x0030;
-const AddressWithType empty_address_with_type = hci::AddressWithType();
+const bluetooth::hci::AddressWithType empty_address_with_type = bluetooth::hci::AddressWithType();
 
-class TestController : public Controller {
+}  // namespace
+
+namespace bluetooth {
+namespace hci {
+namespace acl_manager {
+
+class TestController : public testing::MockController {
  public:
   void RegisterCompletedAclPacketsCallback(
       common::ContextualCallback<void(uint16_t /* handle */, uint16_t /* packets */)> cb) override {
@@ -106,7 +112,13 @@
  protected:
   void SetUp() override {
     test_hci_layer_ = new TestHciLayer;  // Ownership is transferred to registry
-    test_controller_ = new TestController;
+    test_controller_ = new TestController;  // Ownership is transferred to registry
+
+    EXPECT_CALL(*test_controller_, GetMacAddress());
+    EXPECT_CALL(*test_controller_, GetLeFilterAcceptListSize());
+    EXPECT_CALL(*test_controller_, GetLeResolvingListSize());
+    EXPECT_CALL(*test_controller_, SupportsBlePrivacy());
+
     fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_);
     fake_registry_.InjectTestModule(&Controller::Factory, test_controller_);
     client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory);
@@ -133,13 +145,22 @@
     my_initiating_address = AddressWithType(
         set_random_address_packet.GetRandomAddress(), AddressType::RANDOM_DEVICE_ADDRESS);
     test_hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
+
+    ON_CALL(mock_connection_callback_, OnConnectSuccess)
+        .WillByDefault([this](std::unique_ptr<ClassicAclConnection> connection) {
+          connections_.push_back(std::move(connection));
+          if (connection_promise_ != nullptr) {
+            connection_promise_->set_value();
+            connection_promise_.reset();
+          }
+        });
   }
 
   void TearDown() override {
     // Invalid mutex exception is raised if the connections
     // are cleared after the AclConnectionInterface is deleted
     // through fake_registry_.
-    mock_connection_callback_.Clear();
+    connections_.clear();
     le_connections_.clear();
     fake_registry_.SynchronizeModuleHandler(&AclManager::Factory, std::chrono::milliseconds(20));
     fake_registry_.StopAll();
@@ -160,9 +181,9 @@
   const bool use_connect_list_ = true;  // gd currently only supports connect list
 
   std::future<void> GetConnectionFuture() {
-    ASSERT_LOG(mock_connection_callback_.connection_promise_ == nullptr, "Promises promises ... Only one at a time");
-    mock_connection_callback_.connection_promise_ = std::make_unique<std::promise<void>>();
-    return mock_connection_callback_.connection_promise_->get_future();
+    ASSERT_LOG(connection_promise_ == nullptr, "Promises promises ... Only one at a time");
+    connection_promise_ = std::make_unique<std::promise<void>>();
+    return connection_promise_->get_future();
   }
 
   std::future<void> GetLeConnectionFuture() {
@@ -172,7 +193,7 @@
   }
 
   std::shared_ptr<ClassicAclConnection> GetLastConnection() {
-    return mock_connection_callback_.connections_.back();
+    return connections_.back();
   }
 
   std::shared_ptr<LeAclConnection> GetLastLeConnection() {
@@ -203,29 +224,9 @@
     return command;
   }
 
-  class MockConnectionCallback : public ConnectionCallbacks {
-   public:
-    void OnConnectSuccess(std::unique_ptr<ClassicAclConnection> connection) override {
-      // Convert to std::shared_ptr during push_back()
-      connections_.push_back(std::move(connection));
-      if (connection_promise_ != nullptr) {
-        connection_promise_->set_value();
-        connection_promise_.reset();
-      }
-    }
-
-    void Clear() {
-      connections_.clear();
-    }
-    MOCK_METHOD(void, OnConnectRequest, (Address, ClassOfDevice), (override));
-    MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason, bool locally_initiated), (override));
-
-    MOCK_METHOD(void, HACK_OnEscoConnectRequest, (Address, ClassOfDevice), (override));
-    MOCK_METHOD(void, HACK_OnScoConnectRequest, (Address, ClassOfDevice), (override));
-
-    std::list<std::shared_ptr<ClassicAclConnection>> connections_;
-    std::unique_ptr<std::promise<void>> connection_promise_;
-  } mock_connection_callback_;
+  std::list<std::shared_ptr<ClassicAclConnection>> connections_;
+  std::unique_ptr<std::promise<void>> connection_promise_;
+  MockConnectionCallback mock_connection_callback_;
 
   std::list<std::shared_ptr<LeAclConnection>> le_connections_;
   std::unique_ptr<std::promise<void>> le_connection_promise_;
@@ -272,7 +273,7 @@
     // Invalid mutex exception is raised if the connection
     // is cleared after the AclConnectionInterface is deleted
     // through fake_registry_.
-    mock_connection_callback_.Clear();
+    connections_.clear();
     le_connections_.clear();
     connection_.reset();
     fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20));
@@ -283,55 +284,12 @@
   uint16_t handle_;
   std::shared_ptr<ClassicAclConnection> connection_;
 
-  class MockConnectionManagementCallbacks : public ConnectionManagementCallbacks {
-   public:
-    MOCK_METHOD1(OnConnectionPacketTypeChanged, void(uint16_t packet_type));
-    MOCK_METHOD1(OnAuthenticationComplete, void(hci::ErrorCode hci_status));
-    MOCK_METHOD1(OnEncryptionChange, void(EncryptionEnabled enabled));
-    MOCK_METHOD0(OnChangeConnectionLinkKeyComplete, void());
-    MOCK_METHOD1(OnReadClockOffsetComplete, void(uint16_t clock_offse));
-    MOCK_METHOD3(OnModeChange, void(ErrorCode status, Mode current_mode, uint16_t interval));
-    MOCK_METHOD5(
-        OnSniffSubrating,
-        void(
-            ErrorCode status,
-            uint16_t maximum_transmit_latency,
-            uint16_t maximum_receive_latency,
-            uint16_t minimum_remote_timeout,
-            uint16_t minimum_local_timeout));
-    MOCK_METHOD5(OnQosSetupComplete, void(ServiceType service_type, uint32_t token_rate, uint32_t peak_bandwidth,
-                                          uint32_t latency, uint32_t delay_variation));
-    MOCK_METHOD6(OnFlowSpecificationComplete,
-                 void(FlowDirection flow_direction, ServiceType service_type, uint32_t token_rate,
-                      uint32_t token_bucket_size, uint32_t peak_bandwidth, uint32_t access_latency));
-    MOCK_METHOD0(OnFlushOccurred, void());
-    MOCK_METHOD1(OnRoleDiscoveryComplete, void(Role current_role));
-    MOCK_METHOD1(OnReadLinkPolicySettingsComplete, void(uint16_t link_policy_settings));
-    MOCK_METHOD1(OnReadAutomaticFlushTimeoutComplete, void(uint16_t flush_timeout));
-    MOCK_METHOD1(OnReadTransmitPowerLevelComplete, void(uint8_t transmit_power_level));
-    MOCK_METHOD1(OnReadLinkSupervisionTimeoutComplete, void(uint16_t link_supervision_timeout));
-    MOCK_METHOD1(OnReadFailedContactCounterComplete, void(uint16_t failed_contact_counter));
-    MOCK_METHOD1(OnReadLinkQualityComplete, void(uint8_t link_quality));
-    MOCK_METHOD2(OnReadAfhChannelMapComplete, void(AfhMode afh_mode, std::array<uint8_t, 10> afh_channel_map));
-    MOCK_METHOD1(OnReadRssiComplete, void(uint8_t rssi));
-    MOCK_METHOD2(OnReadClockComplete, void(uint32_t clock, uint16_t accuracy));
-    MOCK_METHOD1(OnCentralLinkKeyComplete, void(KeyFlag flag));
-    MOCK_METHOD2(OnRoleChange, void(ErrorCode hci_status, Role new_role));
-    MOCK_METHOD1(OnDisconnection, void(ErrorCode reason));
-    MOCK_METHOD4(
-        OnReadRemoteVersionInformationComplete,
-        void(hci::ErrorCode hci_status, uint8_t lmp_version, uint16_t manufacturer_name, uint16_t sub_version));
-    MOCK_METHOD1(OnReadRemoteSupportedFeaturesComplete, void(uint64_t features));
-    MOCK_METHOD3(
-        OnReadRemoteExtendedFeaturesComplete, void(uint8_t page_number, uint8_t max_page_number, uint64_t features));
-  } mock_connection_management_callbacks_;
+  MockConnectionManagementCallbacks mock_connection_management_callbacks_;
 };
 
 TEST_F(AclManagerTest, startup_teardown) {}
 
 TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_success) {
-  uint16_t handle = 1;
-
   acl_manager_->CreateConnection(remote);
 
   // Wait for the connection request
@@ -342,8 +300,8 @@
 
   auto first_connection = GetConnectionFuture();
 
-  test_hci_layer_->IncomingEvent(
-      ConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, handle, remote, LinkType::ACL, Enable::DISABLED));
+  test_hci_layer_->IncomingEvent(ConnectionCompleteBuilder::Create(
+      ErrorCode::SUCCESS, kHciHandle, remote, LinkType::ACL, Enable::DISABLED));
 
   auto first_connection_status = first_connection.wait_for(kTimeout);
   ASSERT_EQ(first_connection_status, std::future_status::ready);
@@ -353,8 +311,6 @@
 }
 
 TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_fail) {
-  uint16_t handle = 0x123;
-
   acl_manager_->CreateConnection(remote);
 
   // Wait for the connection request
@@ -363,12 +319,36 @@
     last_command = GetConnectionManagementCommand(OpCode::CREATE_CONNECTION);
   }
 
+  struct callback_t {
+    hci::Address bd_addr;
+    hci::ErrorCode reason;
+    bool is_locally_initiated;
+  };
+
+  auto promise = std::promise<callback_t>();
+  auto future = promise.get_future();
+  ON_CALL(mock_connection_callback_, OnConnectFail)
+      .WillByDefault(
+          [&promise](hci::Address bd_addr, hci::ErrorCode reason, bool is_locally_initiated) {
+            promise.set_value({
+                .bd_addr = bd_addr,
+                .reason = reason,
+                .is_locally_initiated = is_locally_initiated,
+            });
+          });
+
   EXPECT_CALL(mock_connection_callback_, OnConnectFail(remote, ErrorCode::PAGE_TIMEOUT, true));
-  test_hci_layer_->IncomingEvent(
-      ConnectionCompleteBuilder::Create(ErrorCode::PAGE_TIMEOUT, handle, remote, LinkType::ACL, Enable::DISABLED));
-  fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20));
-  fake_registry_.SynchronizeModuleHandler(&AclManager::Factory, std::chrono::milliseconds(20));
-  fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20));
+
+  // Remote response event to the connection request
+  test_hci_layer_->IncomingEvent(ConnectionCompleteBuilder::Create(
+      ErrorCode::PAGE_TIMEOUT, kHciHandle, remote, LinkType::ACL, Enable::DISABLED));
+
+  ASSERT_EQ(std::future_status::ready, future.wait_for(kTimeout));
+  auto callback = future.get();
+
+  ASSERT_EQ(remote, callback.bd_addr);
+  ASSERT_EQ(ErrorCode::PAGE_TIMEOUT, callback.reason);
+  ASSERT_EQ(true, callback.is_locally_initiated);
 }
 
 class AclManagerWithLeConnectionTest : public AclManagerTest {
@@ -436,7 +416,7 @@
     // Invalid mutex exception is raised if the connection
     // is cleared after the AclConnectionInterface is deleted
     // through fake_registry_.
-    mock_connection_callback_.Clear();
+    connections_.clear();
     le_connections_.clear();
     connection_.reset();
     fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20));
@@ -1407,7 +1387,6 @@
   fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20));
 }
 
-}  // namespace
 }  // namespace acl_manager
 }  // namespace hci
 }  // namespace bluetooth
diff --git a/system/gd/hci/le_scanning_manager.cc b/system/gd/hci/le_scanning_manager.cc
index 7301d80..462dd28 100644
--- a/system/gd/hci/le_scanning_manager.cc
+++ b/system/gd/hci/le_scanning_manager.cc
@@ -870,7 +870,7 @@
         combined_data.push_back((uint8_t)data);
         combined_data.push_back((uint8_t)(data >> 8));
       } else if (uuid_len == Uuid::kNumBytes32) {
-        uint16_t data = uuid.As32Bit();
+        uint32_t data = uuid.As32Bit();
         combined_data.push_back((uint8_t)data);
         combined_data.push_back((uint8_t)(data >> 8));
         combined_data.push_back((uint8_t)(data >> 16));
@@ -889,7 +889,7 @@
           combined_data.push_back((uint8_t)data);
           combined_data.push_back((uint8_t)(data >> 8));
         } else if (uuid_len == Uuid::kNumBytes32) {
-          uint16_t data = uuid_mask.As32Bit();
+          uint32_t data = uuid_mask.As32Bit();
           combined_data.push_back((uint8_t)data);
           combined_data.push_back((uint8_t)(data >> 8));
           combined_data.push_back((uint8_t)(data >> 16));
diff --git a/system/gd/rust/common/src/init_flags.rs b/system/gd/rust/common/src/init_flags.rs
index 598346c..38882be 100644
--- a/system/gd/rust/common/src/init_flags.rs
+++ b/system/gd/rust/common/src/init_flags.rs
@@ -379,7 +379,7 @@
         gd_hal_snoop_logger_filtering = true,
         gd_l2cap,
         gd_link_policy,
-        gd_remote_name_request,
+        gd_remote_name_request = true,
         gd_rust,
         hci_adapter: i32,
         hfp_dynamic_version = true,
diff --git a/system/hci/Android.bp b/system/hci/Android.bp
index e84c138..1e8e2b8 100644
--- a/system/hci/Android.bp
+++ b/system/hci/Android.bp
@@ -73,30 +73,3 @@
         "libchrome",
     ],
 }
-
-cc_test {
-    name: "net_test_hci_fragmenter_native",
-    static_libs: [
-        "libbase",
-        "libchrome",
-    ],
-    test_suites: ["device-tests"],
-    defaults: [
-        "bluetooth_gtest_x86_asan_workaround",
-        "fluoride_test_defaults",
-        "mts_defaults",
-    ],
-    local_include_dirs: [
-        "include",
-    ],
-    include_dirs: [
-        "packages/modules/Bluetooth/system",
-        "packages/modules/Bluetooth/system/gd",
-        "packages/modules/Bluetooth/system/osi/test",
-        "packages/modules/Bluetooth/system/stack/include",
-    ],
-    srcs: [
-        "src/buffer_allocator.cc",
-        "test/packet_fragmenter_host_test.cc",
-    ],
-}
diff --git a/system/hci/include/hci_layer.h b/system/hci/include/hci_layer.h
index 21b4c22..2e1986d 100644
--- a/system/hci/include/hci_layer.h
+++ b/system/hci/include/hci_layer.h
@@ -33,7 +33,6 @@
 #define MSG_SUB_EVT_MASK 0x00FF /* eq. BT_SUB_EVT_MASK */
 
 /* Message event ID passed from Host/Controller lib to stack */
-#define MSG_HC_TO_STACK_HCI_ACL 0x1100      /* eq. BT_EVT_TO_BTU_HCI_ACL */
 #define MSG_HC_TO_STACK_HCI_SCO 0x1200      /* eq. BT_EVT_TO_BTU_HCI_SCO */
 #define MSG_HC_TO_STACK_HCI_ERR 0x1300      /* eq. BT_EVT_TO_BTU_HCIT_ERR */
 #define MSG_HC_TO_STACK_HCI_ISO 0x1700      /* eq. BT_EVT_TO_BTU_HCI_ISO */
@@ -65,8 +64,6 @@
                            command_complete_cb complete_callback,
                            command_status_cb status_cb, void* context);
 
-  future_t* (*transmit_command_futured)(const BT_HDR* command);
-
   // Send some data downward through the HCI layer
   void (*transmit_downward)(uint16_t type, void* data);
 } hci_t;
diff --git a/system/hci/include/packet_fragmenter.h b/system/hci/include/packet_fragmenter.h
index 29651a0..c82f537 100644
--- a/system/hci/include/packet_fragmenter.h
+++ b/system/hci/include/packet_fragmenter.h
@@ -23,7 +23,6 @@
 #include "osi/include/allocator.h"
 #include "stack/include/bt_hdr.h"
 
-typedef void (*transmit_finished_cb)(BT_HDR* packet, bool all_fragments_sent);
 typedef void (*packet_reassembled_cb)(BT_HDR* packet);
 typedef void (*packet_fragmented_cb)(BT_HDR* packet,
                                      bool send_transmit_finished);
@@ -34,10 +33,6 @@
 
   // Called for every completely reassembled packet.
   packet_reassembled_cb reassembled;
-
-  // Called when the fragmenter finishes sending all requested fragments,
-  // but the packet has not been entirely sent.
-  transmit_finished_cb transmit_finished;
 } packet_fragmenter_callbacks_t;
 
 typedef struct packet_fragmenter_t {
@@ -51,10 +46,8 @@
   // callback.
   void (*fragment_and_dispatch)(BT_HDR* packet);
   // If |packet| is a complete packet, forwards to the reassembled callback.
-  // Otherwise
-  // holds onto it until all fragments arrive, at which point the reassembled
-  // callback is called
-  // with the reassembled data.
+  // Otherwise holds onto it until all fragments arrive, at which point the
+  // reassembled callback is called with the reassembled data.
   void (*reassemble_and_dispatch)(BT_HDR* packet);
 } packet_fragmenter_t;
 
diff --git a/system/hci/src/packet_fragmenter.cc b/system/hci/src/packet_fragmenter.cc
index 93c1a7e..ca0709f 100644
--- a/system/hci/src/packet_fragmenter.cc
+++ b/system/hci/src/packet_fragmenter.cc
@@ -30,12 +30,8 @@
 #include "device/include/controller.h"
 #include "hci/include/buffer_allocator.h"
 #include "osi/include/log.h"
-#include "osi/include/osi.h"
 #include "stack/include/bt_hdr.h"
 
-// 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.2)
-#define HCI_ACL_PREAMBLE_SIZE 4
-
 #define HCI_ISO_BF_FIRST_FRAGMENTED_PACKET (0)
 #define HCI_ISO_BF_CONTINUATION_FRAGMENT_PACKET (1)
 #define HCI_ISO_BF_COMPLETE_PACKET (2)
@@ -84,39 +80,21 @@
 static const controller_t* controller;
 static const packet_fragmenter_callbacks_t* callbacks;
 
-static std::unordered_map<uint16_t /* handle */, BT_HDR*> partial_packets;
 static std::unordered_map<uint16_t /* handle */, BT_HDR*> partial_iso_packets;
 
 static void init(const packet_fragmenter_callbacks_t* result_callbacks) {
   callbacks = result_callbacks;
 }
 
-static void cleanup() {
-  partial_packets.clear();
-  partial_iso_packets.clear();
-}
-
-static bool check_uint16_overflow(uint16_t a, uint16_t b) {
-  return (UINT16_MAX - a) < b;
-}
-
-static void fragment_and_dispatch_iso(BT_HDR* packet);
+static void cleanup() { partial_iso_packets.clear(); }
 
 static void fragment_and_dispatch(BT_HDR* packet) {
   CHECK(packet != NULL);
 
   uint16_t event = packet->event & MSG_EVT_MASK;
 
-  if (event == MSG_HC_TO_STACK_HCI_SCO) {
-    callbacks->fragmented(packet, true);
-  } else if (event == MSG_STACK_TO_HC_HCI_ISO) {
-    fragment_and_dispatch_iso(packet);
-  } else {
-    callbacks->fragmented(packet, true);
-  }
-}
+  CHECK(event == MSG_STACK_TO_HC_HCI_ISO);
 
-static void fragment_and_dispatch_iso(BT_HDR* packet) {
   uint8_t* stream = packet->data + packet->offset;
   uint16_t max_data_size = controller->get_iso_data_size();
   uint16_t max_packet_size = max_data_size + HCI_ISO_PREAMBLE_SIZE;
@@ -162,7 +140,7 @@
   callbacks->fragmented(packet, true);
 }
 
-static void reassemble_and_dispatch_iso(UNUSED_ATTR BT_HDR* packet) {
+static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR* packet) {
   uint8_t* stream = packet->data;
   uint16_t handle;
   uint16_t iso_length;
@@ -170,6 +148,9 @@
   BT_HDR* partial_packet;
   uint16_t iso_full_len;
 
+  uint16_t event = packet->event & MSG_EVT_MASK;
+  CHECK(event == MSG_HC_TO_STACK_HCI_ISO);
+
   STREAM_TO_UINT16(handle, stream);
   STREAM_TO_UINT16(iso_length, stream);
   // last 2 bits is RFU
@@ -343,139 +324,6 @@
   }
 }
 
-static void reassemble_and_dispatch(BT_HDR* packet) {
-  if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ACL) {
-    uint8_t* stream = packet->data;
-    uint16_t handle;
-    uint16_t acl_length;
-
-    STREAM_TO_UINT16(handle, stream);
-    STREAM_TO_UINT16(acl_length, stream);
-
-    CHECK(acl_length == packet->len - HCI_ACL_PREAMBLE_SIZE);
-
-    uint8_t boundary_flag = GET_BOUNDARY_FLAG(handle);
-    uint8_t broadcast_flag = GET_BROADCAST_FLAG(handle);
-    handle = handle & HANDLE_MASK;
-
-    if (broadcast_flag != POINT_TO_POINT) {
-      LOG_WARN("dropping broadcast packet");
-      buffer_allocator->free(packet);
-      return;
-    }
-
-    if (boundary_flag == START_PACKET_BOUNDARY) {
-      if (acl_length < 2) {
-        LOG_WARN("%s invalid acl_length %d", __func__, acl_length);
-        buffer_allocator->free(packet);
-        return;
-      }
-      uint16_t l2cap_length;
-      STREAM_TO_UINT16(l2cap_length, stream);
-      auto map_iter = partial_packets.find(handle);
-      if (map_iter != partial_packets.end()) {
-        LOG_WARN(
-            "%s found unfinished packet for handle with start packet. "
-            "Dropping old.",
-            __func__);
-
-        BT_HDR* hdl = map_iter->second;
-        partial_packets.erase(map_iter);
-        buffer_allocator->free(hdl);
-      }
-
-      if (acl_length < L2CAP_HEADER_PDU_LEN_SIZE) {
-        LOG_WARN("%s L2CAP packet too small (%d < %d). Dropping it.", __func__,
-                 packet->len, L2CAP_HEADER_PDU_LEN_SIZE);
-        buffer_allocator->free(packet);
-        return;
-      }
-
-      uint16_t full_length =
-          l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
-
-      // Check for buffer overflow and that the full packet size + BT_HDR size
-      // is less than the max buffer size
-      if (check_uint16_overflow(l2cap_length,
-                                (L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE)) ||
-          ((full_length + sizeof(BT_HDR)) > BT_DEFAULT_BUFFER_SIZE)) {
-        LOG_ERROR("%s Dropping L2CAP packet with invalid length (%d).",
-                  __func__, l2cap_length);
-        buffer_allocator->free(packet);
-        return;
-      }
-
-      if (full_length <= packet->len) {
-        if (full_length < packet->len)
-          LOG_WARN("%s found l2cap full length %d less than the hci length %d.",
-                   __func__, l2cap_length, packet->len);
-
-        callbacks->reassembled(packet);
-        return;
-      }
-
-      BT_HDR* partial_packet =
-          (BT_HDR*)buffer_allocator->alloc(full_length + sizeof(BT_HDR));
-      partial_packet->event = packet->event;
-      partial_packet->len = full_length;
-      partial_packet->offset = packet->len;
-
-      memcpy(partial_packet->data, packet->data, packet->len);
-
-      // Update the ACL data size to indicate the full expected length
-      stream = partial_packet->data;
-      STREAM_SKIP_UINT16(stream);  // skip the handle
-      UINT16_TO_STREAM(stream, full_length - HCI_ACL_PREAMBLE_SIZE);
-
-      partial_packets[handle] = partial_packet;
-
-      // Free the old packet buffer, since we don't need it anymore
-      buffer_allocator->free(packet);
-    } else {
-      auto map_iter = partial_packets.find(handle);
-      if (map_iter == partial_packets.end()) {
-        LOG_WARN("%s got continuation for unknown packet. Dropping it.",
-                 __func__);
-        buffer_allocator->free(packet);
-        return;
-      }
-      BT_HDR* partial_packet = map_iter->second;
-
-      packet->offset = HCI_ACL_PREAMBLE_SIZE;
-      uint16_t projected_offset =
-          partial_packet->offset + (packet->len - HCI_ACL_PREAMBLE_SIZE);
-      if ((packet->len - packet->offset) >
-          (partial_packet->len - partial_packet->offset)) {
-        LOG_WARN(
-            "%s got packet which would exceed expected length of %d. "
-            "Truncating.",
-            __func__, partial_packet->len);
-        packet->len = (partial_packet->len - partial_packet->offset) + packet->offset;
-        projected_offset = partial_packet->len;
-      }
-
-      memcpy(partial_packet->data + partial_packet->offset,
-             packet->data + packet->offset, packet->len - packet->offset);
-
-      // Free the old packet buffer, since we don't need it anymore
-      buffer_allocator->free(packet);
-      partial_packet->offset = projected_offset;
-
-      if (partial_packet->offset == partial_packet->len) {
-        partial_packets.erase(handle);
-        partial_packet->offset = 0;
-        callbacks->reassembled(partial_packet);
-      }
-    }
-  } else if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_SCO) {
-    callbacks->reassembled(packet);
-  } else if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ISO) {
-    reassemble_and_dispatch_iso(packet);
-  } else {
-    callbacks->reassembled(packet);
-  }
-}
-
 static const packet_fragmenter_t interface = {init, cleanup,
 
                                               fragment_and_dispatch,
diff --git a/system/hci/test/packet_fragmenter_host_test.cc b/system/hci/test/packet_fragmenter_host_test.cc
deleted file mode 100644
index 7c566f5..0000000
--- a/system/hci/test/packet_fragmenter_host_test.cc
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <base/logging.h>
-#include <gtest/gtest.h>
-
-#include <cstdint>
-#include <queue>
-
-#include "hci/src/packet_fragmenter.cc"
-#include "osi/include/allocator.h"
-#include "osi/test/AllocationTestHarness.h"
-#include "stack/include/bt_hdr.h"
-
-void allocation_tracker_uninit(void);
-
-enum kPacketOrder {
-  kStart = 1,
-  kContinuation = 2,
-};
-
-struct AclPacketHeader {
-  struct {
-    uint16_t handle : 12;
-    uint16_t continuation : 1;
-    uint16_t start : 1;
-    uint16_t reserved : 2;
-  } s;
-  uint16_t length;
-
-  uint16_t GetRawHandle() const { return *(uint16_t*)(this); }
-
-  uint16_t GetHandle() const { return s.handle; }
-  uint16_t GetLength() const { return length; }
-} __attribute__((packed));
-
-struct L2capPacketHeader {
-  uint16_t length;
-  uint16_t cid;
-} __attribute__((packed));
-
-struct AclL2capPacketHeader {
-  struct AclPacketHeader acl_header;
-  struct L2capPacketHeader l2cap_header;
-} __attribute__((packed));
-
-namespace {
-
-constexpr uint16_t kHandle = 0x123;
-constexpr uint16_t kCid = 0x4567;
-constexpr uint16_t kMaxPacketSize = BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR) -
-                                    L2CAP_HEADER_SIZE - HCI_ACL_PREAMBLE_SIZE;
-constexpr size_t kTypicalPacketSizes[] = {
-    1, 2, 3, 4, 8, 16, 32, 64, 127, 128, 129, 256, 1024, 2048, kMaxPacketSize};
-constexpr size_t kNumberOfTypicalPacketSizes =
-    sizeof(kTypicalPacketSizes) / sizeof(kTypicalPacketSizes[0]);
-
-void FreeBuffer(BT_HDR* bt_hdr) { osi_free(bt_hdr); }
-
-struct TestMutables {
-  struct {
-    int access_count_{0};
-  } fragmented;
-  struct {
-    int access_count_{0};
-    std::queue<std::unique_ptr<BT_HDR, decltype(&FreeBuffer)>> queue;
-  } reassembled;
-  struct {
-    int access_count_{0};
-  } transmit_finished;
-};
-
-TestMutables test_state_;
-
-void OnFragmented(BT_HDR* packet, bool send_transmit_finished) {
-  test_state_.fragmented.access_count_++;
-}
-
-void OnReassembled(BT_HDR* packet) {
-  test_state_.reassembled.access_count_++;
-  test_state_.reassembled.queue.push(
-      std::unique_ptr<BT_HDR, decltype(&FreeBuffer)>(packet, &FreeBuffer));
-}
-
-void OnTransmitFinished(BT_HDR* packet, bool all_fragments_sent) {
-  test_state_.transmit_finished.access_count_++;
-}
-
-packet_fragmenter_callbacks_t result_callbacks = {
-    .fragmented = OnFragmented,
-    .reassembled = OnReassembled,
-    .transmit_finished = OnTransmitFinished,
-};
-
-AclPacketHeader* AclHeader(BT_HDR* packet) {
-  return (AclPacketHeader*)packet->data;
-}
-L2capPacketHeader* L2capHeader(BT_HDR* packet) {
-  return &((AclL2capPacketHeader*)packet->data)->l2cap_header;
-}
-
-uint8_t* Data(BT_HDR* packet) {
-  AclPacketHeader* acl_header =
-      reinterpret_cast<AclPacketHeader*>(packet->data);
-  return acl_header->s.start
-             ? (uint8_t*)(packet->data + sizeof(AclL2capPacketHeader))
-             : (uint8_t*)(packet->data + sizeof(AclPacketHeader));
-}
-
-}  // namespace
-
-// Needed for linkage
-const controller_t* controller_get_interface() { return nullptr; }
-
-/**
- * Test class to test selected functionality in hci/src/hci_layer.cc
- */
-class HciPacketFragmenterTest : public AllocationTestHarness {
- protected:
-  void SetUp() override {
-    AllocationTestHarness::SetUp();
-    // Disable our allocation tracker to allow ASAN full range
-    allocation_tracker_uninit();
-    packet_fragmenter_ = packet_fragmenter_get_interface();
-    packet_fragmenter_->init(&result_callbacks);
-    test_state_ = TestMutables();
-  }
-
-  void TearDown() override {
-    FlushPartialPackets();
-    while (!test_state_.reassembled.queue.empty()) {
-      test_state_.reassembled.queue.pop();
-    }
-    packet_fragmenter_->cleanup();
-    AllocationTestHarness::TearDown();
-  }
-  const packet_fragmenter_t* packet_fragmenter_;
-
-  // Start acl packet
-  BT_HDR* AllocateL2capPacket(size_t l2cap_length,
-                              const std::vector<uint8_t> data) const {
-    auto packet =
-        AllocateAclPacket(data.size() + sizeof(L2capPacketHeader), kStart);
-    L2capHeader(packet)->length = l2cap_length;
-    L2capHeader(packet)->cid = kCid;
-    std::copy(data.cbegin(), data.cend(), Data(packet));
-    return packet;
-  }
-
-  // Continuation acl packet
-  BT_HDR* AllocateL2capPacket(const std::vector<uint8_t> data) const {
-    auto packet = AllocateAclPacket(data.size(), kContinuation);
-    std::copy(data.cbegin(), data.cend(), Data(packet));
-    return packet;
-  }
-
-  const std::vector<uint8_t> CreateData(size_t size) const {
-    CHECK(size > 0);
-    std::vector<uint8_t> v(size);
-    uint8_t sum = 0;
-    for (size_t s = 0; s < size; s++) {
-      sum += v[s] = s;
-    }
-    v[0] = (~sum + 1);  // First byte has sum complement
-    return v;
-  }
-
-  // Verify packet integrity
-  bool VerifyData(const uint8_t* data, size_t size) const {
-    CHECK(size > 0);
-    uint8_t sum = 0;
-    for (size_t s = 0; s < size; s++) {
-      sum += data[s];
-    }
-    return sum == 0;
-  }
-
- private:
-  BT_HDR* AllocateAclPacket(size_t acl_length,
-                            kPacketOrder packet_order) const {
-    BT_HDR* packet = AllocatePacket(sizeof(AclPacketHeader) + acl_length,
-                                    MSG_HC_TO_STACK_HCI_ACL);
-    AclHeader(packet)->s.handle = kHandle;
-    AclHeader(packet)->length = acl_length;
-    switch (packet_order) {
-      case kStart:
-        AclHeader(packet)->s.start = 1;
-        break;
-      case kContinuation:
-        AclHeader(packet)->s.continuation = 1;
-        break;
-    }
-    return packet;
-  }
-
-  BT_HDR* AllocatePacket(size_t packet_length, uint16_t event_mask) const {
-    BT_HDR* packet =
-        static_cast<BT_HDR*>(osi_calloc(sizeof(BT_HDR) + packet_length));
-    packet->event = event_mask;
-    packet->len = static_cast<uint16_t>(packet_length);
-    return packet;
-  }
-
-  void FlushPartialPackets() const {
-    while (!partial_packets.empty()) {
-      BT_HDR* partial_packet = partial_packets.at(kHandle);
-      partial_packets.erase(kHandle);
-      osi_free(partial_packet);
-    }
-  }
-};
-
-TEST_F(HciPacketFragmenterTest, TestStruct_Handle) {
-  AclPacketHeader acl_header;
-  memset(&acl_header, 0, sizeof(acl_header));
-
-  for (uint16_t h = 0; h < UINT16_MAX; h++) {
-    acl_header.s.handle = h;
-    CHECK(acl_header.GetHandle() == (h & HANDLE_MASK));
-    CHECK(acl_header.s.continuation == 0);
-    CHECK(acl_header.s.start == 0);
-    CHECK(acl_header.s.reserved == 0);
-
-    CHECK((acl_header.GetRawHandle() & HANDLE_MASK) == (h & HANDLE_MASK));
-    GET_BOUNDARY_FLAG(acl_header.GetRawHandle() == 0);
-  }
-}
-
-TEST_F(HciPacketFragmenterTest, TestStruct_Continuation) {
-  AclPacketHeader acl_header;
-  memset(&acl_header, 0, sizeof(acl_header));
-
-  for (uint16_t h = 0; h < UINT16_MAX; h++) {
-    acl_header.s.continuation = h;
-    CHECK(acl_header.GetHandle() == 0);
-    CHECK(acl_header.s.continuation == (h & 0x1));
-    CHECK(acl_header.s.start == 0);
-    CHECK(acl_header.s.reserved == 0);
-
-    CHECK((acl_header.GetRawHandle() & HANDLE_MASK) == 0);
-    GET_BOUNDARY_FLAG(acl_header.GetRawHandle() == (h & 0x3));
-  }
-}
-
-TEST_F(HciPacketFragmenterTest, TestStruct_Start) {
-  AclPacketHeader acl_header;
-  memset(&acl_header, 0, sizeof(acl_header));
-
-  for (uint16_t h = 0; h < UINT16_MAX; h++) {
-    acl_header.s.start = h;
-    CHECK(acl_header.GetHandle() == 0);
-    CHECK(acl_header.s.continuation == 0);
-    CHECK(acl_header.s.start == (h & 0x1));
-    CHECK(acl_header.s.reserved == 0);
-
-    CHECK((acl_header.GetRawHandle() & HANDLE_MASK) == 0);
-    GET_BOUNDARY_FLAG(acl_header.GetRawHandle() == (h & 0x3));
-  }
-}
-
-TEST_F(HciPacketFragmenterTest, TestStruct_Reserved) {
-  AclPacketHeader acl_header;
-  memset(&acl_header, 0, sizeof(acl_header));
-
-  for (uint16_t h = 0; h < UINT16_MAX; h++) {
-    acl_header.s.reserved = h;
-    CHECK(acl_header.GetHandle() == 0);
-    CHECK(acl_header.s.continuation == 0);
-    CHECK(acl_header.s.start == 0);
-    CHECK(acl_header.s.reserved == (h & 0x3));
-  }
-}
-TEST_F(HciPacketFragmenterTest, CreateAndVerifyPackets) {
-  const size_t size_check[] = {1,  2,   3,   4,   8,   16,   32,
-                               64, 127, 128, 129, 256, 1024, 0xfff0};
-  const std::vector<size_t> sizes(
-      size_check, size_check + sizeof(size_check) / sizeof(size_check[0]));
-
-  for (const auto packet_size : sizes) {
-    const std::vector<uint8_t> data = CreateData(packet_size);
-    uint8_t buf[packet_size];
-    std::copy(data.cbegin(), data.cend(), buf);
-    CHECK(VerifyData(buf, packet_size));
-  }
-}
-
-TEST_F(HciPacketFragmenterTest, OnePacket_Immediate) {
-  const std::vector<size_t> sizes(
-      kTypicalPacketSizes, kTypicalPacketSizes + kNumberOfTypicalPacketSizes);
-
-  int reassembled_access_count = 0;
-  for (const auto packet_size : sizes) {
-    const std::vector<uint8_t> data = CreateData(packet_size);
-    reassemble_and_dispatch(AllocateL2capPacket(data.size(), data));
-
-    CHECK(partial_packets.size() == 0);
-    CHECK(test_state_.reassembled.access_count_ == ++reassembled_access_count);
-    auto packet = std::move(test_state_.reassembled.queue.front());
-    test_state_.reassembled.queue.pop();
-    CHECK(VerifyData(Data(packet.get()), packet_size));
-  }
-}
-
-TEST_F(HciPacketFragmenterTest, OnePacket_ImmediateTooBig) {
-  const size_t packet_size = kMaxPacketSize + 1;
-  const std::vector<uint8_t> data = CreateData(packet_size);
-  reassemble_and_dispatch(AllocateL2capPacket(data.size(), data));
-
-  CHECK(partial_packets.size() == 0);
-  CHECK(test_state_.reassembled.access_count_ == 0);
-}
-
-TEST_F(HciPacketFragmenterTest, ThreePackets_Immediate) {
-  const size_t packet_size = 512;
-  const std::vector<uint8_t> data = CreateData(packet_size);
-  reassemble_and_dispatch(AllocateL2capPacket(data.size(), data));
-  reassemble_and_dispatch(AllocateL2capPacket(data.size(), data));
-  reassemble_and_dispatch(AllocateL2capPacket(data.size(), data));
-  CHECK(partial_packets.size() == 0);
-  CHECK(test_state_.reassembled.access_count_ == 3);
-}
-
-TEST_F(HciPacketFragmenterTest, OnePacket_SplitTwo) {
-  const std::vector<size_t> sizes(
-      kTypicalPacketSizes, kTypicalPacketSizes + kNumberOfTypicalPacketSizes);
-
-  int reassembled_access_count = 0;
-  for (auto packet_size : sizes) {
-    const std::vector<uint8_t> data = CreateData(packet_size);
-    const std::vector<uint8_t> part1(data.cbegin(),
-                                     data.cbegin() + packet_size / 2);
-    reassemble_and_dispatch(AllocateL2capPacket(data.size(), part1));
-
-    CHECK(partial_packets.size() == 1);
-    CHECK(test_state_.reassembled.access_count_ == reassembled_access_count);
-
-    const std::vector<uint8_t> part2(data.cbegin() + packet_size / 2,
-                                     data.cend());
-    reassemble_and_dispatch(AllocateL2capPacket(part2));
-
-    CHECK(partial_packets.size() == 0);
-    CHECK(test_state_.reassembled.access_count_ == ++reassembled_access_count);
-
-    auto packet = std::move(test_state_.reassembled.queue.front());
-    test_state_.reassembled.queue.pop();
-    CHECK(VerifyData(Data(packet.get()), packet_size));
-  }
-}
-
-TEST_F(HciPacketFragmenterTest, OnePacket_SplitALot) {
-  const size_t packet_size = 512;
-  const size_t stride = 2;
-
-  const std::vector<uint8_t> data = CreateData(packet_size);
-  const std::vector<uint8_t> first_part(data.cbegin(), data.cbegin() + stride);
-  reassemble_and_dispatch(AllocateL2capPacket(data.size(), first_part));
-  CHECK(partial_packets.size() == 1);
-
-  for (size_t i = 2; i < packet_size - stride; i += stride) {
-    const std::vector<uint8_t> middle_part(data.cbegin() + i,
-                                           data.cbegin() + i + stride);
-    reassemble_and_dispatch(AllocateL2capPacket(middle_part));
-  }
-  CHECK(partial_packets.size() == 1);
-  CHECK(test_state_.reassembled.access_count_ == 0);
-
-  const std::vector<uint8_t> last_part(data.cbegin() + packet_size - stride,
-                                       data.cend());
-  reassemble_and_dispatch(AllocateL2capPacket(last_part));
-
-  CHECK(partial_packets.size() == 0);
-  CHECK(test_state_.reassembled.access_count_ == 1);
-  auto packet = std::move(test_state_.reassembled.queue.front());
-  CHECK(VerifyData(Data(packet.get()), packet_size));
-}
-
-TEST_F(HciPacketFragmenterTest, TwoPacket_InvalidLength) {
-  const size_t packet_size = UINT16_MAX;
-  const std::vector<uint8_t> data = CreateData(packet_size);
-  const std::vector<uint8_t> first_part(data.cbegin(),
-                                        data.cbegin() + packet_size / 2);
-  reassemble_and_dispatch(AllocateL2capPacket(data.size(), first_part));
-
-  CHECK(partial_packets.size() == 0);
-  CHECK(test_state_.reassembled.access_count_ == 0);
-
-  const std::vector<uint8_t> second_part(data.cbegin() + packet_size / 2,
-                                         data.cend());
-  reassemble_and_dispatch(AllocateL2capPacket(second_part));
-
-  CHECK(partial_packets.size() == 0);
-  CHECK(test_state_.reassembled.access_count_ == 0);
-}
-
-TEST_F(HciPacketFragmenterTest, TwoPacket_HugeBogusSecond) {
-  const size_t packet_size = kMaxPacketSize;
-  const std::vector<uint8_t> data = CreateData(UINT16_MAX);
-  const std::vector<uint8_t> first_part(data.cbegin(),
-                                        data.cbegin() + packet_size - 1);
-  reassemble_and_dispatch(AllocateL2capPacket(packet_size, first_part));
-
-  CHECK(partial_packets.size() == 1);
-  CHECK(test_state_.reassembled.access_count_ == 0);
-
-  const std::vector<uint8_t> second_part(data.cbegin() + packet_size - 1,
-                                         data.cend());
-  reassemble_and_dispatch(AllocateL2capPacket(second_part));
-
-  CHECK(partial_packets.size() == 0);
-  CHECK(test_state_.reassembled.access_count_ == 1);
-}
diff --git a/system/hci/test/packet_fragmenter_test.cc b/system/hci/test/packet_fragmenter_test.cc
index f9efd4b..7ba0934 100644
--- a/system/hci/test/packet_fragmenter_test.cc
+++ b/system/hci/test/packet_fragmenter_test.cc
@@ -389,12 +389,6 @@
 UNEXPECTED_CALL;
 }
 
-STUB_FUNCTION(void, transmit_finished_callback,
-              (UNUSED_ATTR BT_HDR * packet,
-               UNUSED_ATTR bool sent_all_fragments))
-UNEXPECTED_CALL;
-}
-
 STUB_FUNCTION(uint16_t, get_acl_data_size_classic, (void))
 DURING(no_fragmentation, non_acl_passthrough_fragmentation, no_reassembly)
 return 42;
@@ -424,7 +418,6 @@
 static void reset_for(TEST_MODES_T next) {
   RESET_CALL_COUNT(fragmented_callback);
   RESET_CALL_COUNT(reassembled_callback);
-  RESET_CALL_COUNT(transmit_finished_callback);
   RESET_CALL_COUNT(get_acl_data_size_classic);
   RESET_CALL_COUNT(get_acl_data_size_ble);
   RESET_CALL_COUNT(get_iso_data_size);
@@ -443,7 +436,6 @@
 
     callbacks.fragmented = fragmented_callback;
     callbacks.reassembled = reassembled_callback;
-    callbacks.transmit_finished = transmit_finished_callback;
     controller.get_acl_data_size_classic = get_acl_data_size_classic;
     controller.get_acl_data_size_ble = get_acl_data_size_ble;
     controller.get_iso_data_size = get_iso_data_size;
@@ -461,25 +453,6 @@
   packet_fragmenter_callbacks_t callbacks;
 };
 
-TEST_F(PacketFragmenterTest, test_non_acl_passthrough_fragmentation) {
-  reset_for(non_acl_passthrough_fragmentation);
-  BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_CMD,
-                                                        sample_data);
-  fragmenter->fragment_and_dispatch(packet);
-
-  EXPECT_EQ(strlen(sample_data), data_size_sum);
-  EXPECT_CALL_COUNT(fragmented_callback, 1);
-}
-
-TEST_F(PacketFragmenterTest, test_non_acl_passthrough_reasseembly) {
-  reset_for(non_acl_passthrough_reassembly);
-  manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_EVT, 42,
-                                         sample_data);
-
-  EXPECT_EQ(strlen(sample_data), data_size_sum);
-  EXPECT_CALL_COUNT(reassembled_callback, 1);
-}
-
 TEST_F(PacketFragmenterTest, test_iso_fragment_necessary) {
   reset_for(iso_fragmentation);
   iso_has_ts = true;
diff --git a/system/main/shim/hci_layer.cc b/system/main/shim/hci_layer.cc
index 1780455..71ba464 100644
--- a/system/main/shim/hci_layer.cc
+++ b/system/main/shim/hci_layer.cc
@@ -267,17 +267,12 @@
 }  // namespace
 
 namespace cpp {
-bluetooth::common::BidiQueueEnd<bluetooth::hci::AclBuilder,
-                                bluetooth::hci::AclView>* hci_queue_end =
-    nullptr;
 bluetooth::common::BidiQueueEnd<bluetooth::hci::ScoBuilder,
                                 bluetooth::hci::ScoView>* hci_sco_queue_end =
     nullptr;
 bluetooth::common::BidiQueueEnd<bluetooth::hci::IsoBuilder,
                                 bluetooth::hci::IsoView>* hci_iso_queue_end =
     nullptr;
-static bluetooth::os::EnqueueBuffer<bluetooth::hci::AclBuilder>* pending_data =
-    nullptr;
 static bluetooth::os::EnqueueBuffer<bluetooth::hci::IsoBuilder>*
     pending_iso_data = nullptr;
 static bluetooth::os::EnqueueBuffer<bluetooth::hci::ScoBuilder>*
@@ -449,7 +444,7 @@
     return;
   }
   auto data = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_SCO, packet.get());
-  packet_fragmenter->reassemble_and_dispatch(data);
+  send_data_upwards.Run(FROM_HERE, data);
 }
 
 static void iso_data_callback() {
@@ -490,11 +485,6 @@
 }
 
 static void on_shutting_down() {
-  if (pending_data != nullptr) {
-    pending_data->Clear();
-    delete pending_data;
-    pending_data = nullptr;
-  }
   if (pending_sco_data != nullptr) {
     pending_sco_data->Clear();
     delete pending_sco_data;
@@ -505,25 +495,6 @@
     delete pending_iso_data;
     pending_iso_data = nullptr;
   }
-  if (hci_queue_end != nullptr) {
-    for (uint16_t event_code_raw = 0; event_code_raw < 0x100;
-         event_code_raw++) {
-      auto event_code = static_cast<bluetooth::hci::EventCode>(event_code_raw);
-      if (!is_valid_event_code(event_code)) {
-        continue;
-      }
-      if (event_already_registered_in_hci_layer(event_code)) {
-        continue;
-      } else if (event_already_registered_in_le_advertising_manager(
-                     event_code)) {
-        continue;
-      } else if (event_already_registered_in_le_scanning_manager(event_code)) {
-        continue;
-      }
-      bluetooth::shim::GetHciLayer()->UnregisterEventHandler(event_code);
-    }
-    hci_queue_end = nullptr;
-  }
   if (hci_sco_queue_end != nullptr) {
     hci_sco_queue_end->UnregisterDequeue();
     hci_sco_queue_end = nullptr;
@@ -551,24 +522,6 @@
   cpp::transmit_command(command, complete_callback, status_callback, context);
 }
 
-static void command_complete_callback(BT_HDR* response, void* context) {
-  auto future = static_cast<future_t*>(context);
-  future_ready(future, response);
-}
-
-static void command_status_callback(uint8_t status, BT_HDR* command,
-                                    void* context) {
-  LOG_ALWAYS_FATAL(
-      "transmit_command_futured should only send command complete opcode");
-}
-
-static future_t* transmit_command_futured(const BT_HDR* command) {
-  future_t* future = future_new();
-  transmit_command(command, command_complete_callback, command_status_callback,
-                   future);
-  return future;
-}
-
 static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished) {
   uint16_t event = packet->event & MSG_EVT_MASK;
 
@@ -577,11 +530,7 @@
   bool free_after_transmit =
       event != MSG_STACK_TO_HC_HCI_CMD && send_transmit_finished;
 
-  if (event == MSG_STACK_TO_HC_HCI_SCO) {
-    const uint8_t* stream = packet->data + packet->offset;
-    size_t length = packet->len;
-    cpp::transmit_sco_fragment(stream, length);
-  } else if (event == MSG_STACK_TO_HC_HCI_ISO) {
+  if (event == MSG_STACK_TO_HC_HCI_ISO) {
     const uint8_t* stream = packet->data + packet->offset;
     size_t length = packet->len;
     cpp::transmit_iso_fragment(stream, length);
@@ -592,34 +541,28 @@
   }
 }
 static void dispatch_reassembled(BT_HDR* packet) {
-  // Events should already have been dispatched before this point
-  CHECK((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT);
+  // Only ISO should be handled here
+  CHECK((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ISO);
   CHECK(!send_data_upwards.is_null());
   send_data_upwards.Run(FROM_HERE, packet);
 }
-static void fragmenter_transmit_finished(BT_HDR* packet,
-                                         bool all_fragments_sent) {
-  if (all_fragments_sent) {
-    osi_free(packet);
-  } else {
-    // This is kind of a weird case, since we're dispatching a partially sent
-    // packet up to a higher layer.
-    // TODO(zachoverflow): rework upper layer so this isn't necessary.
-    send_data_upwards.Run(FROM_HERE, packet);
-  }
-}
 
 static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
-    transmit_fragment, dispatch_reassembled, fragmenter_transmit_finished};
+    transmit_fragment, dispatch_reassembled};
 
 static void transmit_downward(uint16_t type, void* raw_data) {
+  if (type == BT_EVT_TO_LM_HCI_SCO) {
+    BT_HDR* event = static_cast<BT_HDR*>(raw_data);
+    bluetooth::shim::GetGdShimHandler()->Call(
+        cpp::transmit_sco_fragment, event->data + event->offset, event->len);
+    return;
+  }
   bluetooth::shim::GetGdShimHandler()->Call(
       packet_fragmenter->fragment_and_dispatch, static_cast<BT_HDR*>(raw_data));
 }
 
 static hci_t interface = {.set_data_cb = set_data_cb,
                           .transmit_command = transmit_command,
-                          .transmit_command_futured = transmit_command_futured,
                           .transmit_downward = transmit_downward};
 
 const hci_t* bluetooth::shim::hci_layer_get_interface() {
diff --git a/system/stack/a2dp/a2dp_api.cc b/system/stack/a2dp/a2dp_api.cc
index 73df2b1b..e00a5a5 100644
--- a/system/stack/a2dp/a2dp_api.cc
+++ b/system/stack/a2dp/a2dp_api.cc
@@ -36,9 +36,12 @@
 #include "osi/include/log.h"
 #include "sdpdefs.h"
 #include "stack/include/bt_types.h"
+#include "stack/include/sdp_api.h"
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 using bluetooth::Uuid;
 
 /*****************************************************************************
@@ -80,7 +83,7 @@
     /* loop through all records we found */
     do {
       /* get next record; if none found, we're done */
-      if ((p_rec = SDP_FindServiceInDb(
+      if ((p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
                a2dp_cb.find.p_db, a2dp_cb.find.service_uuid, p_rec)) == NULL) {
         break;
       }
@@ -88,27 +91,28 @@
       peer_address = p_rec->remote_bd_addr;
 
       /* get service name */
-      if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) !=
-          NULL) {
+      if ((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+               p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
         a2dp_svc.p_service_name = (char*)p_attr->attr_value.v.array;
         a2dp_svc.service_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
       }
 
       /* get provider name */
-      if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PROVIDER_NAME)) !=
-          NULL) {
+      if ((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+               p_rec, ATTR_ID_PROVIDER_NAME)) != NULL) {
         a2dp_svc.p_provider_name = (char*)p_attr->attr_value.v.array;
         a2dp_svc.provider_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
       }
 
       /* get supported features */
-      if ((p_attr = SDP_FindAttributeInRec(
+      if ((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
                p_rec, ATTR_ID_SUPPORTED_FEATURES)) != NULL) {
         a2dp_svc.features = p_attr->attr_value.v.u16;
       }
 
       /* get AVDTP version */
-      if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_AVDTP, &elem)) {
+      if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+              p_rec, UUID_PROTOCOL_AVDTP, &elem)) {
         a2dp_svc.avdt_version = elem.params[0];
         LOG_VERBOSE("avdt_version: 0x%x", a2dp_svc.avdt_version);
       }
@@ -190,7 +194,8 @@
     return A2DP_INVALID_PARAMS;
 
   /* add service class id list */
-  result &= SDP_AddServiceClassIdList(sdp_handle, 1, &service_uuid);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
+      sdp_handle, 1, &service_uuid);
 
   memset((void*)proto_list, 0,
          A2DP_NUM_PROTO_ELEMS * sizeof(tSDP_PROTOCOL_ELEM));
@@ -203,38 +208,40 @@
   proto_list[1].num_params = 1;
   proto_list[1].params[0] = a2dp_cb.avdt_sdp_ver;
 
-  result &= SDP_AddProtocolList(sdp_handle, A2DP_NUM_PROTO_ELEMS, proto_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(
+      sdp_handle, A2DP_NUM_PROTO_ELEMS, proto_list);
 
   /* add profile descriptor list   */
-  result &= SDP_AddProfileDescriptorList(
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
       sdp_handle, UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION, A2DP_VERSION);
 
   /* add supported feature */
   if (features != 0) {
     p = temp;
     UINT16_TO_BE_STREAM(p, features);
-    result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES,
-                               UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, (uint32_t)2,
+        (uint8_t*)temp);
   }
 
   /* add provider name */
   if (p_provider_name != NULL) {
-    result &= SDP_AddAttribute(
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
         sdp_handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE,
         (uint32_t)(strlen(p_provider_name) + 1), (uint8_t*)p_provider_name);
   }
 
   /* add service name */
   if (p_service_name != NULL) {
-    result &= SDP_AddAttribute(
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
         sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
         (uint32_t)(strlen(p_service_name) + 1), (uint8_t*)p_service_name);
   }
 
   /* add browse group list */
   browse_list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
-  result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1,
-                                browse_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
+      sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
 
   return (result ? A2DP_SUCCESS : A2DP_FAIL);
 }
@@ -301,8 +308,9 @@
   a2dp_cb.find.p_db = (tSDP_DISCOVERY_DB*)osi_malloc(p_db->db_len);
   Uuid uuid_list = Uuid::From16Bit(service_uuid);
 
-  if (!SDP_InitDiscoveryDb(a2dp_cb.find.p_db, p_db->db_len, 1, &uuid_list,
-                           p_db->num_attr, p_db->p_attrs)) {
+  if (!get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+          a2dp_cb.find.p_db, p_db->db_len, 1, &uuid_list, p_db->num_attr,
+          p_db->p_attrs)) {
     osi_free_and_reset((void**)&a2dp_cb.find.p_db);
     LOG_ERROR("Unable to initialize SDP discovery for peer %s UUID 0x%04X",
               ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid);
@@ -314,8 +322,8 @@
   a2dp_cb.find.p_cback = p_cback;
 
   /* perform service search */
-  if (!SDP_ServiceSearchAttributeRequest(bd_addr, a2dp_cb.find.p_db,
-                                         a2dp_sdp_cback)) {
+  if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest(
+          bd_addr, a2dp_cb.find.p_db, a2dp_sdp_cback)) {
     a2dp_cb.find.service_uuid = 0;
     a2dp_cb.find.p_cback = NULL;
     osi_free_and_reset((void**)&a2dp_cb.find.p_db);
diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc
index f69c3f4..02716d0 100644
--- a/system/stack/acl/btm_acl.cc
+++ b/system/stack/acl/btm_acl.cc
@@ -148,7 +148,7 @@
      HCI_PKT_TYPES_MASK_NO_2_DH3 | HCI_PKT_TYPES_MASK_NO_3_DH3 |
      HCI_PKT_TYPES_MASK_NO_2_DH5 | HCI_PKT_TYPES_MASK_NO_3_DH5);
 
-inline bool IsEprAvailable(const tACL_CONN& p_acl) {
+static bool IsEprAvailable(const tACL_CONN& p_acl) {
   if (!p_acl.peer_lmp_feature_valid[0]) {
     LOG_WARN("Checking incomplete feature page read");
     return false;
diff --git a/system/stack/avrc/avrc_sdp.cc b/system/stack/avrc/avrc_sdp.cc
index 753f8d2..a393346 100644
--- a/system/stack/avrc/avrc_sdp.cc
+++ b/system/stack/avrc/avrc_sdp.cc
@@ -25,9 +25,12 @@
 
 #include "avrc_api.h"
 #include "avrc_int.h"
+#include "stack/include/sdp_api.h"
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 using bluetooth::Uuid;
 
 /*****************************************************************************
@@ -129,8 +132,8 @@
   }
 
   Uuid uuid_list = Uuid::From16Bit(service_uuid);
-  result = SDP_InitDiscoveryDb(p_db->p_db, p_db->db_len, 1, &uuid_list,
-                               p_db->num_attr, p_db->p_attrs);
+  result = get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+      p_db->p_db, p_db->db_len, 1, &uuid_list, p_db->num_attr, p_db->p_attrs);
 
   if (result) {
     /* store service_uuid and discovery db pointer */
@@ -140,7 +143,8 @@
 
     /* perform service search */
     result =
-        SDP_ServiceSearchAttributeRequest(bd_addr, p_db->p_db, avrc_sdp_cback);
+        get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest(
+            bd_addr, p_db->p_db, avrc_sdp_cback);
 
     if (!result) {
       AVRC_TRACE_ERROR("%s: Failed to init SDP for peer %s", __func__,
@@ -158,7 +162,8 @@
  *
  * Description      This function is called to build an AVRCP SDP record.
  *                  Prior to calling this function the application must
- *                  call SDP_CreateRecord() to create an SDP record.
+ *                  call get_legacy_stack_sdp_api()->handle.SDP_CreateRecord()
+ *                  to create an SDP record.
  *
  *                  Input Parameters:
  *                      service_uuid:  Indicates
@@ -166,16 +171,17 @@
  *                                     or CT(UUID_SERVCLASS_AV_REMOTE_CONTROL)
  *
  *                      p_service_name:  Pointer to a null-terminated character
- *                      string containing the service name.
+ *                                       string containing the service name.
  *                      If service name is not used set this to NULL.
  *
  *                      p_provider_name:  Pointer to a null-terminated character
- *                      string containing the provider name.
+ *                                        string containing the provider name.
  *                      If provider name is not used set this to NULL.
  *
  *                      categories:  Supported categories.
  *
- *                      sdp_handle:  SDP handle returned by SDP_CreateRecord().
+ *                      sdp_handle:  SDP handle returned by
+ *                      get_legacy_stack_sdp_api()->handle.SDP_CreateRecord().
  *
  *                      browse_supported:  browse support info.
  *
@@ -219,7 +225,8 @@
     class_list[1] = UUID_SERVCLASS_AV_REM_CTRL_CONTROL;
     count = 2;
   }
-  result &= SDP_AddServiceClassIdList(sdp_handle, count, class_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
+      sdp_handle, count, class_list);
 
   uint16_t protocol_reported_version;
   /* AVRCP versions 1.3 to 1.5 report (version - 1) in the protocol
@@ -243,8 +250,8 @@
     avrc_proto_desc_list[index].params[0] = protocol_reported_version;
     avrc_proto_desc_list[index].params[1] = 0;
   }
-  result &= SDP_AddProtocolList(sdp_handle, AVRC_NUM_PROTO_ELEMS,
-                                &avrc_proto_desc_list[0]);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(
+      sdp_handle, AVRC_NUM_PROTO_ELEMS, &avrc_proto_desc_list[0]);
 
   /* additional protocal descriptor, required only for version > 1.3 */
   if (profile_version > AVRC_REV_1_3) {
@@ -296,38 +303,39 @@
     if (num_additional_protocols > 0) {
       AVRC_TRACE_API("%s: Add %d additonal protocol descriptor lists",
                      __func__, num_additional_protocols);
-      result &= SDP_AddAdditionProtoLists(sdp_handle, num_additional_protocols,
-                                          avrc_add_proto_desc_lists);
+      result &= get_legacy_stack_sdp_api()->handle.SDP_AddAdditionProtoLists(
+          sdp_handle, num_additional_protocols, avrc_add_proto_desc_lists);
     }
   }
   /* add profile descriptor list   */
-  result &= SDP_AddProfileDescriptorList(
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
       sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, profile_version);
 
   /* add supported categories */
   p = temp;
   UINT16_TO_BE_STREAM(p, categories);
-  result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES,
-                             UINT_DESC_TYPE, (uint32_t)2, (uint8_t*)temp);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+      sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE, (uint32_t)2,
+      (uint8_t*)temp);
 
   /* add provider name */
   if (p_provider_name != NULL) {
-    result &= SDP_AddAttribute(
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
         sdp_handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE,
         (uint32_t)(strlen(p_provider_name) + 1), (uint8_t*)p_provider_name);
   }
 
   /* add service name */
   if (p_service_name != NULL) {
-    result &= SDP_AddAttribute(
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
         sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
         (uint32_t)(strlen(p_service_name) + 1), (uint8_t*)p_service_name);
   }
 
   /* add browse group list */
   browse_list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
-  result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1,
-                                browse_list);
+  result &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
+      sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);
 
   return (result ? AVRC_SUCCESS : AVRC_FAIL);
 }
@@ -347,7 +355,7 @@
  *******************************************************************************/
 uint16_t AVRC_RemoveRecord(uint32_t sdp_handle) {
   AVRC_TRACE_API("%s: remove AVRCP SDP record", __func__);
-  bool result = SDP_DeleteRecord(sdp_handle);
+  bool result = get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle);
   return (result ? AVRC_SUCCESS : AVRC_FAIL);
 }
 
diff --git a/system/stack/btm/btm_sco.cc b/system/stack/btm/btm_sco.cc
index 6668e31..475c977 100644
--- a/system/stack/btm/btm_sco.cc
+++ b/system/stack/btm/btm_sco.cc
@@ -36,6 +36,8 @@
 #include "device/include/device_iot_config.h"
 #include "embdrv/sbc/decoder/include/oi_codec_sbc.h"
 #include "embdrv/sbc/decoder/include/oi_status.h"
+#include "hci/include/hci_layer.h"
+#include "main/shim/hci_layer.h"
 #include "osi/include/allocator.h"
 #include "osi/include/log.h"
 #include "osi/include/osi.h"
@@ -379,7 +381,12 @@
     return;
   }
   BT_HDR* packet = btm_sco_make_packet(std::move(data), active_sco->hci_handle);
-  bte_main_hci_send(packet, BT_EVT_TO_LM_HCI_SCO);
+
+  auto hci = bluetooth::shim::hci_layer_get_interface();
+
+  packet->event = BT_EVT_TO_LM_HCI_SCO;
+
+  hci->transmit_downward(packet->event, packet);
 }
 
 // Build a SCO packet from uint8
diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc
index b286ff4..04ffffc 100644
--- a/system/stack/btm/btm_sec.cc
+++ b/system/stack/btm/btm_sec.cc
@@ -116,7 +116,6 @@
                                                tHCI_STATUS reason,
                                                uint16_t conn_handle,
                                                std::string comment);
-tBTM_SEC_DEV_REC* btm_sec_find_dev_by_sec_state(uint8_t state);
 
 static bool btm_dev_authenticated(tBTM_SEC_DEV_REC* p_dev_rec);
 static bool btm_dev_encrypted(tBTM_SEC_DEV_REC* p_dev_rec);
@@ -232,6 +231,23 @@
 
 /*******************************************************************************
  *
+ * Function         btm_sec_find_dev_by_sec_state
+ *
+ * Description      Look for the record in the device database for the device
+ *                  which is being authenticated or encrypted
+ *
+ * Returns          Pointer to the record or NULL
+ *
+ ******************************************************************************/
+static tBTM_SEC_DEV_REC* btm_sec_find_dev_by_sec_state(uint8_t state) {
+  list_node_t* n = list_foreach(btm_cb.sec_dev_rec, is_sec_state_equal, &state);
+  if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n));
+
+  return nullptr;
+}
+
+/*******************************************************************************
+ *
  * Function         BTM_SecRegister
  *
  * Description      Application manager calls this function to register for
@@ -4683,23 +4699,6 @@
 
 /*******************************************************************************
  *
- * Function         btm_sec_find_dev_by_sec_state
- *
- * Description      Look for the record in the device database for the device
- *                  which is being authenticated or encrypted
- *
- * Returns          Pointer to the record or NULL
- *
- ******************************************************************************/
-tBTM_SEC_DEV_REC* btm_sec_find_dev_by_sec_state(uint8_t state) {
-  list_node_t* n = list_foreach(btm_cb.sec_dev_rec, is_sec_state_equal, &state);
-  if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n));
-
-  return NULL;
-}
-
-/*******************************************************************************
- *
  * Function         btm_sec_change_pairing_state
  *
  * Description      This function is called to change pairing state
diff --git a/system/stack/btm/btm_sec.h b/system/stack/btm/btm_sec.h
index c1c80cd..f17a3e7 100644
--- a/system/stack/btm/btm_sec.h
+++ b/system/stack/btm/btm_sec.h
@@ -40,8 +40,6 @@
  ******************************************************************************/
 tBTM_SEC_SERV_REC* btm_sec_find_first_serv(bool is_originator, uint16_t psm);
 
-tBTM_SEC_DEV_REC* btm_sec_find_dev_by_sec_state(uint8_t state);
-
 /*******************************************************************************
  *
  * Function         BTM_SecRegister
@@ -715,18 +713,6 @@
 
 /*******************************************************************************
  *
- * Function         btm_sec_find_dev_by_sec_state
- *
- * Description      Look for the record in the device database for the device
- *                  which is being authenticated or encrypted
- *
- * Returns          Pointer to the record or NULL
- *
- ******************************************************************************/
-tBTM_SEC_DEV_REC* btm_sec_find_dev_by_sec_state(uint8_t state);
-
-/*******************************************************************************
- *
  * Function         btm_sec_dev_rec_cback_event
  *
  * Description      This function calls the callback function with the given
diff --git a/system/stack/btm/neighbor_inquiry.h b/system/stack/btm/neighbor_inquiry.h
index 2ef6e82..5e9f35a 100644
--- a/system/stack/btm/neighbor_inquiry.h
+++ b/system/stack/btm/neighbor_inquiry.h
@@ -285,12 +285,6 @@
 
 } tBTM_INQUIRY_VAR_ST;
 
-typedef union /* contains the inquiry filter condition */
-{
-  RawAddress bdaddr_cond;
-  tBTM_COD_COND cod_cond;
-} tBTM_INQ_FILT_COND;
-
 #define BTM_INQ_RESULT_BR 0x01
 #define BTM_INQ_RESULT_BLE 0x02
 
diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc
index da76a85..12d8122 100644
--- a/system/stack/gatt/gatt_api.cc
+++ b/system/stack/gatt/gatt_api.cc
@@ -48,6 +48,8 @@
 #include "types/bt_transport.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 using bluetooth::Uuid;
 
 bool BTM_BackgroundConnectAddressKnown(const RawAddress& address);
@@ -418,7 +420,7 @@
   }
 
   if (it->sdp_handle) {
-    SDP_DeleteRecord(it->sdp_handle);
+    get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(it->sdp_handle);
   }
 
   gatt_cb.srv_list_info->erase(it);
diff --git a/system/stack/gatt/gatt_utils.cc b/system/stack/gatt/gatt_utils.cc
index 7b45eea..3b9bca1 100644
--- a/system/stack/gatt/gatt_utils.cc
+++ b/system/stack/gatt/gatt_utils.cc
@@ -46,6 +46,8 @@
 
 uint8_t btm_ble_read_sec_key_size(const RawAddress& bd_addr);
 
+using namespace bluetooth::legacy::stack::sdp;
+
 using base::StringPrintf;
 using bluetooth::Uuid;
 using bluetooth::eatt::EattExtension;
@@ -881,13 +883,14 @@
   VLOG(1) << __func__
           << StringPrintf(" s_hdl=0x%x  s_hdl=0x%x", start_hdl, end_hdl);
 
-  uint32_t sdp_handle = SDP_CreateRecord();
+  uint32_t sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
   if (sdp_handle == 0) return 0;
 
   switch (uuid.GetShortestRepresentationSize()) {
     case Uuid::kNumBytes16: {
       uint16_t tmp = uuid.As16Bit();
-      SDP_AddServiceClassIdList(sdp_handle, 1, &tmp);
+      get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle,
+                                                                   1, &tmp);
       break;
     }
 
@@ -895,16 +898,18 @@
       UINT8_TO_BE_STREAM(p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
       uint32_t tmp = uuid.As32Bit();
       UINT32_TO_BE_STREAM(p, tmp);
-      SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST,
-                       DATA_ELE_SEQ_DESC_TYPE, (uint32_t)(p - buff), buff);
+      get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+          sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
+          (uint32_t)(p - buff), buff);
       break;
     }
 
     case Uuid::kNumBytes128:
       UINT8_TO_BE_STREAM(p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
       ARRAY_TO_BE_STREAM(p, uuid.To128BitBE().data(), (int)Uuid::kNumBytes128);
-      SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST,
-                       DATA_ELE_SEQ_DESC_TYPE, (uint32_t)(p - buff), buff);
+      get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+          sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
+          (uint32_t)(p - buff), buff);
       break;
   }
 
@@ -918,11 +923,13 @@
   proto_elem_list[1].params[0] = start_hdl;
   proto_elem_list[1].params[1] = end_hdl;
 
-  SDP_AddProtocolList(sdp_handle, 2, proto_elem_list);
+  get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(sdp_handle, 2,
+                                                         proto_elem_list);
 
   /* Make the service browseable */
   uint16_t list = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
-  SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
+  get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
+      sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list);
 
   return (sdp_handle);
 }
diff --git a/system/stack/hid/hidd_api.cc b/system/stack/hid/hidd_api.cc
index 4281ac8..503bfdc 100644
--- a/system/stack/hid/hidd_api.cc
+++ b/system/stack/hid/hidd_api.cc
@@ -36,10 +36,13 @@
 #include "osi/include/allocator.h"
 #include "stack/btm/btm_sec.h"
 #include "stack/include/bt_types.h"
+#include "stack/include/sdp_api.h"
 #include "stack/include/stack_metrics_logging.h"
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 tHID_DEV_CTB hd_cb;
 
 /*******************************************************************************
@@ -165,7 +168,8 @@
   // Service Class ID List
   if (result) {
     uint16_t uuid = UUID_SERVCLASS_HUMAN_INTERFACE;
-    result &= SDP_AddServiceClassIdList(handle, 1, &uuid);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
+        handle, 1, &uuid);
   }
 
   // Protocol Descriptor List
@@ -179,14 +183,15 @@
     proto_list[1].protocol_uuid = UUID_PROTOCOL_HIDP;
     proto_list[1].num_params = 0;
 
-    result &= SDP_AddProtocolList(handle, 2, proto_list);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(
+        handle, 2, proto_list);
   }
 
   // Language Base Attribute ID List
   if (result) {
-    result &= SDP_AddLanguageBaseAttrIDList(handle, LANG_ID_CODE_ENGLISH,
-                                            LANG_ID_CHAR_ENCODE_UTF8,
-                                            LANGUAGE_BASE_ID);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddLanguageBaseAttrIDList(
+        handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8,
+        LANGUAGE_BASE_ID);
   }
 
   // Additional Protocol Descriptor List
@@ -200,7 +205,8 @@
     add_proto_list.list_elem[1].protocol_uuid = UUID_PROTOCOL_HIDP;
     add_proto_list.list_elem[1].num_params = 0;
 
-    result &= SDP_AddAdditionProtoLists(handle, 1, &add_proto_list);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAdditionProtoLists(
+        handle, 1, &add_proto_list);
   }
 
   // Service Name (O)
@@ -211,16 +217,17 @@
     const char* srv_desc = p_description;
     const char* provider_name = p_provider;
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
-                               strlen(srv_name) + 1, (uint8_t*)srv_name);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, strlen(srv_name) + 1,
+        (uint8_t*)srv_name);
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_SERVICE_DESCRIPTION,
-                               TEXT_STR_DESC_TYPE, strlen(srv_desc) + 1,
-                               (uint8_t*)srv_desc);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE,
+        strlen(srv_desc) + 1, (uint8_t*)srv_desc);
 
-    result &=
-        SDP_AddAttribute(handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE,
-                         strlen(provider_name) + 1, (uint8_t*)provider_name);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE,
+        strlen(provider_name) + 1, (uint8_t*)provider_name);
   }
 
   // Bluetooth Profile Descriptor List
@@ -228,7 +235,8 @@
     const uint16_t profile_uuid = UUID_SERVCLASS_HUMAN_INTERFACE;
     const uint16_t version = 0x0100;
 
-    result &= SDP_AddProfileDescriptorList(handle, profile_uuid, version);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
+        handle, profile_uuid, version);
   }
 
   // HID Parser Version
@@ -245,25 +253,29 @@
 
     p = (uint8_t*)&temp;
     UINT16_TO_BE_STREAM(p, rel_num);
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_DEVICE_RELNUM,
-                               UINT_DESC_TYPE, 2, (uint8_t*)&temp);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_DEVICE_RELNUM, UINT_DESC_TYPE, 2, (uint8_t*)&temp);
 
     p = (uint8_t*)&temp;
     UINT16_TO_BE_STREAM(p, parser_version);
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_PARSER_VERSION,
-                               UINT_DESC_TYPE, 2, (uint8_t*)&temp);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_PARSER_VERSION, UINT_DESC_TYPE, 2, (uint8_t*)&temp);
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_DEVICE_SUBCLASS,
-                               UINT_DESC_TYPE, 1, (uint8_t*)&dev_subclass);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_DEVICE_SUBCLASS, UINT_DESC_TYPE, 1,
+        (uint8_t*)&dev_subclass);
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_COUNTRY_CODE, UINT_DESC_TYPE,
-                               1, (uint8_t*)&country_code);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_COUNTRY_CODE, UINT_DESC_TYPE, 1,
+        (uint8_t*)&country_code);
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_VIRTUAL_CABLE,
-                               BOOLEAN_DESC_TYPE, 1, (uint8_t*)&bool_true);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_VIRTUAL_CABLE, BOOLEAN_DESC_TYPE, 1,
+        (uint8_t*)&bool_true);
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_RECONNECT_INITIATE,
-                               BOOLEAN_DESC_TYPE, 1, (uint8_t*)&bool_true);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_RECONNECT_INITIATE, BOOLEAN_DESC_TYPE, 1,
+        (uint8_t*)&bool_true);
 
     {
       static uint8_t cdt = 0x22;
@@ -305,8 +317,9 @@
       UINT8_TO_BE_STREAM(p, desc_len);
       ARRAY_TO_BE_STREAM(p, p_desc_data, (int)desc_len);
 
-      result &= SDP_AddAttribute(handle, ATTR_ID_HID_DESCRIPTOR_LIST,
-                                 DATA_ELE_SEQ_DESC_TYPE, p - p_buf, p_buf);
+      result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+          handle, ATTR_ID_HID_DESCRIPTOR_LIST, DATA_ELE_SEQ_DESC_TYPE,
+          p - p_buf, p_buf);
 
       osi_free(p_buf);
     }
@@ -322,33 +335,38 @@
       UINT16_TO_BE_STREAM(p, lang_english);
       UINT8_TO_BE_STREAM(p, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
       UINT16_TO_BE_STREAM(p, LANGUAGE_BASE_ID);
-      result &=
-          SDP_AddAttribute(handle, ATTR_ID_HID_LANGUAGE_ID_BASE,
-                           DATA_ELE_SEQ_DESC_TYPE, p - lang_buf, lang_buf);
+      result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+          handle, ATTR_ID_HID_LANGUAGE_ID_BASE, DATA_ELE_SEQ_DESC_TYPE,
+          p - lang_buf, lang_buf);
     }
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_BATTERY_POWER,
-                               BOOLEAN_DESC_TYPE, 1, (uint8_t*)&bool_true);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_BATTERY_POWER, BOOLEAN_DESC_TYPE, 1,
+        (uint8_t*)&bool_true);
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_REMOTE_WAKE,
-                               BOOLEAN_DESC_TYPE, 1, (uint8_t*)&bool_false);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_REMOTE_WAKE, BOOLEAN_DESC_TYPE, 1,
+        (uint8_t*)&bool_false);
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_NORMALLY_CONNECTABLE,
-                               BOOLEAN_DESC_TYPE, 1, (uint8_t*)&bool_true);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_NORMALLY_CONNECTABLE, BOOLEAN_DESC_TYPE, 1,
+        (uint8_t*)&bool_true);
 
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_BOOT_DEVICE,
-                               BOOLEAN_DESC_TYPE, 1, (uint8_t*)&bool_true);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_BOOT_DEVICE, BOOLEAN_DESC_TYPE, 1,
+        (uint8_t*)&bool_true);
 
     p = (uint8_t*)&temp;
     UINT16_TO_BE_STREAM(p, prof_ver);
-    result &= SDP_AddAttribute(handle, ATTR_ID_HID_PROFILE_VERSION,
-                               UINT_DESC_TYPE, 2, (uint8_t*)&temp);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        handle, ATTR_ID_HID_PROFILE_VERSION, UINT_DESC_TYPE, 2,
+        (uint8_t*)&temp);
   }
 
   if (result) {
     uint16_t browse_group = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
-    result &= SDP_AddUuidSequence(handle, ATTR_ID_BROWSE_GROUP_LIST, 1,
-                                  &browse_group);
+    result &= get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
+        handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_group);
   }
 
   if (!result) {
diff --git a/system/stack/hid/hidh_api.cc b/system/stack/hid/hidh_api.cc
index 3cad623..be26c70 100644
--- a/system/stack/hid/hidh_api.cc
+++ b/system/stack/hid/hidh_api.cc
@@ -41,6 +41,7 @@
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
 using bluetooth::Uuid;
 
 tHID_HOST_CTB hh_cb;
@@ -67,9 +68,11 @@
 
   hh_cb.p_sdp_db = p_db;
   Uuid uuid_list = Uuid::From16Bit(UUID_SERVCLASS_HUMAN_INTERFACE);
-  SDP_InitDiscoveryDb(p_db, db_len, 1, &uuid_list, 0, NULL);
+  get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(p_db, db_len, 1,
+                                                          &uuid_list, 0, NULL);
 
-  if (SDP_ServiceSearchRequest(addr, p_db, hidh_search_callback)) {
+  if (get_legacy_stack_sdp_api()->service.SDP_ServiceSearchRequest(
+          addr, p_db, hidh_search_callback)) {
     hh_cb.sdp_cback = sdp_cback;
     hh_cb.sdp_busy = true;
     return HID_SUCCESS;
@@ -86,7 +89,8 @@
   tSDP_DISC_ATTR* p_attr;
   uint16_t name_len;
 
-  p_attr = SDP_FindAttributeInRec(p_rec, attr_id);
+  p_attr =
+      get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, attr_id);
   if (p_attr != NULL) {
     name_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
     if (name_len < max_len) {
@@ -116,7 +120,8 @@
   }
 
   Uuid hid_uuid = Uuid::From16Bit(UUID_SERVCLASS_HUMAN_INTERFACE);
-  p_rec = SDP_FindServiceUUIDInDb(p_db, hid_uuid, NULL);
+  p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceUUIDInDb(p_db, hid_uuid,
+                                                                 NULL);
   if (p_rec == NULL) {
     hh_cb.sdp_cback(HID_SDP_NO_SERV_UUID, 0, NULL);
     return;
@@ -125,8 +130,8 @@
   memset(&hh_cb.sdp_rec, 0, sizeof(tHID_DEV_SDP_INFO));
 
   /* First, verify the mandatory fields we care about */
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_DESCRIPTOR_LIST)) ==
-       NULL) ||
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_DESCRIPTOR_LIST)) == NULL) ||
       (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) ||
       ((p_subattr1 = p_attr->attr_value.v.p_sub_attr) == NULL) ||
       (SDP_DISC_ATTR_TYPE(p_subattr1->attr_len_type) !=
@@ -142,38 +147,38 @@
   if (p_nvi->dscp_info.dl_len != 0)
     p_nvi->dscp_info.dsc_list = (uint8_t*)&p_repdesc->attr_value;
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_VIRTUAL_CABLE)) !=
-       NULL) &&
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_VIRTUAL_CABLE)) != NULL) &&
       (p_attr->attr_value.v.u8)) {
     attr_mask |= HID_VIRTUAL_CABLE;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
             p_rec, ATTR_ID_HID_RECONNECT_INITIATE)) != NULL) &&
       (p_attr->attr_value.v.u8)) {
     attr_mask |= HID_RECONN_INIT;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
             p_rec, ATTR_ID_HID_NORMALLY_CONNECTABLE)) != NULL) &&
       (p_attr->attr_value.v.u8)) {
     attr_mask |= HID_NORMALLY_CONNECTABLE;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_SDP_DISABLE)) !=
-       NULL) &&
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_SDP_DISABLE)) != NULL) &&
       (p_attr->attr_value.v.u8)) {
     attr_mask |= HID_SDP_DISABLE;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_BATTERY_POWER)) !=
-       NULL) &&
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_BATTERY_POWER)) != NULL) &&
       (p_attr->attr_value.v.u8)) {
     attr_mask |= HID_BATTERY_POWER;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_REMOTE_WAKE)) !=
-       NULL) &&
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_REMOTE_WAKE)) != NULL) &&
       (p_attr->attr_value.v.u8)) {
     attr_mask |= HID_REMOTE_WAKE;
   }
@@ -185,40 +190,40 @@
   hidh_get_str_attr(p_rec, ATTR_ID_PROVIDER_NAME, HID_MAX_PROV_NAME_LEN,
                     p_nvi->prov_name);
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_DEVICE_RELNUM)) !=
-       NULL)) {
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_DEVICE_RELNUM)) != NULL)) {
     p_nvi->rel_num = p_attr->attr_value.v.u16;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_COUNTRY_CODE)) !=
-       NULL)) {
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_COUNTRY_CODE)) != NULL)) {
     p_nvi->ctry_code = p_attr->attr_value.v.u8;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_DEVICE_SUBCLASS)) !=
-       NULL)) {
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_DEVICE_SUBCLASS)) != NULL)) {
     p_nvi->sub_class = p_attr->attr_value.v.u8;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_PARSER_VERSION)) !=
-       NULL)) {
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_PARSER_VERSION)) != NULL)) {
     p_nvi->hpars_ver = p_attr->attr_value.v.u16;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
             p_rec, ATTR_ID_HID_LINK_SUPERVISION_TO)) != NULL)) {
     attr_mask |= HID_SUP_TOUT_AVLBL;
     p_nvi->sup_timeout = p_attr->attr_value.v.u16;
   }
 
-  if (((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HID_SSR_HOST_MAX_LAT)) !=
-       NULL)) {
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+            p_rec, ATTR_ID_HID_SSR_HOST_MAX_LAT)) != NULL)) {
     attr_mask |= HID_SSR_MAX_LATENCY;
     p_nvi->ssr_max_latency = p_attr->attr_value.v.u16;
   } else
     p_nvi->ssr_max_latency = HID_SSR_PARAM_INVALID;
 
-  if (((p_attr = SDP_FindAttributeInRec(
+  if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
             p_rec, ATTR_ID_HID_SSR_HOST_MIN_TOUT)) != NULL)) {
     attr_mask |= HID_SSR_MIN_TOUT;
     p_nvi->ssr_min_tout = p_attr->attr_value.v.u16;
diff --git a/system/stack/include/bt_dev_class.h b/system/stack/include/bt_dev_class.h
index b19c7a0..a0d182d 100644
--- a/system/stack/include/bt_dev_class.h
+++ b/system/stack/include/bt_dev_class.h
@@ -123,6 +123,12 @@
   }
 
 #ifdef __cplusplus
+inline void dev_class_copy(DEV_CLASS& dst, const DEV_CLASS& src) {
+  dst[0] = src[0];
+  dst[1] = src[1];
+  dst[2] = src[2];
+}
+
 #include <sstream>
 inline std::string dev_class_text(const DEV_CLASS& dev_class) {
   std::ostringstream oss;
diff --git a/system/stack/include/bt_name.h b/system/stack/include/bt_name.h
index 9cf6d6d..8f98059 100644
--- a/system/stack/include/bt_name.h
+++ b/system/stack/include/bt_name.h
@@ -48,6 +48,10 @@
 inline constexpr tBTM_BD_NAME kBtmBdNameEmpty = {};
 constexpr size_t kBdNameLength = static_cast<size_t>(BD_NAME_LEN);
 
+inline size_t bd_name_copy(BD_NAME bd_name_dest, const char* src) {
+  return strlcpy(reinterpret_cast<char*>(bd_name_dest), const_cast<char*>(src),
+                 kBdNameLength + 1);
+}
 inline size_t bd_name_copy(BD_NAME bd_name_dest, const BD_NAME bd_name_src) {
   return strlcpy(reinterpret_cast<char*>(bd_name_dest),
                  reinterpret_cast<const char*>(bd_name_src), kBdNameLength + 1);
diff --git a/system/stack/include/btm_api_types.h b/system/stack/include/btm_api_types.h
index 5113bd6..450e556 100644
--- a/system/stack/include/btm_api_types.h
+++ b/system/stack/include/btm_api_types.h
@@ -129,12 +129,6 @@
  ***************************/
 /* Definitions of the parameters passed to BTM_StartInquiry.
  */
-typedef struct /* contains the two device class condition fields */
-{
-  DEV_CLASS dev_class;
-  DEV_CLASS dev_class_mask;
-} tBTM_COD_COND;
-
 constexpr uint8_t BLE_EVT_CONNECTABLE_BIT = 0;
 constexpr uint8_t BLE_EVT_SCANNABLE_BIT = 1;
 constexpr uint8_t BLE_EVT_DIRECTED_BIT = 2;
diff --git a/system/stack/pan/pan_api.cc b/system/stack/pan/pan_api.cc
index 378263c..4967652 100644
--- a/system/stack/pan/pan_api.cc
+++ b/system/stack/pan/pan_api.cc
@@ -43,6 +43,8 @@
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 using bluetooth::Uuid;
 
 namespace {
@@ -168,7 +170,8 @@
     p_desc = PAN_NAP_DEFAULT_DESCRIPTION;
 
     if (pan_cb.pan_nap_sdp_handle != 0)
-      SDP_DeleteRecord(pan_cb.pan_nap_sdp_handle);
+      get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+          pan_cb.pan_nap_sdp_handle);
 
     pan_cb.pan_nap_sdp_handle =
         pan_register_with_sdp(UUID_SERVCLASS_NAP, p_nap_name.c_str(), p_desc);
@@ -179,7 +182,8 @@
    */
   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);
+      get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+          pan_cb.pan_nap_sdp_handle);
       pan_cb.pan_nap_sdp_handle = 0;
       bta_sys_remove_uuid(UUID_SERVCLASS_NAP);
       nap_service_name.clear();
@@ -193,7 +197,8 @@
     /* Registering for PANU service with SDP */
     p_desc = PAN_PANU_DEFAULT_DESCRIPTION;
     if (pan_cb.pan_user_sdp_handle != 0)
-      SDP_DeleteRecord(pan_cb.pan_user_sdp_handle);
+      get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+          pan_cb.pan_user_sdp_handle);
 
     pan_cb.pan_user_sdp_handle =
         pan_register_with_sdp(UUID_SERVCLASS_PANU, p_user_name.c_str(), p_desc);
@@ -204,7 +209,8 @@
    */
   else if (pan_cb.role & PAN_ROLE_CLIENT) {
     if (pan_cb.pan_user_sdp_handle != 0) {
-      SDP_DeleteRecord(pan_cb.pan_user_sdp_handle);
+      get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
+          pan_cb.pan_user_sdp_handle);
       pan_cb.pan_user_sdp_handle = 0;
       bta_sys_remove_uuid(UUID_SERVCLASS_PANU);
       user_service_name.clear();
diff --git a/system/stack/pan/pan_utils.cc b/system/stack/pan/pan_utils.cc
index 7252ddf..d81bbb5 100644
--- a/system/stack/pan/pan_utils.cc
+++ b/system/stack/pan/pan_utils.cc
@@ -33,6 +33,8 @@
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 static const uint8_t pan_proto_elem_data[] = {
     0x35, 0x18,       /* data element sequence of length 0x18 bytes */
     0x35, 0x06,       /* data element sequence for L2CAP descriptor */
@@ -66,7 +68,7 @@
   uint32_t proto_len = (uint32_t)pan_proto_elem_data[1];
 
   /* Create a record */
-  sdp_handle = SDP_CreateRecord();
+  sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
 
   if (sdp_handle == 0) {
     PAN_TRACE_ERROR("PAN_SetRole - could not create SDP record");
@@ -74,35 +76,41 @@
   }
 
   /* Service Class ID List */
-  SDP_AddServiceClassIdList(sdp_handle, 1, &uuid);
+  get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(sdp_handle, 1,
+                                                               &uuid);
 
   /* Add protocol element sequence from the constant string */
-  SDP_AddAttribute(sdp_handle, ATTR_ID_PROTOCOL_DESC_LIST,
-                   DATA_ELE_SEQ_DESC_TYPE, proto_len,
-                   (uint8_t*)(pan_proto_elem_data + 2));
+  get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+      sdp_handle, ATTR_ID_PROTOCOL_DESC_LIST, DATA_ELE_SEQ_DESC_TYPE, proto_len,
+      (uint8_t*)(pan_proto_elem_data + 2));
 
   /* Language base */
-  SDP_AddLanguageBaseAttrIDList(sdp_handle, LANG_ID_CODE_ENGLISH,
-                                LANG_ID_CHAR_ENCODE_UTF8, LANGUAGE_BASE_ID);
+  get_legacy_stack_sdp_api()->handle.SDP_AddLanguageBaseAttrIDList(
+      sdp_handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8,
+      LANGUAGE_BASE_ID);
 
   /* Profile descriptor list */
-  SDP_AddProfileDescriptorList(sdp_handle, uuid, PAN_PROFILE_VERSION);
+  get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
+      sdp_handle, uuid, PAN_PROFILE_VERSION);
 
   /* Service Name */
-  SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
-                   (uint8_t)(strlen(p_name) + 1), (uint8_t*)p_name);
+  get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+      sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
+      (uint8_t)(strlen(p_name) + 1), (uint8_t*)p_name);
 
   /* Service description */
-  SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE,
-                   (uint8_t)(strlen(p_desc) + 1), (uint8_t*)p_desc);
+  get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+      sdp_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE,
+      (uint8_t)(strlen(p_desc) + 1), (uint8_t*)p_desc);
 
   /* Security description */
   // Only NAP and PANU has service level security; GN has no security
   if (uuid == UUID_SERVCLASS_NAP || uuid == UUID_SERVCLASS_PANU) {
     UINT16_TO_BE_FIELD(&security, 0x0001);
   }
-  SDP_AddAttribute(sdp_handle, ATTR_ID_SECURITY_DESCRIPTION, UINT_DESC_TYPE, 2,
-                   (uint8_t*)&security);
+  get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+      sdp_handle, ATTR_ID_SECURITY_DESCRIPTION, UINT_DESC_TYPE, 2,
+      (uint8_t*)&security);
 
   if (uuid == UUID_SERVCLASS_NAP) {
     uint16_t NetAccessType = 0x0005;      /* Ethernet */
@@ -112,18 +120,19 @@
     /* Net access type. */
     p = array;
     UINT16_TO_BE_STREAM(p, NetAccessType);
-    SDP_AddAttribute(sdp_handle, ATTR_ID_NET_ACCESS_TYPE, UINT_DESC_TYPE, 2,
-                     array);
+    get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        sdp_handle, ATTR_ID_NET_ACCESS_TYPE, UINT_DESC_TYPE, 2, array);
 
     /* Net access rate. */
     p = array;
     UINT32_TO_BE_STREAM(p, NetAccessRate);
-    SDP_AddAttribute(sdp_handle, ATTR_ID_MAX_NET_ACCESS_RATE, UINT_DESC_TYPE, 4,
-                     array);
+    get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
+        sdp_handle, ATTR_ID_MAX_NET_ACCESS_RATE, UINT_DESC_TYPE, 4, array);
   }
 
   /* Make the service browsable */
-  SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_list);
+  get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
+      sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_list);
 
   return sdp_handle;
 }
diff --git a/system/stack/sdp/sdp_api.cc b/system/stack/sdp/sdp_api.cc
index 27c4a8f..fa5a7f0 100644
--- a/system/stack/sdp/sdp_api.cc
+++ b/system/stack/sdp/sdp_api.cc
@@ -32,6 +32,7 @@
 #include "osi/include/osi.h"  // PTR_TO_UINT
 #include "stack/include/bt_types.h"
 #include "stack/include/sdp_api.h"
+#include "stack/sdp/internal/sdp_api.h"
 #include "stack/sdp/sdpint.h"
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
diff --git a/system/stack/sdp/sdp_db.cc b/system/stack/sdp/sdp_db.cc
index d032e49..b9a9329 100644
--- a/system/stack/sdp/sdp_db.cc
+++ b/system/stack/sdp/sdp_db.cc
@@ -42,6 +42,11 @@
                              const uint8_t* p_his_uuid, uint16_t his_len,
                              int nest_level);
 
+bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
+                      uint32_t attr_len, uint8_t* p_val);
+
+bool SDP_DeleteAttribute(uint32_t handle, uint16_t attr_id);
+
 /*******************************************************************************
  *
  * Function         sdp_db_service_search
diff --git a/system/stack/sdp/sdp_utils.cc b/system/stack/sdp/sdp_utils.cc
index e3150d9..3d8785a 100644
--- a/system/stack/sdp/sdp_utils.cc
+++ b/system/stack/sdp/sdp_utils.cc
@@ -54,6 +54,16 @@
 #include "types/raw_address.h"
 
 using bluetooth::Uuid;
+
+bool SDP_FindProtocolListElemInRec(const tSDP_DISC_REC* p_rec,
+                                   uint16_t layer_uuid,
+                                   tSDP_PROTOCOL_ELEM* p_elem);
+tSDP_DISC_ATTR* SDP_FindAttributeInRec(const tSDP_DISC_REC* p_rec,
+                                       uint16_t attr_id);
+uint16_t SDP_GetDiRecord(uint8_t getRecordIndex,
+                         tSDP_DI_GET_RECORD* device_info,
+                         const tSDP_DISCOVERY_DB* p_db);
+
 static const uint8_t sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                         0x10, 0x00, 0x80, 0x00, 0x00, 0x80,
                                         0x5F, 0x9B, 0x34, 0xFB};
diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc
index 22942fc..e6ea894 100644
--- a/system/stack/smp/smp_act.cc
+++ b/system/stack/smp/smp_act.cc
@@ -45,6 +45,9 @@
 constexpr char kBtmLogTag[] = "SMP";
 }
 
+static void smp_key_distribution_by_transport(tSMP_CB* p_cb,
+                                              tSMP_INT_DATA* p_data);
+
 #define SMP_KEY_DIST_TYPE_MAX 4
 
 const tSMP_ACT smp_distribute_act[] = {
@@ -2245,7 +2248,8 @@
  * Description  depending on the transport used at the moment calls either
  *              smp_key_distribution(...) or smp_br_key_distribution(...).
  ******************************************************************************/
-void smp_key_distribution_by_transport(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
+static void smp_key_distribution_by_transport(tSMP_CB* p_cb,
+                                              tSMP_INT_DATA* p_data) {
   SMP_TRACE_DEBUG("%s", __func__);
   if (p_cb->smp_over_br) {
     smp_br_select_next_key(p_cb, NULL);
diff --git a/system/stack/smp/smp_int.h b/system/stack/smp/smp_int.h
index 8b7a913..3a3fe65 100644
--- a/system/stack/smp/smp_int.h
+++ b/system/stack/smp/smp_int.h
@@ -404,7 +404,6 @@
 void smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data);
 void smp_br_select_next_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data);
 void smp_br_process_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data);
-void smp_key_distribution_by_transport(tSMP_CB* p_cb, tSMP_INT_DATA* p_data);
 void smp_br_pairing_complete(tSMP_CB* p_cb, tSMP_INT_DATA* p_data);
 
 /* smp_l2c */
diff --git a/system/stack/test/common/stack_test_packet_utils.cc b/system/stack/test/common/stack_test_packet_utils.cc
index 7f89a61..e605813 100644
--- a/system/stack/test/common/stack_test_packet_utils.cc
+++ b/system/stack/test/common/stack_test_packet_utils.cc
@@ -64,7 +64,7 @@
   packet->offset = 4 + L2CAP_PKT_OVERHEAD;
   packet->len = static_cast<uint16_t>(buffer_length - 4 - L2CAP_PKT_OVERHEAD);
   packet->layer_specific = 0;
-  packet->event = MSG_HC_TO_STACK_HCI_ACL;
+  packet->event = 0x1100;  // MSG_HC_TO_STACK_HCI_ACL;
   memcpy(packet->data, acl_packet_bytes, buffer_length);
   return packet;
 }
diff --git a/system/stack/test/fuzzers/sdp/sdpFuzzFunctions.h b/system/stack/test/fuzzers/sdp/sdpFuzzFunctions.h
index 10423f5..435d214 100644
--- a/system/stack/test/fuzzers/sdp/sdpFuzzFunctions.h
+++ b/system/stack/test/fuzzers/sdp/sdpFuzzFunctions.h
@@ -37,7 +37,7 @@
  */
 static const std::vector<std::function<void(FuzzedDataProvider*)>>
     sdp_operations = {
-        // SDP_InitDiscoveryDb
+        // ::SDP_InitDiscoveryDb
         [](FuzzedDataProvider* fdp) -> void {
           if (sdp_db_vect.size() >= MAX_NUM_DBS) {
             return;
@@ -58,43 +58,47 @@
           std::shared_ptr<tSDP_DISCOVERY_DB> p_db(
               reinterpret_cast<tSDP_DISCOVERY_DB*>(malloc(db_size)), free);
           if (p_db) {
-            bool success = SDP_InitDiscoveryDb(
-                p_db.get(), db_size, uuid_list.size(), uuid_list.data(),
-                attr_list.size(),
-                reinterpret_cast<uint16_t*>(attr_list.data()));
+            bool success =
+                get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+                    p_db.get(), db_size, uuid_list.size(), uuid_list.data(),
+                    attr_list.size(),
+                    reinterpret_cast<uint16_t*>(attr_list.data()));
             if (success) {
               sdp_db_vect.push_back(p_db);
             }
           }
         },
 
-        // SDP_CancelServiceSearch
+        // ::SDP_CancelServiceSearch
         [](FuzzedDataProvider* fdp) -> void {
-          SDP_CancelServiceSearch(
+          get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(
               getArbitraryVectorElement(fdp, sdp_db_vect, true).get());
         },
 
-        // SDP_ServiceSearchRequest
+        // ::SDP_ServiceSearchRequest
         [](FuzzedDataProvider* fdp) -> void {
           const RawAddress bd_addr = generateRawAddress(fdp);
           tSDP_DISCOVERY_DB* db =
               getArbitraryVectorElement(fdp, sdp_db_vect, false).get();
           if (db) {
-            SDP_ServiceSearchRequest(bd_addr, db, &sdp_disc_cmpl_cb);
+            get_legacy_stack_sdp_api()->service.SDP_ServiceSearchRequest(
+                bd_addr, db, &sdp_disc_cmpl_cb);
           }
         },
 
-        // SDP_ServiceSearchAttributeRequest
+        // ::SDP_ServiceSearchAttributeRequest
         [](FuzzedDataProvider* fdp) -> void {
           const RawAddress bd_addr = generateRawAddress(fdp);
           tSDP_DISCOVERY_DB* db =
               getArbitraryVectorElement(fdp, sdp_db_vect, false).get();
           if (db) {
-            SDP_ServiceSearchAttributeRequest(bd_addr, db, &sdp_disc_cmpl_cb);
+            get_legacy_stack_sdp_api()
+                ->service.SDP_ServiceSearchAttributeRequest(bd_addr, db,
+                                                            &sdp_disc_cmpl_cb);
           }
         },
 
-        // SDP_ServiceSearchAttributeRequest2
+        // ::SDP_ServiceSearchAttributeRequest2
         [](FuzzedDataProvider* fdp) -> void {
           const RawAddress bd_addr = generateRawAddress(fdp);
           std::vector<uint8_t> user_data = fdp->ConsumeBytes<uint8_t>(
@@ -103,105 +107,109 @@
               getArbitraryVectorElement(fdp, sdp_db_vect, false).get();
 
           if (db) {
-            SDP_ServiceSearchAttributeRequest2(bd_addr, db, &sdp_disc_cmpl_cb2,
-                                               user_data.data());
+            get_legacy_stack_sdp_api()
+                ->service.SDP_ServiceSearchAttributeRequest2(
+                    bd_addr, db, &sdp_disc_cmpl_cb2, user_data.data());
           }
         },
 
-        // SDP_FindAttributeInRec
+        // ::SDP_FindAttributeInRec
         [](FuzzedDataProvider* fdp) -> void {
           tSDP_DISC_REC* p_rec =
               generateArbitrarySdpDiscRecord(fdp, false).get();
-          SDP_FindAttributeInRec(p_rec, fdp->ConsumeIntegral<uint16_t>());
+          get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
+              p_rec, fdp->ConsumeIntegral<uint16_t>());
         },
 
-        // SDP_FindServiceInDb
+        // ::SDP_FindServiceInDb
         [](FuzzedDataProvider* fdp) -> void {
-          SDP_FindServiceInDb(
+          get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
               getArbitraryVectorElement(fdp, sdp_db_vect, true).get(),
               fdp->ConsumeIntegral<uint16_t>(),
               generateArbitrarySdpDiscRecord(fdp, true).get());
         },
 
-        // SDP_FindServiceUUIDInDb
+        // ::SDP_FindServiceUUIDInDb
         [](FuzzedDataProvider* fdp) -> void {
           const bluetooth::Uuid uuid = generateArbitraryUuid(fdp);
-          SDP_FindServiceUUIDInDb(
+          get_legacy_stack_sdp_api()->db.SDP_FindServiceUUIDInDb(
               getArbitraryVectorElement(fdp, sdp_db_vect, true).get(), uuid,
               generateArbitrarySdpDiscRecord(fdp, true).get());
         },
 
-        // SDP_FindServiceUUIDInRec_128bit
+        // ::SDP_FindServiceUUIDInRec_128bit
         [](FuzzedDataProvider* fdp) -> void {
           bluetooth::Uuid uuid = generateArbitraryUuid(fdp);
           tSDP_DISC_REC* p_rec =
               generateArbitrarySdpDiscRecord(fdp, false).get();
-          SDP_FindServiceUUIDInRec_128bit(p_rec, &uuid);
+          get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec_128bit(
+              p_rec, &uuid);
         },
 
-        // SDP_FindServiceInDb_128bit
+        // ::SDP_FindServiceInDb_128bit
         [](FuzzedDataProvider* fdp) -> void {
-          SDP_FindServiceInDb_128bit(
+          get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb_128bit(
               getArbitraryVectorElement(fdp, sdp_db_vect, true).get(),
               generateArbitrarySdpDiscRecord(fdp, true).get());
         },
 
-        // SDP_FindProtocolListElemInRec
+        // ::SDP_FindProtocolListElemInRec
         [](FuzzedDataProvider* fdp) -> void {
           tSDP_PROTOCOL_ELEM elem = generateArbitrarySdpProtocolElements(fdp);
           tSDP_DISC_REC* p_rec =
               generateArbitrarySdpDiscRecord(fdp, false).get();
-          SDP_FindProtocolListElemInRec(p_rec, fdp->ConsumeIntegral<uint16_t>(),
-                                        &elem);
+          get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
+              p_rec, fdp->ConsumeIntegral<uint16_t>(), &elem);
         },
 
-        // SDP_FindProfileVersionInRec
+        // ::SDP_FindProfileVersionInRec
         [](FuzzedDataProvider* fdp) -> void {
           uint16_t p_version;
           tSDP_DISC_REC* p_rec =
               generateArbitrarySdpDiscRecord(fdp, false).get();
 
-          SDP_FindProfileVersionInRec(p_rec, fdp->ConsumeIntegral<uint16_t>(),
-                                      &p_version);
+          get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
+              p_rec, fdp->ConsumeIntegral<uint16_t>(), &p_version);
         },
 
-        // SDP_CreateRecord
+        // ::SDP_CreateRecord
         [](FuzzedDataProvider* fdp) -> void {
-          uint32_t handle = SDP_CreateRecord();
+          uint32_t handle =
+              get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
           if (handle) {
             sdp_record_handles.push_back(handle);
           }
         },
 
-        // SDP_DeleteRecord
+        // ::SDP_DeleteRecord
         [](FuzzedDataProvider* fdp) -> void {
-          SDP_DeleteRecord(
+          get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
               getArbitraryVectorElement(fdp, sdp_record_handles, true));
         },
 
-        // SDP_AddAttribute
+        // ::SDP_AddAttribute
         [](FuzzedDataProvider* fdp) -> void {
           std::vector<uint8_t> val = fdp->ConsumeBytes<uint8_t>(
               fdp->ConsumeIntegralInRange<size_t>(1, 1024));
           if (val.size() > 0) {
-            SDP_AddAttribute(
+            get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
                 getArbitraryVectorElement(fdp, sdp_record_handles, true),
                 fdp->ConsumeIntegral<uint16_t>(),
                 fdp->ConsumeIntegral<uint8_t>(), val.size(), val.data());
           }
         },
 
-        // SDP_AddSequence
+        // ::SDP_AddSequence
         [](FuzzedDataProvider* fdp) -> void {
           SDP_Sequence_Helper seq = generateArbitrarySdpElemSequence(fdp);
 
-          SDP_AddSequence(
+          get_legacy_stack_sdp_api()->handle.SDP_AddSequence(
               getArbitraryVectorElement(fdp, sdp_record_handles, true),
               fdp->ConsumeIntegral<uint16_t>(), seq.num_elem, seq.type.get(),
               seq.len.get(), seq.p_val.get());
         },
 
-        // SDP_AddUuidSequence
+        // ::SDP_AddUuidSequence
         [](FuzzedDataProvider* fdp) -> void {
           uint16_t num_uuids = fdp->ConsumeIntegralInRange<uint16_t>(1, 64);
           uint16_t* uuids = new uint16_t[num_uuids];
@@ -209,31 +217,31 @@
             uuids[i] = fdp->ConsumeIntegral<uint16_t>();
           }
 
-          SDP_AddUuidSequence(
+          get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
               getArbitraryVectorElement(fdp, sdp_record_handles, true),
               fdp->ConsumeIntegral<uint16_t>(), num_uuids, uuids);
           delete[] uuids;
         },
 
-        // SDP_AddProtocolList
+        // ::SDP_AddProtocolList
         [](FuzzedDataProvider* fdp) -> void {
           std::shared_ptr<tSDP_PROTO_LIST_ELEM> p_proto_list =
               generateArbitrarySdpProtocolElementList(fdp);
           if (p_proto_list) {
-            SDP_AddProtocolList(
+            get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(
                 getArbitraryVectorElement(fdp, sdp_record_handles, true),
                 p_proto_list.get()->num_elems, p_proto_list.get()->list_elem);
           }
         },
 
-        // SDP_AddAdditionProtoLists
+        // ::SDP_AddAdditionProtoLists
         [](FuzzedDataProvider* fdp) -> void {
           uint16_t arr_size;
           tSDP_PROTO_LIST_ELEM** p_proto_list =
               generateArbitrarySdpProtocolElementListArray(fdp, &arr_size);
           if (p_proto_list) {
             if (p_proto_list[0]) {
-              SDP_AddAdditionProtoLists(
+              get_legacy_stack_sdp_api()->handle.SDP_AddAdditionProtoLists(
                   getArbitraryVectorElement(fdp, sdp_record_handles, true),
                   arr_size, p_proto_list[0]);
               for (uint16_t i = 0; i < arr_size; i++) {
@@ -244,24 +252,24 @@
           }
         },
 
-        // SDP_AddProfileDescriptorList
+        // ::SDP_AddProfileDescriptorList
         [](FuzzedDataProvider* fdp) -> void {
-          SDP_AddProfileDescriptorList(
+          get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
               getArbitraryVectorElement(fdp, sdp_record_handles, true),
               fdp->ConsumeIntegral<uint16_t>(),
               fdp->ConsumeIntegral<uint16_t>());
         },
 
-        // SDP_AddLanguageBaseAttrIDList
+        // ::SDP_AddLanguageBaseAttrIDList
         [](FuzzedDataProvider* fdp) -> void {
-          SDP_AddLanguageBaseAttrIDList(
+          get_legacy_stack_sdp_api()->handle.SDP_AddLanguageBaseAttrIDList(
               getArbitraryVectorElement(fdp, sdp_record_handles, true),
               fdp->ConsumeIntegral<uint16_t>(),
               fdp->ConsumeIntegral<uint16_t>(),
               fdp->ConsumeIntegral<uint16_t>());
         },
 
-        // SDP_AddServiceClassIdList
+        // ::SDP_AddServiceClassIdList
         [](FuzzedDataProvider* fdp) -> void {
           uint16_t num_services = fdp->ConsumeIntegralInRange<uint16_t>(0, 64);
           uint16_t* service_uuids = new uint16_t[num_services];
@@ -269,28 +277,29 @@
             service_uuids[i] = fdp->ConsumeIntegral<uint16_t>();
           }
 
-          SDP_AddServiceClassIdList(
+          get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
               getArbitraryVectorElement(fdp, sdp_record_handles, true),
               num_services, service_uuids);
 
           delete[] service_uuids;
         },
 
-        // SDP_DeleteAttribute
+        // ::SDP_DeleteAttribute
         [](FuzzedDataProvider* fdp) -> void {
-          SDP_DeleteAttribute(
+          get_legacy_stack_sdp_api()->handle.SDP_DeleteAttribute(
               getArbitraryVectorElement(fdp, sdp_record_handles, true),
               fdp->ConsumeIntegral<uint16_t>());
         },
 
-        // SDP_SetLocalDiRecord
+        // ::SDP_SetLocalDiRecord
         [](FuzzedDataProvider* fdp) -> void {
           uint32_t handle;  // Output var
           tSDP_DI_RECORD device_info = generateArbitrarySdpDiRecord(fdp);
-          SDP_SetLocalDiRecord(&device_info, &handle);
+          get_legacy_stack_sdp_api()->device_id.SDP_SetLocalDiRecord(
+              &device_info, &handle);
         },
 
-        // SDP_DiDiscover
+        // ::SDP_DiDiscover
         [](FuzzedDataProvider* fdp) -> void {
           const RawAddress remote_device = generateRawAddress(fdp);
 
@@ -300,36 +309,37 @@
           std::shared_ptr<tSDP_DISCOVERY_DB> p_db(
               reinterpret_cast<tSDP_DISCOVERY_DB*>(malloc(db_size)), free);
           if (p_db) {
-            SDP_DiDiscover(remote_device, p_db.get(), db_size,
-                           &sdp_disc_cmpl_cb);
+            get_legacy_stack_sdp_api()->device_id.SDP_DiDiscover(
+                remote_device, p_db.get(), db_size, &sdp_disc_cmpl_cb);
           }
         },
 
-        // SDP_GetNumDiRecords
+        // ::SDP_GetNumDiRecords
         [](FuzzedDataProvider* fdp) -> void {
-          SDP_GetNumDiRecords(
+          get_legacy_stack_sdp_api()->device_id.SDP_GetNumDiRecords(
               getArbitraryVectorElement(fdp, sdp_db_vect, true).get());
         },
 
-        // SDP_GetDiRecord
+        // ::SDP_GetDiRecord
         [](FuzzedDataProvider* fdp) -> void {
           tSDP_DI_GET_RECORD device_info;  // Output var
-          SDP_GetDiRecord(
+          get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(
               fdp->ConsumeIntegral<uint8_t>(), &device_info,
               getArbitraryVectorElement(fdp, sdp_db_vect, true).get());
         },
 
-        // SDP_SetTraceLevel
+        // ::SDP_SetTraceLevel
         [](FuzzedDataProvider* fdp) -> void {
           SDP_SetTraceLevel(fdp->ConsumeIntegral<uint8_t>());
         },
 
-        // SDP_FindServiceUUIDInRec
+        // ::SDP_FindServiceUUIDInRec
         [](FuzzedDataProvider* fdp) -> void {
           tSDP_DISC_REC* p_rec =
               generateArbitrarySdpDiscRecord(fdp, false).get();
           bluetooth::Uuid uuid;  // Output var
-          SDP_FindServiceUUIDInRec(p_rec, &uuid);
+          get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec(p_rec,
+                                                                      &uuid);
         }};
 
 #endif  // FUZZER_SDP_FUNCTIONS_H_
diff --git a/system/stack/test/fuzzers/sdp/sdpFuzzHelpers.h b/system/stack/test/fuzzers/sdp/sdpFuzzHelpers.h
index fead81e..43b4710 100644
--- a/system/stack/test/fuzzers/sdp/sdpFuzzHelpers.h
+++ b/system/stack/test/fuzzers/sdp/sdpFuzzHelpers.h
@@ -27,9 +27,12 @@
 
 #include "fuzzers/common/commonFuzzHelpers.h"
 #include "osi/include/alarm.h"
+#include "stack/include/sdp_api.h"
 #include "stack/sdp/sdpint.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
+
 #define SDP_MAX_NUM_ELEMS 128
 #define SDP_MAX_ELEM_LEN 1024
 #define SDP_MAX_ATTRS 1024
@@ -76,7 +79,7 @@
   sdp_protolist_elem_vect.clear();
 
   // Delete all records
-  SDP_DeleteRecord(0);
+  get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(0);
   sdp_record_handles.clear();
 
   // Delete Databases
diff --git a/system/stack/test/gatt/stack_gatt_test.cc b/system/stack/test/gatt/stack_gatt_test.cc
index fb000ef..8d6b9ea 100644
--- a/system/stack/test/gatt/stack_gatt_test.cc
+++ b/system/stack/test/gatt/stack_gatt_test.cc
@@ -27,10 +27,26 @@
 #include "stack/gatt/gatt_int.h"
 #include "stack/include/gatt_api.h"
 #include "test/common/mock_functions.h"
+#include "test/mock/mock_stack_sdp_legacy_api.h"
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
-class StackGattTest : public ::testing::Test {};
+class StackGattTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    test::mock::stack_sdp_legacy::api_.handle.SDP_CreateRecord =
+        ::SDP_CreateRecord;
+    test::mock::stack_sdp_legacy::api_.handle.SDP_AddServiceClassIdList =
+        ::SDP_AddServiceClassIdList;
+    test::mock::stack_sdp_legacy::api_.handle.SDP_AddAttribute =
+        ::SDP_AddAttribute;
+    test::mock::stack_sdp_legacy::api_.handle.SDP_AddProtocolList =
+        ::SDP_AddProtocolList;
+    test::mock::stack_sdp_legacy::api_.handle.SDP_AddUuidSequence =
+        ::SDP_AddUuidSequence;
+  }
+  void TearDown() override { test::mock::stack_sdp_legacy::api_.handle = {}; }
+};
 
 namespace {
 
diff --git a/system/test/Android.bp b/system/test/Android.bp
index 32cc9d2..5656eca 100644
--- a/system/test/Android.bp
+++ b/system/test/Android.bp
@@ -206,6 +206,27 @@
 }
 
 filegroup {
+    name: "TestMockStackAvct",
+    srcs: [
+        "mock/mock_stack_avct_*.cc",
+    ],
+}
+
+filegroup {
+    name: "TestMockStackAvdt",
+    srcs: [
+        "mock/mock_stack_avdt_*.cc",
+    ],
+}
+
+filegroup {
+    name: "TestMockStackAvrc",
+    srcs: [
+        "mock/mock_stack_avrc_*.cc",
+    ],
+}
+
+filegroup {
     name: "TestMockStackL2cap",
     srcs: [
         "mock/mock_stack_l2cap_*.cc",
@@ -315,6 +336,20 @@
 }
 
 filegroup {
+    name: "TestMockStackHid",
+    srcs: [
+        "mock/mock_stack_hid*.cc",
+    ],
+}
+
+filegroup {
+    name: "TestMockStackPan",
+    srcs: [
+        "mock/mock_stack_pan*.cc",
+    ],
+}
+
+filegroup {
     name: "TestMockStackSdp",
     srcs: [
         "mock/mock_stack_sdp*.cc",
diff --git a/system/test/headless/sdp/sdp.cc b/system/test/headless/sdp/sdp.cc
index 4779fb4..f5adcae 100644
--- a/system/test/headless/sdp/sdp.cc
+++ b/system/test/headless/sdp/sdp.cc
@@ -29,6 +29,7 @@
 #include "types/bluetooth/uuid.h"
 #include "types/raw_address.h"
 
+using namespace bluetooth::legacy::stack::sdp;
 using namespace bluetooth::test::headless;
 
 static void bta_jv_start_discovery_callback(tSDP_STATUS result,
@@ -85,10 +86,10 @@
                    const RawAddress& raw_address, const bluetooth::Uuid& uuid) {
   SdpDb sdp_discovery_db(kMaxDiscoveryRecords);
 
-  if (!SDP_InitDiscoveryDb(sdp_discovery_db.RawPointer(),
-                           sdp_discovery_db.Length(),
-                           1,  // num_uuid,
-                           &uuid, 0, nullptr)) {
+  if (!get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
+          sdp_discovery_db.RawPointer(), sdp_discovery_db.Length(),
+          1,  // num_uuid,
+          &uuid, 0, nullptr)) {
     fprintf(stdout, "%s Unable to initialize sdp discovery\n", __func__);
     return -1;
   }
@@ -98,7 +99,7 @@
 
   sdp_discovery_db.Print(stdout);
 
-  if (!SDP_ServiceSearchAttributeRequest2(
+  if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest2(
           raw_address, sdp_discovery_db.RawPointer(),
           bta_jv_start_discovery_callback, (void*)&promise)) {
     fprintf(stdout, "%s Failed to start search attribute request\n", __func__);
@@ -112,8 +113,8 @@
     return result;
   }
 
-  tSDP_DISC_REC* rec = SDP_FindServiceInDb(sdp_discovery_db.RawPointer(),
-                                           uuid.As16Bit(), nullptr);
+  tSDP_DISC_REC* rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
+      sdp_discovery_db.RawPointer(), uuid.As16Bit(), nullptr);
   if (rec == nullptr) {
     fprintf(stdout, "discovery record is null from:%s uuid:%s\n",
             raw_address.ToString().c_str(), uuid.ToString().c_str());
diff --git a/system/test/mock/mock_btif_co_bta_hh_co.cc b/system/test/mock/mock_btif_co_bta_hh_co.cc
index 887ef8c..da9560d 100644
--- a/system/test/mock/mock_btif_co_bta_hh_co.cc
+++ b/system/test/mock/mock_btif_co_bta_hh_co.cc
@@ -43,16 +43,13 @@
   inc_func_call_count(__func__);
   return nullptr;
 }
-void bta_hh_co_close(uint8_t dev_handle, uint8_t app_id) {
-  inc_func_call_count(__func__);
-}
+void bta_hh_co_close(btif_hh_device_t* p_dev) { inc_func_call_count(__func__); }
 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 const RawAddress& peer_addr,
                     uint8_t app_id) {
   inc_func_call_count(__func__);
 }
-void bta_hh_co_destroy(int fd) { inc_func_call_count(__func__); }
 void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status,
                            const uint8_t* p_rpt, uint16_t len) {
   inc_func_call_count(__func__);
diff --git a/system/test/mock/mock_stack_acl.cc b/system/test/mock/mock_stack_acl.cc
index 2958682..afe452f 100644
--- a/system/test/mock/mock_stack_acl.cc
+++ b/system/test/mock/mock_stack_acl.cc
@@ -77,7 +77,6 @@
 struct sco_peer_supports_esco_2m_phy sco_peer_supports_esco_2m_phy;
 struct sco_peer_supports_esco_3m_phy sco_peer_supports_esco_3m_phy;
 struct acl_create_classic_connection acl_create_classic_connection;
-struct IsEprAvailable IsEprAvailable;
 struct acl_get_connection_from_address acl_get_connection_from_address;
 struct btm_acl_for_bda btm_acl_for_bda;
 struct acl_get_connection_from_handle acl_get_connection_from_handle;
@@ -320,10 +319,6 @@
   return test::mock::stack_acl::acl_create_classic_connection(
       bd_addr, there_are_high_priority_channels, is_bonding);
 }
-bool IsEprAvailable(const tACL_CONN& p_acl) {
-  inc_func_call_count(__func__);
-  return test::mock::stack_acl::IsEprAvailable(p_acl);
-}
 tACL_CONN* acl_get_connection_from_address(const RawAddress& bd_addr,
                                            tBT_TRANSPORT transport) {
   inc_func_call_count(__func__);
diff --git a/system/test/mock/mock_stack_acl.h b/system/test/mock/mock_stack_acl.h
index 25ebc36..400e27d 100644
--- a/system/test/mock/mock_stack_acl.h
+++ b/system/test/mock/mock_stack_acl.h
@@ -359,15 +359,6 @@
   };
 };
 extern struct acl_create_classic_connection acl_create_classic_connection;
-// Name: IsEprAvailable
-// Params: const tACL_CONN& p_acl
-// Returns: inline bool
-struct IsEprAvailable {
-  std::function<bool(const tACL_CONN& p_acl)> body{
-      [](const tACL_CONN& p_acl) { return 0; }};
-  inline bool operator()(const tACL_CONN& p_acl) { return body(p_acl); };
-};
-extern struct IsEprAvailable IsEprAvailable;
 // Name: acl_get_connection_from_address
 // Params: const RawAddress& bd_addr, tBT_TRANSPORT transport
 // Returns: tACL_CONN*
diff --git a/system/test/mock/mock_stack_btm_inq.cc b/system/test/mock/mock_stack_btm_inq.cc
index f782f59..0c7f59e 100644
--- a/system/test/mock/mock_stack_btm_inq.cc
+++ b/system/test/mock/mock_stack_btm_inq.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2023 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.
@@ -13,170 +13,299 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 /*
  * Generated mock file from original source file
- *   Functions generated:44
+ *   Functions generated:43
+ *
+ *  mockcify.pl ver 0.6.0
  */
 
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
+#include <cstdint>
+#include <functional>
 #include <map>
 #include <string>
 
-#include "advertise_data_parser.h"
-#include "btm_api.h"
-#include "common/time_util.h"
-#include "device/include/controller.h"
-#include "main/shim/btm_api.h"
-#include "main/shim/shim.h"
-#include "osi/include/log.h"
-#include "osi/include/osi.h"
-#include "stack/btm/btm_ble_int.h"
-#include "stack/btm/btm_int_types.h"
-#include "stack/include/acl_api.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/btm_ble_api.h"
-#include "stack/include/inq_hci_link_interface.h"
-#include "test/common/mock_functions.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
+// Mock include file to share data between tests and mock
+#include "test/mock/mock_stack_btm_inq.h"
 
-#ifndef UNUSED_ATTR
-#define UNUSED_ATTR
-#endif
+// Original usings
 
-void SendRemoteNameRequest(const RawAddress& raw_address) {
+// Mocked internal structures, if any
+
+namespace test {
+namespace mock {
+namespace stack_btm_inq {
+
+// Function state capture and return values, if needed
+struct BTM_AddEirService BTM_AddEirService;
+struct BTM_CancelInquiry BTM_CancelInquiry;
+struct BTM_CancelRemoteDeviceName BTM_CancelRemoteDeviceName;
+struct BTM_ClearInqDb BTM_ClearInqDb;
+struct BTM_EnableInterlacedInquiryScan BTM_EnableInterlacedInquiryScan;
+struct BTM_EnableInterlacedPageScan BTM_EnableInterlacedPageScan;
+struct BTM_GetEirSupportedServices BTM_GetEirSupportedServices;
+struct BTM_GetEirUuidList BTM_GetEirUuidList;
+struct BTM_HasEirService BTM_HasEirService;
+struct BTM_HasInquiryEirService BTM_HasInquiryEirService;
+struct BTM_InqDbFirst BTM_InqDbFirst;
+struct BTM_InqDbNext BTM_InqDbNext;
+struct BTM_InqDbRead BTM_InqDbRead;
+struct BTM_IsInquiryActive BTM_IsInquiryActive;
+struct BTM_IsRemoteNameKnown BTM_IsRemoteNameKnown;
+struct BTM_ReadRemoteDeviceName BTM_ReadRemoteDeviceName;
+struct BTM_RemoveEirService BTM_RemoveEirService;
+struct BTM_SetConnectability BTM_SetConnectability;
+struct BTM_SetDiscoverability BTM_SetDiscoverability;
+struct BTM_SetInquiryMode BTM_SetInquiryMode;
+struct BTM_StartInquiry BTM_StartInquiry;
+struct BTM_WriteEIR BTM_WriteEIR;
+struct SendRemoteNameRequest SendRemoteNameRequest;
+struct btm_clear_all_pending_le_entry btm_clear_all_pending_le_entry;
+struct btm_clr_inq_db btm_clr_inq_db;
+struct btm_clr_inq_result_flt btm_clr_inq_result_flt;
+struct btm_initiate_rem_name btm_initiate_rem_name;
+struct btm_inq_clear_ssp btm_inq_clear_ssp;
+struct btm_inq_db_find btm_inq_db_find;
+struct btm_inq_db_free btm_inq_db_free;
+struct btm_inq_db_init btm_inq_db_init;
+struct btm_inq_db_new btm_inq_db_new;
+struct btm_inq_db_reset btm_inq_db_reset;
+struct btm_inq_find_bdaddr btm_inq_find_bdaddr;
+struct btm_inq_remote_name_timer_timeout btm_inq_remote_name_timer_timeout;
+struct btm_inq_rmt_name_failed_cancelled btm_inq_rmt_name_failed_cancelled;
+struct btm_inq_stop_on_ssp btm_inq_stop_on_ssp;
+struct btm_process_cancel_complete btm_process_cancel_complete;
+struct btm_process_inq_complete btm_process_inq_complete;
+struct btm_process_inq_results btm_process_inq_results;
+struct btm_process_remote_name btm_process_remote_name;
+struct btm_set_eir_uuid btm_set_eir_uuid;
+struct btm_sort_inq_result btm_sort_inq_result;
+
+}  // namespace stack_btm_inq
+}  // namespace mock
+}  // namespace test
+
+// Mocked function return values, if any
+namespace test {
+namespace mock {
+namespace stack_btm_inq {
+
+tBTM_STATUS BTM_CancelRemoteDeviceName::return_value = 0;
+tBTM_STATUS BTM_ClearInqDb::return_value = 0;
+uint8_t BTM_GetEirSupportedServices::return_value = 0;
+uint8_t BTM_GetEirUuidList::return_value = 0;
+bool BTM_HasEirService::return_value = false;
+tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService::return_value = 0;
+tBTM_INQ_INFO* BTM_InqDbFirst::return_value = nullptr;
+tBTM_INQ_INFO* BTM_InqDbNext::return_value = nullptr;
+tBTM_INQ_INFO* BTM_InqDbRead::return_value = nullptr;
+uint16_t BTM_IsInquiryActive::return_value = 0;
+bool BTM_IsRemoteNameKnown::return_value = false;
+tBTM_STATUS BTM_ReadRemoteDeviceName::return_value = 0;
+tBTM_STATUS BTM_SetConnectability::return_value = 0;
+tBTM_STATUS BTM_SetDiscoverability::return_value = 0;
+tBTM_STATUS BTM_SetInquiryMode::return_value = 0;
+tBTM_STATUS BTM_StartInquiry::return_value = 0;
+tBTM_STATUS BTM_WriteEIR::return_value = 0;
+tBTM_STATUS btm_initiate_rem_name::return_value = 0;
+tINQ_DB_ENT* btm_inq_db_find::return_value = nullptr;
+tINQ_DB_ENT* btm_inq_db_new::return_value = nullptr;
+bool btm_inq_find_bdaddr::return_value = false;
+
+}  // namespace stack_btm_inq
+}  // namespace mock
+}  // namespace test
+
+// Mocked functions, if any
+void BTM_AddEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
   inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::BTM_AddEirService(p_eir_uuid, uuid16);
 }
-bool BTM_HasEirService(const uint32_t* p_eir_uuid, uint16_t uuid16) {
+void BTM_CancelInquiry(void) {
   inc_func_call_count(__func__);
-  return false;
-}
-bool btm_inq_find_bdaddr(const RawAddress& p_bda) {
-  inc_func_call_count(__func__);
-  return false;
-}
-tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService(tBTM_INQ_RESULTS* p_results,
-                                                uint16_t uuid16) {
-  inc_func_call_count(__func__);
-  return 0;
-}
-tBTM_INQ_INFO* BTM_InqDbFirst(void) {
-  inc_func_call_count(__func__);
-  return nullptr;
-}
-tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) {
-  inc_func_call_count(__func__);
-  return nullptr;
-}
-tBTM_INQ_INFO* BTM_InqDbRead(const RawAddress& p_bda) {
-  inc_func_call_count(__func__);
-  return nullptr;
+  test::mock::stack_btm_inq::BTM_CancelInquiry();
 }
 tBTM_STATUS BTM_CancelRemoteDeviceName(void) {
   inc_func_call_count(__func__);
-  return BTM_SUCCESS;
+  return test::mock::stack_btm_inq::BTM_CancelRemoteDeviceName();
 }
 tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda) {
   inc_func_call_count(__func__);
-  return BTM_SUCCESS;
+  return test::mock::stack_btm_inq::BTM_ClearInqDb(p_bda);
 }
-tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
-                                     tBTM_NAME_CMPL_CB* p_cb,
-                                     tBT_TRANSPORT transport) {
+void BTM_EnableInterlacedInquiryScan() {
   inc_func_call_count(__func__);
-  return BTM_SUCCESS;
+  test::mock::stack_btm_inq::BTM_EnableInterlacedInquiryScan();
 }
-tBTM_STATUS BTM_SetConnectability(uint16_t page_mode) {
+void BTM_EnableInterlacedPageScan() {
   inc_func_call_count(__func__);
-  return BTM_SUCCESS;
-}
-tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) {
-  inc_func_call_count(__func__);
-  return BTM_SUCCESS;
-}
-tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) {
-  inc_func_call_count(__func__);
-  return BTM_SUCCESS;
-}
-tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb,
-                             tBTM_CMPL_CB* p_cmpl_cb) {
-  inc_func_call_count(__func__);
-  return BTM_SUCCESS;
-}
-tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
-                                  uint64_t timeout_ms, tBTM_CMPL_CB* p_cb) {
-  inc_func_call_count(__func__);
-  return BTM_SUCCESS;
-}
-tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda) {
-  inc_func_call_count(__func__);
-  return nullptr;
-}
-tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda) {
-  inc_func_call_count(__func__);
-  return nullptr;
-}
-uint16_t BTM_IsInquiryActive(void) {
-  inc_func_call_count(__func__);
-  return 0;
+  test::mock::stack_btm_inq::BTM_EnableInterlacedPageScan();
 }
 uint8_t BTM_GetEirSupportedServices(uint32_t* p_eir_uuid, uint8_t** p,
                                     uint8_t max_num_uuid16,
                                     uint8_t* p_num_uuid16) {
   inc_func_call_count(__func__);
-  return 0;
+  return test::mock::stack_btm_inq::BTM_GetEirSupportedServices(
+      p_eir_uuid, p, max_num_uuid16, p_num_uuid16);
 }
 uint8_t BTM_GetEirUuidList(const uint8_t* p_eir, size_t eir_len,
                            uint8_t uuid_size, uint8_t* p_num_uuid,
                            uint8_t* p_uuid_list, uint8_t max_num_uuid) {
   inc_func_call_count(__func__);
-  return 0;
+  return test::mock::stack_btm_inq::BTM_GetEirUuidList(
+      p_eir, eir_len, uuid_size, p_num_uuid, p_uuid_list, max_num_uuid);
 }
-void BTM_AddEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
+bool BTM_HasEirService(const uint32_t* p_eir_uuid, uint16_t uuid16) {
   inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_HasEirService(p_eir_uuid, uuid16);
 }
-void BTM_CancelInquiry(void) { inc_func_call_count(__func__); }
-void BTM_EnableInterlacedInquiryScan() { inc_func_call_count(__func__); }
-void BTM_EnableInterlacedPageScan() { inc_func_call_count(__func__); }
-void btm_clr_inq_db(const RawAddress* p_bda) { inc_func_call_count(__func__); }
-void btm_clr_inq_result_flt(void) { inc_func_call_count(__func__); }
-void btm_inq_clear_ssp(void) { inc_func_call_count(__func__); }
-void btm_inq_db_free(void) { inc_func_call_count(__func__); }
-void btm_inq_db_init(void) { inc_func_call_count(__func__); }
-void btm_inq_db_reset(void) { inc_func_call_count(__func__); }
-void btm_inq_remote_name_timer_timeout(UNUSED_ATTR void* data) {
+tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService(tBTM_INQ_RESULTS* p_results,
+                                                uint16_t uuid16) {
   inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_HasInquiryEirService(p_results, uuid16);
 }
-void btm_inq_rmt_name_failed_cancelled(void) { inc_func_call_count(__func__); }
-void btm_inq_stop_on_ssp(void) { inc_func_call_count(__func__); }
+tBTM_INQ_INFO* BTM_InqDbFirst(void) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_InqDbFirst();
+}
+tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_InqDbNext(p_cur);
+}
+tBTM_INQ_INFO* BTM_InqDbRead(const RawAddress& p_bda) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_InqDbRead(p_bda);
+}
+uint16_t BTM_IsInquiryActive(void) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_IsInquiryActive();
+}
+bool BTM_IsRemoteNameKnown(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_IsRemoteNameKnown(bd_addr, transport);
+}
+tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
+                                     tBTM_NAME_CMPL_CB* p_cb,
+                                     tBT_TRANSPORT transport) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_ReadRemoteDeviceName(remote_bda, p_cb,
+                                                             transport);
+}
+void BTM_RemoveEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::BTM_RemoveEirService(p_eir_uuid, uuid16);
+}
+tBTM_STATUS BTM_SetConnectability(uint16_t page_mode) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_SetConnectability(page_mode);
+}
+tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_SetDiscoverability(inq_mode);
+}
+tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_SetInquiryMode(mode);
+}
+tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb,
+                             tBTM_CMPL_CB* p_cmpl_cb) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_StartInquiry(p_results_cb, p_cmpl_cb);
+}
+tBTM_STATUS BTM_WriteEIR(BT_HDR* p_buff) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::BTM_WriteEIR(p_buff);
+}
+void SendRemoteNameRequest(const RawAddress& raw_address) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::SendRemoteNameRequest(raw_address);
+}
+void btm_clear_all_pending_le_entry(void) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_clear_all_pending_le_entry();
+}
+void btm_clr_inq_db(const RawAddress* p_bda) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_clr_inq_db(p_bda);
+}
+void btm_clr_inq_result_flt(void) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_clr_inq_result_flt();
+}
+tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
+                                  uint64_t timeout_ms,
+                                  tBTM_NAME_CMPL_CB* p_cb) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::btm_initiate_rem_name(remote_bda, origin,
+                                                          timeout_ms, p_cb);
+}
+void btm_inq_clear_ssp(void) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_inq_clear_ssp();
+}
+tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::btm_inq_db_find(p_bda);
+}
+void btm_inq_db_free(void) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_inq_db_free();
+}
+void btm_inq_db_init(void) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_inq_db_init();
+}
+tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::btm_inq_db_new(p_bda);
+}
+void btm_inq_db_reset(void) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_inq_db_reset();
+}
+bool btm_inq_find_bdaddr(const RawAddress& p_bda) {
+  inc_func_call_count(__func__);
+  return test::mock::stack_btm_inq::btm_inq_find_bdaddr(p_bda);
+}
+void btm_inq_remote_name_timer_timeout(void* data) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_inq_remote_name_timer_timeout(data);
+}
+void btm_inq_rmt_name_failed_cancelled(void) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_inq_rmt_name_failed_cancelled();
+}
+void btm_inq_stop_on_ssp(void) {
+  inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_inq_stop_on_ssp();
+}
 void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode) {
   inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_process_cancel_complete(status, mode);
 }
 void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) {
   inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_process_inq_complete(status, mode);
 }
 void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len,
                              uint8_t inq_res_mode) {
   inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_process_inq_results(p, hci_evt_len,
+                                                     inq_res_mode);
 }
 void btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn,
                              uint16_t evt_len, tHCI_STATUS hci_status) {
   inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_process_remote_name(bda, bdn, evt_len,
+                                                     hci_status);
 }
 void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) {
   inc_func_call_count(__func__);
+  test::mock::stack_btm_inq::btm_set_eir_uuid(p_eir, p_results);
 }
-void btm_sort_inq_result(void) { inc_func_call_count(__func__); }
-bool BTM_IsRemoteNameKnown(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
+void btm_sort_inq_result(void) {
   inc_func_call_count(__func__);
-  return false;
+  test::mock::stack_btm_inq::btm_sort_inq_result();
 }
-void btm_clear_all_pending_le_entry(void) { inc_func_call_count(__func__); }
-
 // Mocked functions complete
 // END mockcify generation
diff --git a/system/test/mock/mock_stack_btm_inq.h b/system/test/mock/mock_stack_btm_inq.h
new file mode 100644
index 0000000..6265607
--- /dev/null
+++ b/system/test/mock/mock_stack_btm_inq.h
@@ -0,0 +1,573 @@
+/*
+ * Copyright 2023 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
+
+/*
+ * Generated mock file from original source file
+ *   Functions generated:43
+ *
+ *  mockcify.pl ver 0.6.0
+ */
+
+#include <cstdint>
+#include <functional>
+#include <map>
+#include <string>
+
+#include "test/common/mock_functions.h"
+
+// Original included files, if any
+// NOTE: Since this is a mock file with mock definitions some number of
+//       include files may not be required.  The include-what-you-use
+//       still applies, but crafting proper inclusion is out of scope
+//       for this effort.  This compilation unit may compile as-is, or
+//       may need attention to prune from (or add to ) the inclusion set.
+#include <base/logging.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <mutex>
+
+#include "advertise_data_parser.h"
+#include "common/time_util.h"
+#include "device/include/controller.h"
+#include "main/shim/btm_api.h"
+#include "main/shim/shim.h"
+#include "osi/include/allocator.h"
+#include "osi/include/log.h"
+#include "osi/include/osi.h"
+#include "osi/include/properties.h"
+#include "stack/btm/btm_ble_int.h"
+#include "stack/btm/btm_dev.h"
+#include "stack/btm/btm_int_types.h"
+#include "stack/include/acl_api.h"
+#include "stack/include/bt_hdr.h"
+#include "stack/include/btm_api.h"
+#include "stack/include/btm_ble_api.h"
+#include "stack/include/inq_hci_link_interface.h"
+#include "types/bluetooth/uuid.h"
+#include "types/raw_address.h"
+
+// Original usings
+using bluetooth::Uuid;
+
+// Mocked compile conditionals, if any
+
+namespace test {
+namespace mock {
+namespace stack_btm_inq {
+
+// Shared state between mocked functions and tests
+// Name: BTM_AddEirService
+// Params: uint32_t* p_eir_uuid, uint16_t uuid16
+// Return: void
+struct BTM_AddEirService {
+  std::function<void(uint32_t* p_eir_uuid, uint16_t uuid16)> body{
+      [](uint32_t* p_eir_uuid, uint16_t uuid16) {}};
+  void operator()(uint32_t* p_eir_uuid, uint16_t uuid16) {
+    body(p_eir_uuid, uuid16);
+  };
+};
+extern struct BTM_AddEirService BTM_AddEirService;
+
+// Name: BTM_CancelInquiry
+// Params: void
+// Return: void
+struct BTM_CancelInquiry {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct BTM_CancelInquiry BTM_CancelInquiry;
+
+// Name: BTM_CancelRemoteDeviceName
+// Params: void
+// Return: tBTM_STATUS
+struct BTM_CancelRemoteDeviceName {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(void)> body{[](void) { return return_value; }};
+  tBTM_STATUS operator()(void) { return body(); };
+};
+extern struct BTM_CancelRemoteDeviceName BTM_CancelRemoteDeviceName;
+
+// Name: BTM_ClearInqDb
+// Params: const RawAddress* p_bda
+// Return: tBTM_STATUS
+struct BTM_ClearInqDb {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(const RawAddress* p_bda)> body{
+      [](const RawAddress* p_bda) { return return_value; }};
+  tBTM_STATUS operator()(const RawAddress* p_bda) { return body(p_bda); };
+};
+extern struct BTM_ClearInqDb BTM_ClearInqDb;
+
+// Name: BTM_EnableInterlacedInquiryScan
+// Params:
+// Return: void
+struct BTM_EnableInterlacedInquiryScan {
+  std::function<void()> body{[]() {}};
+  void operator()() { body(); };
+};
+extern struct BTM_EnableInterlacedInquiryScan BTM_EnableInterlacedInquiryScan;
+
+// Name: BTM_EnableInterlacedPageScan
+// Params:
+// Return: void
+struct BTM_EnableInterlacedPageScan {
+  std::function<void()> body{[]() {}};
+  void operator()() { body(); };
+};
+extern struct BTM_EnableInterlacedPageScan BTM_EnableInterlacedPageScan;
+
+// Name: BTM_GetEirSupportedServices
+// Params: uint32_t* p_eir_uuid, uint8_t** p, uint8_t max_num_uuid16, uint8_t*
+// p_num_uuid16 Return: uint8_t
+struct BTM_GetEirSupportedServices {
+  static uint8_t return_value;
+  std::function<uint8_t(uint32_t* p_eir_uuid, uint8_t** p,
+                        uint8_t max_num_uuid16, uint8_t* p_num_uuid16)>
+      body{[](uint32_t* p_eir_uuid, uint8_t** p, uint8_t max_num_uuid16,
+              uint8_t* p_num_uuid16) { return return_value; }};
+  uint8_t operator()(uint32_t* p_eir_uuid, uint8_t** p, uint8_t max_num_uuid16,
+                     uint8_t* p_num_uuid16) {
+    return body(p_eir_uuid, p, max_num_uuid16, p_num_uuid16);
+  };
+};
+extern struct BTM_GetEirSupportedServices BTM_GetEirSupportedServices;
+
+// Name: BTM_GetEirUuidList
+// Params: const uint8_t* p_eir, size_t eir_len, uint8_t uuid_size, uint8_t*
+// p_num_uuid, uint8_t* p_uuid_list, uint8_t max_num_uuid Return: uint8_t
+struct BTM_GetEirUuidList {
+  static uint8_t return_value;
+  std::function<uint8_t(const uint8_t* p_eir, size_t eir_len, uint8_t uuid_size,
+                        uint8_t* p_num_uuid, uint8_t* p_uuid_list,
+                        uint8_t max_num_uuid)>
+      body{[](const uint8_t* p_eir, size_t eir_len, uint8_t uuid_size,
+              uint8_t* p_num_uuid, uint8_t* p_uuid_list,
+              uint8_t max_num_uuid) { return return_value; }};
+  uint8_t operator()(const uint8_t* p_eir, size_t eir_len, uint8_t uuid_size,
+                     uint8_t* p_num_uuid, uint8_t* p_uuid_list,
+                     uint8_t max_num_uuid) {
+    return body(p_eir, eir_len, uuid_size, p_num_uuid, p_uuid_list,
+                max_num_uuid);
+  };
+};
+extern struct BTM_GetEirUuidList BTM_GetEirUuidList;
+
+// Name: BTM_HasEirService
+// Params: const uint32_t* p_eir_uuid, uint16_t uuid16
+// Return: bool
+struct BTM_HasEirService {
+  static bool return_value;
+  std::function<bool(const uint32_t* p_eir_uuid, uint16_t uuid16)> body{
+      [](const uint32_t* p_eir_uuid, uint16_t uuid16) { return return_value; }};
+  bool operator()(const uint32_t* p_eir_uuid, uint16_t uuid16) {
+    return body(p_eir_uuid, uuid16);
+  };
+};
+extern struct BTM_HasEirService BTM_HasEirService;
+
+// Name: BTM_HasInquiryEirService
+// Params: tBTM_INQ_RESULTS* p_results, uint16_t uuid16
+// Return: tBTM_EIR_SEARCH_RESULT
+struct BTM_HasInquiryEirService {
+  static tBTM_EIR_SEARCH_RESULT return_value;
+  std::function<tBTM_EIR_SEARCH_RESULT(tBTM_INQ_RESULTS* p_results,
+                                       uint16_t uuid16)>
+      body{[](tBTM_INQ_RESULTS* p_results, uint16_t uuid16) {
+        return return_value;
+      }};
+  tBTM_EIR_SEARCH_RESULT operator()(tBTM_INQ_RESULTS* p_results,
+                                    uint16_t uuid16) {
+    return body(p_results, uuid16);
+  };
+};
+extern struct BTM_HasInquiryEirService BTM_HasInquiryEirService;
+
+// Name: BTM_InqDbFirst
+// Params: void
+// Return: tBTM_INQ_INFO*
+struct BTM_InqDbFirst {
+  static tBTM_INQ_INFO* return_value;
+  std::function<tBTM_INQ_INFO*(void)> body{[](void) { return return_value; }};
+  tBTM_INQ_INFO* operator()(void) { return body(); };
+};
+extern struct BTM_InqDbFirst BTM_InqDbFirst;
+
+// Name: BTM_InqDbNext
+// Params: tBTM_INQ_INFO* p_cur
+// Return: tBTM_INQ_INFO*
+struct BTM_InqDbNext {
+  static tBTM_INQ_INFO* return_value;
+  std::function<tBTM_INQ_INFO*(tBTM_INQ_INFO* p_cur)> body{
+      [](tBTM_INQ_INFO* p_cur) { return return_value; }};
+  tBTM_INQ_INFO* operator()(tBTM_INQ_INFO* p_cur) { return body(p_cur); };
+};
+extern struct BTM_InqDbNext BTM_InqDbNext;
+
+// Name: BTM_InqDbRead
+// Params: const RawAddress& p_bda
+// Return: tBTM_INQ_INFO*
+struct BTM_InqDbRead {
+  static tBTM_INQ_INFO* return_value;
+  std::function<tBTM_INQ_INFO*(const RawAddress& p_bda)> body{
+      [](const RawAddress& p_bda) { return return_value; }};
+  tBTM_INQ_INFO* operator()(const RawAddress& p_bda) { return body(p_bda); };
+};
+extern struct BTM_InqDbRead BTM_InqDbRead;
+
+// Name: BTM_IsInquiryActive
+// Params: void
+// Return: uint16_t
+struct BTM_IsInquiryActive {
+  static uint16_t return_value;
+  std::function<uint16_t(void)> body{[](void) { return return_value; }};
+  uint16_t operator()(void) { return body(); };
+};
+extern struct BTM_IsInquiryActive BTM_IsInquiryActive;
+
+// Name: BTM_IsRemoteNameKnown
+// Params: const RawAddress& bd_addr, tBT_TRANSPORT transport
+// Return: bool
+struct BTM_IsRemoteNameKnown {
+  static bool return_value;
+  std::function<bool(const RawAddress& bd_addr, tBT_TRANSPORT transport)> body{
+      [](const RawAddress& bd_addr, tBT_TRANSPORT transport) {
+        return return_value;
+      }};
+  bool operator()(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
+    return body(bd_addr, transport);
+  };
+};
+extern struct BTM_IsRemoteNameKnown BTM_IsRemoteNameKnown;
+
+// Name: BTM_ReadRemoteDeviceName
+// Params: const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb, tBT_TRANSPORT
+// transport Return: tBTM_STATUS
+struct BTM_ReadRemoteDeviceName {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(const RawAddress& remote_bda,
+                            tBTM_NAME_CMPL_CB* p_cb, tBT_TRANSPORT transport)>
+      body{[](const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb,
+              tBT_TRANSPORT transport) { return return_value; }};
+  tBTM_STATUS operator()(const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb,
+                         tBT_TRANSPORT transport) {
+    return body(remote_bda, p_cb, transport);
+  };
+};
+extern struct BTM_ReadRemoteDeviceName BTM_ReadRemoteDeviceName;
+
+// Name: BTM_RemoveEirService
+// Params: uint32_t* p_eir_uuid, uint16_t uuid16
+// Return: void
+struct BTM_RemoveEirService {
+  std::function<void(uint32_t* p_eir_uuid, uint16_t uuid16)> body{
+      [](uint32_t* p_eir_uuid, uint16_t uuid16) {}};
+  void operator()(uint32_t* p_eir_uuid, uint16_t uuid16) {
+    body(p_eir_uuid, uuid16);
+  };
+};
+extern struct BTM_RemoveEirService BTM_RemoveEirService;
+
+// Name: BTM_SetConnectability
+// Params: uint16_t page_mode
+// Return: tBTM_STATUS
+struct BTM_SetConnectability {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(uint16_t page_mode)> body{
+      [](uint16_t page_mode) { return return_value; }};
+  tBTM_STATUS operator()(uint16_t page_mode) { return body(page_mode); };
+};
+extern struct BTM_SetConnectability BTM_SetConnectability;
+
+// Name: BTM_SetDiscoverability
+// Params: uint16_t inq_mode
+// Return: tBTM_STATUS
+struct BTM_SetDiscoverability {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(uint16_t inq_mode)> body{
+      [](uint16_t inq_mode) { return return_value; }};
+  tBTM_STATUS operator()(uint16_t inq_mode) { return body(inq_mode); };
+};
+extern struct BTM_SetDiscoverability BTM_SetDiscoverability;
+
+// Name: BTM_SetInquiryMode
+// Params: uint8_t mode
+// Return: tBTM_STATUS
+struct BTM_SetInquiryMode {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(uint8_t mode)> body{
+      [](uint8_t mode) { return return_value; }};
+  tBTM_STATUS operator()(uint8_t mode) { return body(mode); };
+};
+extern struct BTM_SetInquiryMode BTM_SetInquiryMode;
+
+// Name: BTM_StartInquiry
+// Params: tBTM_INQ_RESULTS_CB* p_results_cb, tBTM_CMPL_CB* p_cmpl_cb
+// Return: tBTM_STATUS
+struct BTM_StartInquiry {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(tBTM_INQ_RESULTS_CB* p_results_cb,
+                            tBTM_CMPL_CB* p_cmpl_cb)>
+      body{[](tBTM_INQ_RESULTS_CB* p_results_cb, tBTM_CMPL_CB* p_cmpl_cb) {
+        return return_value;
+      }};
+  tBTM_STATUS operator()(tBTM_INQ_RESULTS_CB* p_results_cb,
+                         tBTM_CMPL_CB* p_cmpl_cb) {
+    return body(p_results_cb, p_cmpl_cb);
+  };
+};
+extern struct BTM_StartInquiry BTM_StartInquiry;
+
+// Name: BTM_WriteEIR
+// Params: BT_HDR* p_buff
+// Return: tBTM_STATUS
+struct BTM_WriteEIR {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(BT_HDR* p_buff)> body{
+      [](BT_HDR* p_buff) { return return_value; }};
+  tBTM_STATUS operator()(BT_HDR* p_buff) { return body(p_buff); };
+};
+extern struct BTM_WriteEIR BTM_WriteEIR;
+
+// Name: SendRemoteNameRequest
+// Params: const RawAddress& raw_address
+// Return: void
+struct SendRemoteNameRequest {
+  std::function<void(const RawAddress& raw_address)> body{
+      [](const RawAddress& raw_address) {}};
+  void operator()(const RawAddress& raw_address) { body(raw_address); };
+};
+extern struct SendRemoteNameRequest SendRemoteNameRequest;
+
+// Name: btm_clear_all_pending_le_entry
+// Params: void
+// Return: void
+struct btm_clear_all_pending_le_entry {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_clear_all_pending_le_entry btm_clear_all_pending_le_entry;
+
+// Name: btm_clr_inq_db
+// Params: const RawAddress* p_bda
+// Return: void
+struct btm_clr_inq_db {
+  std::function<void(const RawAddress* p_bda)> body{
+      [](const RawAddress* p_bda) {}};
+  void operator()(const RawAddress* p_bda) { body(p_bda); };
+};
+extern struct btm_clr_inq_db btm_clr_inq_db;
+
+// Name: btm_clr_inq_result_flt
+// Params: void
+// Return: void
+struct btm_clr_inq_result_flt {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_clr_inq_result_flt btm_clr_inq_result_flt;
+
+// Name: btm_initiate_rem_name
+// Params: const RawAddress& remote_bda, uint8_t origin, uint64_t timeout_ms,
+// tBTM_NAME_CMPL_CB* p_cb Return: tBTM_STATUS
+struct btm_initiate_rem_name {
+  static tBTM_STATUS return_value;
+  std::function<tBTM_STATUS(const RawAddress& remote_bda, uint8_t origin,
+                            uint64_t timeout_ms, tBTM_NAME_CMPL_CB* p_cb)>
+      body{[](const RawAddress& remote_bda, uint8_t origin, uint64_t timeout_ms,
+              tBTM_NAME_CMPL_CB* p_cb) { return return_value; }};
+  tBTM_STATUS operator()(const RawAddress& remote_bda, uint8_t origin,
+                         uint64_t timeout_ms, tBTM_NAME_CMPL_CB* p_cb) {
+    return body(remote_bda, origin, timeout_ms, p_cb);
+  };
+};
+extern struct btm_initiate_rem_name btm_initiate_rem_name;
+
+// Name: btm_inq_clear_ssp
+// Params: void
+// Return: void
+struct btm_inq_clear_ssp {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_inq_clear_ssp btm_inq_clear_ssp;
+
+// Name: btm_inq_db_find
+// Params: const RawAddress& p_bda
+// Return: tINQ_DB_ENT*
+struct btm_inq_db_find {
+  static tINQ_DB_ENT* return_value;
+  std::function<tINQ_DB_ENT*(const RawAddress& p_bda)> body{
+      [](const RawAddress& p_bda) { return return_value; }};
+  tINQ_DB_ENT* operator()(const RawAddress& p_bda) { return body(p_bda); };
+};
+extern struct btm_inq_db_find btm_inq_db_find;
+
+// Name: btm_inq_db_free
+// Params: void
+// Return: void
+struct btm_inq_db_free {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_inq_db_free btm_inq_db_free;
+
+// Name: btm_inq_db_init
+// Params: void
+// Return: void
+struct btm_inq_db_init {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_inq_db_init btm_inq_db_init;
+
+// Name: btm_inq_db_new
+// Params: const RawAddress& p_bda
+// Return: tINQ_DB_ENT*
+struct btm_inq_db_new {
+  static tINQ_DB_ENT* return_value;
+  std::function<tINQ_DB_ENT*(const RawAddress& p_bda)> body{
+      [](const RawAddress& p_bda) { return return_value; }};
+  tINQ_DB_ENT* operator()(const RawAddress& p_bda) { return body(p_bda); };
+};
+extern struct btm_inq_db_new btm_inq_db_new;
+
+// Name: btm_inq_db_reset
+// Params: void
+// Return: void
+struct btm_inq_db_reset {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_inq_db_reset btm_inq_db_reset;
+
+// Name: btm_inq_find_bdaddr
+// Params: const RawAddress& p_bda
+// Return: bool
+struct btm_inq_find_bdaddr {
+  static bool return_value;
+  std::function<bool(const RawAddress& p_bda)> body{
+      [](const RawAddress& p_bda) { return return_value; }};
+  bool operator()(const RawAddress& p_bda) { return body(p_bda); };
+};
+extern struct btm_inq_find_bdaddr btm_inq_find_bdaddr;
+
+// Name: btm_inq_remote_name_timer_timeout
+// Params:  void* data
+// Return: void
+struct btm_inq_remote_name_timer_timeout {
+  std::function<void(void* data)> body{[](void* data) {}};
+  void operator()(void* data) { body(data); };
+};
+extern struct btm_inq_remote_name_timer_timeout
+    btm_inq_remote_name_timer_timeout;
+
+// Name: btm_inq_rmt_name_failed_cancelled
+// Params: void
+// Return: void
+struct btm_inq_rmt_name_failed_cancelled {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_inq_rmt_name_failed_cancelled
+    btm_inq_rmt_name_failed_cancelled;
+
+// Name: btm_inq_stop_on_ssp
+// Params: void
+// Return: void
+struct btm_inq_stop_on_ssp {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_inq_stop_on_ssp btm_inq_stop_on_ssp;
+
+// Name: btm_process_cancel_complete
+// Params: tHCI_STATUS status, uint8_t mode
+// Return: void
+struct btm_process_cancel_complete {
+  std::function<void(tHCI_STATUS status, uint8_t mode)> body{
+      [](tHCI_STATUS status, uint8_t mode) {}};
+  void operator()(tHCI_STATUS status, uint8_t mode) { body(status, mode); };
+};
+extern struct btm_process_cancel_complete btm_process_cancel_complete;
+
+// Name: btm_process_inq_complete
+// Params: tHCI_STATUS status, uint8_t mode
+// Return: void
+struct btm_process_inq_complete {
+  std::function<void(tHCI_STATUS status, uint8_t mode)> body{
+      [](tHCI_STATUS status, uint8_t mode) {}};
+  void operator()(tHCI_STATUS status, uint8_t mode) { body(status, mode); };
+};
+extern struct btm_process_inq_complete btm_process_inq_complete;
+
+// Name: btm_process_inq_results
+// Params: const uint8_t* p, uint8_t hci_evt_len, uint8_t inq_res_mode
+// Return: void
+struct btm_process_inq_results {
+  std::function<void(const uint8_t* p, uint8_t hci_evt_len,
+                     uint8_t inq_res_mode)>
+      body{[](const uint8_t* p, uint8_t hci_evt_len, uint8_t inq_res_mode) {}};
+  void operator()(const uint8_t* p, uint8_t hci_evt_len, uint8_t inq_res_mode) {
+    body(p, hci_evt_len, inq_res_mode);
+  };
+};
+extern struct btm_process_inq_results btm_process_inq_results;
+
+// Name: btm_process_remote_name
+// Params: const RawAddress* bda, const BD_NAME bdn, uint16_t evt_len,
+// tHCI_STATUS hci_status Return: void
+struct btm_process_remote_name {
+  std::function<void(const RawAddress* bda, const BD_NAME bdn, uint16_t evt_len,
+                     tHCI_STATUS hci_status)>
+      body{[](const RawAddress* bda, const BD_NAME bdn, uint16_t evt_len,
+              tHCI_STATUS hci_status) {}};
+  void operator()(const RawAddress* bda, const BD_NAME bdn, uint16_t evt_len,
+                  tHCI_STATUS hci_status) {
+    body(bda, bdn, evt_len, hci_status);
+  };
+};
+extern struct btm_process_remote_name btm_process_remote_name;
+
+// Name: btm_set_eir_uuid
+// Params: const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results
+// Return: void
+struct btm_set_eir_uuid {
+  std::function<void(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results)> body{
+      [](const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) {}};
+  void operator()(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) {
+    body(p_eir, p_results);
+  };
+};
+extern struct btm_set_eir_uuid btm_set_eir_uuid;
+
+// Name: btm_sort_inq_result
+// Params: void
+// Return: void
+struct btm_sort_inq_result {
+  std::function<void(void)> body{[](void) {}};
+  void operator()(void) { body(); };
+};
+extern struct btm_sort_inq_result btm_sort_inq_result;
+
+}  // namespace stack_btm_inq
+}  // namespace mock
+}  // namespace test
+
+// END mockcify generation
\ No newline at end of file
diff --git a/system/test/mock/mock_stack_btm_sec.cc b/system/test/mock/mock_stack_btm_sec.cc
index 815a3fa..c424e06 100644
--- a/system/test/mock/mock_stack_btm_sec.cc
+++ b/system/test/mock/mock_stack_btm_sec.cc
@@ -132,10 +132,6 @@
   inc_func_call_count(__func__);
   return 0;
 }
-tBTM_SEC_DEV_REC* btm_sec_find_dev_by_sec_state(uint8_t state) {
-  inc_func_call_count(__func__);
-  return nullptr;
-}
 tBTM_SEC_SERV_REC* btm_sec_find_first_serv(bool is_originator, uint16_t psm) {
   inc_func_call_count(__func__);
   return nullptr;
diff --git a/system/test/mock/mock_stack_sdp_legacy_api.cc b/system/test/mock/mock_stack_sdp_legacy_api.cc
index f339a26..a41c690 100644
--- a/system/test/mock/mock_stack_sdp_legacy_api.cc
+++ b/system/test/mock/mock_stack_sdp_legacy_api.cc
@@ -1,4 +1,18 @@
-
+/*
+ * Copyright 2023 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 <cstdint>
 
diff --git a/system/test/mock/mock_stack_sdp_legacy_api.h b/system/test/mock/mock_stack_sdp_legacy_api.h
new file mode 100644
index 0000000..93d9077
--- /dev/null
+++ b/system/test/mock/mock_stack_sdp_legacy_api.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 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 "stack/include/sdp_api.h"
+
+namespace test {
+namespace mock {
+namespace stack_sdp_legacy {
+
+extern bluetooth::legacy::stack::sdp::tSdpApi api_;
+
+}  // namespace stack_sdp_legacy
+}  // namespace mock
+}  // namespace test
diff --git a/system/test/mock/mock_stack_smp_act.cc b/system/test/mock/mock_stack_smp_act.cc
index 06badb8..198a2b9 100644
--- a/system/test/mock/mock_stack_smp_act.cc
+++ b/system/test/mock/mock_stack_smp_act.cc
@@ -124,7 +124,6 @@
 struct smp_derive_link_key_from_long_term_key
     smp_derive_link_key_from_long_term_key;
 struct smp_br_process_link_key smp_br_process_link_key;
-struct smp_key_distribution_by_transport smp_key_distribution_by_transport;
 struct smp_br_pairing_complete smp_br_pairing_complete;
 
 }  // namespace stack_smp_act
@@ -417,10 +416,6 @@
   inc_func_call_count(__func__);
   test::mock::stack_smp_act::smp_br_process_link_key(p_cb, p_data);
 }
-void smp_key_distribution_by_transport(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
-  inc_func_call_count(__func__);
-  test::mock::stack_smp_act::smp_key_distribution_by_transport(p_cb, p_data);
-}
 void smp_br_pairing_complete(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
   inc_func_call_count(__func__);
   test::mock::stack_smp_act::smp_br_pairing_complete(p_cb, p_data);
diff --git a/system/test/mock/mock_stack_smp_act.h b/system/test/mock/mock_stack_smp_act.h
index 5754f3b..c45fecb 100644
--- a/system/test/mock/mock_stack_smp_act.h
+++ b/system/test/mock/mock_stack_smp_act.h
@@ -679,16 +679,6 @@
   void operator()(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { body(p_cb, p_data); };
 };
 extern struct smp_br_process_link_key smp_br_process_link_key;
-// Name: smp_key_distribution_by_transport
-// Params: tSMP_CB* p_cb, tSMP_INT_DATA* p_data
-// Returns: void
-struct smp_key_distribution_by_transport {
-  std::function<void(tSMP_CB* p_cb, tSMP_INT_DATA* p_data)> body{
-      [](tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {}};
-  void operator()(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { body(p_cb, p_data); };
-};
-extern struct smp_key_distribution_by_transport
-    smp_key_distribution_by_transport;
 // Name: smp_br_pairing_complete
 // Params: tSMP_CB* p_cb, tSMP_INT_DATA* p_data
 // Returns: void
diff --git a/tools/rootcanal/Android.bp b/tools/rootcanal/Android.bp
index 2b4b168..0b5e9d4 100644
--- a/tools/rootcanal/Android.bp
+++ b/tools/rootcanal/Android.bp
@@ -323,6 +323,7 @@
     srcs: [
         "test/async_manager_unittest.cc",
         "test/h4_parser_unittest.cc",
+        "test/pcap_filter_unittest.cc",
         "test/posix_socket_unittest.cc",
     ],
     header_libs: [
diff --git a/tools/rootcanal/include/hci/pcap_filter.h b/tools/rootcanal/include/hci/pcap_filter.h
index beac219..a6b3993 100644
--- a/tools/rootcanal/include/hci/pcap_filter.h
+++ b/tools/rootcanal/include/hci/pcap_filter.h
@@ -50,7 +50,6 @@
   std::vector<uint8_t> FilterHciCommand(std::vector<uint8_t> const& packet);
   std::vector<uint8_t> FilterHciEvent(std::vector<uint8_t> const& packet);
 
- private:
   // Specific filters for HCI commands.
   std::vector<uint8_t> FilterWriteLocalName(
       bluetooth::hci::CommandView& command);
@@ -87,9 +86,8 @@
 
   // Specific filter for any Gap data array.
   // The Gap data entries are modified in place.
-  void FilterGapData(std::vector<bluetooth::hci::GapData>& gap_data);
-  void FilterLengthAndData(
-      std::vector<bluetooth::hci::LengthAndData>& gap_data);
+  void FilterGapData(uint8_t* gap_data, size_t gap_data_len);
+  void FilterGapData(std::vector<uint8_t>& gap_data);
 
   // Helpers to replace local names.
   std::array<uint8_t, 248> ChangeDeviceName(
@@ -97,6 +95,7 @@
   std::vector<uint8_t> ChangeDeviceName(
       std::vector<uint8_t> const& device_name);
 
+ private:
   // Map device names to anonymous replacements.
   std::vector<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>>
       device_name_map{};
diff --git a/tools/rootcanal/lib/hci/pcap_filter.cc b/tools/rootcanal/lib/hci/pcap_filter.cc
index bab0d9d..b8edda8 100644
--- a/tools/rootcanal/lib/hci/pcap_filter.cc
+++ b/tools/rootcanal/lib/hci/pcap_filter.cc
@@ -168,41 +168,50 @@
 }
 
 // Replace device names in GAP entries.
-void PcapFilter::FilterGapData(std::vector<GapData>& gap_data) {
-  for (GapData& entry : gap_data) {
-    switch (entry.data_type_) {
-      case GapDataType::COMPLETE_LOCAL_NAME:
-      case GapDataType::SHORTENED_LOCAL_NAME:
-        entry.data_ = ChangeDeviceName(entry.data_);
-        break;
-      default:
-        break;
-    }
-  }
-}
+// TODO: extended advertising reports can be chunked across multiple
+// events, and a single GAP data entry can be segmented in two.
+// The filter should account for that and keep a state for partial
+// GAP entries.
+void PcapFilter::FilterGapData(uint8_t* gap_data, size_t gap_data_len) {
+  size_t offset = 0;
+  while ((offset + 2) <= gap_data_len) {
+    size_t length = gap_data[offset];
+    GapDataType data_type = static_cast<GapDataType>(gap_data[offset + 1]);
 
-void PcapFilter::FilterLengthAndData(
-    std::vector<bluetooth::hci::LengthAndData>& gap_data) {
-  for (LengthAndData& entry : gap_data) {
-    if (entry.data_.empty()) {
+    // Truncated entry.
+    if ((offset + length + 1) > gap_data_len) {
+      break;
+    }
+
+    // Empty entry.
+    if (length == 0) {
+      offset += 1;
       continue;
     }
-    switch (GapDataType(entry.data_[0])) {
+
+    // Apply the filter to entries that contain user data.
+    switch (data_type) {
       case GapDataType::COMPLETE_LOCAL_NAME:
       case GapDataType::SHORTENED_LOCAL_NAME: {
-        std::vector<uint8_t> device_name(entry.data_.begin() + 1,
-                                         entry.data_.end());
-        device_name = ChangeDeviceName(device_name);
-        entry.data_.insert(device_name.begin(), device_name.end(),
-                           entry.data_.begin() + 1);
+        auto start_pos = gap_data + offset + 1;
+        auto end_pos = gap_data + offset + length;
+        std::vector<uint8_t> new_name =
+            ChangeDeviceName(std::vector<uint8_t>{start_pos, end_pos});
+        std::copy(new_name.begin(), new_name.end(), start_pos);
         break;
       }
       default:
         break;
     }
+
+    offset += length + 1;
   }
 }
 
+void PcapFilter::FilterGapData(std::vector<uint8_t>& gap_data) {
+  FilterGapData(gap_data.data(), gap_data.size());
+}
+
 // Replace the local device name.
 std::vector<uint8_t> PcapFilter::FilterWriteLocalName(CommandView& command) {
   auto parameters = WriteLocalNameView::Create(command);
@@ -219,9 +228,10 @@
   auto parameters = WriteExtendedInquiryResponseView::Create(command);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> extended_inquiry_response =
+  std::array<uint8_t, 240> extended_inquiry_response =
       parameters.GetExtendedInquiryResponse();
-  FilterGapData(extended_inquiry_response);
+  FilterGapData(extended_inquiry_response.data(),
+                extended_inquiry_response.size());
   return WriteExtendedInquiryResponseBuilder::Create(
              parameters.GetFecRequired(), extended_inquiry_response)
       ->SerializeToBytes();
@@ -233,7 +243,7 @@
   auto parameters = LeSetAdvertisingDataView::Create(command);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> advertising_data = parameters.GetAdvertisingData();
+  std::vector<uint8_t> advertising_data = parameters.GetAdvertisingData();
   FilterGapData(advertising_data);
   return LeSetAdvertisingDataBuilder::Create(advertising_data)
       ->SerializeToBytes();
@@ -245,7 +255,7 @@
   auto parameters = LeSetScanResponseDataView::Create(command);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> advertising_data = parameters.GetAdvertisingData();
+  std::vector<uint8_t> advertising_data = parameters.GetAdvertisingData();
   FilterGapData(advertising_data);
   return LeSetScanResponseDataBuilder::Create(advertising_data)
       ->SerializeToBytes();
@@ -257,7 +267,7 @@
   auto parameters = LeSetExtendedAdvertisingDataView::Create(command);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> advertising_data = parameters.GetAdvertisingData();
+  std::vector<uint8_t> advertising_data = parameters.GetAdvertisingData();
   FilterGapData(advertising_data);
   return LeSetExtendedAdvertisingDataBuilder::Create(
              parameters.GetAdvertisingHandle(), parameters.GetOperation(),
@@ -272,7 +282,7 @@
   auto parameters = LeSetExtendedScanResponseDataView::Create(command);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> advertising_data = parameters.GetScanResponseData();
+  std::vector<uint8_t> advertising_data = parameters.GetScanResponseData();
   FilterGapData(advertising_data);
   return LeSetExtendedScanResponseDataBuilder::Create(
              parameters.GetAdvertisingHandle(), parameters.GetOperation(),
@@ -287,7 +297,7 @@
   auto parameters = LeSetPeriodicAdvertisingDataView::Create(command);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> advertising_data = parameters.GetAdvertisingData();
+  std::vector<uint8_t> advertising_data = parameters.GetAdvertisingData();
   FilterGapData(advertising_data);
   return LeSetPeriodicAdvertisingDataBuilder::Create(
              parameters.GetAdvertisingHandle(), parameters.GetOperation(),
@@ -301,7 +311,7 @@
   auto parameters = LeMultiAdvtSetDataView::Create(command);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> advertising_data = parameters.GetAdvertisingData();
+  std::vector<uint8_t> advertising_data = parameters.GetAdvertisingData();
   FilterGapData(advertising_data);
   return LeMultiAdvtSetDataBuilder::Create(advertising_data,
                                            parameters.GetAdvertisingInstance())
@@ -314,7 +324,7 @@
   auto parameters = LeMultiAdvtSetScanRespView::Create(command);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> advertising_data = parameters.GetAdvertisingData();
+  std::vector<uint8_t> advertising_data = parameters.GetAdvertisingData();
   FilterGapData(advertising_data);
   return LeMultiAdvtSetScanRespBuilder::Create(
              advertising_data, parameters.GetAdvertisingInstance())
@@ -345,10 +355,11 @@
       ReadExtendedInquiryResponseCompleteView::Create(command_complete);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> extended_inquiry_response =
+  std::array<uint8_t, 240> extended_inquiry_response =
       parameters.GetExtendedInquiryResponse();
   if (parameters.GetStatus() == ErrorCode::SUCCESS) {
-    FilterGapData(extended_inquiry_response);
+    FilterGapData(extended_inquiry_response.data(),
+                  extended_inquiry_response.size());
   }
 
   return ReadExtendedInquiryResponseCompleteBuilder::Create(
@@ -379,10 +390,10 @@
   auto parameters = ExtendedInquiryResultView::Create(event);
   ASSERT(parameters.IsValid());
 
-  std::vector<GapData> extended_inquiry_response =
+  std::array<uint8_t, 240> extended_inquiry_response =
       parameters.GetExtendedInquiryResponse();
-  FilterGapData(extended_inquiry_response);
-
+  FilterGapData(extended_inquiry_response.data(),
+                extended_inquiry_response.size());
   return ExtendedInquiryResultBuilder::Create(
              parameters.GetAddress(), parameters.GetPageScanRepetitionMode(),
              parameters.GetClassOfDevice(), parameters.GetClockOffset(),
@@ -398,7 +409,7 @@
 
   std::vector<LeAdvertisingResponse> responses = parameters.GetResponses();
   for (auto& response : responses) {
-    FilterLengthAndData(response.advertising_data_);
+    FilterGapData(response.advertising_data_);
   }
 
   return LeAdvertisingReportBuilder::Create(responses)->SerializeToBytes();
@@ -414,7 +425,7 @@
   std::vector<LeExtendedAdvertisingResponse> responses =
       parameters.GetResponses();
   for (auto& response : responses) {
-    FilterLengthAndData(response.advertising_data_);
+    FilterGapData(response.advertising_data_);
   }
 
   return LeExtendedAdvertisingReportBuilder::Create(responses)
diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc
index 57585c7..0ec16da 100644
--- a/tools/rootcanal/model/controller/dual_mode_controller.cc
+++ b/tools/rootcanal/model/controller/dual_mode_controller.cc
@@ -1546,13 +1546,14 @@
   auto command_view =
       bluetooth::hci::LeReadLocalSupportedFeaturesView::Create(command);
   ASSERT(command_view.IsValid());
+  uint64_t le_features = link_layer_controller_.GetLeSupportedFeatures();
   LOG_INFO("%s | LeReadLocalSupportedFeatures (%016llx)",
            GetAddress().ToString().c_str(),
-           static_cast<unsigned long long>(properties_.le_features));
+           static_cast<unsigned long long>(le_features));
 
   send_event_(
       bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create(
-          kNumCommandPackets, ErrorCode::SUCCESS, properties_.le_features));
+          kNumCommandPackets, ErrorCode::SUCCESS, le_features));
 }
 
 void DualModeController::LeSetRandomAddress(CommandView command) {
@@ -1592,8 +1593,7 @@
 }
 
 void DualModeController::LeSetAdvertisingData(CommandView command) {
-  auto command_view =
-      bluetooth::hci::LeSetAdvertisingDataRawView::Create(command);
+  auto command_view = bluetooth::hci::LeSetAdvertisingDataView::Create(command);
   ASSERT(command_view.IsValid());
   ErrorCode status = link_layer_controller_.LeSetAdvertisingData(
       command_view.GetAdvertisingData());
@@ -1603,7 +1603,7 @@
 
 void DualModeController::LeSetScanResponseData(CommandView command) {
   auto command_view =
-      bluetooth::hci::LeSetScanResponseDataRawView::Create(command);
+      bluetooth::hci::LeSetScanResponseDataView::Create(command);
   ASSERT(command_view.IsValid());
   ErrorCode status = link_layer_controller_.LeSetScanResponseData(
       command_view.GetAdvertisingData());
@@ -1945,7 +1945,7 @@
 
 void DualModeController::LeSetPeriodicAdvertisingData(CommandView command) {
   auto command_view =
-      bluetooth::hci::LeSetPeriodicAdvertisingDataRawView::Create(command);
+      bluetooth::hci::LeSetPeriodicAdvertisingDataView::Create(command);
   ASSERT(command_view.IsValid());
   ErrorCode status = link_layer_controller_.LeSetPeriodicAdvertisingData(
       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
@@ -2558,7 +2558,7 @@
       bluetooth::hci::LeSetExtendedAdvertisingDataView::Create(command);
   ASSERT(command_view.IsValid());
   auto raw_command_view =
-      bluetooth::hci::LeSetExtendedAdvertisingDataRawView::Create(command);
+      bluetooth::hci::LeSetExtendedAdvertisingDataView::Create(command);
   ASSERT(raw_command_view.IsValid());
   ErrorCode status = link_layer_controller_.LeSetExtendedAdvertisingData(
       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
@@ -2574,7 +2574,7 @@
       bluetooth::hci::LeSetExtendedScanResponseDataView::Create(command);
   ASSERT(command_view.IsValid());
   auto raw_command_view =
-      bluetooth::hci::LeSetExtendedScanResponseDataRawView::Create(command);
+      bluetooth::hci::LeSetExtendedScanResponseDataView::Create(command);
   ASSERT(raw_command_view.IsValid());
   ErrorCode status = link_layer_controller_.LeSetExtendedScanResponseData(
       command_view.GetAdvertisingHandle(), command_view.GetOperation(),
diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc
index df1d4dc..6fc81c8 100644
--- a/tools/rootcanal/model/controller/link_layer_controller.cc
+++ b/tools/rootcanal/model/controller/link_layer_controller.cc
@@ -2691,7 +2691,6 @@
               static_cast<uint8_t>(GetPageScanRepetitionMode()),
               class_of_device_, GetClockOffset(), rssi,
               extended_inquiry_response_));
-
     } break;
     default:
       LOG_WARN("Unhandled Incoming Inquiry of type %d",
@@ -2759,13 +2758,13 @@
               basic_inquiry_response);
       ASSERT(inquiry_response.IsValid());
 
-      send_event_(bluetooth::hci::ExtendedInquiryResultRawBuilder::Create(
+      send_event_(bluetooth::hci::ExtendedInquiryResultBuilder::Create(
           inquiry_response.GetSourceAddress(),
           static_cast<bluetooth::hci::PageScanRepetitionMode>(
               inquiry_response.GetPageScanRepetitionMode()),
           inquiry_response.GetClassOfDevice(),
           inquiry_response.GetClockOffset(), inquiry_response.GetRssi(),
-          extended_inquiry_response_));
+          inquiry_response.GetExtendedInquiryResponse()));
     } break;
     default:
       LOG_WARN("Unhandled Incoming Inquiry Response of type %d",
@@ -3181,7 +3180,7 @@
   if (LegacyAdvertising() && should_send_advertising_report &&
       !should_send_directed_advertising_report &&
       IsLeEventUnmasked(SubeventCode::ADVERTISING_REPORT)) {
-    bluetooth::hci::LeAdvertisingResponseRaw response;
+    bluetooth::hci::LeAdvertisingResponse response;
     response.address_type_ = resolved_advertising_address.GetAddressType();
     response.address_ = resolved_advertising_address.GetAddress();
     response.advertising_data_ = advertising_data;
@@ -3205,14 +3204,13 @@
         break;
     }
 
-    send_event_(
-        bluetooth::hci::LeAdvertisingReportRawBuilder::Create({response}));
+    send_event_(bluetooth::hci::LeAdvertisingReportBuilder::Create({response}));
   }
 
   // Extended scanning.
   if (ExtendedAdvertising() && should_send_advertising_report &&
       IsLeEventUnmasked(SubeventCode::EXTENDED_ADVERTISING_REPORT)) {
-    bluetooth::hci::LeExtendedAdvertisingResponseRaw response;
+    bluetooth::hci::LeExtendedAdvertisingResponse response;
     response.connectable_ = connectable_advertising;
     response.scannable_ = scannable_advertising;
     response.directed_ = directed_advertising;
@@ -3241,8 +3239,8 @@
     }
     response.advertising_data_ = advertising_data;
 
-    send_event_(bluetooth::hci::LeExtendedAdvertisingReportRawBuilder::Create(
-        {response}));
+    send_event_(
+        bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({response}));
   }
 
   // Did the user enable Active scanning ?
@@ -3635,7 +3633,7 @@
 
   if (should_send_advertising_report &&
       IsLeEventUnmasked(SubeventCode::EXTENDED_ADVERTISING_REPORT)) {
-    bluetooth::hci::LeExtendedAdvertisingResponseRaw response;
+    bluetooth::hci::LeExtendedAdvertisingResponse response;
     response.connectable_ = connectable_advertising;
     response.scannable_ = scannable_advertising;
     response.directed_ = directed_advertising;
@@ -3680,7 +3678,7 @@
           std::vector(advertising_data.begin() + offset,
                       advertising_data.begin() + offset + fragment_size);
       offset += fragment_size;
-      send_event_(bluetooth::hci::LeExtendedAdvertisingReportRawBuilder::Create(
+      send_event_(bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create(
           {response}));
     } while (offset < advertising_data.size());
   }
@@ -5039,19 +5037,18 @@
 
   if (LegacyAdvertising() && should_send_advertising_report &&
       IsLeEventUnmasked(SubeventCode::ADVERTISING_REPORT)) {
-    bluetooth::hci::LeAdvertisingResponseRaw response;
+    bluetooth::hci::LeAdvertisingResponse response;
     response.event_type_ = bluetooth::hci::AdvertisingEventType::SCAN_RESPONSE;
     response.address_ = resolved_advertising_address.GetAddress();
     response.address_type_ = resolved_advertising_address.GetAddressType();
     response.advertising_data_ = scan_response.GetScanResponseData();
     response.rssi_ = rssi;
-    send_event_(
-        bluetooth::hci::LeAdvertisingReportRawBuilder::Create({response}));
+    send_event_(bluetooth::hci::LeAdvertisingReportBuilder::Create({response}));
   }
 
   if (ExtendedAdvertising() && should_send_advertising_report &&
       IsLeEventUnmasked(SubeventCode::EXTENDED_ADVERTISING_REPORT)) {
-    bluetooth::hci::LeExtendedAdvertisingResponseRaw response;
+    bluetooth::hci::LeExtendedAdvertisingResponse response;
     response.address_ = resolved_advertising_address.GetAddress();
     response.address_type_ =
         static_cast<bluetooth::hci::DirectAdvertisingAddressType>(
@@ -5065,8 +5062,8 @@
     response.tx_power_ = 0x7F;
     response.advertising_data_ = scan_response.GetScanResponseData();
     response.rssi_ = rssi;
-    send_event_(bluetooth::hci::LeExtendedAdvertisingReportRawBuilder::Create(
-        {response}));
+    send_event_(
+        bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({response}));
   }
 }
 
diff --git a/tools/rootcanal/packets/hci/hci_packets.pdl b/tools/rootcanal/packets/hci/hci_packets.pdl
index 2eb4e5e..63d5bb9 100644
--- a/tools/rootcanal/packets/hci/hci_packets.pdl
+++ b/tools/rootcanal/packets/hci/hci_packets.pdl
@@ -8,66 +8,6 @@
   ENABLED = 0x01,
 }
 
-// https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
-enum GapDataType : 8 {
-  INVALID = 0x00,
-  FLAGS = 0x01,
-  INCOMPLETE_LIST_16_BIT_UUIDS = 0x02,
-  COMPLETE_LIST_16_BIT_UUIDS = 0x03,
-  INCOMPLETE_LIST_32_BIT_UUIDS = 0x04,
-  COMPLETE_LIST_32_BIT_UUIDS = 0x05,
-  INCOMPLETE_LIST_128_BIT_UUIDS = 0x06,
-  COMPLETE_LIST_128_BIT_UUIDS = 0x07,
-  SHORTENED_LOCAL_NAME = 0x08,
-  COMPLETE_LOCAL_NAME = 0x09,
-  TX_POWER_LEVEL = 0x0A,
-  CLASS_OF_DEVICE = 0x0D,
-  SIMPLE_PAIRING_HASH_C = 0x0E,
-  SIMPLE_PAIRING_RANDOMIZER_R = 0x0F,
-  DEVICE_ID = 0x10,
-  SECURITY_MANAGER_OOB_FLAGS = 0x11,
-  SLAVE_CONNECTION_INTERVAL_RANGE = 0x12,
-  LIST_16BIT_SERVICE_SOLICITATION_UUIDS = 0x14,
-  LIST_128BIT_SERVICE_SOLICITATION_UUIDS = 0x15,
-  SERVICE_DATA_16_BIT_UUIDS = 0x16,
-  PUBLIC_TARGET_ADDRESS = 0x17,
-  RANDOM_TARGET_ADDRESS = 0x18,
-  APPEARANCE = 0x19,
-  ADVERTISING_INTERVAL = 0x1A,
-  LE_BLUETOOTH_DEVICE_ADDRESS = 0x1B,
-  LE_ROLE = 0x1C,
-  SIMPLE_PAIRING_HASH_C_256 = 0x1D,
-  SIMPLE_PAIRING_RANDOMIZER_R_256 = 0x1E,
-  LIST_32BIT_SERVICE_SOLICITATION_UUIDS = 0x1F,
-  SERVICE_DATA_32_BIT_UUIDS = 0x20,
-  SERVICE_DATA_128_BIT_UUIDS = 0x21,
-  LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE = 0x22,
-  LE_SECURE_CONNECTIONS_RANDOM_VALUE = 0x23,
-  URI = 0x24,
-  INDOOR_POSITIONING = 0x25,
-  TRANSPORT_DISCOVERY_DATA = 0x26,
-  LE_SUPPORTED_FEATURES = 0x27,
-  CHANNEL_MAP_UPDATE_INDICATION = 0x28,
-  MESH_PB_ADV = 0x29,
-  MESH_MESSAGE = 0x2A,
-  MESH_BEACON = 0x2B,
-  BIG_INFO = 0x2C,
-  BROADCAST_CODE = 0x2D,
-  THREE_D_INFORMATION_DATA = 0x3D,
-  MANUFACTURER_SPECIFIC_DATA = 0xFF,
-}
-
-struct LengthAndData {
-  _size_(data) : 8,
-  data: 8[],
-}
-
-struct GapData {
-  _size_(data) : 8, // Including one byte for data_type
-  data_type : GapDataType,
-  data : 8[+1],
-}
-
 // HCI ACL Packets
 
 enum PacketBoundaryFlag : 2 {
@@ -2426,13 +2366,12 @@
 packet ReadExtendedInquiryResponseComplete : CommandComplete (command_op_code = READ_EXTENDED_INQUIRY_RESPONSE) {
   status : ErrorCode,
   fec_required : FecRequired,
-  extended_inquiry_response : GapData[],
+  extended_inquiry_response : 8[240],
 }
 
 packet WriteExtendedInquiryResponse : Command (op_code = WRITE_EXTENDED_INQUIRY_RESPONSE) {
   fec_required : FecRequired,
-  extended_inquiry_response : GapData[],
-  _padding_[240], // Zero padding GapData[] to be 240 octets
+  extended_inquiry_response : 8[240],
 }
 
 packet WriteExtendedInquiryResponseComplete : CommandComplete (command_op_code = WRITE_EXTENDED_INQUIRY_RESPONSE) {
@@ -3246,12 +3185,6 @@
 
 packet LeSetAdvertisingData : Command (op_code = LE_SET_ADVERTISING_DATA) {
   _size_(advertising_data) : 8,
-  advertising_data : GapData[],
-  _padding_[31], // Zero padding to 31 bytes of advertising_data
-}
-
-packet LeSetAdvertisingDataRaw : Command (op_code = LE_SET_ADVERTISING_DATA) {
-  _size_(advertising_data) : 8,
   advertising_data : 8[],
   _padding_[31], // Zero padding to 31 bytes of advertising_data
 }
@@ -3262,12 +3195,6 @@
 
 packet LeSetScanResponseData : Command (op_code = LE_SET_SCAN_RESPONSE_DATA) {
   _size_(advertising_data) : 8,
-  advertising_data : GapData[],
-  _padding_[31], // Zero padding to 31 bytes of advertising_data
-}
-
-packet LeSetScanResponseDataRaw : Command (op_code = LE_SET_SCAN_RESPONSE_DATA) {
-  _size_(advertising_data) : 8,
   advertising_data : 8[],
   _padding_[31], // Zero padding to 31 bytes of advertising_data
 }
@@ -3897,23 +3824,13 @@
   fragment_preference : FragmentPreference,
   _reserved_ : 7,
   _size_(advertising_data) : 8,
-  advertising_data : GapData[],
+  advertising_data : 8[],
 }
 
 test LeSetExtendedAdvertisingData {
   "\x37\x20\x12\x00\x03\x01\x0e\x02\x01\x02\x0a\x09\x50\x69\x78\x65\x6c\x20\x33\x20\x58",
 }
 
-packet LeSetExtendedAdvertisingDataRaw : Command (op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
-  advertising_handle : 8,
-  operation : Operation,
-  _reserved_ : 5,
-  fragment_preference : FragmentPreference,
-  _reserved_ : 7,
-  _size_(advertising_data) : 8,
-  advertising_data : 8[],
-}
-
 packet LeSetExtendedAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
   status : ErrorCode,
 }
@@ -3929,16 +3846,6 @@
   fragment_preference : FragmentPreference,
   _reserved_ : 7,
   _size_(scan_response_data) : 8,
-  scan_response_data : GapData[],
-}
-
-packet LeSetExtendedScanResponseDataRaw : Command (op_code = LE_SET_EXTENDED_SCAN_RESPONSE_DATA) {
-  advertising_handle : 8,
-  operation : Operation,
-  _reserved_ : 5,
-  fragment_preference : FragmentPreference,
-  _reserved_ : 7,
-  _size_(scan_response_data) : 8,
   scan_response_data : 8[],
 }
 
@@ -4048,14 +3955,6 @@
   operation : Operation,
   _reserved_ : 5,
   _size_(advertising_data) : 8,
-  advertising_data : GapData[],
-}
-
-packet LeSetPeriodicAdvertisingDataRaw : Command (op_code = LE_SET_PERIODIC_ADVERTISING_DATA) {
-  advertising_handle : 8,
-  operation : Operation,
-  _reserved_ : 5,
-  _size_(advertising_data) : 8,
   advertising_data : 8[],
 }
 
@@ -4856,7 +4755,7 @@
 
 packet LeMultiAdvtSetData : LeMultiAdvt (sub_cmd = SET_DATA) {
   _size_(advertising_data) : 8,
-  advertising_data : GapData[],
+  advertising_data : 8[],
   _padding_[31], // Zero padding to 31 bytes of advertising_data
   advertising_instance : 8,
 }
@@ -4866,7 +4765,7 @@
 
 packet LeMultiAdvtSetScanResp : LeMultiAdvt (sub_cmd = SET_SCAN_RESP) {
   _size_(advertising_data) : 8,
-  advertising_data : GapData[],
+  advertising_data : 8[],
   _padding_[31], // Zero padding to 31 bytes of advertising_data
   advertising_instance : 8,
 }
@@ -5603,29 +5502,12 @@
   clock_offset : 15,
   _reserved_ : 1,
   rssi : 8,
-  extended_inquiry_response : GapData[],
-  // Extended inquiry Result is always 255 bytes long
-  // padded GapData with zeroes as necessary
-  // Refer to BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part C Section 8 on page 1340
-  _padding_[240],
-}
-
-packet ExtendedInquiryResultRaw : Event (event_code = EXTENDED_INQUIRY_RESULT) {
-  _fixed_ = 0x01 : 8,
-  address : Address,
-  page_scan_repetition_mode : PageScanRepetitionMode,
-  _reserved_ : 8,
-  class_of_device : ClassOfDevice,
-  clock_offset : 15,
-  _reserved_ : 1,
-  rssi : 8,
-  // Extended inquiry Result is always 255 bytes long
-  // padded GapData with zeroes as necessary
+  // Extended inquiry Result is always 255 bytes long;
+  // the gap data is padded with zeros as necessary.
   // Refer to BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part C Section 8 on page 1340
   extended_inquiry_response : 8[240],
 }
 
-
 packet EncryptionKeyRefreshComplete : Event (event_code = ENCRYPTION_KEY_REFRESH_COMPLETE) {
   status : ErrorCode,
   connection_handle : 12,
@@ -5747,7 +5629,7 @@
   address_type : AddressType,
   address : Address,
   _size_(advertising_data) : 8,
-  advertising_data : LengthAndData[],
+  advertising_data : 8[],
   rssi : 8,
 }
 
@@ -5756,20 +5638,6 @@
   responses : LeAdvertisingResponse[],
 }
 
-struct LeAdvertisingResponseRaw {
-  event_type : AdvertisingEventType,
-  address_type : AddressType,
-  address : Address,
-  _size_(advertising_data) : 8,
-  advertising_data : 8[],
-  rssi : 8,
-}
-
-packet LeAdvertisingReportRaw : LeMetaEvent (subevent_code = ADVERTISING_REPORT) {
-  _count_(responses) : 8,
-  responses : LeAdvertisingResponseRaw[],
-}
-
 packet LeConnectionUpdateComplete : LeMetaEvent (subevent_code = CONNECTION_UPDATE_COMPLETE) {
   status : ErrorCode,
   connection_handle : 12,
@@ -5901,36 +5769,9 @@
   direct_address_type : DirectAdvertisingAddressType,
   direct_address : Address,
   _size_(advertising_data) : 8,
-  advertising_data: LengthAndData[],
-}
-
-struct LeExtendedAdvertisingResponseRaw {
-  connectable : 1,
-  scannable : 1,
-  directed : 1,
-  scan_response : 1,
-  legacy : 1,
-  data_status : DataStatus,
-  _reserved_ : 9,
-  address_type : DirectAdvertisingAddressType,
-  address : Address,
-  primary_phy : PrimaryPhyType,
-  secondary_phy : SecondaryPhyType,
-  advertising_sid : 8, // SID subfield in the ADI field
-  tx_power : 8,
-  rssi : 8, // -127 to +20 (0x7F means not available)
-  periodic_advertising_interval : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
-  direct_address_type : DirectAdvertisingAddressType,
-  direct_address : Address,
-  _size_(advertising_data) : 8,
   advertising_data: 8[],
 }
 
-packet LeExtendedAdvertisingReportRaw : LeMetaEvent (subevent_code = EXTENDED_ADVERTISING_REPORT) {
-  _count_(responses) : 8,
-  responses : LeExtendedAdvertisingResponseRaw[],
-}
-
 packet LeExtendedAdvertisingReport : LeMetaEvent (subevent_code = EXTENDED_ADVERTISING_REPORT) {
   _count_(responses) : 8,
   responses : LeExtendedAdvertisingResponse[],
@@ -6544,3 +6385,52 @@
   "\x02\x01\x00\x01\x02\x03\x04\x05\x10\x00",
   "\x02\x02\xf0\xf1\xf2\xf3\xf4\xf5\xaa\x02",
 }
+
+// https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
+enum GapDataType : 8 {
+  INVALID = 0x00,
+  FLAGS = 0x01,
+  INCOMPLETE_LIST_16_BIT_UUIDS = 0x02,
+  COMPLETE_LIST_16_BIT_UUIDS = 0x03,
+  INCOMPLETE_LIST_32_BIT_UUIDS = 0x04,
+  COMPLETE_LIST_32_BIT_UUIDS = 0x05,
+  INCOMPLETE_LIST_128_BIT_UUIDS = 0x06,
+  COMPLETE_LIST_128_BIT_UUIDS = 0x07,
+  SHORTENED_LOCAL_NAME = 0x08,
+  COMPLETE_LOCAL_NAME = 0x09,
+  TX_POWER_LEVEL = 0x0A,
+  CLASS_OF_DEVICE = 0x0D,
+  SIMPLE_PAIRING_HASH_C = 0x0E,
+  SIMPLE_PAIRING_RANDOMIZER_R = 0x0F,
+  DEVICE_ID = 0x10,
+  SECURITY_MANAGER_OOB_FLAGS = 0x11,
+  SLAVE_CONNECTION_INTERVAL_RANGE = 0x12,
+  LIST_16BIT_SERVICE_SOLICITATION_UUIDS = 0x14,
+  LIST_128BIT_SERVICE_SOLICITATION_UUIDS = 0x15,
+  SERVICE_DATA_16_BIT_UUIDS = 0x16,
+  PUBLIC_TARGET_ADDRESS = 0x17,
+  RANDOM_TARGET_ADDRESS = 0x18,
+  APPEARANCE = 0x19,
+  ADVERTISING_INTERVAL = 0x1A,
+  LE_BLUETOOTH_DEVICE_ADDRESS = 0x1B,
+  LE_ROLE = 0x1C,
+  SIMPLE_PAIRING_HASH_C_256 = 0x1D,
+  SIMPLE_PAIRING_RANDOMIZER_R_256 = 0x1E,
+  LIST_32BIT_SERVICE_SOLICITATION_UUIDS = 0x1F,
+  SERVICE_DATA_32_BIT_UUIDS = 0x20,
+  SERVICE_DATA_128_BIT_UUIDS = 0x21,
+  LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE = 0x22,
+  LE_SECURE_CONNECTIONS_RANDOM_VALUE = 0x23,
+  URI = 0x24,
+  INDOOR_POSITIONING = 0x25,
+  TRANSPORT_DISCOVERY_DATA = 0x26,
+  LE_SUPPORTED_FEATURES = 0x27,
+  CHANNEL_MAP_UPDATE_INDICATION = 0x28,
+  MESH_PB_ADV = 0x29,
+  MESH_MESSAGE = 0x2A,
+  MESH_BEACON = 0x2B,
+  BIG_INFO = 0x2C,
+  BROADCAST_CODE = 0x2D,
+  THREE_D_INFORMATION_DATA = 0x3D,
+  MANUFACTURER_SPECIFIC_DATA = 0xFF,
+}
diff --git a/tools/rootcanal/test/pcap_filter_unittest.cc b/tools/rootcanal/test/pcap_filter_unittest.cc
new file mode 100644
index 0000000..8803540
--- /dev/null
+++ b/tools/rootcanal/test/pcap_filter_unittest.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2022 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/pcap_filter.h"
+
+#include <gtest/gtest.h>
+
+#include "hci/hci_packets.h"
+
+namespace rootcanal {
+
+using namespace bluetooth::hci;
+
+class PcapFilterTest : public ::testing::Test {
+ public:
+  PcapFilterTest() = default;
+  ~PcapFilterTest() override = default;
+
+ protected:
+  PcapFilter pcap_filter_;
+};
+
+TEST_F(PcapFilterTest, UnchangedIfNotDeviceName) {
+  // Leaves gap data entries that do not contain a name unchanged.
+  std::vector<uint8_t> input_gap_data{
+      0x2, static_cast<uint8_t>(GapDataType::FLAGS), 0x0};
+  std::vector<uint8_t> output_gap_data{input_gap_data.begin(),
+                                       input_gap_data.end()};
+  pcap_filter_.FilterGapData(output_gap_data);
+  ASSERT_EQ(input_gap_data, output_gap_data);
+}
+
+TEST_F(PcapFilterTest, ReplacesShortenedDeviceName) {
+  // Replaces the input gap data once, with a name of equal length.
+  std::vector<uint8_t> input_gap_data{
+      0x2,
+      static_cast<uint8_t>(GapDataType::FLAGS),
+      0x0,
+      0x4,
+      static_cast<uint8_t>(GapDataType::SHORTENED_LOCAL_NAME),
+      0xa,
+      0xb,
+      0xc};
+  std::vector<uint8_t> output_gap_data_1{input_gap_data.begin(),
+                                         input_gap_data.end()};
+  pcap_filter_.FilterGapData(output_gap_data_1);
+  ASSERT_EQ(input_gap_data.size(), output_gap_data_1.size());
+  ASSERT_NE(input_gap_data, output_gap_data_1);
+
+  // Replaces the input gap data a second time with the same name.
+  std::vector<uint8_t> output_gap_data_2{input_gap_data.begin(),
+                                         input_gap_data.end()};
+  pcap_filter_.FilterGapData(output_gap_data_2);
+  ASSERT_EQ(output_gap_data_1, output_gap_data_2);
+}
+
+TEST_F(PcapFilterTest, ReplacesCompleteDeviceName) {
+  // Replaces the input gap data once, with a name of equal length.
+  std::vector<uint8_t> input_gap_data{
+      0x2,
+      static_cast<uint8_t>(GapDataType::FLAGS),
+      0x0,
+      0x4,
+      static_cast<uint8_t>(GapDataType::COMPLETE_LOCAL_NAME),
+      0xa,
+      0xb,
+      0xc};
+  std::vector<uint8_t> output_gap_data_1{input_gap_data.begin(),
+                                         input_gap_data.end()};
+  pcap_filter_.FilterGapData(output_gap_data_1);
+  ASSERT_EQ(input_gap_data.size(), output_gap_data_1.size());
+  ASSERT_NE(input_gap_data, output_gap_data_1);
+
+  // Replaces the input gap data a second time with the same name.
+  std::vector<uint8_t> output_gap_data_2{input_gap_data.begin(),
+                                         input_gap_data.end()};
+  pcap_filter_.FilterGapData(output_gap_data_2);
+  ASSERT_EQ(output_gap_data_1, output_gap_data_2);
+}
+
+}  // namespace rootcanal