diff options
118 files changed, 2593 insertions, 3038 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING index a3778c855e..a676392014 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 382a61e146..131a4aa12e 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 @@ public class HeadsetStateMachine extends StateMachine { 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 b63078329b..35010f0489 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 @@ public class HeadsetClientStateMachine extends StateMachine { * 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 2a9648920e..632bdb30a9 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.InstrumentationRegistry; 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 com.android.bluetooth.btservice.storage.DatabaseManager; 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 @@ public class HeadsetStateMachineTest { @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 @@ public class HeadsetStateMachineTest { "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 bfda3f757b..e377201cbd 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 androidx.test.runner.AndroidJUnit4; 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 @@ public class HeadsetClientStateMachineTest { // 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 2a474ecac6..4f0bd3c4df 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/opp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/opp.py @@ -122,7 +122,7 @@ class OPPProxy(ProfileProxy): Take action to create an rfcomm channel for an OBEX connection. """ - self._android.SendFile() + self._android.SendFile('PTS') return "OK" @@ -132,7 +132,7 @@ class OPPProxy(ProfileProxy): 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 6f2fd329e5..1119acb73e 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 @@ class AndroidInternal(val context: Context) : AndroidImplBase(), Closeable { 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 @@ class AndroidInternal(val context: Context) : AndroidImplBase(), Closeable { } } - 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 @@ class AndroidInternal(val context: Context) : AndroidImplBase(), Closeable { } } - 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 5fd5e3084f..1d73c36f9f 100644 --- a/android/pandora/test/Android.bp +++ b/android/pandora/test/Android.bp @@ -20,9 +20,8 @@ python_test_host { 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 0eeabc4867..24332e22ef 100644 --- a/android/pandora/test/asha_test.py +++ b/android/pandora/test/asha_test.py @@ -18,7 +18,8 @@ import enum 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 @@ class Ear(enum.IntEnum): 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 69f6cca72a..688ee1cf1c 100755 --- a/android/pandora/test/avatar.sh +++ b/android/pandora/test/avatar.sh @@ -24,10 +24,9 @@ _VENV_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/avatar/venv" _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 0b1335f104..0000000000 --- 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 27ac5be15a..0000000000 --- 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 156e27bce1..df8b912cc4 100644 --- a/android/pandora/test/gatt_test.py +++ b/android/pandora/test/gatt_test.py @@ -16,7 +16,8 @@ import asyncio 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 cb7f6eb492..0000000000 --- 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 d963e31bf0..f1a27ab5fd 100644 --- a/android/pandora/test/main.py +++ b/android/pandora/test/main.py @@ -13,21 +13,23 @@ from typing import List, Tuple _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 75665b4748..f9ff30807a 100644 --- a/framework/java/android/bluetooth/BluetoothHapClient.java +++ b/framework/java/android/bluetooth/BluetoothHapClient.java @@ -88,11 +88,9 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable 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 af7e0fe44b..1f749be4eb 100644 --- a/framework/java/android/bluetooth/BluetoothLeAudio.java +++ b/framework/java/android/bluetooth/BluetoothLeAudio.java @@ -91,10 +91,8 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { 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 89fb54e77f..d724335d3b 100644 --- a/framework/java/android/bluetooth/BluetoothLeBroadcast.java +++ b/framework/java/android/bluetooth/BluetoothLeBroadcast.java @@ -194,11 +194,12 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi 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 8620ed67ee..7eaebcd8d8 100644 --- a/framework/java/android/bluetooth/BluetoothProfileConnector.java +++ b/framework/java/android/bluetooth/BluetoothProfileConnector.java @@ -131,7 +131,7 @@ public abstract class BluetoothProfileConnector<T> { 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 @@ public abstract class BluetoothProfileConnector<T> { 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 116783755b..1eb59dfb29 100644 --- a/framework/java/android/bluetooth/BluetoothUtils.java +++ b/framework/java/android/bluetooth/BluetoothUtils.java @@ -35,10 +35,8 @@ public final class BluetoothUtils { */ 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 4c495cad25..530e2081e5 100644 --- a/pandora/interfaces/pandora_experimental/_android.proto +++ b/pandora/interfaces/pandora_experimental/_android.proto @@ -21,7 +21,8 @@ service Android { // 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 @@ message SetAccessPermissionRequest { 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 @@ message InternalConnectionRef { // 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 fab9100c56..8db1a56026 100644 --- a/pandora/server/bumble_experimental/asha.py +++ b/pandora/server/bumble_experimental/asha.py @@ -17,7 +17,6 @@ import grpc 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 @@ from bumble.gatt import ( 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 323a43e9c4..adbb6dd54f 100644 --- a/pandora/server/bumble_experimental/gatt.py +++ b/pandora/server/bumble_experimental/gatt.py @@ -16,10 +16,10 @@ import asyncio 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 a035338b4f..0000000000 --- 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 197ec46e57..0000000000 --- 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 8fb2c3247d..958ebc0747 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.RequiresPermission; 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.Process; 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 @@ class BluetoothManagerService { 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 @@ class BluetoothManagerService { 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 @@ class BluetoothManagerService { // 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 IBluetooth mBluetooth = null; - private IBluetoothGatt mBluetoothGatt; - private boolean mBinding; - private boolean mUnbinding; + 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 @@ class BluetoothManagerService { 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 @@ class BluetoothManagerService { } } - @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 @@ class BluetoothManagerService { 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 @@ class BluetoothManagerService { "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 @@ class BluetoothManagerService { .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 @@ class BluetoothManagerService { 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 @@ class BluetoothManagerService { if (mBluetoothAirplaneModeListener != null) { mBluetoothAirplaneModeListener.start(mBluetoothModeChangeHelper); } - registerForProvisioningStateChange(); - mBluetoothDeviceConfigListener = new BluetoothDeviceConfigListener(this, DBG); loadApmEnhancementStateFromResource(); } @@ -1671,9 +1586,7 @@ class BluetoothManagerService { 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 @@ class BluetoothManagerService { 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 @@ class BluetoothManagerService { } /** - * 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 @@ class BluetoothManagerService { } 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 9eaffc16bd..0000000000 --- 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 a8eb5a1daa..c8026837f9 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 @@ public class BluetoothManagerServiceTest { 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 @@ public class BluetoothManagerServiceTest { } 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 @@ public class BluetoothManagerServiceTest { 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 @@ public class BluetoothManagerServiceTest { // 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 @@ public class BluetoothManagerServiceTest { // 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 @@ public class BluetoothManagerServiceTest { 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 db9186094e..2fc1025e7d 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 @@ class GattConnectTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 @@ class GattConnectTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 @@ class GattConnectTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 @@ class GattConnectTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 @@ class GattConnectTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 @@ class GattConnectTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 @@ class GattConnectTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 eab98feeaf..eb96468da7 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 @@ class GattConnectWithIrkTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): # 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 @@ class GattConnectWithIrkTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 @@ class GattConnectWithIrkTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): # 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 9061f13f1a..40ab025d54 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 @@ class IrkRotationTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): 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 c1948e7d95..414be14938 100644 --- a/system/blueberry/utils/bt_test_utils.py +++ b/system/blueberry/utils/bt_test_utils.py @@ -206,12 +206,13 @@ def write_record_file(file_name, audio_params, frames): 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 @@ def get_mac_address_of_generic_advertisement(scan_device, adv_device): 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 d05fb13d20..26ca647370 100644 --- a/system/bta/Android.bp +++ b/system/bta/Android.bp @@ -202,6 +202,7 @@ cc_test { ":LegacyStackSdp", ":TestCommonLogMsg", ":TestCommonMockFunctions", + ":TestFakeOsi", ":TestMockBtif", ":TestMockMainShim", ":TestMockStackBtm", @@ -237,7 +238,6 @@ cc_test { "libchrome", "libcom.android.sysprop.bluetooth", "libgmock", - "libosi", ], data: [ ":audio_set_configurations_bfbs", @@ -302,16 +302,31 @@ cc_test { "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 @@ cc_test { "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 b8a8a24518..25a7e5382c 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 @@ void bta_ag_handle_collision(tBTA_AG_SCB* p_scb, 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 956335c160..fa8b033393 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 @@ bool bta_ag_add_record(uint16_t service_uuid, const char* p_service_name, 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 @@ bool bta_ag_add_record(uint16_t service_uuid, const char* p_service_name, 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 @@ bool bta_ag_add_record(uint16_t service_uuid, const char* p_service_name, /* 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 @@ bool bta_ag_add_record(uint16_t service_uuid, const char* p_service_name, 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 @@ void bta_ag_create_records(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { 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 @@ void bta_ag_del_records(tBTA_AG_SCB* p_scb) { 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 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { /* 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 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { /* 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 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { /* 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 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { } } /* 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 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { /* 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 @@ void bta_ag_do_disc(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { /* 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 ea6108f967..c122fc25be 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 @@ void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name, 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 @@ void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name, 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 @@ void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name, * 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 @@ void bta_ar_dereg_avrc(uint16_t service_uuid) { 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 @@ void bta_ar_dereg_avrc(uint16_t service_uuid) { 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 8711e6e6dd..a2fbf43dc1 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_close_all_rc(tBTA_AV_CB* p_cb) { ******************************************************************************/ 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 @@ static void bta_av_store_peer_rc_version() { 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 @@ static void bta_av_store_peer_rc_version() { } 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 @@ tBTA_AV_FEAT bta_av_check_peer_features(uint16_t service_uuid) { /* 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 @@ tBTA_AV_FEAT bta_av_check_peer_features(uint16_t service_uuid) { 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 @@ tBTA_AV_FEAT bta_avk_check_peer_features(uint16_t service_uuid) { 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 @@ tBTA_AV_FEAT bta_avk_check_peer_features(uint16_t service_uuid) { /* 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 @@ tBTA_AV_FEAT bta_avk_check_peer_features(uint16_t service_uuid) { } } /* 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 @@ uint16_t bta_avk_get_cover_art_psm() { 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 @@ uint16_t bta_avk_get_cover_art_psm() { } } /* 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 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { /* 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 f646da3161..3088c9bed6 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 @@ static void bta_av_api_enable(tBTA_AV_DATA* p_data) { 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 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { 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 c39f948e5a..0a709b9b04 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 @@ void bta_dm_remote_name_cmpl(const tBTA_DM_MSG* p_data) { 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 @@ static void bta_dm_store_audio_profiles_version() { }}; 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 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { 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 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { 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 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { 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 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { #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 @@ static void bta_dm_find_services(const RawAddress& bd_addr) { } 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 @@ static void bta_dm_find_services(const RawAddress& bd_addr) { 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 void bta_dm_authentication_complete_cback( 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 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, 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 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, 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 @@ tBT_TRANSPORT bta_dm_determine_discovery_transport(const RawAddress& bd_addr) { 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 b8be10a4c3..91c3c52bc0 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 BTA_DmSetLocalDiRecord(tSDP_DI_RECORD* p_device_info, 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 cd0f64db09..4fc81e2aed 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 @@ void bta_gattc_sdp_callback(tSDP_STATUS sdp_status, const void* user_data) { 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 @@ void bta_gattc_sdp_callback(tSDP_STATUS sdp_status, const void* user_data) { !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 @@ void bta_gattc_sdp_callback(tSDP_STATUS sdp_status, const void* user_data) { 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 @@ static tGATT_STATUS bta_gattc_sdp_service_disc(uint16_t conn_id, 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 76fc8ece9c..4572f1c3d5 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 @@ void bta_hd_api_disable(void) { /* 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 @@ void bta_hd_register_act(tBTA_HD_DATA* p_data) { /* 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 @@ void bta_hd_unregister_act() { 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 cae579822f..7ec21650fe 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 @@ void bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, /* 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 2999eb9ed1..e9e73e5028 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 @@ void bta_hf_client_rfc_do_close(tBTA_HF_CLIENT_DATA* p_data) { /* 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 e0ba984de3..1c84dca44f 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 @@ static void bta_hf_client_sdp_cback(tSDP_STATUS status, const void* data) { * 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 @@ bool bta_hf_client_add_record(const char* p_service_name, uint8_t scn, 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 @@ bool bta_hf_client_add_record(const char* p_service_name, uint8_t scn, 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 @@ void bta_hf_client_create_record(tBTA_HF_CLIENT_CB_ARR* client_cb_arr, 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 @@ void bta_hf_client_del_record(tBTA_HF_CLIENT_CB_ARR* client_cb) { 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 @@ bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb) { /* 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 @@ bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb) { } /* 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 @@ bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb) { } /* 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 @@ void bta_hf_client_do_disc(tBTA_HF_CLIENT_CB* client_cb) { 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 c237534160..6c3abd06c3 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 @@ static void bta_hh_di_sdp_cback(tSDP_RESULT result) { 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 @@ static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { (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 @@ void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { } /* 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 6324f1f114..11ea9305a0 100644 --- a/system/bta/hh/bta_hh_le.cc +++ b/system/bta/hh/bta_hh_le.cc @@ -1679,8 +1679,7 @@ void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { /* 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 ce4858c358..ace748404e 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 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status) { 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 2814aaa93b..2ddaf6831e 100644 --- a/system/bta/include/bta_hh_co.h +++ b/system/bta/include/bta_hh_co.h @@ -70,18 +70,6 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, uint16_t attr_mask, /******************************************************************************* * - * 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 d8d593dabd..532e980fb2 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 @@ static void bta_jv_start_discovery_cback(tSDP_RESULT result, 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 @@ void bta_jv_start_discovery(const RawAddress& bd_addr, uint16_t num_uuid, /* 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 @@ void bta_jv_start_discovery(const RawAddress& bd_addr, uint16_t num_uuid, 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_create_record(uint32_t rfcomm_slot_id) { 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 f0f2291475..4ac2d4c8a2 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 @@ static void bta_create_mns_sdp_record(bluetooth_sdp_record* record, 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 @@ static void bta_create_mas_sdp_record(bluetooth_sdp_record* record, 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 @@ static void bta_create_pse_sdp_record(bluetooth_sdp_record* record, 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 @@ static void bta_create_ops_sdp_record(bluetooth_sdp_record* record, 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 @@ static void bta_create_sap_sdp_record(bluetooth_sdp_record* record, 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 @@ static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, 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 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record* record, 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 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record* record, } /* 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 @@ static void bta_sdp_search_cback(tSDP_RESULT result, const void* user_data) { 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 @@ static void bta_sdp_search_cback(tSDP_RESULT result, const void* user_data) { 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 @@ void bta_sdp_search(const RawAddress bd_addr, const bluetooth::Uuid uuid) { /* 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 a0cdcb5657..bae16a7a24 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 c46a297b4c..a0f8345e1c 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 @@ namespace { 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 @@ const tBTA_SYS_REG bta_dm_search_reg = {bta_dm_search_sm_execute, } // 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 @@ class BtaDmTest : public testing::Test { 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 @@ void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p); 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 @@ TEST_F(BtaDmTest, bta_dm_remote_name_cmpl) { 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 851315f165..5af46688ac 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 ca45b44890..d92585cfe2 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 @@ const RawAddress bdaddr2({0x66, 0x55, 0x44, 0x33, 0x22, 0x11}); 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 abc10db3ee..d9ad012dab 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 @@ class BtaSdpTest : public testing::Test { 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 637f56ed59..0ace9f3157 100644 --- a/system/bta/vc/vc.cc +++ b/system/bta/vc/vc.cc @@ -798,28 +798,6 @@ class VolumeControlImpl : public VolumeControl { 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 1fb06681b0..1918f2fcb2 100644 --- a/system/btif/co/bta_hh_co.cc +++ b/system/btif/co/bta_hh_co.cc @@ -48,10 +48,15 @@ static tBTA_HH_RPT_CACHE_ENTRY sReportCache[BTA_HH_NV_LOAD_MAX]; #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 @@ static inline pthread_t create_thread(void* (*start_routine)(void*), 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 inline pthread_t create_thread(void* (*start_routine)(void*), 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 @@ static void* btif_hh_poll_event_thread(void* arg) { 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 @@ int bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len) { 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 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, * 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; - - 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; +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)); + + /* 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 c59fc6642d..d524687149 100644 --- a/system/btif/include/btif_hh.h +++ b/system/btif/include/btif_hh.h @@ -97,7 +97,6 @@ typedef struct { 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 451cee10e5..add6c4c09c 100644 --- a/system/btif/src/btif_hh.cc +++ b/system/btif/src/btif_hh.cc @@ -119,7 +119,7 @@ static tHID_KB_LIST hid_kb_numlock_on_list[] = {{LOGITECH_KB_MX5500_PRODUCT_ID, ******************************************************************************/ 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 @@ void btif_hh_remove_device(RawAddress bd_addr) { 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 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { 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 @@ static void cleanup(void) { 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 ed206b857c..9096796f65 100644 --- a/system/device/include/esco_parameters.h +++ b/system/device/include/esco_parameters.h @@ -137,6 +137,8 @@ typedef struct { 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 48607e6d54..861dfd90cc 100644 --- a/system/device/src/esco_parameters.cc +++ b/system/device/src/esco_parameters.cc @@ -57,6 +57,7 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { .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 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { 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 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { 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 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { 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 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { (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 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { 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 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { (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 0000000000..4f50b8a72b --- /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 0000000000..88ab212f26 --- /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 2e1f82f9c7..594fa62805 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(); + +} // namespace + +namespace bluetooth { +namespace hci { +namespace acl_manager { -class TestController : public Controller { +class TestController : public testing::MockController { public: void RegisterCompletedAclPacketsCallback( common::ContextualCallback<void(uint16_t /* handle */, uint16_t /* packets */)> cb) override { @@ -106,7 +112,13 @@ class AclManagerNoCallbacksTest : public ::testing::Test { 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 @@ class AclManagerNoCallbacksTest : public ::testing::Test { 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 @@ class AclManagerNoCallbacksTest : public ::testing::Test { 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 @@ class AclManagerNoCallbacksTest : public ::testing::Test { } std::shared_ptr<ClassicAclConnection> GetLastConnection() { - return mock_connection_callback_.connections_.back(); + return connections_.back(); } std::shared_ptr<LeAclConnection> GetLastLeConnection() { @@ -203,29 +224,9 @@ class AclManagerNoCallbacksTest : public ::testing::Test { 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 @@ class AclManagerWithConnectionTest : public AclManagerTest { // 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 @@ class AclManagerWithConnectionTest : public AclManagerTest { 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 @@ TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_success) { 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_success) { } 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 @@ TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_fail) { 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 @@ class AclManagerWithLeConnectionTest : public AclManagerTest { // 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 @@ TEST_F(AclManagerWithConnectionTest, remote_esco_connect_request) { 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 7301d805c1..462dd28e1c 100644 --- a/system/gd/hci/le_scanning_manager.cc +++ b/system/gd/hci/le_scanning_manager.cc @@ -870,7 +870,7 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { 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 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { 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 598346c16e..38882beb58 100644 --- a/system/gd/rust/common/src/init_flags.rs +++ b/system/gd/rust/common/src/init_flags.rs @@ -379,7 +379,7 @@ init_flags!( 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 e84c1381e3..1e8e2b8a3a 100644 --- a/system/hci/Android.bp +++ b/system/hci/Android.bp @@ -73,30 +73,3 @@ cc_test { "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 21b4c229aa..2e1986d0e5 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 @@ typedef struct hci_t { 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 29651a043d..c82f537394 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 @@ typedef struct { // 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 @@ typedef struct packet_fragmenter_t { // 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 93c1a7e6a8..ca0709f5d0 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 allocator_t* buffer_allocator; 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 @@ static void fragment_and_dispatch_iso(BT_HDR* packet) { 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 @@ static void reassemble_and_dispatch_iso(UNUSED_ATTR BT_HDR* packet) { 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_iso(UNUSED_ATTR BT_HDR* packet) { } } -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 7c566f5b35..0000000000 --- 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 f9efd4b2f4..7ba09343d1 100644 --- a/system/hci/test/packet_fragmenter_test.cc +++ b/system/hci/test/packet_fragmenter_test.cc @@ -389,12 +389,6 @@ DURING(non_acl_passthrough_reassembly) AT_CALL(0) { 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 @@ return 0; 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 @@ class PacketFragmenterTest : public AllocationTestHarness { 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 @@ class PacketFragmenterTest : public AllocationTestHarness { 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 17804550df..71ba464aa2 100644 --- a/system/main/shim/hci_layer.cc +++ b/system/main/shim/hci_layer.cc @@ -267,17 +267,12 @@ static bool event_already_registered_in_le_scanning_manager( } // 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 @@ static void sco_data_callback() { 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 register_for_iso() { } 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 @@ static void on_shutting_down() { 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 @@ static void transmit_command(const BT_HDR* command, 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 @@ static void transmit_fragment(BT_HDR* packet, bool send_transmit_finished) { 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 transmit_fragment(BT_HDR* packet, bool send_transmit_finished) { } } 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 73df2b1bf9..e00a5a5e81 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 @@ static void a2dp_sdp_cback(tSDP_STATUS status) { /* 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 @@ static void a2dp_sdp_cback(tSDP_STATUS status) { 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 @@ tA2DP_STATUS A2DP_AddRecord(uint16_t service_uuid, char* p_service_name, 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 @@ tA2DP_STATUS A2DP_AddRecord(uint16_t service_uuid, char* p_service_name, 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 @@ tA2DP_STATUS A2DP_FindService(uint16_t service_uuid, const RawAddress& bd_addr, 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 @@ tA2DP_STATUS A2DP_FindService(uint16_t service_uuid, const RawAddress& bd_addr, 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 f69c3f4758..02716d010b 100644 --- a/system/stack/acl/btm_acl.cc +++ b/system/stack/acl/btm_acl.cc @@ -148,7 +148,7 @@ constexpr uint16_t BTM_ACL_EXCEPTION_PKTS_MASK = 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 753f8d2e82..a393346b3c 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 @@ uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr, } 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 @@ uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr, /* 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 @@ uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr, * * 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 @@ uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr, * 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 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, 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 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, 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 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, 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_AddRecord(uint16_t service_uuid, const char* p_service_name, *******************************************************************************/ 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 6668e31f8f..475c977f56 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 @@ void btm_send_sco_packet(std::vector<uint8_t> data) { 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 b286ff4e81..04ffffc72f 100644 --- a/system/stack/btm/btm_sec.cc +++ b/system/stack/btm/btm_sec.cc @@ -116,7 +116,6 @@ static tBTM_STATUS btm_sec_send_hci_disconnect(tBTM_SEC_DEV_REC* p_dev_rec, 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 @@ static bool btm_dev_16_digit_authenticated(tBTM_SEC_DEV_REC* p_dev_rec) { /******************************************************************************* * + * 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 @@ bool is_sec_state_equal(void* data, void* context) { /******************************************************************************* * - * 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 c1c80cd3bf..f17a3e7eec 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 @@ bool is_sec_state_equal(void* data, void* context); /******************************************************************************* * - * 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 2ef6e828e7..5e9f35a42e 100644 --- a/system/stack/btm/neighbor_inquiry.h +++ b/system/stack/btm/neighbor_inquiry.h @@ -285,12 +285,6 @@ typedef struct { } 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 da76a85bdd..12d8122fac 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 @@ void GATTS_StopService(uint16_t service_handle) { } 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 7b45eead66..3b9bca1488 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 @@ uint32_t gatt_add_sdp_record(const Uuid& uuid, uint16_t start_hdl, 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 @@ uint32_t gatt_add_sdp_record(const Uuid& uuid, uint16_t start_hdl, 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 @@ uint32_t gatt_add_sdp_record(const Uuid& uuid, uint16_t start_hdl, 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 4281ac81fb..503bfdc1f1 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 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, // 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 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, 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 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, 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 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, 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 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, 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 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, 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 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, 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 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, 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 3cad6232e9..be26c7080f 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 @@ tHID_STATUS HID_HostGetSDPRecord(const RawAddress& addr, 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 @@ void hidh_get_str_attr(tSDP_DISC_REC* p_rec, uint16_t attr_id, uint16_t max_len, 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 @@ static void hidh_search_callback(tSDP_RESULT sdp_result) { } 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 @@ static void hidh_search_callback(tSDP_RESULT sdp_result) { 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 @@ static void hidh_search_callback(tSDP_RESULT sdp_result) { 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 @@ static void hidh_search_callback(tSDP_RESULT sdp_result) { 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 b19c7a04c2..a0d182db56 100644 --- a/system/stack/include/bt_dev_class.h +++ b/system/stack/include/bt_dev_class.h @@ -123,6 +123,12 @@ inline constexpr DEV_CLASS kDevClassEmpty = {}; } #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 9cf6d6d8ae..8f98059906 100644 --- a/system/stack/include/bt_name.h +++ b/system/stack/include/bt_name.h @@ -48,6 +48,10 @@ typedef uint8_t tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1]; 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 5113bd678d..450e556556 100644 --- a/system/stack/include/btm_api_types.h +++ b/system/stack/include/btm_api_types.h @@ -129,12 +129,6 @@ typedef enum : uint8_t { ***************************/ /* 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 378263cce3..4967652871 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 @@ tPAN_RESULT PAN_SetRole(uint8_t role, std::string p_user_name, 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 @@ tPAN_RESULT PAN_SetRole(uint8_t role, std::string p_user_name, */ 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 @@ tPAN_RESULT PAN_SetRole(uint8_t role, std::string p_user_name, /* 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 @@ tPAN_RESULT PAN_SetRole(uint8_t role, std::string p_user_name, */ 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 7252ddfd7b..d81bbb5274 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 pan_register_with_sdp(uint16_t uuid, const char* p_name, 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 @@ uint32_t pan_register_with_sdp(uint16_t uuid, const char* p_name, } /* 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 @@ uint32_t pan_register_with_sdp(uint16_t uuid, const char* p_name, /* 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 27c4a8f29a..fa5a7f01f1 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 d032e4910e..b9a93291f4 100644 --- a/system/stack/sdp/sdp_db.cc +++ b/system/stack/sdp/sdp_db.cc @@ -42,6 +42,11 @@ static bool find_uuid_in_seq(uint8_t* p, uint32_t seq_len, 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 e3150d9bda..3d8785a0f6 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 22942fc759..e6ea894c6d 100644 --- a/system/stack/smp/smp_act.cc +++ b/system/stack/smp/smp_act.cc @@ -45,6 +45,9 @@ namespace { 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 @@ void smp_br_process_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * 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 8b7a913e4f..3a3fe65fb9 100644 --- a/system/stack/smp/smp_int.h +++ b/system/stack/smp/smp_int.h @@ -404,7 +404,6 @@ void smp_br_send_pair_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data); 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 7f89a61c80..e605813ebe 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 @@ BT_HDR* AllocateWrappedIncomingL2capAclPacket(const uint8_t* acl_packet_bytes, 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 10423f5f09..435d214773 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 @@ static const std::vector<std::function<void(FuzzedDataProvider*)>> 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 @@ static const std::vector<std::function<void(FuzzedDataProvider*)>> 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 @@ static const std::vector<std::function<void(FuzzedDataProvider*)>> 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 @@ static const std::vector<std::function<void(FuzzedDataProvider*)>> } }, - // 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 @@ static const std::vector<std::function<void(FuzzedDataProvider*)>> 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 @@ static const std::vector<std::function<void(FuzzedDataProvider*)>> 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 fead81e986..43b47109e3 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 @@ void cleanupSdpFuzz() { 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 fb000ef838..8d6b9ea085 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 32cc9d2ae6..5656eca0da 100644 --- a/system/test/Android.bp +++ b/system/test/Android.bp @@ -206,6 +206,27 @@ filegroup { } 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 { } 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 4779fb4d96..f5adcae7cc 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 @@ int sdp_query_uuid([[maybe_unused]] unsigned int num_loops, 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 @@ int sdp_query_uuid([[maybe_unused]] unsigned int num_loops, 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 @@ int sdp_query_uuid([[maybe_unused]] unsigned int num_loops, 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 887ef8cb27..da9560d76d 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 @@ tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const RawAddress& remote_bda, 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 2958682a07..afe452f3f1 100644 --- a/system/test/mock/mock_stack_acl.cc +++ b/system/test/mock/mock_stack_acl.cc @@ -77,7 +77,6 @@ struct acl_set_peer_le_features_from_handle 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 @@ void acl_create_classic_connection(const RawAddress& bd_addr, 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 25ebc36ecd..400e27d4d0 100644 --- a/system/test/mock/mock_stack_acl.h +++ b/system/test/mock/mock_stack_acl.h @@ -359,15 +359,6 @@ struct acl_create_classic_connection { }; }; 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 f782f59fd8..0c7f59eb2a 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; + test::mock::stack_btm_inq::BTM_CancelInquiry(); } -bool btm_inq_find_bdaddr(const RawAddress& p_bda) { +tBTM_STATUS BTM_CancelRemoteDeviceName(void) { + inc_func_call_count(__func__); + return test::mock::stack_btm_inq::BTM_CancelRemoteDeviceName(); +} +tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda) { + inc_func_call_count(__func__); + return test::mock::stack_btm_inq::BTM_ClearInqDb(p_bda); +} +void BTM_EnableInterlacedInquiryScan() { + inc_func_call_count(__func__); + test::mock::stack_btm_inq::BTM_EnableInterlacedInquiryScan(); +} +void BTM_EnableInterlacedPageScan() { + inc_func_call_count(__func__); + 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 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 test::mock::stack_btm_inq::BTM_GetEirUuidList( + p_eir, eir_len, uuid_size, p_num_uuid, p_uuid_list, max_num_uuid); +} +bool BTM_HasEirService(const uint32_t* p_eir_uuid, uint16_t uuid16) { inc_func_call_count(__func__); - return false; + return test::mock::stack_btm_inq::BTM_HasEirService(p_eir_uuid, uuid16); } tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService(tBTM_INQ_RESULTS* p_results, uint16_t uuid16) { inc_func_call_count(__func__); - return 0; + return test::mock::stack_btm_inq::BTM_HasInquiryEirService(p_results, uuid16); } tBTM_INQ_INFO* BTM_InqDbFirst(void) { inc_func_call_count(__func__); - return nullptr; + return test::mock::stack_btm_inq::BTM_InqDbFirst(); } tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) { inc_func_call_count(__func__); - return nullptr; + 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 nullptr; + return test::mock::stack_btm_inq::BTM_InqDbRead(p_bda); } -tBTM_STATUS BTM_CancelRemoteDeviceName(void) { +uint16_t BTM_IsInquiryActive(void) { inc_func_call_count(__func__); - return BTM_SUCCESS; + return test::mock::stack_btm_inq::BTM_IsInquiryActive(); } -tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda) { +bool BTM_IsRemoteNameKnown(const RawAddress& bd_addr, tBT_TRANSPORT transport) { inc_func_call_count(__func__); - return BTM_SUCCESS; + 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 BTM_SUCCESS; + 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 BTM_SUCCESS; + return test::mock::stack_btm_inq::BTM_SetConnectability(page_mode); } tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) { inc_func_call_count(__func__); - return BTM_SUCCESS; + return test::mock::stack_btm_inq::BTM_SetDiscoverability(inq_mode); } tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) { inc_func_call_count(__func__); - return BTM_SUCCESS; + 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 BTM_SUCCESS; + 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_CMPL_CB* p_cb) { + uint64_t timeout_ms, + tBTM_NAME_CMPL_CB* p_cb) { inc_func_call_count(__func__); - return BTM_SUCCESS; + 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 nullptr; + 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 nullptr; + return test::mock::stack_btm_inq::btm_inq_db_new(p_bda); } -uint16_t BTM_IsInquiryActive(void) { +void btm_inq_db_reset(void) { inc_func_call_count(__func__); - return 0; + test::mock::stack_btm_inq::btm_inq_db_reset(); } -uint8_t BTM_GetEirSupportedServices(uint32_t* p_eir_uuid, uint8_t** p, - uint8_t max_num_uuid16, - uint8_t* p_num_uuid16) { +bool btm_inq_find_bdaddr(const RawAddress& p_bda) { inc_func_call_count(__func__); - return 0; + return test::mock::stack_btm_inq::btm_inq_find_bdaddr(p_bda); } -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) { +void btm_inq_remote_name_timer_timeout(void* data) { inc_func_call_count(__func__); - return 0; + test::mock::stack_btm_inq::btm_inq_remote_name_timer_timeout(data); } -void BTM_AddEirService(uint32_t* p_eir_uuid, uint16_t uuid16) { +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_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) { +void btm_inq_stop_on_ssp(void) { inc_func_call_count(__func__); + test::mock::stack_btm_inq::btm_inq_stop_on_ssp(); } -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__); } 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 0000000000..6265607727 --- /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 815a3fa6a1..c424e069bc 100644 --- a/system/test/mock/mock_stack_btm_sec.cc +++ b/system/test/mock/mock_stack_btm_sec.cc @@ -132,10 +132,6 @@ tBTM_LINK_KEY_TYPE BTM_SecGetDeviceLinkKeyType(const RawAddress& bd_addr) { 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 f339a266bb..a41c690445 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 0000000000..93d9077e33 --- /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 06badb8f53..198a2b96db 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_set_derive_link_key smp_set_derive_link_key; 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 @@ void smp_br_process_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { 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 5754f3bed9..c45fecbe0a 100644 --- a/system/test/mock/mock_stack_smp_act.h +++ b/system/test/mock/mock_stack_smp_act.h @@ -679,16 +679,6 @@ struct smp_br_process_link_key { 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 2b4b168e53..0b5e9d4cce 100644 --- a/tools/rootcanal/Android.bp +++ b/tools/rootcanal/Android.bp @@ -323,6 +323,7 @@ cc_test_host { 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 beac219cb6..a6b3993984 100644 --- a/tools/rootcanal/include/hci/pcap_filter.h +++ b/tools/rootcanal/include/hci/pcap_filter.h @@ -50,7 +50,6 @@ class PcapFilter final { 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 @@ class PcapFilter final { // 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 @@ class PcapFilter final { 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 bab0d9df55..b8edda8995 100644 --- a/tools/rootcanal/lib/hci/pcap_filter.cc +++ b/tools/rootcanal/lib/hci/pcap_filter.cc @@ -168,41 +168,50 @@ static std::vector<uint8_t> FilterHciIso(std::vector<uint8_t> const& packet) { } // 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]); + + // Truncated entry. + if ((offset + length + 1) > gap_data_len) { + break; } - } -} -void PcapFilter::FilterLengthAndData( - std::vector<bluetooth::hci::LengthAndData>& gap_data) { - for (LengthAndData& entry : gap_data) { - if (entry.data_.empty()) { + // 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 @@ std::vector<uint8_t> PcapFilter::FilterWriteExtendedInquiryResponse( 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 @@ std::vector<uint8_t> PcapFilter::FilterLeSetAdvertisingData( 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 @@ std::vector<uint8_t> PcapFilter::FilterLeSetScanResponseData( 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 @@ std::vector<uint8_t> PcapFilter::FilterLeSetExtendedAdvertisingData( 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 @@ std::vector<uint8_t> PcapFilter::FilterLeSetExtendedScanResponseData( 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 @@ std::vector<uint8_t> PcapFilter::FilterLeSetPeriodicAdvertisingData( 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 @@ std::vector<uint8_t> PcapFilter::FilterLeMultiAdvtSetData( 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 @@ std::vector<uint8_t> PcapFilter::FilterLeMultiAdvtSetScanResp( 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 @@ std::vector<uint8_t> PcapFilter::FilterReadExtendedInquiryResponseComplete( 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 @@ std::vector<uint8_t> PcapFilter::FilterExtendedInquiryResult( 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<uint8_t> PcapFilter::FilterLeAdvertisingReport( 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<uint8_t> PcapFilter::FilterLeExtendedAdvertisingReport( 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 57585c7fda..0ec16da875 100644 --- a/tools/rootcanal/model/controller/dual_mode_controller.cc +++ b/tools/rootcanal/model/controller/dual_mode_controller.cc @@ -1546,13 +1546,14 @@ void DualModeController::LeReadLocalSupportedFeatures(CommandView command) { 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::LeReadAdvertisingPhysicalChannelTxPower( } 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::LeSetAdvertisingData(CommandView command) { 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::LeSetPeriodicAdvertisingParameters( 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 @@ void DualModeController::LeSetExtendedAdvertisingData(CommandView command) { 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 @@ void DualModeController::LeSetExtendedScanResponseData(CommandView command) { 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 df1d4dc173..6fc81c8c9b 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.cc +++ b/tools/rootcanal/model/controller/link_layer_controller.cc @@ -2691,7 +2691,6 @@ void LinkLayerController::IncomingInquiryPacket( 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 @@ void LinkLayerController::IncomingInquiryResponsePacket( 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 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu( 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 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu( 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 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu( } 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 @@ void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu( 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 @@ void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu( 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 @@ void LinkLayerController::IncomingLeScanResponsePacket( 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 @@ void LinkLayerController::IncomingLeScanResponsePacket( 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 2eb4e5ea5a..63d5bb9325 100644 --- a/tools/rootcanal/packets/hci/hci_packets.pdl +++ b/tools/rootcanal/packets/hci/hci_packets.pdl @@ -8,66 +8,6 @@ enum Enable : 8 { 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 ReadExtendedInquiryResponse : Command (op_code = READ_EXTENDED_INQUIRY_RE 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 LeReadAdvertisingPhysicalChannelTxPowerComplete : CommandComplete (comman 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 LeSetAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_ 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 @@ packet LeSetExtendedAdvertisingData : Command (op_code = LE_SET_EXTENDED_ADVERTI 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 @@ packet LeSetExtendedScanResponseData : Command (op_code = LE_SET_EXTENDED_SCAN_R 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 @@ packet LeSetPeriodicAdvertisingData : Command (op_code = LE_SET_PERIODIC_ADVERTI 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 LeMultiAdvtParamComplete : LeMultiAdvtComplete (sub_cmd = SET_PARAM) { 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 LeMultiAdvtSetDataComplete : LeMultiAdvtComplete (sub_cmd = SET_DATA) { 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 @@ packet ExtendedInquiryResult : Event (event_code = EXTENDED_INQUIRY_RESULT) { 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 @@ struct LeAdvertisingResponse { address_type : AddressType, address : Address, _size_(advertising_data) : 8, - advertising_data : LengthAndData[], + advertising_data : 8[], rssi : 8, } @@ -5756,20 +5638,6 @@ packet LeAdvertisingReport : LeMetaEvent (subevent_code = ADVERTISING_REPORT) { 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 @@ struct LeExtendedAdvertisingResponse { 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 @@ test MsftLeMonitorDeviceEventPayload { "\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 0000000000..88035402e4 --- /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 |