Loading android/app/src/com/android/bluetooth/bass_client/BassClientService.java +29 −6 Original line number Diff line number Diff line Loading @@ -69,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; Loading Loading @@ -326,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) { Loading Loading @@ -633,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) Loading Loading @@ -688,6 +710,7 @@ public class BassClientService extends ProfileService { scanner.stopScan(mSearchScanCallback); mSearchScanCallback = null; mCallbacks.notifySearchStopped(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); mScanBroadcasts.clear(); } } Loading android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +25 −3 Original line number Diff line number Diff line Loading @@ -436,7 +436,13 @@ public class BassClientStateMachine extends StateMachine { channel.setSelected(false); subGroup.addChannel(channel.build()); } subGroup.setCodecId(ByteBuffer.wrap(baseLevel2.codecId).getLong()); 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. Loading @@ -444,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(); } Loading Loading @@ -634,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]; Loading @@ -644,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>(); Loading @@ -659,6 +679,8 @@ public class BassClientStateMachine extends StateMachine { offset += BassConstants.BCAST_RCVR_STATE_BIS_SYNC_SIZE; log("BIS index byte array: "); BassUtils.printByteArray(audioSyncIndex); ByteBuffer wrapped = ByteBuffer.wrap(reverseBytes(audioSyncIndex)); audioSyncState.add((long) wrapped.getInt()); byte metaDataLength = receiverState[offset++]; if (metaDataLength > 0) { Loading Loading
android/app/src/com/android/bluetooth/bass_client/BassClientService.java +29 −6 Original line number Diff line number Diff line Loading @@ -69,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; Loading Loading @@ -326,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) { Loading Loading @@ -633,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) Loading Loading @@ -688,6 +710,7 @@ public class BassClientService extends ProfileService { scanner.stopScan(mSearchScanCallback); mSearchScanCallback = null; mCallbacks.notifySearchStopped(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); mScanBroadcasts.clear(); } } Loading
android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +25 −3 Original line number Diff line number Diff line Loading @@ -436,7 +436,13 @@ public class BassClientStateMachine extends StateMachine { channel.setSelected(false); subGroup.addChannel(channel.build()); } subGroup.setCodecId(ByteBuffer.wrap(baseLevel2.codecId).getLong()); 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. Loading @@ -444,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(); } Loading Loading @@ -634,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]; Loading @@ -644,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>(); Loading @@ -659,6 +679,8 @@ public class BassClientStateMachine extends StateMachine { offset += BassConstants.BCAST_RCVR_STATE_BIS_SYNC_SIZE; log("BIS index byte array: "); BassUtils.printByteArray(audioSyncIndex); ByteBuffer wrapped = ByteBuffer.wrap(reverseBytes(audioSyncIndex)); audioSyncState.add((long) wrapped.getInt()); byte metaDataLength = receiverState[offset++]; if (metaDataLength > 0) { Loading