diff options
author | Scott Lobdell <slobdell@google.com> | 2022-06-13 17:31:27 +0000 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2022-06-13 17:36:26 +0000 |
commit | 96230268500ca72fd4d4c4cb15c54dbfd268ac89 (patch) | |
tree | ed9f7baeca3035a0e01d0de1b97ee361fbb1cb09 | |
parent | 5ccf9c5f1a35b5f4ee2ea952df82dfe6706e043c (diff) | |
parent | 197e748fe27845baab411394ac5aaaae5337663a (diff) |
Merge TP1A.220609.001
Change-Id: I6c3c168fb196a53feb1d2688b74bea4fdbc5b3e8
45 files changed, 550 insertions, 616 deletions
diff --git a/android/app/AndroidManifest.xml b/android/app/AndroidManifest.xml index 53ceddac59..ed7daa182d 100644 --- a/android/app/AndroidManifest.xml +++ b/android/app/AndroidManifest.xml @@ -519,12 +519,9 @@ <action android:name="android.bluetooth.IBluetoothPbapClient"/> </intent-filter> </service> - <!-- Note: This service doesn't get started, it just indicates to the Authentication - framework that we can create accounts of a specific type. As such, its safe to - have as enabled on all targets and not just the ones that use PBAP Client --> <service android:process="@string/process" android:name="com.android.bluetooth.pbapclient.AuthenticationService" - android:enabled="true" + android:enabled="false" android:exported="true"> <intent-filter> <action android:name="android.accounts.AccountAuthenticator"/> diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java index d4aeea0e8f..881ef14533 100755 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java @@ -49,6 +49,7 @@ import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.internal.annotations.VisibleForTesting; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -68,6 +69,7 @@ public class BassClientService extends ProfileService { private final Map<BluetoothDevice, BassClientStateMachine> mStateMachines = new HashMap<>(); private final Object mSearchScanCallbackLock = new Object(); + private final Map<Integer, ScanResult> mScanBroadcasts = new HashMap<>(); private HandlerThread mStateMachinesThread; private HandlerThread mCallbackHandlerThread; @@ -325,8 +327,16 @@ public class BassClientService extends ProfileService { } private boolean hasRoomForBroadcastSourceAddition(BluetoothDevice device) { - List<BluetoothLeBroadcastReceiveState> currentAllSources = getAllSources(device); - return currentAllSources.size() < getMaximumSourceCapacity(device); + boolean isRoomAvailable = false; + String emptyBluetoothDevice = "00:00:00:00:00:00"; + for (BluetoothLeBroadcastReceiveState recvState: getAllSources(device)) { + if (recvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { + isRoomAvailable = true; + break; + } + } + log("isRoomAvailable: " + isRoomAvailable); + return isRoomAvailable; } private BassClientStateMachine getOrCreateStateMachine(BluetoothDevice device) { @@ -632,16 +642,29 @@ public class BassClientService extends ProfileService { BassConstants.BAAS_UUID)) { return; } - Message msg = mBassUtils.getAutoAssistScanHandler() - .obtainMessage(BassConstants.AA_SCAN_SUCCESS); - msg.obj = result; - mBassUtils.getAutoAssistScanHandler().sendMessage(msg); + log( "Broadcast Source Found:" + result.getDevice()); + byte[] broadcastIdArray = listOfUuids.get(BassConstants.BAAS_UUID); + int broadcastId = (int)(((broadcastIdArray[2] & 0xff) << 16) + | ((broadcastIdArray[1] & 0xff) << 8) + | (broadcastIdArray[0] & 0xff)); + if (mScanBroadcasts.get(broadcastId) == null) { + log("selectBroadcastSource: broadcastId " + broadcastId); + mScanBroadcasts.put(broadcastId, result); + synchronized (mStateMachines) { + for (BassClientStateMachine sm : mStateMachines.values()) { + if (sm.isConnected()) { + selectSource(sm.getDevice(), result, false); + } + } + } + } } public void onScanFailed(int errorCode) { Log.e(TAG, "Scan Failure:" + errorCode); } }; + mScanBroadcasts.clear(); ScanSettings settings = new ScanSettings.Builder().setCallbackType( ScanSettings.CALLBACK_TYPE_ALL_MATCHES) .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) @@ -687,6 +710,7 @@ public class BassClientService extends ProfileService { scanner.stopScan(mSearchScanCallback); mSearchScanCallback = null; mCallbacks.notifySearchStopped(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); + mScanBroadcasts.clear(); } } @@ -792,6 +816,7 @@ public class BassClientService extends ProfileService { } Message message = stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE); message.arg1 = sourceId; + message.arg2 = BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_INVALID; message.obj = updatedMetadata; stateMachine.sendMessage(message); } @@ -820,6 +845,20 @@ public class BassClientService extends ProfileService { BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR); return; } + BluetoothLeBroadcastReceiveState recvState = + stateMachine.getBroadcastReceiveStateForSourceId(sourceId); + BluetoothLeBroadcastMetadata metaData = + stateMachine.getCurrentBroadcastMetadata(sourceId); + if (metaData != null && recvState != null && recvState.getPaSyncState() == + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { + log("Force source to lost PA sync"); + Message message = stateMachine.obtainMessage( + BassClientStateMachine.UPDATE_BCAST_SOURCE); + message.arg1 = sourceId; + message.arg2 = BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE; + message.obj = metaData; + stateMachine.sendMessage(message); + } Message message = stateMachine.obtainMessage(BassClientStateMachine.REMOVE_BCAST_SOURCE); message.arg1 = sourceId; stateMachine.sendMessage(message); diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java index cdc9dabcb6..1e304805c5 100755 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java @@ -436,11 +436,13 @@ public class BassClientStateMachine extends StateMachine { channel.setSelected(false); subGroup.addChannel(channel.build()); } - subGroup.setCodecId((long)(baseLevel2.codecId[4] << 32 - | baseLevel2.codecId[3] << 24 - | baseLevel2.codecId[2] << 16 - | baseLevel2.codecId[1] << 8 - | baseLevel2.codecId[0])); + byte[] arrayCodecId = baseLevel2.codecId; + long codeId = (long) ((arrayCodecId[4] & 0xff) << 32 + | (arrayCodecId[3] & 0xff) << 24 + | (arrayCodecId[2] & 0xff) << 16 + | (arrayCodecId[1] & 0xff) << 8 + | (arrayCodecId[0] & 0xff)); + subGroup.setCodecId(codeId); subGroup.setCodecSpecificConfig(BluetoothLeAudioCodecConfigMetadata. fromRawBytes(baseLevel2.codecConfigInfo)); subGroup.setContentMetadata(BluetoothLeAudioContentMetadata. @@ -448,6 +450,18 @@ public class BassClientStateMachine extends StateMachine { metaData.addSubgroup(subGroup.build()); } metaData.setSourceDevice(device, device.getAddressType()); + byte[] arrayPresentationDelay = baseData.getLevelOne().presentationDelay; + int presentationDelay = (int) ((arrayPresentationDelay[2] & 0xff) << 16 + | (arrayPresentationDelay[1] & 0xff) + | (arrayPresentationDelay[0] & 0xff)); + metaData.setPresentationDelayMicros(presentationDelay); + PeriodicAdvertisementResult result = + mService.getPeriodicAdvertisementResult(device); + if (result != null) { + int broadcastId = result.getBroadcastId(); + log("broadcast ID: " + broadcastId); + metaData.setBroadcastId(broadcastId); + } return metaData.build(); } @@ -638,6 +652,7 @@ public class BassClientStateMachine extends StateMachine { byte metaDataSyncState = receiverState[BassConstants.BCAST_RCVR_STATE_PA_SYNC_IDX]; byte encryptionStatus = receiverState[BassConstants.BCAST_RCVR_STATE_ENC_STATUS_IDX]; byte[] badBroadcastCode = null; + int badBroadcastCodeLen = 0; if (encryptionStatus == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE) { badBroadcastCode = new byte[BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE]; @@ -648,11 +663,12 @@ public class BassClientStateMachine extends StateMachine { 0, BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE); badBroadcastCode = reverseBytes(badBroadcastCode); + badBroadcastCodeLen = BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE; } byte numSubGroups = receiverState[BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX - + BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE]; + + badBroadcastCodeLen]; int offset = BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX - + BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE + 1; + + badBroadcastCodeLen + 1; ArrayList<BluetoothLeAudioContentMetadata> metadataList = new ArrayList<BluetoothLeAudioContentMetadata>(); ArrayList<Long> audioSyncState = new ArrayList<Long>(); @@ -664,7 +680,7 @@ public class BassClientStateMachine extends StateMachine { log("BIS index byte array: "); BassUtils.printByteArray(audioSyncIndex); ByteBuffer wrapped = ByteBuffer.wrap(reverseBytes(audioSyncIndex)); - audioSyncState.add(wrapped.getLong()); + audioSyncState.add((long) wrapped.getInt()); byte metaDataLength = receiverState[offset++]; if (metaDataLength > 0) { @@ -1255,7 +1271,7 @@ public class BassClientStateMachine extends StateMachine { } private byte[] convertBroadcastMetadataToUpdateSourceByteArray(int sourceId, - BluetoothLeBroadcastMetadata metaData) { + BluetoothLeBroadcastMetadata metaData, int paSync) { BluetoothLeBroadcastReceiveState existingState = getBroadcastReceiveStateForSourceId(sourceId); if (existingState == null) { @@ -1287,7 +1303,9 @@ public class BassClientStateMachine extends StateMachine { // Source_ID res[offset++] = (byte) sourceId; // PA_Sync - if (existingState.getPaSyncState() + if (paSync != BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_INVALID) { + res[offset++] = (byte) paSync; + } else if (existingState.getPaSyncState() == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { res[offset++] = (byte) (0x01); } else { @@ -1299,7 +1317,12 @@ public class BassClientStateMachine extends StateMachine { // Num_Subgroups res[offset++] = numSubGroups; for (int i = 0; i < numSubGroups; i++) { - int bisIndexValue = existingState.getBisSyncState().get(i).intValue(); + int bisIndexValue; + if (paSync != BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_INVALID) { + bisIndexValue = 0; + } else { + bisIndexValue = existingState.getBisSyncState().get(i).intValue(); + } log("UPDATE_BCAST_SOURCE: bisIndexValue : " + bisIndexValue); // BIS_Sync res[offset++] = (byte) (bisIndexValue & 0x00000000000000FF); @@ -1497,9 +1520,10 @@ public class BassClientStateMachine extends StateMachine { case UPDATE_BCAST_SOURCE: metaData = (BluetoothLeBroadcastMetadata) message.obj; int sourceId = message.arg1; + int paSync = message.arg2; log("Updating Broadcast source" + metaData); byte[] updateSourceInfo = convertBroadcastMetadataToUpdateSourceByteArray( - sourceId, metaData); + sourceId, metaData, paSync); if (updateSourceInfo == null) { Log.e(TAG, "update source: source Info is NULL"); break; diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java index f9540c0557..6dce0d1c0b 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java @@ -696,7 +696,7 @@ class AdapterProperties { + prevState + " -> " + state); BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, state, 0 /* deprecated */, profile, mService.obfuscateAddress(device), - mService.getMetricId(device)); + mService.getMetricId(device), 0); if (!isNormalStateTransition(prevState, state)) { Log.w(TAG, diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java index 81d1a86351..da78ec6373 100644 --- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -724,7 +724,7 @@ final class RemoteDevices { break; case AbstractionLayer.BT_PROPERTY_TYPE_OF_DEVICE: if (device.isConsolidated()) { - return; + break; } // The device type from hal layer, defined in bluetooth.h, // matches the type defined in BluetoothDevice.java diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java index 72e95d7749..29c2781d47 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattService.java +++ b/android/app/src/com/android/bluetooth/gatt/GattService.java @@ -66,6 +66,7 @@ import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.IBluetoothGatt; import android.bluetooth.IBluetoothGattCallback; @@ -104,6 +105,7 @@ import android.text.format.DateUtils; import android.util.Log; import com.android.bluetooth.BluetoothMetricsProto; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AbstractionLayer; @@ -2063,7 +2065,7 @@ public class GattService extends ProfileService { Log.d(TAG, "onConnected() - clientIf=" + clientIf + ", connId=" + connId + ", address=" + address); } - + int connectionState = BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED; if (status == 0) { mClientMap.addConnection(clientIf, connId, address); @@ -2073,12 +2075,16 @@ public class GattService extends ProfileService { + address); mPermits.putIfAbsent(address, new AtomicBoolean(true)); } + connectionState = BluetoothProtoEnums.CONNECTION_STATE_CONNECTED; + } ClientMap.App app = mClientMap.getById(clientIf); if (app != null) { app.callback.onClientConnectionState(status, clientIf, (status == BluetoothGatt.GATT_SUCCESS), address); } + statsLogGattConnectionStateChange( + BluetoothProfile.GATT, address, clientIf, connectionState); } void onDisconnected(int clientIf, int connId, int status, String address) @@ -2104,6 +2110,9 @@ public class GattService extends ProfileService { if (app != null) { app.callback.onClientConnectionState(status, clientIf, false, address); } + statsLogGattConnectionStateChange( + BluetoothProfile.GATT, address, clientIf, + BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED); } void onClientPhyUpdate(int connId, int txPhy, int rxPhy, int status) throws RemoteException { @@ -3485,6 +3494,9 @@ public class GattService extends ProfileService { Log.d(TAG, "clientConnect() - address=" + address + ", isDirect=" + isDirect + ", opportunistic=" + opportunistic + ", phy=" + phy); } + statsLogGattConnectionStateChange( + BluetoothProfile.GATT, address, clientIf, + BluetoothProtoEnums.CONNECTION_STATE_CONNECTING); gattClientConnectNative(clientIf, address, isDirect, transport, opportunistic, phy); } @@ -3499,7 +3511,9 @@ public class GattService extends ProfileService { if (DBG) { Log.d(TAG, "clientDisconnect() - address=" + address + ", connId=" + connId); } - + statsLogGattConnectionStateChange( + BluetoothProfile.GATT, address, clientIf, + BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTING); gattClientDisconnectNative(clientIf, address, connId != null ? connId : 0); } @@ -4136,14 +4150,18 @@ public class GattService extends ProfileService { if (app == null) { return; } - + int connectionState; if (connected) { mServerMap.addConnection(serverIf, connId, address); + connectionState = BluetoothProtoEnums.CONNECTION_STATE_CONNECTED; } else { mServerMap.removeConnection(serverIf, connId); + connectionState = BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED; } app.callback.onServerConnectionState((byte) 0, serverIf, connected, address); + statsLogGattConnectionStateChange( + BluetoothProfile.GATT_SERVER, address, serverIf, connectionState); } void onServerReadCharacteristic(String address, int connId, int transId, int handle, int offset, @@ -4817,6 +4835,20 @@ public class GattService extends ProfileService { } } + private void statsLogGattConnectionStateChange( + int profile, String address, int sessionIndex, int connectionState) { + BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address); + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, connectionState, + 0 /* deprecated */, profile, new byte[0], + mAdapterService.getMetricId(device), sessionIndex); + if (DBG) { + Log.d(TAG, "Gatt Logging: metric_id=" + mAdapterService.getMetricId(device) + + ", session_index=" + sessionIndex + + ", connection state=" + connectionState); + } + } + @Override public void dumpProto(BluetoothMetricsProto.BluetoothLog.Builder builder) { synchronized (mScanEvents) { diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java index a948631857..34feddca0d 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java @@ -29,6 +29,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Handler; import android.provider.CallLog; import android.sysprop.BluetoothProperties; import android.util.Log; @@ -60,6 +61,12 @@ public class PbapClientService extends ProfileService { private static final String TAG = "PbapClientService"; private static final String SERVICE_NAME = "Phonebook Access PCE"; + /** + * The component names for the owned authenticator service + */ + private static final String AUTHENTICATOR_SERVICE = + AuthenticationService.class.getCanonicalName(); + // MAXIMUM_DEVICES set to 10 to prevent an excessive number of simultaneous devices. private static final int MAXIMUM_DEVICES = 10; private Map<BluetoothDevice, PbapClientStateMachine> mPbapClientStateMachineMap = @@ -70,6 +77,40 @@ public class PbapClientService extends ProfileService { private DatabaseManager mDatabaseManager; + /** + * There's an ~1-2 second latency between when our Authentication service is set as available to + * the system and when the Authentication/Account framework code will recognize it and allow us + * to alter accounts. In lieu of the Accounts team dealing with this race condition, we're going + * to periodically poll over 3 seconds until our accounts are visible, remove old accounts, and + * then notify device state machines that they can create accounts and download contacts. + */ + // TODO(233361365): Remove this pattern when the framework solves their race condition + private static final int ACCOUNT_VISIBILITY_CHECK_MS = 500; + private static final int ACCOUNT_VISIBILITY_CHECK_TRIES_MAX = 6; + private int mAccountVisibilityCheckTries = 0; + private final Handler mAuthServiceHandler = new Handler(); + private final Runnable mCheckAuthService = new Runnable() { + @Override + public void run() { + // If our accounts are finally visible to use, clean up old ones and tell devices they + // can issue downloads if they're ready. Otherwise, wait and try again. + if (isAuthenticationServiceReady()) { + Log.i(TAG, "Service ready! Clean up old accounts and try contacts downloads"); + removeUncleanAccounts(); + for (PbapClientStateMachine stateMachine : mPbapClientStateMachineMap.values()) { + stateMachine.tryDownloadIfConnected(); + } + } else if (mAccountVisibilityCheckTries < ACCOUNT_VISIBILITY_CHECK_TRIES_MAX) { + mAccountVisibilityCheckTries += 1; + Log.w(TAG, "AccountManager hasn't registered our service yet. Retry " + + mAccountVisibilityCheckTries + "/" + ACCOUNT_VISIBILITY_CHECK_TRIES_MAX); + mAuthServiceHandler.postDelayed(this, ACCOUNT_VISIBILITY_CHECK_MS); + } else { + Log.e(TAG, "Failed to register Authenication Service and get account visibility"); + } + } + }; + public static boolean isEnabled() { return BluetoothProperties.isProfilePbapClientEnabled().orElse(false); } @@ -88,6 +129,8 @@ public class PbapClientService extends ProfileService { mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(), "DatabaseManager cannot be null when PbapClientService starts"); + setComponentAvailable(AUTHENTICATOR_SERVICE, true); + IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); // delay initial download until after the user is unlocked to add an account. @@ -101,7 +144,7 @@ public class PbapClientService extends ProfileService { Log.w(TAG, "Unable to register pbapclient receiver", e); } - removeUncleanAccounts(); + initializeAuthenticationService(); registerSdpRecord(); setPbapClientService(this); return true; @@ -119,7 +162,8 @@ public class PbapClientService extends ProfileService { for (PbapClientStateMachine pbapClientStateMachine : mPbapClientStateMachineMap.values()) { pbapClientStateMachine.doQuit(); } - removeUncleanAccounts(); + cleanupAuthenicationService(); + setComponentAvailable(AUTHENTICATOR_SERVICE, false); return true; } @@ -133,7 +177,45 @@ public class PbapClientService extends ProfileService { } } + /** + * Periodically check if the account framework has recognized our service and will allow us to + * interact with our accounts. Notify state machines once our service is ready so we can trigger + * account downloads. + */ + private void initializeAuthenticationService() { + mAuthServiceHandler.postDelayed(mCheckAuthService, ACCOUNT_VISIBILITY_CHECK_MS); + } + + private void cleanupAuthenicationService() { + mAuthServiceHandler.removeCallbacks(mCheckAuthService); + removeUncleanAccounts(); + } + + /** + * Determine if our account type is visible to us yet. If it is, then our service is ready and + * our account type is ready to use. + * + * Make a placeholder device account and determine our visibility relative to it. Note that this + * function uses the same restrictions are the other add and remove functions, but is *also* + * available to all system apps instead of throwing a runtime SecurityException. + */ + protected boolean isAuthenticationServiceReady() { + Account account = new Account("00:00:00:00:00:00", getString(R.string.pbap_account_type)); + AccountManager accountManager = AccountManager.get(this); + int visibility = accountManager.getAccountVisibility(account, getPackageName()); + if (DBG) { + Log.d(TAG, "Checking visibility, visibility=" + visibility); + } + return visibility == AccountManager.VISIBILITY_VISIBLE + || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE; + } + private void removeUncleanAccounts() { + if (!isAuthenticationServiceReady()) { + Log.w(TAG, "Can't remove accounts. AccountManager hasn't registered our service yet."); + return; + } + // Find all accounts that match the type "pbap" and delete them. AccountManager accountManager = AccountManager.get(this); Account[] accounts = @@ -208,7 +290,7 @@ public class PbapClientService extends ProfileService { } } else if (action.equals(Intent.ACTION_USER_UNLOCKED)) { for (PbapClientStateMachine stateMachine : mPbapClientStateMachineMap.values()) { - stateMachine.resumeDownload(); + stateMachine.tryDownloadIfConnected(); } } else if (action.equals(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED)) { // PbapClientConnectionHandler has code to remove calllogs when PBAP disconnects. @@ -542,6 +624,7 @@ public class PbapClientService extends ProfileService { @Override public void dump(StringBuilder sb) { super.dump(sb); + ProfileService.println(sb, "isAuthServiceReady: " + isAuthenticationServiceReady()); for (PbapClientStateMachine stateMachine : mPbapClientStateMachineMap.values()) { stateMachine.dump(sb); } diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java index 84bea769be..6f4c0fab6c 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java @@ -301,10 +301,7 @@ final class PbapClientStateMachine extends StateMachine { onConnectionStateChanged(mCurrentDevice, mMostRecentState, BluetoothProfile.STATE_CONNECTED); mMostRecentState = BluetoothProfile.STATE_CONNECTED; - if (mUserManager.isUserUnlocked()) { - mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) - .sendToTarget(); - } + downloadIfReady(); } @Override @@ -321,8 +318,7 @@ final class PbapClientStateMachine extends StateMachine { break; case MSG_RESUME_DOWNLOAD: - mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) - .sendToTarget(); + downloadIfReady(); break; default: @@ -333,6 +329,21 @@ final class PbapClientStateMachine extends StateMachine { } } + /** + * Trigger a contacts download if the user is unlocked and our accounts are available to us + */ + private void downloadIfReady() { + boolean userReady = mUserManager.isUserUnlocked(); + boolean accountServiceReady = mService.isAuthenticationServiceReady(); + if (!userReady || !accountServiceReady) { + Log.w(TAG, "Cannot download contacts yet, userReady=" + userReady + + ", accountServiceReady=" + accountServiceReady); + return; + } + mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DOWNLOAD) + .sendToTarget(); + } + private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) { if (device == null) { Log.w(TAG, "onConnectionStateChanged with invalid device"); @@ -357,7 +368,7 @@ final class PbapClientStateMachine extends StateMachine { sendMessage(MSG_DISCONNECT, device); } - public void resumeDownload() { + public void tryDownloadIfConnected() { sendMessage(MSG_RESUME_DOWNLOAD); } diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json index 905a96b0ed..b97fc52417 100644 --- a/apex/apex_manifest.json +++ b/apex/apex_manifest.json @@ -1,6 +1,6 @@ { "name": "com.android.bluetooth", - "version": 330090000, + "version": 339990000, "requireNativeLibs": [ "libaptX_encoder.so", "libaptXHD_encoder.so" diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java index 4d96ebc518..67515bef5c 100644 --- a/framework/java/android/bluetooth/BluetoothAdapter.java +++ b/framework/java/android/bluetooth/BluetoothAdapter.java @@ -1007,8 +1007,8 @@ public final class BluetoothAdapter { /** * Get a {@link BluetoothDevice} object for the given Bluetooth hardware * address. - * <p>Valid Bluetooth hardware addresses must be upper case, in a format - * such as "00:11:22:33:AA:BB". The helper {@link #checkBluetoothAddress} is + * <p>Valid Bluetooth hardware addresses must be upper case, in big endian byte order, and in a + * format such as "00:11:22:33:AA:BB". The helper {@link #checkBluetoothAddress} is * available to validate a Bluetooth address. * <p>A {@link BluetoothDevice} will always be returned for a valid * hardware address, even if this adapter has never seen that device. @@ -1027,8 +1027,8 @@ public final class BluetoothAdapter { /** * Get a {@link BluetoothDevice} object for the given Bluetooth hardware * address and addressType. - * <p>Valid Bluetooth hardware addresses must be upper case, in a format - * such as "00:11:22:33:AA:BB". The helper {@link #checkBluetoothAddress} is + * <p>Valid Bluetooth hardware addresses must be upper case, in big endian byte order, and in a + * format such as "00:11:22:33:AA:BB". The helper {@link #checkBluetoothAddress} is * available to validate a Bluetooth address. * <p>A {@link BluetoothDevice} will always be returned for a valid * hardware address and type, even if this adapter has never seen that device. @@ -3396,7 +3396,7 @@ public final class BluetoothAdapter { * can use the same UUID to query our SDP server and discover which channel * to connect to. This SDP record will be removed when this socket is * closed, or if this application closes unexpectedly. - * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to + * <p>Use {@link BluetoothDevice#createInsecureRfcommSocketToServiceRecord} to * connect to this socket from another device using the same {@link UUID}. * * @param name service name for SDP record diff --git a/framework/java/android/bluetooth/le/ScanFilter.java b/framework/java/android/bluetooth/le/ScanFilter.java index 737f58f4a2..b72e7ef31a 100644 --- a/framework/java/android/bluetooth/le/ScanFilter.java +++ b/framework/java/android/bluetooth/le/ScanFilter.java @@ -820,13 +820,15 @@ public final class ScanFilter implements Parcelable { } /** - * Set filter on device address. + * Set a scan filter on the remote device address. + * <p> + * The address passed to this API must be in big endian byte order. It needs to be in the + * format of "01:02:03:AB:CD:EF". The device address can be validated using + * {@link BluetoothAdapter#checkBluetoothAddress}. The @AddressType is defaulted to + * {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC}. * - * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the - * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link - * BluetoothAdapter#checkBluetoothAddress}. The @AddressType is defaulted to {@link - * BluetoothDevice#ADDRESS_TYPE_PUBLIC} - * @throws IllegalArgumentException If the {@code deviceAddress} is invalid. + * @param deviceAddress the remote device Bluetooth address for the filter + * @throws IllegalArgumentException if the {@code deviceAddress} is invalid */ public Builder setDeviceAddress(String deviceAddress) { if (deviceAddress == null) { @@ -837,20 +839,20 @@ public final class ScanFilter implements Parcelable { } /** - * Set filter on Address with AddressType - * - * <p>This key is used to resolve a private address from a public address. + * Set a scan filter on the remote device address with an address type. + * <p> + * The address passed to this API must be in big endian byte order. It needs to be in the + * format of "01:02:03:AB:CD:EF". The device address can be validated using + * {@link BluetoothAdapter#checkBluetoothAddress}. * - * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the - * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link - * BluetoothAdapter#checkBluetoothAddress}. May be any type of address. + * @param deviceAddress the remote device Bluetooth address for the filter * @param addressType indication of the type of address - * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} - * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM} * - * @throws IllegalArgumentException If the {@code deviceAddress} is invalid. - * @throws IllegalArgumentException If the {@code addressType} is invalid length - * @throws NullPointerException if {@code deviceAddress} is null. + * @throws IllegalArgumentException If the {@code deviceAddress} is invalid + * @throws IllegalArgumentException If the {@code addressType} is invalid length or is not + * either {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} or + * {@link BluetoothDevice#ADDRESS_TYPE_RANDOM} + * @throws NullPointerException if {@code deviceAddress} is null * * @hide */ @@ -862,25 +864,25 @@ public final class ScanFilter implements Parcelable { } /** - * Set filter on Address with AddressType and the Identity Resolving Key (IRK). - * - * <p>The IRK is used to resolve a {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} from - * a PRIVATE_ADDRESS type. + * Set a scan filter on the remote device address with an address type and the Identity + * Resolving Key (IRK). + * <p> + * The address passed to this API must be either a public or random static address in big + * endian byte order. It needs to be in the format of "01:02:03:AB:CD:EF". The device + * address can be validated using {@link BluetoothAdapter#checkBluetoothAddress}. + * <p> + * The IRK is used to resolve a static address from a private address. The IRK must be + * provided in little endian byte order. * - * @param deviceAddress The device Bluetooth address for the filter. It needs to be in the - * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link - * BluetoothAdapter#checkBluetoothAddress}. This Address type must only be PUBLIC OR RANDOM - * STATIC. + * @param deviceAddress the remote device Bluetooth address for the filter * @param addressType indication of the type of address - * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} - * or {@link BluetoothDevice#ADDRESS_TYPE_RANDOM} - * @param irk non-null byte array representing the Identity Resolving Key + * @param irk non-null little endian byte array representing the Identity Resolving Key * - * @throws IllegalArgumentException If the {@code deviceAddress} is invalid. - * @throws IllegalArgumentException if the {@code irk} is invalid length. - * @throws IllegalArgumentException If the {@code addressType} is invalid length or is not - * PUBLIC or RANDOM STATIC when an IRK is present. - * @throws NullPointerException if {@code deviceAddress} or {@code irk} is null. + * @throws IllegalArgumentException If the {@code deviceAddress} is invalid + * @throws IllegalArgumentException if the {@code irk} is invalid length + * @throws IllegalArgumentException If the {@code addressType} is an invalid length or is + * not PUBLIC or RANDOM STATIC + * @throws NullPointerException if {@code deviceAddress} or {@code irk} is null * * @hide */ @@ -905,13 +907,13 @@ public final class ScanFilter implements Parcelable { * format of "01:02:03:AB:CD:EF". The device address can be validated using {@link * BluetoothAdapter#checkBluetoothAddress}. * @param addressType indication of the type of address - * e.g. {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} - * @param irk non-null byte array representing the Identity Resolving Address; nullable - * internally. + * @param irk non-null little endian byte array representing the Identity Resolving Key; + * nullable internally. * - * @throws IllegalArgumentException If the {@code deviceAddress} is invalid. - * @throws IllegalArgumentException If the {@code addressType} is invalid length. - * @throws NullPointerException if {@code deviceAddress} is null. + * @throws IllegalArgumentException if the {@code deviceAddress} is invalid + * @throws IllegalArgumentException if the {@code addressType} is not PUBLIC or RANDOM + * STATIC when an IRK is present + * @throws NullPointerException if {@code deviceAddress} is null * * @hide */ diff --git a/system/Android.mk b/system/Android.mk index a6a4c1a76f..1596e4981e 100644 --- a/system/Android.mk +++ b/system/Android.mk @@ -46,7 +46,6 @@ LOCAL_target_executables := \ $(TARGET_OUT_EXECUTABLES)/bluetooth_stack_with_facade LOCAL_target_libraries := \ - $(TARGET_OUT_SHARED_LIBRARIES)/android.system.suspend.control-V1-ndk.so \ $(TARGET_OUT_SHARED_LIBRARIES)/libcrypto.so \ $(TARGET_OUT_SHARED_LIBRARIES)/libbluetooth_gd.so \ $(TARGET_OUT_SHARED_LIBRARIES)/libgrpc++_unsecure.so \ diff --git a/system/audio_bluetooth_hw/stream_apis.h b/system/audio_bluetooth_hw/stream_apis.h index 76845d9ee5..36dd589b16 100644 --- a/system/audio_bluetooth_hw/stream_apis.h +++ b/system/audio_bluetooth_hw/stream_apis.h @@ -31,7 +31,7 @@ constexpr audio_format_t kBluetoothDefaultAudioFormatBitsPerSample = constexpr unsigned int kBluetoothDefaultInputBufferMs = 20; constexpr unsigned int kBluetoothDefaultInputStateTimeoutMs = 20; -constexpr unsigned int kBluetoothDefaultOutputBufferMs = 2; +constexpr unsigned int kBluetoothDefaultOutputBufferMs = 10; constexpr unsigned int kBluetoothSpatializerOutputBufferMs = 10; constexpr audio_channel_mask_t kBluetoothDefaultOutputChannelModeMask = diff --git a/system/blueberry/tests/gd/cert/gd_device.py b/system/blueberry/tests/gd/cert/gd_device.py index 7fbc93c9f0..44a22c6cf7 100644 --- a/system/blueberry/tests/gd/cert/gd_device.py +++ b/system/blueberry/tests/gd/cert/gd_device.py @@ -491,8 +491,6 @@ class GdAndroidDevice(GdDeviceBase): # Push test binaries self.push_or_die(os.path.join(get_gd_root(), "target", "bluetooth_stack_with_facade"), "system/bin") - self.push_or_die( - os.path.join(get_gd_root(), "target", "android.system.suspend.control-V1-ndk.so"), "system/lib64") self.push_or_die(os.path.join(get_gd_root(), "target", "libbluetooth_gd.so"), "system/lib64") self.push_or_die(os.path.join(get_gd_root(), "target", "libgrpc++_unsecure.so"), "system/lib64") self.push_or_die(os.path.join(get_gd_root(), "target", "libgrpc++.so"), "system/lib64") @@ -529,7 +527,8 @@ class GdAndroidDevice(GdDeviceBase): self.ensure_no_output(self.adb.shell("settings put global ble_scan_always_enabled 0")) self.adb.shell("cmd bluetooth_manager disable") device_bt_state = int(self.adb.shell("settings get global bluetooth_on")) - asserts.assert_equal(device_bt_state, 0, "Failed to disable Bluetooth on device %s %s" % (self.label, self.serial_number)) + asserts.assert_equal(device_bt_state, 0, + "Failed to disable Bluetooth on device %s %s" % (self.label, self.serial_number)) logging.info("Bluetooth disabled on device %s %s" % (self.label, self.serial_number)) # Start logcat logging diff --git a/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py b/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py index 899df006a6..24844ff1b8 100644 --- a/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py +++ b/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py @@ -61,9 +61,10 @@ class GdSl4aBaseTestClass(BaseTestClass): # Enable full btsnoop log self.dut.adb.root() self.dut.adb.shell("setprop persist.bluetooth.btsnooplogmode full") - getprop_result = self.dut.adb.shell("getprop persist.bluetooth.btsnooplogmode") == "full" - if not getprop_result: - self.dut.log.warning("Failed to enable Bluetooth Hci Snoop Logging.") + getprop_result = self.dut.adb.getprop("persist.bluetooth.btsnooplogmode") + if getprop_result is None or ("full" not in getprop_result.lower()): + self.dut.log.warning( + "Failed to enable Bluetooth Hci Snoop Logging, getprop returned {}".format(getprop_result)) self.ble = BleLib(dut=self.dut) @@ -95,7 +96,10 @@ class GdSl4aBaseTestClass(BaseTestClass): # Make sure BLE is disabled and Bluetooth is disabled after test self.dut.sl4a.bluetoothDisableBLE() disable_bluetooth(self.dut.sl4a, self.dut.ed) - self.cert.rootservice.StopStack(facade_rootservice.StopStackRequest()) + try: + self.cert.rootservice.StopStack(facade_rootservice.StopStackRequest()) + except Exception: + logging.error("Failed to stop CERT stack") # TODO: split cert logcat logs into individual tests current_test_dir = get_current_context().get_full_output_path() diff --git a/system/bta/gatt/bta_gattc_act.cc b/system/bta/gatt/bta_gattc_act.cc index 63da73cf8c..d170778bd8 100644 --- a/system/bta/gatt/bta_gattc_act.cc +++ b/system/bta/gatt/bta_gattc_act.cc @@ -255,8 +255,7 @@ void bta_gattc_process_api_open(const tBTA_GATTC_DATA* p_msg) { tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if); if (!p_clreg) { - LOG(ERROR) << __func__ - << ": Failed, unknown client_if=" << +p_msg->api_conn.client_if; + LOG_ERROR("Failed, unknown client_if=%d", +p_msg->api_conn.client_if); return; } @@ -268,10 +267,10 @@ void bta_gattc_process_api_open(const tBTA_GATTC_DATA* p_msg) { tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_alloc_clcb( p_msg->api_conn.client_if, p_msg->api_conn.remote_bda, p_msg->api_conn.transport); - if (p_clcb != NULL) { + if (p_clcb != nullptr) { bta_gattc_sm_execute(p_clcb, event, p_msg); } else { - LOG(ERROR) << "No resources to open a new connection."; + LOG_ERROR("No resources to open a new connection."); bta_gattc_send_open_cback(p_clreg, GATT_NO_RESOURCES, p_msg->api_conn.remote_bda, GATT_INVALID_CONN_ID, @@ -367,7 +366,6 @@ void bta_gattc_open(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { p_data->api_conn.transport, p_data->api_conn.opportunistic, p_data->api_conn.initiating_phys)) { LOG(ERROR) << "Connection open failure"; - bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data); return; } @@ -387,7 +385,7 @@ void bta_gattc_open(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { static void bta_gattc_init_bk_conn(const tBTA_GATTC_API_OPEN* p_data, tBTA_GATTC_RCB* p_clreg) { if (!bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, true)) { - LOG_WARN("Unable to find space for acceptlist connection mask"); + LOG_WARN("Unable to find space for accept list connection mask"); bta_gattc_send_open_cback(p_clreg, GATT_NO_RESOURCES, p_data->remote_bda, GATT_INVALID_CONN_ID, BT_TRANSPORT_LE, 0); return; @@ -396,8 +394,8 @@ static void bta_gattc_init_bk_conn(const tBTA_GATTC_API_OPEN* p_data, /* always call open to hold a connection */ if (!GATT_Connect(p_data->client_if, p_data->remote_bda, false, p_data->transport, false)) { - LOG(ERROR) << __func__ - << " unable to connect to remote bd_addr=" << p_data->remote_bda; + LOG_ERROR("Unable to connect to remote bd_addr=%s", + p_data->remote_bda.ToString().c_str()); bta_gattc_send_open_cback(p_clreg, GATT_ERROR, p_data->remote_bda, GATT_INVALID_CONN_ID, BT_TRANSPORT_LE, 0); return; @@ -406,7 +404,7 @@ static void bta_gattc_init_bk_conn(const tBTA_GATTC_API_OPEN* p_data, uint16_t conn_id; if (!GATT_GetConnIdIfConnected(p_data->client_if, p_data->remote_bda, &conn_id, p_data->transport)) { - LOG_WARN("Not a connected remote device"); + LOG_INFO("Not a connected remote device yet"); return; } @@ -442,7 +440,9 @@ void bta_gattc_cancel_bk_conn(const tBTA_GATTC_API_CANCEL_OPEN* p_data) { if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, false)) { cb_data.status = GATT_SUCCESS; } else { - LOG(ERROR) << __func__ << ": failed"; + LOG_ERROR("failed for client_if=%d, remote_bda=%s, is_direct=false", + static_cast<int>(p_data->client_if), + p_data->remote_bda.ToString().c_str()); } } p_clreg = bta_gattc_cl_get_regcb(p_data->client_if); @@ -577,16 +577,17 @@ void bta_gattc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { tBTA_GATTC cb_data = { .close = { - .client_if = p_clcb->p_rcb->client_if, .conn_id = p_clcb->bta_conn_id, - .reason = GATT_CONN_OK, - .remote_bda = p_clcb->bda, .status = GATT_SUCCESS, + .client_if = p_clcb->p_rcb->client_if, + .remote_bda = p_clcb->bda, + .reason = GATT_CONN_OK, }, }; - if (p_clcb->transport == BT_TRANSPORT_BR_EDR) + if (p_clcb->transport == BT_TRANSPORT_BR_EDR) { bta_sys_conn_close(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda); + } bta_gattc_clcb_dealloc(p_clcb); diff --git a/system/bta/gatt/bta_gatts_act.cc b/system/bta/gatt/bta_gatts_act.cc index 3cd7b34bdf..3cd143ddec 100644 --- a/system/bta/gatt/bta_gatts_act.cc +++ b/system/bta/gatt/bta_gatts_act.cc @@ -489,18 +489,20 @@ void bta_gatts_close(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport)) { - if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) { - LOG(ERROR) << __func__ - << ": fail conn_id=" << loghex(p_msg->hdr.layer_specific); - } else { - status = GATT_SUCCESS; + LOG_DEBUG("Disconnecting gatt_if=%d, remote_bda=%s, transport=%d", +gatt_if, + remote_bda.ToString().c_str(), transport); + status = GATT_Disconnect(p_msg->hdr.layer_specific); + if (status != GATT_SUCCESS) { + LOG_ERROR("fail conn_id=%d", +p_msg->hdr.layer_specific); + status = GATT_ERROR; } p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); if (p_rcb && p_rcb->p_cback) { - if (transport == BT_TRANSPORT_BR_EDR) + if (transport == BT_TRANSPORT_BR_EDR) { bta_sys_conn_close(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); + } tBTA_GATTS bta_gatts; bta_gatts.status = status; diff --git a/system/bta/hearing_aid/hearing_aid.cc b/system/bta/hearing_aid/hearing_aid.cc index ce3c4c4a3a..61a83cdda0 100644 --- a/system/bta/hearing_aid/hearing_aid.cc +++ b/system/bta/hearing_aid/hearing_aid.cc @@ -359,8 +359,6 @@ class HearingAidImpl : public HearingAid { void OnGattConnected(tGATT_STATUS status, uint16_t conn_id, tGATT_IF client_if, RawAddress address, tBT_TRANSPORT transport, uint16_t mtu) { - VLOG(2) << __func__ << ": address=" << address << ", conn_id=" << conn_id; - HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { /* When Hearing Aid is quickly disabled and enabled in settings, this case @@ -371,6 +369,8 @@ class HearingAidImpl : public HearingAid { return; } + LOG(INFO) << __func__ << ": address=" << address << ", conn_id=" << conn_id; + if (status != GATT_SUCCESS) { if (!hearingDevice->connecting_actively) { // acceptlist connection failed, that's ok. @@ -402,6 +402,15 @@ class HearingAidImpl : public HearingAid { hearingDevice->connection_update_status = AWAITING; } + if (controller_get_interface()->supports_ble_2m_phy()) { + LOG(INFO) << address << " set preferred 2M PHY"; + BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0); + } + + // Set data length + // TODO(jpawlowski: for 16khz only 87 is required, optimize + BTM_SetBleDataLength(address, 167); + if (BTM_SecIsSecurityPending(address)) { /* if security collision happened, wait for encryption done * (BTA_GATTC_ENC_CMPL_CB_EVT) */ @@ -890,15 +899,6 @@ class HearingAidImpl : public HearingAid { void ConnectSocket(HearingDevice* hearingDevice, uint16_t psm) { tL2CAP_CFG_INFO cfg_info = tL2CAP_CFG_INFO{.mtu = 512}; - if (controller_get_interface()->supports_ble_2m_phy()) { - LOG(INFO) << hearingDevice->address << " set preferred PHY to 2M"; - BTM_BleSetPhy(hearingDevice->address, PHY_LE_2M, PHY_LE_2M, 0); - } - - // Set data length - // TODO(jpawlowski: for 16khz only 87 is required, optimize - BTM_SetBleDataLength(hearingDevice->address, 167); - SendEnableServiceChangedInd(hearingDevice); uint8_t service_id = hearingDevice->isLeft() diff --git a/system/bta/le_audio/client_parser.cc b/system/bta/le_audio/client_parser.cc index 9a42e057a6..e7d64613cf 100644 --- a/system/bta/le_audio/client_parser.cc +++ b/system/bta/le_audio/client_parser.cc @@ -31,8 +31,11 @@ #include "bta_le_audio_api.h" #include "gap_api.h" +#include "gatt_api.h" +#include "gd/common/strings.h" #include "le_audio_types.h" #include "osi/include/allocator.h" +#include "osi/include/log.h" using le_audio::types::acs_ac_record; @@ -379,11 +382,24 @@ bool PrepareAseCtpEnable(const std::vector<struct ctp_enable>& confs, std::vector<uint8_t>& value) { if (confs.size() == 0) return false; + if (confs.size() > UINT8_MAX) { + LOG_ERROR(" To many ASEs to update metadata"); + return false; + } + uint16_t msg_len = confs.size() * kCtpEnableMinLen + kAseNumSize + kCtpOpSize; - std::for_each(confs.begin(), confs.end(), - [&msg_len](const struct ctp_enable& conf) { - msg_len += conf.metadata.size(); - }); + for (auto& conf : confs) { + if (msg_len > GATT_MAX_ATTR_LEN) { + LOG_ERROR(" Message length above GATT maximum"); + return false; + } + if (conf.metadata.size() > UINT8_MAX) { + LOG_ERROR(" ase[%d] metadata length is invalid", conf.ase_id); + return false; + } + + msg_len += conf.metadata.size(); + } value.resize(msg_len); uint8_t* msg = value.data(); @@ -466,12 +482,25 @@ bool PrepareAseCtpUpdateMetadata( std::vector<uint8_t>& value) { if (confs.size() == 0) return false; + if (confs.size() > UINT8_MAX) { + LOG_ERROR(" To many ASEs to update metadata"); + return false; + } + uint16_t msg_len = confs.size() * kCtpUpdateMetadataMinLen + kAseNumSize + kCtpOpSize; - std::for_each(confs.begin(), confs.end(), - [&msg_len](const struct ctp_update_metadata& conf) { - msg_len += conf.metadata.size(); - }); + for (auto& conf : confs) { + if (msg_len > GATT_MAX_ATTR_LEN) { + LOG_ERROR(" Message length above GATT maximum"); + return false; + } + if (conf.metadata.size() > UINT8_MAX) { + LOG_ERROR(" ase[%d] metadata length is invalid", conf.ase_id); + return false; + } + + msg_len += conf.metadata.size(); + } value.resize(msg_len); uint8_t* msg = value.data(); diff --git a/system/bta/le_audio/state_machine.cc b/system/bta/le_audio/state_machine.cc index bb6f8f0a2d..2265f42900 100644 --- a/system/bta/le_audio/state_machine.cc +++ b/system/bta/le_audio/state_machine.cc @@ -367,12 +367,12 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { do { auto ases_pair = leAudioDevice->GetAsesByCisId(ase->cis_id); - if (ases_pair.sink) { + if (ases_pair.sink && ases_pair.sink->active) { ases_pair.sink->cis_conn_hdl = conn_handles[i]; ases_pair.sink->data_path_state = AudioStreamDataPathState::CIS_ASSIGNED; } - if (ases_pair.source) { + if (ases_pair.source && ases_pair.source->active) { ases_pair.source->cis_conn_hdl = conn_handles[i]; ases_pair.source->data_path_state = AudioStreamDataPathState::CIS_ASSIGNED; diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index bc59694759..5e8a5140c8 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -1209,7 +1209,8 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, /* inquiry result */ bt_bdname_t bdname; uint8_t remote_name_len; - tBTA_SERVICE_MASK services = 0; + uint8_t num_uuids = 0, max_num_uuid = 32; + uint8_t uuid_list[32 * Uuid::kNumBytes16]; p_search_data->inq_res.remt_name_not_required = check_eir_remote_name(p_search_data, NULL, NULL); @@ -1223,18 +1224,15 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, if (!check_eir_remote_name(p_search_data, bdname.name, &remote_name_len)) check_cached_remote_name(p_search_data, bdname.name, &remote_name_len); - /* Check EIR for remote name and services */ + /* Check EIR for services */ if (p_search_data->inq_res.p_eir) { - BTA_GetEirService(p_search_data->inq_res.p_eir, - p_search_data->inq_res.eir_len, &services); - BTIF_TRACE_DEBUG("%s()EIR BTA services = %08X", __func__, - (uint32_t)services); - /* TODO: Get the service list and check to see which uuids we got and - * send it back to the client. */ + BTM_GetEirUuidList(p_search_data->inq_res.p_eir, + p_search_data->inq_res.eir_len, Uuid::kNumBytes16, + &num_uuids, uuid_list, max_num_uuid); } { - bt_property_t properties[6]; + bt_property_t properties[7]; bt_device_type_t dev_type; uint32_t num_properties = 0; bt_status_t status; @@ -1298,6 +1296,21 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, &(p_search_data->inq_res.include_rsi)); num_properties++; + /* EIR queried services */ + std::vector<Uuid> uuid128_list; + if (num_uuids > 0) { + uint16_t* p_uuid16 = (uint16_t*)uuid_list; + for (int i = 0; i < num_uuids; ++i) { + Uuid uuid = Uuid::From16Bit(p_uuid16[i]); + uuid128_list.push_back(uuid); + } + + BTIF_STORAGE_FILL_PROPERTY( + &properties[num_properties], BT_PROPERTY_UUIDS, + num_uuids * Uuid::kNumBytes128, uuid128_list.data()); + num_properties++; + } + status = btif_storage_add_remote_device(&bdaddr, num_properties, properties); ASSERTC(status == BT_STATUS_SUCCESS, diff --git a/system/btif/src/btif_gatt_client.cc b/system/btif/src/btif_gatt_client.cc index 5f8cb3ffc8..915be7bb4a 100644 --- a/system/btif/src/btif_gatt_client.cc +++ b/system/btif/src/btif_gatt_client.cc @@ -378,12 +378,15 @@ void btif_gattc_open_impl(int client_if, RawAddress address, bool is_direct, else transport = BT_TRANSPORT_BR_EDR; break; + default: + LOG_ERROR("Unknown device type %d", +device_type); + break; } } // Connect! - LOG_INFO("%s Transport=%d, device type=%d, address type =%d, phy=%d", - __func__, transport, device_type, addr_type, initiating_phys); + LOG_INFO("Transport=%d, device type=%d, address type =%d, phy=%d", transport, + device_type, addr_type, initiating_phys); BTA_GATTC_Open(client_if, address, is_direct, transport, opportunistic, initiating_phys); } @@ -399,11 +402,14 @@ static bt_status_t btif_gattc_open(int client_if, const RawAddress& bd_addr, } void btif_gattc_close_impl(int client_if, RawAddress address, int conn_id) { + LOG_INFO("client_if=%d, conn_id=%d, address=%s", client_if, conn_id, + PRIVATE_ADDRESS(address)); // Disconnect established connections - if (conn_id != 0) + if (conn_id != 0) { BTA_GATTC_Close(conn_id); - else + } else { BTA_GATTC_CancelOpen(client_if, address, true); + } // Cancel pending background connections (remove from acceptlist) BTA_GATTC_CancelOpen(client_if, address, false); diff --git a/system/btif/src/btif_storage.cc b/system/btif/src/btif_storage.cc index 42f9b31ac1..865bcf9508 100644 --- a/system/btif/src/btif_storage.cc +++ b/system/btif/src/btif_storage.cc @@ -945,6 +945,10 @@ static void remove_devices_with_sample_ltk() { void btif_storage_load_consolidate_devices(void) { btif_bonded_devices_t bonded_devices; btif_in_fetch_bonded_devices(&bonded_devices, 1); + std::unordered_set<RawAddress> bonded_addresses; + for (uint16_t i = 0; i < bonded_devices.num_devices; i++) { + bonded_addresses.insert(bonded_devices.devices[i]); + } std::vector<std::pair<RawAddress, RawAddress>> consolidated_devices; for (uint16_t i = 0; i < bonded_devices.num_devices; i++) { @@ -953,7 +957,9 @@ void btif_storage_load_consolidate_devices(void) { if (btif_storage_get_ble_bonding_key( bonded_devices.devices[i], BTM_LE_KEY_PID, (uint8_t*)&key, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) { - if (bonded_devices.devices[i] != key.pid_key.identity_addr) { + if (bonded_devices.devices[i] != key.pid_key.identity_addr && + bonded_addresses.find(key.pid_key.identity_addr) != + bonded_addresses.end()) { LOG_INFO("found consolidated device %s %s", bonded_devices.devices[i].ToString().c_str(), key.pid_key.identity_addr.ToString().c_str()); diff --git a/system/gd/Android.bp b/system/gd/Android.bp index b005c4b797..8eca557cf7 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -289,14 +289,16 @@ cc_binary { shared_libs: [ "android.hardware.bluetooth@1.0", "android.hardware.bluetooth@1.1", - "android.system.suspend.control-V1-ndk", - "android.system.suspend-V1-ndk", "libbinder_ndk", "libhidlbase", "libutils", "libcutils", "libstatslog_bt", ], + static_libs: [ + "android.system.suspend.control-V1-ndk", + "android.system.suspend-V1-ndk", + ], }, host: { required: [ diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h index 0b828354d1..ea2eb1354e 100644 --- a/system/gd/hci/acl_manager/le_impl.h +++ b/system/gd/hci/acl_manager/le_impl.h @@ -305,7 +305,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { return; } - canceled_connections_.erase(remote_address); + arm_on_resume_ = false; ready_to_unregister = true; remove_device_from_connect_list(remote_address); @@ -390,7 +390,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { return; } - canceled_connections_.erase(remote_address); + arm_on_resume_ = false; ready_to_unregister = true; remove_device_from_connect_list(remote_address); @@ -795,7 +795,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } if (pause_connection) { - canceled_connections_.insert(address_with_type); + arm_on_resume_ = true; return; } @@ -811,7 +811,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { // If we added to filter accept list then the arming of the le state machine // must wait until the filter accept list command as completed if (add_to_connect_list) { - canceled_connections_.insert(address_with_type); + arm_on_resume_ = true; LOG_DEBUG("Deferred until filter accept list has completed"); } else { handler_->CallOn(this, &le_impl::arm_connectability); @@ -930,16 +930,16 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { le_address_manager_->AckPause(this); return; } - canceled_connections_ = connecting_le_; + arm_on_resume_ = !connecting_le_.empty(); disarm_connectability(); } void OnResume() override { // bluetooth::hci::LeAddressManagerCallback pause_connection = false; - if (!canceled_connections_.empty()) { + if (arm_on_resume_) { arm_connectability(); } - canceled_connections_.clear(); + arm_on_resume_ = false; le_address_manager_->AckResume(this); check_for_unregister(); } @@ -987,7 +987,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { LeConnectionCallbacks* le_client_callbacks_ = nullptr; os::Handler* le_client_handler_ = nullptr; std::unordered_set<AddressWithType> connecting_le_; - std::unordered_set<AddressWithType> canceled_connections_; + bool arm_on_resume_; std::unordered_set<AddressWithType> direct_connections_; // Set of devices that will not be removed from connect list after direct connect timeout std::unordered_set<AddressWithType> background_connections_; diff --git a/system/setup.py b/system/setup.py index cdb76f8a3a..597b9df2ed 100644 --- a/system/setup.py +++ b/system/setup.py @@ -29,7 +29,7 @@ force_install = False install_requires = [ 'grpcio', 'psutil', - 'protobuf>=3.14.0', + 'protobuf>=3.14.0, <4.0', 'mobly', ] diff --git a/system/stack/acl/ble_acl.cc b/system/stack/acl/ble_acl.cc index 448dabd12c..a09012a37b 100644 --- a/system/stack/acl/ble_acl.cc +++ b/system/stack/acl/ble_acl.cc @@ -65,8 +65,6 @@ static bool acl_ble_common_connection(const tBLE_BD_ADDR& address_with_type, return false; } - btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, true); - /* Tell BTM Acl management about the link */ btm_acl_created(address_with_type.bda, handle, role, BT_TRANSPORT_LE); @@ -154,12 +152,10 @@ void acl_ble_connection_fail(const tBLE_BD_ADDR& address_with_type, if (status != HCI_ERR_ADVERTISING_TIMEOUT) { btm_cb.ble_ctr_cb.set_connection_state_idle(); btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT); - btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, true); connection_manager::on_connection_timed_out_from_shim( address_with_type.bda); } else { btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; - btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true); } btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, &address_with_type.bda, status); diff --git a/system/stack/btm/btm_ble.cc b/system/stack/btm/btm_ble.cc index 55d7097587..9d313b3ea8 100644 --- a/system/stack/btm/btm_ble.cc +++ b/system/stack/btm/btm_ble.cc @@ -65,7 +65,7 @@ void BTM_SecAddBleDevice(const RawAddress& bd_addr, tBT_DEVICE_TYPE dev_type, return bluetooth::shim::BTM_SecAddBleDevice(bd_addr, dev_type, addr_type); } - BTM_TRACE_DEBUG("%s: dev_type=0x%x", __func__, dev_type); + LOG_DEBUG("dev_type=0x%x", dev_type); tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (!p_dev_rec) { @@ -81,27 +81,27 @@ void BTM_SecAddBleDevice(const RawAddress& bd_addr, tBT_DEVICE_TYPE dev_type, p_dev_rec->conn_params.supervision_tout = BTM_BLE_CONN_PARAM_UNDEF; p_dev_rec->conn_params.peripheral_latency = BTM_BLE_CONN_PARAM_UNDEF; - BTM_TRACE_DEBUG("%s: Device added, handle=0x%x, p_dev_rec=%p, bd_addr=%s", - __func__, p_dev_rec->ble_hci_handle, p_dev_rec, - bd_addr.ToString().c_str()); + LOG_DEBUG("Device added, handle=0x%x, p_dev_rec=%p, bd_addr=%s", + p_dev_rec->ble_hci_handle, p_dev_rec, bd_addr.ToString().c_str()); } memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME)); p_dev_rec->device_type |= dev_type; - if (is_ble_addr_type_known(addr_type)) + if (is_ble_addr_type_known(addr_type)) { p_dev_rec->ble.SetAddressType(addr_type); - else + } else { LOG_WARN( "Please do not update device record from anonymous le advertisement"); + } /* sync up with the Inq Data base*/ tBTM_INQ_INFO* p_info = BTM_InqDbRead(bd_addr); if (p_info) { p_info->results.ble_addr_type = p_dev_rec->ble.AddressType(); p_info->results.device_type = p_dev_rec->device_type; - BTM_TRACE_DEBUG("InqDb device_type =0x%x addr_type=0x%x", - p_info->results.device_type, p_info->results.ble_addr_type); + LOG_DEBUG("InqDb device_type =0x%x addr_type=0x%x", + p_info->results.device_type, p_info->results.ble_addr_type); } } diff --git a/system/stack/btm/btm_ble_bgconn.cc b/system/stack/btm/btm_ble_bgconn.cc index 965e0d08a1..d093aa5a2a 100644 --- a/system/stack/btm/btm_ble_bgconn.cc +++ b/system/stack/btm/btm_ble_bgconn.cc @@ -205,11 +205,9 @@ bool BTM_AcceptlistAdd(const RawAddress& address) { LOG_WARN("Controller does not support Le"); return false; } - - return bluetooth::shim::ACL_AcceptLeConnectionFrom( - convert_to_address_with_type(address, btm_find_dev(address)), - /* is_direct */ false); - + return bluetooth::shim::ACL_AcceptLeConnectionFrom( + convert_to_address_with_type(address, btm_find_dev(address)), + /* is_direct */ false); } /** Removes the device from acceptlist */ @@ -218,11 +216,8 @@ void BTM_AcceptlistRemove(const RawAddress& address) { LOG_WARN("Controller does not support Le"); return; } - - bluetooth::shim::ACL_IgnoreLeConnectionFrom( - convert_to_address_with_type(address, btm_find_dev(address))); - return; - + bluetooth::shim::ACL_IgnoreLeConnectionFrom( + convert_to_address_with_type(address, btm_find_dev(address))); } /** Clear the acceptlist, end any pending acceptlist connections */ @@ -231,7 +226,5 @@ void BTM_AcceptlistClear() { LOG_WARN("Controller does not support Le"); return; } - - bluetooth::shim::ACL_IgnoreAllLeConnections(); - return; + bluetooth::shim::ACL_IgnoreAllLeConnections(); } diff --git a/system/stack/btm/btm_ble_gap.cc b/system/stack/btm/btm_ble_gap.cc index 1365e76f7b..d87962f489 100644 --- a/system/stack/btm/btm_ble_gap.cc +++ b/system/stack/btm/btm_ble_gap.cc @@ -524,10 +524,6 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI : p_inq->scan_type; - /* assume observe always not using acceptlist */ - /* enable resolving list */ - btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN); - btm_send_hci_set_scan_params( p_inq->scan_type, (uint16_t)scan_interval, (uint16_t)scan_window, btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, BTM_BLE_DEFAULT_SFP); @@ -916,12 +912,6 @@ void btm_ble_start_sync_request(uint8_t sid, RawAddress addr, uint16_t skip, address_type = p_i->inq_info.results.ble_addr_type; // Random } btm_random_pseudo_to_identity_addr(&addr, &address_type); - if (address_type & BLE_ADDR_TYPE_ID_BIT) { -#if (BLE_PRIVACY_SPT == TRUE) - LOG_INFO("Enable resolving list"); - btm_ble_enable_resolving_list(BTM_BLE_RL_SCAN); -#endif - } address_type &= ~BLE_ADDR_TYPE_ID_BIT; uint8_t options = 0; uint8_t cte_type = 7; @@ -1111,9 +1101,6 @@ void btm_ble_periodic_adv_sync_established(uint8_t status, uint16_t sync_handle, tBLE_ADDR_TYPE ble_addr_type = to_ble_addr_type(address_type); if (ble_addr_type & BLE_ADDR_TYPE_ID_BIT) { btm_identity_addr_to_random_pseudo(&bda, &ble_addr_type, true); -#if (BLE_PRIVACY_SPT == TRUE) - btm_ble_disable_resolving_list(BTM_BLE_RL_SCAN, true); -#endif } int index = btm_ble_get_psync_index(adv_sid, bda); if (index == MAX_SYNC_TRANSACTION) { @@ -1531,16 +1518,12 @@ static uint8_t btm_set_conn_mode_adv_init_addr( /* only do so for bonded device */ if ((p_dev_rec = btm_find_or_alloc_dev(p_cb->direct_bda.bda)) != NULL && p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) { - btm_ble_enable_resolving_list(BTM_BLE_RL_ADV); p_peer_addr_ptr = p_dev_rec->ble.identity_address_with_type.bda; *p_peer_addr_type = p_dev_rec->ble.identity_address_with_type.type; *p_own_addr_type = BLE_ADDR_RANDOM_ID; return evt_type; } /* otherwise fall though as normal directed adv */ - else { - btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true); - } } /* direct adv mode does not have privacy, if privacy is not enabled */ *p_peer_addr_type = p_cb->direct_bda.type; @@ -1840,8 +1823,6 @@ tBTM_STATUS btm_ble_set_discoverability(uint16_t combined_mode) { /* start initial GAP mode adv timer */ alarm_set_on_mloop(p_cb->fast_adv_timer, BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS, btm_ble_fast_adv_timer_timeout, NULL); - } else { - btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true); } /* set up stop advertising timer */ @@ -1925,8 +1906,6 @@ tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode) { /* start initial GAP mode adv timer */ alarm_set_on_mloop(p_cb->fast_adv_timer, BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS, btm_ble_fast_adv_timer_timeout, NULL); - } else { - btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true); } return status; } @@ -2028,8 +2007,6 @@ tBTM_STATUS btm_ble_start_inquiry(uint8_t duration) { BTM_BLE_SCAN_MODE_ACTI, BTM_BLE_LOW_LATENCY_SCAN_INT, BTM_BLE_LOW_LATENCY_SCAN_WIN, btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, SP_ADV_ALL); - /* enable IRK list */ - btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN); p_ble_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_ACTI; btm_ble_start_scan(); } else if ((p_ble_cb->inq_var.scan_interval != @@ -3073,13 +3050,6 @@ tBTM_STATUS btm_ble_start_adv(void) { if (!btm_ble_adv_states_operation(btm_ble_topology_check, p_cb->evt_type)) return BTM_WRONG_MODE; - /* To relax resolving list, always have resolving list enabled, unless - * directed adv */ - if (p_cb->evt_type != BTM_BLE_CONNECT_LO_DUTY_DIR_EVT && - p_cb->evt_type != BTM_BLE_CONNECT_DIR_EVT) - /* enable resolving list is desired */ - btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_ADV); - btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_ENABLE); p_cb->adv_mode = BTM_BLE_ADV_ENABLE; btm_ble_adv_states_operation(btm_ble_set_topology_mask, p_cb->evt_type); diff --git a/system/stack/btm/btm_ble_int.h b/system/stack/btm/btm_ble_int.h index 8ca11f7a8c..25ab518dfb 100644 --- a/system/stack/btm/btm_ble_int.h +++ b/system/stack/btm/btm_ble_int.h @@ -121,12 +121,7 @@ extern bool btm_ble_addr_resolvable(const RawAddress& rpa, tBTM_SEC_DEV_REC* p_dev_rec); extern void btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC& p_dev_rec); -extern bool btm_ble_resolving_list_load_dev( - tBTM_SEC_DEV_REC* p_dev_rec); // DEPRECATED extern void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec); -extern void btm_ble_enable_resolving_list(uint8_t); -extern bool btm_ble_disable_resolving_list(uint8_t rl_mask, bool to_resume); -extern void btm_ble_enable_resolving_list_for_platform(uint8_t rl_mask); extern void btm_ble_resolving_list_init(uint8_t max_irk_list_sz); extern void btm_ble_adv_init(void); diff --git a/system/stack/btm/btm_ble_privacy.cc b/system/stack/btm/btm_ble_privacy.cc index f5e2b78f3f..0a3035dadf 100644 --- a/system/stack/btm/btm_ble_privacy.cc +++ b/system/stack/btm/btm_ble_privacy.cc @@ -503,131 +503,6 @@ bool btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) { return true; } -/******************************************************************************* - * - * Function btm_ble_disable_resolving_list - * - * Description Disable LE Address resolution - * - * Returns none - * - ******************************************************************************/ -bool btm_ble_disable_resolving_list(uint8_t rl_mask, bool to_resume) { - LOG_DEBUG("GD automatically disables Address Resolution list"); - return true; -} - -/******************************************************************************* - * - * Function btm_ble_resolving_list_load_dev - * - * Description This function adds a device which is using RPA into the - * acceptlist. - * - * Parameters pointer to device security record - * - * Returns true if device added, otherwise falase. - * - ******************************************************************************/ -bool btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC* p_dev_rec) { - ASSERT_LOG(false, - "API is disabled...use signature <void(tBTM_SEC_DEV_REC&)>"); - - const uint8_t rl_state = btm_cb.ble_ctr_cb.rl_state; - - if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) { - BTM_TRACE_DEBUG( - "%s: Controller does not support RPA offloading or privacy 1.2", - __func__); - return false; - } - - BTM_TRACE_DEBUG("%s: btm_cb.ble_ctr_cb.privacy_mode = %d", __func__, - btm_cb.ble_ctr_cb.privacy_mode); - - if (!p_dev_rec) { - BTM_TRACE_DEBUG("%s: No device security record", __func__); - return false; - } - - /* only add RPA enabled device into resolving list */ - if (controller_get_interface()->supports_ble_privacy()) { - if ((p_dev_rec->ble.key_type & (BTM_LE_KEY_PID | BTM_LE_KEY_LID)) == 0) { - BTM_TRACE_DEBUG("%s: privacy 1.2: Device not a RPA enabled device", - __func__); - return false; - } - } else if ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) == 0) { - BTM_TRACE_DEBUG("%s: RPA offloading: Device not a RPA enabled device", - __func__); - return false; - } - - if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) || - btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr, - BTM_BLE_META_ADD_IRK_ENTRY)) { - BTM_TRACE_ERROR("%s: Device already in Resolving list", __func__); - return true; - } - - if (btm_cb.ble_ctr_cb.resolving_list_avail_size == 0) { - return false; - } - - if (rl_state && !btm_ble_disable_resolving_list(rl_state, false)) { - return false; - } - - if (controller_get_interface()->supports_ble_privacy()) { - const Octet16& peer_irk = p_dev_rec->ble.keys.irk; - const Octet16& local_irk = btm_cb.devcb.id_keys.irk; - - if (p_dev_rec->ble.identity_address_with_type.bda.IsEmpty()) { - p_dev_rec->ble.identity_address_with_type.bda = p_dev_rec->bd_addr; - p_dev_rec->ble.identity_address_with_type.type = - p_dev_rec->ble.AddressType(); - } - - BTM_TRACE_DEBUG( - "%s: adding device %s to controller resolving list", __func__, - p_dev_rec->ble.identity_address_with_type.bda.ToString().c_str()); - - // use identical IRK for now - btsnd_hcic_ble_add_device_resolving_list( - p_dev_rec->ble.identity_address_with_type.type, - p_dev_rec->ble.identity_address_with_type.bda, peer_irk, local_irk); - - if (controller_get_interface()->supports_ble_set_privacy_mode()) { - BTM_TRACE_DEBUG("%s: adding device privacy mode", __func__); - btsnd_hcic_ble_set_privacy_mode( - p_dev_rec->ble.identity_address_with_type.type, - p_dev_rec->ble.identity_address_with_type.bda, 0x01); - } - } else { - uint8_t param[40] = {0}; - uint8_t* p = param; - - UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY); - ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, OCTET16_LEN); - UINT8_TO_STREAM(p, p_dev_rec->ble.identity_address_with_type.type); - BDADDR_TO_STREAM(p, p_dev_rec->ble.identity_address_with_type.bda); - - BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_META_ADD_IRK_LEN, - param, btm_ble_resolving_list_vsc_op_cmpl); - } - - btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr, - BTM_BLE_META_ADD_IRK_ENTRY); - - /* if resolving list has been turned on, re-enable it */ - if (rl_state) - btm_ble_enable_resolving_list(rl_state); - else - btm_ble_enable_resolving_list(BTM_BLE_RL_INIT); - - return true; -} - static void btm_ble_ble_unsupported_resolving_list_load_dev( tBTM_SEC_DEV_REC* p_dev_rec) { LOG_INFO("Controller does not support BLE privacy"); @@ -707,12 +582,7 @@ void btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC& dev_rec) { * ******************************************************************************/ void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) { - uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state; - BTM_TRACE_EVENT("%s", __func__); - if (rl_mask) { - if (!btm_ble_disable_resolving_list(rl_mask, false)) return; - } if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && !btm_ble_brcm_find_resolving_pending_entry( @@ -722,63 +592,6 @@ void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) { } else { BTM_TRACE_DEBUG("Device not in resolving list"); } - - /* if resolving list has been turned on, re-enable it */ - if (rl_mask) btm_ble_enable_resolving_list(rl_mask); -} - -/******************************************************************************* - * - * Function btm_ble_enable_resolving_list - * - * Description enable LE resolve address list - * - * Returns none - * - ******************************************************************************/ -void btm_ble_enable_resolving_list(uint8_t rl_mask) { - LOG_DEBUG("GD automatically enables Address Resolution list"); -} - -static bool is_on_resolving_list(void* data, void* context) { - tBTM_SEC_DEV_REC* p_dev = static_cast<tBTM_SEC_DEV_REC*>(data); - if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && - (p_dev->ble.in_controller_list & BTM_ACCEPTLIST_BIT)) - return false; - - return true; -} - -/******************************************************************************* - * - * Function btm_ble_enable_resolving_list_for_platform - * - * Description enable/disable resolving list feature depending on if any - * resolving list is empty and acceptlist is involoved in the - * operation. - * - * Returns none - * - ******************************************************************************/ -void btm_ble_enable_resolving_list_for_platform(uint8_t rl_mask) { - /* if controller does not support, skip */ - if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) - return; - - if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) { - if (controller_get_interface()->get_ble_resolving_list_max_size() > - btm_cb.ble_ctr_cb.resolving_list_avail_size) - btm_ble_enable_resolving_list(rl_mask); - else - btm_ble_disable_resolving_list(rl_mask, true); - return; - } - - list_node_t* n = list_foreach(btm_cb.sec_dev_rec, is_on_resolving_list, NULL); - if (n) - btm_ble_enable_resolving_list(rl_mask); - else - btm_ble_disable_resolving_list(rl_mask, true); } /******************************************************************************* diff --git a/system/stack/gatt/connection_manager.cc b/system/stack/gatt/connection_manager.cc index b2499b4949..c6052c236c 100644 --- a/system/stack/gatt/connection_manager.cc +++ b/system/stack/gatt/connection_manager.cc @@ -86,6 +86,7 @@ bool anyone_connecting( /** background connection device from the list. Returns pointer to the device * record, or nullptr if not found */ std::set<tAPP_ID> get_apps_connecting_to(const RawAddress& address) { + LOG_DEBUG("address=%s", address.ToString().c_str()); auto it = bgconn_dev.find(address); return (it != bgconn_dev.end()) ? it->second.doing_bg_conn : std::set<tAPP_ID>(); @@ -94,6 +95,8 @@ std::set<tAPP_ID> get_apps_connecting_to(const RawAddress& address) { /** Add a device from the background connection list. Returns true if device * added to the list, or already in list, false otherwise */ bool background_connect_add(uint8_t app_id, const RawAddress& address) { + LOG_DEBUG("app_id=%d, address=%s", static_cast<int>(app_id), + address.ToString().c_str()); if (bluetooth::shim::is_gd_l2cap_enabled()) { return L2CA_ConnectFixedChnl(L2CAP_ATT_CID, address); } @@ -103,23 +106,30 @@ bool background_connect_add(uint8_t app_id, const RawAddress& address) { if (it != bgconn_dev.end()) { // device already in the acceptlist, just add interested app to the list if (it->second.doing_bg_conn.count(app_id)) { - LOG(INFO) << "App id=" << loghex(app_id) - << "already doing background connection to " << address; + LOG_DEBUG("app_id=%d, already doing background connection to address=%s", + static_cast<int>(app_id), address.ToString().c_str()); return true; } // Already in acceptlist ? if (anyone_connecting(it)) { + LOG_DEBUG("app_id=%d, address=%s, already in accept list", + static_cast<int>(app_id), address.ToString().c_str()); in_acceptlist = true; } } if (!in_acceptlist) { // the device is not in the acceptlist - if (!BTM_AcceptlistAdd(address)) return false; + if (!BTM_AcceptlistAdd(address)) { + LOG_WARN("Failed to add device %s to accept list for app %d", + address.ToString().c_str(), static_cast<int>(app_id)); + return false; + } } - // create endtry for address, and insert app_id. + // create entry for address, and insert app_id. + // new tAPPS_CONNECTING will be default constructed if not exist bgconn_dev[address].doing_bg_conn.insert(app_id); return true; } @@ -127,8 +137,12 @@ bool background_connect_add(uint8_t app_id, const RawAddress& address) { /** Removes all registrations for connection for given device. * Returns true if anything was removed, false otherwise */ bool remove_unconditional(const RawAddress& address) { + LOG_DEBUG("address=%s", address.ToString().c_str()); auto it = bgconn_dev.find(address); - if (it == bgconn_dev.end()) return false; + if (it == bgconn_dev.end()) { + LOG_WARN("address %s is not found", address.ToString().c_str()); + return false; + } BTM_AcceptlistRemove(address); bgconn_dev.erase(it); @@ -140,25 +154,41 @@ bool remove_unconditional(const RawAddress& address) { * shim purposes. * Returns true if anything was removed, false otherwise */ bool remove_unconditional_from_shim(const RawAddress& address) { + LOG_DEBUG("address=%s", address.ToString().c_str()); auto it = bgconn_dev.find(address); - if (it == bgconn_dev.end()) return false; + if (it == bgconn_dev.end()) { + LOG_WARN("address %s is not found", address.ToString().c_str()); + return false; + } bgconn_dev.erase(it); return true; } /** Remove device from the background connection device list or listening to - * advertising list. Returns true if device was on the list and was succesfully - * removed */ + * advertising list. Returns true if device was on the list and was + * successfully removed */ bool background_connect_remove(uint8_t app_id, const RawAddress& address) { - VLOG(2) << __func__; + LOG_DEBUG("app_id=%d, address=%s", static_cast<int>(app_id), + address.ToString().c_str()); auto it = bgconn_dev.find(address); - if (it == bgconn_dev.end()) return false; + if (it == bgconn_dev.end()) { + LOG_WARN("address %s is not found", address.ToString().c_str()); + return false; + } - if (!it->second.doing_bg_conn.erase(app_id)) return false; + if (!it->second.doing_bg_conn.erase(app_id)) { + LOG_WARN("Failed to remove background connection app %d for address %s", + static_cast<int>(app_id), address.ToString().c_str()); + return false; + } - if (anyone_connecting(it)) return true; + if (anyone_connecting(it)) { + LOG_DEBUG("some device is still connecting, app_id=%d, address=%s", + static_cast<int>(app_id), address.ToString().c_str()); + return true; + } - // no more apps interested - remove from acceptlist and delete record + // no more apps interested - remove from accept list and delete record BTM_AcceptlistRemove(address); bgconn_dev.erase(it); return true; @@ -166,6 +196,7 @@ bool background_connect_remove(uint8_t app_id, const RawAddress& address) { /** deregister all related background connetion device. */ void on_app_deregistered(uint8_t app_id) { + LOG_DEBUG("app_id=%d", static_cast<int>(app_id)); auto it = bgconn_dev.begin(); auto end = bgconn_dev.end(); /* update the BG conn device list */ @@ -186,6 +217,7 @@ void on_app_deregistered(uint8_t app_id) { static void remove_all_clients_with_pending_connections( const RawAddress& address) { + LOG_DEBUG("address=%s", address.ToString().c_str()); auto it = bgconn_dev.find(address); while (it != bgconn_dev.end() && !it->second.doing_direct_conn.empty()) { uint8_t app_id = it->second.doing_direct_conn.begin()->first; @@ -212,6 +244,8 @@ void reset(bool after_reset) { } void wl_direct_connect_timeout_cb(uint8_t app_id, const RawAddress& address) { + LOG_DEBUG("app_id=%d, address=%s", static_cast<int>(app_id), + address.ToString().c_str()); on_connection_timed_out(app_id, address); // TODO: this would free the timer, from within the timer callback, which is @@ -222,6 +256,8 @@ void wl_direct_connect_timeout_cb(uint8_t app_id, const RawAddress& address) { /** Add a device to the direcgt connection list. Returns true if device * added to the list, false otherwise */ bool direct_connect_add(uint8_t app_id, const RawAddress& address) { + LOG_DEBUG("app_id=%d, address=%s", static_cast<int>(app_id), + address.ToString().c_str()); if (bluetooth::shim::is_gd_l2cap_enabled()) { return L2CA_ConnectFixedChnl(L2CAP_ATT_CID, address); } @@ -274,6 +310,8 @@ static bool any_direct_connect_left() { } bool direct_connect_remove(uint8_t app_id, const RawAddress& address) { + LOG_DEBUG("app_id=%d, address=%s", static_cast<int>(app_id), + address.ToString().c_str()); auto it = bgconn_dev.find(address); if (it == bgconn_dev.end()) { LOG_WARN("Unable to find background connection to remove"); diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc index ded621b2f6..b55e62563e 100644 --- a/system/stack/gatt/gatt_api.cc +++ b/system/stack/gatt/gatt_api.cc @@ -961,16 +961,17 @@ void GATT_SetIdleTimeout(const RawAddress& bd_addr, uint16_t idle_tout, bool status = false; tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport); - if (p_tcb != NULL) { + if (p_tcb != nullptr) { status = L2CA_SetLeGattTimeout(bd_addr, idle_tout); - if (idle_tout == GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP) + if (idle_tout == GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP) { L2CA_SetIdleTimeoutByBdAddr( p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, BT_TRANSPORT_LE); + } } - VLOG(1) << __func__ << " idle_tout=" << idle_tout << ", status=" << +status - << " (1-OK 0-not performed)"; + LOG_INFO("idle_timeout=%d, status=%d, (1-OK 0-not performed)", idle_tout, + +status); } /******************************************************************************* @@ -1162,22 +1163,18 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, bool is_direct, /* Make sure app is registered */ tGATT_REG* p_reg = gatt_get_regcb(gatt_if); if (!p_reg) { - LOG(ERROR) << __func__ - << ": Unable to find registered app gatt_if=" << +gatt_if; + LOG_ERROR("Unable to find registered app gatt_if=%d", +gatt_if); return false; } if (!is_direct && transport != BT_TRANSPORT_LE) { - LOG(ERROR) << __func__ - << ": Unsupported transport for background connection gatt_if=" - << +gatt_if; + LOG_WARN("Unsupported transport for background connection gatt_if=%d", + +gatt_if); return false; } if (opportunistic) { - LOG(INFO) << __func__ - << ": Registered for opportunistic connection gatt_if=" - << +gatt_if; + LOG_INFO("Registered for opportunistic connection gatt_if=%d", +gatt_if); return true; } @@ -1193,20 +1190,27 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, bool is_direct, // RPA can rotate, causing address to "expire" in the background // connection list. RPA is allowed for direct connect, as such request // times out after 30 seconds - LOG(INFO) << __func__ - << ": Unable to add RPA to background connection gatt_if=" - << +gatt_if; - ret = true; + LOG_WARN("Unable to add RPA %s to background connection gatt_if=%d", + bd_addr.ToString().c_str(), +gatt_if); + ret = false; } else { - LOG_DEBUG("Adding to acceptlist device:%s", PRIVATE_ADDRESS(bd_addr)); + LOG_DEBUG("Adding to accept list device:%s", PRIVATE_ADDRESS(bd_addr)); ret = connection_manager::background_connect_add(gatt_if, bd_addr); } } tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, transport); // background connections don't necessarily create tcb - if (p_tcb && ret) + if (p_tcb && ret) { gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, !is_direct); + } else { + if (p_tcb == nullptr) { + LOG_DEBUG("p_tcb is null"); + } + if (!ret) { + LOG_DEBUG("Previous step returned false"); + } + } return ret; } @@ -1239,10 +1243,11 @@ bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr, return false; } - if (is_direct) + if (is_direct) { return gatt_cancel_open(gatt_if, bd_addr); - else + } else { return gatt_auto_connect_dev_remove(p_reg->gatt_if, bd_addr); + } } VLOG(1) << " unconditional"; @@ -1283,11 +1288,14 @@ bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr, * ******************************************************************************/ tGATT_STATUS GATT_Disconnect(uint16_t conn_id) { - LOG(INFO) << __func__ << " conn_id=" << loghex(conn_id); + LOG_INFO("conn_id=%d", +conn_id); uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); - if (!p_tcb) return GATT_ILLEGAL_PARAMETER; + if (!p_tcb) { + LOG_WARN("Cannot find TCB for connection %d", conn_id); + return GATT_ILLEGAL_PARAMETER; + } tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); gatt_update_app_use_link_flag(gatt_if, p_tcb, false, true); @@ -1351,6 +1359,6 @@ bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, const RawAddress& bd_addr, status = true; } - VLOG(1) << __func__ << " status= " << +status; + LOG_DEBUG("status=%d", status); return status; } diff --git a/system/stack/gatt/gatt_main.cc b/system/stack/gatt/gatt_main.cc index 6b61708209..f2d0637b7a 100644 --- a/system/stack/gatt/gatt_main.cc +++ b/system/stack/gatt/gatt_main.cc @@ -290,26 +290,27 @@ bool gatt_disconnect(tGATT_TCB* p_tcb) { ******************************************************************************/ bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb, bool is_add) { + LOG_DEBUG("gatt_if=%d, is_add=%d, peer_bda=%s", +gatt_if, is_add, + p_tcb->peer_bda.ToString().c_str()); auto& holders = p_tcb->app_hold_link; - VLOG(1) << __func__; if (is_add) { auto ret = holders.insert(gatt_if); if (ret.second) { - VLOG(1) << "added gatt_if=" << +gatt_if; + LOG_DEBUG("added gatt_if=%d", +gatt_if); } else { - VLOG(1) << "attempt to add already existing gatt_if=" << +gatt_if; + LOG_DEBUG("attempt to add already existing gatt_if=%d", +gatt_if); } return true; } //! is_add if (!holders.erase(gatt_if)) { - VLOG(1) << "attempt to remove nonexisting gatt_if=" << +gatt_if; + LOG_WARN("attempt to remove non-existing gatt_if=%d", +gatt_if); return false; } - VLOG(1) << "removed gatt_if=" << +gatt_if; + LOG_INFO("removed gatt_if=%d", +gatt_if); return true; } @@ -326,16 +327,23 @@ bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb, ******************************************************************************/ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb, bool is_add, bool check_acl_link) { - VLOG(1) << StringPrintf("%s: is_add=%d chk_link=%d", __func__, is_add, - check_acl_link); + LOG_DEBUG("gatt_if=%d, is_add=%d chk_link=%d", +gatt_if, is_add, + check_acl_link); - if (!p_tcb) return; + if (!p_tcb) { + LOG_WARN("p_tcb is null"); + return; + } // If we make no modification, i.e. kill app that was never connected to a // device, skip updating the device state. - if (!gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add)) return; + if (!gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add)) { + LOG_INFO("App status is not updated for gatt_if=%d", +gatt_if); + return; + } if (!check_acl_link) { + LOG_INFO("check_acl_link is false, no need to check"); return; } @@ -345,28 +353,37 @@ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb, if (is_add) { if (p_tcb->att_lcid == L2CAP_ATT_CID && is_valid_handle) { - VLOG(1) << "disable link idle timer"; + LOG_INFO("disable link idle timer for %s", + p_tcb->peer_bda.ToString().c_str()); /* acl link is connected disable the idle timeout */ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport); + } else { + LOG_INFO("invalid handle %d or dynamic CID %d", is_valid_handle, + p_tcb->att_lcid); } } else { if (p_tcb->app_hold_link.empty()) { // acl link is connected but no application needs to use the link if (p_tcb->att_lcid == L2CAP_ATT_CID && is_valid_handle) { - /* Drop EATT before closing ATT */ EattExtension::GetInstance()->Disconnect(p_tcb->peer_bda); /* for fixed channel, set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */ - VLOG(1) << " start link idle timer = " - << GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP << " sec"; + LOG_INFO( + "GATT fixed channel is no longer useful, start link idle timer for " + "%d seconds", + GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP); GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport); - } else + } else { // disconnect the dynamic channel + LOG_INFO("disconnect GATT dynamic channel"); gatt_disconnect(p_tcb); + } + } else { + LOG_INFO("is_add=false, but some app is still using the ACL link"); } } } diff --git a/system/stack/gatt/gatt_utils.cc b/system/stack/gatt/gatt_utils.cc index 338b277aca..11a0f85eb6 100644 --- a/system/stack/gatt/gatt_utils.cc +++ b/system/stack/gatt/gatt_utils.cc @@ -409,7 +409,7 @@ tGATT_TCB* gatt_get_tcb_by_idx(uint8_t tcb_idx) { ******************************************************************************/ tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda, tBT_TRANSPORT transport) { - tGATT_TCB* p_tcb = NULL; + tGATT_TCB* p_tcb = nullptr; uint8_t i = 0; i = gatt_find_i_tcb_by_addr(bda, transport); diff --git a/system/stack/hcic/hciblecmds.cc b/system/stack/hcic/hciblecmds.cc index 63742022ab..25e66d6978 100644 --- a/system/stack/hcic/hciblecmds.cc +++ b/system/stack/hcic/hciblecmds.cc @@ -593,73 +593,6 @@ void btsnd_hcic_ble_rc_param_req_neg_reply(uint16_t handle, uint8_t reason) { btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); } -void btsnd_hcic_ble_add_device_resolving_list(uint8_t addr_type_peer, - const RawAddress& bda_peer, - const Octet16& irk_peer, - const Octet16& irk_local) { - BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); - uint8_t* pp = (uint8_t*)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST; - p->offset = 0; - - UINT16_TO_STREAM(pp, HCI_BLE_ADD_DEV_RESOLVING_LIST); - UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST); - UINT8_TO_STREAM(pp, addr_type_peer); - BDADDR_TO_STREAM(pp, bda_peer); - ARRAY_TO_STREAM(pp, irk_peer.data(), HCIC_BLE_ENCRYPT_KEY_SIZE); - ARRAY_TO_STREAM(pp, irk_local.data(), HCIC_BLE_ENCRYPT_KEY_SIZE); - - btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); -} - -void btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer, - const RawAddress& bda_peer) { - BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); - uint8_t* pp = (uint8_t*)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST; - p->offset = 0; - - UINT16_TO_STREAM(pp, HCI_BLE_RM_DEV_RESOLVING_LIST); - UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST); - UINT8_TO_STREAM(pp, addr_type_peer); - BDADDR_TO_STREAM(pp, bda_peer); - - btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); -} - -void btsnd_hcic_ble_set_privacy_mode(uint8_t addr_type_peer, - const RawAddress& bda_peer, - uint8_t privacy_type) { - BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); - uint8_t* pp = (uint8_t*)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_PRIVACY_MODE; - p->offset = 0; - - UINT16_TO_STREAM(pp, HCI_BLE_SET_PRIVACY_MODE); - UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_PRIVACY_MODE); - UINT8_TO_STREAM(pp, addr_type_peer); - BDADDR_TO_STREAM(pp, bda_peer); - UINT8_TO_STREAM(pp, privacy_type); - - btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); -} - -void btsnd_hcic_ble_clear_resolving_list(void) { - BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); - uint8_t* pp = (uint8_t*)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_RESOLVING_LIST; - p->offset = 0; - - UINT16_TO_STREAM(pp, HCI_BLE_CLEAR_RESOLVING_LIST); - UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_CLEAR_RESOLVING_LIST); - - btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); -} - void btsnd_hcic_ble_read_resolvable_addr_peer(uint8_t addr_type_peer, const RawAddress& bda_peer) { BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); diff --git a/system/stack/include/hcimsgs.h b/system/stack/include/hcimsgs.h index d35944a66c..6fe70a3e69 100644 --- a/system/stack/include/hcimsgs.h +++ b/system/stack/include/hcimsgs.h @@ -463,11 +463,6 @@ extern void btsnd_hcic_ble_set_data_length(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time); -extern void btsnd_hcic_ble_add_device_resolving_list(uint8_t addr_type_peer, - const RawAddress& bda_peer, - const Octet16& irk_peer, - const Octet16& irk_local); - struct scanning_phy_cfg { uint8_t scan_type; uint16_t scan_int; @@ -501,15 +496,6 @@ extern void btsnd_hcic_ble_ext_create_conn(uint8_t init_filter_policy, uint8_t initiating_phys, EXT_CONN_PHY_CFG* phy_cfg); -extern void btsnd_hcic_ble_rm_device_resolving_list( - tBLE_ADDR_TYPE addr_type_peer, const RawAddress& bda_peer); - -extern void btsnd_hcic_ble_set_privacy_mode(tBLE_ADDR_TYPE addr_type_peer, - const RawAddress& bda_peer, - uint8_t privacy_type); - -extern void btsnd_hcic_ble_clear_resolving_list(void); - extern void btsnd_hcic_ble_read_resolvable_addr_peer( uint8_t addr_type_peer, const RawAddress& bda_peer); diff --git a/system/stack/l2cap/l2c_ble.cc b/system/stack/l2cap/l2c_ble.cc index e3ce2c93b9..5ab208ced3 100755 --- a/system/stack/l2cap/l2c_ble.cc +++ b/system/stack/l2cap/l2c_ble.cc @@ -26,6 +26,7 @@ #include <base/logging.h> #include <base/strings/stringprintf.h> +#include <log/log.h> #include "bt_target.h" #include "bta/include/bta_hearing_aid_api.h" @@ -522,6 +523,15 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* Check how many channels remote side wants. */ num_of_channels = (p_pkt_end - p) / sizeof(uint16_t); + if (num_of_channels > L2CAP_CREDIT_BASED_MAX_CIDS) { + android_errorWriteLog(0x534e4554, "232256974"); + LOG_WARN("L2CAP - invalid number of channels requested: %d", + num_of_channels); + l2cu_reject_credit_based_conn_req(p_lcb, id, + L2CAP_CREDIT_BASED_MAX_CIDS, + L2CAP_LE_RESULT_INVALID_PARAMETERS); + return; + } LOG_DEBUG( "Recv L2CAP_CMD_CREDIT_BASED_CONN_REQ with " diff --git a/system/stack/rfcomm/port_api.cc b/system/stack/rfcomm/port_api.cc index 56b0fd1d0f..cca0f05310 100644 --- a/system/stack/rfcomm/port_api.cc +++ b/system/stack/rfcomm/port_api.cc @@ -516,7 +516,7 @@ bool PORT_IsOpening(RawAddress* bd_addr) { } LOG_INFO("RFC_MX_STATE_CONNECTED, found_port=%d, tRFC_PORT_STATE=%d", - found_port, p_port->rfc.state); + found_port, p_port != nullptr ? p_port->rfc.state : 0); if ((!found_port) || (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) { /* Port is not established yet. */ diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc index 7ec7c63598..6d8f007c72 100644 --- a/system/stack/smp/smp_act.cc +++ b/system/stack/smp/smp_act.cc @@ -902,15 +902,6 @@ void smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { } SMP_TRACE_DEBUG("%s: use h7 = %d", __func__, p_cb->key_derivation_h7_used); - /* SMP over BR/EDR should always be used with CTKD, so derive LTK from - * LK before receiving keys */ - if ((p_cb->role == HCI_ROLE_CENTRAL && - (p_cb->local_i_key & SMP_SEC_KEY_TYPE_ENC)) || - (p_cb->role == HCI_ROLE_PERIPHERAL && - (p_cb->local_r_key & SMP_SEC_KEY_TYPE_ENC))) { - smp_generate_ltk(p_cb, p_data); - } - SMP_TRACE_DEBUG( "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x (i-initiator r-responder)", __func__, p_cb->local_i_key, p_cb->local_r_key); diff --git a/system/stack/smp/smp_keys.cc b/system/stack/smp/smp_keys.cc index 8add0a9546..ac9f67423f 100644 --- a/system/stack/smp/smp_keys.cc +++ b/system/stack/smp/smp_keys.cc @@ -533,7 +533,7 @@ static void smp_generate_ltk_cont(uint16_t div, tSMP_CB* p_cb) { void smp_generate_ltk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { SMP_TRACE_DEBUG("%s", __func__); - if (p_cb->smp_over_br) { + if (smp_get_br_state() == SMP_BR_STATE_BOND_PENDING) { smp_br_process_link_key(p_cb, NULL); return; } else if (p_cb->le_secure_connections_mode_is_used) { diff --git a/system/test/mock/mock_stack_btm_ble_privacy.cc b/system/test/mock/mock_stack_btm_ble_privacy.cc index 49e29d21e2..e4d9c34c87 100644 --- a/system/test/mock/mock_stack_btm_ble_privacy.cc +++ b/system/test/mock/mock_stack_btm_ble_privacy.cc @@ -59,12 +59,8 @@ struct btm_ble_read_resolving_list_entry_complete struct btm_ble_remove_resolving_list_entry btm_ble_remove_resolving_list_entry; struct btm_ble_clear_resolving_list btm_ble_clear_resolving_list; struct btm_ble_read_resolving_list_entry btm_ble_read_resolving_list_entry; -struct btm_ble_disable_resolving_list btm_ble_disable_resolving_list; struct btm_ble_resolving_list_load_dev btm_ble_resolving_list_load_dev; struct btm_ble_resolving_list_remove_dev btm_ble_resolving_list_remove_dev; -struct btm_ble_enable_resolving_list btm_ble_enable_resolving_list; -struct btm_ble_enable_resolving_list_for_platform - btm_ble_enable_resolving_list_for_platform; struct btm_ble_resolving_list_init btm_ble_resolving_list_init; } // namespace stack_btm_ble_privacy @@ -108,16 +104,6 @@ bool btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) { return test::mock::stack_btm_ble_privacy::btm_ble_read_resolving_list_entry( p_dev_rec); } -bool btm_ble_disable_resolving_list(uint8_t rl_mask, bool to_resume) { - mock_function_count_map[__func__]++; - return test::mock::stack_btm_ble_privacy::btm_ble_disable_resolving_list( - rl_mask, to_resume); -} -bool btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC* p_dev_rec) { - mock_function_count_map[__func__]++; - return test::mock::stack_btm_ble_privacy::btm_ble_resolving_list_load_dev( - p_dev_rec); -} void btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC& p_dev_rec) { mock_function_count_map[__func__]++; } @@ -126,15 +112,6 @@ void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) { test::mock::stack_btm_ble_privacy::btm_ble_resolving_list_remove_dev( p_dev_rec); } -void btm_ble_enable_resolving_list(uint8_t rl_mask) { - mock_function_count_map[__func__]++; - test::mock::stack_btm_ble_privacy::btm_ble_enable_resolving_list(rl_mask); -} -void btm_ble_enable_resolving_list_for_platform(uint8_t rl_mask) { - mock_function_count_map[__func__]++; - test::mock::stack_btm_ble_privacy::btm_ble_enable_resolving_list_for_platform( - rl_mask); -} void btm_ble_resolving_list_init(uint8_t max_irk_list_sz) { mock_function_count_map[__func__]++; test::mock::stack_btm_ble_privacy::btm_ble_resolving_list_init( diff --git a/system/test/mock/mock_stack_btm_ble_privacy.h b/system/test/mock/mock_stack_btm_ble_privacy.h index 58ea637e1f..35e82e540d 100644 --- a/system/test/mock/mock_stack_btm_ble_privacy.h +++ b/system/test/mock/mock_stack_btm_ble_privacy.h @@ -116,24 +116,13 @@ struct btm_ble_read_resolving_list_entry { }; extern struct btm_ble_read_resolving_list_entry btm_ble_read_resolving_list_entry; -// Name: btm_ble_disable_resolving_list -// Params: uint8_t rl_mask, bool to_resume -// Returns: bool -struct btm_ble_disable_resolving_list { - std::function<bool(uint8_t rl_mask, bool to_resume)> body{ - [](uint8_t rl_mask, bool to_resume) { return false; }}; - bool operator()(uint8_t rl_mask, bool to_resume) { - return body(rl_mask, to_resume); - }; -}; -extern struct btm_ble_disable_resolving_list btm_ble_disable_resolving_list; // Name: btm_ble_resolving_list_load_dev // Params: tBTM_SEC_DEV_REC* p_dev_rec -// Returns: bool +// Returns: void struct btm_ble_resolving_list_load_dev { - std::function<bool(tBTM_SEC_DEV_REC* p_dev_rec)> body{ - [](tBTM_SEC_DEV_REC* p_dev_rec) { return false; }}; - bool operator()(tBTM_SEC_DEV_REC* p_dev_rec) { return body(p_dev_rec); }; + std::function<void(const tBTM_SEC_DEV_REC& p_dev_rec)> body{ + [](const tBTM_SEC_DEV_REC& p_dev_rec) {}}; + void operator()(const tBTM_SEC_DEV_REC& p_dev_rec) { body(p_dev_rec); }; }; extern struct btm_ble_resolving_list_load_dev btm_ble_resolving_list_load_dev; // Name: btm_ble_resolving_list_remove_dev @@ -146,14 +135,6 @@ struct btm_ble_resolving_list_remove_dev { }; extern struct btm_ble_resolving_list_remove_dev btm_ble_resolving_list_remove_dev; -// Name: btm_ble_enable_resolving_list -// Params: uint8_t rl_mask -// Returns: void -struct btm_ble_enable_resolving_list { - std::function<void(uint8_t rl_mask)> body{[](uint8_t rl_mask) {}}; - void operator()(uint8_t rl_mask) { body(rl_mask); }; -}; -extern struct btm_ble_enable_resolving_list btm_ble_enable_resolving_list; // Name: btm_ble_enable_resolving_list_for_platform // Params: uint8_t rl_mask // Returns: void diff --git a/system/test/mock/mock_stack_hcic_hciblecmds.cc b/system/test/mock/mock_stack_hcic_hciblecmds.cc index f0c43e7f2f..0f8ee48031 100644 --- a/system/test/mock/mock_stack_hcic_hciblecmds.cc +++ b/system/test/mock/mock_stack_hcic_hciblecmds.cc @@ -49,10 +49,7 @@ struct btsnd_hcic_accept_cis_req btsnd_hcic_accept_cis_req; struct btsnd_hcic_big_create_sync btsnd_hcic_big_create_sync; struct btsnd_hcic_big_term_sync btsnd_hcic_big_term_sync; struct btsnd_hcic_ble_add_acceptlist btsnd_hcic_ble_add_acceptlist; -struct btsnd_hcic_ble_add_device_resolving_list - btsnd_hcic_ble_add_device_resolving_list; struct btsnd_hcic_ble_clear_acceptlist btsnd_hcic_ble_clear_acceptlist; -struct btsnd_hcic_ble_clear_resolving_list btsnd_hcic_ble_clear_resolving_list; struct btsnd_hcic_ble_create_conn_cancel btsnd_hcic_ble_create_conn_cancel; struct btsnd_hcic_ble_create_ll_conn btsnd_hcic_ble_create_ll_conn; struct btsnd_hcic_ble_enh_rx_test btsnd_hcic_ble_enh_rx_test; @@ -86,8 +83,6 @@ struct btsnd_hcic_ble_read_resolvable_addr_peer struct btsnd_hcic_ble_receiver_test btsnd_hcic_ble_receiver_test; struct btsnd_hcic_ble_remove_from_acceptlist btsnd_hcic_ble_remove_from_acceptlist; -struct btsnd_hcic_ble_rm_device_resolving_list - btsnd_hcic_ble_rm_device_resolving_list; struct btsnd_hcic_ble_set_addr_resolution_enable btsnd_hcic_ble_set_addr_resolution_enable; struct btsnd_hcic_ble_set_adv_data btsnd_hcic_ble_set_adv_data; @@ -194,24 +189,12 @@ void btsnd_hcic_ble_add_acceptlist( test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_add_acceptlist( addr_type, bda, std::move(cb)); } -void btsnd_hcic_ble_add_device_resolving_list(uint8_t addr_type_peer, - const RawAddress& bda_peer, - const Octet16& irk_peer, - const Octet16& irk_local) { - mock_function_count_map[__func__]++; - test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_add_device_resolving_list( - addr_type_peer, bda_peer, irk_peer, irk_local); -} void btsnd_hcic_ble_clear_acceptlist( base::OnceCallback<void(uint8_t*, uint16_t)> cb) { mock_function_count_map[__func__]++; test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_clear_acceptlist( std::move(cb)); } -void btsnd_hcic_ble_clear_resolving_list(void) { - mock_function_count_map[__func__]++; - test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_clear_resolving_list(); -} void btsnd_hcic_ble_create_conn_cancel(void) { mock_function_count_map[__func__]++; test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_create_conn_cancel(); @@ -359,12 +342,6 @@ void btsnd_hcic_ble_remove_from_acceptlist( test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_remove_from_acceptlist( addr_type, bda, std::move(cb)); } -void btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer, - const RawAddress& bda_peer) { - mock_function_count_map[__func__]++; - test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_rm_device_resolving_list( - addr_type_peer, bda_peer); -} void btsnd_hcic_ble_set_addr_resolution_enable(uint8_t addr_resolution_enable) { mock_function_count_map[__func__]++; test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_set_addr_resolution_enable( |