Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac2d2a60 authored by Jack He's avatar Jack He Committed by Gerrit Code Review
Browse files

Merge changes I70820082,I15691674,Ie018fe09,I7a2a190b,If5003302, ...

* changes:
  BassClient: Fix byte order in parsing the receiver state
  BassClient: Convert metadata for addSource op
  BassClient: Fix not clearing pending op. metadata
  BassClient: Fix not putting empty metadata buffer on the list
  BassClient: Fix missing SID in the reported metadata
  BassClient: Fix nullptr on BluetoothLeBroadcastSubgroup creation
  broadcast: Fix address type in the advertising
  broadcast: Fix filling broadcast code in JNI
parents 284c2e03 82422dcb
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -1133,9 +1133,11 @@ static void CreateBroadcastNative(JNIEnv* env, jobject object,
  std::shared_lock<std::shared_timed_mutex> lock(sBroadcasterInterfaceMutex);
  if (!sLeAudioBroadcasterInterface) return;

  std::array<uint8_t, 16> code_array;
  if (broadcast_code)
    env->GetByteArrayRegion(broadcast_code, 0, 16, (jbyte*)code_array.data());
  std::array<uint8_t, 16> code_array{};
  if (broadcast_code) {
    jsize size = env->GetArrayLength(broadcast_code);
    env->GetByteArrayRegion(broadcast_code, 0, size, (jbyte*)code_array.data());
  }

  jbyte* meta = env->GetByteArrayElements(metadata, nullptr);
  sLeAudioBroadcasterInterface->CreateBroadcast(
+2 −2
Original line number Diff line number Diff line
@@ -104,9 +104,9 @@ class BaseData {
            presentationDelay = new byte[3];
            codecId = new byte[5];
            codecConfigLength = 0;
            codecConfigInfo = null;
            codecConfigInfo = new byte[0];
            metaDataLength = 0;
            metaData = null;
            metaData = new byte[0];
            numSubGroups = 0;
            bisIndices = null;
            index = (byte) 0xFF;
+61 −85
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;

import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -104,7 +105,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
import java.util.stream.IntStream;
@@ -461,6 +461,7 @@ public class BassClientStateMachine extends StateMachine {
            int broadcastId = result.getBroadcastId();
            log("broadcast ID: " + broadcastId);
            metaData.setBroadcastId(broadcastId);
            metaData.setSourceAdvertisingSid(result.getAdvSid());
        }
        return metaData.build();
    }
@@ -662,7 +663,6 @@ public class BassClientStateMachine extends StateMachine {
                        badBroadcastCode,
                        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
@@ -679,7 +679,7 @@ 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));
                ByteBuffer wrapped = ByteBuffer.wrap(audioSyncIndex);
                audioSyncState.add((long) wrapped.getInt());

                byte metaDataLength = receiverState[offset++];
@@ -688,8 +688,9 @@ public class BassClientStateMachine extends StateMachine {
                    byte[] metaData = new byte[metaDataLength];
                    System.arraycopy(receiverState, offset, metaData, 0, metaDataLength);
                    offset += metaDataLength;
                    metaData = reverseBytes(metaData);
                    metadataList.add(BluetoothLeAudioContentMetadata.fromRawBytes(metaData));
                } else {
                    metadataList.add(BluetoothLeAudioContentMetadata.fromRawBytes(new byte[0]));
                }
            }
            byte[] broadcastIdBytes = new byte[mBroadcastSourceIdLength];
@@ -709,10 +710,7 @@ public class BassClientStateMachine extends StateMachine {
                    BassConstants.BCAST_RCVR_STATE_SRC_ADDR_SIZE);
            byte sourceAddressType = receiverState[BassConstants
                    .BCAST_RCVR_STATE_SRC_ADDR_TYPE_IDX];
            byte[] revAddress = reverseBytes(sourceAddress);
            String address = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
                    revAddress[0], revAddress[1], revAddress[2],
                    revAddress[3], revAddress[4], revAddress[5]);
            String address = Utils.getAddressStringFromByte(sourceAddress);
            BluetoothDevice device = btAdapter.getRemoteLeDevice(
                    address, sourceAddressType);
            byte sourceAdvSid = receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ADV_SID_IDX];
