Loading android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +59 −11 Original line number Original line Diff line number Diff line Loading @@ -63,9 +63,12 @@ import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothLeAudioCodecConfigMetadata; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastChannel; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastSubgroup; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.le.PeriodicAdvertisingCallback; import android.bluetooth.le.PeriodicAdvertisingCallback; Loading Loading @@ -390,6 +393,40 @@ public class BassClientStateMachine extends StateMachine { mNoStopScanOffload = false; mNoStopScanOffload = false; } } private BluetoothLeBroadcastMetadata getBroadcastMetadataFromBaseData(BaseData baseData, BluetoothDevice device) { BluetoothLeBroadcastMetadata.Builder metaData = new BluetoothLeBroadcastMetadata.Builder(); int index = 0; for (BaseData.BaseInformation baseLevel2 : baseData.getLevelTwo()) { BluetoothLeBroadcastSubgroup.Builder subGroup = new BluetoothLeBroadcastSubgroup.Builder(); for (int j = 0; j < baseLevel2.numSubGroups; j ++) { BaseData.BaseInformation baseLevel3 = baseData.getLevelThree().get(index++); BluetoothLeBroadcastChannel.Builder channel = new BluetoothLeBroadcastChannel.Builder(); channel.setChannelIndex(baseLevel3.index); channel.setCodecMetadata(BluetoothLeAudioCodecConfigMetadata. fromRawBytes(baseLevel3.codecConfigInfo)); 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])); subGroup.setCodecSpecificConfig(BluetoothLeAudioCodecConfigMetadata. fromRawBytes(baseLevel2.codecConfigInfo)); subGroup.setContentMetadata(BluetoothLeAudioContentMetadata. fromRawBytes(baseLevel2.metaData)); metaData.addSubgroup(subGroup.build()); } metaData.setSourceDevice(device, device.getAddressType()); return metaData.build(); } /** Internal periodc Advertising manager callback */ /** Internal periodc Advertising manager callback */ private PeriodicAdvertisingCallback mPeriodicAdvCallback = private PeriodicAdvertisingCallback mPeriodicAdvCallback = new PeriodicAdvertisingCallback() { new PeriodicAdvertisingCallback() { Loading Loading @@ -435,6 +472,13 @@ public class BassClientStateMachine extends StateMachine { // Parse the BIS indices from report's service data // Parse the BIS indices from report's service data if (mFirstTimeBisDiscovery) { if (mFirstTimeBisDiscovery) { parseScanRecord(report.getSyncHandle(), report.getData()); parseScanRecord(report.getSyncHandle(), report.getData()); BaseData baseData = mService.getBase(report.getSyncHandle()); if (baseData != null) { BluetoothLeBroadcastMetadata metaData = getBroadcastMetadataFromBaseData(baseData, mService.getDeviceForSyncHandle(report.getSyncHandle())); mService.getCallbacks().notifySourceFound(metaData); } mFirstTimeBisDiscovery = false; mFirstTimeBisDiscovery = false; } } } } Loading Loading @@ -524,13 +568,15 @@ public class BassClientStateMachine extends StateMachine { } } log("processBroadcastReceiverState: receiverState length: " + receiverState.length); log("processBroadcastReceiverState: receiverState length: " + receiverState.length); BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothLeBroadcastReceiveState recvState = null; BluetoothLeBroadcastReceiveState recvState = null; if (receiverState.length == 0 if (receiverState.length == 0 || isEmpty(Arrays.copyOfRange(receiverState, 1, receiverState.length - 1))) { || isEmpty(Arrays.copyOfRange(receiverState, 1, receiverState.length - 1))) { String emptyBluetoothDevice = "00:00:00:00:00:00"; if (mPendingOperation == REMOVE_BCAST_SOURCE) { if (mPendingOperation == REMOVE_BCAST_SOURCE) { recvState = new BluetoothLeBroadcastReceiveState(mPendingSourceId, recvState = new BluetoothLeBroadcastReceiveState(mPendingSourceId, BluetoothDevice.ADDRESS_TYPE_UNKNOWN, // sourceAddressType BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType null, // sourceDevice btAdapter.getRemoteDevice(emptyBluetoothDevice), // sourceDevice 0, // sourceAdvertisingSid 0, // sourceAdvertisingSid 0, // broadcastId 0, // broadcastId BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState Loading @@ -538,8 +584,8 @@ public class BassClientStateMachine extends StateMachine { BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null, // badCode null, // badCode 0, // numSubgroups 0, // numSubgroups null, // bisSyncState Arrays.asList(new Long[0]), // bisSyncState null // subgroupMetadata Arrays.asList(new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata ); ); } else if (receiverState.length == 0) { } else if (receiverState.length == 0) { if (mBluetoothLeBroadcastReceiveStates != null) { if (mBluetoothLeBroadcastReceiveStates != null) { Loading @@ -551,8 +597,8 @@ public class BassClientStateMachine extends StateMachine { } } mNextSourceId++; mNextSourceId++; recvState = new BluetoothLeBroadcastReceiveState(mNextSourceId, recvState = new BluetoothLeBroadcastReceiveState(mNextSourceId, BluetoothDevice.ADDRESS_TYPE_UNKNOWN, // sourceAddressType BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType null, // sourceDevice btAdapter.getRemoteDevice(emptyBluetoothDevice), // sourceDevice 0, // sourceAdvertisingSid 0, // sourceAdvertisingSid 0, // broadcastId 0, // broadcastId BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState Loading @@ -560,8 +606,8 @@ public class BassClientStateMachine extends StateMachine { BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null, // badCode null, // badCode 0, // numSubgroups 0, // numSubgroups null, // bisSyncState Arrays.asList(new Long[0]), // bisSyncState null // subgroupMetadata Arrays.asList(new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata ); ); } } } else { } else { Loading Loading @@ -614,7 +660,6 @@ public class BassClientStateMachine extends StateMachine { 0, 0, mBroadcastSourceIdLength); mBroadcastSourceIdLength); int broadcastId = BassUtils.parseBroadcastId(broadcastIdBytes); int broadcastId = BassUtils.parseBroadcastId(broadcastIdBytes); BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); byte[] sourceAddress = new byte[BassConstants.BCAST_RCVR_STATE_SRC_ADDR_SIZE]; byte[] sourceAddress = new byte[BassConstants.BCAST_RCVR_STATE_SRC_ADDR_SIZE]; System.arraycopy( System.arraycopy( receiverState, receiverState, Loading Loading @@ -672,7 +717,9 @@ public class BassClientStateMachine extends StateMachine { log("old sourceInfo: " + oldRecvState); log("old sourceInfo: " + oldRecvState); log("new sourceInfo: " + recvState); log("new sourceInfo: " + recvState); mBluetoothLeBroadcastReceiveStates.replace(characteristic.getInstanceId(), recvState); mBluetoothLeBroadcastReceiveStates.replace(characteristic.getInstanceId(), recvState); if (oldRecvState.getSourceDevice() == null) { String emptyBluetoothDevice = "00:00:00:00:00:00"; if (oldRecvState.getSourceDevice() == null || oldRecvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { log("New Source Addition"); log("New Source Addition"); mService.getCallbacks().notifySourceAdded(mDevice, mService.getCallbacks().notifySourceAdded(mDevice, recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); Loading @@ -682,7 +729,8 @@ public class BassClientStateMachine extends StateMachine { checkAndUpdateBroadcastCode(recvState); checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); processPASyncState(recvState); } else { } else { if (recvState.getSourceDevice() == null) { if (recvState.getSourceDevice() == null || recvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { BluetoothDevice removedDevice = oldRecvState.getSourceDevice(); BluetoothDevice removedDevice = oldRecvState.getSourceDevice(); log("sourceInfo removal" + removedDevice); log("sourceInfo removal" + removedDevice); cancelActiveSync(removedDevice); cancelActiveSync(removedDevice); Loading Loading
android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +59 −11 Original line number Original line Diff line number Diff line Loading @@ -63,9 +63,12 @@ import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothGattService; import android.bluetooth.BluetoothLeAudioCodecConfigMetadata; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastChannel; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastSubgroup; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.le.PeriodicAdvertisingCallback; import android.bluetooth.le.PeriodicAdvertisingCallback; Loading Loading @@ -390,6 +393,40 @@ public class BassClientStateMachine extends StateMachine { mNoStopScanOffload = false; mNoStopScanOffload = false; } } private BluetoothLeBroadcastMetadata getBroadcastMetadataFromBaseData(BaseData baseData, BluetoothDevice device) { BluetoothLeBroadcastMetadata.Builder metaData = new BluetoothLeBroadcastMetadata.Builder(); int index = 0; for (BaseData.BaseInformation baseLevel2 : baseData.getLevelTwo()) { BluetoothLeBroadcastSubgroup.Builder subGroup = new BluetoothLeBroadcastSubgroup.Builder(); for (int j = 0; j < baseLevel2.numSubGroups; j ++) { BaseData.BaseInformation baseLevel3 = baseData.getLevelThree().get(index++); BluetoothLeBroadcastChannel.Builder channel = new BluetoothLeBroadcastChannel.Builder(); channel.setChannelIndex(baseLevel3.index); channel.setCodecMetadata(BluetoothLeAudioCodecConfigMetadata. fromRawBytes(baseLevel3.codecConfigInfo)); 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])); subGroup.setCodecSpecificConfig(BluetoothLeAudioCodecConfigMetadata. fromRawBytes(baseLevel2.codecConfigInfo)); subGroup.setContentMetadata(BluetoothLeAudioContentMetadata. fromRawBytes(baseLevel2.metaData)); metaData.addSubgroup(subGroup.build()); } metaData.setSourceDevice(device, device.getAddressType()); return metaData.build(); } /** Internal periodc Advertising manager callback */ /** Internal periodc Advertising manager callback */ private PeriodicAdvertisingCallback mPeriodicAdvCallback = private PeriodicAdvertisingCallback mPeriodicAdvCallback = new PeriodicAdvertisingCallback() { new PeriodicAdvertisingCallback() { Loading Loading @@ -435,6 +472,13 @@ public class BassClientStateMachine extends StateMachine { // Parse the BIS indices from report's service data // Parse the BIS indices from report's service data if (mFirstTimeBisDiscovery) { if (mFirstTimeBisDiscovery) { parseScanRecord(report.getSyncHandle(), report.getData()); parseScanRecord(report.getSyncHandle(), report.getData()); BaseData baseData = mService.getBase(report.getSyncHandle()); if (baseData != null) { BluetoothLeBroadcastMetadata metaData = getBroadcastMetadataFromBaseData(baseData, mService.getDeviceForSyncHandle(report.getSyncHandle())); mService.getCallbacks().notifySourceFound(metaData); } mFirstTimeBisDiscovery = false; mFirstTimeBisDiscovery = false; } } } } Loading Loading @@ -524,13 +568,15 @@ public class BassClientStateMachine extends StateMachine { } } log("processBroadcastReceiverState: receiverState length: " + receiverState.length); log("processBroadcastReceiverState: receiverState length: " + receiverState.length); BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothLeBroadcastReceiveState recvState = null; BluetoothLeBroadcastReceiveState recvState = null; if (receiverState.length == 0 if (receiverState.length == 0 || isEmpty(Arrays.copyOfRange(receiverState, 1, receiverState.length - 1))) { || isEmpty(Arrays.copyOfRange(receiverState, 1, receiverState.length - 1))) { String emptyBluetoothDevice = "00:00:00:00:00:00"; if (mPendingOperation == REMOVE_BCAST_SOURCE) { if (mPendingOperation == REMOVE_BCAST_SOURCE) { recvState = new BluetoothLeBroadcastReceiveState(mPendingSourceId, recvState = new BluetoothLeBroadcastReceiveState(mPendingSourceId, BluetoothDevice.ADDRESS_TYPE_UNKNOWN, // sourceAddressType BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType null, // sourceDevice btAdapter.getRemoteDevice(emptyBluetoothDevice), // sourceDevice 0, // sourceAdvertisingSid 0, // sourceAdvertisingSid 0, // broadcastId 0, // broadcastId BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState Loading @@ -538,8 +584,8 @@ public class BassClientStateMachine extends StateMachine { BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null, // badCode null, // badCode 0, // numSubgroups 0, // numSubgroups null, // bisSyncState Arrays.asList(new Long[0]), // bisSyncState null // subgroupMetadata Arrays.asList(new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata ); ); } else if (receiverState.length == 0) { } else if (receiverState.length == 0) { if (mBluetoothLeBroadcastReceiveStates != null) { if (mBluetoothLeBroadcastReceiveStates != null) { Loading @@ -551,8 +597,8 @@ public class BassClientStateMachine extends StateMachine { } } mNextSourceId++; mNextSourceId++; recvState = new BluetoothLeBroadcastReceiveState(mNextSourceId, recvState = new BluetoothLeBroadcastReceiveState(mNextSourceId, BluetoothDevice.ADDRESS_TYPE_UNKNOWN, // sourceAddressType BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType null, // sourceDevice btAdapter.getRemoteDevice(emptyBluetoothDevice), // sourceDevice 0, // sourceAdvertisingSid 0, // sourceAdvertisingSid 0, // broadcastId 0, // broadcastId BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState Loading @@ -560,8 +606,8 @@ public class BassClientStateMachine extends StateMachine { BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null, // badCode null, // badCode 0, // numSubgroups 0, // numSubgroups null, // bisSyncState Arrays.asList(new Long[0]), // bisSyncState null // subgroupMetadata Arrays.asList(new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata ); ); } } } else { } else { Loading Loading @@ -614,7 +660,6 @@ public class BassClientStateMachine extends StateMachine { 0, 0, mBroadcastSourceIdLength); mBroadcastSourceIdLength); int broadcastId = BassUtils.parseBroadcastId(broadcastIdBytes); int broadcastId = BassUtils.parseBroadcastId(broadcastIdBytes); BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); byte[] sourceAddress = new byte[BassConstants.BCAST_RCVR_STATE_SRC_ADDR_SIZE]; byte[] sourceAddress = new byte[BassConstants.BCAST_RCVR_STATE_SRC_ADDR_SIZE]; System.arraycopy( System.arraycopy( receiverState, receiverState, Loading Loading @@ -672,7 +717,9 @@ public class BassClientStateMachine extends StateMachine { log("old sourceInfo: " + oldRecvState); log("old sourceInfo: " + oldRecvState); log("new sourceInfo: " + recvState); log("new sourceInfo: " + recvState); mBluetoothLeBroadcastReceiveStates.replace(characteristic.getInstanceId(), recvState); mBluetoothLeBroadcastReceiveStates.replace(characteristic.getInstanceId(), recvState); if (oldRecvState.getSourceDevice() == null) { String emptyBluetoothDevice = "00:00:00:00:00:00"; if (oldRecvState.getSourceDevice() == null || oldRecvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { log("New Source Addition"); log("New Source Addition"); mService.getCallbacks().notifySourceAdded(mDevice, mService.getCallbacks().notifySourceAdded(mDevice, recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); Loading @@ -682,7 +729,8 @@ public class BassClientStateMachine extends StateMachine { checkAndUpdateBroadcastCode(recvState); checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); processPASyncState(recvState); } else { } else { if (recvState.getSourceDevice() == null) { if (recvState.getSourceDevice() == null || recvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { BluetoothDevice removedDevice = oldRecvState.getSourceDevice(); BluetoothDevice removedDevice = oldRecvState.getSourceDevice(); log("sourceInfo removal" + removedDevice); log("sourceInfo removal" + removedDevice); cancelActiveSync(removedDevice); cancelActiveSync(removedDevice); Loading