Loading android/app/src/com/android/bluetooth/bass_client/BassClientService.java +6 −44 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ 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 @@ -327,16 +326,8 @@ public class BassClientService extends ProfileService { } private boolean hasRoomForBroadcastSourceAddition(BluetoothDevice 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; List<BluetoothLeBroadcastReceiveState> currentAllSources = getAllSources(device); return currentAllSources.size() < getMaximumSourceCapacity(device); } private BassClientStateMachine getOrCreateStateMachine(BluetoothDevice device) { Loading Loading @@ -642,29 +633,16 @@ public class BassClientService extends ProfileService { BassConstants.BAAS_UUID)) { return; } 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); } } } } Message msg = mBassUtils.getAutoAssistScanHandler() .obtainMessage(BassConstants.AA_SCAN_SUCCESS); msg.obj = result; mBassUtils.getAutoAssistScanHandler().sendMessage(msg); } 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 @@ -710,7 +688,6 @@ public class BassClientService extends ProfileService { scanner.stopScan(mSearchScanCallback); mSearchScanCallback = null; mCallbacks.notifySearchStopped(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); mScanBroadcasts.clear(); } } Loading Loading @@ -816,7 +793,6 @@ 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); } Loading Loading @@ -845,20 +821,6 @@ 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); Loading android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +7 −37 Original line number Diff line number Diff line Loading @@ -436,13 +436,7 @@ public class BassClientStateMachine extends StateMachine { channel.setSelected(false); subGroup.addChannel(channel.build()); } 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.setCodecId(ByteBuffer.wrap(baseLevel2.codecId).getLong()); subGroup.setCodecSpecificConfig(BluetoothLeAudioCodecConfigMetadata. fromRawBytes(baseLevel2.codecConfigInfo)); subGroup.setContentMetadata(BluetoothLeAudioContentMetadata. Loading @@ -450,18 +444,6 @@ 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 @@ -652,7 +634,6 @@ 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 @@ -663,12 +644,11 @@ 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 + badBroadcastCodeLen]; + BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE]; int offset = BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX + badBroadcastCodeLen + 1; + BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE + 1; ArrayList<BluetoothLeAudioContentMetadata> metadataList = new ArrayList<BluetoothLeAudioContentMetadata>(); ArrayList<Long> audioSyncState = new ArrayList<Long>(); Loading @@ -679,8 +659,6 @@ 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 @@ -1271,7 +1249,7 @@ public class BassClientStateMachine extends StateMachine { } private byte[] convertBroadcastMetadataToUpdateSourceByteArray(int sourceId, BluetoothLeBroadcastMetadata metaData, int paSync) { BluetoothLeBroadcastMetadata metaData) { BluetoothLeBroadcastReceiveState existingState = getBroadcastReceiveStateForSourceId(sourceId); if (existingState == null) { Loading Loading @@ -1303,9 +1281,7 @@ public class BassClientStateMachine extends StateMachine { // Source_ID res[offset++] = (byte) sourceId; // PA_Sync if (paSync != BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_INVALID) { res[offset++] = (byte) paSync; } else if (existingState.getPaSyncState() if (existingState.getPaSyncState() == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { res[offset++] = (byte) (0x01); } else { Loading @@ -1317,12 +1293,7 @@ public class BassClientStateMachine extends StateMachine { // Num_Subgroups res[offset++] = numSubGroups; for (int i = 0; i < numSubGroups; i++) { int bisIndexValue; if (paSync != BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_INVALID) { bisIndexValue = 0; } else { bisIndexValue = existingState.getBisSyncState().get(i).intValue(); } int bisIndexValue = existingState.getBisSyncState().get(i).intValue(); log("UPDATE_BCAST_SOURCE: bisIndexValue : " + bisIndexValue); // BIS_Sync res[offset++] = (byte) (bisIndexValue & 0x00000000000000FF); Loading Loading @@ -1520,10 +1491,9 @@ 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, paSync); sourceId, metaData); if (updateSourceInfo == null) { Log.e(TAG, "update source: source Info is NULL"); break; Loading service/java/com/android/server/bluetooth/BluetoothManagerService.java +5 −1 Original line number Diff line number Diff line Loading @@ -2189,7 +2189,11 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { break; } if (msg.arg1 > 0) { try { mContext.unbindService(psc); } catch (IllegalArgumentException e) { Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e); } psc.bindService(msg.arg1 - 1); } break; Loading system/bta/dm/bta_dm_act.cc +59 −23 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #include "main/shim/shim.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "osi/include/fixed_queue.h" #include "osi/include/log.h" #include "osi/include/osi.h" #include "stack/btm/btm_ble_int.h" Loading Loading @@ -320,6 +321,8 @@ void BTA_dm_on_hw_off() { /* hw is ready, go on with BTA DM initialization */ alarm_free(bta_dm_search_cb.search_timer); alarm_free(bta_dm_search_cb.gatt_close_timer); osi_free(bta_dm_search_cb.p_pending_search); fixed_queue_free(bta_dm_search_cb.pending_discovery_queue, osi_free); memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb)); } Loading @@ -339,6 +342,8 @@ void BTA_dm_on_hw_on() { /* hw is ready, go on with BTA DM initialization */ alarm_free(bta_dm_search_cb.search_timer); alarm_free(bta_dm_search_cb.gatt_close_timer); osi_free(bta_dm_search_cb.p_pending_search); fixed_queue_free(bta_dm_search_cb.pending_discovery_queue, osi_free); memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb)); /* * TODO: Should alarm_free() the bta_dm_search_cb timers during Loading @@ -347,6 +352,7 @@ void BTA_dm_on_hw_on() { bta_dm_search_cb.search_timer = alarm_new("bta_dm_search.search_timer"); bta_dm_search_cb.gatt_close_timer = alarm_new("bta_dm_search.gatt_close_timer"); bta_dm_search_cb.pending_discovery_queue = fixed_queue_new(SIZE_MAX); memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs)); memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB)); Loading Loading @@ -990,7 +996,7 @@ static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, void bta_dm_inq_cmpl(uint8_t num) { if (bta_dm_search_get_state() == BTA_DM_SEARCH_CANCELLING) { bta_dm_search_set_state(BTA_DM_SEARCH_IDLE); bta_dm_search_cancel_cmpl(); bta_dm_execute_queued_request(); return; } Loading Loading @@ -1289,6 +1295,7 @@ void bta_dm_search_cmpl() { /* no BLE connection, i.e. Classic service discovery end */ if (conn_id == GATT_INVALID_CONN_ID) { bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); bta_dm_execute_queued_request(); return; } Loading @@ -1299,6 +1306,7 @@ void bta_dm_search_cmpl() { if (count == 0) { LOG_INFO("Empty GATT database - no BLE services discovered"); bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); bta_dm_execute_queued_request(); return; } Loading @@ -1323,6 +1331,8 @@ void bta_dm_search_cmpl() { bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); bta_dm_execute_queued_request(); } /******************************************************************************* Loading Loading @@ -1419,13 +1429,13 @@ void bta_dm_free_sdp_db() { * * Function bta_dm_queue_search * * Description Queues search command while search is being cancelled * Description Queues search command * * Returns void * ******************************************************************************/ void bta_dm_queue_search(tBTA_DM_MSG* p_data) { bta_dm_search_clear_queue(); osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search); bta_dm_search_cb.p_pending_search = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_SEARCH)); memcpy(bta_dm_search_cb.p_pending_search, p_data, sizeof(tBTA_DM_API_SEARCH)); Loading @@ -1435,50 +1445,76 @@ void bta_dm_queue_search(tBTA_DM_MSG* p_data) { * * Function bta_dm_queue_disc * * Description Queues discovery command while search is being cancelled * Description Queues discovery command * * Returns void * ******************************************************************************/ void bta_dm_queue_disc(tBTA_DM_MSG* p_data) { bta_dm_search_clear_queue(); bta_dm_search_cb.p_pending_discovery = tBTA_DM_MSG* p_pending_discovery = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_DISCOVER)); memcpy(bta_dm_search_cb.p_pending_discovery, p_data, sizeof(tBTA_DM_API_DISCOVER)); memcpy(p_pending_discovery, p_data, sizeof(tBTA_DM_API_DISCOVER)); fixed_queue_enqueue(bta_dm_search_cb.pending_discovery_queue, p_pending_discovery); } /******************************************************************************* * * Function bta_dm_search_clear_queue * Function bta_dm_execute_queued_request * * Description Clears the queue if API search cancel is called * Description Executes queued request if one exists * * Returns void * ******************************************************************************/ void bta_dm_search_clear_queue() { osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search); osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_discovery); void bta_dm_execute_queued_request() { if (bta_dm_search_cb.p_pending_search) { // Updated queued event to search event to trigger start search if (bta_dm_search_cb.p_pending_search->hdr.event == BTA_DM_API_QUEUE_SEARCH_EVT) { bta_dm_search_cb.p_pending_search->hdr.event = BTA_DM_API_SEARCH_EVT; } LOG_INFO("%s Start pending search", __func__); bta_sys_sendmsg(bta_dm_search_cb.p_pending_search); bta_dm_search_cb.p_pending_search = NULL; } else { tBTA_DM_MSG* p_pending_discovery = (tBTA_DM_MSG*)fixed_queue_try_dequeue( bta_dm_search_cb.pending_discovery_queue); if (p_pending_discovery) { if (p_pending_discovery->hdr.event == BTA_DM_API_QUEUE_DISCOVER_EVT) { p_pending_discovery->hdr.event = BTA_DM_API_DISCOVER_EVT; } LOG_INFO("%s Start pending discovery", __func__); bta_sys_sendmsg(p_pending_discovery); } } } /******************************************************************************* * * Function bta_dm_search_cancel_cmpl * Function bta_dm_is_search_request_queued * * Description Search cancel is complete * Description Checks if there is a queued search request * * Returns void * Returns bool * ******************************************************************************/ void bta_dm_search_cancel_cmpl() { if (bta_dm_search_cb.p_pending_search) { bta_sys_sendmsg(bta_dm_search_cb.p_pending_search); bta_dm_search_cb.p_pending_search = NULL; } else if (bta_dm_search_cb.p_pending_discovery) { bta_sys_sendmsg(bta_dm_search_cb.p_pending_discovery); bta_dm_search_cb.p_pending_discovery = NULL; bool bta_dm_is_search_request_queued() { return bta_dm_search_cb.p_pending_search != NULL; } /******************************************************************************* * * Function bta_dm_search_clear_queue * * Description Clears the queue if API search cancel is called * * Returns void * ******************************************************************************/ void bta_dm_search_clear_queue() { osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search); fixed_queue_flush(bta_dm_search_cb.pending_discovery_queue, osi_free); } /******************************************************************************* Loading system/bta/dm/bta_dm_api.cc +15 −5 Original line number Diff line number Diff line Loading @@ -80,11 +80,16 @@ void BTA_DmSetDeviceName(const char* p_name) { * Returns void * ******************************************************************************/ void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback) { void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback, bool is_bonding_or_sdp) { tBTA_DM_API_SEARCH* p_msg = (tBTA_DM_API_SEARCH*)osi_calloc(sizeof(tBTA_DM_API_SEARCH)); /* Queue request if a device is bonding or performing service discovery */ if (is_bonding_or_sdp) { p_msg->hdr.event = BTA_DM_API_QUEUE_SEARCH_EVT; } else { p_msg->hdr.event = BTA_DM_API_SEARCH_EVT; } p_msg->p_cback = p_cback; bta_sys_sendmsg(p_msg); Loading @@ -101,6 +106,8 @@ void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback) { * ******************************************************************************/ void BTA_DmSearchCancel(void) { bta_dm_search_clear_queue(); switch (bta_dm_search_get_state()) { case BTA_DM_SEARCH_IDLE: bta_dm_search_cancel_notify(); Loading @@ -110,7 +117,6 @@ void BTA_DmSearchCancel(void) { bta_dm_search_cancel(); break; case BTA_DM_SEARCH_CANCELLING: bta_dm_search_clear_queue(); bta_dm_search_cancel_notify(); break; case BTA_DM_DISCOVER_ACTIVE: Loading @@ -132,11 +138,15 @@ void BTA_DmSearchCancel(void) { * ******************************************************************************/ void BTA_DmDiscover(const RawAddress& bd_addr, tBTA_DM_SEARCH_CBACK* p_cback, tBT_TRANSPORT transport) { tBT_TRANSPORT transport, bool is_bonding_or_sdp) { tBTA_DM_API_DISCOVER* p_msg = (tBTA_DM_API_DISCOVER*)osi_calloc(sizeof(tBTA_DM_API_DISCOVER)); if (is_bonding_or_sdp) { p_msg->hdr.event = BTA_DM_API_QUEUE_DISCOVER_EVT; } else { p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT; } p_msg->bd_addr = bd_addr; p_msg->transport = transport; p_msg->p_cback = p_cback; Loading Loading
android/app/src/com/android/bluetooth/bass_client/BassClientService.java +6 −44 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ 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 @@ -327,16 +326,8 @@ public class BassClientService extends ProfileService { } private boolean hasRoomForBroadcastSourceAddition(BluetoothDevice 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; List<BluetoothLeBroadcastReceiveState> currentAllSources = getAllSources(device); return currentAllSources.size() < getMaximumSourceCapacity(device); } private BassClientStateMachine getOrCreateStateMachine(BluetoothDevice device) { Loading Loading @@ -642,29 +633,16 @@ public class BassClientService extends ProfileService { BassConstants.BAAS_UUID)) { return; } 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); } } } } Message msg = mBassUtils.getAutoAssistScanHandler() .obtainMessage(BassConstants.AA_SCAN_SUCCESS); msg.obj = result; mBassUtils.getAutoAssistScanHandler().sendMessage(msg); } 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 @@ -710,7 +688,6 @@ public class BassClientService extends ProfileService { scanner.stopScan(mSearchScanCallback); mSearchScanCallback = null; mCallbacks.notifySearchStopped(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); mScanBroadcasts.clear(); } } Loading Loading @@ -816,7 +793,6 @@ 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); } Loading Loading @@ -845,20 +821,6 @@ 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); Loading
android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +7 −37 Original line number Diff line number Diff line Loading @@ -436,13 +436,7 @@ public class BassClientStateMachine extends StateMachine { channel.setSelected(false); subGroup.addChannel(channel.build()); } 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.setCodecId(ByteBuffer.wrap(baseLevel2.codecId).getLong()); subGroup.setCodecSpecificConfig(BluetoothLeAudioCodecConfigMetadata. fromRawBytes(baseLevel2.codecConfigInfo)); subGroup.setContentMetadata(BluetoothLeAudioContentMetadata. Loading @@ -450,18 +444,6 @@ 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 @@ -652,7 +634,6 @@ 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 @@ -663,12 +644,11 @@ 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 + badBroadcastCodeLen]; + BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE]; int offset = BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX + badBroadcastCodeLen + 1; + BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE + 1; ArrayList<BluetoothLeAudioContentMetadata> metadataList = new ArrayList<BluetoothLeAudioContentMetadata>(); ArrayList<Long> audioSyncState = new ArrayList<Long>(); Loading @@ -679,8 +659,6 @@ 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 @@ -1271,7 +1249,7 @@ public class BassClientStateMachine extends StateMachine { } private byte[] convertBroadcastMetadataToUpdateSourceByteArray(int sourceId, BluetoothLeBroadcastMetadata metaData, int paSync) { BluetoothLeBroadcastMetadata metaData) { BluetoothLeBroadcastReceiveState existingState = getBroadcastReceiveStateForSourceId(sourceId); if (existingState == null) { Loading Loading @@ -1303,9 +1281,7 @@ public class BassClientStateMachine extends StateMachine { // Source_ID res[offset++] = (byte) sourceId; // PA_Sync if (paSync != BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_INVALID) { res[offset++] = (byte) paSync; } else if (existingState.getPaSyncState() if (existingState.getPaSyncState() == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { res[offset++] = (byte) (0x01); } else { Loading @@ -1317,12 +1293,7 @@ public class BassClientStateMachine extends StateMachine { // Num_Subgroups res[offset++] = numSubGroups; for (int i = 0; i < numSubGroups; i++) { int bisIndexValue; if (paSync != BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_INVALID) { bisIndexValue = 0; } else { bisIndexValue = existingState.getBisSyncState().get(i).intValue(); } int bisIndexValue = existingState.getBisSyncState().get(i).intValue(); log("UPDATE_BCAST_SOURCE: bisIndexValue : " + bisIndexValue); // BIS_Sync res[offset++] = (byte) (bisIndexValue & 0x00000000000000FF); Loading Loading @@ -1520,10 +1491,9 @@ 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, paSync); sourceId, metaData); if (updateSourceInfo == null) { Log.e(TAG, "update source: source Info is NULL"); break; Loading
service/java/com/android/server/bluetooth/BluetoothManagerService.java +5 −1 Original line number Diff line number Diff line Loading @@ -2189,7 +2189,11 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { break; } if (msg.arg1 > 0) { try { mContext.unbindService(psc); } catch (IllegalArgumentException e) { Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e); } psc.bindService(msg.arg1 - 1); } break; Loading
system/bta/dm/bta_dm_act.cc +59 −23 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #include "main/shim/shim.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "osi/include/fixed_queue.h" #include "osi/include/log.h" #include "osi/include/osi.h" #include "stack/btm/btm_ble_int.h" Loading Loading @@ -320,6 +321,8 @@ void BTA_dm_on_hw_off() { /* hw is ready, go on with BTA DM initialization */ alarm_free(bta_dm_search_cb.search_timer); alarm_free(bta_dm_search_cb.gatt_close_timer); osi_free(bta_dm_search_cb.p_pending_search); fixed_queue_free(bta_dm_search_cb.pending_discovery_queue, osi_free); memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb)); } Loading @@ -339,6 +342,8 @@ void BTA_dm_on_hw_on() { /* hw is ready, go on with BTA DM initialization */ alarm_free(bta_dm_search_cb.search_timer); alarm_free(bta_dm_search_cb.gatt_close_timer); osi_free(bta_dm_search_cb.p_pending_search); fixed_queue_free(bta_dm_search_cb.pending_discovery_queue, osi_free); memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb)); /* * TODO: Should alarm_free() the bta_dm_search_cb timers during Loading @@ -347,6 +352,7 @@ void BTA_dm_on_hw_on() { bta_dm_search_cb.search_timer = alarm_new("bta_dm_search.search_timer"); bta_dm_search_cb.gatt_close_timer = alarm_new("bta_dm_search.gatt_close_timer"); bta_dm_search_cb.pending_discovery_queue = fixed_queue_new(SIZE_MAX); memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs)); memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB)); Loading Loading @@ -990,7 +996,7 @@ static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, void bta_dm_inq_cmpl(uint8_t num) { if (bta_dm_search_get_state() == BTA_DM_SEARCH_CANCELLING) { bta_dm_search_set_state(BTA_DM_SEARCH_IDLE); bta_dm_search_cancel_cmpl(); bta_dm_execute_queued_request(); return; } Loading Loading @@ -1289,6 +1295,7 @@ void bta_dm_search_cmpl() { /* no BLE connection, i.e. Classic service discovery end */ if (conn_id == GATT_INVALID_CONN_ID) { bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); bta_dm_execute_queued_request(); return; } Loading @@ -1299,6 +1306,7 @@ void bta_dm_search_cmpl() { if (count == 0) { LOG_INFO("Empty GATT database - no BLE services discovered"); bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); bta_dm_execute_queued_request(); return; } Loading @@ -1323,6 +1331,8 @@ void bta_dm_search_cmpl() { bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr); bta_dm_execute_queued_request(); } /******************************************************************************* Loading Loading @@ -1419,13 +1429,13 @@ void bta_dm_free_sdp_db() { * * Function bta_dm_queue_search * * Description Queues search command while search is being cancelled * Description Queues search command * * Returns void * ******************************************************************************/ void bta_dm_queue_search(tBTA_DM_MSG* p_data) { bta_dm_search_clear_queue(); osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search); bta_dm_search_cb.p_pending_search = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_SEARCH)); memcpy(bta_dm_search_cb.p_pending_search, p_data, sizeof(tBTA_DM_API_SEARCH)); Loading @@ -1435,50 +1445,76 @@ void bta_dm_queue_search(tBTA_DM_MSG* p_data) { * * Function bta_dm_queue_disc * * Description Queues discovery command while search is being cancelled * Description Queues discovery command * * Returns void * ******************************************************************************/ void bta_dm_queue_disc(tBTA_DM_MSG* p_data) { bta_dm_search_clear_queue(); bta_dm_search_cb.p_pending_discovery = tBTA_DM_MSG* p_pending_discovery = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_DISCOVER)); memcpy(bta_dm_search_cb.p_pending_discovery, p_data, sizeof(tBTA_DM_API_DISCOVER)); memcpy(p_pending_discovery, p_data, sizeof(tBTA_DM_API_DISCOVER)); fixed_queue_enqueue(bta_dm_search_cb.pending_discovery_queue, p_pending_discovery); } /******************************************************************************* * * Function bta_dm_search_clear_queue * Function bta_dm_execute_queued_request * * Description Clears the queue if API search cancel is called * Description Executes queued request if one exists * * Returns void * ******************************************************************************/ void bta_dm_search_clear_queue() { osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search); osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_discovery); void bta_dm_execute_queued_request() { if (bta_dm_search_cb.p_pending_search) { // Updated queued event to search event to trigger start search if (bta_dm_search_cb.p_pending_search->hdr.event == BTA_DM_API_QUEUE_SEARCH_EVT) { bta_dm_search_cb.p_pending_search->hdr.event = BTA_DM_API_SEARCH_EVT; } LOG_INFO("%s Start pending search", __func__); bta_sys_sendmsg(bta_dm_search_cb.p_pending_search); bta_dm_search_cb.p_pending_search = NULL; } else { tBTA_DM_MSG* p_pending_discovery = (tBTA_DM_MSG*)fixed_queue_try_dequeue( bta_dm_search_cb.pending_discovery_queue); if (p_pending_discovery) { if (p_pending_discovery->hdr.event == BTA_DM_API_QUEUE_DISCOVER_EVT) { p_pending_discovery->hdr.event = BTA_DM_API_DISCOVER_EVT; } LOG_INFO("%s Start pending discovery", __func__); bta_sys_sendmsg(p_pending_discovery); } } } /******************************************************************************* * * Function bta_dm_search_cancel_cmpl * Function bta_dm_is_search_request_queued * * Description Search cancel is complete * Description Checks if there is a queued search request * * Returns void * Returns bool * ******************************************************************************/ void bta_dm_search_cancel_cmpl() { if (bta_dm_search_cb.p_pending_search) { bta_sys_sendmsg(bta_dm_search_cb.p_pending_search); bta_dm_search_cb.p_pending_search = NULL; } else if (bta_dm_search_cb.p_pending_discovery) { bta_sys_sendmsg(bta_dm_search_cb.p_pending_discovery); bta_dm_search_cb.p_pending_discovery = NULL; bool bta_dm_is_search_request_queued() { return bta_dm_search_cb.p_pending_search != NULL; } /******************************************************************************* * * Function bta_dm_search_clear_queue * * Description Clears the queue if API search cancel is called * * Returns void * ******************************************************************************/ void bta_dm_search_clear_queue() { osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search); fixed_queue_flush(bta_dm_search_cb.pending_discovery_queue, osi_free); } /******************************************************************************* Loading
system/bta/dm/bta_dm_api.cc +15 −5 Original line number Diff line number Diff line Loading @@ -80,11 +80,16 @@ void BTA_DmSetDeviceName(const char* p_name) { * Returns void * ******************************************************************************/ void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback) { void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback, bool is_bonding_or_sdp) { tBTA_DM_API_SEARCH* p_msg = (tBTA_DM_API_SEARCH*)osi_calloc(sizeof(tBTA_DM_API_SEARCH)); /* Queue request if a device is bonding or performing service discovery */ if (is_bonding_or_sdp) { p_msg->hdr.event = BTA_DM_API_QUEUE_SEARCH_EVT; } else { p_msg->hdr.event = BTA_DM_API_SEARCH_EVT; } p_msg->p_cback = p_cback; bta_sys_sendmsg(p_msg); Loading @@ -101,6 +106,8 @@ void BTA_DmSearch(tBTA_DM_SEARCH_CBACK* p_cback) { * ******************************************************************************/ void BTA_DmSearchCancel(void) { bta_dm_search_clear_queue(); switch (bta_dm_search_get_state()) { case BTA_DM_SEARCH_IDLE: bta_dm_search_cancel_notify(); Loading @@ -110,7 +117,6 @@ void BTA_DmSearchCancel(void) { bta_dm_search_cancel(); break; case BTA_DM_SEARCH_CANCELLING: bta_dm_search_clear_queue(); bta_dm_search_cancel_notify(); break; case BTA_DM_DISCOVER_ACTIVE: Loading @@ -132,11 +138,15 @@ void BTA_DmSearchCancel(void) { * ******************************************************************************/ void BTA_DmDiscover(const RawAddress& bd_addr, tBTA_DM_SEARCH_CBACK* p_cback, tBT_TRANSPORT transport) { tBT_TRANSPORT transport, bool is_bonding_or_sdp) { tBTA_DM_API_DISCOVER* p_msg = (tBTA_DM_API_DISCOVER*)osi_calloc(sizeof(tBTA_DM_API_DISCOVER)); if (is_bonding_or_sdp) { p_msg->hdr.event = BTA_DM_API_QUEUE_DISCOVER_EVT; } else { p_msg->hdr.event = BTA_DM_API_DISCOVER_EVT; } p_msg->bd_addr = bd_addr; p_msg->transport = transport; p_msg->p_cback = p_cback; Loading