summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java3
-rw-r--r--android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java8
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioService.java11
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlService.java31
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java10
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java40
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java106
-rw-r--r--flags/bta_dm.aconfig7
-rw-r--r--flags/hci.aconfig7
-rw-r--r--framework/tests/bumble/src/android/bluetooth/PandoraDevice.java6
-rw-r--r--framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java274
-rw-r--r--framework/tests/bumble/src/bumble_server.py4
-rw-r--r--pandora/interfaces/pandora_experimental/oob.proto24
-rw-r--r--pandora/interfaces/python/Android.bp5
-rw-r--r--pandora/server/bumble_experimental/oob.py53
-rw-r--r--service/src/com/android/server/bluetooth/BluetoothManagerService.java648
-rw-r--r--system/bta/Android.bp1
-rw-r--r--system/bta/BUILD.gn1
-rw-r--r--system/bta/av/bta_av_aact.cc8
-rw-r--r--system/bta/dm/bta_dm_act.cc19
-rw-r--r--system/bta/dm/bta_dm_device_search.cc47
-rw-r--r--system/bta/dm/bta_dm_disc.cc83
-rw-r--r--system/bta/dm/bta_dm_disc.h6
-rw-r--r--system/bta/dm/bta_dm_disc_int_legacy.h187
-rw-r--r--system/bta/dm/bta_dm_disc_legacy.cc2080
-rw-r--r--system/bta/dm/bta_dm_disc_legacy.h66
-rw-r--r--system/bta/include/bta_api.h11
-rw-r--r--system/bta/include/bta_jv_api.h1
-rw-r--r--system/bta/test/bta_disc_test.cc32
-rw-r--r--system/btif/src/btif_dm.cc36
-rw-r--r--system/gd/hci/controller.cc11
-rw-r--r--system/gd/hci/controller.h1
-rw-r--r--system/gd/hci/security_interface.h1
-rw-r--r--system/gd/rust/common/src/logging.rs2
-rw-r--r--system/gd/rust/topshim/src/btif.rs8
-rw-r--r--system/gd/security/channel/security_manager_channel_unittest.cc16
-rw-r--r--system/main/shim/hci_layer.cc1
-rw-r--r--system/pdl/hci/hci_packets.pdl9
-rw-r--r--system/stack/avct/avct_api.cc5
-rw-r--r--system/stack/avct/avct_int.h1
-rw-r--r--system/stack/avct/avct_l2c.cc2
-rw-r--r--system/stack/avct/avct_l2c_br.cc2
-rw-r--r--system/stack/avdt/avdt_ad.cc4
-rw-r--r--system/stack/avdt/avdt_int.h3
-rw-r--r--system/stack/avdt/avdt_l2c.cc5
-rw-r--r--system/stack/bnep/bnep_main.cc2
-rw-r--r--system/stack/btm/btm_dev.cc1
-rw-r--r--system/stack/btm/btm_sec.cc49
-rw-r--r--system/stack/btm/btm_sec.h6
-rw-r--r--system/stack/btm/security_event_parser.cc22
-rw-r--r--system/stack/btu/btu_hcif.cc41
-rw-r--r--system/stack/fuzzers/l2cap_fuzzer.cc33
-rw-r--r--system/stack/gap/gap_conn.cc2
-rw-r--r--system/stack/gatt/att_protocol.cc1
-rw-r--r--system/stack/gatt/gatt_api.cc1
-rw-r--r--system/stack/gatt/gatt_main.cc1
-rw-r--r--system/stack/gatt/gatt_sr.cc3
-rw-r--r--system/stack/hid/hidh_conn.cc2
-rw-r--r--system/stack/include/bnep_api.h1
-rw-r--r--system/stack/include/gap_api.h2
-rw-r--r--system/stack/include/hcidefs.h1
-rw-r--r--system/stack/include/l2c_api.h893
-rw-r--r--system/stack/include/sec_hci_link_interface.h6
-rw-r--r--system/stack/l2cap/internal/l2c_api.h10
-rw-r--r--system/stack/l2cap/l2c_api.h140
-rw-r--r--system/stack/l2cap/l2c_ble.cc1
-rw-r--r--system/stack/l2cap/l2c_fcr.cc2
-rw-r--r--system/stack/l2cap/l2c_link.cc1
-rw-r--r--system/stack/l2cap/l2c_main.cc1
-rw-r--r--system/stack/l2cap/l2c_utils.cc1
-rw-r--r--system/stack/l2cap/l2cap_api.cc3
-rw-r--r--system/stack/rfcomm/rfc_ts_frames.cc1
-rw-r--r--system/stack/smp/smp_api.cc2
-rw-r--r--system/stack/test/btm/stack_btm_sec_test.cc15
-rw-r--r--system/stack/test/common/mock_l2cap_layer.h2
-rw-r--r--system/stack/test/common/stack_test_packet_utils.cc3
-rw-r--r--system/test/mock/mock_stack_btm_sec.cc11
-rw-r--r--system/test/mock/mock_stack_btm_sec.h26
-rw-r--r--system/test/mock/mock_stack_gap_conn.cc1
-rw-r--r--system/test/mock/mock_stack_gatt_main.cc1
-rw-r--r--system/test/mock/mock_stack_l2cap_api.h2
-rw-r--r--system/test/mock/mock_stack_l2cap_main.cc1
-rw-r--r--tools/rootcanal/model/controller/link_layer_controller.cc18
-rw-r--r--tools/rootcanal/packets/hci_packets.pdl8
84 files changed, 1142 insertions, 4061 deletions
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
index 53b82ac023..e7d4ed900d 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java
@@ -37,6 +37,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.ParcelUuid;
+import android.os.UserHandle;
import android.sysprop.BluetoothProperties;
import android.util.Log;
@@ -662,7 +663,7 @@ public class HearingAidService extends ProfileService {
intent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- sendBroadcast(intent, BLUETOOTH_CONNECT);
+ sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_CONNECT);
}
/* Notifications of audio device disconnection events. */
diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java
index 4fc71b373f..3a701d5c65 100644
--- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidStateMachine.java
@@ -37,6 +37,7 @@ import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.os.Looper;
import android.os.Message;
+import android.os.UserHandle;
import android.util.Log;
import com.android.bluetooth.Utils;
@@ -556,8 +557,11 @@ final class HearingAidStateMachine extends StateMachine {
intent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- mService.sendBroadcast(
- intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
+ mService.sendBroadcastAsUser(
+ intent,
+ UserHandle.ALL,
+ BLUETOOTH_CONNECT,
+ Utils.getTempBroadcastOptions().toBundle());
}
private static String messageWhatToString(int what) {
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index 264a8267db..04873a0514 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -1831,7 +1831,11 @@ public class LeAudioService extends ProfileService {
intent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- sendBroadcast(intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
+ sendBroadcastAsUser(
+ intent,
+ UserHandle.ALL,
+ BLUETOOTH_CONNECT,
+ Utils.getTempBroadcastOptions().toBundle());
}
void sentActiveDeviceChangeIntent(BluetoothDevice device) {
@@ -1840,8 +1844,9 @@ public class LeAudioService extends ProfileService {
intent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- sendBroadcastWithMultiplePermissions(
- intent, new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED});
+ createContextAsUser(UserHandle.ALL, /* flags= */ 0)
+ .sendBroadcastWithMultiplePermissions(
+ intent, new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED});
}
void notifyVolumeControlServiceAboutActiveGroup(BluetoothDevice device) {
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
index 1128a79f36..87adb315f9 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
@@ -805,24 +805,27 @@ public class VolumeControlService extends ProfileService {
+ (", mute: " + mute)
+ (", flags: " + flags));
/* We are here, because system has just started and LeAudio device is connected. If
- * remote device has User Persistent flag set or the volume != 0, Android sets the
- * volume to local cache and to the audio system. If Reset Flag is set and remote has
- * volume set to 0, then Android sets to remote devices either cached volume volume
- * taken from audio manager. Note, to match BR/EDR behavior, don't show volume change in
- * UI here
+ * remote device has User Persistent flag set, Android sets the volume to local cache
+ * and to the audio system.
+ * If Reset Flag is set, then Android sets to remote devices either cached volume volume
+ * taken from audio manager.
+ * Note, to match BR/EDR behavior, don't show volume change in UI here
*/
- if ((flags & VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK) == 0x01 || (volume != 0)) {
+ if ((flags & VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK) == 0x01) {
updateGroupCacheAndAudioSystem(groupId, volume, mute, false);
+ return;
+ }
+
+ // Reset flag is used
+ if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) {
+ Log.i(TAG, "Setting volume: " + groupVolume + " to the group: " + groupId);
+ setGroupVolume(groupId, groupVolume);
} else {
- if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) {
- Log.i(TAG, "Setting volume: " + groupVolume + " to the group: " + groupId);
- setGroupVolume(groupId, groupVolume);
- } else {
- int vol = getBleVolumeFromCurrentStream();
- Log.i(TAG, "Setting system volume: " + vol + " to the group: " + groupId);
- setGroupVolume(groupId, getBleVolumeFromCurrentStream());
- }
+ int vol = getBleVolumeFromCurrentStream();
+ Log.i(TAG, "Setting system volume: " + vol + " to the group: " + groupId);
+ setGroupVolume(groupId, getBleVolumeFromCurrentStream());
}
+
return;
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java
index 7c7a166f2a..5b1dceb486 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java
@@ -43,6 +43,7 @@ import android.media.AudioManager;
import android.media.BluetoothProfileConnectionInfo;
import android.os.Looper;
import android.os.ParcelUuid;
+import android.os.UserHandle;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.filters.MediumTest;
@@ -166,7 +167,11 @@ public class HearingAidServiceTest {
@SafeVarargs
private void verifyIntentSent(Matcher<Intent>... matchers) {
mInOrder.verify(mContext, timeout(TIMEOUT.toMillis() * 2))
- .sendBroadcast(MockitoHamcrest.argThat(AllOf.allOf(matchers)), any(), any());
+ .sendBroadcastAsUser(
+ MockitoHamcrest.argThat(AllOf.allOf(matchers)),
+ eq(UserHandle.ALL),
+ any(),
+ any());
}
private void verifyConnectionStateIntent(BluetoothDevice device, int newState, int prevState) {
@@ -1253,9 +1258,10 @@ public class HearingAidServiceTest {
mService.messageFromNative(stackEvent);
// Verify the connection state broadcast
mInOrder.verify(mContext, times(0))
- .sendBroadcast(
+ .sendBroadcastAsUser(
MockitoHamcrest.argThat(
hasAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED)),
+ eq(UserHandle.ALL),
any(),
any());
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java
index 64b7573555..301051fed4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidStateMachineTest.java
@@ -24,6 +24,7 @@ import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.os.Bundle;
import android.os.HandlerThread;
+import android.os.UserHandle;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
@@ -118,7 +119,8 @@ public class HearingAidStateMachineTest {
// Verify that no connection state broadcast is executed
verify(mHearingAidService, after(TIMEOUT_MS).never())
- .sendBroadcast(any(Intent.class), anyString(), any(Bundle.class));
+ .sendBroadcastAsUser(
+ any(Intent.class), eq(UserHandle.ALL), anyString(), any(Bundle.class));
// Check that we are in Disconnected state
Assert.assertThat(
mHearingAidStateMachine.getCurrentState(),
@@ -140,7 +142,11 @@ public class HearingAidStateMachineTest {
// Verify that one connection state broadcast is executed
ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
verify(mHearingAidService, timeout(TIMEOUT_MS).times(1))
- .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class));
+ .sendBroadcastAsUser(
+ intentArgument1.capture(),
+ eq(UserHandle.ALL),
+ anyString(),
+ any(Bundle.class));
Assert.assertEquals(
BluetoothProfile.STATE_CONNECTING,
intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
@@ -161,7 +167,11 @@ public class HearingAidStateMachineTest {
// - two calls to broadcastConnectionState(): Disconnected -> Conecting -> Connected
ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
verify(mHearingAidService, timeout(TIMEOUT_MS).times(2))
- .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class));
+ .sendBroadcastAsUser(
+ intentArgument2.capture(),
+ eq(UserHandle.ALL),
+ anyString(),
+ any(Bundle.class));
// Check that we are in Connected state
Assert.assertThat(
mHearingAidStateMachine.getCurrentState(),
@@ -186,7 +196,11 @@ public class HearingAidStateMachineTest {
// Verify that one connection state broadcast is executed
ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
verify(mHearingAidService, timeout(TIMEOUT_MS).times(1))
- .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class));
+ .sendBroadcastAsUser(
+ intentArgument1.capture(),
+ eq(UserHandle.ALL),
+ anyString(),
+ any(Bundle.class));
Assert.assertEquals(
BluetoothProfile.STATE_CONNECTING,
intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
@@ -199,7 +213,11 @@ public class HearingAidStateMachineTest {
// Verify that one connection state broadcast is executed
ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
verify(mHearingAidService, timeout(HearingAidStateMachine.sConnectTimeoutMs * 2L).times(2))
- .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class));
+ .sendBroadcastAsUser(
+ intentArgument2.capture(),
+ eq(UserHandle.ALL),
+ anyString(),
+ any(Bundle.class));
Assert.assertEquals(
BluetoothProfile.STATE_DISCONNECTED,
intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
@@ -233,7 +251,11 @@ public class HearingAidStateMachineTest {
// Verify that one connection state broadcast is executed
ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
verify(mHearingAidService, timeout(TIMEOUT_MS).times(1))
- .sendBroadcast(intentArgument1.capture(), anyString(), any(Bundle.class));
+ .sendBroadcastAsUser(
+ intentArgument1.capture(),
+ eq(UserHandle.ALL),
+ anyString(),
+ any(Bundle.class));
Assert.assertEquals(
BluetoothProfile.STATE_CONNECTING,
intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
@@ -246,7 +268,11 @@ public class HearingAidStateMachineTest {
// Verify that one connection state broadcast is executed
ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
verify(mHearingAidService, timeout(HearingAidStateMachine.sConnectTimeoutMs * 2L).times(2))
- .sendBroadcast(intentArgument2.capture(), anyString(), any(Bundle.class));
+ .sendBroadcastAsUser(
+ intentArgument2.capture(),
+ eq(UserHandle.ALL),
+ anyString(),
+ any(Bundle.class));
Assert.assertEquals(
BluetoothProfile.STATE_DISCONNECTED,
intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
index f617bfea5b..441fdaa753 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
@@ -804,79 +804,15 @@ public class VolumeControlServiceTest {
verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
}
- /** Test if phone will set volume which is read from the buds */
- @Test
- public void testConnectedDeviceWithResetFlagSetWithNonZeroVolume() throws Exception {
+ private void testConnectedDeviceWithResetFlag(
+ int resetVolumeDeviceOne, int resetVolumeDeviceTwo) {
int groupId = 1;
- int volumeDevice = 56;
- int volumeDeviceTwo = 100;
- int flags = 0;
- boolean initialMuteState = false;
- boolean initialAutonomousFlag = true;
-
- // Both devices are in the same group
- when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
- when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
-
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
- generateDeviceAvailableMessageFromNative(mDevice, 1);
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
-
- // Group is not active, AF will not be notified
- generateVolumeStateChanged(
- mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag);
- verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt());
-
- // Make device Active now. This will trigger setting volume to AF
- when(mLeAudioService.getActiveGroupId()).thenReturn(groupId);
- mServiceBinder.setGroupActive(groupId, true, mAttributionSource);
- int expectedAfVol =
- (int) Math.round((double) (volumeDevice * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
- verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
-
- // Connect second device and read different volume. Expect it will be set to AF and to
- // another set member
- generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
-
- // Group is now active, AF will be notified. Native will take care to sync the volume
- generateVolumeStateChanged(
- mDeviceTwo,
- groupId,
- volumeDeviceTwo,
- flags,
- initialMuteState,
- initialAutonomousFlag);
- expectedAfVol =
- (int) Math.round((double) (volumeDeviceTwo * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
- verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
- }
+ int streamVolume = 30;
+ int streamMaxVolume = 100;
+ int resetFlag = 0;
- /** Test if phone will set volume to buds which has no volume */
- @Test
- public void testConnectedDeviceWithResetFlagSetWithZeroVolume() throws Exception {
- int groupId = 1;
- int volumeDevice = 0;
- int volumeDeviceTwo = 0;
- int flags = 0;
boolean initialMuteState = false;
boolean initialAutonomousFlag = true;
- int streamVolume = 50;
- int streamMaxVolume = 100;
// Both devices are in the same group
when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
@@ -899,19 +835,25 @@ public class VolumeControlServiceTest {
Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
Assert.assertTrue(mService.getDevices().contains(mDevice));
- // Group is not active, AF will not be notified but device will get phone volume
- int expectedDeviceVol =
+ int expectedAfVol =
(int) Math.round((double) streamVolume * BT_LE_AUDIO_MAX_VOL / streamMaxVolume);
+
+ // Group is not active, AF will not be notified
generateVolumeStateChanged(
- mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag);
+ mDevice,
+ groupId,
+ resetVolumeDeviceOne,
+ resetFlag,
+ initialMuteState,
+ initialAutonomousFlag);
verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt());
- verify(mNativeInterface, times(1)).setGroupVolume(eq(groupId), eq(expectedDeviceVol));
// Make device Active now. This will trigger setting volume to AF
when(mLeAudioService.getActiveGroupId()).thenReturn(groupId);
mServiceBinder.setGroupActive(groupId, true, mAttributionSource);
verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(streamVolume), anyInt());
+ verify(mNativeInterface, times(1)).setGroupVolume(eq(groupId), eq(expectedAfVol));
// Connect second device and read different volume. Expect it will be set to AF and to
// another set member
@@ -926,13 +868,25 @@ public class VolumeControlServiceTest {
generateVolumeStateChanged(
mDeviceTwo,
groupId,
- volumeDeviceTwo,
- flags,
+ resetVolumeDeviceTwo,
+ resetFlag,
initialMuteState,
initialAutonomousFlag);
verify(mAudioManager, times(1)).setStreamVolume(anyInt(), anyInt(), anyInt());
- verify(mNativeInterface, times(2)).setGroupVolume(eq(groupId), eq(expectedDeviceVol));
+ verify(mNativeInterface, times(2)).setGroupVolume(eq(groupId), eq(expectedAfVol));
+ }
+
+ /** Test if phone will set volume which is read from the buds */
+ @Test
+ public void testConnectedDeviceWithResetFlagSetWithNonZeroVolume() throws Exception {
+ testConnectedDeviceWithResetFlag(56, 100);
+ }
+
+ /** Test if phone will set volume to buds which has no volume */
+ @Test
+ public void testConnectedDeviceWithResetFlagSetWithZeroVolume() throws Exception {
+ testConnectedDeviceWithResetFlag(0, 0);
}
/**
diff --git a/flags/bta_dm.aconfig b/flags/bta_dm.aconfig
index 1d74b37df1..c882038d6f 100644
--- a/flags/bta_dm.aconfig
+++ b/flags/bta_dm.aconfig
@@ -23,13 +23,6 @@ flag {
}
flag {
- name: "separate_service_and_device_discovery"
- namespace: "bluetooth"
- description: "Separate service and device discovery state machines such that one does not block on another"
- bug: "335732980"
-}
-
-flag {
name: "bta_dm_discover_both"
namespace: "bluetooth"
description: "perform both LE and Classic service discovery simulteanously on capable devices"
diff --git a/flags/hci.aconfig b/flags/hci.aconfig
index d6175fff84..8c5180a298 100644
--- a/flags/hci.aconfig
+++ b/flags/hci.aconfig
@@ -10,3 +10,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "encryption_change_v2"
+ namespace: "bluetooth"
+ description: "Enable encryption change V2 event"
+ bug: "366018699"
+}
diff --git a/framework/tests/bumble/src/android/bluetooth/PandoraDevice.java b/framework/tests/bumble/src/android/bluetooth/PandoraDevice.java
index 00799fbfa0..9933101913 100644
--- a/framework/tests/bumble/src/android/bluetooth/PandoraDevice.java
+++ b/framework/tests/bumble/src/android/bluetooth/PandoraDevice.java
@@ -37,6 +37,7 @@ import pandora.HostGrpc;
import pandora.HostProto;
import pandora.HostProto.AdvertiseRequest;
import pandora.HostProto.OwnAddressType;
+import pandora.OOBGrpc;
import pandora.RFCOMMGrpc;
import pandora.SecurityGrpc;
import pandora.l2cap.L2CAPGrpc;
@@ -198,6 +199,11 @@ public final class PandoraDevice extends ExternalResource {
return SecurityGrpc.newStub(mChannel);
}
+ /** Get Pandora OOB blocking service */
+ public OOBGrpc.OOBBlockingStub oobBlocking() {
+ return OOBGrpc.newBlockingStub(mChannel);
+ }
+
/** Get Pandora GATT service */
public GATTGrpc.GATTStub gatt() {
return GATTGrpc.newStub(mChannel);
diff --git a/framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java b/framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java
new file mode 100644
index 0000000000..64c196bc5e
--- /dev/null
+++ b/framework/tests/bumble/src/android/bluetooth/pairing/OobPairingTest.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2024 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 android.bluetooth.pairing;
+
+import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction;
+import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.timeout;
+
+import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothAdapter.OobDataCallback;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.OobData;
+import android.bluetooth.PandoraDevice;
+import android.bluetooth.Utils;
+import android.bluetooth.cts.EnableBluetoothRule;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.AdoptShellPermissionsRule;
+
+import com.google.common.primitives.Bytes;
+import com.google.protobuf.ByteString;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.core.AllOf;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.hamcrest.MockitoHamcrest;
+import org.mockito.stubbing.Answer;
+
+import pandora.HostProto.AdvertiseRequest;
+import pandora.HostProto.OwnAddressType;
+import pandora.OobProto.OobDataRequest;
+import pandora.OobProto.OobDataResponse;
+
+import java.time.Duration;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class OobPairingTest {
+ private static final String TAG = OobPairingTest.class.getSimpleName();
+ private static final Duration INTENT_TIMEOUT = Duration.ofSeconds(10);
+ private BluetoothDevice mDevice;
+ private final Context mContext =
+ InstrumentationRegistry.getInstrumentation().getTargetContext();
+ private final BluetoothAdapter mAdapter =
+ mContext.getSystemService(BluetoothManager.class).getAdapter();
+ private OobDataResponse mRemoteOobData;
+
+ private static final int HASH_START_POSITION = 0;
+ private static final int HASH_END_POSITION = 16;
+ private static final int RANDOMIZER_START_POSITION = 16;
+ private static final int RANDOMIZER_END_POSITION = 32;
+
+ @Rule(order = 0)
+ public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule();
+
+ @Rule(order = 1)
+ public final PandoraDevice mBumble = new PandoraDevice();
+
+ @Rule(order = 3)
+ public final EnableBluetoothRule enableBluetoothRule = new EnableBluetoothRule(false, true);
+
+ @Mock private BroadcastReceiver mReceiver;
+ private InOrder mInOrder = null;
+
+ @SuppressLint("MissingPermission")
+ private final Answer<Void> mIntentHandler =
+ inv -> {
+ Log.i(TAG, "onReceive(): intent=" + Arrays.toString(inv.getArguments()));
+ Intent intent = inv.getArgument(1);
+ String action = intent.getAction();
+ if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
+ BluetoothDevice device =
+ intent.getParcelableExtra(
+ BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class);
+ int bondState =
+ intent.getIntExtra(
+ BluetoothDevice.EXTRA_BOND_STATE, BluetoothAdapter.ERROR);
+ int prevBondState =
+ intent.getIntExtra(
+ BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE,
+ BluetoothAdapter.ERROR);
+ Log.i(
+ TAG,
+ "onReceive(): device "
+ + device
+ + " bond state changed from "
+ + prevBondState
+ + " to "
+ + bondState);
+ } else {
+ Log.i(TAG, "onReceive(): unknown intent action " + action);
+ }
+ return null;
+ };
+
+ private OobData buildOobData() {
+
+ byte[] confirmationHash =
+ mRemoteOobData
+ .getOob()
+ .substring(HASH_START_POSITION, HASH_END_POSITION)
+ .toByteArray();
+ byte[] randomizer =
+ mRemoteOobData
+ .getOob()
+ .substring(RANDOMIZER_START_POSITION, RANDOMIZER_END_POSITION)
+ .toByteArray();
+ byte[] address = Utils.addressBytesFromString(Utils.BUMBLE_RANDOM_ADDRESS);
+ byte[] addressType = {BluetoothDevice.ADDRESS_TYPE_RANDOM};
+
+ OobData p256 =
+ new OobData.LeBuilder(
+ confirmationHash,
+ Bytes.concat(address, addressType),
+ OobData.LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL)
+ .setRandomizerHash(randomizer)
+ .build();
+ return p256;
+ }
+
+ private void startAdvertise() throws Exception {
+ AdvertiseRequest request =
+ AdvertiseRequest.newBuilder()
+ .setLegacy(true)
+ .setConnectable(true)
+ .setOwnAddressType(OwnAddressType.RANDOM)
+ .build();
+ mBumble.hostBlocking().advertise(request);
+ }
+
+ private final OobDataCallback mGenerateOobDataCallback =
+ new OobDataCallback() {
+ @Override
+ public void onError(int error) {
+ Log.i(TAG, "onError: " + error);
+ }
+
+ @Override
+ public void onOobData(int transport, OobData data) {
+ Log.d(TAG, "OobData: " + data);
+ data.getConfirmationHash();
+ data.getRandomizerHash();
+ byte[] localData =
+ Bytes.concat(data.getConfirmationHash(), data.getRandomizerHash());
+ OobDataRequest localOobData =
+ OobDataRequest.newBuilder()
+ .setOob(ByteString.copyFrom(localData))
+ .build();
+ mRemoteOobData = mBumble.oobBlocking().shareOobData(localOobData);
+ OobData p256 = buildOobData();
+ mDevice.createBondOutOfBand(BluetoothDevice.TRANSPORT_LE, null, p256);
+ }
+ };
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mInOrder = inOrder(mReceiver);
+ doAnswer(mIntentHandler).when(mReceiver).onReceive(any(), any());
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+ mContext.registerReceiver(mReceiver, filter);
+ mDevice =
+ mAdapter.getRemoteLeDevice(
+ Utils.BUMBLE_RANDOM_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (mDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
+ mDevice.removeBond();
+ verifyIntentReceived(
+ hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED),
+ hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice),
+ hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE));
+ }
+ mContext.unregisterReceiver(mReceiver);
+ }
+
+ /**
+ * Test OOB pairing: Configuration: Initiator: Locali, Local OOB: No, Remote OOB: Yes ,Secure
+ * Connections: Yes
+ *
+ * <ol>
+ * <li>1. Android gets OOB Data from Bumble.
+ * <li>2. Android creates bond with remote OOB data
+ * <li>5. Android verifies bonded intent
+ * </ol>
+ */
+ @Test
+ public void createBondWithRemoteOob() throws Exception {
+
+ startAdvertise();
+ OobDataRequest noLocalOobData =
+ OobDataRequest.newBuilder().setOob(ByteString.EMPTY).build();
+ mRemoteOobData = mBumble.oobBlocking().shareOobData(noLocalOobData);
+ OobData p256 = buildOobData();
+ mDevice.createBondOutOfBand(BluetoothDevice.TRANSPORT_LE, null, p256);
+ verifyIntentReceived(
+ hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED),
+ hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice),
+ hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING));
+ verifyIntentReceived(
+ hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED),
+ hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice),
+ hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED));
+ }
+
+ /**
+ * Test OOB pairing: Configuration: Initiator - Local, Local OOB - Yes, Remote OOB - Yes, Secure
+ * Connections - Yes
+ *
+ * <ol>
+ * <li>1. Android gets OOB Data from Bumble.
+ * <li>2. Android creates bond with remote OOB data
+ * <li>5. Android verifies bonded intent
+ * </ol>
+ */
+ @Test
+ public void createBondWithRemoteAndLocalOob() throws Exception {
+
+ startAdvertise();
+ mAdapter.generateLocalOobData(
+ BluetoothDevice.TRANSPORT_LE, mContext.getMainExecutor(), mGenerateOobDataCallback);
+ verifyIntentReceived(
+ hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED),
+ hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice),
+ hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING));
+ verifyIntentReceived(
+ hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED),
+ hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice),
+ hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED));
+ }
+
+ @SafeVarargs
+ private void verifyIntentReceived(Matcher<Intent>... matchers) {
+ mInOrder.verify(mReceiver, timeout(INTENT_TIMEOUT.toMillis()))
+ .onReceive(any(Context.class), MockitoHamcrest.argThat(AllOf.allOf(matchers)));
+ }
+}
diff --git a/framework/tests/bumble/src/bumble_server.py b/framework/tests/bumble/src/bumble_server.py
index 227d05de14..8f5a39f8f2 100644
--- a/framework/tests/bumble/src/bumble_server.py
+++ b/framework/tests/bumble/src/bumble_server.py
@@ -26,6 +26,7 @@ from bumble_experimental.gatt import GATTService
from bumble_experimental.rfcomm import RFCOMMService
from bumble_experimental.avrcp import AvrcpService
from bumble_experimental.hid import HIDService
+from bumble_experimental.oob import OOBService
from pandora_experimental.asha_grpc_aio import add_AshaServicer_to_server
from pandora_experimental.dck_grpc_aio import add_DckServicer_to_server
@@ -33,6 +34,7 @@ from pandora_experimental.gatt_grpc_aio import add_GATTServicer_to_server
from pandora_experimental.rfcomm_grpc_aio import add_RFCOMMServicer_to_server
from pandora_experimental.avrcp_grpc_aio import add_AVRCPServicer_to_server
from pandora_experimental.hid_grpc_aio import add_HIDServicer_to_server
+from pandora_experimental.oob_grpc_aio import add_OOBServicer_to_server
from typing import Any, Dict
@@ -85,6 +87,8 @@ def register_experimental_services() -> None:
lambda bumble, _, server: add_RFCOMMServicer_to_server(RFCOMMService(bumble.device), server))
bumble_server.register_servicer_hook(
lambda bumble, _, server: add_HIDServicer_to_server(HIDService(bumble.device), server))
+ bumble_server.register_servicer_hook(
+ lambda bumble, _, server: add_OOBServicer_to_server(OOBService(bumble.device), server))
def retrieve_config(config: str) -> Dict[str, Any]:
diff --git a/pandora/interfaces/pandora_experimental/oob.proto b/pandora/interfaces/pandora_experimental/oob.proto
new file mode 100644
index 0000000000..e34c444f91
--- /dev/null
+++ b/pandora/interfaces/pandora_experimental/oob.proto
@@ -0,0 +1,24 @@
+syntax = "proto3";
+
+package pandora;
+
+option java_outer_classname = "OobProto";
+
+
+service OOB {
+ // Share OOB data
+ rpc ShareOobData(OobDataRequest) returns (OobDataResponse);
+}
+
+// Local Device OOB data.
+message OobDataRequest {
+ // OOB data Pairing Hash and Randomizer - 32 bytes.
+ bytes oob = 1;
+}
+
+// Remote Device OOB data.
+message OobDataResponse {
+ // OOB data Pairing Hash and Randomizer - 32 bytes.
+ bytes oob = 1;
+}
+
diff --git a/pandora/interfaces/python/Android.bp b/pandora/interfaces/python/Android.bp
index 4893f597c2..cffb61990a 100644
--- a/pandora/interfaces/python/Android.bp
+++ b/pandora/interfaces/python/Android.bp
@@ -66,6 +66,10 @@ genrule {
"pandora_experimental/mediaplayer_grpc_aio.py",
"pandora_experimental/mediaplayer_pb2.py",
"pandora_experimental/mediaplayer_pb2.pyi",
+ "pandora_experimental/oob_grpc.py",
+ "pandora_experimental/oob_grpc_aio.py",
+ "pandora_experimental/oob_pb2.py",
+ "pandora_experimental/oob_pb2.pyi",
"pandora_experimental/opp_grpc.py",
"pandora_experimental/opp_grpc_aio.py",
"pandora_experimental/opp_pb2.py",
@@ -113,6 +117,7 @@ filegroup {
":pandora_experimental-python-gen-src{pandora_experimental/le_audio_pb2.pyi}",
":pandora_experimental-python-gen-src{pandora_experimental/map_pb2.pyi}",
":pandora_experimental-python-gen-src{pandora_experimental/mediaplayer_pb2.pyi}",
+ ":pandora_experimental-python-gen-src{pandora_experimental/oob_pb2.pyi}",
":pandora_experimental-python-gen-src{pandora_experimental/opp_pb2.pyi}",
":pandora_experimental-python-gen-src{pandora_experimental/os_pb2.pyi}",
":pandora_experimental-python-gen-src{pandora_experimental/pan_pb2.pyi}",
diff --git a/pandora/server/bumble_experimental/oob.py b/pandora/server/bumble_experimental/oob.py
new file mode 100644
index 0000000000..7fca914ba2
--- /dev/null
+++ b/pandora/server/bumble_experimental/oob.py
@@ -0,0 +1,53 @@
+from __future__ import annotations
+import grpc
+import grpc.aio
+import logging
+
+from pandora_experimental.oob_grpc_aio import OOBServicer
+from pandora_experimental.oob_pb2 import (
+ OobDataRequest,
+ OobDataResponse,
+)
+
+from bumble.smp import OobContext, OobSharedData
+from bumble.pairing import PairingConfig, PairingDelegate
+from bumble.device import Device
+from bumble.pandora import utils
+
+
+# This class implements the Hid Pandora interface.
+class OOBService(OOBServicer):
+
+ def __init__(self, device: Device) -> None:
+ super().__init__()
+ self.log = utils.BumbleServerLoggerAdapter(logging.getLogger(), {'service_name': 'oob', 'device': device})
+ self.device = device
+
+ def configure_oob_pairing(self, peer_oob: OobSharedData) -> str:
+ our_oob_context = OobContext()
+ share_oob = our_oob_context.share().__str__()
+ self.log.debug(f"Local oob data: {share_oob}")
+ oob_contexts = PairingConfig.OobConfig(our_context=our_oob_context, peer_data=peer_oob, legacy_context=None)
+ self.device.pairing_config_factory = lambda connection: PairingConfig(
+ sc=True,
+ mitm=True,
+ bonding=True,
+ oob=oob_contexts,
+ )
+
+ return share_oob
+
+ @utils.rpc
+ async def ShareOobData(self, request: OobDataRequest, context: grpc.ServicerContext) -> OobDataResponse:
+
+ if request.oob:
+ data = str(bytes(request.oob).hex())
+ oob_c, oob_r = data[:len(data) // 2], data[len(data) // 2:]
+ peer_oob = OobSharedData(c=bytearray.fromhex(oob_c), r=bytearray.fromhex(oob_r))
+ self.log.debug(f'peer oob data {peer_oob}')
+ else:
+ peer_oob = None
+ share_oob = self.configure_oob_pairing(peer_oob)
+ # Extract data from string `OOB(C=XXXXXXXXXXXXXXXX, R=YYYYYYYYYYYYYYYY)`
+ extracted_oob = share_oob.strip("OOB()C=").replace(", R=", "")
+ return OobDataResponse(oob=bytes(bytearray.fromhex(extracted_oob)))
diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
index 6d61cea76a..bf867fe9f2 100644
--- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
@@ -84,7 +84,6 @@ import android.util.proto.ProtoOutputStream;
import androidx.annotation.RequiresApi;
import com.android.bluetooth.flags.Flags;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.expresslog.Counter;
import com.android.modules.expresslog.Histogram;
@@ -116,7 +115,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
class BluetoothManagerService {
private static final String TAG = BluetoothManagerService.class.getSimpleName();
@@ -188,9 +186,6 @@ class BluetoothManagerService {
new RemoteCallbackList<IBluetoothManagerCallback>();
private final BluetoothServiceBinder mBinder;
- private final ReentrantReadWriteLock mAdapterLock = new ReentrantReadWriteLock();
-
- @GuardedBy("mAdapterLock")
private AdapterBinder mAdapter = null;
// used inside handler thread
@@ -267,22 +262,14 @@ class BluetoothManagerService {
// Clear registered LE apps to force shut-off Bluetooth
clearBleApps();
int state = getState();
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter == null) {
- return false;
- }
- if (state == STATE_BLE_ON) {
- ActiveLogs.add(ENABLE_DISABLE_REASON_FACTORY_RESET, false);
- bleOnToOff();
- return true;
- } else if (state == STATE_ON) {
- ActiveLogs.add(ENABLE_DISABLE_REASON_FACTORY_RESET, false);
- onToBleOn();
- return true;
- }
- } finally {
- mAdapterLock.readLock().unlock();
+ if (state == STATE_BLE_ON) {
+ ActiveLogs.add(ENABLE_DISABLE_REASON_FACTORY_RESET, false);
+ bleOnToOff();
+ return true;
+ } else if (state == STATE_ON) {
+ ActiveLogs.add(ENABLE_DISABLE_REASON_FACTORY_RESET, false);
+ onToBleOn();
+ return true;
}
return false;
}
@@ -405,31 +392,15 @@ class BluetoothManagerService {
}
if (currentState == STATE_ON) {
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter == null) {
- return;
- }
- mEnable = false;
- ActiveLogs.add(reason, false);
- onToBleOn();
- } finally {
- mAdapterLock.readLock().unlock();
- }
+ mEnable = false;
+ ActiveLogs.add(reason, false);
+ onToBleOn();
} else if (currentState == STATE_BLE_ON) {
// If currentState is BLE_ON make sure we trigger stopBle
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter == null) {
- return;
- }
- mEnable = false;
- mEnableExternal = false;
- ActiveLogs.add(reason, false);
- bleOnToOff();
- } finally {
- mAdapterLock.readLock().unlock();
- }
+ mEnable = false;
+ mEnableExternal = false;
+ ActiveLogs.add(reason, false);
+ bleOnToOff();
}
}
@@ -544,20 +515,12 @@ class BluetoothManagerService {
} else if (action.equals(Intent.ACTION_SHUTDOWN)) {
Log.i(TAG, "Device is shutting down.");
mShutdownInProgress = true;
- mAdapterLock.readLock().lock();
- try {
- mEnable = false;
- mEnableExternal = false;
- if (mAdapter == null) {
- return;
- }
- if (mState.oneOf(STATE_BLE_ON)) {
- bleOnToOff();
- } else if (mState.oneOf(STATE_ON)) {
- onToBleOn();
- }
- } finally {
- mAdapterLock.readLock().unlock();
+ mEnable = false;
+ mEnableExternal = false;
+ if (mState.oneOf(STATE_BLE_ON)) {
+ bleOnToOff();
+ } else if (mState.oneOf(STATE_ON)) {
+ onToBleOn();
}
}
}
@@ -781,11 +744,14 @@ class BluetoothManagerService {
Log.d(TAG, logHeader + "Completed successfully");
}
+ // Called from unsafe binder thread
IBluetooth registerAdapter(IBluetoothManagerCallback callback) {
synchronized (mCallbacks) {
mCallbacks.register(callback);
}
- return mAdapter != null ? mAdapter.getAdapterBinder() : null;
+ // Copy to local variable to avoid race condition when checking for null
+ AdapterBinder adapter = mAdapter;
+ return adapter != null ? adapter.getAdapterBinder() : null;
}
void unregisterAdapter(IBluetoothManagerCallback callback) {
@@ -805,15 +771,13 @@ class BluetoothManagerService {
* @param userId is the foreground user id we are propagating to the Bluetooth process
*/
private void propagateForegroundUserId(int userId) {
- mAdapterLock.readLock().lock();
+ if (mAdapter == null) {
+ return;
+ }
try {
- if (mAdapter != null) {
- mAdapter.setForegroundUserId(userId, mContext.getAttributionSource());
- }
+ mAdapter.setForegroundUserId(userId, mContext.getAttributionSource());
} catch (RemoteException e) {
Log.e(TAG, "Unable to set foreground user id", e);
- } finally {
- mAdapterLock.readLock().unlock();
}
}
@@ -875,7 +839,7 @@ class BluetoothManagerService {
}
boolean isMediaProfileConnected() {
- if (mAdapter == null || !mState.oneOf(STATE_ON)) {
+ if (!mState.oneOf(STATE_ON)) {
return false;
}
return mAdapter.isMediaProfileConnected(mContext.getAttributionSource());
@@ -894,14 +858,9 @@ class BluetoothManagerService {
// BLE scan is not available.
disableBleScanMode();
clearBleApps();
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter != null) {
- ActiveLogs.add(ENABLE_DISABLE_REASON_APPLICATION_REQUEST, false);
- bleOnToOff();
- }
- } finally {
- mAdapterLock.readLock().unlock();
+ if (mState.oneOf(STATE_BLE_ON)) {
+ ActiveLogs.add(ENABLE_DISABLE_REASON_APPLICATION_REQUEST, false);
+ bleOnToOff();
}
}
};
@@ -914,14 +873,9 @@ class BluetoothManagerService {
// Disable ble scan only mode.
private void disableBleScanMode() {
- mAdapterLock.writeLock().lock();
- try {
- if (mAdapter != null && mState.oneOf(STATE_ON)) {
- Log.d(TAG, "disableBleScanMode: Resetting the mEnable flag for clean disable");
- mEnable = false;
- }
- } finally {
- mAdapterLock.writeLock().unlock();
+ if (mState.oneOf(STATE_ON)) {
+ Log.d(TAG, "disableBleScanMode: Resetting the mEnable flag for clean disable");
+ mEnable = false;
}
}
@@ -1045,30 +999,25 @@ class BluetoothManagerService {
* BLE should be off
*/
private void continueFromBleOnState() {
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter == null) {
- Log.e(TAG, "continueFromBleOnState: Adapter is null");
- return;
- }
- if (!mEnableExternal && !isBleAppPresent()) {
- // TODO(b/262605980): this code is unlikely to be trigger and will never be once
- // enableBle & disableBle are executed on the handler
- Log.i(TAG, "continueFromBleOnState: Disabled while enabling BLE, disable BLE now");
- mEnable = false;
- bleOnToOff();
- return;
- }
- if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
- Log.i(TAG, "continueFromBleOnState: Starting br edr");
- // This triggers transition to STATE_ON
- bleOnToOn();
- setBluetoothPersistedState(BLUETOOTH_ON_BLUETOOTH);
- } else {
- Log.i(TAG, "continueFromBleOnState: Staying in BLE_ON");
- }
- } finally {
- mAdapterLock.readLock().unlock();
+ if (!mState.oneOf(STATE_BLE_ON)) {
+ Log.e(TAG, "continueFromBleOnState: Impossible transition from " + mState);
+ return;
+ }
+ if (!mEnableExternal && !isBleAppPresent()) {
+ // TODO(b/262605980): this code is unlikely to be trigger and will never be once
+ // enableBle & disableBle are executed on the handler
+ Log.i(TAG, "continueFromBleOnState: Disabled while enabling BLE, disable BLE now");
+ mEnable = false;
+ bleOnToOff();
+ return;
+ }
+ if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
+ Log.i(TAG, "continueFromBleOnState: Starting br edr");
+ // This triggers transition to STATE_ON
+ bleOnToOn();
+ setBluetoothPersistedState(BLUETOOTH_ON_BLUETOOTH);
+ } else {
+ Log.i(TAG, "continueFromBleOnState: Staying in BLE_ON");
}
}
@@ -1077,26 +1026,23 @@ class BluetoothManagerService {
* if no LE app needs it
*/
private void sendBrEdrDownCallback() {
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter == null) {
- Log.w(TAG, "sendBrEdrDownCallback: mAdapter is null");
- return;
- }
- boolean scanIsAllowed =
- !Flags.respectBleScanSetting() || BleScanSettingListener.isScanAllowed();
- if (!AirplaneModeListener.isOn() && isBleAppPresent() && scanIsAllowed) {
- // Need to stay at BLE ON. Disconnect all Gatt connections
- Log.i(TAG, "sendBrEdrDownCallback: Staying in BLE_ON");
+ if (mAdapter == null) {
+ Log.d(TAG, "sendBrEdrDownCallback: mAdapter is null");
+ return;
+ }
+ boolean scanIsAllowed =
+ !Flags.respectBleScanSetting() || BleScanSettingListener.isScanAllowed();
+ if (!AirplaneModeListener.isOn() && isBleAppPresent() && scanIsAllowed) {
+ // Need to stay at BLE ON. Disconnect all Gatt connections
+ Log.i(TAG, "sendBrEdrDownCallback: Staying in BLE_ON");
+ try {
mAdapter.unregAllGattClient(mContext.getAttributionSource());
- } else {
- Log.i(TAG, "sendBrEdrDownCallback: Stopping ble");
- bleOnToOff();
+ } catch (RemoteException e) {
+ Log.e(TAG, "sendBrEdrDownCallback: failed to call unregAllGattClient()", e);
}
- } catch (RemoteException e) {
- Log.e(TAG, "sendBrEdrDownCallback: Call to mAdapter failed.", e);
- } finally {
- mAdapterLock.readLock().unlock();
+ } else {
+ Log.i(TAG, "sendBrEdrDownCallback: Stopping ble");
+ bleOnToOff();
}
}
@@ -1187,67 +1133,59 @@ class BluetoothManagerService {
void unbindAndFinish() {
Log.d(TAG, "unbindAndFinish(): mAdapter=" + mAdapter + " isBinding=" + isBinding());
- mAdapterLock.writeLock().lock();
- try {
- mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
- if (mAdapter == null) {
- return;
- }
- long currentTimeMs = System.currentTimeMillis();
+ mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
+ long currentTimeMs = System.currentTimeMillis();
- try {
- mAdapter.unregisterCallback(mBluetoothCallback, mContext.getAttributionSource());
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to unregister BluetoothCallback", e);
- }
+ try {
+ mAdapter.unregisterCallback(mBluetoothCallback, mContext.getAttributionSource());
+ } catch (RemoteException e) {
+ Log.e(TAG, "unbindAndFinish(): Unable to unregister BluetoothCallback", e);
+ }
- CompletableFuture<Void> binderDead = new CompletableFuture<>();
- try {
- mAdapter.getAdapterBinder()
- .asBinder()
- .linkToDeath(
- () -> {
- Log.i(TAG, "Successfully received Bluetooth death");
- binderDead.complete(null);
- },
- 0);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to linkToDeath", e);
- binderDead.complete(null);
- }
+ CompletableFuture<Void> binderDead = new CompletableFuture<>();
+ try {
+ mAdapter.getAdapterBinder()
+ .asBinder()
+ .linkToDeath(
+ () -> {
+ Log.i(TAG, "Successfully received Bluetooth death");
+ binderDead.complete(null);
+ },
+ 0);
+ } catch (RemoteException e) {
+ Log.e(TAG, "unbindAndFinish(): Failed to linkToDeath", e);
+ binderDead.complete(null);
+ }
- // Unbind first to avoid receiving unwanted "onServiceDisconnected"
- mContext.unbindService(mConnection);
+ // Unbind first to avoid receiving unwanted "onServiceDisconnected"
+ mContext.unbindService(mConnection);
- try {
- // Force kill Bluetooth to make sure its process is not reused.
- // Note: In a perfect world, we should be able to re-init the same process.
- // Unfortunately, this requires an heavy rework of the Bluetooth app
- // TODO: b/339501753 - Properly stop Bluetooth without killing it
- mAdapter.killBluetoothProcess();
-
- binderDead.get(2_000, TimeUnit.MILLISECONDS);
- } catch (android.os.DeadObjectException e) {
- // Reduce exception to info and skip waiting (Bluetooth is dead as wanted)
- Log.i(TAG, "Bluetooth already dead 💀");
- } catch (RemoteException e) {
- Log.e(TAG, "Unexpected RemoteException when calling killBluetoothProcess", e);
- } catch (TimeoutException | InterruptedException | ExecutionException e) {
- Log.e(TAG, "Bluetooth death not received correctly after > 2000ms", e);
- }
+ try {
+ // Force kill Bluetooth to make sure its process is not reused.
+ // Note: In a perfect world, we should be able to re-init the same process.
+ // Unfortunately, this requires an heavy rework of the Bluetooth app
+ // TODO: b/339501753 - Properly stop Bluetooth without killing it
+ mAdapter.killBluetoothProcess();
+
+ binderDead.get(2_000, TimeUnit.MILLISECONDS);
+ } catch (android.os.DeadObjectException e) {
+ // Reduce exception to info and skip waiting (Bluetooth is dead as wanted)
+ Log.i(TAG, "unbindAndFinish(): Bluetooth already dead 💀");
+ } catch (RemoteException e) {
+ Log.e(TAG, "unbindAndFinish(): Unable to call killBluetoothProcess", e);
+ } catch (TimeoutException | InterruptedException | ExecutionException e) {
+ Log.e(TAG, "unbindAndFinish(): Bluetooth death not received after > 2000ms", e);
+ }
- long timeSpentForShutdown = System.currentTimeMillis() - currentTimeMs;
- mShutdownLatencyHistogram.logSample((float) timeSpentForShutdown);
+ long timeSpentForShutdown = System.currentTimeMillis() - currentTimeMs;
+ mShutdownLatencyHistogram.logSample((float) timeSpentForShutdown);
- // TODO: b/356931756 - Remove sleep
- Log.d(TAG, "Force sleep 100 ms for propagating Bluetooth app death");
- SystemClock.sleep(100); // required to let the ActivityManager be notified of BT death
+ // TODO: b/356931756 - Remove sleep
+ Log.d(TAG, "Force sleep 100 ms for propagating Bluetooth app death");
+ SystemClock.sleep(100); // required to let the ActivityManager be notified of BT death
- mAdapter = null;
- mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
- } finally {
- mAdapterLock.writeLock().unlock();
- }
+ mAdapter = null; // Don't call resetAdapter as we already call unbindService
+ mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
}
/**
@@ -1349,58 +1287,47 @@ class BluetoothManagerService {
/** Inform BluetoothAdapter instances that Adapter service is up */
private void sendBluetoothServiceUpCallback() {
synchronized (mCallbacks) {
- mAdapterLock.readLock().lock();
- try {
- int n = mCallbacks.beginBroadcast();
- Log.d(TAG, "sendBluetoothServiceUpCallback(): to " + n + " receivers");
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks
- .getBroadcastItem(i)
- .onBluetoothServiceUp(mAdapter.getAdapterBinder().asBinder());
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
- }
+ int n = mCallbacks.beginBroadcast();
+ Log.d(TAG, "sendBluetoothServiceUpCallback(): to " + n + " receivers");
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks
+ .getBroadcastItem(i)
+ .onBluetoothServiceUp(mAdapter.getAdapterBinder().asBinder());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
}
- } finally {
- mCallbacks.finishBroadcast();
- mAdapterLock.readLock().unlock();
}
+ mCallbacks.finishBroadcast();
}
}
/** Inform BluetoothAdapter instances that Adapter service is down */
private void sendBluetoothServiceDownCallback() {
synchronized (mCallbacks) {
- try {
- int n = mCallbacks.beginBroadcast();
- Log.d(TAG, "sendBluetoothServiceDownCallback(): to " + n + " receivers");
- for (int i = 0; i < n; i++) {
- try {
- mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
- }
+ int n = mCallbacks.beginBroadcast();
+ Log.d(TAG, "sendBluetoothServiceDownCallback(): to " + n + " receivers");
+ for (int i = 0; i < n; i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
}
- } finally {
- mCallbacks.finishBroadcast();
}
+ mCallbacks.finishBroadcast();
}
}
+ // Called from unsafe binder thread
String getAddress() {
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter != null) {
+ // Copy to local variable to avoid race condition when checking for null
+ AdapterBinder adapter = mAdapter;
+ if (adapter != null) {
+ try {
return mAdapter.getAddress(mContext.getAttributionSource());
+ } catch (RemoteException e) {
+ Log.e(TAG, "getAddress(): Returning cached address", e);
}
- } catch (RemoteException e) {
- Log.e(
- TAG,
- "getAddress(): Unable to retrieve address remotely. Returning cached address",
- e);
- } finally {
- mAdapterLock.readLock().unlock();
}
// mAddress is accessed from outside.
@@ -1409,16 +1336,16 @@ class BluetoothManagerService {
return mAddress;
}
+ // Called from unsafe binder thread
String getName() {
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter != null) {
+ // Copy to local variable to avoid race condition when checking for null
+ AdapterBinder adapter = mAdapter;
+ if (adapter != null) {
+ try {
return mAdapter.getName(mContext.getAttributionSource());
+ } catch (RemoteException e) {
+ Log.e(TAG, "getName(): Returning cached name", e);
}
- } catch (RemoteException e) {
- Log.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e);
- } finally {
- mAdapterLock.readLock().unlock();
}
// mName is accessed from outside.
@@ -1468,27 +1395,22 @@ class BluetoothManagerService {
switch (msg.what) {
case MESSAGE_GET_NAME_AND_ADDRESS:
Log.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
- mAdapterLock.writeLock().lock();
- try {
- if (mAdapter == null && !isBinding()) {
- Log.d(TAG, "Binding to service to get name and address");
- mGetNameAddressOnly = true;
- bindToAdapter();
- } else if (mAdapter != null) {
- try {
- storeNameAndAddress(
- mAdapter.getName(mContext.getAttributionSource()),
- mAdapter.getAddress(mContext.getAttributionSource()));
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to grab names", e);
- }
- if (mGetNameAddressOnly && !mEnable) {
- unbindAndFinish();
- }
- mGetNameAddressOnly = false;
+ if (mAdapter == null && !isBinding()) {
+ Log.d(TAG, "Binding to service to get name and address");
+ mGetNameAddressOnly = true;
+ bindToAdapter();
+ } else if (mAdapter != null) {
+ try {
+ storeNameAndAddress(
+ mAdapter.getName(mContext.getAttributionSource()),
+ mAdapter.getAddress(mContext.getAttributionSource()));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to grab name or address", e);
+ }
+ if (mGetNameAddressOnly && !mEnable) {
+ unbindAndFinish();
}
- } finally {
- mAdapterLock.writeLock().unlock();
+ mGetNameAddressOnly = false;
}
break;
@@ -1600,42 +1522,36 @@ class BluetoothManagerService {
IBinder service = (IBinder) msg.obj;
Log.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: service=" + service);
- mAdapterLock.writeLock().lock();
- try {
- // Remove timeout
- mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+ // Remove timeout
+ mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
- mAdapter = BluetoothServerProxy.getInstance().createAdapterBinder(service);
+ mAdapter = BluetoothServerProxy.getInstance().createAdapterBinder(service);
- int foregroundUserId = ActivityManager.getCurrentUser();
- propagateForegroundUserId(foregroundUserId);
+ propagateForegroundUserId(ActivityManager.getCurrentUser());
- if (!isNameAndAddressSet()) {
- mHandler.sendEmptyMessage(MESSAGE_GET_NAME_AND_ADDRESS);
- if (mGetNameAddressOnly) {
- return;
- }
+ if (!isNameAndAddressSet()) {
+ mHandler.sendEmptyMessage(MESSAGE_GET_NAME_AND_ADDRESS);
+ if (mGetNameAddressOnly) {
+ return;
}
+ }
- // Register callback object
- try {
- mAdapter.registerCallback(
- mBluetoothCallback, mContext.getAttributionSource());
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to register BluetoothCallback", e);
- }
- // Inform BluetoothAdapter instances that service is up
- if (!Flags.fastBindToApp()) {
- sendBluetoothServiceUpCallback();
- }
+ // Register callback object
+ try {
+ mAdapter.registerCallback(
+ mBluetoothCallback, mContext.getAttributionSource());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to register BluetoothCallback", e);
+ }
+ // Inform BluetoothAdapter instances that service is up
+ if (!Flags.fastBindToApp()) {
+ sendBluetoothServiceUpCallback();
+ }
- // Do enable request
- offToBleOn();
- if (Flags.fastBindToApp()) {
- sendBluetoothServiceUpCallback();
- }
- } finally {
- mAdapterLock.writeLock().unlock();
+ // Do enable request
+ offToBleOn();
+ if (Flags.fastBindToApp()) {
+ sendBluetoothServiceUpCallback();
}
if (!mEnable) {
@@ -1657,13 +1573,11 @@ class BluetoothManagerService {
// unbind and rebind bluetooth service and enable bluetooth
if ((prevState == STATE_BLE_TURNING_ON)
&& (newState == STATE_OFF)
- && (mAdapter != null)
&& mEnable) {
recoverBluetoothServiceFromError(false);
}
if ((prevState == STATE_TURNING_ON)
&& (newState == STATE_BLE_ON)
- && (mAdapter != null)
&& mEnable) {
recoverBluetoothServiceFromError(true);
}
@@ -1689,16 +1603,9 @@ class BluetoothManagerService {
case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
Log.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED");
- mAdapterLock.writeLock().lock();
- try {
- // if service is unbinded already, do nothing and return
- if (mAdapter == null) {
- break;
- }
- mContext.unbindService(mConnection);
- mAdapter = null;
- } finally {
- mAdapterLock.writeLock().unlock();
+
+ if (!resetAdapter()) {
+ break;
}
// log the unexpected crash
@@ -1737,11 +1644,9 @@ class BluetoothManagerService {
* service restarts */
mEnable = true;
ActiveLogs.add(ENABLE_DISABLE_REASON_RESTARTED, true);
- handleEnable(mQuietEnable);
+ handleEnable();
} else {
- mAdapterLock.writeLock().lock();
- mAdapter = null;
- mAdapterLock.writeLock().unlock();
+ resetAdapter();
Log.e(TAG, "Reach maximum retry to restart Bluetooth!");
}
break;
@@ -1762,7 +1667,7 @@ class BluetoothManagerService {
mCurrentUserContext = mContext.createContextAsUser(userTo, 0);
/* disable and enable BT when detect a user switch */
- if (mAdapter != null && mState.oneOf(STATE_ON)) {
+ if (mState.oneOf(STATE_ON)) {
restartForNewUser(userTo);
} else if (isBinding() || mAdapter != null) {
Message userMsg = Message.obtain(msg);
@@ -1790,28 +1695,19 @@ class BluetoothManagerService {
// reason; maybe the Bluetooth service wasn't encryption
// aware, so try binding again.
Log.d(TAG, "Enabled but not bound; retrying after unlock");
- handleEnable(mQuietEnable);
+ handleEnable();
}
break;
}
}
private void restartForNewUser(UserHandle unusedNewUser) {
- mAdapterLock.readLock().lock();
try {
- if (mAdapter != null) {
- mAdapter.unregisterCallback(
- mBluetoothCallback, mContext.getAttributionSource());
- }
+ mAdapter.unregisterCallback(mBluetoothCallback, mContext.getAttributionSource());
} catch (RemoteException e) {
Log.e(TAG, "Unable to unregister", e);
- } finally {
- mAdapterLock.readLock().unlock();
}
- // This method is always called while bluetooth is in STATE_ON
- assert (mState.oneOf(STATE_ON));
-
// disable
ActiveLogs.add(ENABLE_DISABLE_REASON_USER_SWITCH, false);
onToBleOn();
@@ -1840,7 +1736,7 @@ class BluetoothManagerService {
ActiveLogs.add(ENABLE_DISABLE_REASON_USER_SWITCH, true);
// mEnable flag could have been reset on stopBle. Reenable it.
mEnable = true;
- handleEnable(mQuietEnable);
+ handleEnable();
}
}
@@ -1870,59 +1766,43 @@ class BluetoothManagerService {
setBluetoothPersistedState(BLUETOOTH_ON_BLUETOOTH);
}
- // Use service interface to get the exact state
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter != null) {
- boolean isHandled = true;
- switch (mState.get()) {
- case STATE_BLE_ON:
- if (isBle == 1) {
- Log.i(TAG, "Already at BLE_ON State");
- } else {
- Log.w(TAG, "BT Enable in BLE_ON State, going to ON");
- bleOnToOn();
- }
- break;
- case STATE_BLE_TURNING_ON:
- case STATE_TURNING_ON:
- case STATE_ON:
- Log.i(TAG, "MESSAGE_ENABLE: already enabled");
- break;
- default:
- isHandled = false;
- break;
- }
- if (isHandled) return;
- }
- } finally {
- mAdapterLock.readLock().unlock();
+ if (mState.oneOf(STATE_BLE_TURNING_ON, STATE_TURNING_ON, STATE_ON)) {
+ Log.i(TAG, "MESSAGE_ENABLE: already enabled. Current state=" + mState);
+ return;
}
- mQuietEnable = (quietEnable == 1);
- if (mAdapter == null) {
- handleEnable(mQuietEnable);
- } else {
+ if (mState.oneOf(STATE_BLE_ON) && isBle == 1) {
+ Log.i(TAG, "MESSAGE_ENABLE: Already in BLE_ON while being requested to go to BLE_ON");
+ return;
+ }
+
+ if (mState.oneOf(STATE_BLE_ON)) {
+ Log.i(TAG, "MESSAGE_ENABLE: Bluetooth transition from STATE_BLE_ON to STATE_ON");
+ bleOnToOn();
+ return;
+ }
+
+ if (mAdapter != null) {
+ // TODO: b/339548431 - Adapt this after removal of Flags.explicitKillFromSystemServer
//
- // We need to wait until transitioned to STATE_OFF and
- // the previous Bluetooth process has exited. The
- // waiting period has three components:
- // (a) Wait until the local state is STATE_OFF. This
- // is accomplished by sending delay a message
- // MESSAGE_HANDLE_ENABLE_DELAYED
- // (b) Wait until the STATE_OFF state is updated to
- // all components.
- // (c) Wait until the Bluetooth process exits, and
- // ActivityManager detects it.
- // The waiting for (b) and (c) is accomplished by
- // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
- // message. The delay time is backed off if Bluetooth
- // continuously failed to turn on itself.
+ // We need to wait until transitioned to STATE_OFF and the previous Bluetooth process
+ // has exited. The waiting period has three components:
+ // (a) Wait until the local state is STATE_OFF. This is accomplished by sending delay a
+ // message MESSAGE_HANDLE_ENABLE_DELAYED
+ // (b) Wait until the STATE_OFF state is updated to all components.
+ // (c) Wait until the Bluetooth process exits, and ActivityManager detects it.
//
+ // The waiting for (b) and (c) is accomplished by delaying the
+ // MESSAGE_RESTART_BLUETOOTH_SERVICE message. The delay time is backed off if Bluetooth
+ // continuously failed to turn on itself.
mWaitForEnableRetry = 0;
mHandler.sendEmptyMessageDelayed(
MESSAGE_HANDLE_ENABLE_DELAYED, ENABLE_DISABLE_DELAY_MS);
+ return;
}
+
+ mQuietEnable = (quietEnable == 1);
+ handleEnable();
}
private void handleDisableMessage() {
@@ -1966,19 +1846,21 @@ class BluetoothManagerService {
}
}
- private void handleEnable(boolean quietMode) {
- mQuietEnable = quietMode;
+ private boolean resetAdapter() {
+ if (mAdapter == null) {
+ return false;
+ }
+ mAdapter = null;
+ mContext.unbindService(mConnection);
+ return true;
+ }
- mAdapterLock.writeLock().lock();
- try {
- if (mAdapter == null && !isBinding()) {
- bindToAdapter();
- } else if (!Flags.fastBindToApp() && mAdapter != null) {
- // Enable bluetooth
- offToBleOn();
- }
- } finally {
- mAdapterLock.writeLock().unlock();
+ private void handleEnable() {
+ if (mAdapter == null && !isBinding()) {
+ bindToAdapter();
+ } else if (!Flags.fastBindToApp() && mAdapter != null) {
+ // Enable bluetooth
+ offToBleOn();
}
}
@@ -2157,16 +2039,13 @@ class BluetoothManagerService {
mHandler.removeCallbacksAndMessages(ON_AIRPLANE_MODE_CHANGED_TOKEN);
repeatAirplaneRunnable = true;
}
- mAdapterLock.readLock().lock();
- try {
- if (mAdapter != null) {
- // Unregister callback object
+
+ if (mAdapter != null) {
+ try {
mAdapter.unregisterCallback(mBluetoothCallback, mContext.getAttributionSource());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to unregister", e);
}
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to unregister", e);
- } finally {
- mAdapterLock.readLock().unlock();
}
Log.d(TAG, "Force sleep 500 ms for recovering from error");
@@ -2180,16 +2059,7 @@ class BluetoothManagerService {
sendBluetoothServiceDownCallback();
- mAdapterLock.writeLock().lock();
- try {
- if (mAdapter != null) {
- mAdapter = null;
- // Unbind
- mContext.unbindService(mConnection);
- }
- } finally {
- mAdapterLock.writeLock().unlock();
- }
+ resetAdapter();
mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
mState.set(STATE_OFF);
@@ -2566,42 +2436,22 @@ class BluetoothManagerService {
this::enableFromAutoOn)));
}
- /**
- * Check if BLE is supported by this platform
- *
- * @param context current device context
- * @return true if BLE is supported, false otherwise
- */
+ /** Check if BLE is supported by this platform */
private static boolean isBleSupported(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
- /**
- * Check if this is an automotive device
- *
- * @param context current device context
- * @return true if this Android device is an automotive device, false otherwise
- */
+ /** Check if this is an automotive device */
private static boolean isAutomotive(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
}
- /**
- * Check if this is a watch device
- *
- * @param context current device context
- * @return true if this Android device is a watch device, false otherwise
- */
+ /** Check if this is a watch device */
private static boolean isWatch(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
}
- /**
- * Check if this is a TV device
- *
- * @param context current device context
- * @return true if this Android device is a TV device, false otherwise
- */
+ /** Check if this is a TV device */
private static boolean isTv(Context context) {
PackageManager pm = context.getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
diff --git a/system/bta/Android.bp b/system/bta/Android.bp
index 8d05b06336..2a045eb947 100644
--- a/system/bta/Android.bp
+++ b/system/bta/Android.bp
@@ -41,7 +41,6 @@ filegroup {
"dm/bta_dm_ci.cc",
"dm/bta_dm_device_search.cc",
"dm/bta_dm_disc.cc",
- "dm/bta_dm_disc_legacy.cc",
"dm/bta_dm_disc_sdp.cc",
"dm/bta_dm_gatt_client.cc",
"dm/bta_dm_main.cc",
diff --git a/system/bta/BUILD.gn b/system/bta/BUILD.gn
index f8009f830d..306aaae1e9 100644
--- a/system/bta/BUILD.gn
+++ b/system/bta/BUILD.gn
@@ -45,7 +45,6 @@ static_library("bta") {
"dm/bta_dm_ci.cc",
"dm/bta_dm_device_search.cc",
"dm/bta_dm_disc.cc",
- "dm/bta_dm_disc_legacy.cc",
"dm/bta_dm_disc_sdp.cc",
"dm/bta_dm_gatt_client.cc",
"dm/bta_dm_main.cc",
diff --git a/system/bta/av/bta_av_aact.cc b/system/bta/av/bta_av_aact.cc
index a263d9b336..b6ade3ff1d 100644
--- a/system/bta/av/bta_av_aact.cc
+++ b/system/bta/av/bta_av_aact.cc
@@ -56,7 +56,6 @@
#include "stack/include/btm_client_interface.h"
#include "stack/include/btm_log_history.h"
#include "stack/include/btm_status.h"
-#include "stack/include/l2c_api.h"
#include "stack/include/l2cap_interface.h"
#include "storage/config_keys.h"
#include "types/hci_role.h"
@@ -2592,16 +2591,17 @@ void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) {
if (com::android::bluetooth::flags::fix_avdt_rconfig_not_setting_l2cap()) {
/* Set the media channel as high priority */
- if (!L2CA_SetTxPriority(p_scb->l2c_cid, L2CAP_CHNL_PRIORITY_HIGH)) {
+ if (!stack::l2cap::get_interface().L2CA_SetTxPriority(p_scb->l2c_cid,
+ L2CAP_CHNL_PRIORITY_HIGH)) {
log::warn("Unable to set L2CAP Tx priority peer:{} cid:{}", p_scb->PeerAddress(),
p_scb->l2c_cid);
}
- if (!L2CA_SetChnlFlushability(p_scb->l2c_cid, true)) {
+ if (!stack::l2cap::get_interface().L2CA_SetChnlFlushability(p_scb->l2c_cid, true)) {
log::warn("Unable to set L2CAP flush peer:{} cid:{}", p_scb->PeerAddress(), p_scb->l2c_cid);
}
- L2CA_SetMediaStreamChannel(p_scb->l2c_cid, true);
+ stack::l2cap::get_interface().L2CA_SetMediaStreamChannel(p_scb->l2c_cid, true);
}
/* rc listen */
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index bcf0dcbfc1..237da0097d 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -319,12 +319,9 @@ void bta_dm_disable() {
bta_dm_disable_pm();
}
- if (com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_disable_search();
- bta_dm_disc_disable_disc();
- } else {
- bta_dm_disc_disable_search_and_disc();
- }
+ bta_dm_disc_disable_search();
+ bta_dm_disc_disable_disc();
+
bta_dm_cb.disabling = true;
connection_manager::reset(false);
@@ -574,6 +571,10 @@ void bta_dm_remove_device(const RawAddress& target) {
RawAddress identity_addr = target;
bool le_connected = get_btm_client_interface().peer.BTM_ReadConnectedTransportAddress(
&pseudo_addr, BT_TRANSPORT_LE);
+ if (pseudo_addr.IsEmpty()) {
+ pseudo_addr = target;
+ }
+
bool bredr_connected = get_btm_client_interface().peer.BTM_ReadConnectedTransportAddress(
&identity_addr, BT_TRANSPORT_BR_EDR);
/* If connection not found with identity address, check with pseudo address if different */
@@ -582,9 +583,6 @@ void bta_dm_remove_device(const RawAddress& target) {
bredr_connected = get_btm_client_interface().peer.BTM_ReadConnectedTransportAddress(
&identity_addr, BT_TRANSPORT_BR_EDR);
}
- if (pseudo_addr.IsEmpty()) {
- pseudo_addr = target;
- }
if (identity_addr.IsEmpty()) {
identity_addr = target;
}
@@ -889,8 +887,6 @@ static void bta_dm_acl_down_(const RawAddress& bd_addr, tBT_TRANSPORT transport)
bta_dm_cb.device_list.le_count--;
}
- bta_dm_disc_acl_down(bd_addr, transport);
-
if (bta_dm_cb.disabling) {
if (!BTM_GetNumAclLinks()) {
/*
@@ -952,7 +948,6 @@ static void bta_dm_acl_down(const RawAddress& bd_addr, tBT_TRANSPORT transport)
bta_dm_cb.device_list.le_count--;
}
- bta_dm_disc_acl_down(bd_addr, transport);
if (bta_dm_cb.disabling && !BTM_GetNumAclLinks()) {
/*
* Start a timer to make sure that the profiles
diff --git a/system/bta/dm/bta_dm_device_search.cc b/system/bta/dm/bta_dm_device_search.cc
index 9f8769fe9c..bc3fde0d91 100644
--- a/system/bta/dm/bta_dm_device_search.cc
+++ b/system/bta/dm/bta_dm_device_search.cc
@@ -30,7 +30,6 @@
#include <vector>
#include "bta/dm/bta_dm_device_search_int.h"
-#include "bta/dm/bta_dm_disc_legacy.h"
#include "common/circular_buffer.h"
#include "common/strings.h"
#include "device/include/interop.h"
@@ -67,7 +66,6 @@ static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, tBT_TRANSP
static void bta_dm_discover_name(const RawAddress& remote_bd_addr);
static void bta_dm_execute_queued_search_request();
static void bta_dm_search_cancel_notify();
-static void bta_dm_disable_search();
static void bta_dm_search_sm_execute(tBTA_DM_DEV_SEARCH_EVT event,
std::unique_ptr<tBTA_DM_SEARCH_MSG> msg);
@@ -89,14 +87,6 @@ static void post_search_evt(tBTA_DM_DEV_SEARCH_EVT event, std::unique_ptr<tBTA_D
}
}
-void bta_dm_disc_disable_search() {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- log::info("no-op when flag is disabled");
- return;
- }
- bta_dm_disable_search();
-}
-
/*******************************************************************************
*
* Function bta_dm_search_start
@@ -559,12 +549,7 @@ static void bta_dm_discover_name(const RawAddress& remote_bd_addr) {
* Returns bool
*
******************************************************************************/
-bool bta_dm_is_search_request_queued() {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- return bta_dm_disc_legacy::bta_dm_is_search_request_queued();
- }
- return bta_dm_search_cb.p_pending_search != NULL;
-}
+bool bta_dm_is_search_request_queued() { return bta_dm_search_cb.p_pending_search != NULL; }
/*******************************************************************************
*
@@ -869,7 +854,7 @@ static void bta_dm_search_sm_execute(tBTA_DM_DEV_SEARCH_EVT event,
}
}
-static void bta_dm_disable_search(void) {
+void bta_dm_disc_disable_search(void) {
switch (bta_dm_search_get_state()) {
case BTA_DM_SEARCH_IDLE:
break;
@@ -885,19 +870,11 @@ static void bta_dm_disable_search(void) {
}
void bta_dm_disc_start_device_discovery(tBTA_DM_SEARCH_CBACK* p_cback) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_start_device_discovery(p_cback);
- return;
- }
bta_dm_search_sm_execute(BTA_DM_API_SEARCH_EVT, std::make_unique<tBTA_DM_SEARCH_MSG>(
tBTA_DM_API_SEARCH{.p_cback = p_cback}));
}
void bta_dm_disc_stop_device_discovery() {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_stop_device_discovery();
- return;
- }
bta_dm_search_sm_execute(BTA_DM_API_SEARCH_CANCEL_EVT, nullptr);
}
@@ -911,28 +888,12 @@ static void bta_dm_search_reset() {
bta_dm_disc_init_search_cb(::bta_dm_search_cb);
}
-void bta_dm_search_stop() {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- log::info("no-op when flag is disabled");
- return;
- }
- bta_dm_search_reset();
-}
+void bta_dm_search_stop() { bta_dm_search_reset(); }
-void bta_dm_disc_discover_next_device() {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_discover_next_device();
- return;
- }
- bta_dm_discover_next_device();
-}
+void bta_dm_disc_discover_next_device() { bta_dm_discover_next_device(); }
#define DUMPSYS_TAG "shim::legacy::bta::dm"
void DumpsysBtaDmSearch(int fd) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- log::info("no-op when flag is disabled");
- return;
- }
auto copy = search_state_history_.Pull();
LOG_DUMPSYS(fd, " last %zu search state transitions", copy.size());
for (const auto& it : copy) {
diff --git a/system/bta/dm/bta_dm_disc.cc b/system/bta/dm/bta_dm_disc.cc
index aa82c80f59..c84c0f4388 100644
--- a/system/bta/dm/bta_dm_disc.cc
+++ b/system/bta/dm/bta_dm_disc.cc
@@ -30,7 +30,6 @@
#include <vector>
#include "bta/dm/bta_dm_disc_int.h"
-#include "bta/dm/bta_dm_disc_legacy.h"
#include "bta/include/bta_gatt_api.h"
#include "common/circular_buffer.h"
#include "common/strings.h"
@@ -93,8 +92,6 @@ static void post_disc_evt(tBTA_DM_DISC_EVT event, std::unique_ptr<tBTA_DM_MSG> m
}
static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status);
-static void bta_dm_disable_disc(void);
-static void bta_dm_gattc_register(void);
static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
static void bta_dm_execute_queued_discovery_request();
static void bta_dm_close_gatt_conn();
@@ -149,27 +146,7 @@ gatt_interface_t& get_gatt_interface() { return *gatt_interface; }
} // namespace
-void bta_dm_disc_disable_search_and_disc() {
- if (com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- log::info("No one should be calling this when flag is enabled");
- return;
- }
- bta_dm_disc_legacy::bta_dm_disc_disable_search_and_disc();
-}
-
-void bta_dm_disc_disable_disc() {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- log::info("no-op when flag is disabled");
- return;
- }
- bta_dm_disable_disc();
-}
-
void bta_dm_disc_gatt_cancel_open(const RawAddress& bd_addr) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_gatt_cancel_open(bd_addr);
- return;
- }
get_gatt_interface().BTA_GATTC_CancelOpen(0, bd_addr, false);
if (com::android::bluetooth::flags::cancel_open_discovery_client() &&
bta_dm_discovery_cb.client_if != BTA_GATTS_INVALID_IF) {
@@ -178,18 +155,10 @@ void bta_dm_disc_gatt_cancel_open(const RawAddress& bd_addr) {
}
void bta_dm_disc_gatt_refresh(const RawAddress& bd_addr) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_gatt_refresh(bd_addr);
- return;
- }
get_gatt_interface().BTA_GATTC_Refresh(bd_addr);
}
void bta_dm_disc_remove_device(const RawAddress& bd_addr) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_remove_device(bd_addr);
- return;
- }
if (bta_dm_discovery_cb.service_discovery_state == BTA_DM_DISCOVER_ACTIVE &&
bta_dm_discovery_cb.peer_bdaddr == bd_addr) {
log::info("Device removed while service discovery was pending, conclude the service discovery");
@@ -197,14 +166,6 @@ void bta_dm_disc_remove_device(const RawAddress& bd_addr) {
}
}
-void bta_dm_disc_gattc_register() {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_gattc_register();
- return;
- }
- bta_dm_gattc_register();
-}
-
static void bta_dm_discovery_set_state(tBTA_DM_SERVICE_DISCOVERY_STATE state) {
bta_dm_discovery_cb.service_discovery_state = state;
}
@@ -217,15 +178,14 @@ static void bta_dm_discovery_cancel() {}
/*******************************************************************************
*
- * Function bta_dm_disable_search_and_disc
+ * Function bta_dm_disc_disable_disc
*
- * Description Cancels an ongoing search or discovery for devices in case
- * of a Bluetooth disable
+ * Description Cancels an ongoing discovery in case of a Bluetooth disable
*
* Returns void
*
******************************************************************************/
-static void bta_dm_disable_disc(void) {
+void bta_dm_disc_disable_disc(void) {
switch (bta_dm_discovery_get_state()) {
case BTA_DM_DISCOVER_IDLE:
break;
@@ -305,7 +265,7 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) {
if (!r.gatt_uuids.empty()) {
log::info("Sending GATT services discovered using SDP");
// send GATT result back to app, if any
- bta_dm_discovery_cb.service_search_cbacks.on_gatt_results(r.bd_addr, BD_NAME{}, r.gatt_uuids,
+ bta_dm_discovery_cb.service_search_cbacks.on_gatt_results(r.bd_addr, r.gatt_uuids,
/* transport_le */ false);
}
bta_dm_discovery_cb.service_search_cbacks.on_service_discovery_results(r.bd_addr, r.uuids,
@@ -315,7 +275,7 @@ static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) {
GAP_BleReadPeerPrefConnParams(bta_dm_discovery_cb.peer_bdaddr);
bta_dm_discovery_cb.service_search_cbacks.on_gatt_results(bta_dm_discovery_cb.peer_bdaddr,
- BD_NAME{}, disc_result.gatt_uuids,
+ disc_result.gatt_uuids,
/* transport_le */ true);
}
@@ -395,7 +355,7 @@ static tBT_TRANSPORT bta_dm_determine_discovery_transport(const RawAddress& remo
/* Discovers services on a remote device */
static void bta_dm_discover_services(tBTA_DM_API_DISCOVER& discover) {
- bta_dm_gattc_register();
+ bta_dm_disc_gattc_register();
RawAddress bd_addr = discover.bd_addr;
tBT_TRANSPORT transport = (discover.transport == BT_TRANSPORT_AUTO)
@@ -478,7 +438,7 @@ void bta_dm_disc_override_gatt_performer_for_testing(
/*******************************************************************************
*
- * Function bta_dm_gattc_register
+ * Function bta_dm_disc_gattc_register
*
* Description Register with GATTC in DM if BLE is needed.
*
@@ -486,7 +446,7 @@ void bta_dm_disc_override_gatt_performer_for_testing(
* Returns void
*
******************************************************************************/
-static void bta_dm_gattc_register(void) {
+void bta_dm_disc_gattc_register(void) {
if (bta_dm_discovery_cb.client_if != BTA_GATTS_INVALID_IF) {
// Already registered
return;
@@ -847,37 +807,16 @@ static void bta_dm_disc_reset() {
}
void bta_dm_disc_start(bool delay_close_gatt) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_start(delay_close_gatt);
- return;
- }
bta_dm_disc_reset();
bta_dm_discovery_cb.gatt_close_timer =
delay_close_gatt ? alarm_new("bta_dm_search.gatt_close_timer") : nullptr;
bta_dm_discovery_cb.pending_discovery_queue = {};
}
-void bta_dm_disc_acl_down(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_acl_down(bd_addr, transport);
- return;
- }
-}
-
-void bta_dm_disc_stop() {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_stop();
- return;
- }
- bta_dm_disc_reset();
-}
+void bta_dm_disc_stop() { bta_dm_disc_reset(); }
void bta_dm_disc_start_service_discovery(service_discovery_callbacks cbacks,
const RawAddress& bd_addr, tBT_TRANSPORT transport) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::bta_dm_disc_start_service_discovery(cbacks, bd_addr, transport);
- return;
- }
bta_dm_disc_sm_execute(BTA_DM_API_DISCOVER_EVT,
std::make_unique<tBTA_DM_MSG>(tBTA_DM_API_DISCOVER{
.bd_addr = bd_addr, .cbacks = cbacks, .transport = transport}));
@@ -885,10 +824,6 @@ void bta_dm_disc_start_service_discovery(service_discovery_callbacks cbacks,
#define DUMPSYS_TAG "shim::legacy::bta::dm"
void DumpsysBtaDmDisc(int fd) {
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- bta_dm_disc_legacy::DumpsysBtaDmDisc(fd);
- return;
- }
auto copy = discovery_state_history_.Pull();
LOG_DUMPSYS(fd, " last %zu discovery state transitions", copy.size());
for (const auto& it : copy) {
diff --git a/system/bta/dm/bta_dm_disc.h b/system/bta/dm/bta_dm_disc.h
index 4190fa1ce7..a243b785d9 100644
--- a/system/bta/dm/bta_dm_disc.h
+++ b/system/bta/dm/bta_dm_disc.h
@@ -34,13 +34,7 @@ void bta_dm_disc_start_service_discovery(service_discovery_callbacks cbacks,
const RawAddress& bd_addr, tBT_TRANSPORT transport);
// Bta subsystem entrypoint and lifecycle
-// Remove when separate_service_and_device_discovery rolls out
-void bta_dm_disc_disable_search_and_disc();
void bta_dm_disc_disable_disc();
-void bta_dm_disc_disable_search();
-// Indication that an acl has gone down and to examine the current
-// service discovery procedure, if any.
-void bta_dm_disc_acl_down(const RawAddress& bd_addr, tBT_TRANSPORT transport);
// LE observe and scan interface
void bta_dm_ble_scan(bool start, uint8_t duration_sec);
diff --git a/system/bta/dm/bta_dm_disc_int_legacy.h b/system/bta/dm/bta_dm_disc_int_legacy.h
deleted file mode 100644
index b8c3ad2567..0000000000
--- a/system/bta/dm/bta_dm_disc_int_legacy.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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 <base/strings/stringprintf.h>
-#include <bluetooth/log.h>
-
-#include <queue>
-#include <string>
-
-#include "bta/include/bta_api.h"
-#include "bta/sys/bta_sys.h"
-#include "macros.h"
-#include "stack/btm/neighbor_inquiry.h"
-#include "stack/include/sdp_status.h"
-#include "stack/sdp/sdp_discovery_db.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-#define BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 << (id))
-
-// TODO: Remove this file after flag separate_service_and_device_discovery rolls
-// out
-namespace bta_dm_disc_legacy {
-
-/* DM search events */
-typedef enum : uint16_t {
- /* DM search API events */
- BTA_DM_API_SEARCH_EVT,
- BTA_DM_API_SEARCH_CANCEL_EVT,
- BTA_DM_API_DISCOVER_EVT,
- BTA_DM_INQUIRY_CMPL_EVT,
- BTA_DM_REMT_NAME_EVT,
- BTA_DM_SDP_RESULT_EVT,
- BTA_DM_SEARCH_CMPL_EVT,
- BTA_DM_DISCOVERY_RESULT_EVT,
- BTA_DM_DISC_CLOSE_TOUT_EVT,
-} tBTA_DM_EVT;
-
-inline std::string bta_dm_event_text(const tBTA_DM_EVT& event) {
- switch (event) {
- CASE_RETURN_TEXT(BTA_DM_API_SEARCH_EVT);
- CASE_RETURN_TEXT(BTA_DM_API_SEARCH_CANCEL_EVT);
- CASE_RETURN_TEXT(BTA_DM_API_DISCOVER_EVT);
- CASE_RETURN_TEXT(BTA_DM_INQUIRY_CMPL_EVT);
- CASE_RETURN_TEXT(BTA_DM_REMT_NAME_EVT);
- CASE_RETURN_TEXT(BTA_DM_SDP_RESULT_EVT);
- CASE_RETURN_TEXT(BTA_DM_SEARCH_CMPL_EVT);
- CASE_RETURN_TEXT(BTA_DM_DISCOVERY_RESULT_EVT);
- CASE_RETURN_TEXT(BTA_DM_DISC_CLOSE_TOUT_EVT);
- default:
- return base::StringPrintf("UNKNOWN[0x%04x]", event);
- }
-}
-
-/* data type for BTA_DM_API_SEARCH_EVT */
-typedef struct {
- tBTA_DM_SEARCH_CBACK* p_cback;
-} tBTA_DM_API_SEARCH;
-
-/* data type for BTA_DM_API_DISCOVER_EVT */
-typedef struct {
- RawAddress bd_addr;
- service_discovery_callbacks cbacks;
- tBT_TRANSPORT transport;
-} tBTA_DM_API_DISCOVER;
-
-typedef struct {
-} tBTA_DM_API_DISCOVERY_CANCEL;
-
-typedef struct {
- RawAddress bd_addr;
- BD_NAME bd_name; /* Name of peer device. */
- tHCI_STATUS hci_status;
-} tBTA_DM_REMOTE_NAME;
-
-/* data type for tBTA_DM_DISC_RESULT */
-typedef struct {
- tBTA_DM_SEARCH result;
-} tBTA_DM_DISC_RESULT;
-
-/* data type for BTA_DM_INQUIRY_CMPL_EVT */
-typedef struct {
- uint8_t num;
-} tBTA_DM_INQUIRY_CMPL;
-
-/* data type for BTA_DM_SDP_RESULT_EVT */
-typedef struct {
- tSDP_RESULT sdp_result;
-} tBTA_DM_SDP_RESULT;
-
-typedef struct {
- bool enable;
-} tBTA_DM_API_BLE_FEATURE;
-
-typedef struct {
- RawAddress bd_addr; /* BD address peer device. */
- tBTA_SERVICE_MASK services; /* Services found on peer device. */
- tBT_DEVICE_TYPE device_type; /* device type in case it is BLE device */
- std::vector<bluetooth::Uuid> uuids;
- tBTA_STATUS result;
- tHCI_STATUS hci_status;
-} tBTA_DM_SVC_RES;
-
-using tBTA_DM_MSG = std::variant<tBTA_DM_API_SEARCH, tBTA_DM_API_DISCOVER, tBTA_DM_REMOTE_NAME,
- tBTA_DM_DISC_RESULT, tBTA_DM_INQUIRY_CMPL, tBTA_DM_SDP_RESULT,
- tBTA_DM_SVC_RES>;
-
-/* DM search state */
-typedef enum {
-
- BTA_DM_SEARCH_IDLE,
- BTA_DM_SEARCH_ACTIVE,
- BTA_DM_SEARCH_CANCELLING,
- BTA_DM_DISCOVER_ACTIVE
-
-} tBTA_DM_STATE;
-
-inline std::string bta_dm_state_text(const tBTA_DM_STATE& state) {
- switch (state) {
- CASE_RETURN_TEXT(BTA_DM_SEARCH_IDLE);
- CASE_RETURN_TEXT(BTA_DM_SEARCH_ACTIVE);
- CASE_RETURN_TEXT(BTA_DM_SEARCH_CANCELLING);
- CASE_RETURN_TEXT(BTA_DM_DISCOVER_ACTIVE);
- default:
- return base::StringPrintf("UNKNOWN[%d]", state);
- }
-}
-
-/* DM search control block */
-typedef struct {
- tBTA_DM_SEARCH_CBACK* p_device_search_cback;
- service_discovery_callbacks service_search_cbacks;
- tBTM_INQ_INFO* p_btm_inq_info;
- tBTA_SERVICE_MASK services_to_search;
- tBTA_SERVICE_MASK services_found;
- tSDP_DISCOVERY_DB* p_sdp_db;
- tBTA_DM_STATE state;
- RawAddress peer_bdaddr;
- bool name_discover_done;
- BD_NAME peer_name;
- alarm_t* search_timer;
- uint8_t service_index;
- std::unique_ptr<tBTA_DM_MSG> p_pending_search;
- std::queue<tBTA_DM_API_DISCOVER> pending_discovery_queue;
- bool wait_disc;
- bool sdp_results;
- bluetooth::Uuid uuid;
- uint8_t peer_scn;
- tBT_TRANSPORT transport;
- tBTA_DM_SEARCH_CBACK* p_csis_scan_cback;
- tGATT_IF client_if;
- uint8_t uuid_to_search;
- bool gatt_disc_active;
- uint16_t conn_id;
- alarm_t* gatt_close_timer; /* GATT channel close delay timer */
- RawAddress pending_close_bda; /* pending GATT channel remote device address */
-
-} tBTA_DM_SEARCH_CB;
-
-extern const uint32_t bta_service_id_to_btm_srv_id_lkup_tbl[];
-extern const uint16_t bta_service_id_to_uuid_lkup_tbl[];
-
-} // namespace bta_dm_disc_legacy
-
-namespace fmt {
-template <>
-struct formatter<bta_dm_disc_legacy::tBTA_DM_EVT>
- : enum_formatter<bta_dm_disc_legacy::tBTA_DM_EVT> {};
-template <>
-struct formatter<bta_dm_disc_legacy::tBTA_DM_STATE>
- : enum_formatter<bta_dm_disc_legacy::tBTA_DM_STATE> {};
-} // namespace fmt
diff --git a/system/bta/dm/bta_dm_disc_legacy.cc b/system/bta/dm/bta_dm_disc_legacy.cc
deleted file mode 100644
index 5bac53bfad..0000000000
--- a/system/bta/dm/bta_dm_disc_legacy.cc
+++ /dev/null
@@ -1,2080 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "bt_bta_dm"
-
-#include "bta/dm/bta_dm_disc_legacy.h"
-
-#include <base/functional/bind.h>
-#include <base/strings/stringprintf.h>
-#include <bluetooth/log.h>
-#include <com_android_bluetooth_flags.h>
-#include <stddef.h>
-
-#include <cstdint>
-#include <string>
-#include <variant>
-#include <vector>
-
-#include "bta/dm/bta_dm_disc_int_legacy.h"
-#include "bta/include/bta_gatt_api.h"
-#include "bta/include/bta_sdp_api.h"
-#include "btif/include/btif_config.h"
-#include "common/circular_buffer.h"
-#include "common/strings.h"
-#include "device/include/interop.h"
-#include "internal_include/bt_target.h"
-#include "main/shim/dumpsys.h"
-#include "os/logging/log_adapter.h"
-#include "osi/include/allocator.h"
-#include "stack/btm/btm_int_types.h" // TimestampedStringCircularBuffer
-#include "stack/btm/neighbor_inquiry.h"
-#include "stack/include/bt_dev_class.h"
-#include "stack/include/bt_name.h"
-#include "stack/include/bt_uuid16.h"
-#include "stack/include/btm_client_interface.h"
-#include "stack/include/btm_inq.h"
-#include "stack/include/btm_log_history.h"
-#include "stack/include/btm_status.h"
-#include "stack/include/gap_api.h" // GAP_BleReadPeerPrefConnParams
-#include "stack/include/hidh_api.h"
-#include "stack/include/main_thread.h"
-#include "stack/include/rnr_interface.h"
-#include "stack/include/sdp_status.h"
-#include "stack/rnr/remote_name_request.h"
-#include "stack/sdp/sdpint.h" // is_sdp_pbap_pce_disabled
-#include "storage/config_keys.h"
-#include "types/raw_address.h"
-
-#ifdef TARGET_FLOSS
-#include "stack/include/srvc_api.h"
-#endif
-
-// TODO: Remove this file after flag separate_service_and_device_discovery rolls
-// out
-namespace bta_dm_disc_legacy {
-
-using ::bluetooth::Uuid;
-using namespace ::bluetooth::legacy::stack::sdp;
-using namespace ::bluetooth;
-
-tBTM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
-
-namespace {
-constexpr char kBtmLogTag[] = "SDP";
-
-tBTA_DM_SEARCH_CB bta_dm_search_cb;
-} // namespace
-
-static void bta_dm_search_sm_execute(tBTA_DM_EVT event, std::unique_ptr<tBTA_DM_MSG> msg);
-static void post_disc_evt(tBTA_DM_EVT event, std::unique_ptr<tBTA_DM_MSG> msg) {
- if (do_in_main_thread(base::BindOnce(&bta_dm_search_sm_execute, event, std::move(msg))) !=
- BT_STATUS_SUCCESS) {
- log::error("post_disc_evt failed");
- }
-}
-
-static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status);
-static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir, uint16_t eir_len);
-static void bta_dm_inq_cmpl();
-static void bta_dm_inq_cmpl_cb(void* p_result);
-static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, DEV_CLASS dc,
- BD_NAME bd_name);
-static void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p);
-static void bta_dm_find_services(const RawAddress& bd_addr);
-static void bta_dm_discover_next_device(void);
-static void bta_dm_sdp_callback(const RawAddress& bd_addr, tSDP_STATUS sdp_status);
-
-static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, tBT_TRANSPORT transport);
-static void bta_dm_discover_name(const RawAddress& remote_bd_addr);
-static void bta_dm_discover_services(const RawAddress& remote_bd_addr);
-
-static void bta_dm_disable_search_and_disc(void);
-
-static void bta_dm_gattc_register(void);
-static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr);
-static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
-static void bta_dm_search_cmpl();
-static void bta_dm_free_sdp_db();
-static void bta_dm_execute_queued_request();
-static void bta_dm_search_cancel_notify();
-static void bta_dm_close_gatt_conn();
-
-TimestampedStringCircularBuffer disc_gatt_history_{50};
-
-namespace {
-
-struct gatt_interface_t {
- void (*BTA_GATTC_CancelOpen)(tGATT_IF client_if, const RawAddress& remote_bda, bool is_direct);
- void (*BTA_GATTC_Refresh)(const RawAddress& remote_bda);
- void (*BTA_GATTC_GetGattDb)(uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
- btgatt_db_element_t** db, int* count);
- void (*BTA_GATTC_AppRegister)(tBTA_GATTC_CBACK* p_client_cb, BtaAppRegisterCallback cb,
- bool eatt_support);
- void (*BTA_GATTC_Close)(uint16_t conn_id);
- void (*BTA_GATTC_ServiceSearchRequest)(uint16_t conn_id, const bluetooth::Uuid* p_srvc_uuid);
- void (*BTA_GATTC_Open)(tGATT_IF client_if, const RawAddress& remote_bda,
- tBTM_BLE_CONN_TYPE connection_type, bool opportunistic);
-} default_gatt_interface = {
- .BTA_GATTC_CancelOpen =
- [](tGATT_IF client_if, const RawAddress& remote_bda, bool is_direct) {
- disc_gatt_history_.Push(base::StringPrintf(
- "%-32s bd_addr:%s client_if:%hu is_direct:%c", "GATTC_CancelOpen",
- ADDRESS_TO_LOGGABLE_CSTR(remote_bda), client_if,
- (is_direct) ? 'T' : 'F'));
- BTA_GATTC_CancelOpen(client_if, remote_bda, is_direct);
- },
- .BTA_GATTC_Refresh =
- [](const RawAddress& remote_bda) {
- disc_gatt_history_.Push(base::StringPrintf("%-32s bd_addr:%s", "GATTC_Refresh",
- ADDRESS_TO_LOGGABLE_CSTR(remote_bda)));
- BTA_GATTC_Refresh(remote_bda);
- },
- .BTA_GATTC_GetGattDb =
- [](uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
- btgatt_db_element_t** db, int* count) {
- disc_gatt_history_.Push(
- base::StringPrintf("%-32s conn_id:%hu start_handle:%hu end:handle:%hu",
- "GATTC_GetGattDb", conn_id, start_handle, end_handle));
- BTA_GATTC_GetGattDb(conn_id, start_handle, end_handle, db, count);
- },
- .BTA_GATTC_AppRegister =
- [](tBTA_GATTC_CBACK* p_client_cb, BtaAppRegisterCallback cb, bool eatt_support) {
- disc_gatt_history_.Push(base::StringPrintf("%-32s eatt_support:%c",
- "GATTC_AppRegister",
- (eatt_support) ? 'T' : 'F'));
- BTA_GATTC_AppRegister(p_client_cb, cb, eatt_support);
- },
- .BTA_GATTC_Close =
- [](uint16_t conn_id) {
- disc_gatt_history_.Push(
- base::StringPrintf("%-32s conn_id:%hu", "GATTC_Close", conn_id));
- BTA_GATTC_Close(conn_id);
- },
- .BTA_GATTC_ServiceSearchRequest =
- [](uint16_t conn_id, const bluetooth::Uuid* p_srvc_uuid) {
- disc_gatt_history_.Push(base::StringPrintf(
- "%-32s conn_id:%hu", "GATTC_ServiceSearchRequest", conn_id));
- if (p_srvc_uuid) {
- BTA_GATTC_ServiceSearchRequest(conn_id, *p_srvc_uuid);
- } else {
- BTA_GATTC_ServiceSearchAllRequest(conn_id);
- }
- },
- .BTA_GATTC_Open =
- [](tGATT_IF client_if, const RawAddress& remote_bda,
- tBTM_BLE_CONN_TYPE connection_type, bool opportunistic) {
- disc_gatt_history_.Push(base::StringPrintf(
- "%-32s bd_addr:%s client_if:%hu type:0x%x opportunistic:%c", "GATTC_Open",
- ADDRESS_TO_LOGGABLE_CSTR(remote_bda), client_if, connection_type,
- (opportunistic) ? 'T' : 'F'));
- BTA_GATTC_Open(client_if, remote_bda, connection_type, opportunistic);
- },
-};
-
-gatt_interface_t* gatt_interface = &default_gatt_interface;
-
-gatt_interface_t& get_gatt_interface() { return *gatt_interface; }
-
-} // namespace
-
-void bta_dm_disc_disable_search_and_disc() { bta_dm_disable_search_and_disc(); }
-
-void bta_dm_disc_gatt_cancel_open(const RawAddress& bd_addr) {
- get_gatt_interface().BTA_GATTC_CancelOpen(0, bd_addr, false);
- if (com::android::bluetooth::flags::cancel_open_discovery_client() &&
- bta_dm_search_cb.client_if != BTA_GATTS_INVALID_IF) {
- get_gatt_interface().BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, true);
- }
-}
-
-void bta_dm_disc_gatt_refresh(const RawAddress& bd_addr) {
- get_gatt_interface().BTA_GATTC_Refresh(bd_addr);
-}
-
-void bta_dm_disc_remove_device(const RawAddress& bd_addr) {
- if (bta_dm_search_cb.state == BTA_DM_DISCOVER_ACTIVE && bta_dm_search_cb.peer_bdaddr == bd_addr) {
- log::info("Device removed while service discovery was pending, conclude the service discovery");
- bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID, (tGATT_STATUS)GATT_ERROR);
- }
-}
-
-void bta_dm_disc_discover_next_device() { bta_dm_discover_next_device(); }
-
-void bta_dm_disc_gattc_register() { bta_dm_gattc_register(); }
-
-const uint16_t bta_service_id_to_uuid_lkup_tbl[BTA_MAX_SERVICE_ID] = {
- UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */
- UUID_SERVCLASS_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */
- UUID_SERVCLASS_DIALUP_NETWORKING, /* BTA_DUN_SERVICE_ID */
- UUID_SERVCLASS_AUDIO_SOURCE, /* BTA_A2DP_SOURCE_SERVICE_ID */
- UUID_SERVCLASS_LAN_ACCESS_USING_PPP, /* BTA_LAP_SERVICE_ID */
- UUID_SERVCLASS_HEADSET, /* BTA_HSP_HS_SERVICE_ID */
- UUID_SERVCLASS_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */
- UUID_SERVCLASS_OBEX_OBJECT_PUSH, /* BTA_OPP_SERVICE_ID */
- UUID_SERVCLASS_OBEX_FILE_TRANSFER, /* BTA_FTP_SERVICE_ID */
- UUID_SERVCLASS_CORDLESS_TELEPHONY, /* BTA_CTP_SERVICE_ID */
- UUID_SERVCLASS_INTERCOM, /* BTA_ICP_SERVICE_ID */
- UUID_SERVCLASS_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */
- UUID_SERVCLASS_DIRECT_PRINTING, /* BTA_BPP_SERVICE_ID */
- UUID_SERVCLASS_IMAGING_RESPONDER, /* BTA_BIP_SERVICE_ID */
- UUID_SERVCLASS_PANU, /* BTA_PANU_SERVICE_ID */
- UUID_SERVCLASS_NAP, /* BTA_NAP_SERVICE_ID */
- UUID_SERVCLASS_GN, /* BTA_GN_SERVICE_ID */
- UUID_SERVCLASS_SAP, /* BTA_SAP_SERVICE_ID */
- UUID_SERVCLASS_AUDIO_SINK, /* BTA_A2DP_SERVICE_ID */
- UUID_SERVCLASS_AV_REMOTE_CONTROL, /* BTA_AVRCP_SERVICE_ID */
- UUID_SERVCLASS_HUMAN_INTERFACE, /* BTA_HID_SERVICE_ID */
- UUID_SERVCLASS_VIDEO_SINK, /* BTA_VDP_SERVICE_ID */
- UUID_SERVCLASS_PBAP_PSE, /* BTA_PBAP_SERVICE_ID */
- UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, /* BTA_HSP_SERVICE_ID */
- UUID_SERVCLASS_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */
- UUID_SERVCLASS_MESSAGE_ACCESS, /* BTA_MAP_SERVICE_ID */
- UUID_SERVCLASS_MESSAGE_NOTIFICATION, /* BTA_MN_SERVICE_ID */
- UUID_SERVCLASS_HDP_PROFILE, /* BTA_HDP_SERVICE_ID */
- UUID_SERVCLASS_PBAP_PCE, /* BTA_PCE_SERVICE_ID */
- UUID_PROTOCOL_ATT /* BTA_GATT_SERVICE_ID */
-};
-
-#define MAX_DISC_RAW_DATA_BUF (4096)
-static uint8_t g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF];
-
-static void bta_dm_search_set_state(tBTA_DM_STATE state) { bta_dm_search_cb.state = state; }
-static tBTA_DM_STATE bta_dm_search_get_state() { return bta_dm_search_cb.state; }
-
-/*******************************************************************************
- *
- * Function bta_dm_search_start
- *
- * Description Starts an inquiry
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_search_start(tBTA_DM_API_SEARCH& search) {
- bta_dm_gattc_register();
-
- if (get_btm_client_interface().db.BTM_ClearInqDb(nullptr) != tBTM_STATUS::BTM_SUCCESS) {
- log::warn("Unable to clear inquiry db for device discovery");
- }
-
- /* save search params */
- bta_dm_search_cb.p_device_search_cback = search.p_cback;
-
- const tBTM_STATUS btm_status = BTM_StartInquiry(bta_dm_inq_results_cb, bta_dm_inq_cmpl_cb);
- switch (btm_status) {
- case tBTM_STATUS::BTM_CMD_STARTED:
- // Completion callback will be executed when controller inquiry
- // timer pops or is cancelled by the user
- break;
- default:
- log::warn("Unable to start device discovery search btm_status:{}",
- btm_status_text(btm_status));
- // Not started so completion callback is executed now
- bta_dm_inq_cmpl();
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_search_cancel
- *
- * Description Cancels an ongoing search for devices
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_search_cancel() {
- if (BTM_IsInquiryActive()) {
- BTM_CancelInquiry();
- bta_dm_search_cancel_notify();
- bta_dm_search_cmpl();
- }
- /* If no Service Search going on then issue cancel remote name in case it is
- active */
- else if (!bta_dm_search_cb.name_discover_done) {
- if (get_stack_rnr_interface().BTM_CancelRemoteDeviceName() != tBTM_STATUS::BTM_CMD_STARTED) {
- log::warn("Unable to cancel RNR");
- }
- /* bta_dm_search_cmpl is called when receiving the remote name cancel evt */
- if (!com::android::bluetooth::flags::
- bta_dm_defer_device_discovery_state_change_until_rnr_complete()) {
- bta_dm_search_cmpl();
- }
- } else {
- bta_dm_inq_cmpl();
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_discover
- *
- * Description Discovers services on a remote device
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_discover(tBTA_DM_API_DISCOVER& discover) {
- bta_dm_gattc_register();
-
- bta_dm_search_cb.service_search_cbacks = discover.cbacks;
- bta_dm_search_cb.services_to_search = BTA_ALL_SERVICE_MASK;
- bta_dm_search_cb.service_index = 0;
- bta_dm_search_cb.services_found = 0;
- bta_dm_search_cb.peer_name[0] = 0;
- bta_dm_search_cb.p_btm_inq_info = get_btm_client_interface().db.BTM_InqDbRead(discover.bd_addr);
- bta_dm_search_cb.transport = discover.transport;
-
- bta_dm_search_cb.name_discover_done = false;
-
- log::info("bta_dm_discovery: starting service discovery to {} , transport: {}", discover.bd_addr,
- bt_transport_text(discover.transport));
- bta_dm_discover_services(discover.bd_addr);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_disable_search_and_disc
- *
- * Description Cancels an ongoing search or discovery for devices in case
- * of a Bluetooth disable
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_disable_search_and_disc(void) {
- switch (bta_dm_search_get_state()) {
- case BTA_DM_SEARCH_IDLE:
- break;
- case BTA_DM_SEARCH_ACTIVE:
- case BTA_DM_SEARCH_CANCELLING:
- case BTA_DM_DISCOVER_ACTIVE:
- default:
- log::debug("Search state machine is not idle so issuing search cancel current state:{}",
- bta_dm_state_text(bta_dm_search_get_state()));
- bta_dm_search_cancel();
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_read_remote_device_name
- *
- * Description Initiate to get remote device name
- *
- * Returns true if started to get remote name
- *
- ******************************************************************************/
-static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
- tBTM_STATUS btm_status;
-
- log::verbose("");
-
- bta_dm_search_cb.peer_bdaddr = bd_addr;
- bta_dm_search_cb.peer_name[0] = 0;
-
- btm_status = get_stack_rnr_interface().BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr,
- bta_dm_remname_cback, transport);
-
- if (btm_status == tBTM_STATUS::BTM_CMD_STARTED) {
- log::verbose("BTM_ReadRemoteDeviceName is started");
-
- return true;
- } else if (btm_status == tBTM_STATUS::BTM_BUSY) {
- log::verbose("BTM_ReadRemoteDeviceName is busy");
-
- /* Remote name discovery is on going now so BTM cannot notify through
- * "bta_dm_remname_cback" */
- /* adding callback to get notified that current reading remote name done */
-
- get_stack_rnr_interface().BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
-
- return true;
- } else {
- log::warn("BTM_ReadRemoteDeviceName returns 0x{:02X}", btm_status);
-
- return false;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_inq_cmpl
- *
- * Description Process the inquiry complete event from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_inq_cmpl() {
- if (bta_dm_search_get_state() == BTA_DM_SEARCH_CANCELLING) {
- bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
- bta_dm_execute_queued_request();
- return;
- }
-
- if (bta_dm_search_get_state() != BTA_DM_SEARCH_ACTIVE) {
- return;
- }
-
- log::verbose("bta_dm_inq_cmpl");
-
- bta_dm_search_cb.p_btm_inq_info = get_btm_client_interface().db.BTM_InqDbFirst();
- if (bta_dm_search_cb.p_btm_inq_info != NULL) {
- /* start name discovery from the first device on inquiry result
- */
- bta_dm_search_cb.name_discover_done = false;
- bta_dm_search_cb.peer_name[0] = 0;
- bta_dm_discover_name(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
- } else {
- bta_dm_search_cmpl();
- }
-}
-
-static void bta_dm_remote_name_cmpl(const tBTA_DM_REMOTE_NAME& remote_name_msg) {
- BTM_LogHistory(kBtmLogTag, remote_name_msg.bd_addr, "Remote name completed",
- base::StringPrintf("status:%s state:%s name:\"%s\"",
- hci_status_code_text(remote_name_msg.hci_status).c_str(),
- bta_dm_state_text(bta_dm_search_get_state()).c_str(),
- PRIVATE_NAME(remote_name_msg.bd_name)));
-
- tBTM_INQ_INFO* p_btm_inq_info =
- get_btm_client_interface().db.BTM_InqDbRead(remote_name_msg.bd_addr);
- if (!bd_name_is_empty(remote_name_msg.bd_name) && p_btm_inq_info) {
- p_btm_inq_info->appl_knows_rem_name = true;
- }
-
- // Callback with this property
- if (bta_dm_search_cb.p_device_search_cback != nullptr ||
- bta_dm_search_cb.service_search_cbacks.on_name_read != nullptr) {
- // Both device and service search callbacks end up sending event to java.
- // It's enough to send callback to just one of them.
- if (bta_dm_search_cb.p_device_search_cback != nullptr) {
- tBTA_DM_SEARCH search_data = {
- .name_res = {.bd_addr = remote_name_msg.bd_addr, .bd_name = {}},
- };
- if (remote_name_msg.hci_status == HCI_SUCCESS) {
- bd_name_copy(search_data.name_res.bd_name, remote_name_msg.bd_name);
- }
- bta_dm_search_cb.p_device_search_cback(BTA_DM_NAME_READ_EVT, &search_data);
- } else if (bta_dm_search_cb.service_search_cbacks.on_name_read != nullptr) {
- bta_dm_search_cb.service_search_cbacks.on_name_read(
- remote_name_msg.bd_addr, remote_name_msg.hci_status, remote_name_msg.bd_name);
- }
- } else {
- log::warn("Received remote name complete without callback");
- }
-
- switch (bta_dm_search_get_state()) {
- case BTA_DM_SEARCH_ACTIVE:
- bta_dm_discover_name(bta_dm_search_cb.peer_bdaddr);
- break;
- case BTA_DM_DISCOVER_ACTIVE:
- /* TODO: Get rid of this case when Name and Service discovery state
- * machines are separated */
- bta_dm_discover_name(remote_name_msg.bd_addr);
- break;
- case BTA_DM_SEARCH_IDLE:
- case BTA_DM_SEARCH_CANCELLING:
- log::warn("Received remote name request in state:{}",
- bta_dm_state_text(bta_dm_search_get_state()));
- break;
- }
-}
-
-static void store_avrcp_profile_feature(tSDP_DISC_REC* sdp_rec) {
- tSDP_DISC_ATTR* p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
- sdp_rec, ATTR_ID_SUPPORTED_FEATURES);
- if (p_attr == NULL) {
- return;
- }
-
- uint16_t avrcp_features = p_attr->attr_value.v.u16;
- if (avrcp_features == 0) {
- return;
- }
-
- if (btif_config_set_bin(sdp_rec->remote_bd_addr.ToString().c_str(),
- BTIF_STORAGE_KEY_AV_REM_CTRL_FEATURES, (const uint8_t*)&avrcp_features,
- sizeof(avrcp_features))) {
- log::info("Saving avrcp_features: 0x{:x}", avrcp_features);
- } else {
- log::info("Failed to store avrcp_features 0x{:x} for {}", avrcp_features,
- sdp_rec->remote_bd_addr);
- }
-}
-
-static void bta_dm_store_audio_profiles_version() {
- struct AudioProfile {
- const uint16_t servclass_uuid;
- const uint16_t btprofile_uuid;
- const char* profile_key;
- void (*store_audio_profile_feature)(tSDP_DISC_REC*);
- };
-
- std::array<AudioProfile, 1> audio_profiles = {{
- {
- .servclass_uuid = UUID_SERVCLASS_AV_REMOTE_CONTROL,
- .btprofile_uuid = UUID_SERVCLASS_AV_REMOTE_CONTROL,
- .profile_key = BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION,
- .store_audio_profile_feature = store_avrcp_profile_feature,
- },
- }};
-
- for (const auto& audio_profile : audio_profiles) {
- 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 (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) */
- if (!get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
- sdp_rec, audio_profile.btprofile_uuid, &profile_version)) {
- log::warn("Unable to find SDP profile version in record peer:{}", sdp_rec->remote_bd_addr);
- }
- if (profile_version != 0) {
- if (btif_config_set_bin(sdp_rec->remote_bd_addr.ToString().c_str(), audio_profile.profile_key,
- (const uint8_t*)&profile_version, sizeof(profile_version))) {
- } else {
- log::info("Failed to store peer profile version for {}", sdp_rec->remote_bd_addr);
- }
- }
- audio_profile.store_audio_profile_feature(sdp_rec);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_sdp_result
- *
- * Description Process the discovery result from sdp
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_sdp_result(tBTA_DM_SDP_RESULT& sdp_event) {
- tSDP_DISC_REC* p_sdp_rec = NULL;
- bool scn_found = false;
- uint16_t service = 0xFFFF;
- tSDP_PROTOCOL_ELEM pe;
-
- std::vector<Uuid> uuid_list;
-
- const tSDP_RESULT sdp_result = sdp_event.sdp_result;
-
- if ((sdp_event.sdp_result == tSDP_STATUS::SDP_SUCCESS) ||
- (sdp_event.sdp_result == tSDP_STATUS::SDP_NO_RECS_MATCH) ||
- (sdp_event.sdp_result == tSDP_STATUS::SDP_DB_FULL)) {
- log::verbose("sdp_result::0x{:x}", sdp_event.sdp_result);
- do {
- p_sdp_rec = NULL;
- if (bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1)) {
- 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 = 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 */
- if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) {
- /* all GATT based services */
-
- std::vector<Uuid> gatt_uuids;
-
- do {
- /* find a service record, report it */
- 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 (get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec(p_sdp_rec,
- &service_uuid)) {
- gatt_uuids.push_back(service_uuid);
- }
- }
- } while (p_sdp_rec);
-
- if (!gatt_uuids.empty()) {
- log::info("GATT services discovered using SDP");
-
- // send all result back to app
- BD_NAME bd_name;
- bd_name_from_char_pointer(bd_name, bta_dm_get_remname());
-
- bta_dm_search_cb.service_search_cbacks.on_gatt_results(bta_dm_search_cb.peer_bdaddr,
- bd_name, gatt_uuids,
- /* transport_le */ false);
- }
- } else {
- if (p_sdp_rec != NULL) {
- if (service != UUID_SERVCLASS_PNP_INFORMATION) {
- bta_dm_search_cb.services_found |= (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(
- bta_dm_search_cb.service_index - 1));
- uint16_t tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
- /* Add to the list of UUIDs */
- uuid_list.push_back(Uuid::From16Bit(tmp_svc));
- }
- }
- }
-
- if (bta_dm_search_cb.services_to_search == 0) {
- bta_dm_search_cb.service_index++;
- } else { /* regular one service per search or PNP search */
- break;
- }
-
- } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
-
- log::verbose("services_found = {:04x}", bta_dm_search_cb.services_found);
-
- /* Collect the 128-bit services here and put them into the list */
- p_sdp_rec = NULL;
- do {
- /* find a service record, report it */
- 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 (get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec_128bit(p_sdp_rec,
- &temp_uuid)) {
- uuid_list.push_back(temp_uuid);
- }
- }
- } while (p_sdp_rec);
-
- if (bta_dm_search_cb.services_to_search == 0) {
- bta_dm_store_audio_profiles_version();
- }
-
-#if TARGET_FLOSS
- tSDP_DI_GET_RECORD di_record;
- if (get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(
- 1, &di_record, bta_dm_search_cb.p_sdp_db) == tSDP_STATUS::SDP_SUCCESS) {
- bta_dm_search_cb.service_search_cbacks.on_did_received(
- bta_dm_search_cb.peer_bdaddr, di_record.rec.vendor_id_source, di_record.rec.vendor,
- di_record.rec.product, di_record.rec.version);
- }
-#endif
-
- /* if there are more services to search for */
- if (bta_dm_search_cb.services_to_search) {
- /* Free up the p_sdp_db before checking the next one */
- bta_dm_free_sdp_db();
- bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
- } else {
- /* callbacks */
- /* start next bd_addr if necessary */
-
- get_stack_rnr_interface().BTM_SecDeleteRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
-
- BTM_LogHistory(
- kBtmLogTag, bta_dm_search_cb.peer_bdaddr, "Discovery completed",
- base::StringPrintf("Result:%s services_found:0x%x service_index:0x%d",
- sdp_result_text(sdp_result).c_str(),
- bta_dm_search_cb.services_found, bta_dm_search_cb.service_index));
-
- auto msg = std::make_unique<tBTA_DM_MSG>(tBTA_DM_SVC_RES{});
- auto& disc_result = std::get<tBTA_DM_SVC_RES>(*msg);
-
- disc_result.result = BTA_SUCCESS;
- disc_result.uuids = std::move(uuid_list);
- // Copy the raw_data to the discovery result structure
- if (bta_dm_search_cb.p_sdp_db != NULL && bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
- bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
- log::verbose("raw_data used = 0x{:x} raw_data_ptr = 0x{}",
- bta_dm_search_cb.p_sdp_db->raw_used,
- fmt::ptr(bta_dm_search_cb.p_sdp_db->raw_data));
-
- bta_dm_search_cb.p_sdp_db->raw_data =
- NULL; // no need to free this - it is a global assigned.
- bta_dm_search_cb.p_sdp_db->raw_used = 0;
- bta_dm_search_cb.p_sdp_db->raw_size = 0;
- } else {
- log::verbose("raw data size is 0 or raw_data is null!!");
- }
- /* Done with p_sdp_db. Free it */
- bta_dm_free_sdp_db();
- disc_result.services = bta_dm_search_cb.services_found;
-
- // Piggy back the SCN over result field
- if (scn_found) {
- disc_result.result = static_cast<tBTA_STATUS>(3 + bta_dm_search_cb.peer_scn);
- disc_result.services |= BTA_USER_SERVICE_MASK;
-
- log::verbose("Piggy back the SCN over result field SCN={}", bta_dm_search_cb.peer_scn);
- }
- disc_result.bd_addr = bta_dm_search_cb.peer_bdaddr;
-
- bta_dm_search_sm_execute(BTA_DM_DISCOVERY_RESULT_EVT, std::move(msg));
- }
- } else {
- BTM_LogHistory(kBtmLogTag, bta_dm_search_cb.peer_bdaddr, "Discovery failed",
- base::StringPrintf("Result:%s", sdp_result_text(sdp_result).c_str()));
- log::error("SDP connection failed {}", sdp_status_text(sdp_result));
- if (sdp_event.sdp_result == tSDP_STATUS::SDP_CONN_FAILED) {
- bta_dm_search_cb.wait_disc = false;
- }
-
- /* not able to connect go to next device */
- if (bta_dm_search_cb.p_sdp_db) {
- osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
- }
-
- get_stack_rnr_interface().BTM_SecDeleteRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
-
- auto msg = std::make_unique<tBTA_DM_MSG>(tBTA_DM_SVC_RES{});
- auto& disc_result = std::get<tBTA_DM_SVC_RES>(*msg);
-
- disc_result.result = BTA_FAILURE;
- disc_result.services = bta_dm_search_cb.services_found;
- disc_result.bd_addr = bta_dm_search_cb.peer_bdaddr;
-
- bta_dm_search_sm_execute(BTA_DM_DISCOVERY_RESULT_EVT, std::move(msg));
- }
-}
-
-/** Callback of peer's DIS reply. This is only called for floss */
-#if TARGET_FLOSS
-static void bta_dm_read_dis_cmpl(const RawAddress& addr, tDIS_VALUE* p_dis_value) {
- if (!p_dis_value) {
- log::warn("read DIS failed");
- } else {
- bta_dm_search_cb.service_search_cbacks.on_did_received(
- addr, p_dis_value->pnp_id.vendor_id_src, p_dis_value->pnp_id.vendor_id,
- p_dis_value->pnp_id.product_id, p_dis_value->pnp_id.product_version);
- }
-
- bta_dm_execute_queued_request();
-}
-#endif
-
-/*******************************************************************************
- *
- * Function bta_dm_search_cmpl
- *
- * Description Sends event to application
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_search_cmpl() {
- bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
-
- uint16_t conn_id = bta_dm_search_cb.conn_id;
-
- std::vector<Uuid> gatt_services;
-
- bool send_gatt_results = bta_dm_search_cb.gatt_disc_active;
-
- /* no BLE connection, i.e. Classic service discovery end */
- if (conn_id == GATT_INVALID_CONN_ID) {
- if (bta_dm_search_cb.gatt_disc_active) {
- log::warn("GATT active but no BLE connection, likely disconnected midway through");
- } else {
- log::info("No BLE connection, processing classic results");
- }
- } else {
- btgatt_db_element_t* db = NULL;
- int count = 0;
- get_gatt_interface().BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, &count);
- if (count != 0) {
- for (int i = 0; i < count; i++) {
- // we process service entries only
- if (db[i].type == BTGATT_DB_PRIMARY_SERVICE) {
- gatt_services.push_back(db[i].uuid);
- }
- }
- osi_free(db);
- log::info("GATT services discovered using LE Transport, will always send to upper layer");
- send_gatt_results = true;
- } else {
- log::warn("Empty GATT database - no BLE services discovered");
- }
- }
-
- // send all result back to app
- if (send_gatt_results) {
- if (bta_dm_search_cb.service_search_cbacks.on_gatt_results != nullptr) {
- log::info("Sending GATT results to upper layer");
-
- BD_NAME bd_name;
- bd_name_from_char_pointer(bd_name, bta_dm_get_remname());
- bta_dm_search_cb.service_search_cbacks.on_gatt_results(bta_dm_search_cb.peer_bdaddr, bd_name,
- gatt_services,
- /* transport_le */ true);
- } else {
- log::warn("on_gatt_results is nullptr!");
- }
- }
-
- if (bta_dm_search_cb.p_device_search_cback) {
- bta_dm_search_cb.p_device_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
- }
- bta_dm_search_cb.gatt_disc_active = false;
-
-#if TARGET_FLOSS
- if (conn_id != GATT_INVALID_CONN_ID &&
- DIS_ReadDISInfo(bta_dm_search_cb.peer_bdaddr, bta_dm_read_dis_cmpl, DIS_ATTR_PNP_ID_BIT)) {
- return;
- }
-#endif
-
- bta_dm_execute_queued_request();
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_disc_result
- *
- * Description Service discovery result when discovering services on a
- * device
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) {
- log::verbose("");
-
- /* disc_res.device_type is set only when GATT discovery is finished in
- * bta_dm_gatt_disc_complete */
- bool is_gatt_over_ble = ((disc_result.device_type & BT_DEVICE_TYPE_BLE) != 0);
-
- /* if any BR/EDR service discovery has been done, report the event */
- if (!is_gatt_over_ble) {
- auto& r = disc_result;
- bta_dm_search_cb.service_search_cbacks.on_service_discovery_results(r.bd_addr, r.uuids,
- r.result);
- }
-
- /* Services were discovered while device search is in progress.
- * Don't execute bta_dm_search_cmpl, as it would also finish the device
- * search. It will be executed later when device search is finished. */
- if (bta_dm_search_get_state() != BTA_DM_SEARCH_ACTIVE) {
- get_gatt_interface().BTA_GATTC_CancelOpen(0, bta_dm_search_cb.peer_bdaddr, true);
-
- bta_dm_search_cmpl();
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_free_sdp_db
- *
- * Description Frees SDP data base
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_free_sdp_db() { osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db); }
-
-/*******************************************************************************
- *
- * Function bta_dm_queue_search
- *
- * Description Queues search command
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_queue_search(tBTA_DM_API_SEARCH& search) {
- if (bta_dm_search_cb.p_pending_search) {
- log::warn("Overwrote previous device discovery inquiry scan request");
- }
- bta_dm_search_cb.p_pending_search.reset(new tBTA_DM_MSG(search));
- log::info("Queued device discovery inquiry scan request");
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_queue_disc
- *
- * Description Queues discovery command
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_queue_disc(tBTA_DM_API_DISCOVER& discovery) {
- log::info("bta_dm_discovery: queuing service discovery to {}", discovery.bd_addr);
- bta_dm_search_cb.pending_discovery_queue.push(discovery);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_execute_queued_request
- *
- * Description Executes queued request if one exists
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_execute_queued_request() {
- if (!bta_dm_search_cb.pending_discovery_queue.empty()) {
- tBTA_DM_API_DISCOVER pending_discovery = bta_dm_search_cb.pending_discovery_queue.front();
- bta_dm_search_cb.pending_discovery_queue.pop();
- log::info("Start pending discovery");
- post_disc_evt(BTA_DM_API_DISCOVER_EVT,
- std::make_unique<tBTA_DM_MSG>(tBTA_DM_API_DISCOVER{pending_discovery}));
- } else if (bta_dm_search_cb.p_pending_search) {
- log::info("Start pending search");
- post_disc_evt(BTA_DM_API_SEARCH_EVT, std::move(bta_dm_search_cb.p_pending_search));
- bta_dm_search_cb.p_pending_search.reset();
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_is_search_request_queued
- *
- * Description Checks if there is a queued search request
- *
- * Returns bool
- *
- ******************************************************************************/
-bool bta_dm_is_search_request_queued() { return bta_dm_search_cb.p_pending_search != NULL; }
-
-/*******************************************************************************
- *
- * Function bta_dm_search_clear_queue
- *
- * Description Clears the queue if API search cancel is called
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_search_clear_queue() { bta_dm_search_cb.p_pending_search.reset(); }
-
-/*******************************************************************************
- *
- * Function bta_dm_search_cancel_notify
- *
- * Description Notify application that search has been cancelled
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_search_cancel_notify() {
- if (bta_dm_search_cb.p_device_search_cback) {
- bta_dm_search_cb.p_device_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
- }
- switch (bta_dm_search_get_state()) {
- case BTA_DM_SEARCH_ACTIVE:
- case BTA_DM_SEARCH_CANCELLING:
- if (!bta_dm_search_cb.name_discover_done) {
- if (get_stack_rnr_interface().BTM_CancelRemoteDeviceName() !=
- tBTM_STATUS::BTM_CMD_STARTED) {
- log::warn("Unable to cancel RNR");
- }
- }
- break;
- case BTA_DM_SEARCH_IDLE:
- case BTA_DM_DISCOVER_ACTIVE:
- // Nothing to do
- break;
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_find_services
- *
- * Description Starts discovery on a device
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_find_services(const RawAddress& bd_addr) {
- while (bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) {
- Uuid uuid = Uuid::kEmpty;
- if (bta_dm_search_cb.services_to_search &
- (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))) {
- bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_DM_SDP_DB_SIZE);
-
- /* try to search all services by search based on L2CAP UUID */
- log::info("services_to_search={:08x}", bta_dm_search_cb.services_to_search);
- if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
- uuid = Uuid::From16Bit(bta_service_id_to_uuid_lkup_tbl[0]);
- bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
- } else {
- uuid = Uuid::From16Bit(UUID_PROTOCOL_L2CAP);
- bta_dm_search_cb.services_to_search = 0;
- }
-
- log::info("search UUID = {}", uuid.ToString());
- if (!get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
- bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL)) {
- log::warn("Unable to initialize SDP service discovery db peer:{}", bd_addr);
- }
-
- 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 (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest(
- bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) {
- log::warn("Unable to start SDP service search attribute request peer:{}", bd_addr);
- /*
- * If discovery is not successful with this device, then
- * proceed with the next one.
- */
- osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
- bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
-
- } else {
- 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));
- }
- }
- bta_dm_search_cb.service_index++;
- return;
- }
- }
-
- bta_dm_search_cb.service_index++;
- }
-
- /* no more services to be discovered */
- if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
- auto msg = std::make_unique<tBTA_DM_MSG>(tBTA_DM_SVC_RES{});
- auto& disc_result = std::get<tBTA_DM_SVC_RES>(*msg);
- disc_result.services = bta_dm_search_cb.services_found;
- disc_result.bd_addr = bta_dm_search_cb.peer_bdaddr;
-
- post_disc_evt(BTA_DM_DISCOVERY_RESULT_EVT, std::move(msg));
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_discover_next_device
- *
- * Description Starts discovery on the next device in Inquiry data base
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_discover_next_device(void) {
- log::verbose("bta_dm_discover_next_device");
-
- /* searching next device on inquiry result */
- bta_dm_search_cb.p_btm_inq_info =
- get_btm_client_interface().db.BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info);
- if (bta_dm_search_cb.p_btm_inq_info != NULL) {
- bta_dm_search_cb.name_discover_done = false;
- bta_dm_search_cb.peer_name[0] = 0;
- bta_dm_discover_name(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
- } else {
- post_disc_evt(BTA_DM_SEARCH_CMPL_EVT, nullptr);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_determine_discovery_transport
- *
- * Description Starts name and service discovery on the device
- *
- * Returns void
- *
- ******************************************************************************/
-static tBT_TRANSPORT bta_dm_determine_discovery_transport(const RawAddress& remote_bd_addr) {
- tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
- if (bta_dm_search_cb.transport == BT_TRANSPORT_AUTO) {
- tBT_DEVICE_TYPE dev_type;
- tBLE_ADDR_TYPE addr_type;
-
- get_btm_client_interface().peer.BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
- if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) {
- transport = BT_TRANSPORT_LE;
- } else if (dev_type == BT_DEVICE_TYPE_DUMO) {
- if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(remote_bd_addr,
- BT_TRANSPORT_BR_EDR)) {
- transport = BT_TRANSPORT_BR_EDR;
- } else if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(remote_bd_addr,
- BT_TRANSPORT_LE)) {
- transport = BT_TRANSPORT_LE;
- }
- }
- } else {
- transport = bta_dm_search_cb.transport;
- }
- return transport;
-}
-
-static void bta_dm_discover_name(const RawAddress& remote_bd_addr) {
- const tBT_TRANSPORT transport = bta_dm_determine_discovery_transport(remote_bd_addr);
-
- log::verbose("BDA: {}", remote_bd_addr);
-
- bta_dm_search_cb.peer_bdaddr = remote_bd_addr;
-
- log::verbose("name_discover_done = {} p_btm_inq_info 0x{} state = {}, transport={}",
- bta_dm_search_cb.name_discover_done, fmt::ptr(bta_dm_search_cb.p_btm_inq_info),
- bta_dm_search_get_state(), transport);
-
- if (bta_dm_search_cb.p_btm_inq_info) {
- log::verbose("appl_knows_rem_name {}", bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
- }
- if (((bta_dm_search_cb.p_btm_inq_info) &&
- (bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE) &&
- (bta_dm_search_get_state() == BTA_DM_SEARCH_ACTIVE)) ||
- (transport == BT_TRANSPORT_LE &&
- interop_match_addr(INTEROP_DISABLE_NAME_REQUEST, &bta_dm_search_cb.peer_bdaddr))) {
- /* Do not perform RNR for LE devices at inquiry complete*/
- bta_dm_search_cb.name_discover_done = true;
- }
- // If we already have the name we can skip getting the name
- if (get_stack_rnr_interface().BTM_IsRemoteNameKnown(remote_bd_addr, transport)) {
- log::debug("Security record already known skipping read remote name peer:{}", remote_bd_addr);
- bta_dm_search_cb.name_discover_done = true;
- }
-
- /* if name discovery is not done and application needs remote name */
- if ((!bta_dm_search_cb.name_discover_done) &&
- ((bta_dm_search_cb.p_btm_inq_info == NULL) ||
- (bta_dm_search_cb.p_btm_inq_info &&
- (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) {
- if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport)) {
- if (bta_dm_search_get_state() != BTA_DM_DISCOVER_ACTIVE) {
- log::debug("Reset transport state for next discovery");
- bta_dm_search_cb.transport = BT_TRANSPORT_AUTO;
- }
- BTM_LogHistory(kBtmLogTag, bta_dm_search_cb.peer_bdaddr, "Read remote name",
- base::StringPrintf("Transport:%s", bt_transport_text(transport).c_str()));
- return;
- } else {
- log::error("Unable to start read remote device name");
- }
-
- /* starting name discovery failed */
- bta_dm_search_cb.name_discover_done = true;
- }
-
- /* Reset transport state for next discovery */
- bta_dm_search_cb.transport = BT_TRANSPORT_AUTO;
-
- /* name discovery is done for this device */
- if (bta_dm_search_get_state() == BTA_DM_SEARCH_ACTIVE) {
- // if p_btm_inq_info is nullptr, there is no more inquiry results to
- // discover name for
- if (bta_dm_search_cb.p_btm_inq_info) {
- bta_dm_discover_next_device();
- } else {
- log::info("end of parsing inquiry result");
- }
- } else {
- log::info("name discovery finished in bad state: {}",
- bta_dm_state_text(bta_dm_search_get_state()));
- }
-}
-
-static void bta_dm_discover_services(const RawAddress& remote_bd_addr) {
- const tBT_TRANSPORT transport = bta_dm_determine_discovery_transport(remote_bd_addr);
-
- log::verbose("BDA: {}, transport={}, state = {}", remote_bd_addr, transport,
- bta_dm_search_get_state());
-
- bta_dm_search_cb.peer_bdaddr = remote_bd_addr;
-
- /* Reset transport state for next discovery */
- bta_dm_search_cb.transport = BT_TRANSPORT_AUTO;
-
- bool sdp_disable = HID_HostSDPDisable(remote_bd_addr);
- if (sdp_disable) {
- log::debug("peer:{} with HIDSDPDisable attribute.", remote_bd_addr);
- }
-
- /* if application wants to discover service and HIDSDPDisable attribute is
- false.
- Classic mouses with this attribute should not start SDP here, because the
- SDP has been done during bonding. SDP request here will interleave with
- connections to the Control or Interrupt channels */
- if (!sdp_disable) {
- BTM_LogHistory(kBtmLogTag, remote_bd_addr, "Discovery started ",
- base::StringPrintf("Transport:%s", bt_transport_text(transport).c_str()));
-
- /* initialize variables */
- bta_dm_search_cb.service_index = 0;
- bta_dm_search_cb.services_found = 0;
- bta_dm_search_cb.services_to_search = BTA_ALL_SERVICE_MASK;
-
- /* if seaching with EIR is not completed */
- if (bta_dm_search_cb.services_to_search) {
- /* check whether connection already exists to the device
- if connection exists, we don't have to wait for ACL
- link to go down to start search on next device */
- if (transport == BT_TRANSPORT_BR_EDR) {
- if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr,
- BT_TRANSPORT_BR_EDR)) {
- bta_dm_search_cb.wait_disc = false;
- } else {
- bta_dm_search_cb.wait_disc = true;
- }
- }
-
- if (transport == BT_TRANSPORT_LE) {
- if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) {
- log::info("bta_dm_discovery: starting GATT discovery on {}",
- bta_dm_search_cb.peer_bdaddr);
- // set the raw data buffer here
- memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
- /* start GATT for service discovery */
- btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
- return;
- }
- } else {
- log::info("bta_dm_discovery: starting SDP discovery on {}", bta_dm_search_cb.peer_bdaddr);
- bta_dm_search_cb.sdp_results = false;
- bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
- return;
- }
- }
- }
-
- /* service discovery is done for this device */
- auto msg = std::make_unique<tBTA_DM_MSG>(tBTA_DM_SVC_RES{});
- auto& svc_result = std::get<tBTA_DM_SVC_RES>(*msg);
-
- /* initialize the data structure */
- svc_result.result = BTA_SUCCESS;
- svc_result.services = bta_dm_search_cb.services_found;
- svc_result.bd_addr = bta_dm_search_cb.peer_bdaddr;
-
- bta_dm_search_sm_execute(BTA_DM_DISCOVERY_RESULT_EVT, std::move(msg));
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_sdp_callback
- *
- * Description Callback from sdp with discovery status
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_sdp_callback(const RawAddress& /* bd_addr */, tSDP_STATUS sdp_status) {
- post_disc_evt(BTA_DM_SDP_RESULT_EVT,
- std::make_unique<tBTA_DM_MSG>(tBTA_DM_SDP_RESULT{.sdp_result = sdp_status}));
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_inq_results_cb
- *
- * Description Inquiry results callback from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir, uint16_t eir_len) {
- tBTA_DM_SEARCH result;
- tBTM_INQ_INFO* p_inq_info;
- uint16_t service_class;
-
- result.inq_res.bd_addr = p_inq->remote_bd_addr;
-
- // Pass the original address to GattService#onScanResult
- result.inq_res.original_bda = p_inq->original_bda;
-
- result.inq_res.dev_class = p_inq->dev_class;
- BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
- result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false;
- result.inq_res.rssi = p_inq->rssi;
-
- result.inq_res.ble_addr_type = p_inq->ble_addr_type;
- result.inq_res.inq_result_type = p_inq->inq_result_type;
- result.inq_res.device_type = p_inq->device_type;
- result.inq_res.flag = p_inq->flag;
- result.inq_res.include_rsi = p_inq->include_rsi;
- result.inq_res.clock_offset = p_inq->clock_offset;
-
- /* application will parse EIR to find out remote device name */
- result.inq_res.p_eir = const_cast<uint8_t*>(p_eir);
- result.inq_res.eir_len = eir_len;
-
- result.inq_res.ble_evt_type = p_inq->ble_evt_type;
-
- p_inq_info = get_btm_client_interface().db.BTM_InqDbRead(p_inq->remote_bd_addr);
- if (p_inq_info != NULL) {
- /* initialize remt_name_not_required to false so that we get the name by
- * default */
- result.inq_res.remt_name_not_required = false;
- }
-
- if (bta_dm_search_cb.p_device_search_cback) {
- bta_dm_search_cb.p_device_search_cback(BTA_DM_INQ_RES_EVT, &result);
- }
-
- if (p_inq_info) {
- /* application indicates if it knows the remote name, inside the callback
- copy that to the inquiry data base*/
- if (result.inq_res.remt_name_not_required) {
- p_inq_info->appl_knows_rem_name = true;
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_inq_cmpl_cb
- *
- * Description Inquiry complete callback from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_inq_cmpl_cb(void* /* p_result */) {
- log::verbose("");
-
- bta_dm_inq_cmpl();
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_service_search_remname_cback
- *
- * Description Remote name call back from BTM during service discovery
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, DEV_CLASS /* dc */,
- BD_NAME bd_name) {
- tBTM_REMOTE_DEV_NAME rem_name = {};
- tBTM_STATUS btm_status;
-
- log::verbose("name=<{}>", reinterpret_cast<char const*>(bd_name));
-
- /* if this is what we are looking for */
- if (bta_dm_search_cb.peer_bdaddr == bd_addr) {
- rem_name.bd_addr = bd_addr;
- bd_name_copy(rem_name.remote_bd_name, bd_name);
- rem_name.btm_status = tBTM_STATUS::BTM_SUCCESS;
- rem_name.hci_status = HCI_SUCCESS;
- bta_dm_remname_cback(&rem_name);
- } else {
- /* get name of device */
- btm_status = get_stack_rnr_interface().BTM_ReadRemoteDeviceName(
- bta_dm_search_cb.peer_bdaddr, bta_dm_remname_cback, BT_TRANSPORT_BR_EDR);
- if (btm_status == tBTM_STATUS::BTM_BUSY) {
- /* wait for next chance(notification of remote name discovery done) */
- log::verbose("BTM_ReadRemoteDeviceName is busy");
- } else if (btm_status != tBTM_STATUS::BTM_CMD_STARTED) {
- /* if failed to start getting remote name then continue */
- log::warn("BTM_ReadRemoteDeviceName returns 0x{:02X}", btm_status);
-
- // needed so our response is not ignored, since this corresponds to the
- // actual peer_bdaddr
- rem_name.bd_addr = bta_dm_search_cb.peer_bdaddr;
- rem_name.remote_bd_name[0] = 0;
- rem_name.btm_status = btm_status;
- rem_name.hci_status = HCI_SUCCESS;
- bta_dm_remname_cback(&rem_name);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_remname_cback
- *
- * Description Remote name complete call back from BTM
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p_remote_name) {
- log::assert_that(p_remote_name != nullptr, "assert failed: p_remote_name != nullptr");
-
- log::info(
- "Remote name request complete peer:{} btm_status:{} hci_status:{} name[0]:{:c} length:{}",
- p_remote_name->bd_addr, btm_status_text(p_remote_name->btm_status),
- hci_error_code_text(p_remote_name->hci_status), p_remote_name->remote_bd_name[0],
- strnlen((const char*)p_remote_name->remote_bd_name, BD_NAME_LEN));
-
- if (bta_dm_search_cb.peer_bdaddr == p_remote_name->bd_addr) {
- get_stack_rnr_interface().BTM_SecDeleteRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
- } else {
- // if we got a different response, maybe ignore it
- // we will have made a request directly from BTM_ReadRemoteDeviceName so we
- // expect a dedicated response for us
- if (p_remote_name->hci_status == HCI_ERR_CONNECTION_EXISTS) {
- get_stack_rnr_interface().BTM_SecDeleteRmtNameNotifyCallback(
- &bta_dm_service_search_remname_cback);
- log::info("Assume command failed due to disconnection hci_status:{} peer:{}",
- hci_error_code_text(p_remote_name->hci_status), p_remote_name->bd_addr);
- } else {
- log::info("Ignored remote name response for the wrong address exp:{} act:{}",
- bta_dm_search_cb.peer_bdaddr, p_remote_name->bd_addr);
- return;
- }
- }
-
- /* remote name discovery is done but it could be failed */
- bta_dm_search_cb.name_discover_done = true;
- bd_name_copy(bta_dm_search_cb.peer_name, p_remote_name->remote_bd_name);
-
- if (bta_dm_search_cb.transport == BT_TRANSPORT_LE) {
- GAP_BleReadPeerPrefConnParams(bta_dm_search_cb.peer_bdaddr);
- }
-
- auto msg = std::make_unique<tBTA_DM_MSG>(tBTA_DM_REMOTE_NAME{});
- auto& rmt_name_msg = std::get<tBTA_DM_REMOTE_NAME>(*msg);
- rmt_name_msg.bd_addr = bta_dm_search_cb.peer_bdaddr;
- rmt_name_msg.hci_status = p_remote_name->hci_status;
- bd_name_copy(rmt_name_msg.bd_name, p_remote_name->remote_bd_name);
-
- post_disc_evt(BTA_DM_REMT_NAME_EVT, std::move(msg));
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_get_remname
- *
- * Description Returns a pointer to the remote name stored in the DM
- * control block if it exists, or from the BTM memory.
- *
- * Returns char * - Pointer to the remote device name
- ******************************************************************************/
-const char* bta_dm_get_remname(void) {
- const char* p_name = (const char*)bta_dm_search_cb.peer_name;
-
- /* If the name isn't already stored, try retrieving from BTM */
- if (*p_name == '\0') {
- const char* p_temp =
- get_btm_client_interface().security.BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr);
- if (p_temp != NULL) {
- p_name = (const char*)p_temp;
- }
- }
-
- return p_name;
-}
-
-#ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
-#define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
-#endif
-
-/*******************************************************************************
- *
- * Function bta_dm_gattc_register
- *
- * Description Register with GATTC in DM if BLE is needed.
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_gattc_register(void) {
- if (bta_dm_search_cb.client_if != BTA_GATTS_INVALID_IF) {
- // Already registered
- return;
- }
- get_gatt_interface().BTA_GATTC_AppRegister(
- bta_dm_gattc_callback, base::Bind([](uint8_t client_id, uint8_t status) {
- tGATT_STATUS gatt_status = static_cast<tGATT_STATUS>(status);
- disc_gatt_history_.Push(base::StringPrintf("%-32s client_id:%hu status:%s",
- "GATTC_RegisteredCallback", client_id,
- gatt_status_text(gatt_status).c_str()));
- if (static_cast<tGATT_STATUS>(status) == GATT_SUCCESS) {
- log::info("Registered device discovery search gatt client tGATT_IF:{}", client_id);
- bta_dm_search_cb.client_if = client_id;
- } else {
- log::warn(
- "Failed to register device discovery search gatt client "
- "gatt_status:{} previous tGATT_IF:{}",
- bta_dm_search_cb.client_if, status);
- bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
- }
- }),
- false);
-}
-
-static void gatt_close_timer_cb(void*) {
- bta_dm_search_sm_execute(BTA_DM_DISC_CLOSE_TOUT_EVT, nullptr);
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_gatt_disc_complete
- *
- * Description This function process the GATT service search complete.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) {
- log::verbose("conn_id = {}", conn_id);
-
- auto msg = std::make_unique<tBTA_DM_MSG>(tBTA_DM_SVC_RES{});
- auto& svc_result = std::get<tBTA_DM_SVC_RES>(*msg);
-
- /* no more services to be discovered */
- svc_result.result = (status == GATT_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
- log::verbose("service found: 0x{:08x}", bta_dm_search_cb.services_found);
- svc_result.services = bta_dm_search_cb.services_found;
- svc_result.bd_addr = bta_dm_search_cb.peer_bdaddr;
- svc_result.device_type |= BT_DEVICE_TYPE_BLE;
-
- bta_dm_search_sm_execute(BTA_DM_DISCOVERY_RESULT_EVT, std::move(msg));
-
- if (conn_id != GATT_INVALID_CONN_ID) {
- bta_dm_search_cb.pending_close_bda = bta_dm_search_cb.peer_bdaddr;
- // Gatt will be close immediately if bluetooth.gatt.delay_close.enabled is
- // set to false. If property is true / unset there will be a delay
- if (bta_dm_search_cb.gatt_close_timer != nullptr) {
- /* start a GATT channel close delay timer */
- alarm_set_on_mloop(bta_dm_search_cb.gatt_close_timer, BTA_DM_GATT_CLOSE_DELAY_TOUT,
- gatt_close_timer_cb, 0);
- } else {
- bta_dm_search_sm_execute(BTA_DM_DISC_CLOSE_TOUT_EVT, nullptr);
- }
- } else {
- log::info("Discovery complete for invalid conn ID. Will pick up next job");
- if (com::android::bluetooth::flags::cancel_open_discovery_client()) {
- bta_dm_close_gatt_conn();
- } else {
- bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
- }
- bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
- bta_dm_free_sdp_db();
- bta_dm_execute_queued_request();
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_close_gatt_conn
- *
- * Description This function close the GATT connection after delay
- *timeout.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_close_gatt_conn() {
- if (bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID) {
- BTA_GATTC_Close(bta_dm_search_cb.conn_id);
- }
-
- bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty;
- bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
-}
-/*******************************************************************************
- *
- * Function btm_dm_start_gatt_discovery
- *
- * Description This is GATT initiate the service search by open a GATT
- * connection first.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) {
- constexpr bool kUseOpportunistic = true;
-
- bta_dm_search_cb.gatt_disc_active = true;
-
- /* connection is already open */
- if (bta_dm_search_cb.pending_close_bda == bd_addr &&
- bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID) {
- bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty;
- alarm_cancel(bta_dm_search_cb.gatt_close_timer);
- get_gatt_interface().BTA_GATTC_ServiceSearchRequest(bta_dm_search_cb.conn_id, nullptr);
- } else {
- if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) {
- log::debug(
- "Use existing gatt client connection for discovery peer:{} "
- "transport:{} opportunistic:{:c}",
- bd_addr, bt_transport_text(BT_TRANSPORT_LE), (kUseOpportunistic) ? 'T' : 'F');
- get_gatt_interface().BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr,
- BTM_BLE_DIRECT_CONNECTION, kUseOpportunistic);
- } else {
- log::debug(
- "Opening new gatt client connection for discovery peer:{} "
- "transport:{} opportunistic:{:c}",
- bd_addr, bt_transport_text(BT_TRANSPORT_LE), (!kUseOpportunistic) ? 'T' : 'F');
- get_gatt_interface().BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr,
- BTM_BLE_DIRECT_CONNECTION, !kUseOpportunistic);
- }
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_proc_open_evt
- *
- * Description process BTA_GATTC_OPEN_EVT in DM.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
- log::verbose("DM Search state= {} search_cb.peer_dbaddr:{} connected_bda={}",
- bta_dm_search_get_state(), bta_dm_search_cb.peer_bdaddr, p_data->remote_bda);
-
- log::debug("BTA_GATTC_OPEN_EVT conn_id = {} client_if={} status = {}", p_data->conn_id,
- p_data->client_if, p_data->status);
-
- disc_gatt_history_.Push(base::StringPrintf(
- "%-32s bd_addr:%s conn_id:%hu client_if:%hu event:%s", "GATTC_EventCallback",
- ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda), p_data->conn_id, p_data->client_if,
- gatt_client_event_text(BTA_GATTC_OPEN_EVT).c_str()));
-
- bta_dm_search_cb.conn_id = p_data->conn_id;
-
- if (p_data->status == GATT_SUCCESS) {
- get_gatt_interface().BTA_GATTC_ServiceSearchRequest(p_data->conn_id, nullptr);
- } else {
- bta_dm_gatt_disc_complete(GATT_INVALID_CONN_ID, p_data->status);
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_dm_gattc_callback
- *
- * Description This is GATT client callback function used in DM.
- *
- * Parameters:
- *
- ******************************************************************************/
-static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
- log::verbose("bta_dm_gattc_callback event = {}", event);
-
- switch (event) {
- case BTA_GATTC_OPEN_EVT:
- bta_dm_proc_open_evt(&p_data->open);
- break;
-
- case BTA_GATTC_SEARCH_CMPL_EVT:
- switch (bta_dm_search_get_state()) {
- case BTA_DM_SEARCH_IDLE:
- break;
- case BTA_DM_SEARCH_ACTIVE:
- case BTA_DM_SEARCH_CANCELLING:
- case BTA_DM_DISCOVER_ACTIVE:
- bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
- break;
- }
- disc_gatt_history_.Push(base::StringPrintf(
- "%-32s conn_id:%hu status:%s", "GATTC_EventCallback", p_data->search_cmpl.conn_id,
- gatt_status_text(p_data->search_cmpl.status).c_str()));
- break;
-
- case BTA_GATTC_CLOSE_EVT:
- log::info("BTA_GATTC_CLOSE_EVT reason = {}", p_data->close.reason);
-
- if (p_data->close.remote_bda == bta_dm_search_cb.peer_bdaddr) {
- bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
- }
-
- switch (bta_dm_search_get_state()) {
- case BTA_DM_SEARCH_IDLE:
- case BTA_DM_SEARCH_ACTIVE:
- break;
-
- case BTA_DM_SEARCH_CANCELLING:
- case BTA_DM_DISCOVER_ACTIVE:
- /* in case of disconnect before search is completed */
- if (p_data->close.remote_bda == bta_dm_search_cb.peer_bdaddr) {
- bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID, (tGATT_STATUS)GATT_ERROR);
- }
- }
- break;
-
- case BTA_GATTC_CANCEL_OPEN_EVT:
- case BTA_GATTC_CFG_MTU_EVT:
- case BTA_GATTC_CONGEST_EVT:
- case BTA_GATTC_CONN_UPDATE_EVT:
- case BTA_GATTC_DEREG_EVT:
- case BTA_GATTC_ENC_CMPL_CB_EVT:
- case BTA_GATTC_EXEC_EVT:
- case BTA_GATTC_NOTIF_EVT:
- case BTA_GATTC_PHY_UPDATE_EVT:
- case BTA_GATTC_SEARCH_RES_EVT:
- case BTA_GATTC_SRVC_CHG_EVT:
- case BTA_GATTC_SRVC_DISC_DONE_EVT:
- case BTA_GATTC_SUBRATE_CHG_EVT:
- disc_gatt_history_.Push(base::StringPrintf("%-32s event:%s", "GATTC_EventCallback",
- gatt_client_event_text(event).c_str()));
- break;
- }
-}
-
-namespace bluetooth {
-namespace legacy {
-namespace testing {
-
-void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p) {
- ::bta_dm_disc_legacy::bta_dm_remname_cback(p);
-}
-
-tBT_TRANSPORT bta_dm_determine_discovery_transport(const RawAddress& bd_addr) {
- return ::bta_dm_disc_legacy::bta_dm_determine_discovery_transport(bd_addr);
-}
-
-void bta_dm_remote_name_cmpl(const tBTA_DM_REMOTE_NAME& remote_name_msg) {
- ::bta_dm_disc_legacy::bta_dm_remote_name_cmpl(remote_name_msg);
-}
-
-void bta_dm_sdp_result(tBTA_DM_SDP_RESULT& sdp_event) {
- ::bta_dm_disc_legacy::bta_dm_sdp_result(sdp_event);
-}
-
-} // namespace testing
-} // namespace legacy
-} // namespace bluetooth
-
-namespace {
-constexpr size_t kSearchStateHistorySize = 50;
-constexpr char kTimeFormatString[] = "%Y-%m-%d %H:%M:%S";
-
-constexpr unsigned MillisPerSecond = 1000;
-std::string EpochMillisToString(long long time_ms) {
- time_t time_sec = time_ms / MillisPerSecond;
- struct tm tm;
- localtime_r(&time_sec, &tm);
- std::string s = ::bluetooth::common::StringFormatTime(kTimeFormatString, tm);
- return base::StringPrintf("%s.%03u", s.c_str(),
- static_cast<unsigned int>(time_ms % MillisPerSecond));
-}
-
-} // namespace
-
-struct tSEARCH_STATE_HISTORY {
- const tBTA_DM_STATE state;
- const tBTA_DM_EVT event;
- std::string ToString() const {
- return base::StringPrintf("state:%25s event:%s", bta_dm_state_text(state).c_str(),
- bta_dm_event_text(event).c_str());
- }
-};
-
-::bluetooth::common::TimestampedCircularBuffer<tSEARCH_STATE_HISTORY> search_state_history_(
- kSearchStateHistorySize);
-
-/*******************************************************************************
- *
- * Function bta_dm_search_sm_execute
- *
- * Description State machine event handling function for DM
- *
- *
- * Returns void
- *
- ******************************************************************************/
-static void bta_dm_search_sm_execute(tBTA_DM_EVT event, std::unique_ptr<tBTA_DM_MSG> msg) {
- log::info("state:{}, event:{}[0x{:x}]", bta_dm_state_text(bta_dm_search_get_state()),
- bta_dm_event_text(event), event);
- search_state_history_.Push({
- .state = bta_dm_search_get_state(),
- .event = event,
- });
-
- switch (bta_dm_search_get_state()) {
- case BTA_DM_SEARCH_IDLE:
- switch (event) {
- case BTA_DM_API_SEARCH_EVT:
- bta_dm_search_set_state(BTA_DM_SEARCH_ACTIVE);
- log::assert_that(std::holds_alternative<tBTA_DM_API_SEARCH>(*msg), "bad message type: {}",
- msg->index());
-
- bta_dm_search_start(std::get<tBTA_DM_API_SEARCH>(*msg));
- break;
- case BTA_DM_API_DISCOVER_EVT:
- bta_dm_search_set_state(BTA_DM_DISCOVER_ACTIVE);
- log::assert_that(std::holds_alternative<tBTA_DM_API_DISCOVER>(*msg),
- "bad message type: {}", msg->index());
-
- bta_dm_discover(std::get<tBTA_DM_API_DISCOVER>(*msg));
- break;
- case BTA_DM_API_SEARCH_CANCEL_EVT:
- bta_dm_search_clear_queue();
- bta_dm_search_cancel_notify();
- break;
- case BTA_DM_SDP_RESULT_EVT:
- bta_dm_free_sdp_db();
- break;
- case BTA_DM_DISC_CLOSE_TOUT_EVT:
- bta_dm_close_gatt_conn();
- break;
- default:
- log::info("Received unexpected event {}[0x{:x}] in state {}", bta_dm_event_text(event),
- event, bta_dm_state_text(bta_dm_search_get_state()));
- }
- break;
- case BTA_DM_SEARCH_ACTIVE:
- switch (event) {
- case BTA_DM_REMT_NAME_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_REMOTE_NAME>(*msg),
- "bad message type: {}", msg->index());
-
- bta_dm_remote_name_cmpl(std::get<tBTA_DM_REMOTE_NAME>(*msg));
- break;
- case BTA_DM_SEARCH_CMPL_EVT:
- bta_dm_search_cmpl();
- break;
- case BTA_DM_DISCOVERY_RESULT_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_SVC_RES>(*msg), "bad message type: {}",
- msg->index());
-
- bta_dm_disc_result(std::get<tBTA_DM_SVC_RES>(*msg));
- break;
- case BTA_DM_DISC_CLOSE_TOUT_EVT:
- bta_dm_close_gatt_conn();
- break;
- case BTA_DM_API_DISCOVER_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_API_DISCOVER>(*msg),
- "bad message type: {}", msg->index());
-
- bta_dm_queue_disc(std::get<tBTA_DM_API_DISCOVER>(*msg));
- break;
- case BTA_DM_API_SEARCH_CANCEL_EVT:
- bta_dm_search_clear_queue();
- bta_dm_search_set_state(BTA_DM_SEARCH_CANCELLING);
- bta_dm_search_cancel();
- break;
- default:
- log::info("Received unexpected event {}[0x{:x}] in state {}", bta_dm_event_text(event),
- event, bta_dm_state_text(bta_dm_search_get_state()));
- }
- break;
- case BTA_DM_SEARCH_CANCELLING:
- switch (event) {
- case BTA_DM_API_SEARCH_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_API_SEARCH>(*msg), "bad message type: {}",
- msg->index());
-
- bta_dm_queue_search(std::get<tBTA_DM_API_SEARCH>(*msg));
- break;
- case BTA_DM_API_DISCOVER_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_API_DISCOVER>(*msg),
- "bad message type: {}", msg->index());
-
- bta_dm_queue_disc(std::get<tBTA_DM_API_DISCOVER>(*msg));
- break;
- case BTA_DM_API_SEARCH_CANCEL_EVT:
- bta_dm_search_clear_queue();
- bta_dm_search_cancel_notify();
- break;
- case BTA_DM_SDP_RESULT_EVT:
- case BTA_DM_REMT_NAME_EVT:
- case BTA_DM_SEARCH_CMPL_EVT:
- case BTA_DM_DISCOVERY_RESULT_EVT:
- bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
- bta_dm_free_sdp_db();
- bta_dm_search_cancel_notify();
- bta_dm_execute_queued_request();
- break;
- case BTA_DM_DISC_CLOSE_TOUT_EVT:
- bta_dm_close_gatt_conn();
- break;
- default:
- log::info("Received unexpected event {}[0x{:x}] in state {}", bta_dm_event_text(event),
- event, bta_dm_state_text(bta_dm_search_get_state()));
- }
- break;
- case BTA_DM_DISCOVER_ACTIVE:
- switch (event) {
- case BTA_DM_REMT_NAME_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_REMOTE_NAME>(*msg),
- "bad message type: {}", msg->index());
-
- bta_dm_remote_name_cmpl(std::get<tBTA_DM_REMOTE_NAME>(*msg));
- break;
- case BTA_DM_SDP_RESULT_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_SDP_RESULT>(*msg), "bad message type: {}",
- msg->index());
-
- bta_dm_sdp_result(std::get<tBTA_DM_SDP_RESULT>(*msg));
- break;
- case BTA_DM_SEARCH_CMPL_EVT:
- bta_dm_search_cmpl();
- break;
- case BTA_DM_DISCOVERY_RESULT_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_SVC_RES>(*msg), "bad message type: {}",
- msg->index());
-
- bta_dm_disc_result(std::get<tBTA_DM_SVC_RES>(*msg));
- break;
- case BTA_DM_API_SEARCH_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_API_SEARCH>(*msg), "bad message type: {}",
- msg->index());
-
- bta_dm_queue_search(std::get<tBTA_DM_API_SEARCH>(*msg));
- break;
- case BTA_DM_API_DISCOVER_EVT:
- log::assert_that(std::holds_alternative<tBTA_DM_API_DISCOVER>(*msg),
- "bad message type: {}", msg->index());
-
- bta_dm_queue_disc(std::get<tBTA_DM_API_DISCOVER>(*msg));
- break;
- case BTA_DM_API_SEARCH_CANCEL_EVT:
- bta_dm_search_clear_queue();
- bta_dm_search_set_state(BTA_DM_SEARCH_CANCELLING);
- bta_dm_search_cancel_notify();
- break;
- case BTA_DM_DISC_CLOSE_TOUT_EVT:
- bta_dm_close_gatt_conn();
- break;
- default:
- log::info("Received unexpected event {}[0x{:x}] in state {}", bta_dm_event_text(event),
- event, bta_dm_state_text(bta_dm_search_get_state()));
- }
- break;
- }
-}
-
-static void bta_dm_disc_init_search_cb(tBTA_DM_SEARCH_CB& bta_dm_search_cb) {
- bta_dm_search_cb = {};
- bta_dm_search_cb.state = BTA_DM_SEARCH_IDLE;
- bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
- bta_dm_search_cb.transport = BT_TRANSPORT_AUTO;
-}
-
-static void bta_dm_disc_reset() {
- alarm_free(bta_dm_search_cb.search_timer);
- alarm_free(bta_dm_search_cb.gatt_close_timer);
- bta_dm_search_cb.p_pending_search.reset();
- bta_dm_search_cb.pending_discovery_queue = {};
- bta_dm_disc_init_search_cb(bta_dm_search_cb);
-}
-
-void bta_dm_disc_start(bool delay_close_gatt) {
- bta_dm_disc_reset();
- bta_dm_search_cb.search_timer = alarm_new("bta_dm_search.search_timer");
- bta_dm_search_cb.gatt_close_timer =
- delay_close_gatt ? alarm_new("bta_dm_search.gatt_close_timer") : nullptr;
- bta_dm_search_cb.pending_discovery_queue = {};
-}
-
-void bta_dm_disc_acl_down(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
- switch (transport) {
- case BT_TRANSPORT_BR_EDR:
- if (bta_dm_search_cb.wait_disc && bta_dm_search_cb.peer_bdaddr == bd_addr) {
- bta_dm_search_cb.wait_disc = false;
-
- if (bta_dm_search_cb.sdp_results) {
- log::verbose("timer stopped");
- alarm_cancel(bta_dm_search_cb.search_timer);
- bta_dm_disc_discover_next_device();
- }
- }
- break;
-
- case BT_TRANSPORT_LE:
- default:
- break;
- }
-}
-
-void bta_dm_disc_stop() { bta_dm_disc_reset(); }
-
-void bta_dm_disc_start_device_discovery(tBTA_DM_SEARCH_CBACK* p_cback) {
- bta_dm_search_sm_execute(BTA_DM_API_SEARCH_EVT,
- std::make_unique<tBTA_DM_MSG>(tBTA_DM_API_SEARCH{.p_cback = p_cback}));
-}
-
-void bta_dm_disc_stop_device_discovery() {
- bta_dm_search_sm_execute(BTA_DM_API_SEARCH_CANCEL_EVT, nullptr);
-}
-
-void bta_dm_disc_start_service_discovery(service_discovery_callbacks cbacks,
- const RawAddress& bd_addr, tBT_TRANSPORT transport) {
- bta_dm_search_sm_execute(BTA_DM_API_DISCOVER_EVT,
- std::make_unique<tBTA_DM_MSG>(tBTA_DM_API_DISCOVER{
- .bd_addr = bd_addr, .cbacks = cbacks, .transport = transport}));
-}
-
-#define DUMPSYS_TAG "shim::legacy::bta::dm"
-void DumpsysBtaDmDisc(int fd) {
- auto copy = search_state_history_.Pull();
- LOG_DUMPSYS(fd, " last %zu search state transitions", copy.size());
- for (const auto& it : copy) {
- LOG_DUMPSYS(fd, " %s %s", EpochMillisToString(it.timestamp).c_str(),
- it.entry.ToString().c_str());
- }
- LOG_DUMPSYS(fd, " current bta_dm_search_state:%s",
- bta_dm_state_text(bta_dm_search_get_state()).c_str());
-}
-#undef DUMPSYS_TAG
-
-namespace bluetooth {
-namespace legacy {
-namespace testing {
-
-void bta_dm_disc_init_search_cb(tBTA_DM_SEARCH_CB& bta_dm_search_cb) {
- ::bta_dm_disc_legacy::bta_dm_disc_init_search_cb(bta_dm_search_cb);
-}
-tBTA_DM_SEARCH_CB bta_dm_disc_get_search_cb() {
- tBTA_DM_SEARCH_CB search_cb = {};
- ::bta_dm_disc_legacy::bta_dm_disc_init_search_cb(search_cb);
- return search_cb;
-}
-tBTA_DM_SEARCH_CB& bta_dm_disc_search_cb() { return ::bta_dm_disc_legacy::bta_dm_search_cb; }
-bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
- return ::bta_dm_disc_legacy::bta_dm_read_remote_device_name(bd_addr, transport);
-}
-void bta_dm_discover_next_device() { ::bta_dm_disc_legacy::bta_dm_discover_next_device(); }
-
-void bta_dm_execute_queued_request() { ::bta_dm_disc_legacy::bta_dm_execute_queued_request(); }
-void bta_dm_find_services(const RawAddress& bd_addr) {
- ::bta_dm_disc_legacy::bta_dm_find_services(bd_addr);
-}
-void bta_dm_inq_cmpl() { ::bta_dm_disc_legacy::bta_dm_inq_cmpl(); }
-void bta_dm_inq_cmpl_cb(void* p_result) { ::bta_dm_disc_legacy::bta_dm_inq_cmpl_cb(p_result); }
-
-void bta_dm_queue_search(tBTA_DM_API_SEARCH& search) {
- ::bta_dm_disc_legacy::bta_dm_queue_search(search);
-}
-
-void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, DEV_CLASS dc, BD_NAME bd_name) {
- ::bta_dm_disc_legacy::bta_dm_service_search_remname_cback(bd_addr, dc, bd_name);
-}
-
-void store_avrcp_profile_feature(tSDP_DISC_REC* sdp_rec) {
- ::bta_dm_disc_legacy::store_avrcp_profile_feature(sdp_rec);
-}
-
-} // namespace testing
-} // namespace legacy
-} // namespace bluetooth
-
-} // namespace bta_dm_disc_legacy
diff --git a/system/bta/dm/bta_dm_disc_legacy.h b/system/bta/dm/bta_dm_disc_legacy.h
deleted file mode 100644
index 724c7f94bd..0000000000
--- a/system/bta/dm/bta_dm_disc_legacy.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 "bta/include/bta_api.h" // tBTA_DM_SEARCH_CBACK
-#include "stack/include/bt_hdr.h"
-#include "types/bt_transport.h"
-#include "types/raw_address.h"
-
-// TODO: Remove this file after flag separate_service_and_device_discovery rolls
-// out
-namespace bta_dm_disc_legacy {
-
-// Bta module start and stop entry points
-void bta_dm_disc_start(bool delay_close_gatt);
-void bta_dm_disc_stop();
-
-// Bta device discovery start and stop entry points
-void bta_dm_disc_start_device_discovery(tBTA_DM_SEARCH_CBACK*);
-void bta_dm_disc_stop_device_discovery();
-
-// Bta service discovery start and stop entry points
-void bta_dm_disc_start_service_discovery(service_discovery_callbacks cbacks,
- const RawAddress& bd_addr, tBT_TRANSPORT transport);
-
-// Bta subsystem entrypoint and lifecycle
-void bta_dm_disc_disable_search_and_disc();
-// Indication that an acl has gone down and to examine the current
-// service discovery procedure, if any.
-void bta_dm_disc_acl_down(const RawAddress& bd_addr, tBT_TRANSPORT transport);
-
-// Return most recent remote name
-const char* bta_dm_get_remname(void);
-
-// Checks if there is a device discovery request queued
-bool bta_dm_is_search_request_queued();
-
-// Proceed to execute service discovery on next device in queue
-void bta_dm_disc_discover_next_device();
-
-// GATT service discovery
-void bta_dm_disc_gattc_register();
-void bta_dm_disc_gatt_cancel_open(const RawAddress& bd_addr);
-void bta_dm_disc_gatt_refresh(const RawAddress& bd_addr);
-
-// Stop service discovery procedure, if any, for removed device
-void bta_dm_disc_remove_device(const RawAddress& bd_addr);
-
-// Provide data for the dumpsys procedure
-void DumpsysBtaDmDisc(int fd);
-
-} // namespace bta_dm_disc_legacy
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index e3b51f3f1b..43f5fc1d72 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -272,22 +272,15 @@ typedef union {
/* Search callback */
typedef void(tBTA_DM_SEARCH_CBACK)(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data);
-// TODO: delete bd_name parameter after separate_service_and_device_discovery
-// rolls out
-typedef void(tBTA_DM_GATT_DISC_CBACK)(RawAddress bd_addr, BD_NAME bd_name,
- std::vector<bluetooth::Uuid>& services, bool transport_le);
+typedef void(tBTA_DM_GATT_DISC_CBACK)(RawAddress bd_addr, std::vector<bluetooth::Uuid>& services,
+ bool transport_le);
typedef void(tBTA_DM_DID_RES_CBACK)(RawAddress bd_addr, uint8_t vendor_id_src, uint16_t vendor_id,
uint16_t product_id, uint16_t version);
-// TODO: delete after separate_service_and_device_discovery rolls out
-typedef void(tBTA_DM_NAME_READ_CBACK)(RawAddress bd_addr, tHCI_ERROR_CODE hci_status,
- const BD_NAME bd_name);
typedef void(tBTA_DM_DISC_CBACK)(RawAddress bd_addr, const std::vector<bluetooth::Uuid>& uuids,
tBTA_STATUS result);
struct service_discovery_callbacks {
tBTA_DM_GATT_DISC_CBACK* on_gatt_results;
tBTA_DM_DID_RES_CBACK* on_did_received;
- // TODO: delete after separate_service_and_device_discovery rolls out
- tBTA_DM_NAME_READ_CBACK* on_name_read;
tBTA_DM_DISC_CBACK* on_service_discovery_results;
};
diff --git a/system/bta/include/bta_jv_api.h b/system/bta/include/bta_jv_api.h
index a57c25db78..4bf5cbe490 100644
--- a/system/bta/include/bta_jv_api.h
+++ b/system/bta/include/bta_jv_api.h
@@ -32,7 +32,6 @@
#include "include/macros.h"
#include "internal_include/bt_target.h"
#include "stack/include/bt_hdr.h"
-#include "stack/include/l2c_api.h"
#include "stack/include/l2cap_interface.h"
#include "stack/include/rfcdefs.h"
#include "types/bluetooth/uuid.h"
diff --git a/system/bta/test/bta_disc_test.cc b/system/bta/test/bta_disc_test.cc
index f92cadb1aa..f9db1733f1 100644
--- a/system/bta/test/bta_disc_test.cc
+++ b/system/bta/test/bta_disc_test.cc
@@ -176,7 +176,7 @@ TEST_F(BtaInitializedTest, bta_dm_disc_stop_device_discovery) {
TEST_F(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_AUTO) {
bta_dm_disc_start_service_discovery(
- {nullptr, nullptr, nullptr,
+ {nullptr, nullptr,
[](RawAddress, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {}},
kRawAddress, BT_TRANSPORT_AUTO);
}
@@ -184,9 +184,7 @@ TEST_F(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_AUT
// must be global, as capturing lambda can't be treated as function
int service_cb_call_cnt = 0;
-TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_BR_EDR,
- REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT,
- separate_service_and_device_discovery))) {
+TEST_F(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_BR_EDR) {
bta_dm_disc_start(true);
int sdp_call_cnt = 0;
base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer =
@@ -198,7 +196,7 @@ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TR
bta_dm_disc_override_sdp_performer_for_testing(sdp_performer);
service_cb_call_cnt = 0;
- bta_dm_disc_start_service_discovery({nullptr, nullptr, nullptr,
+ bta_dm_disc_start_service_discovery({nullptr, nullptr,
[](RawAddress addr, const std::vector<bluetooth::Uuid>&,
tBTA_STATUS) { service_cb_call_cnt++; }},
kRawAddress, BT_TRANSPORT_BR_EDR);
@@ -212,9 +210,7 @@ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TR
// must be global, as capturing lambda can't be treated as function
int gatt_service_cb_call_cnt = 0;
-TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_LE,
- REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT,
- separate_service_and_device_discovery))) {
+TEST_F(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_LE) {
bta_dm_disc_start(true);
int gatt_call_cnt = 0;
base::RepeatingCallback<void(const RawAddress&)> gatt_performer =
@@ -225,9 +221,9 @@ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TR
bta_dm_disc_override_gatt_performer_for_testing(gatt_performer);
gatt_service_cb_call_cnt = 0;
- bta_dm_disc_start_service_discovery({[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&,
+ bta_dm_disc_start_service_discovery({[](RawAddress, std::vector<bluetooth::Uuid>&,
bool) { gatt_service_cb_call_cnt++; },
- nullptr, nullptr, nullptr},
+ nullptr, nullptr},
kRawAddress, BT_TRANSPORT_LE);
EXPECT_EQ(gatt_call_cnt, 1);
@@ -244,8 +240,6 @@ int gatt_service_cb_both_call_cnt = 0;
* dual-mode, CTKD capable device on LE transport.
*/
TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_disabled,
- REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT,
- separate_service_and_device_discovery)),
REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_BT, bta_dm_discover_both))) {
bta_dm_disc_start(true);
@@ -267,7 +261,7 @@ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_disabled,
service_cb_both_call_cnt = 0;
bta_dm_disc_start_service_discovery(
- {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {}, nullptr, nullptr,
+ {[](RawAddress, std::vector<bluetooth::Uuid>&, bool) {}, nullptr,
[](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
service_cb_both_call_cnt++;
}},
@@ -275,10 +269,10 @@ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_disabled,
EXPECT_EQ(sdp_call_cnt, 1);
bta_dm_disc_start_service_discovery(
- {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {
+ {[](RawAddress, std::vector<bluetooth::Uuid>&, bool) {
gatt_service_cb_both_call_cnt++;
},
- nullptr, nullptr,
+ nullptr,
[](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {}},
kRawAddress, BT_TRANSPORT_LE);
@@ -318,17 +312,17 @@ TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_enabled,
gatt_service_cb_both_call_cnt = 0;
service_cb_both_call_cnt = 0;
- bta_dm_disc_start_service_discovery({[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&,
+ bta_dm_disc_start_service_discovery({[](RawAddress, std::vector<bluetooth::Uuid>&,
bool) { gatt_service_cb_both_call_cnt++; },
- nullptr, nullptr,
+ nullptr,
[](RawAddress addr, const std::vector<bluetooth::Uuid>&,
tBTA_STATUS) { service_cb_both_call_cnt++; }},
kRawAddress, BT_TRANSPORT_BR_EDR);
EXPECT_EQ(sdp_call_cnt, 1);
- bta_dm_disc_start_service_discovery({[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&,
+ bta_dm_disc_start_service_discovery({[](RawAddress, std::vector<bluetooth::Uuid>&,
bool) { gatt_service_cb_both_call_cnt++; },
- nullptr, nullptr,
+ nullptr,
[](RawAddress addr, const std::vector<bluetooth::Uuid>&,
tBTA_STATUS) { service_cb_both_call_cnt++; }},
kRawAddress, BT_TRANSPORT_LE);
diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index b832dccf3e..abbf784179 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -1708,8 +1708,8 @@ static void btif_on_service_discovery_results(RawAddress bd_addr,
}
}
-void btif_on_gatt_results(RawAddress bd_addr, BD_NAME bd_name,
- std::vector<bluetooth::Uuid>& services, bool is_transport_le) {
+void btif_on_gatt_results(RawAddress bd_addr, std::vector<bluetooth::Uuid>& services,
+ bool is_transport_le) {
std::vector<bt_property_t> prop;
std::vector<uint8_t> property_value;
std::set<Uuid> uuids;
@@ -1821,16 +1821,6 @@ void btif_on_gatt_results(RawAddress bd_addr, BD_NAME bd_name,
bt_status_t ret = btif_storage_set_remote_device_property(&bd_addr, &prop[0]);
ASSERTC(ret == BT_STATUS_SUCCESS, "storing remote services failed", ret);
- /* Remote name update */
- if (!com::android::bluetooth::flags::separate_service_and_device_discovery() &&
- strnlen((const char*)bd_name, BD_NAME_LEN)) {
- prop.push_back(bt_property_t{BT_PROPERTY_BDNAME,
- static_cast<int>(strnlen((char*)bd_name, BD_NAME_LEN)), bd_name});
-
- ret = btif_storage_set_remote_device_property(&bd_addr, &prop[1]);
- ASSERTC(ret == BT_STATUS_SUCCESS, "failed to save remote device property", ret);
- }
-
if (!is_transport_le) {
/* If services were returned as part of SDP discovery, we will immediately
* send them with rest of SDP results in on_service_discovery_results */
@@ -1852,14 +1842,6 @@ void btif_on_gatt_results(RawAddress bd_addr, BD_NAME bd_name,
static void btif_on_name_read(RawAddress bd_addr, tHCI_ERROR_CODE hci_status, const BD_NAME bd_name,
bool during_device_search) {
- // Differentiate between merged callbacks
- if (!during_device_search
- // New fix after refactor, this callback is needed for the fix to work
- && !com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- log::info("Skipping name read event - called on bad callback.");
- return;
- }
-
if (hci_status != HCI_SUCCESS) {
log::warn("Received RNR event with bad status addr:{} hci_status:{}", bd_addr,
hci_error_code_text(hci_status));
@@ -1964,9 +1946,7 @@ void BTIF_dm_enable() {
log::info("Local BLE Privacy enabled:{}", ble_privacy_enabled);
BTA_DmBleConfigLocalPrivacy(ble_privacy_enabled);
- if (com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- get_stack_rnr_interface().BTM_SecAddRmtNameNotifyCallback(btif_on_name_read_from_btm);
- }
+ get_stack_rnr_interface().BTM_SecAddRmtNameNotifyCallback(btif_on_name_read_from_btm);
/* for each of the enabled services in the mask, trigger the profile
* enable */
@@ -1992,9 +1972,7 @@ void BTIF_dm_enable() {
}
void BTIF_dm_disable() {
- if (com::android::bluetooth::flags::separate_service_and_device_discovery()) {
- get_stack_rnr_interface().BTM_SecDeleteRmtNameNotifyCallback(&btif_on_name_read_from_btm);
- }
+ get_stack_rnr_interface().BTM_SecDeleteRmtNameNotifyCallback(&btif_on_name_read_from_btm);
/* for each of the enabled services in the mask, trigger the profile
* disable */
@@ -2805,11 +2783,6 @@ bt_status_t btif_dm_get_adapter_property(bt_property_t* prop) {
return BT_STATUS_SUCCESS;
}
-static void btif_on_name_read_legacy(RawAddress bd_addr, tHCI_ERROR_CODE hci_status,
- const BD_NAME bd_name) {
- btif_on_name_read(bd_addr, hci_status, bd_name, false /* during_device_search */);
-}
-
/*******************************************************************************
*
* Function btif_dm_get_remote_services
@@ -2829,7 +2802,6 @@ void btif_dm_get_remote_services(RawAddress remote_addr, const tBT_TRANSPORT tra
service_discovery_callbacks{
.on_gatt_results = btif_on_gatt_results,
.on_did_received = btif_on_did_received,
- .on_name_read = btif_on_name_read_legacy,
.on_service_discovery_results = btif_on_service_discovery_results},
transport);
}
diff --git a/system/gd/hci/controller.cc b/system/gd/hci/controller.cc
index b5e2d00006..523a20bbca 100644
--- a/system/gd/hci/controller.cc
+++ b/system/gd/hci/controller.cc
@@ -56,6 +56,10 @@ struct Controller::impl {
handler->BindOn(this, &Controller::impl::NumberOfCompletedPackets));
set_event_mask(kDefaultEventMask);
+ if (com::android::bluetooth::flags::encryption_change_v2()) {
+ set_event_mask_page_2(kDefaultEventMaskPage2);
+ }
+
write_le_host_support(Enable::ENABLED, Enable::DISABLED);
hci_->EnqueueCommand(
ReadLocalNameBuilder::Create(),
@@ -766,6 +770,13 @@ struct Controller::impl {
module_.GetHandler()->BindOnce(check_complete<SetEventMaskCompleteView>));
}
+ void set_event_mask_page_2(uint64_t event_mask_page_2) {
+ std::unique_ptr<SetEventMaskPage2Builder> packet =
+ SetEventMaskPage2Builder::Create(event_mask_page_2);
+ hci_->EnqueueCommand(std::move(packet), module_.GetHandler()->BindOnce(
+ check_complete<SetEventMaskPage2CompleteView>));
+ }
+
void write_le_host_support(Enable enable, Enable deprecated_host_bit) {
if (deprecated_host_bit == Enable::ENABLED) {
// Since Bluetooth Core Spec 4.1, this bit should be 0
diff --git a/system/gd/hci/controller.h b/system/gd/hci/controller.h
index 9eaa026b23..498546ef3a 100644
--- a/system/gd/hci/controller.h
+++ b/system/gd/hci/controller.h
@@ -202,6 +202,7 @@ public:
static const ModuleFactory Factory;
static constexpr uint64_t kDefaultEventMask = 0x3dbfffffffffffff;
+ static constexpr uint64_t kDefaultEventMaskPage2 = 0x2000000;
static constexpr uint64_t kDefaultLeEventMask = 0x000000074d02fe7f;
static constexpr uint64_t kLeCSEventMask = 0x0007f80000000000;
diff --git a/system/gd/hci/security_interface.h b/system/gd/hci/security_interface.h
index d1126bd4ab..ad7a628b73 100644
--- a/system/gd/hci/security_interface.h
+++ b/system/gd/hci/security_interface.h
@@ -39,6 +39,7 @@ constexpr hci::EventCode SecurityEvents[] = {
hci::EventCode::KEYPRESS_NOTIFICATION,
hci::EventCode::USER_CONFIRMATION_REQUEST,
hci::EventCode::USER_PASSKEY_REQUEST,
+ hci::EventCode::ENCRYPTION_CHANGE_V2,
};
typedef CommandInterface<SecurityCommandBuilder> SecurityInterface;
diff --git a/system/gd/rust/common/src/logging.rs b/system/gd/rust/common/src/logging.rs
index 4207114d92..71c60da64b 100644
--- a/system/gd/rust/common/src/logging.rs
+++ b/system/gd/rust/common/src/logging.rs
@@ -1,7 +1,7 @@
/// Inits logging for Android
#[cfg(target_os = "android")]
pub fn init_logging() {
- android_logger::init_once(android_logger::Config::default().with_tag("bt"));
+ android_logger::init_once(android_logger::Config::default().with_tag("bluetooth"));
}
/// Inits logging for host
diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs
index c7ca1e9082..e1ec1ed946 100644
--- a/system/gd/rust/topshim/src/btif.rs
+++ b/system/gd/rust/topshim/src/btif.rs
@@ -14,6 +14,7 @@ use std::hash::{Hash, Hasher};
use std::mem;
use std::os::fd::RawFd;
use std::os::raw::c_char;
+use std::ptr::NonNull;
use std::sync::{Arc, Mutex};
use std::vec::Vec;
use topshim_macros::{cb_variant, gen_cxx_extern_trivial};
@@ -788,9 +789,12 @@ impl BluetoothProperty {
// TODO(abps) - Check that sizes are correct when given a BtProperty
impl From<bindings::bt_property_t> for BluetoothProperty {
fn from(prop: bindings::bt_property_t) -> Self {
- let slice: &[u8] =
- unsafe { std::slice::from_raw_parts(prop.val as *mut u8, prop.len as usize) };
+ // Property values may be null, which isn't valid to pass for `slice::from_raw_parts`.
+ // Choose a dangling pointer in that case.
+ let prop_val_ptr =
+ NonNull::new(prop.val as *mut u8).unwrap_or(NonNull::dangling()).as_ptr();
let len = prop.len as usize;
+ let slice: &[u8] = unsafe { std::slice::from_raw_parts(prop_val_ptr, len) };
match BtPropertyType::from(prop.type_) {
BtPropertyType::BdName => BluetoothProperty::BdName(ascii_to_string(slice, len)),
diff --git a/system/gd/security/channel/security_manager_channel_unittest.cc b/system/gd/security/channel/security_manager_channel_unittest.cc
index b3feb5d499..c1680c3760 100644
--- a/system/gd/security/channel/security_manager_channel_unittest.cc
+++ b/system/gd/security/channel/security_manager_channel_unittest.cc
@@ -82,6 +82,7 @@ public:
bool receivedUserPasskeyRequest = false;
bool receivedKeypressNotification = false;
bool receivedUserConfirmationRequest = false;
+ bool receivedEncryptionChangeV2 = false;
void OnReceive(hci::AddressWithType device, hci::ChangeConnectionLinkKeyCompleteView packet) {
ASSERT_TRUE(packet.IsValid());
@@ -147,6 +148,10 @@ public:
ASSERT_TRUE(packet.IsValid());
receivedUserPasskeyRequest = true;
}
+ void OnReceive(hci::AddressWithType device, hci::EncryptionChangeV2View packet) {
+ ASSERT_TRUE(packet.IsValid());
+ receivedEncryptionChangeV2 = true;
+ }
void OnHciEventReceived(EventView packet) override {
auto event = EventView::Create(packet);
@@ -201,6 +206,9 @@ public:
case hci::EventCode::USER_PASSKEY_REQUEST:
OnReceive(hci::AddressWithType(), hci::UserPasskeyRequestView::Create(event));
break;
+ case hci::EventCode::ENCRYPTION_CHANGE_V2:
+ OnReceive(hci::AddressWithType(), hci::EncryptionChangeV2View::Create(event));
+ break;
default:
log::fatal("Cannot handle received packet: {}", hci::EventCodeText(code));
break;
@@ -584,6 +592,14 @@ TEST_F(SecurityManagerChannelTest, recv_encryption_change) {
ASSERT_TRUE(callback_->receivedEncryptionChange);
}
+TEST_F(SecurityManagerChannelTest, recv_encryption_change_v2) {
+ uint16_t connection_handle = 0x0;
+ hci_layer_->IncomingEvent(hci::EncryptionChangeV2Builder::Create(
+ hci::ErrorCode::SUCCESS, connection_handle, hci::EncryptionEnabled::ON, 0x10));
+ synchronize();
+ ASSERT_TRUE(callback_->receivedEncryptionChangeV2);
+}
+
TEST_F(SecurityManagerChannelTest, recv_encryption_key_refresh) {
uint16_t connection_handle = 0x0;
hci_layer_->IncomingEvent(hci::EncryptionKeyRefreshCompleteBuilder::Create(
diff --git a/system/main/shim/hci_layer.cc b/system/main/shim/hci_layer.cc
index 95c00cea4d..95794f0492 100644
--- a/system/main/shim/hci_layer.cc
+++ b/system/main/shim/hci_layer.cc
@@ -77,6 +77,7 @@ bool register_event_code(bluetooth::hci::EventCode event_code) {
case bluetooth::hci::EventCode::USER_PASSKEY_NOTIFICATION:
case bluetooth::hci::EventCode::USER_CONFIRMATION_REQUEST:
case bluetooth::hci::EventCode::USER_PASSKEY_REQUEST:
+ case bluetooth::hci::EventCode::ENCRYPTION_CHANGE_V2:
return true;
default:
return false;
diff --git a/system/pdl/hci/hci_packets.pdl b/system/pdl/hci/hci_packets.pdl
index cbda6ff235..9225204045 100644
--- a/system/pdl/hci/hci_packets.pdl
+++ b/system/pdl/hci/hci_packets.pdl
@@ -862,6 +862,7 @@ enum EventCode : 8 {
LE_META_EVENT = 0x3e,
NUMBER_OF_COMPLETED_DATA_BLOCKS = 0x48,
AUTHENTICATED_PAYLOAD_TIMEOUT_EXPIRED = 0x57,
+ ENCRYPTION_CHANGE_V2 = 0x59,
VENDOR_SPECIFIC = 0xFF,
}
@@ -6327,6 +6328,14 @@ packet AuthenticatedPayloadTimeoutExpired : Event (event_code = AUTHENTICATED_PA
_reserved_ : 4,
}
+packet EncryptionChangeV2 : Event (event_code = ENCRYPTION_CHANGE_V2) {
+ status : ErrorCode,
+ connection_handle : 12,
+ _reserved_ : 4,
+ encryption_enabled : EncryptionEnabled,
+ key_size : 8,
+}
+
// LE Events
packet LeConnectionComplete : LeMetaEvent (subevent_code = CONNECTION_COMPLETE) {
status : ErrorCode,
diff --git a/system/stack/avct/avct_api.cc b/system/stack/avct/avct_api.cc
index 926db22e49..10c441d876 100644
--- a/system/stack/avct/avct_api.cc
+++ b/system/stack/avct/avct_api.cc
@@ -31,8 +31,6 @@
#include "avct_int.h"
#include "bta/include/bta_sec_api.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_interface.h"
@@ -106,6 +104,9 @@ void AVCT_Deregister(void) {
/* deregister PSM with L2CAP */
stack::l2cap::get_interface().L2CA_Deregister(AVCT_PSM);
+
+ /* deregister AVCT_BR_PSM with L2CAP */
+ stack::l2cap::get_interface().L2CA_Deregister(AVCT_BR_PSM);
}
/*******************************************************************************
diff --git a/system/stack/avct/avct_int.h b/system/stack/avct/avct_int.h
index 46bd73d793..db1528b80e 100644
--- a/system/stack/avct/avct_int.h
+++ b/system/stack/avct/avct_int.h
@@ -26,7 +26,6 @@
#include "avct_api.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
#include "osi/include/fixed_queue.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_interface.h"
diff --git a/system/stack/avct/avct_l2c.cc b/system/stack/avct/avct_l2c.cc
index 7147ef6029..adca67c851 100644
--- a/system/stack/avct/avct_l2c.cc
+++ b/system/stack/avct/avct_l2c.cc
@@ -29,8 +29,6 @@
#include "avct_int.h"
#include "btif/include/btif_av.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_interface.h"
diff --git a/system/stack/avct/avct_l2c_br.cc b/system/stack/avct/avct_l2c_br.cc
index a8af279049..4c5ccc503b 100644
--- a/system/stack/avct/avct_l2c_br.cc
+++ b/system/stack/avct/avct_l2c_br.cc
@@ -31,8 +31,6 @@
#include "avct_api.h"
#include "avct_int.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_interface.h"
diff --git a/system/stack/avdt/avdt_ad.cc b/system/stack/avdt/avdt_ad.cc
index 3b66f66b5b..f566688ef7 100644
--- a/system/stack/avdt/avdt_ad.cc
+++ b/system/stack/avdt/avdt_ad.cc
@@ -31,8 +31,6 @@
#include "avdt_api.h"
#include "avdt_int.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/btm_sec_api_types.h"
@@ -587,7 +585,7 @@ void avdt_ad_close_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb) {
default:
lcid = p_tbl->lcid;
/* call l2cap disconnect req */
- if (!L2CA_DisconnectReq(lcid)) {
+ if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
log::warn("Unable to disconnect L2CAP lcid: 0x{:04x}", lcid);
}
avdt_ad_tc_close_ind(p_tbl);
diff --git a/system/stack/avdt/avdt_int.h b/system/stack/avdt/avdt_int.h
index 54e5fa9b6f..6b2b354b06 100644
--- a/system/stack/avdt/avdt_int.h
+++ b/system/stack/avdt/avdt_int.h
@@ -33,9 +33,8 @@
#include "avdt_api.h"
#include "avdt_defs.h"
#include "avdtc_api.h"
+#include "include/macros.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
-#include "macros.h"
#include "osi/include/alarm.h"
#include "osi/include/fixed_queue.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/avdt/avdt_l2c.cc b/system/stack/avdt/avdt_l2c.cc
index 1f9c18517d..6eab341865 100644
--- a/system/stack/avdt/avdt_l2c.cc
+++ b/system/stack/avdt/avdt_l2c.cc
@@ -29,12 +29,9 @@
#include "avdt_int.h"
#include "bta/include/bta_av_api.h"
#include "device/include/interop.h"
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "osi/include/allocator.h"
#include "stack/include/acl_api.h"
#include "stack/include/bt_hdr.h"
-#include "stack/include/btm_status.h"
#include "stack/include/l2cap_interface.h"
#include "types/raw_address.h"
@@ -226,7 +223,7 @@ static void avdt_on_l2cap_error(uint16_t lcid, uint16_t result) {
AvdtpTransportChannel* p_tbl;
log::warn("lcid: 0x{:04x}, result: {}", lcid, to_l2cap_result_code(result));
- if (!L2CA_DisconnectReq(lcid)) {
+ if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
log::warn("Unable to disconnect L2CAP lcid: 0x{:04x}", lcid);
}
diff --git a/system/stack/bnep/bnep_main.cc b/system/stack/bnep/bnep_main.cc
index 9d00fd63be..e0e3c4540c 100644
--- a/system/stack/bnep/bnep_main.cc
+++ b/system/stack/bnep/bnep_main.cc
@@ -32,8 +32,6 @@
#include "bta/include/bta_sec_api.h"
#include "hci/controller_interface.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "main/shim/entry.h"
#include "main/shim/helpers.h"
#include "osi/include/allocator.h"
diff --git a/system/stack/btm/btm_dev.cc b/system/stack/btm/btm_dev.cc
index 6450bf5502..76a69b5fbe 100644
--- a/system/stack/btm/btm_dev.cc
+++ b/system/stack/btm/btm_dev.cc
@@ -36,7 +36,6 @@
#include "btm_sec_api.h"
#include "btm_sec_cb.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
#include "main/shim/dumpsys.h"
#include "osi/include/allocator.h"
#include "rust/src/connection/ffi/connection_shim.h"
diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc
index 93ce8c0dfa..f310bde7bd 100644
--- a/system/stack/btm/btm_sec.cc
+++ b/system/stack/btm/btm_sec.cc
@@ -3174,7 +3174,8 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status) {
* Returns void
*
******************************************************************************/
-void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable) {
+void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable,
+ uint8_t key_size, bool = false) {
/* For transaction collision we need to wait and repeat. There is no need */
/* for random timeout because only peripheral should receive the result */
if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) ||
@@ -3197,12 +3198,16 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_en
const tBT_TRANSPORT transport =
BTM_IsBleConnection(handle) ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR;
+ if (transport == BT_TRANSPORT_LE) {
+ key_size = p_dev_rec->sec_rec.ble_keys.key_size;
+ }
+
log::debug(
"Security Manager encryption change request hci_status:{} request:{} "
- "state: le_link:{} classic_link:{} sec_flags:0x{:x}",
+ "state: le_link:{} classic_link:{} sec_flags:0x{:x} key_size:{}",
hci_status_code_text(status), (encr_enable) ? "encrypt" : "unencrypt",
- p_dev_rec->sec_rec.le_link, p_dev_rec->sec_rec.classic_link,
- p_dev_rec->sec_rec.sec_flags);
+ p_dev_rec->sec_rec.le_link, p_dev_rec->sec_rec.classic_link, p_dev_rec->sec_rec.sec_flags,
+ key_size);
if (status == HCI_SUCCESS) {
if (encr_enable) {
@@ -3396,7 +3401,7 @@ static void read_encryption_key_size_complete_after_encryption_change(uint8_t st
// good key size - succeed
btm_acl_encrypt_change(handle, static_cast<tHCI_STATUS>(status), 1 /* enable */);
- btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status), 1 /* enable */);
+ btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status), 1 /* enable */, key_size);
}
// TODO: Remove
@@ -3411,21 +3416,29 @@ void smp_cancel_start_encryption_attempt();
* Returns void
*
******************************************************************************/
-void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable) {
- if (status != HCI_SUCCESS || encr_enable == 0 || BTM_IsBleConnection(handle) ||
- !bluetooth::shim::GetController()->IsSupported(
- bluetooth::hci::OpCode::READ_ENCRYPTION_KEY_SIZE)) {
- if (status == HCI_ERR_CONNECTION_TOUT) {
- smp_cancel_start_encryption_attempt();
+void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable,
+ uint8_t key_size) {
+ if (status == HCI_SUCCESS && encr_enable != 0 && !BTM_IsBleConnection(handle)) {
+ if (key_size != 0) {
+ read_encryption_key_size_complete_after_encryption_change(status, handle, key_size);
return;
}
- btm_acl_encrypt_change(handle, static_cast<tHCI_STATUS>(status), encr_enable);
- btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status), encr_enable);
- } else {
- btsnd_hcic_read_encryption_key_size(
- handle, base::Bind(&read_encryption_key_size_complete_after_encryption_change));
+ if (bluetooth::shim::GetController()->IsSupported(
+ bluetooth::hci::OpCode::READ_ENCRYPTION_KEY_SIZE)) {
+ btsnd_hcic_read_encryption_key_size(
+ handle, base::Bind(&read_encryption_key_size_complete_after_encryption_change));
+ return;
+ }
}
+
+ if (status == HCI_ERR_CONNECTION_TOUT) {
+ smp_cancel_start_encryption_attempt();
+ return;
+ }
+
+ btm_acl_encrypt_change(handle, static_cast<tHCI_STATUS>(status), encr_enable);
+ btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status), encr_enable, 0);
}
/*******************************************************************************
*
@@ -3948,7 +3961,7 @@ static void read_encryption_key_size_complete_after_key_refresh(uint8_t status,
return;
}
- btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status), 1 /* enc_enable */);
+ btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status), 1 /* enc_enable */, key_size);
}
void btm_sec_encryption_key_refresh_complete(uint16_t handle, tHCI_STATUS status) {
@@ -3957,7 +3970,7 @@ void btm_sec_encryption_key_refresh_complete(uint16_t handle, tHCI_STATUS status
bluetooth::shim::GetController()->IsSupported(
bluetooth::hci::OpCode::SET_MIN_ENCRYPTION_KEY_SIZE)) {
btm_sec_encrypt_change(handle, static_cast<tHCI_STATUS>(status),
- (status == HCI_SUCCESS) ? 1 : 0);
+ (status == HCI_SUCCESS) ? 1 : 0, 0, true);
} else {
btsnd_hcic_read_encryption_key_size(
handle, base::Bind(&read_encryption_key_size_complete_after_key_refresh));
diff --git a/system/stack/btm/btm_sec.h b/system/stack/btm/btm_sec.h
index c8a2e16c61..9646ada250 100644
--- a/system/stack/btm/btm_sec.h
+++ b/system/stack/btm/btm_sec.h
@@ -549,7 +549,8 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status);
* Returns void
*
******************************************************************************/
-void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable);
+void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable,
+ uint8_t key_size);
/*******************************************************************************
*
@@ -561,7 +562,8 @@ void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t
* Returns void
*
******************************************************************************/
-void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable);
+void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable,
+ uint8_t key_size, bool from_key_refresh);
/*******************************************************************************
*
diff --git a/system/stack/btm/security_event_parser.cc b/system/stack/btm/security_event_parser.cc
index 4de55a16cb..84d7005d16 100644
--- a/system/stack/btm/security_event_parser.cc
+++ b/system/stack/btm/security_event_parser.cc
@@ -68,7 +68,24 @@ static void parse_encryption_change(const EventView event) {
EncryptionEnabled encr_enable = change.GetEncryptionEnabled();
btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status),
- static_cast<uint8_t>(encr_enable));
+ static_cast<uint8_t>(encr_enable), 0);
+ log_classic_pairing_event(
+ ToRawAddress(Address::kEmpty), handle, android::bluetooth::hci::CMD_UNKNOWN,
+ static_cast<uint32_t>(change.GetEventCode()), static_cast<uint16_t>(status),
+ android::bluetooth::hci::STATUS_UNKNOWN, 0);
+}
+static void parse_encryption_change_v2(const EventView event) {
+ auto change_opt = EncryptionChangeV2View::CreateOptional(event);
+ log::assert_that(change_opt.has_value(), "assert failed: change_opt.has_value()");
+ auto change = change_opt.value();
+
+ ErrorCode status = change.GetStatus();
+ uint16_t handle = change.GetConnectionHandle();
+ EncryptionEnabled encr_enable = change.GetEncryptionEnabled();
+ uint8_t key_size = change.GetKeySize();
+
+ btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status),
+ static_cast<uint8_t>(encr_enable), key_size);
log_classic_pairing_event(
ToRawAddress(Address::kEmpty), handle, android::bluetooth::hci::CMD_UNKNOWN,
static_cast<uint32_t>(change.GetEventCode()), static_cast<uint16_t>(status),
@@ -261,6 +278,9 @@ void SecurityEventParser::OnSecurityEvent(bluetooth::hci::EventView event) {
case EventCode::USER_PASSKEY_REQUEST:
parse_user_passkey_request(event);
break;
+ case EventCode::ENCRYPTION_CHANGE_V2:
+ parse_encryption_change_v2(event);
+ break;
default:
log::error("Unhandled event {}", EventCodeText(event.GetEventCode()));
}
diff --git a/system/stack/btu/btu_hcif.cc b/system/stack/btu/btu_hcif.cc
index 33cd9d05f7..d392f29fdd 100644
--- a/system/stack/btu/btu_hcif.cc
+++ b/system/stack/btu/btu_hcif.cc
@@ -74,6 +74,7 @@ void acl_disconnect_from_handle(uint16_t handle, tHCI_STATUS reason,
/******************************************************************************/
static void btu_hcif_authentication_comp_evt(uint8_t* p);
static void btu_hcif_encryption_change_evt(uint8_t* p);
+static void btu_hcif_encryption_change_evt_v2(uint8_t* p);
static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p, uint8_t evt_len);
static void btu_hcif_command_complete_evt(BT_HDR* response, void* context);
static void btu_hcif_command_status_evt(uint8_t status, BT_HDR* command, void* context);
@@ -148,6 +149,16 @@ static void btu_hcif_log_event_metrics(uint8_t evt_code, const uint8_t* p_event)
log_classic_pairing_event(bda, handle, cmd, evt_code, status, reason, encryption_enabled);
break;
}
+ case HCI_ENCRYPTION_CHANGE_EVT_V2: {
+ uint8_t encryption_enabled;
+ uint8_t key_size;
+ STREAM_TO_UINT8(status, p_event);
+ STREAM_TO_UINT16(handle, p_event);
+ STREAM_TO_UINT8(encryption_enabled, p_event);
+ STREAM_TO_UINT8(key_size, p_event);
+ log_classic_pairing_event(bda, handle, cmd, evt_code, status, reason, encryption_enabled);
+ break;
+ }
case HCI_ESCO_CONNECTION_COMP_EVT: {
uint8_t link_type;
STREAM_TO_UINT8(status, p_event);
@@ -220,6 +231,9 @@ void btu_hcif_process_event(uint8_t /* controller_id */, const BT_HDR* p_msg) {
case HCI_ENCRYPTION_CHANGE_EVT:
btu_hcif_encryption_change_evt(p);
break;
+ case HCI_ENCRYPTION_CHANGE_EVT_V2:
+ btu_hcif_encryption_change_evt_v2(p);
+ break;
case HCI_ENCRYPTION_KEY_REFRESH_COMP_EVT:
btu_hcif_encryption_key_refresh_cmpl_evt(p);
break;
@@ -750,7 +764,30 @@ static void btu_hcif_encryption_change_evt(uint8_t* p) {
STREAM_TO_UINT16(handle, p);
STREAM_TO_UINT8(encr_enable, p);
- btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status), encr_enable);
+ btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status), encr_enable, 0);
+}
+
+/*******************************************************************************
+ *
+ * Function btu_hcif_encryption_change_evt_v2
+ *
+ * Description Process event HCI_ENCRYPTION_CHANGE_EVT_V2
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+static void btu_hcif_encryption_change_evt_v2(uint8_t* p) {
+ uint8_t status;
+ uint16_t handle;
+ uint8_t encr_enable;
+ uint8_t key_size;
+
+ STREAM_TO_UINT8(status, p);
+ STREAM_TO_UINT16(handle, p);
+ STREAM_TO_UINT8(encr_enable, p);
+ STREAM_TO_UINT8(key_size, p);
+
+ btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status), encr_enable, key_size);
}
/*******************************************************************************
@@ -1025,7 +1062,7 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status, const u
if (status != HCI_SUCCESS) {
// Device refused to start encryption
// This is treated as an encryption failure
- btm_sec_encrypt_change(HCI_INVALID_HANDLE, hci_status, false);
+ btm_sec_encrypt_change(HCI_INVALID_HANDLE, hci_status, false, 0);
}
break;
case HCI_READ_RMT_EXT_FEATURES:
diff --git a/system/stack/fuzzers/l2cap_fuzzer.cc b/system/stack/fuzzers/l2cap_fuzzer.cc
index c6cfee87ca..f8714cc3f3 100644
--- a/system/stack/fuzzers/l2cap_fuzzer.cc
+++ b/system/stack/fuzzers/l2cap_fuzzer.cc
@@ -30,10 +30,10 @@
#include "osi/include/allocator.h"
#include "stack/btm/btm_int_types.h"
#include "stack/include/bt_psm_types.h"
-#include "stack/include/l2c_api.h"
#include "stack/include/l2cap_acl_interface.h"
#include "stack/include/l2cap_controller_interface.h"
#include "stack/include/l2cap_hci_link_interface.h"
+#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cap_module.h"
#include "stack/include/l2cdefs.h"
#include "test/fake/fake_osi.h"
@@ -197,34 +197,37 @@ static void Fuzz(const uint8_t* data, size_t size) {
tL2CAP_LE_CFG_INFO*) {},
.pL2CA_CreditBasedCollisionInd_Cb = [](const RawAddress&) {},
};
- log::assert_that(L2CA_RegisterWithSecurity(BT_PSM_ATT, appl_info, false, nullptr, L2CAP_MTU_SIZE,
- 0, BTM_SEC_NONE),
+ log::assert_that(stack::l2cap::get_interface().L2CA_RegisterWithSecurity(
+ BT_PSM_ATT, appl_info, false, nullptr, L2CAP_MTU_SIZE, 0, BTM_SEC_NONE),
"assert failed: L2CA_RegisterWithSecurity(BT_PSM_ATT, appl_info, "
"false, nullptr, L2CAP_MTU_SIZE, 0, BTM_SEC_NONE)");
- log::assert_that(L2CA_RegisterLECoc(BT_PSM_EATT, appl_info, BTM_SEC_NONE, {}),
+ log::assert_that(stack::l2cap::get_interface().L2CA_RegisterLECoc(BT_PSM_EATT, appl_info,
+ BTM_SEC_NONE, {}),
"assert failed: L2CA_RegisterLECoc(BT_PSM_EATT, appl_info, "
"BTM_SEC_NONE, {{}})");
- log::assert_that(L2CA_RegisterFixedChannel(L2CAP_ATT_CID, &reg),
+ log::assert_that(stack::l2cap::get_interface().L2CA_RegisterFixedChannel(L2CAP_ATT_CID, &reg),
"assert failed: L2CA_RegisterFixedChannel(L2CAP_ATT_CID, &reg)");
- log::assert_that(L2CA_ConnectFixedChnl(L2CAP_ATT_CID, kAttAddr),
+ log::assert_that(stack::l2cap::get_interface().L2CA_ConnectFixedChnl(L2CAP_ATT_CID, kAttAddr),
"assert failed: L2CA_ConnectFixedChnl(L2CAP_ATT_CID, kAttAddr)");
log::assert_that(
l2cble_conn_comp(kAttHndl, HCI_ROLE_CENTRAL, kAttAddr, BLE_ADDR_PUBLIC, 100, 100, 100),
"assert failed: l2cble_conn_comp(kAttHndl, HCI_ROLE_CENTRAL, kAttAddr, "
"BLE_ADDR_PUBLIC, 100, 100, 100)");
- log::assert_that(L2CA_RegisterFixedChannel(L2CAP_SMP_BR_CID, &reg),
+ log::assert_that(stack::l2cap::get_interface().L2CA_RegisterFixedChannel(L2CAP_SMP_BR_CID, &reg),
"assert failed: L2CA_RegisterFixedChannel(L2CAP_SMP_BR_CID, &reg)");
- log::assert_that(L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr),
- "assert failed: L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr)");
+ log::assert_that(
+ stack::l2cap::get_interface().L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr),
+ "assert failed: L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr)");
l2c_link_hci_conn_comp(HCI_SUCCESS, kSmpBrHndl, kSmpBrAddr);
- auto att_cid = L2CA_ConnectReq(BT_PSM_ATT, kAttAddr);
+ auto att_cid = stack::l2cap::get_interface().L2CA_ConnectReq(BT_PSM_ATT, kAttAddr);
log::assert_that(att_cid != 0, "assert failed: att_cid != 0");
tL2CAP_LE_CFG_INFO cfg;
- auto eatt_cid = L2CA_ConnectLECocReq(BT_PSM_EATT, kEattAddr, &cfg, 0);
+ auto eatt_cid =
+ stack::l2cap::get_interface().L2CA_ConnectLECocReq(BT_PSM_EATT, kEattAddr, &cfg, 0);
log::assert_that(eatt_cid != 0, "assert failed: eatt_cid != 0");
FuzzedDataProvider fdp(data, size);
@@ -245,13 +248,13 @@ static void Fuzz(const uint8_t* data, size_t size) {
l2c_rcv_acl_data(hdr);
}
- (void)L2CA_DisconnectReq(att_cid);
- (void)L2CA_DisconnectLECocReq(eatt_cid);
+ (void)stack::l2cap::get_interface().L2CA_DisconnectReq(att_cid);
+ (void)stack::l2cap::get_interface().L2CA_DisconnectLECocReq(eatt_cid);
- (void)L2CA_RemoveFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr);
+ (void)stack::l2cap::get_interface().L2CA_RemoveFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr);
l2c_link_hci_disc_comp(kSmpBrHndl, HCI_SUCCESS);
- (void)L2CA_RemoveFixedChnl(L2CAP_ATT_CID, kAttAddr);
+ (void)stack::l2cap::get_interface().L2CA_RemoveFixedChnl(L2CAP_ATT_CID, kAttAddr);
l2c_link_hci_disc_comp(kAttHndl, HCI_SUCCESS);
l2cu_device_reset();
diff --git a/system/stack/gap/gap_conn.cc b/system/stack/gap/gap_conn.cc
index ad59ebca80..1375b3e838 100644
--- a/system/stack/gap/gap_conn.cc
+++ b/system/stack/gap/gap_conn.cc
@@ -23,8 +23,6 @@
#include "gap_api.h"
#include "hci/controller_interface.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "main/shim/entry.h"
#include "osi/include/allocator.h"
#include "osi/include/fixed_queue.h"
diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc
index 29e196bfea..af8cfdc7d8 100644
--- a/system/stack/gatt/att_protocol.cc
+++ b/system/stack/gatt/att_protocol.cc
@@ -26,7 +26,6 @@
#include "gatt_int.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc
index 6c804e10bc..9008ee0850 100644
--- a/system/stack/gatt/gatt_api.cc
+++ b/system/stack/gatt/gatt_api.cc
@@ -33,7 +33,6 @@
#include "internal_include/bt_target.h"
#include "internal_include/stack_config.h"
-#include "l2c_api.h"
#include "os/system_properties.h"
#include "osi/include/allocator.h"
#include "rust/src/connection/ffi/connection_shim.h"
diff --git a/system/stack/gatt/gatt_main.cc b/system/stack/gatt/gatt_main.cc
index 6a195533cb..7c14d3a5a1 100644
--- a/system/stack/gatt/gatt_main.cc
+++ b/system/stack/gatt/gatt_main.cc
@@ -32,7 +32,6 @@
#include "device/include/interop.h"
#include "internal_include/bt_target.h"
#include "internal_include/stack_config.h"
-#include "l2c_api.h"
#include "main/shim/acl_api.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
diff --git a/system/stack/gatt/gatt_sr.cc b/system/stack/gatt/gatt_sr.cc
index 3efce5a466..ccb017edcc 100644
--- a/system/stack/gatt/gatt_sr.cc
+++ b/system/stack/gatt/gatt_sr.cc
@@ -31,7 +31,6 @@
#include "hardware/bt_gatt_types.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
#include "osi/include/allocator.h"
#include "stack/arbiter/acl_arbiter.h"
#include "stack/eatt/eatt.h"
@@ -39,7 +38,7 @@
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
#include "stack/include/btm_client_interface.h"
-#include "stack/include/l2cdefs.h"
+#include "stack/include/l2cap_types.h"
#include "types/bluetooth/uuid.h"
#define GATT_MTU_REQ_MIN_LEN 2
diff --git a/system/stack/hid/hidh_conn.cc b/system/stack/hid/hidh_conn.cc
index 9387295a03..5205b322df 100644
--- a/system/stack/hid/hidh_conn.cc
+++ b/system/stack/hid/hidh_conn.cc
@@ -33,8 +33,6 @@
#include "hidh_api.h"
#include "hidh_int.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "stack/include/acl_api.h"
diff --git a/system/stack/include/bnep_api.h b/system/stack/include/bnep_api.h
index fc8343ee48..a11ce06218 100644
--- a/system/stack/include/bnep_api.h
+++ b/system/stack/include/bnep_api.h
@@ -27,7 +27,6 @@
#include <cstdint>
-#include "l2c_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_types.h"
#include "types/bluetooth/uuid.h"
diff --git a/system/stack/include/gap_api.h b/system/stack/include/gap_api.h
index 6a3b8203d5..04329fdd9e 100644
--- a/system/stack/include/gap_api.h
+++ b/system/stack/include/gap_api.h
@@ -21,8 +21,6 @@
#include <cstdint>
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "profiles_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_types.h"
diff --git a/system/stack/include/hcidefs.h b/system/stack/include/hcidefs.h
index e874d9fa91..7a6c4c733b 100644
--- a/system/stack/include/hcidefs.h
+++ b/system/stack/include/hcidefs.h
@@ -561,6 +561,7 @@ constexpr uint8_t HCI_LE_STATES_INIT_CENTRAL_PERIPHERAL_BIT = 41;
#define HCI_USER_PASSKEY_NOTIFY_EVT 0x3B
#define HCI_KEYPRESS_NOTIFY_EVT 0x3C
#define HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT 0x3D
+#define HCI_ENCRYPTION_CHANGE_EVT_V2 0x59
/* ULP HCI Event */
#define HCI_BLE_EVENT 0x3e
diff --git a/system/stack/include/l2c_api.h b/system/stack/include/l2c_api.h
deleted file mode 100644
index 790d6f5cac..0000000000
--- a/system/stack/include/l2c_api.h
+++ /dev/null
@@ -1,893 +0,0 @@
-/******************************************************************************
- *
- * Copyright 1999-2012 Broadcom Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- * this file contains the L2CAP API definitions
- *
- ******************************************************************************/
-#pragma once
-
-#include <bluetooth/log.h>
-#include <stdbool.h>
-
-#include <cstdint>
-#include <vector>
-
-#include "l2cdefs.h"
-#include "stack/include/bt_hdr.h"
-#include "stack/include/l2cap_interface.h"
-#include "stack/include/l2cap_types.h"
-#include "types/bt_transport.h"
-#include "types/hci_role.h"
-#include "types/raw_address.h"
-
-/*****************************************************************************
- * Constants
- ****************************************************************************/
-
-/* Define the minimum offset that L2CAP needs in a buffer. This is made up of
- * HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) => 9
- */
-#define L2CAP_MIN_OFFSET 13 /* plus control(2), SDU length(2) */
-
-#define L2CAP_LCC_SDU_LENGTH 2
-#define L2CAP_LCC_OFFSET (L2CAP_MIN_OFFSET + L2CAP_LCC_SDU_LENGTH) /* plus SDU length(2) */
-
-#define L2CAP_FCS_LENGTH 2
-
-/* Values for priority parameter to L2CA_SetTxPriority */
-#define L2CAP_CHNL_PRIORITY_HIGH 0
-#define L2CAP_CHNL_PRIORITY_LOW 2
-
-typedef uint8_t tL2CAP_CHNL_PRIORITY;
-
-/* Values for Tx/Rx data rate parameter to L2CA_SetChnlDataRate */
-#define L2CAP_CHNL_DATA_RATE_LOW 1
-
-typedef uint8_t tL2CAP_CHNL_DATA_RATE;
-
-/* Data Packet Flags (bits 2-15 are reserved) */
-/* layer specific 14-15 bits are used for FCR SAR */
-#define L2CAP_FLUSHABLE_MASK 0x0003
-#define L2CAP_FLUSHABLE_CH_BASED 0x0000
-#define L2CAP_FLUSHABLE_PKT 0x0001
-#define L2CAP_NON_FLUSHABLE_PKT 0x0002
-
-/* L2CA_FlushChannel num_to_flush definitions */
-#define L2CAP_FLUSH_CHANS_ALL 0xffff
-#define L2CAP_FLUSH_CHANS_GET 0x0000
-
-/* Values for 'allowed_modes' field passed in structure tL2CAP_ERTM_INFO
- */
-#define L2CAP_FCR_CHAN_OPT_BASIC (1 << L2CAP_FCR_BASIC_MODE)
-#define L2CAP_FCR_CHAN_OPT_ERTM (1 << L2CAP_FCR_ERTM_MODE)
-
-#define L2CAP_FCR_CHAN_OPT_ALL_MASK (L2CAP_FCR_CHAN_OPT_BASIC | L2CAP_FCR_CHAN_OPT_ERTM)
-
-/* Validity check for PSM. PSM values must be odd. Also, all PSM values must
- * be assigned such that the least significant bit of the most sigificant
- * octet equals zero.
- */
-#define L2C_INVALID_PSM(psm) (((psm) & 0x0101) != 0x0001)
-#define L2C_IS_VALID_PSM(psm) (((psm) & 0x0101) == 0x0001)
-#define L2C_IS_VALID_LE_PSM(psm) (((psm) > 0x0000) && ((psm) < 0x0100))
-
-#define L2CAP_NO_IDLE_TIMEOUT 0xFFFF
-
-/*****************************************************************************
- * Type Definitions
- ****************************************************************************/
-
-/* Values for service_type */
-#define SVC_TYPE_BEST_EFFORT 1
-#define SVC_TYPE_GUARANTEED 2
-
-// This is initial amout of credits we send, and amount to which we increase
-// credits once they fall below threshold
-uint16_t L2CA_LeCreditDefault();
-
-// If credit count on remote fall below this value, we send back credits to
-// reach default value.
-uint16_t L2CA_LeCreditThreshold();
-
-/*********************************
- * Callback Functions Prototypes
- *********************************/
-
-/* Connection indication callback prototype. Parameters are
- * BD Address of remote
- * Local CID assigned to the connection
- * PSM that the remote wants to connect to
- * Identifier that the remote sent
- */
-typedef void(tL2CA_CONNECT_IND_CB)(const RawAddress&, uint16_t, uint16_t, uint8_t);
-
-/* Connection confirmation callback prototype. Parameters are
- * Local CID
- * Result - 0 = connected
- * If there is an error, tL2CA_ERROR_CB is invoked
- */
-typedef void(tL2CA_CONNECT_CFM_CB)(uint16_t, tL2CAP_CONN);
-
-/* Configuration indication callback prototype. Parameters are
- * Local CID assigned to the connection
- * Pointer to configuration info
- */
-typedef void(tL2CA_CONFIG_IND_CB)(uint16_t, tL2CAP_CFG_INFO*);
-
-/* Configuration confirm callback prototype. Parameters are
- * Local CID assigned to the connection
- * Initiator (1 for local, 0 for remote)
- * Initial config from remote
- * If there is an error, tL2CA_ERROR_CB is invoked
- */
-typedef void(tL2CA_CONFIG_CFM_CB)(uint16_t, uint16_t, tL2CAP_CFG_INFO*);
-
-/* Disconnect indication callback prototype. Parameters are
- * Local CID
- * Boolean whether upper layer should ack this
- */
-typedef void(tL2CA_DISCONNECT_IND_CB)(uint16_t, bool);
-
-/* Disconnect confirm callback prototype. Parameters are
- * Local CID
- * Result
- */
-typedef void(tL2CA_DISCONNECT_CFM_CB)(uint16_t, uint16_t);
-
-/* Disconnect confirm callback prototype. Parameters are
- * Local CID
- * Result
- */
-typedef void(tL2CA_DATA_IND_CB)(uint16_t, BT_HDR*);
-
-/* Congestion status callback protype. This callback is optional. If
- * an application tries to send data when the transmit queue is full,
- * the data will anyways be dropped. The parameter is:
- * Local CID
- * true if congested, false if uncongested
- */
-typedef void(tL2CA_CONGESTION_STATUS_CB)(uint16_t, bool);
-
-/* Transmit complete callback protype. This callback is optional. If
- * set, L2CAP will call it when packets are sent or flushed. If the
- * count is 0xFFFF, it means all packets are sent for that CID (eRTM
- * mode only). The parameters are:
- * Local CID
- * Number of SDUs sent or dropped
- */
-typedef void(tL2CA_TX_COMPLETE_CB)(uint16_t, uint16_t);
-
-/*
- * Notify the user when the remote send error result on ConnectRsp or ConfigRsp
- * The parameters are:
- * Local CID
- * Error type (L2CAP_CONN_OTHER_ERROR for ConnectRsp,
- * L2CAP_CFG_FAILED_NO_REASON for ConfigRsp)
- */
-typedef void(tL2CA_ERROR_CB)(uint16_t, uint16_t);
-
-/* Create credit based connection request callback prototype. Parameters are
- * BD Address of remote
- * Vector of allocated local cids to accept
- * PSM
- * Peer MTU
- * Identifier that the remote sent
- */
-typedef void(tL2CA_CREDIT_BASED_CONNECT_IND_CB)(const RawAddress& bdaddr,
- std::vector<uint16_t>& lcids, uint16_t psm,
- uint16_t peer_mtu, uint8_t identifier);
-
-/* Collision Indication callback prototype. Used to notify upper layer that
- * remote devices sent Credit Based Connection Request but it was rejected due
- * to ongoing local request. Upper layer might want to sent another request when
- * local request is completed. Parameters are:
- * BD Address of remote
- */
-typedef void(tL2CA_CREDIT_BASED_COLLISION_IND_CB)(const RawAddress& bdaddr);
-
-/* Credit based connection confirmation callback prototype. Parameters are
- * BD Address of remote
- * Connected Local CIDs
- * Peer MTU
- * Result - 0 = connected, non-zero means CID is not connected
- */
-typedef void(tL2CA_CREDIT_BASED_CONNECT_CFM_CB)(const RawAddress& bdaddr, uint16_t lcid,
- uint16_t peer_mtu, tL2CAP_LE_RESULT_CODE result);
-
-/* Credit based reconfiguration confirm callback prototype. Parameters are
- * BD Address of remote
- * Local CID assigned to the connection
- * Flag indicating if this is local or peer configuration
- * Pointer to configuration info
- */
-typedef void(tL2CA_CREDIT_BASED_RECONFIG_COMPLETED_CB)(const RawAddress& bdaddr, uint16_t lcid,
- bool is_local_cfg,
- tL2CAP_LE_CFG_INFO* p_cfg);
-
-/*****************************************************************************
- * External Function Declarations
- ****************************************************************************/
-
-// Also does security for you
-[[nodiscard]] uint16_t L2CA_RegisterWithSecurity(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
- bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
- uint16_t my_mtu, uint16_t required_remote_mtu,
- uint16_t sec_level);
-
-/*******************************************************************************
- *
- * Function L2CA_Register
- *
- * Description Other layers call this function to register for L2CAP
- * services.
- *
- * Returns PSM to use or zero if error. Typically, the PSM returned
- * is the same as was passed in, but for an outgoing-only
- * connection to a dynamic PSM, a "virtual" PSM is returned
- * and should be used in the calls to L2CA_ConnectReq() and
- * BTM_SetSecurityLevel().
- *
- ******************************************************************************/
-[[nodiscard]] uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
- bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
- uint16_t my_mtu, uint16_t required_remote_mtu,
- uint16_t sec_level);
-
-/*******************************************************************************
- *
- * Function L2CA_Deregister
- *
- * Description Other layers call this function to deregister for L2CAP
- * services.
- *
- * Returns void
- *
- ******************************************************************************/
-void L2CA_Deregister(uint16_t psm);
-
-/*******************************************************************************
- *
- * Function L2CA_AllocateLePSM
- *
- * Description Other layers call this function to find an unused LE PSM for
- * L2CAP services.
- *
- * Returns LE_PSM to use if success. Otherwise returns 0.
- *
- ******************************************************************************/
-[[nodiscard]] uint16_t L2CA_AllocateLePSM(void);
-
-/*******************************************************************************
- *
- * Function L2CA_FreeLePSM
- *
- * Description Free an assigned LE PSM.
- *
- * Returns void
- *
- ******************************************************************************/
-void L2CA_FreeLePSM(uint16_t psm);
-
-[[nodiscard]] uint16_t L2CA_ConnectReqWithSecurity(uint16_t psm, const RawAddress& p_bd_addr,
- uint16_t sec_level);
-/*******************************************************************************
- *
- * Function L2CA_ConnectReq
- *
- * Description Higher layers call this function to create an L2CAP
- * connection.
- * Note that the connection is not established at this time,
- * but connection establishment gets started. The callback
- * will be invoked when connection establishes or fails.
- *
- * Returns the CID of the connection, or 0 if it failed to start
- *
- ******************************************************************************/
-[[nodiscard]] uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr);
-
-/*******************************************************************************
- *
- * Function L2CA_RegisterLECoc
- *
- * Description Other layers call this function to register for L2CAP
- * Connection Oriented Channel.
- *
- * Returns PSM to use or zero if error. Typically, the PSM returned
- * is the same as was passed in, but for an outgoing-only
- * connection to a dynamic PSM, a "virtual" PSM is returned
- * and should be used in the calls to L2CA_ConnectLECocReq()
- * and BTM_SetSecurityLevel().
- *
- ******************************************************************************/
-[[nodiscard]] uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
- uint16_t sec_level, tL2CAP_LE_CFG_INFO cfg);
-
-/*******************************************************************************
- *
- * Function L2CA_DeregisterLECoc
- *
- * Description Other layers call this function to deregister for L2CAP
- * Connection Oriented Channel.
- *
- * Returns void
- *
- ******************************************************************************/
-void L2CA_DeregisterLECoc(uint16_t psm);
-
-/*******************************************************************************
- *
- * Function L2CA_ConnectLECocReq
- *
- * Description Higher layers call this function to create an L2CAP LE COC.
- * Note that the connection is not established at this time,
- * but connection establishment gets started. The callback
- * will be invoked when connection establishes or fails.
- *
- * Returns the CID of the connection, or 0 if it failed to start
- *
- ******************************************************************************/
-[[nodiscard]] uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr,
- tL2CAP_LE_CFG_INFO* p_cfg, uint16_t sec_level);
-
-/*******************************************************************************
- *
- * Function L2CA_GetPeerLECocConfig
- *
- * Description Get peers configuration for LE Connection Oriented Channel.
- *
- * Return value: true if peer is connected
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_GetPeerLECocConfig(uint16_t lcid, tL2CAP_LE_CFG_INFO* peer_cfg);
-
-/*******************************************************************************
- *
- * Function L2CA_GetPeerLECocCredit
- *
- * Description Get peers current credit for LE Connection Oriented
- * Channel.
- *
- * Return value: Number of the peer current credit
- *
- ******************************************************************************/
-[[nodiscard]] uint16_t L2CA_GetPeerLECocCredit(const RawAddress& bd_addr, uint16_t lcid);
-
-/*******************************************************************************
- *
- * Function L2CA_ReconfigCreditBasedConnsReq
- *
- * Description Start reconfigure procedure on Connection Oriented Channel.
- *
- * Return value: true if peer is connected
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& bd_addr,
- std::vector<uint16_t>& lcids,
- tL2CAP_LE_CFG_INFO* p_cfg);
-
-/*******************************************************************************
- *
- * Function L2CA_ConnectCreditBasedReq
- *
- * Description With this function L2CAP will initiate setup of up to 5 credit
- * based connections for given psm using provided configuration.
- * L2CAP will notify user on the connection result, by calling
- * pL2CA_CreditBasedConnectCfm_Cb for each cid with a result.
- *
- * Return value: vector of allocated local cids for the connection
- *
- ******************************************************************************/
-
-[[nodiscard]] std::vector<uint16_t> L2CA_ConnectCreditBasedReq(uint16_t psm,
- const RawAddress& p_bd_addr,
- tL2CAP_LE_CFG_INFO* p_cfg);
-
-/*******************************************************************************
- *
- * Function L2CA_ConnectCreditBasedRsp
- *
- * Description Response for the pL2CA_CreditBasedConnectInd_Cb which is the
- * indication for peer requesting credit based connection.
- *
- * Return value: true if peer is connected
- *
- ******************************************************************************/
-
-[[nodiscard]] bool L2CA_ConnectCreditBasedRsp(const RawAddress& p_bd_addr, uint8_t id,
- std::vector<uint16_t>& accepted_lcids,
- tL2CAP_LE_RESULT_CODE result,
- tL2CAP_LE_CFG_INFO* p_cfg);
-/*******************************************************************************
- *
- * Function L2CA_DisconnectReq
- *
- * Description Higher layers call this function to disconnect a channel.
- *
- * Returns true if disconnect sent, else false
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_DisconnectReq(uint16_t cid);
-
-[[nodiscard]] bool L2CA_DisconnectLECocReq(uint16_t cid);
-
-/*******************************************************************************
- *
- * Function L2CA_DataWrite
- *
- * Description Higher layers call this function to write data.
- *
- * Returns tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted, else
- * false
- * tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED, if data accepted and
- * the channel is congested
- * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error
- *
- ******************************************************************************/
-[[nodiscard]] tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data);
-
-[[nodiscard]] tL2CAP_DW_RESULT L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data);
-
-/*******************************************************************************
- *
- * Function L2CA_GetRemoteChannelId
- *
- * Description Given a local channel identifier, |lcid|, this function
- * returns the bound remote channel identifier, |rcid|. If
- * |lcid| is not known or is invalid, this function returns
- * false and does not modify the value pointed at by |rcid|.
- *
- * Parameters: lcid: Local CID
- * rcid: Pointer to remote CID must NOT be nullptr
- *
- * Return value: true if rcid lookup was successful
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_GetRemoteChannelId(uint16_t lcid, uint16_t* rcid);
-
-/*******************************************************************************
- *
- * Function L2CA_SetIdleTimeoutByBdAddr
- *
- * Description Higher layers call this function to set the idle timeout for
- * a connection. The "idle timeout" is the amount of time that
- * a connection can remain up with no L2CAP channels on it.
- * A timeout of zero means that the connection will be torn
- * down immediately when the last channel is removed.
- * A timeout of 0xFFFF means no timeout. Values are in seconds.
- * A bd_addr is the remote BD address. If bd_addr =
- * RawAddress::kAny, then the idle timeouts for all active
- * l2cap links will be changed.
- *
- * Returns true if command succeeded, false if failed
- *
- * NOTE This timeout applies to all logical channels active on the
- * ACL link.
- ******************************************************************************/
-[[nodiscard]] bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout,
- tBT_TRANSPORT transport);
-
-/*******************************************************************************
- *
- * Function L2CA_FlushChannel
- *
- * Description This function flushes none, some or all buffers queued up
- * for xmission for a particular CID. If called with
- * L2CAP_FLUSH_CHANS_GET (0), it simply returns the number
- * of buffers queued for that CID L2CAP_FLUSH_CHANS_ALL (0xffff)
- * flushes all buffers. All other values specifies the maximum
- * buffers to flush.
- *
- * Returns Number of buffers left queued for that CID
- *
- ******************************************************************************/
-[[nodiscard]] uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush);
-
-/*******************************************************************************
- *
- * Function L2CA_UseLatencyMode
- *
- * Description Sets use latency mode for an ACL channel.
- *
- * Returns true if a valid channel, else false
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_UseLatencyMode(const RawAddress& bd_addr, bool use_latency_mode);
-
-/*******************************************************************************
- *
- * Function L2CA_SetAclPriority
- *
- * Description Sets the transmission priority for an ACL channel.
- * (For initial implementation only two values are valid.
- * L2CAP_PRIORITY_NORMAL and L2CAP_PRIORITY_HIGH).
- *
- * Returns true if a valid channel, else false
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority);
-
-/*******************************************************************************
- *
- * Function L2CA_SetAclLatency
- *
- * Description Sets the transmission latency for a channel.
- *
- * Returns true if a valid channel, else false
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_SetAclLatency(const RawAddress& bd_addr, tL2CAP_LATENCY latency);
-
-/*******************************************************************************
- *
- * Function L2CA_SetTxPriority
- *
- * Description Sets the transmission priority for a channel. (FCR Mode)
- *
- * Returns true if a valid channel, else false
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority);
-
-/*******************************************************************************
- *
- * Function L2CA_SetChnlFlushability
- *
- * Description Higher layers call this function to set a channels
- * flushability flags
- *
- * Returns true if CID found, else false
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable);
-
-/*******************************************************************************
- *
- * Function L2CA_GetPeerFeatures
- *
- * Description Get a peers features and fixed channel map
- *
- * Parameters: BD address of the peer
- * Pointers to features and channel mask storage area
- *
- * Return value: true if peer is connected
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat,
- uint8_t* p_chnl_mask);
-
-/*******************************************************************************
- *
- * Fixed Channel callback prototypes
- *
- ******************************************************************************/
-
-/* Fixed channel connected and disconnected. Parameters are
- * channel
- * BD Address of remote
- * true if channel is connected, false if disconnected
- * Reason for connection failure
- * transport : physical transport, BR/EDR or LE
- */
-typedef void(tL2CA_FIXED_CHNL_CB)(uint16_t, const RawAddress&, bool, uint16_t, tBT_TRANSPORT);
-
-/* Signalling data received. Parameters are
- * channel
- * BD Address of remote
- * Pointer to buffer with data
- */
-typedef void(tL2CA_FIXED_DATA_CB)(uint16_t, const RawAddress&, BT_HDR*);
-
-/* Congestion status callback protype. This callback is optional. If
- * an application tries to send data when the transmit queue is full,
- * the data will anyways be dropped. The parameter is:
- * remote BD_ADDR
- * true if congested, false if uncongested
- */
-typedef void(tL2CA_FIXED_CONGESTION_STATUS_CB)(const RawAddress&, bool);
-
-/*******************************************************************************
- *
- * Function L2CA_RegisterFixedChannel
- *
- * Description Register a fixed channel.
- *
- * Parameters: Fixed Channel #
- * Channel Callbacks and config
- *
- * Return value: true if registered OK
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_RegisterFixedChannel(uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg);
-
-/*******************************************************************************
- *
- * Function L2CA_ConnectFixedChnl
- *
- * Description Connect an fixed signalling channel to a remote device.
- *
- * Parameters: Fixed CID
- * BD Address of remote
- *
- * Return value: true if connection started
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& bd_addr);
-
-/*******************************************************************************
- *
- * Function L2CA_SendFixedChnlData
- *
- * Description Write data on a fixed signalling channel.
- *
- * Parameters: Fixed CID
- * BD Address of remote
- * Pointer to buffer of type BT_HDR
- *
- * Return value tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted
- * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error
- *
- ******************************************************************************/
-[[nodiscard]] tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda,
- BT_HDR* p_buf);
-
-/*******************************************************************************
- *
- * Function L2CA_RemoveFixedChnl
- *
- * Description Remove a fixed channel to a remote device.
- *
- * Parameters: Fixed CID
- * BD Address of remote
- *
- * Return value: true if channel removed or marked for removal
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda);
-
-/*******************************************************************************
- *
- * Function L2CA_SetLeGattTimeout
- *
- * Description Higher layers call this function to set the idle timeout for
- * a fixed channel. The "idle timeout" is the amount of time
- * that a connection can remain up with no L2CAP channels on
- * it. A timeout of zero means that the connection will be torn
- * down immediately when the last channel is removed.
- * A timeout of 0xFFFF means no timeout. Values are in seconds.
- * A bd_addr is the remote BD address. If bd_addr =
- * RawAddress::kAny, then the idle timeouts for all active
- * l2cap links will be changed.
- *
- * Returns true if command succeeded, false if failed
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_SetLeGattTimeout(const RawAddress& rem_bda, uint16_t idle_tout);
-
-[[nodiscard]] bool L2CA_MarkLeLinkAsActive(const RawAddress& rem_bda);
-
-[[nodiscard]] bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int,
- uint16_t max_int, uint16_t latency, uint16_t timeout,
- uint16_t min_ce_len, uint16_t max_ce_len);
-
-/* When called with lock=true, LE connection parameters will be locked on
- * fastest value, and we won't accept request to change it from remote. When
- * called with lock=false, parameters are relaxed.
- */
-void L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress& rem_bda, bool lock);
-
-/* When called with lock=true, LE connection parameters will be locked on
- * fastest value, and we won't accept request to change it from remote. When
- * called with lock=false, parameters are relaxed.
- */
-void L2CA_LockBleConnParamsForProfileConnection(const RawAddress& rem_bda, bool lock);
-
-/*******************************************************************************
- *
- * Function L2CA_GetBleConnRole
- *
- * Description This function returns the connection role.
- *
- * Returns link role.
- *
- ******************************************************************************/
-void L2CA_Consolidate(const RawAddress& identity_addr, const RawAddress& rpa);
-[[nodiscard]] tHCI_ROLE L2CA_GetBleConnRole(const RawAddress& bd_addr);
-
-void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, uint16_t* max_interval,
- uint16_t floor_interval);
-
-void L2CA_SetEcosystemBaseInterval(uint32_t base_interval);
-
-/**
- * Check whether an ACL or LE link to the remote device is established
- */
-[[nodiscard]] bool L2CA_IsLinkEstablished(const RawAddress& bd_addr, tBT_TRANSPORT transport);
-
-/*******************************************************************************
- *
- * Function L2CA_SetDefaultSubrate
- *
- * Description BLE Set Default Subrate.
- *
- * Parameters: Subrate parameters
- *
- * Return value: void
- *
- ******************************************************************************/
-void L2CA_SetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency,
- uint16_t cont_num, uint16_t timeout);
-
-/*******************************************************************************
- *
- * Function L2CA_SubrateRequest
- *
- * Description BLE Subrate request.
- *
- * Parameters: Subrate parameters
- *
- * Return value: true if update started
- *
- ******************************************************************************/
-[[nodiscard]] bool L2CA_SubrateRequest(const RawAddress& rem_bda, uint16_t subrate_min,
- uint16_t subrate_max, uint16_t max_latency,
- uint16_t cont_num, uint16_t timeout);
-
-/*******************************************************************************
-**
-** Function L2CA_SetMediaStreamChannel
-**
-** Description This function is called to set/reset the ccb of active media
-** streaming channel
-**
-** Parameters: local_media_cid: The local cid provided to A2DP to be used
-** for streaming
-** status: The status of media streaming on this channel
-**
-** Returns void
-**
-*******************************************************************************/
-void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status);
-
-/*******************************************************************************
-**
-** Function L2CA_isMediaChannel
-**
-** Description This function returns if the channel id passed as parameter
-** is an A2DP streaming channel
-**
-** Parameters: handle: Connection handle with the remote device
-** channel_id: Channel ID
-** is_local_cid: Signifies if the channel id passed is local
-** cid or remote cid (true if local, remote otherwise)
-**
-** Returns bool
-**
-*******************************************************************************/
-[[nodiscard]] bool L2CA_isMediaChannel(uint16_t handle, uint16_t channel_id, bool is_local_cid);
-
-namespace bluetooth {
-namespace stack {
-namespace l2cap {
-
-class Impl : public Interface {
-public:
- virtual ~Impl() = default;
-
- // Lifecycle methods to register BR/EDR l2cap services
- [[nodiscard]] uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
- bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
- uint16_t my_mtu, uint16_t required_remote_mtu,
- uint16_t sec_level) override;
- [[nodiscard]] uint16_t L2CA_RegisterWithSecurity(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
- bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
- uint16_t my_mtu, uint16_t required_remote_mtu,
- uint16_t sec_level) override;
- void L2CA_Deregister(uint16_t psm) override;
-
- // Lifecycle methods to register BLE l2cap services
- [[nodiscard]] uint16_t L2CA_AllocateLePSM(void) override;
- void L2CA_FreeLePSM(uint16_t psm) override;
-
- [[nodiscard]] uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
- uint16_t sec_level, tL2CAP_LE_CFG_INFO cfg) override;
- void L2CA_DeregisterLECoc(uint16_t psm) override;
-
- // Methods used for both BR/EDR and BLE
- [[nodiscard]] bool L2CA_IsLinkEstablished(const RawAddress& bd_addr,
- tBT_TRANSPORT transport) override;
- [[nodiscard]] bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout,
- tBT_TRANSPORT transport) override;
- [[nodiscard]] bool L2CA_GetRemoteChannelId(uint16_t lcid, uint16_t* rcid) override;
-
- // Connection methods to configure and connect to peer over BR/EDR ACL
- [[nodiscard]] uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& bd_addr) override;
- [[nodiscard]] uint16_t L2CA_ConnectReqWithSecurity(uint16_t psm, const RawAddress& bd_addr,
- uint16_t sec_level) override;
- [[nodiscard]] bool L2CA_SetAclLatency(const RawAddress& bd_addr, tL2CAP_LATENCY latency) override;
- [[nodiscard]] bool L2CA_UseLatencyMode(const RawAddress& bd_addr, bool use_latency_mode) override;
- [[nodiscard]] bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat,
- uint8_t* p_chnl_mask) override;
- [[nodiscard]] bool L2CA_SetAclPriority(const RawAddress& bd_addr,
- tL2CAP_PRIORITY priority) override;
- void L2CA_SetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency,
- uint16_t cont_num, uint16_t timeout) override;
- void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, uint16_t* max_interval,
- uint16_t floor_interval) override;
- void L2CA_SetEcosystemBaseInterval(uint32_t base_interval) override;
-
- [[nodiscard]] bool L2CA_SubrateRequest(const RawAddress& bd_addr, uint16_t subrate_min,
- uint16_t subrate_max, uint16_t max_latency,
- uint16_t cont_num, uint16_t timeout) override;
- [[nodiscard]] uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) override;
- [[nodiscard]] bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) override;
- [[nodiscard]] bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) override;
-
- // Connection methods to configure and connect to peer over BLE ACL
- [[nodiscard]] uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& bd_addr,
- tL2CAP_LE_CFG_INFO* p_cfg,
- uint16_t sec_level) override;
- [[nodiscard]] std::vector<uint16_t> L2CA_ConnectCreditBasedReq(
- uint16_t psm, const RawAddress& bd_addr, tL2CAP_LE_CFG_INFO* p_cfg) override;
- [[nodiscard]] bool L2CA_ConnectCreditBasedRsp(const RawAddress& bd_addr, uint8_t id,
- std::vector<uint16_t>& accepted_lcids,
- tL2CAP_LE_RESULT_CODE result,
- tL2CAP_LE_CFG_INFO* p_cfg) override;
- [[nodiscard]] uint16_t L2CA_GetPeerLECocCredit(const RawAddress& bd_addr, uint16_t lcid) override;
- [[nodiscard]] bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& bd_addr,
- std::vector<uint16_t>& lcids,
- tL2CAP_LE_CFG_INFO* p_cfg) override;
- [[nodiscard]] bool L2CA_UpdateBleConnParams(const RawAddress& bd_addr, uint16_t min_int,
- uint16_t max_int, uint16_t latency, uint16_t timeout,
- uint16_t min_ce_len, uint16_t max_ce_len) override;
- void L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress& bd_addr, bool lock) override;
- void L2CA_LockBleConnParamsForProfileConnection(const RawAddress& bd_addr, bool lock) override;
- [[nodiscard]] tHCI_ROLE L2CA_GetBleConnRole(const RawAddress& bd_addr) override;
- [[nodiscard]] bool L2CA_SetLeGattTimeout(const RawAddress& bd_addr, uint16_t idle_tout) override;
- [[nodiscard]] bool L2CA_MarkLeLinkAsActive(const RawAddress& bd_addr) override;
- [[nodiscard]] bool L2CA_GetPeerLECocConfig(uint16_t lcid, tL2CAP_LE_CFG_INFO* peer_cfg) override;
- // Method to consolidate two BLE addresses into a single device
- void L2CA_Consolidate(const RawAddress& identity_addr, const RawAddress& rpa) override;
-
- // Disconnect methods an active connection for both BR/EDR and BLE
- [[nodiscard]] bool L2CA_DisconnectReq(uint16_t cid) override;
- [[nodiscard]] bool L2CA_DisconnectLECocReq(uint16_t cid) override;
-
- // Data write methods for both BR/EDR and BLE
- [[nodiscard]] tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) override;
- [[nodiscard]] tL2CAP_DW_RESULT L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) override;
-
- // Fixed channel methods
- [[nodiscard]] bool L2CA_RegisterFixedChannel(uint16_t fixed_cid,
- tL2CAP_FIXED_CHNL_REG* p_freg) override;
- [[nodiscard]] bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& bd_addr) override;
- [[nodiscard]] tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid,
- const RawAddress& bd_addr,
- BT_HDR* p_buf) override;
- [[nodiscard]] bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& bd_addr) override;
-
- // Media methods
- void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) override;
- [[nodiscard]] bool L2CA_isMediaChannel(uint16_t handle, uint16_t channel_id,
- bool is_local_cid) override;
-};
-
-} // namespace l2cap
-} // namespace stack
-} // namespace bluetooth
diff --git a/system/stack/include/sec_hci_link_interface.h b/system/stack/include/sec_hci_link_interface.h
index eb142adfa4..0612f1b1e3 100644
--- a/system/stack/include/sec_hci_link_interface.h
+++ b/system/stack/include/sec_hci_link_interface.h
@@ -33,8 +33,10 @@ void btm_read_local_oob_complete(const tBTM_SP_LOC_OOB evt_data);
void btm_rem_oob_req(const RawAddress bd_addr);
void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status);
void btm_sec_disconnected(uint16_t handle, tHCI_STATUS reason, std::string);
-void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable);
-void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable);
+void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable,
+ uint8_t key_size, bool from_key_refresh = false);
+void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable,
+ uint8_t key_size);
void btm_sec_encryption_key_refresh_complete(uint16_t handle, tHCI_STATUS status);
void btm_sec_link_key_notification(const RawAddress& p_bda, const Octet16& link_key,
uint8_t key_type);
diff --git a/system/stack/l2cap/internal/l2c_api.h b/system/stack/l2cap/internal/l2c_api.h
index 06741bed8f..6f65f81d71 100644
--- a/system/stack/l2cap/internal/l2c_api.h
+++ b/system/stack/l2cap/internal/l2c_api.h
@@ -40,11 +40,6 @@
* Constants
****************************************************************************/
-/* Define the minimum offset that L2CAP needs in a buffer. This is made up of
- * HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) => 9
- */
-#define L2CAP_MIN_OFFSET 13 /* plus control(2), SDU length(2) */
-
#define L2CAP_LCC_SDU_LENGTH 2
#define L2CAP_LCC_OFFSET (L2CAP_MIN_OFFSET + L2CAP_LCC_SDU_LENGTH) /* plus SDU length(2) */
@@ -410,10 +405,11 @@ void L2CA_DeregisterLECoc(uint16_t psm);
* Return value: true if peer is connected
*
******************************************************************************/
-
[[nodiscard]] bool L2CA_ConnectCreditBasedRsp(const RawAddress& p_bd_addr, uint8_t id,
std::vector<uint16_t>& accepted_lcids,
- uint16_t result, tL2CAP_LE_CFG_INFO* p_cfg);
+ tL2CAP_LE_RESULT_CODE result,
+ tL2CAP_LE_CFG_INFO* p_cfg);
+
/*******************************************************************************
*
* Function L2CA_DisconnectReq
diff --git a/system/stack/l2cap/l2c_api.h b/system/stack/l2cap/l2c_api.h
new file mode 100644
index 0000000000..f645803dad
--- /dev/null
+++ b/system/stack/l2cap/l2c_api.h
@@ -0,0 +1,140 @@
+/******************************************************************************
+ *
+ * Copyright 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#pragma once
+
+#include <bluetooth/log.h>
+#include <stdbool.h>
+
+#include <cstdint>
+#include <vector>
+
+#include "stack/include/bt_hdr.h"
+#include "stack/include/l2cap_interface.h"
+#include "types/bt_transport.h"
+#include "types/hci_role.h"
+#include "types/raw_address.h"
+
+namespace bluetooth {
+namespace stack {
+namespace l2cap {
+
+class Impl : public Interface {
+public:
+ virtual ~Impl() = default;
+
+ // Lifecycle methods to register BR/EDR l2cap services
+ [[nodiscard]] uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
+ bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
+ uint16_t my_mtu, uint16_t required_remote_mtu,
+ uint16_t sec_level) override;
+ [[nodiscard]] uint16_t L2CA_RegisterWithSecurity(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
+ bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
+ uint16_t my_mtu, uint16_t required_remote_mtu,
+ uint16_t sec_level) override;
+ void L2CA_Deregister(uint16_t psm) override;
+
+ // Lifecycle methods to register BLE l2cap services
+ [[nodiscard]] uint16_t L2CA_AllocateLePSM(void) override;
+ void L2CA_FreeLePSM(uint16_t psm) override;
+
+ [[nodiscard]] uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
+ uint16_t sec_level, tL2CAP_LE_CFG_INFO cfg) override;
+ void L2CA_DeregisterLECoc(uint16_t psm) override;
+
+ // Methods used for both BR/EDR and BLE
+ [[nodiscard]] bool L2CA_IsLinkEstablished(const RawAddress& bd_addr,
+ tBT_TRANSPORT transport) override;
+ [[nodiscard]] bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout,
+ tBT_TRANSPORT transport) override;
+ [[nodiscard]] bool L2CA_GetRemoteChannelId(uint16_t lcid, uint16_t* rcid) override;
+
+ // Connection methods to configure and connect to peer over BR/EDR ACL
+ [[nodiscard]] uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& bd_addr) override;
+ [[nodiscard]] uint16_t L2CA_ConnectReqWithSecurity(uint16_t psm, const RawAddress& bd_addr,
+ uint16_t sec_level) override;
+ [[nodiscard]] bool L2CA_SetAclLatency(const RawAddress& bd_addr, tL2CAP_LATENCY latency) override;
+ [[nodiscard]] bool L2CA_UseLatencyMode(const RawAddress& bd_addr, bool use_latency_mode) override;
+ [[nodiscard]] bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat,
+ uint8_t* p_chnl_mask) override;
+ [[nodiscard]] bool L2CA_SetAclPriority(const RawAddress& bd_addr,
+ tL2CAP_PRIORITY priority) override;
+ void L2CA_SetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency,
+ uint16_t cont_num, uint16_t timeout) override;
+ void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, uint16_t* max_interval,
+ uint16_t floor_interval) override;
+ void L2CA_SetEcosystemBaseInterval(uint32_t base_interval) override;
+
+ [[nodiscard]] bool L2CA_SubrateRequest(const RawAddress& bd_addr, uint16_t subrate_min,
+ uint16_t subrate_max, uint16_t max_latency,
+ uint16_t cont_num, uint16_t timeout) override;
+ [[nodiscard]] uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) override;
+ [[nodiscard]] bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) override;
+ [[nodiscard]] bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) override;
+
+ // Connection methods to configure and connect to peer over BLE ACL
+ [[nodiscard]] uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& bd_addr,
+ tL2CAP_LE_CFG_INFO* p_cfg,
+ uint16_t sec_level) override;
+ [[nodiscard]] std::vector<uint16_t> L2CA_ConnectCreditBasedReq(
+ uint16_t psm, const RawAddress& bd_addr, tL2CAP_LE_CFG_INFO* p_cfg) override;
+ [[nodiscard]] bool L2CA_ConnectCreditBasedRsp(const RawAddress& bd_addr, uint8_t id,
+ std::vector<uint16_t>& accepted_lcids,
+ tL2CAP_LE_RESULT_CODE result,
+ tL2CAP_LE_CFG_INFO* p_cfg) override;
+ [[nodiscard]] uint16_t L2CA_GetPeerLECocCredit(const RawAddress& bd_addr, uint16_t lcid) override;
+ [[nodiscard]] bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& bd_addr,
+ std::vector<uint16_t>& lcids,
+ tL2CAP_LE_CFG_INFO* p_cfg) override;
+ [[nodiscard]] bool L2CA_UpdateBleConnParams(const RawAddress& bd_addr, uint16_t min_int,
+ uint16_t max_int, uint16_t latency, uint16_t timeout,
+ uint16_t min_ce_len, uint16_t max_ce_len) override;
+ void L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress& bd_addr, bool lock) override;
+ void L2CA_LockBleConnParamsForProfileConnection(const RawAddress& bd_addr, bool lock) override;
+ [[nodiscard]] tHCI_ROLE L2CA_GetBleConnRole(const RawAddress& bd_addr) override;
+ [[nodiscard]] bool L2CA_SetLeGattTimeout(const RawAddress& bd_addr, uint16_t idle_tout) override;
+ [[nodiscard]] bool L2CA_MarkLeLinkAsActive(const RawAddress& bd_addr) override;
+ [[nodiscard]] bool L2CA_GetPeerLECocConfig(uint16_t lcid, tL2CAP_LE_CFG_INFO* peer_cfg) override;
+ // Method to consolidate two BLE addresses into a single device
+ void L2CA_Consolidate(const RawAddress& identity_addr, const RawAddress& rpa) override;
+
+ // Disconnect methods an active connection for both BR/EDR and BLE
+ [[nodiscard]] bool L2CA_DisconnectReq(uint16_t cid) override;
+ [[nodiscard]] bool L2CA_DisconnectLECocReq(uint16_t cid) override;
+
+ // Data write methods for both BR/EDR and BLE
+ [[nodiscard]] tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) override;
+ [[nodiscard]] tL2CAP_DW_RESULT L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) override;
+
+ // Fixed channel methods
+ [[nodiscard]] bool L2CA_RegisterFixedChannel(uint16_t fixed_cid,
+ tL2CAP_FIXED_CHNL_REG* p_freg) override;
+ [[nodiscard]] bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& bd_addr) override;
+ [[nodiscard]] tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid,
+ const RawAddress& bd_addr,
+ BT_HDR* p_buf) override;
+ [[nodiscard]] bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& bd_addr) override;
+
+ // Media methods
+ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) override;
+ [[nodiscard]] bool L2CA_isMediaChannel(uint16_t handle, uint16_t channel_id,
+ bool is_local_cid) override;
+};
+
+} // namespace l2cap
+} // namespace stack
+} // namespace bluetooth
diff --git a/system/stack/l2cap/l2c_ble.cc b/system/stack/l2cap/l2c_ble.cc
index 261bcbb51e..ab18235791 100644
--- a/system/stack/l2cap/l2c_ble.cc
+++ b/system/stack/l2cap/l2c_ble.cc
@@ -50,7 +50,6 @@
#include "stack/include/btm_client_interface.h"
#include "stack/include/btm_log_history.h"
#include "stack/include/btm_status.h"
-#include "stack/include/l2c_api.h"
#include "stack/include/l2cap_acl_interface.h"
#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cdefs.h"
diff --git a/system/stack/l2cap/l2c_fcr.cc b/system/stack/l2cap/l2c_fcr.cc
index 6eadd80987..fdcbdb0506 100644
--- a/system/stack/l2cap/l2c_fcr.cc
+++ b/system/stack/l2cap/l2c_fcr.cc
@@ -31,8 +31,8 @@
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
-#include "stack/include/l2c_api.h"
#include "stack/include/l2cdefs.h"
+#include "stack/l2cap/internal/l2c_api.h"
#include "stack/l2cap/l2c_int.h"
/* Flag passed to retransmit_i_frames() when all packets should be retransmitted
diff --git a/system/stack/l2cap/l2c_link.cc b/system/stack/l2cap/l2c_link.cc
index a6257941b5..d9582b65c3 100644
--- a/system/stack/l2cap/l2c_link.cc
+++ b/system/stack/l2cap/l2c_link.cc
@@ -32,7 +32,6 @@
#include "device/include/device_iot_config.h"
#include "internal_include/bt_target.h"
-#include "l2c_api.h"
#include "osi/include/allocator.h"
#include "stack/btm/btm_int_types.h"
#include "stack/include/acl_api.h"
diff --git a/system/stack/l2cap/l2c_main.cc b/system/stack/l2cap/l2c_main.cc
index a2963483ee..9d5645e9c1 100644
--- a/system/stack/l2cap/l2c_main.cc
+++ b/system/stack/l2cap/l2c_main.cc
@@ -35,7 +35,6 @@
#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
#include "stack/include/hcimsgs.h" // HCID_GET_
-#include "stack/include/l2c_api.h"
#include "stack/include/l2cap_hci_link_interface.h"
#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cdefs.h"
diff --git a/system/stack/l2cap/l2c_utils.cc b/system/stack/l2cap/l2c_utils.cc
index 106e84e2fe..8e69744d82 100644
--- a/system/stack/l2cap/l2c_utils.cc
+++ b/system/stack/l2cap/l2c_utils.cc
@@ -43,7 +43,6 @@
#include "stack/include/btm_status.h"
#include "stack/include/hci_error_code.h"
#include "stack/include/hcidefs.h"
-#include "stack/include/l2c_api.h"
#include "stack/include/l2cap_acl_interface.h"
#include "stack/include/l2cap_hci_link_interface.h"
#include "stack/include/l2cap_interface.h"
diff --git a/system/stack/l2cap/l2cap_api.cc b/system/stack/l2cap/l2cap_api.cc
index 3b4159d786..94466c90e2 100644
--- a/system/stack/l2cap/l2cap_api.cc
+++ b/system/stack/l2cap/l2cap_api.cc
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-#include "stack/include/l2c_api.h"
#include "stack/include/l2cap_interface.h"
+#include "stack/l2cap/internal/l2c_api.h"
+#include "stack/l2cap/l2c_api.h"
static bluetooth::stack::l2cap::Impl l2cap_impl;
static bluetooth::stack::l2cap::Interface* interface_ = &l2cap_impl;
diff --git a/system/stack/rfcomm/rfc_ts_frames.cc b/system/stack/rfcomm/rfc_ts_frames.cc
index 7dfff833c6..b0b4b1c143 100644
--- a/system/stack/rfcomm/rfc_ts_frames.cc
+++ b/system/stack/rfcomm/rfc_ts_frames.cc
@@ -31,7 +31,6 @@
#include "os/logging/log_adapter.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
-#include "stack/include/l2c_api.h"
#include "stack/include/rfcdefs.h"
#include "stack/rfcomm/port_int.h"
#include "stack/rfcomm/rfc_int.h"
diff --git a/system/stack/smp/smp_api.cc b/system/stack/smp/smp_api.cc
index 247d5fdb19..4485bf3fcb 100644
--- a/system/stack/smp/smp_api.cc
+++ b/system/stack/smp/smp_api.cc
@@ -29,8 +29,6 @@
#include <bluetooth/log.h>
#include <string.h>
-#include "l2c_api.h"
-#include "l2cdefs.h"
#include "smp_int.h"
#include "stack/include/bt_octets.h"
#include "stack/include/btm_sec_api_types.h"
diff --git a/system/stack/test/btm/stack_btm_sec_test.cc b/system/stack/test/btm/stack_btm_sec_test.cc
index 812d1563cd..daa6bfbfb4 100644
--- a/system/stack/test/btm/stack_btm_sec_test.cc
+++ b/system/stack/test/btm/stack_btm_sec_test.cc
@@ -30,6 +30,7 @@
#include "stack/btm/btm_sec_cb.h"
#include "stack/btm/security_device_record.h"
#include "stack/include/btm_status.h"
+#include "stack/include/sec_hci_link_interface.h"
#include "stack/test/btm/btm_test_fixtures.h"
#include "test/mock/mock_main_shim_entry.h"
#include "types/raw_address.h"
@@ -118,18 +119,18 @@ TEST_F(StackBtmSecWithInitFreeTest, btm_sec_encrypt_change) {
// Check the collision conditionals
::btm_sec_cb.collision_start_time = 0UL;
- btm_sec_encrypt_change(classic_handle, HCI_ERR_LMP_ERR_TRANS_COLLISION, 0x01);
+ btm_sec_encrypt_change(classic_handle, HCI_ERR_LMP_ERR_TRANS_COLLISION, 0x01, 0x10);
uint64_t collision_start_time = ::btm_sec_cb.collision_start_time;
ASSERT_NE(0UL, collision_start_time);
::btm_sec_cb.collision_start_time = 0UL;
- btm_sec_encrypt_change(classic_handle, HCI_ERR_DIFF_TRANSACTION_COLLISION, 0x01);
+ btm_sec_encrypt_change(classic_handle, HCI_ERR_DIFF_TRANSACTION_COLLISION, 0x01, 0x10);
collision_start_time = ::btm_sec_cb.collision_start_time;
ASSERT_NE(0UL, collision_start_time);
// No device
::btm_sec_cb.collision_start_time = 0;
- btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x01);
+ btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x01, 0x10);
ASSERT_EQ(0UL, ::btm_sec_cb.collision_start_time);
// Setup device
@@ -141,21 +142,21 @@ TEST_F(StackBtmSecWithInitFreeTest, btm_sec_encrypt_change) {
device_record->ble_hci_handle = ble_handle;
// With classic device encryption enable
- btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x01);
+ btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x01, 0x10);
ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED,
device_record->sec_rec.sec_flags);
// With classic device encryption disable
- btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x00);
+ btm_sec_encrypt_change(classic_handle, HCI_SUCCESS, 0x00, 0x10);
ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_AUTHENTICATED, device_record->sec_rec.sec_flags);
device_record->sec_rec.sec_flags = BTM_SEC_IN_USE;
// With le device encryption enable
- btm_sec_encrypt_change(ble_handle, HCI_SUCCESS, 0x01);
+ btm_sec_encrypt_change(ble_handle, HCI_SUCCESS, 0x01, 0x10);
ASSERT_EQ(BTM_SEC_IN_USE | BTM_SEC_LE_ENCRYPTED, device_record->sec_rec.sec_flags);
// With le device encryption disable
- btm_sec_encrypt_change(ble_handle, HCI_SUCCESS, 0x00);
+ btm_sec_encrypt_change(ble_handle, HCI_SUCCESS, 0x00, 0x10);
ASSERT_EQ(BTM_SEC_IN_USE, device_record->sec_rec.sec_flags);
device_record->sec_rec.sec_flags = BTM_SEC_IN_USE;
diff --git a/system/stack/test/common/mock_l2cap_layer.h b/system/stack/test/common/mock_l2cap_layer.h
index 21a6038338..6c4f3ed4e7 100644
--- a/system/stack/test/common/mock_l2cap_layer.h
+++ b/system/stack/test/common/mock_l2cap_layer.h
@@ -22,7 +22,7 @@
#include <vector>
#include "stack/include/bt_hdr.h"
-#include "stack/include/l2c_api.h"
+#include "stack/include/l2cap_interface.h"
#include "types/raw_address.h"
namespace bluetooth {
diff --git a/system/stack/test/common/stack_test_packet_utils.cc b/system/stack/test/common/stack_test_packet_utils.cc
index 841d331a8a..e87f3cfc77 100644
--- a/system/stack/test/common/stack_test_packet_utils.cc
+++ b/system/stack/test/common/stack_test_packet_utils.cc
@@ -20,10 +20,9 @@
#include <bluetooth/log.h>
-#include "hci/include/hci_layer.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
-#include "stack/include/l2c_api.h"
+#include "stack/include/l2cap_types.h"
#include "stack/include/l2cdefs.h"
namespace bluetooth {
diff --git a/system/test/mock/mock_stack_btm_sec.cc b/system/test/mock/mock_stack_btm_sec.cc
index 3971582d81..4be4fe51cb 100644
--- a/system/test/mock/mock_stack_btm_sec.cc
+++ b/system/test/mock/mock_stack_btm_sec.cc
@@ -316,13 +316,16 @@ void btm_sec_disconnected(uint16_t handle, tHCI_REASON reason, std::string comme
inc_func_call_count(__func__);
test::mock::stack_btm_sec::btm_sec_disconnected(handle, reason, comment);
}
-void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable) {
+void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable,
+ uint8_t key_size, bool from_key_refresh) {
inc_func_call_count(__func__);
- test::mock::stack_btm_sec::btm_sec_encrypt_change(handle, status, encr_enable);
+ test::mock::stack_btm_sec::btm_sec_encrypt_change(handle, status, encr_enable, key_size,
+ from_key_refresh);
}
-void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable) {
+void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable,
+ uint8_t key_size) {
inc_func_call_count(__func__);
- test::mock::stack_btm_sec::btm_sec_encryption_change_evt(handle, status, encr_enable);
+ test::mock::stack_btm_sec::btm_sec_encryption_change_evt(handle, status, encr_enable, key_size);
}
bool btm_sec_is_a_bonded_dev(const RawAddress& bda) {
inc_func_call_count(__func__);
diff --git a/system/test/mock/mock_stack_btm_sec.h b/system/test/mock/mock_stack_btm_sec.h
index 7cb1354929..8f716f443b 100644
--- a/system/test/mock/mock_stack_btm_sec.h
+++ b/system/test/mock/mock_stack_btm_sec.h
@@ -553,25 +553,29 @@ struct btm_sec_disconnected {
extern struct btm_sec_disconnected btm_sec_disconnected;
// Name: btm_sec_encrypt_change
-// Params: uint16_t handle, tHCI_STATUS status, uint8_t encr_enable
-// Return: void
+// Params: uint16_t handle, tHCI_STATUS status, uint8_t encr_enable, uint8_t key_size, bool
+// from_key_refresh Return: void
struct btm_sec_encrypt_change {
- std::function<void(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable)> body{
- [](uint16_t /* handle */, tHCI_STATUS /* status */, uint8_t /* encr_enable */) {}};
- void operator()(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable) {
- body(handle, status, encr_enable);
+ std::function<void(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable, uint8_t key_size,
+ bool from_key_refresh)>
+ body{[](uint16_t /* handle */, tHCI_STATUS /* status */, uint8_t /* encr_enable */,
+ uint8_t /* key_size */, bool /* from_key_refresh */) {}};
+ void operator()(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable, uint8_t key_size,
+ bool from_key_refresh) {
+ body(handle, status, encr_enable, key_size, from_key_refresh);
}
};
extern struct btm_sec_encrypt_change btm_sec_encrypt_change;
// Name: btm_sec_encryption_change_evt
-// Params: uint16_t handle, tHCI_STATUS status, uint8_t encr_enable
+// Params: uint16_t handle, tHCI_STATUS status, uint8_t encr_enable, uint8_t key_size
// Return: void
struct btm_sec_encryption_change_evt {
- std::function<void(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable)> body{
- [](uint16_t /* handle */, tHCI_STATUS /* status */, uint8_t /* encr_enable */) {}};
- void operator()(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable) {
- body(handle, status, encr_enable);
+ std::function<void(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable, uint8_t key_size)>
+ body{[](uint16_t /* handle */, tHCI_STATUS /* status */, uint8_t /* encr_enable */,
+ uint8_t /* key_size */) {}};
+ void operator()(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable, uint8_t key_size) {
+ body(handle, status, encr_enable, key_size);
}
};
extern struct btm_sec_encryption_change_evt btm_sec_encryption_change_evt;
diff --git a/system/test/mock/mock_stack_gap_conn.cc b/system/test/mock/mock_stack_gap_conn.cc
index f38bb97588..0ef505d14a 100644
--- a/system/test/mock/mock_stack_gap_conn.cc
+++ b/system/test/mock/mock_stack_gap_conn.cc
@@ -20,7 +20,6 @@
*/
#include "gap_api.h"
-#include "l2c_api.h"
#include "stack/include/bt_hdr.h"
#include "test/common/mock_functions.h"
#include "types/raw_address.h"
diff --git a/system/test/mock/mock_stack_gatt_main.cc b/system/test/mock/mock_stack_gatt_main.cc
index ec4ca1d9ee..66cb4a5844 100644
--- a/system/test/mock/mock_stack_gatt_main.cc
+++ b/system/test/mock/mock_stack_gatt_main.cc
@@ -19,7 +19,6 @@
* Functions generated:23
*/
-#include "l2c_api.h"
#include "stack/gatt/gatt_int.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_interface.h"
diff --git a/system/test/mock/mock_stack_l2cap_api.h b/system/test/mock/mock_stack_l2cap_api.h
index 84b36a4d9e..c2d162afd2 100644
--- a/system/test/mock/mock_stack_l2cap_api.h
+++ b/system/test/mock/mock_stack_l2cap_api.h
@@ -31,7 +31,7 @@
#include <cstdint>
#include "stack/include/bt_hdr.h"
-#include "stack/include/l2c_api.h"
+#include "stack/include/l2cap_interface.h"
#include "types/bt_transport.h"
#include "types/raw_address.h"
diff --git a/system/test/mock/mock_stack_l2cap_main.cc b/system/test/mock/mock_stack_l2cap_main.cc
index 937d9d0209..fb33fed8f8 100644
--- a/system/test/mock/mock_stack_l2cap_main.cc
+++ b/system/test/mock/mock_stack_l2cap_main.cc
@@ -19,7 +19,6 @@
* Functions generated:9
*/
-#include "l2c_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/l2cap/l2c_int.h"
#include "test/common/mock_functions.h"
diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc
index 047ea9c96e..e793ac16e3 100644
--- a/tools/rootcanal/model/controller/link_layer_controller.cc
+++ b/tools/rootcanal/model/controller/link_layer_controller.cc
@@ -83,8 +83,16 @@ AddressWithType PeerIdentityAddress(Address address, PeerAddressType peer_addres
}
bool LinkLayerController::IsEventUnmasked(EventCode event) const {
- uint64_t bit = UINT64_C(1) << (static_cast<uint8_t>(event) - 1);
- return (event_mask_ & bit) != 0;
+ uint8_t evt = static_cast<uint8_t>(event);
+
+ if (evt <= 64) {
+ uint64_t bit = UINT64_C(1) << (evt - 1);
+ return (event_mask_ & bit) != 0;
+ } else {
+ evt -= 64;
+ uint64_t bit = UINT64_C(1) << (evt - 1);
+ return (event_mask_page_2_ & bit) != 0;
+ }
}
bool LinkLayerController::IsLeEventUnmasked(SubeventCode subevent) const {
@@ -5638,7 +5646,11 @@ ErrorCode LinkLayerController::LeLongTermKeyRequestReply(uint16_t handle,
}
} else {
connections_.Encrypt(handle);
- if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
+ if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE_V2)) {
+ send_event_(bluetooth::hci::EncryptionChangeV2Builder::Create(
+ ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON,
+ 0x10 /* key_size */));
+ } else if (IsEventUnmasked(EventCode::ENCRYPTION_CHANGE)) {
send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
ErrorCode::SUCCESS, handle, bluetooth::hci::EncryptionEnabled::ON));
}
diff --git a/tools/rootcanal/packets/hci_packets.pdl b/tools/rootcanal/packets/hci_packets.pdl
index 2b404bdff1..6cb90fea7f 100644
--- a/tools/rootcanal/packets/hci_packets.pdl
+++ b/tools/rootcanal/packets/hci_packets.pdl
@@ -749,6 +749,7 @@ enum EventCode : 8 {
REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION = 0x3D,
LE_META_EVENT = 0x3e,
NUMBER_OF_COMPLETED_DATA_BLOCKS = 0x48,
+ ENCRYPTION_CHANGE_V2 = 0x59,
VENDOR_SPECIFIC = 0xFF,
}
@@ -4767,6 +4768,13 @@ packet EncryptionChange : Event (event_code = ENCRYPTION_CHANGE) {
encryption_enabled : EncryptionEnabled,
}
+packet EncryptionChangeV2 : Event (event_code = ENCRYPTION_CHANGE_V2) {
+ status : ErrorCode,
+ connection_handle : 12,
+ _reserved_ : 4,
+ encryption_enabled : EncryptionEnabled,
+ key_size : 8,
+}
packet ChangeConnectionLinkKeyComplete : Event (event_code = CHANGE_CONNECTION_LINK_KEY_COMPLETE) {
status : ErrorCode,
connection_handle : 12,