@@ -1159,15 +1157,6 @@ public class BassClientStateMachine extends StateMachine {
        }
    }

    private byte[] reverseBytes(byte[] a) {
        for (int i = 0; i < a.length / 2; i++) {
            byte tmp = a[i];
            a[i] = a[a.length - i - 1];
            a[a.length - i - 1] = tmp;
        }
        return a;
    }

    private byte[] bluetoothAddressToBytes(String s) {
        log("BluetoothAddressToBytes: input string:" + s);
        String[] splits = s.split(":");
@@ -1180,91 +1169,77 @@ public class BassClientStateMachine extends StateMachine {
        return addressBytes;
    }

    private byte[] convertMetadataToAddSourceByteArray(BluetoothLeBroadcastMetadata metaData) {
        log("Get PeriodicAdvertisementResult for :" + metaData.getSourceDevice());
        BluetoothDevice broadcastSource = metaData.getSourceDevice();
        PeriodicAdvertisementResult paRes =
                mService.getPeriodicAdvertisementResult(broadcastSource);
        if (paRes == null) {
            Log.e(TAG, "No matching psync, scan res for this addition");
            mService.getCallbacks().notifySourceAddFailed(
                    mDevice, metaData, BluetoothStatusCodes.ERROR_UNKNOWN);
            return null;
    private static int getBisSyncFromChannelPreference(
                List<BluetoothLeBroadcastChannel> channels) {
        int bisSync = 0;
        for (BluetoothLeBroadcastChannel channel : channels) {
            if (channel.isSelected()) {
                bisSync |= 1 << channel.getChannelIndex();
            }
        // populate metadata from BASE levelOne
        BaseData base = mService.getBase(paRes.getSyncHandle());
        if (base == null) {
            Log.e(TAG, "No valid base data populated for this device");
            mService.getCallbacks().notifySourceAddFailed(
                    mDevice, metaData, BluetoothStatusCodes.ERROR_UNKNOWN);
            return null;
        }
        int numSubGroups = base.getNumberOfSubgroupsofBIG();
        byte[] metaDataLength = new byte[numSubGroups];
        int totalMetadataLength = 0;
        for (int i = 0; i < numSubGroups; i++) {
            if (base.getMetadata(i) == null) {
                Log.w(TAG, "no valid metadata from BASE");
                metaDataLength[i] = 0;
            } else {
                metaDataLength[i] = (byte) base.getMetadata(i).length;
                log("metaDataLength updated:" + metaDataLength[i]);
        }
            totalMetadataLength = totalMetadataLength + metaDataLength[i];

        return bisSync;
    }
        byte[] res = new byte[ADD_SOURCE_FIXED_LENGTH
                + numSubGroups * 5 + totalMetadataLength];
        int offset = 0;

    private byte[] convertMetadataToAddSourceByteArray(BluetoothLeBroadcastMetadata metaData) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        BluetoothDevice advSource = metaData.getSourceDevice();

        // Opcode
        res[offset++] = OPCODE_ADD_SOURCE;
        stream.write(OPCODE_ADD_SOURCE);

        // Advertiser_Address_Type
        if (paRes.getAddressType() != (byte) BassConstants.INVALID_ADV_ADDRESS_TYPE) {
            res[offset++] = (byte) paRes.getAddressType();
        } else {
            res[offset++] = (byte) BassConstants.BROADCAST_ASSIST_ADDRESS_TYPE_PUBLIC;
        }
        String address = broadcastSource.getAddress();
        byte[] addrByteVal = bluetoothAddressToBytes(address);
        log("Address bytes: " + Arrays.toString(addrByteVal));
        byte[] revAddress = reverseBytes(addrByteVal);
        log("reverse Address bytes: " + Arrays.toString(revAddress));
        stream.write(metaData.getSourceAddressType());

        // Advertiser_Address
        System.arraycopy(revAddress, 0, res, offset, 6);
        offset += 6;
        stream.write(Utils.getBytesFromAddress(advSource.getAddress()), 0, 6);
        log("Address bytes: " + advSource.getAddress());

        // Advertising_SID
        res[offset++] = (byte) paRes.getAdvSid();
        log("mBroadcastId: " + paRes.getBroadcastId());
        stream.write(metaData.getSourceAdvertisingSid());

        // Broadcast_ID
        res[offset++] = (byte) (paRes.getBroadcastId() & 0x00000000000000FF);
        res[offset++] = (byte) ((paRes.getBroadcastId() & 0x000000000000FF00) >>> 8);
        res[offset++] = (byte) ((paRes.getBroadcastId() & 0x0000000000FF0000) >>> 16);
        stream.write(metaData.getBroadcastId() & 0x00000000000000FF);
        stream.write((metaData.getBroadcastId() & 0x000000000000FF00) >>> 8);
        stream.write((metaData.getBroadcastId() & 0x0000000000FF0000) >>> 16);
        log("mBroadcastId: " + metaData.getBroadcastId());

        // PA_Sync
        if (!mDefNoPAS) {
            res[offset++] = (byte) (0x01);
            stream.write(0x01);
        } else {
            log("setting PA sync to ZERO");
            res[offset++] = (byte) 0x00;
            stream.write(0x00);
        }

        // PA_Interval
        res[offset++] = (byte) (paRes.getAdvInterval() & 0x00000000000000FF);
        res[offset++] = (byte) ((paRes.getAdvInterval() & 0x000000000000FF00) >>> 8);
        stream.write((metaData.getPaSyncInterval() & 0x00000000000000FF));
        stream.write((metaData.getPaSyncInterval() & 0x000000000000FF00) >>> 8);

        // Num_Subgroups
        res[offset++] = base.getNumberOfSubgroupsofBIG();
        for (int i = 0; i < base.getNumberOfSubgroupsofBIG(); i++) {
        List<BluetoothLeBroadcastSubgroup> subGroups = metaData.getSubgroups();
        stream.write(metaData.getSubgroups().size());

        for (BluetoothLeBroadcastSubgroup subGroup : subGroups) {
            // BIS_Sync
            res[offset++] = (byte) 0xFF;
            res[offset++] = (byte) 0xFF;
            res[offset++] = (byte) 0xFF;
            res[offset++] = (byte) 0xFF;
            int bisSync = getBisSyncFromChannelPreference(subGroup.getChannels());
            if (bisSync == 0) {
                bisSync = 0xFFFFFFFF;
            }
            stream.write(bisSync & 0x00000000000000FF);
            stream.write((bisSync & 0x000000000000FF00) >>> 8);
            stream.write((bisSync & 0x0000000000FF0000) >>> 16);
            stream.write((bisSync & 0x00000000FF000000) >>> 24);

            // Metadata_Length
            res[offset++] = metaDataLength[i];
            if (metaDataLength[i] != 0) {
                byte[] revMetadata = reverseBytes(base.getMetadata(i));
            BluetoothLeAudioContentMetadata metadata = subGroup.getContentMetadata();
            stream.write(metadata.getRawMetadata().length);

            // Metadata
                System.arraycopy(revMetadata, 0, res, offset, metaDataLength[i]);
            }
            offset = offset + metaDataLength[i];
            stream.write(metadata.getRawMetadata(), 0, metadata.getRawMetadata().length);
        }

        byte[] res = stream.toByteArray();
        log("ADD_BCAST_SOURCE in Bytes");
        BassUtils.printByteArray(res);
        return res;
@@ -1670,6 +1645,7 @@ public class BassClientStateMachine extends StateMachine {
        }
        @Override
        public void exit() {
            mPendingMetadata = null;
            log("Exit ConnectedProcessing(" + mDevice + "): "
                    + messageWhatToString(getCurrentMessage().what));
        }
+1 −0
Original line number Diff line number Diff line
@@ -293,6 +293,7 @@ class BroadcastStateMachineImpl : public BroadcastStateMachine {
      adv_params.primary_advertising_phy = PHY_LE_1M;
      adv_params.secondary_advertising_phy = streaming_phy;
      adv_params.scan_request_notification_enable = 0;
      adv_params.own_address_type = BLE_ADDR_RANDOM;

      periodic_params.max_interval = BroadcastStateMachine::kPaIntervalMax;
      periodic_params.min_interval = BroadcastStateMachine::kPaIntervalMin;
+8 −2
Original line number Diff line number Diff line
@@ -856,12 +856,13 @@ TEST_F(StateMachineTest, GetBroadcastAnnouncement) {
            broadcasts_[broadcast_id]->GetBroadcastAnnouncement());
}

TEST_F(StateMachineTest, AnnouncementUUIDs) {
TEST_F(StateMachineTest, AnnouncementTest) {
  tBTM_BLE_ADV_PARAMS adv_params;
  std::vector<uint8_t> a_data;
  std::vector<uint8_t> p_data;

  EXPECT_CALL(*mock_ble_advertising_manager_, StartAdvertisingSet)
      .WillOnce([&p_data, &a_data](
      .WillOnce([&p_data, &a_data, &adv_params](
                    base::Callback<void(uint8_t, int8_t, uint8_t)> cb,
                    tBTM_BLE_ADV_PARAMS* params,
                    std::vector<uint8_t> advertise_data,
@@ -879,6 +880,8 @@ TEST_F(StateMachineTest, AnnouncementUUIDs) {
        a_data = std::move(advertise_data);
        p_data = std::move(periodic_data);

        adv_params = *params;

        cb.Run(advertiser_id, tx_power, status);
      });

@@ -900,6 +903,9 @@ TEST_F(StateMachineTest, AnnouncementUUIDs) {
  ASSERT_EQ(p_data[1], 0x16);  // BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE
  ASSERT_EQ(p_data[2], (kBasicAudioAnnouncementServiceUuid & 0x00FF));
  ASSERT_EQ(p_data[3], ((kBasicAudioAnnouncementServiceUuid >> 8) & 0x00FF));

  // Check advertising parameters
  ASSERT_EQ(adv_params.own_address_type, BLE_ADDR_RANDOM);
}

}  // namespace