summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--OWNERS_chromeos2
-rw-r--r--TEST_MAPPING3
-rw-r--r--android/app/Android.bp16
-rw-r--r--android/app/aidl/android/bluetooth/IBluetooth.aidl2
-rw-r--r--android/app/jni/com_android_bluetooth_vc.cpp6
-rw-r--r--android/app/src/com/android/bluetooth/BluetoothEventLogger.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java3
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java3
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java4
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java2
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java35
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterService.java80
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterState.java5
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java9
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/HeadsetService.java5
-rw-r--r--android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java1
-rw-r--r--android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java2
-rw-r--r--android/app/src/com/android/bluetooth/hid/HidHostService.java22
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioService.java1
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/AppScanStats.java7
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java7
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/ScanManager.java1
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java2
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java3
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java11
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/obex/Message.java2
-rw-r--r--android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java5
-rw-r--r--android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java2
-rw-r--r--android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java3
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppService.java2
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java1
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java8
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java7
-rw-r--r--android/app/src/com/android/bluetooth/tbs/TbsGatt.java8
-rw-r--r--android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java21
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java4
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlService.java64
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java12
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java1
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java27
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java56
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java3
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java296
-rw-r--r--flags/Android.bp1
-rw-r--r--flags/BUILD.gn1
-rw-r--r--flags/active_device_manager.aconfig6
-rw-r--r--flags/connectivity.aconfig11
-rw-r--r--flags/gap.aconfig10
-rw-r--r--flags/sniff.aconfig9
-rw-r--r--flags/system_service.aconfig10
-rw-r--r--floss/hcidoc/packets/Cargo.toml2
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java239
-rw-r--r--framework/java/android/bluetooth/BluetoothLeCallControl.java36
-rw-r--r--framework/java/android/bluetooth/le/PeriodicAdvertisingManager.java95
-rw-r--r--framework/tests/bumble/src/android/bluetooth/GattClientTest.java13
-rw-r--r--framework/tests/bumble/src/android/bluetooth/Host.kt22
-rw-r--r--framework/tests/bumble/src/android/bluetooth/SdpClientTest.java22
-rw-r--r--framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java1
-rw-r--r--framework/tests/util/src/BlockingBluetoothAdapter.kt2
-rw-r--r--pandora/server/bumble_experimental/hid.py2
-rw-r--r--pandora/server/bumble_experimental/rfcomm.py2
-rw-r--r--service/src/LogTest.kt2
-rw-r--r--service/src/com/android/server/bluetooth/BluetoothManagerService.java11
-rw-r--r--system/TEST_MAPPING7
-rw-r--r--system/audio_hal_interface/aidl/client_interface_aidl.cc21
-rw-r--r--system/bta/ag/bta_ag_sco.cc8
-rw-r--r--system/bta/dm/bta_dm_act.cc11
-rw-r--r--system/bta/gatt/bta_gattc_act.cc234
-rw-r--r--system/bta/gatt/bta_gattc_int.h5
-rw-r--r--system/bta/gatt/bta_gattc_utils.cc280
-rw-r--r--system/bta/hh/bta_hh_act.cc130
-rw-r--r--system/bta/hh/bta_hh_api.cc11
-rw-r--r--system/bta/hh/bta_hh_int.h16
-rw-r--r--system/bta/hh/bta_hh_le.cc61
-rw-r--r--system/bta/hh/bta_hh_main.cc436
-rw-r--r--system/bta/hh/bta_hh_utils.cc220
-rw-r--r--system/bta/include/bta_hh_api.h11
-rw-r--r--system/bta/include/bta_jv_api.h20
-rw-r--r--system/bta/jv/bta_jv_act.cc7
-rw-r--r--system/bta/le_audio/audio_set_configurations.json15791
-rw-r--r--system/bta/le_audio/audio_set_scenarios.json550
-rw-r--r--system/bta/le_audio/client.cc53
-rw-r--r--system/bta/le_audio/codec_manager.cc9
-rw-r--r--system/bta/le_audio/codec_manager.h8
-rw-r--r--system/bta/le_audio/codec_manager_test.cc16
-rw-r--r--system/bta/le_audio/device_groups.cc37
-rw-r--r--system/bta/le_audio/device_groups.h2
-rw-r--r--system/bta/le_audio/devices_test.cc14
-rw-r--r--system/bta/le_audio/le_audio_client_test.cc43
-rw-r--r--system/bta/le_audio/mock_codec_manager.cc2
-rw-r--r--system/bta/le_audio/mock_codec_manager.h2
-rw-r--r--system/bta/le_audio/state_machine_test.cc25
-rw-r--r--system/bta/test/bta_dm_test.cc26
-rw-r--r--system/bta/vc/vc.cc15
-rw-r--r--system/bta/vc/vc_test.cc13
-rw-r--r--system/btif/src/btif_gatt.cc4
-rw-r--r--system/btif/src/btif_gatt_client.cc66
-rw-r--r--system/btif/src/btif_gatt_server.cc51
-rw-r--r--system/btif/src/btif_hh.cc1
-rw-r--r--system/btif/src/btif_vc.cc4
-rw-r--r--system/btif/src/stack_manager.cc2
-rw-r--r--system/gd/hci/acl_manager/le_impl.h26
-rw-r--r--system/gd/hci/acl_manager/le_impl_test.cc111
-rw-r--r--system/gd/hci/acl_manager/round_robin_scheduler.cc9
-rw-r--r--system/gd/hci/hci_layer_fake.cc17
-rw-r--r--system/gd/rust/topshim/Cargo.toml2
-rw-r--r--system/gd/rust/topshim/vc/vc_shim.cc6
-rw-r--r--system/include/hardware/bt_vc.h2
-rw-r--r--system/internal_include/bt_target.h91
-rw-r--r--system/profile/avrcp/device.cc4
-rw-r--r--system/rust/src/connection/ffi.rs2
-rw-r--r--system/rust/src/core/ffi/module.cc5
-rw-r--r--system/stack/Android.bp5
-rw-r--r--system/stack/BUILD.gn2
-rw-r--r--system/stack/ais/ais_ble.cc144
-rw-r--r--system/stack/fuzzers/gatt_fuzzer.cc3
-rw-r--r--system/stack/gatt/connection_manager.cc6
-rw-r--r--system/stack/gatt/gatt_api.cc67
-rw-r--r--system/stack/gatt/gatt_auth.cc15
-rw-r--r--system/stack/gatt/gatt_cl.cc49
-rw-r--r--system/stack/gatt/gatt_int.h7
-rw-r--r--system/stack/gatt/gatt_main.cc191
-rw-r--r--system/stack/gatt/gatt_sr.cc44
-rw-r--r--system/stack/gatt/gatt_utils.cc181
-rw-r--r--system/stack/hid/hidh_api.cc10
-rw-r--r--system/stack/include/ais_api.h43
-rw-r--r--system/stack/include/hidh_api.h4
-rw-r--r--system/stack/include/rfcdefs.h57
-rw-r--r--system/stack/rfcomm/port_api.cc6
-rw-r--r--system/stack/rfcomm/rfc_ts_frames.cc1
-rw-r--r--system/stack/test/gatt/gatt_sr_test.cc1
-rw-r--r--system/stack/test/gatt/mock_gatt_utils_ref.cc1
-rw-r--r--system/test/mock/mock_bta_hh_api.cc1
-rw-r--r--system/test/mock/mock_bta_hh_utils.cc7
-rw-r--r--system/test/mock/mock_bta_hh_utils.h17
-rw-r--r--system/test/mock/mock_stack_ais_ble.cc20
-rw-r--r--system/test/mock/mock_stack_gatt_main.cc3
144 files changed, 11282 insertions, 9357 deletions
diff --git a/OWNERS_chromeos b/OWNERS_chromeos
index 0280ec47df..15a57740e4 100644
--- a/OWNERS_chromeos
+++ b/OWNERS_chromeos
@@ -1,6 +1,5 @@
# Project owners
abhishekpandit@google.com
-sonnysasaka@google.com
# Audio
enshuo@google.com
@@ -12,3 +11,4 @@ whalechang@google.com
michaelfsun@google.com
laikatherine@google.com
yinghsu@google.com
+apusaka@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 3a88aa07cb..5f21a9b800 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -108,9 +108,6 @@
"name": "bluetooth_test_common"
},
{
- "name": "bluetooth_test_gd_unit"
- },
- {
"name": "bluetooth_test_sdp"
},
{
diff --git a/android/app/Android.bp b/android/app/Android.bp
index b38f847323..71b8a38760 100644
--- a/android/app/Android.bp
+++ b/android/app/Android.bp
@@ -323,23 +323,39 @@ android_app {
enabled: true,
javacflags: [
"-Xep:AlmostJavadoc:ERROR",
+ "-Xep:AlreadyChecked:ERROR",
+ "-Xep:AndroidFrameworkBinderIdentity:ERROR",
"-Xep:AndroidFrameworkEfficientStrings:ERROR",
"-Xep:AndroidFrameworkRequiresPermission:ERROR",
"-Xep:BadImport:ERROR",
"-Xep:ClassCanBeStatic:ERROR",
+ "-Xep:DateFormatConstant:ERROR",
"-Xep:EmptyBlockTag:ERROR",
+ "-Xep:FallThrough:ERROR",
+ "-Xep:HidingField:ERROR",
"-Xep:InlineMeInliner:ERROR",
"-Xep:InvalidBlockTag:ERROR",
"-Xep:InvalidParam:ERROR",
+ "-Xep:LoopOverCharArray:ERROR",
+ "-Xep:MissingCasesInEnumSwitch:ERROR",
"-Xep:MockNotUsedInProduction:ERROR",
+ "-Xep:ModifyCollectionInEnhancedForLoop:ERROR",
+ "-Xep:NarrowCalculation:ERROR",
"-Xep:NonApiType:ERROR",
+ "-Xep:NonAtomicVolatileUpdate:ERROR",
"-Xep:NonCanonicalType:ERROR",
"-Xep:NotJavadoc:ERROR",
+ "-Xep:OperatorPrecedence:ERROR",
"-Xep:ReturnAtTheEndOfVoidFunction:ERROR",
"-Xep:StringCaseLocaleUsage:ERROR",
"-Xep:StringCharset:ERROR",
+ "-Xep:ToStringReturnsNull:ERROR",
+ "-Xep:UnnecessaryStringBuilder:ERROR",
+ "-Xep:UnrecognisedJavadocTag:ERROR",
"-Xep:UnusedMethod:ERROR",
+ "-Xep:UnusedNestedClass:ERROR",
"-Xep:UnusedVariable:ERROR",
+ "-Xep:WaitNotInLoop:ERROR",
"-XepExcludedPaths:.*/srcjars/.*", // Exclude generated files
],
},
diff --git a/android/app/aidl/android/bluetooth/IBluetooth.aidl b/android/app/aidl/android/bluetooth/IBluetooth.aidl
index aaccb15c95..27061542f7 100644
--- a/android/app/aidl/android/bluetooth/IBluetooth.aidl
+++ b/android/app/aidl/android/bluetooth/IBluetooth.aidl
@@ -280,6 +280,8 @@ interface IBluetooth
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
Bundle getPreferredAudioProfiles(in BluetoothDevice device, in AttributionSource source);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ int isDualModeAudioEnabled(in AttributionSource attributionSource);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
int registerPreferredAudioProfilesChangedCallback(in IBluetoothPreferredAudioProfilesCallback callback, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
int unregisterPreferredAudioProfilesChangedCallback(in IBluetoothPreferredAudioProfilesCallback callback, in AttributionSource attributionSource);
diff --git a/android/app/jni/com_android_bluetooth_vc.cpp b/android/app/jni/com_android_bluetooth_vc.cpp
index f56b913afe..986605dab1 100644
--- a/android/app/jni/com_android_bluetooth_vc.cpp
+++ b/android/app/jni/com_android_bluetooth_vc.cpp
@@ -67,7 +67,7 @@ public:
addr.get());
}
- void OnVolumeStateChanged(const RawAddress& bd_addr, uint8_t volume, bool mute,
+ void OnVolumeStateChanged(const RawAddress& bd_addr, uint8_t volume, bool mute, uint8_t flags,
bool isAutonomous) override {
log::info("");
@@ -86,7 +86,7 @@ public:
sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), (jbyte*)&bd_addr);
sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeStateChanged, (jint)volume,
- (jboolean)mute, addr.get(), (jboolean)isAutonomous);
+ (jboolean)mute, (jint)flags, addr.get(), (jboolean)isAutonomous);
}
void OnGroupVolumeStateChanged(int group_id, uint8_t volume, bool mute,
@@ -533,7 +533,7 @@ int register_com_android_bluetooth_vc(JNIEnv* env) {
const JNIJavaMethod javaMethods[] = {
{"onConnectionStateChanged", "(I[B)V", &method_onConnectionStateChanged},
- {"onVolumeStateChanged", "(IZ[BZ)V", &method_onVolumeStateChanged},
+ {"onVolumeStateChanged", "(IZI[BZ)V", &method_onVolumeStateChanged},
{"onGroupVolumeStateChanged", "(IZIZ)V", &method_onGroupVolumeStateChanged},
{"onDeviceAvailable", "(I[B)V", &method_onDeviceAvailable},
{"onExtAudioOutVolumeOffsetChanged", "(II[B)V", &method_onExtAudioOutVolumeOffsetChanged},
diff --git a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
index c4591ef000..9a5f811bcf 100644
--- a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
+++ b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
@@ -36,7 +36,7 @@ public class BluetoothEventLogger {
}
public String toString() {
- return (new StringBuilder(mTimeStamp).append(" ").append(mMsg).toString());
+ return mTimeStamp + " " + mMsg;
}
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
index 7ac0842b01..a48b2d5ea2 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
@@ -128,7 +128,8 @@ public class AvrcpCoverArtManager {
*/
public static boolean isValidImageHandle(String handle) {
if (handle == null || handle.length() != 7) return false;
- for (char c : handle.toCharArray()) {
+ for (int i = 0; i < handle.length(); i++) {
+ char c = handle.charAt(i);
if (!Character.isDigit(c)) {
return false;
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java
index 380111aa81..53260b050b 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java
@@ -16,6 +16,8 @@
package com.android.bluetooth.avrcpcontroller;
+import android.annotation.SuppressLint;
+
import com.android.bluetooth.Utils;
import java.util.Calendar;
@@ -121,6 +123,7 @@ public class BipDateTime {
}
@Override
+ @SuppressLint("ToStringReturnsNull")
public String toString() {
Date d = getTime();
if (d == null) {
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java
index 3eae52076a..4ddac205b0 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java
@@ -16,6 +16,7 @@
package com.android.bluetooth.avrcpcontroller;
+import android.annotation.SuppressLint;
import android.util.Log;
import android.util.Xml;
@@ -262,6 +263,7 @@ public class BipImageDescriptor {
}
@Override
+ @SuppressLint("ToStringReturnsNull") // Since this is used for encoding to xml
public String toString() {
if (mEncoding == null || mPixel == null) {
error(
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java
index cb564b639e..f9a93c560d 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java
@@ -16,6 +16,7 @@
package com.android.bluetooth.avrcpcontroller;
+import android.annotation.SuppressLint;
import android.util.Log;
import java.util.Objects;
@@ -179,6 +180,7 @@ public class BipImageFormat {
}
@Override
+ @SuppressLint("ToStringReturnsNull") // Since this is used for encoding to xml
public String toString() {
if (mEncoding == null
|| mEncoding.getType() == BipEncoding.UNKNOWN
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java
index e49d9dd5a9..442b03f529 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java
@@ -16,6 +16,7 @@
package com.android.bluetooth.avrcpcontroller;
+import android.annotation.SuppressLint;
import android.util.Log;
import android.util.Xml;
@@ -298,6 +299,7 @@ public class BipImageProperties {
}
@Override
+ @SuppressLint("ToStringReturnsNull") // Since this is used for encoding to xml
public String toString() {
StringWriter writer = new StringWriter();
XmlSerializer xmlMsgElement = Xml.newSerializer();
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java
index f3be13363d..1308c47c12 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java
@@ -197,9 +197,11 @@ public class BipPixel {
private static int determinePixelType(String pixel) {
if (pixel == null || pixel.length() > 23) return TYPE_UNKNOWN;
int delimCount = 0;
- for (char c : pixel.toCharArray()) {
+ for (int i = 0; i < pixel.length(); i++) {
+ char c = pixel.charAt(i);
if (c == '*') delimCount++;
}
+
return delimCount > 0 && delimCount <= 3 ? delimCount : TYPE_UNKNOWN;
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java
index 31e4f29a86..830daf563b 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java
@@ -16,6 +16,7 @@
package com.android.bluetooth.avrcpcontroller;
+import android.annotation.SuppressLint;
import android.util.Log;
import com.google.common.base.Ascii;
@@ -152,6 +153,7 @@ public class BipTransformation {
}
@Override
+ @SuppressLint("ToStringReturnsNull")
public String toString() {
if (!supportsAny()) return null;
StringBuilder transformations = new StringBuilder();
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 4739530850..7fd6bb349f 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
@@ -171,7 +171,7 @@ public class BassClientStateMachine extends StateMachine {
AdapterService adapterService,
Looper looper,
int connectTimeoutMs) {
- super(TAG + "(" + device.toString() + ")", looper);
+ super(TAG + "(" + device + ")", looper);
mDevice = device;
mService = svc;
mAdapterService = adapterService;
@@ -182,21 +182,24 @@ public class BassClientStateMachine extends StateMachine {
addState(mConnectedProcessing);
setInitialState(mDisconnected);
mFirstTimeBisDiscoveryMap = new HashMap<Integer, Boolean>();
- long token = Binder.clearCallingIdentity();
- mIsAllowedList =
- DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_BLUETOOTH, "persist.vendor.service.bt.wl", true);
- mDefNoPAS =
- DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_BLUETOOTH,
- "persist.vendor.service.bt.defNoPAS",
- false);
- mForceSB =
- DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_BLUETOOTH,
- "persist.vendor.service.bt.forceSB",
- false);
- Binder.restoreCallingIdentity(token);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ mIsAllowedList =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_BLUETOOTH, "persist.vendor.service.bt.wl", true);
+ mDefNoPAS =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_BLUETOOTH,
+ "persist.vendor.service.bt.defNoPAS",
+ false);
+ mForceSB =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_BLUETOOTH,
+ "persist.vendor.service.bt.forceSB",
+ false);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
static BassClientStateMachine make(
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
index bc5a0dfe46..dde36b7e5d 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
@@ -794,28 +794,14 @@ public class AdapterService extends Service {
}
@Override
- @RequiresPermission(BLUETOOTH_CONNECT)
public boolean onUnbind(Intent intent) {
- if (Flags.explicitKillFromSystemServer()) {
- Log.d(TAG, "onUnbind()");
- return super.onUnbind(intent);
- }
- Log.d(TAG, "onUnbind() - calling cleanup");
- cleanup();
+ Log.d(TAG, "onUnbind()");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy()");
- if (Flags.explicitKillFromSystemServer()) {
- return;
- }
- if (!isMock()) {
- // TODO(b/27859763)
- Log.i(TAG, "Force exit to cleanup internal state in Bluetooth stack");
- System.exit(0);
- }
}
public ActiveDeviceManager getActiveDeviceManager() {
@@ -1484,14 +1470,6 @@ public class AdapterService extends Service {
mBluetoothSocketManagerBinder = null;
}
- if (!Flags.explicitKillFromSystemServer()) {
- // Bluetooth will be killed, no need to cleanup binder
- if (mBinder != null) {
- mBinder.cleanup();
- mBinder = null; // Do not remove. Otherwise Binder leak!
- }
- }
-
mPreferredAudioProfilesCallbacks.kill();
mBluetoothQualityReportReadyCallbacks.kill();
@@ -2252,20 +2230,12 @@ public class AdapterService extends Service {
}
/**
- * The Binder implementation must be declared to be a static class, with the AdapterService
- * instance passed in the constructor. Furthermore, when the AdapterService shuts down, the
- * reference to the AdapterService must be explicitly removed.
- *
- * <p>Otherwise, a memory leak can occur from repeated starting/stopping the service...Please
- * refer to android.os.Binder for further details on why an inner instance class should be
- * avoided.
- *
- * <p>TODO: b/339548431 -- Delete this comment as it does not apply when we get killed
+ * There is no leak of this binder since it is never re-used and the process is systematically
+ * killed
*/
@VisibleForTesting
public static class AdapterServiceBinder extends IBluetooth.Stub {
- // TODO: b/339548431 move variable to final
- private AdapterService mService;
+ private final AdapterService mService;
AdapterServiceBinder(AdapterService svc) {
mService = svc;
@@ -2273,18 +2243,11 @@ public class AdapterService extends Service {
BluetoothAdapter.getDefaultAdapter().disableBluetoothGetStateCache();
}
- public void cleanup() {
- mService = null;
- }
-
public AdapterService getService() {
- // Cache mService because it can change while getService is called
- AdapterService service = mService;
-
- if (service == null || !service.isAvailable()) {
+ if (!mService.isAvailable()) {
return null;
}
- return service;
+ return mService;
}
@Override
@@ -4020,6 +3983,24 @@ public class AdapterService extends Service {
}
@Override
+ public int isDualModeAudioEnabled(AttributionSource source) {
+ AdapterService service = getService();
+ if (service == null) {
+ return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+ }
+ if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
+ return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION;
+ }
+ service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
+
+ if (!Utils.isDualModeAudioEnabled()) {
+ return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
+ }
+
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ @Override
public int registerPreferredAudioProfilesChangedCallback(
IBluetoothPreferredAudioProfilesCallback callback, AttributionSource source) {
AdapterService service = getService();
@@ -4037,7 +4018,7 @@ public class AdapterService extends Service {
service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
// If LE only mode is enabled, the dual mode audio feature is disabled
- if (!isDualModeAudioEnabled()) {
+ if (!Utils.isDualModeAudioEnabled()) {
return BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
}
@@ -6888,15 +6869,4 @@ public class AdapterService extends Service {
mPhonePolicy.onUuidsDiscovered(device, uuids);
}
}
-
- // TODO: b/339548431 delete isMock
- // Returns if this is a mock object. This is currently used in testing so that we may not call
- // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up
- // calling finalize() which in turn calls System.exit() and the process crashes.
- //
- // Mock this in your testing framework to return true to avoid the mentioned behavior. In
- // production this has no effect.
- public boolean isMock() {
- return false;
- }
}
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterState.java b/android/app/src/com/android/bluetooth/btservice/AdapterState.java
index cd2182c1a7..bcdd092716 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterState.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterState.java
@@ -22,7 +22,6 @@ import android.os.Message;
import android.os.SystemProperties;
import android.util.Log;
-import com.android.bluetooth.flags.Flags;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
@@ -172,10 +171,6 @@ final class AdapterState extends StateMachine {
@Override
public void enter() {
- if (!Flags.explicitKillFromSystemServer()) {
- super.enter();
- return;
- }
int prevState = mPrevState;
super.enter();
if (prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
diff --git a/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java b/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java
index bad17b6a47..59c3e794e7 100644
--- a/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java
@@ -68,7 +68,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
private AudioRoutingHandler mHandler = null;
private final AudioManager mAudioManager;
private final MediaSessionManager mSessionManager;
- private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback;
+ private final AudioManagerAudioDeviceCallback mAudioRoutingManagerAudioDeviceCallback;
@Override
public void onBluetoothStateChange(int prevState, int newState) {
@@ -144,7 +144,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
mFactory = factory;
mAudioManager = service.getSystemService(AudioManager.class);
mSessionManager = service.getSystemService(MediaSessionManager.class);
- mAudioManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback();
+ mAudioRoutingManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback();
}
@Override
@@ -157,7 +157,8 @@ public class AudioRoutingManager extends ActiveDeviceManager {
mHandler = new AudioRoutingHandler(mp.handlerThreadGetLooper(mHandlerThread));
mAudioManager.addOnModeChangedListener(cmd -> mHandler.post(cmd), mHandler);
- mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);
+ mAudioManager.registerAudioDeviceCallback(
+ mAudioRoutingManagerAudioDeviceCallback, mHandler);
mAdapterService.registerBluetoothStateCallback((command) -> mHandler.post(command), this);
}
@@ -166,7 +167,7 @@ public class AudioRoutingManager extends ActiveDeviceManager {
Log.d(TAG, "cleanup()");
mAudioManager.removeOnModeChangedListener(mHandler);
- mAudioManager.unregisterAudioDeviceCallback(mAudioManagerAudioDeviceCallback);
+ mAudioManager.unregisterAudioDeviceCallback(mAudioRoutingManagerAudioDeviceCallback);
mAdapterService.unregisterBluetoothStateCallback(this);
if (mHandlerThread != null) {
mHandlerThread.quit();
diff --git a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
index 79f3638f6e..c0a2ca18ef 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java
@@ -438,7 +438,7 @@ public class GattNativeInterface {
/**
* Connect to the remote Gatt server
*
- * @see {@link BluetoothDevice#connectGatt} for parameters.
+ * @see BluetoothDevice#connectGatt for parameters.
*/
public void gattClientConnect(
int clientIf,
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
index df4eac0ea8..f278a3cefa 100644
--- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -27,6 +27,7 @@ import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
@@ -581,6 +582,7 @@ public class HeadsetService extends ProfileService {
}
@Override
+ @SuppressLint("AndroidFrameworkRequiresPermission") // TODO: b/356478621 - remove
public boolean setConnectionPolicy(
BluetoothDevice device, int connectionPolicy, AttributionSource source) {
HeadsetService service = getService(source);
@@ -588,7 +590,8 @@ public class HeadsetService extends ProfileService {
return false;
}
- service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+ // TODO: b/356478621 - put back the permission check
+ // service.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
return service.setConnectionPolicy(device, connectionPolicy);
}
diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
index e26b91f048..8c2f9fbf25 100644
--- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
@@ -1787,6 +1787,7 @@ public class HeadsetClientStateMachine extends StateMachine {
break;
case SEND_ANDROID_AT_COMMAND:
debug("Connected: Received OK for AT+ANDROID");
+ break;
default:
warn("Unhandled AT OK " + event);
break;
diff --git a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java
index 66d323a04c..3509906931 100644
--- a/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java
+++ b/android/app/src/com/android/bluetooth/hfpclient/HfpClientConnection.java
@@ -281,7 +281,7 @@ public class HfpClientConnection extends Connection {
return false;
}
Uri otherAddr = ((HfpClientConnection) o).getAddress();
- return getAddress() == otherAddr || otherAddr != null && otherAddr.equals(getAddress());
+ return getAddress() == otherAddr || (otherAddr != null && otherAddr.equals(getAddress()));
}
@Override
diff --git a/android/app/src/com/android/bluetooth/hid/HidHostService.java b/android/app/src/com/android/bluetooth/hid/HidHostService.java
index 02481e604d..4189cec8e7 100644
--- a/android/app/src/com/android/bluetooth/hid/HidHostService.java
+++ b/android/app/src/com/android/bluetooth/hid/HidHostService.java
@@ -109,7 +109,6 @@ public class HidHostService extends ProfileService {
private final HidHostNativeInterface mNativeInterface;
private boolean mNativeAvailable;
- private BluetoothDevice mTargetDevice = null;
private static final int MESSAGE_CONNECT = 1;
private static final int MESSAGE_DISCONNECT = 2;
@@ -698,7 +697,6 @@ public class HidHostService extends ProfileService {
if (Flags.allowSwitchingHidAndHogp() || connectionAllowed) {
updateConnectionState(device, transport, reportedState);
}
- updateQuietMode(device, reportedState);
}
private void handleMessageDisconnect(Message msg) {
@@ -781,23 +779,6 @@ public class HidHostService extends ProfileService {
return true;
}
- /**
- * Disables the quiet mode if target device gets connected
- *
- * @param device remote device
- * @param state connection state
- */
- private void updateQuietMode(BluetoothDevice device, int state) {
- if (state == BluetoothProfile.STATE_CONNECTED
- && mTargetDevice != null
- && mTargetDevice.equals(device)) {
- // Locally initiated connection, move out of quiet mode
- Log.i(TAG, "updateQuietMode: Move out of quiet mode. device=" + device);
- mTargetDevice = null;
- mAdapterService.enable(false);
- }
- }
-
@VisibleForTesting
static class BluetoothHidHostBinder extends IBluetoothHidHost.Stub
implements IProfileServiceBinder {
@@ -1482,7 +1463,7 @@ public class HidHostService extends ProfileService {
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
public boolean okToConnect(BluetoothDevice device) {
// Check if this is an incoming connection in Quiet mode.
- if (mAdapterService.isQuietModeEnabled() && mTargetDevice == null) {
+ if (mAdapterService.isQuietModeEnabled()) {
Log.w(TAG, "okToConnect: return false because of quiet mode enabled. device=" + device);
return false;
}
@@ -1510,7 +1491,6 @@ public class HidHostService extends ProfileService {
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
- println(sb, "mTargetDevice: " + mTargetDevice);
println(sb, "mInputDevices:");
mInputDevices.forEach(
(k, v) -> sb.append(" ").append(k).append(" : ").append(v).append("\n"));
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index 17313b0946..387c5b8d46 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -2568,6 +2568,7 @@ public class LeAudioService extends ProfileService {
groupDescriptor.mInactivatedDueToContextType = true;
setActiveGroupWithDevice(null, false);
}
+ break;
default:
break;
}
diff --git a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java
index 7bf79ca143..5e15fdaba2 100644
--- a/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java
+++ b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java
@@ -47,7 +47,8 @@ import java.util.Objects;
public class AppScanStats {
private static final String TAG = AppScanStats.class.getSimpleName();
- static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss");
+ private static final ThreadLocal<DateFormat> DATE_FORMAT =
+ ThreadLocal.withInitial(() -> new SimpleDateFormat("MM-dd HH:mm:ss"));
// Weight is the duty cycle of the scan mode
static final int OPPORTUNISTIC_WEIGHT = 0;
@@ -1031,7 +1032,7 @@ public class AppScanStats {
for (int i = 0; i < mLastScans.size(); i++) {
LastScan scan = mLastScans.get(i);
Date timestamp = new Date(currentTime - currTime + scan.timestamp);
- sb.append("\n ").append(DATE_FORMAT.format(timestamp)).append(" - ");
+ sb.append("\n ").append(DATE_FORMAT.get().format(timestamp)).append(" - ");
sb.append(scan.duration).append("ms ");
if (scan.isOpportunisticScan) {
sb.append("Opp ");
@@ -1084,7 +1085,7 @@ public class AppScanStats {
for (Integer key : mOngoingScans.keySet()) {
LastScan scan = mOngoingScans.get(key);
Date timestamp = new Date(currentTime - currTime + scan.timestamp);
- sb.append("\n ").append(DATE_FORMAT.format(timestamp)).append(" - ");
+ sb.append("\n ").append(DATE_FORMAT.get().format(timestamp)).append(" - ");
sb.append((currTime - scan.timestamp)).append("ms ");
if (scan.isOpportunisticScan) {
sb.append("Opp ");
diff --git a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java
index f2af13135a..e3f07a3c3c 100644
--- a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java
+++ b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java
@@ -33,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -191,7 +192,9 @@ public class PeriodicScanManager {
}
synchronized (mSyncs) {
- for (Map.Entry<IBinder, SyncInfo> e : mSyncs.entrySet()) {
+ Iterator<Map.Entry<IBinder, SyncInfo>> it = mSyncs.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<IBinder, SyncInfo> e = it.next();
if (e.getValue().id != regId) {
continue;
}
@@ -224,7 +227,7 @@ public class PeriodicScanManager {
status);
IBinder binder = e.getKey();
binder.unlinkToDeath(e.getValue().deathRecipient, 0);
- mSyncs.remove(binder);
+ it.remove();
}
}
}
diff --git a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java
index 6269e1007f..bfd3019cd0 100644
--- a/android/app/src/com/android/bluetooth/le_scan/ScanManager.java
+++ b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java
@@ -369,6 +369,7 @@ public class ScanManager {
break;
case MSG_BT_PROFILE_CONN_STATE_CHANGED:
handleProfileConnectionStateChanged(msg);
+ break;
default:
// Shouldn't happen.
Log.e(TAG, "received an unknown message : " + msg.what);
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java
index c03347ec32..771d7d4cc9 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAccountItem.java
@@ -104,7 +104,7 @@ public class BluetoothMapAccountItem implements Comparable<BluetoothMapAccountIt
if (mUciPrefix == null) {
return null;
}
- return new StringBuilder(mUciPrefix).append(":").append(mUci).toString();
+ return mUciPrefix + ":" + mUci;
}
@Override
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java b/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
index 6d0c654aa9..080173aec3 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java
@@ -34,7 +34,6 @@ import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils;
import com.android.bluetooth.map.BluetoothMapContentObserver.Msg;
import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
import com.android.bluetooth.sdp.SdpManagerNativeInterface;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.obex.ServerSession;
import java.io.IOException;
@@ -47,7 +46,7 @@ import java.util.concurrent.atomic.AtomicLong;
public class BluetoothMapMasInstance implements IObexConnectionHandler {
private static final String TAG = "BluetoothMapMasInstance";
- @VisibleForTesting static volatile int sInstanceCounter = 0;
+ private static int sInstanceCounter = 0;
private final int mObjectInstanceId;
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
index 5c3130ece7..14262d9034 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
@@ -438,7 +438,7 @@ public class BluetoothMapSmsPdu {
| TP_MMS_NO_MORE
| TP_RP_NO_REPLY_PATH
| TP_SRI_NO_REPORT
- | (mData[0] & 0xff) & TP_UDHI_MASK);
+ | ((mData[0] & 0xff) & TP_UDHI_MASK));
encodedAddress =
PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(originator);
if (encodedAddress != null) {
@@ -855,14 +855,5 @@ public class BluetoothMapSmsPdu {
/** This value is not defined in global standard. Only in Korea, this is used. */
public static final int ENCODING_KSC5601 = 4;
-
- /** SMS Class enumeration. See TS 23.038. */
- public enum MessageClass {
- UNKNOWN,
- CLASS_0,
- CLASS_1,
- CLASS_2,
- CLASS_3;
- }
}
}
diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/Message.java b/android/app/src/com/android/bluetooth/mapclient/obex/Message.java
index 89f40cc7d2..0cfaf74660 100644
--- a/android/app/src/com/android/bluetooth/mapclient/obex/Message.java
+++ b/android/app/src/com/android/bluetooth/mapclient/obex/Message.java
@@ -262,7 +262,7 @@ public class Message {
}
/**
- * @return {@link .ReceptionStatus} object corresponding to <code>reception_status</code>
+ * @return {@link ReceptionStatus} object corresponding to <code>reception_status</code>
* parameter in MAP specification
*/
public ReceptionStatus getReceptionStatus() {
diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java b/android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java
index 97d6bdccd8..8f3392be19 100644
--- a/android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java
+++ b/android/app/src/com/android/bluetooth/mapclient/obex/ObexTime.java
@@ -16,6 +16,8 @@
package com.android.bluetooth.mapclient;
+import android.annotation.SuppressLint;
+
import com.android.bluetooth.Utils;
import java.time.Instant;
@@ -82,7 +84,7 @@ public final class ObexTime {
int ohh = Integer.parseInt(m.group(9));
int omm = Integer.parseInt(m.group(10));
- /* time zone offset is specified in miliseconds */
+ /* time zone offset is specified in milliseconds */
int offset = (ohh * 60 + omm) * 60 * 1000;
if (m.group(8).equals("-")) {
@@ -123,6 +125,7 @@ public final class ObexTime {
}
@Override
+ @SuppressLint("ToStringReturnsNull")
public String toString() {
if (mInstant == null) {
return null;
diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java
index abb87a3ea4..c229f184ae 100644
--- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java
+++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java
@@ -1300,7 +1300,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface
}
private void handlePlaybackSpeedRequest(int speed) {
- float floatingSpeed = (float) Math.pow(2, speed / 64);
+ float floatingSpeed = (float) Math.pow(2, speed / 64.0);
mEventLogger.add("handlePlaybackSpeedRequest: floatingSpeed= " + floatingSpeed);
mCallbacks.onPlaybackSpeedSetRequest(floatingSpeed);
}
diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java b/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java
index d025bc7000..32d07d4145 100644
--- a/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java
+++ b/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java
@@ -686,6 +686,9 @@ public class MediaControlProfile implements MediaControlServiceCallbacks {
+ opcodes);
}
break;
+ case TRACK_TITLE:
+ // Not implemented
+ break;
}
}
}
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
index ae726f2295..abe3fb10f4 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
@@ -774,7 +774,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
* contains an entry that's not in the array, insert a new entry
* in the array, move to next cursor row and next array entry.
*/
- while (!isAfterLast || arrayPos < mShares.size() && mListenStarted) {
+ while (!isAfterLast || (arrayPos < mShares.size() && mListenStarted)) {
if (isAfterLast) {
// We're beyond the end of the cursor but there's still some
// stuff in the local array, which can only be junk
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java
index af1abea1be..b6b742e19c 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java
@@ -446,6 +446,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch
mContext.getContentResolver(), contentUri, updateValues, null, null);
}
+ @SuppressLint("WaitNotInLoop")
private void markBatchFailed(int failReason) {
synchronized (this) {
try {
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
index 86ac40b481..77a2191528 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
@@ -187,10 +187,10 @@ public class BluetoothOppTransferActivity extends AlertActivity
if (isSuccess) {
// should not go here
mWhichDialog = DIALOG_RECEIVE_COMPLETE_SUCCESS;
- } else if (!isSuccess) {
+ } else {
mWhichDialog = DIALOG_RECEIVE_COMPLETE_FAIL;
}
- } else if (!isComplete) {
+ } else {
mWhichDialog = DIALOG_RECEIVE_ONGOING;
}
} else if (direction == BluetoothShare.DIRECTION_OUTBOUND) {
@@ -198,10 +198,10 @@ public class BluetoothOppTransferActivity extends AlertActivity
if (isSuccess) {
mWhichDialog = DIALOG_SEND_COMPLETE_SUCCESS;
- } else if (!isSuccess) {
+ } else {
mWhichDialog = DIALOG_SEND_COMPLETE_FAIL;
}
- } else if (!isComplete) {
+ } else {
mWhichDialog = DIALOG_SEND_ONGOING;
}
}
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
index cdfaff83b9..0292c6f684 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java
@@ -155,7 +155,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect
@VisibleForTesting
final HashMap<BluetoothDevice, PbapStateMachine> mPbapStateMachineMap = new HashMap<>();
- private volatile int mNextNotificationId = PBAP_NOTIFICATION_ID_START;
+ private int mNextNotificationId = PBAP_NOTIFICATION_ID_START;
// package and class name to which we send intent to check phone book access permission
private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings";
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
index 09965dccde..620074d1c0 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
@@ -1215,12 +1215,7 @@ public class BluetoothPbapVcardManager {
.replace(" ", "");
if (vTagAndTel[1].length() < telLenBefore) {
Log.v(TAG, "Fixing vCard TEL to " + vTagAndTel[1]);
- attr[i] =
- new StringBuilder()
- .append(vTagAndTel[0])
- .append(":")
- .append(vTagAndTel[1])
- .toString();
+ attr[i] = vTagAndTel[0] + ":" + vTagAndTel[1];
}
}
}
diff --git a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
index 47b0139250..1e32efb700 100644
--- a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
+++ b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
@@ -28,6 +28,7 @@ import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
+import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelUuid;
@@ -910,7 +911,12 @@ public class TbsGatt {
}
public boolean setIncomingCall(int callIndex, String uri) {
- Log.d(TAG, "setIncomingCall: callIndex=" + callIndex + " uri=" + uri);
+ Log.d(
+ TAG,
+ "setIncomingCall: callIndex="
+ + callIndex
+ + " uri="
+ + Uri.parse(uri).toSafeString());
int uri_len = 0;
if (uri != null) {
uri_len = uri.length();
diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java
index c8a2967d0d..f8fbe2b79b 100644
--- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java
+++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java
@@ -156,6 +156,7 @@ public class BluetoothInCallService extends InCallService {
@Override
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, MODIFY_PHONE_STATE})
public void onServiceConnected(int profile, BluetoothProfile proxy) {
+ Log.d(TAG, "onServiceConnected for profile: " + profile);
synchronized (LOCK) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = new BluetoothHeadsetProxy((BluetoothHeadset) proxy);
@@ -164,17 +165,20 @@ public class BluetoothInCallService extends InCallService {
mBluetoothLeCallControl =
new BluetoothLeCallControlProxy((BluetoothLeCallControl) proxy);
- mBluetoothLeCallControl.registerBearer(
- TAG,
- List.of("tel"),
- BluetoothLeCallControl.CAPABILITY_HOLD_CALL,
- getNetworkOperator(),
- getBearerTechnology(),
- mExecutor,
- mBluetoothLeCallControlCallback);
+ boolean isBearerRegistered =
+ mBluetoothLeCallControl.registerBearer(
+ TAG,
+ List.of("tel"),
+ BluetoothLeCallControl.CAPABILITY_HOLD_CALL,
+ getNetworkOperator(),
+ getBearerTechnology(),
+ mExecutor,
+ mBluetoothLeCallControlCallback);
+ Log.d(TAG, "isBearerRegistered: " + isBearerRegistered);
sendTbsCurrentCallsList();
}
}
+ Log.d(TAG, "Calls updated for profile: " + profile);
}
@Override
@@ -784,6 +788,7 @@ public class BluetoothInCallService extends InCallService {
if (mBluetoothLeCallControl != null) {
mBluetoothLeCallControl.unregisterBearer();
mBluetoothLeCallControl.closeBluetoothLeCallControlProxy(mAdapter);
+ mBluetoothLeCallControl = null;
}
sInstance = null;
mCallbacks.clear();
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java
index 7293f7f086..4d7e721021 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlNativeInterface.java
@@ -251,13 +251,15 @@ public class VolumeControlNativeInterface {
}
@VisibleForTesting
- void onVolumeStateChanged(int volume, boolean mute, byte[] address, boolean isAutonomous) {
+ void onVolumeStateChanged(
+ int volume, boolean mute, int flags, byte[] address, boolean isAutonomous) {
VolumeControlStackEvent event =
new VolumeControlStackEvent(
VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
event.device = getDevice(address);
event.valueInt1 = -1;
event.valueInt2 = volume;
+ event.valueInt3 = flags;
event.valueBool1 = mute;
event.valueBool2 = isAutonomous;
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
index 29d0a95982..889b9bce53 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
@@ -200,6 +200,11 @@ public class VolumeControlService extends ProfileService {
private final Map<Integer, Boolean> mGroupMuteCache = new HashMap<>();
private final Map<BluetoothDevice, Integer> mDeviceVolumeCache = new HashMap<>();
+ /* As defined by Volume Control Service 1.0.1, 3.3.1. Volume Flags behavior.
+ * User Set Volume Setting means that remote keeps volume in its cache.
+ */
+ @VisibleForTesting static final int VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK = 0x01;
+
@VisibleForTesting ServiceFactory mFactory = new ServiceFactory();
public VolumeControlService(Context ctx) {
@@ -862,14 +867,22 @@ public class VolumeControlService extends ProfileService {
}
}
- void handleVolumeControlChanged(
- BluetoothDevice device, int groupId, int volume, boolean mute, boolean isAutonomous) {
+ int getBleVolumeFromCurrentStream() {
+ int streamType = getBluetoothContextualVolumeStream();
+ int streamVolume = mAudioManager.getStreamVolume(streamType);
+ int streamMaxVolume = mAudioManager.getStreamMaxVolume(streamType);
- if (isAutonomous && device != null) {
- Log.e(TAG, "We expect only group notification for autonomous updates");
- return;
- }
+ /* leaudio expect volume value in range 0 to 255 */
+ return (int) Math.round((double) streamVolume * LE_AUDIO_MAX_VOL / streamMaxVolume);
+ }
+ void handleVolumeControlChanged(
+ BluetoothDevice device,
+ int groupId,
+ int volume,
+ int flags,
+ boolean mute,
+ boolean isAutonomous) {
if (groupId == IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID) {
LeAudioService leAudioService = mFactory.getLeAudioService();
if (leAudioService == null) {
@@ -887,6 +900,34 @@ public class VolumeControlService extends ProfileService {
int groupVolume = getGroupVolume(groupId);
Boolean groupMute = getGroupMute(groupId);
+ if (isAutonomous && device != null) {
+ Log.i(
+ TAG,
+ ("Initial volume set after connect, volume: " + volume)
+ + (", mute: " + mute)
+ + (", flags: " + flags));
+ /* We are here, because system has just started and LeAudio device is connected. If
+ * remote device has User Persistent flag set or the volume != 0, Android sets the
+ * volume to local cache and to the audio system. If Reset Flag is set and remote has
+ * volume set to 0, then Android sets to remote devices either cached volume volume
+ * taken from audio manager. Note, to match BR/EDR behavior, don't show volume change in
+ * UI here
+ */
+ if ((flags & VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK) == 0x01 || (volume != 0)) {
+ updateGroupCacheAndAudioSystem(groupId, volume, mute, false);
+ } else {
+ if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) {
+ Log.i(TAG, "Setting volume: " + groupVolume + " to the group: " + groupId);
+ setGroupVolume(groupId, groupVolume);
+ } else {
+ int vol = getBleVolumeFromCurrentStream();
+ Log.i(TAG, "Setting system volume: " + vol + " to the group: " + groupId);
+ setGroupVolume(groupId, getBleVolumeFromCurrentStream());
+ }
+ }
+ return;
+ }
+
if (Flags.leaudioBroadcastVolumeControlForConnectedDevices()) {
Log.i(TAG, "handleVolumeControlChanged: " + device + "; volume: " + volume);
if (device == null) {
@@ -906,16 +947,6 @@ public class VolumeControlService extends ProfileService {
}
}
- if (groupVolume == IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) {
- /* We are here, because system was just started and LeAudio device just connected.
- * In such case, we take Volume stored on remote device and apply it to our cache and
- * audio system.
- * Note, to match BR/EDR behavior, don't show volume change in UI here
- */
- updateGroupCacheAndAudioSystem(groupId, volume, mute, false);
- return;
- }
-
if (!isAutonomous) {
/* If the change is triggered by Android device, the stream is already changed.
* However it might be called with isAutonomous, one the first read of after
@@ -1119,6 +1150,7 @@ public class VolumeControlService extends ProfileService {
stackEvent.device,
stackEvent.valueInt1,
stackEvent.valueInt2,
+ stackEvent.valueInt3,
stackEvent.valueBool1,
stackEvent.valueBool2);
return;
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
index 502519678e..aba8aedaf0 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
@@ -40,6 +40,7 @@ public class VolumeControlStackEvent {
public BluetoothDevice device;
public int valueInt1;
public int valueInt2;
+ public int valueInt3;
public boolean valueBool1;
public boolean valueBool2;
public String valueString1;
@@ -58,6 +59,7 @@ public class VolumeControlStackEvent {
result.append(", device:").append(device);
result.append(", valueInt1:").append(eventTypeValue1ToString(type, valueInt1));
result.append(", valueInt2:").append(eventTypeValue2ToString(type, valueInt2));
+ result.append(", valueInt3:").append(eventTypeValue3ToString(type, valueInt3));
result.append(", valueBool1:").append(eventTypeValueBool1ToString(type, valueBool1));
result.append(", valueBool2:").append(eventTypeValueBool2ToString(type, valueBool2));
result.append(", valueString1:").append(eventTypeString1ToString(type, valueString1));
@@ -138,6 +140,16 @@ public class VolumeControlStackEvent {
return Integer.toString(value);
}
+ private static String eventTypeValue3ToString(int type, int value) {
+ switch (type) {
+ case EVENT_TYPE_VOLUME_STATE_CHANGED:
+ return "{flags:" + value + "}";
+ default:
+ break;
+ }
+ return Integer.toString(value);
+ }
+
private static String eventTypeValueBool1ToString(int type, boolean value) {
switch (type) {
case EVENT_TYPE_VOLUME_STATE_CHANGED:
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java
index 3ea1e6d55f..0ada5156b3 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterPropertiesTest.java
@@ -89,7 +89,6 @@ public class AdapterPropertiesTest {
mRemoteDevices.reset();
doReturn(mHandlerThread.getLooper()).when(mAdapterService).getMainLooper();
- doReturn(true).when(mAdapterService).isMock();
when(mAdapterService.getResources())
.thenReturn(InstrumentationRegistry.getTargetContext().getResources());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java
index 02dd5930e4..eefa37fd3a 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceBinderTest.java
@@ -27,7 +27,6 @@ import android.bluetooth.IBluetoothOobDataCallback;
import android.content.AttributionSource;
import android.os.ParcelUuid;
-import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -56,11 +55,6 @@ public class AdapterServiceBinderTest {
mAttributionSource = new AttributionSource.Builder(0).build();
}
- @After
- public void cleanUp() {
- mBinder.cleanup();
- }
-
@Test
public void getAddress() {
mBinder.getAddress(mAttributionSource);
@@ -73,10 +67,16 @@ public class AdapterServiceBinderTest {
String[] args = new String[] {};
mBinder.dump(fd, args);
verify(mService).dump(any(), any(), any());
+ }
+
+ @Test
+ public void dumpWhenNotAvailable() {
+ FileDescriptor fd = new FileDescriptor();
+ String[] args = new String[] {};
+ doReturn(false).when(mService).isAvailable();
- Mockito.clearInvocations(mService);
- mBinder.cleanup();
mBinder.dump(fd, args);
+
verify(mService, never()).dump(any(), any(), any());
}
@@ -86,11 +86,18 @@ public class AdapterServiceBinderTest {
IBluetoothOobDataCallback cb = Mockito.mock(IBluetoothOobDataCallback.class);
mBinder.generateLocalOobData(transport, cb, mAttributionSource);
+
verify(mService).generateLocalOobData(transport, cb);
+ }
+
+ @Test
+ public void generateLocalOobDataWhenNotAvailable() {
+ int transport = 0;
+ IBluetoothOobDataCallback cb = Mockito.mock(IBluetoothOobDataCallback.class);
+ doReturn(false).when(mService).isAvailable();
- Mockito.clearInvocations(mService);
- mBinder.cleanup();
mBinder.generateLocalOobData(transport, cb, mAttributionSource);
+
verify(mService, never()).generateLocalOobData(transport, cb);
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
index ff51f15b41..9e96712a48 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
@@ -203,7 +203,7 @@ public class AdapterServiceTest {
@Parameters(name = "{0}")
public static List<FlagsParameterization> getParams() {
- return FlagsParameterization.allCombinationsOf(Flags.FLAG_EXPLICIT_KILL_FROM_SYSTEM_SERVER);
+ return FlagsParameterization.allCombinationsOf();
}
public AdapterServiceTest(FlagsParameterization flags) {
@@ -552,12 +552,9 @@ public class AdapterServiceTest {
verify(nativeInterface).disable();
adapter.stateChangeCallback(AbstractionLayer.BT_STATE_OFF);
TestUtils.syncHandler(looper, AdapterState.BLE_STOPPED);
- if (Flags.explicitKillFromSystemServer()) {
- // When reaching the OFF state, the cleanup is called that will destroy the state
- // machine of the adapterService. Destroying state machine send a -1 event on the
- // handler
- TestUtils.syncHandler(looper, -1);
- }
+ // When reaching the OFF state, the cleanup is called that will destroy the state machine of
+ // the adapterService. Destroying state machine send a -1 event on the handler
+ TestUtils.syncHandler(looper, -1);
verifyStateChange(callback, STATE_BLE_TURNING_OFF, STATE_OFF);
assertThat(adapter.getState()).isEqualTo(STATE_OFF);
@@ -640,12 +637,9 @@ public class AdapterServiceTest {
assertThat(mAdapterService.getBluetoothGatt()).isNull();
syncHandler(AdapterState.BLE_STOPPED);
- if (Flags.explicitKillFromSystemServer()) {
- // When reaching the OFF state, the cleanup is called that will destroy the state
- // machine of the adapterService. Destroying state machine send a -1 event on the
- // handler
- syncHandler(-1);
- }
+ // When reaching the OFF state, the cleanup is called that will destroy the state machine of
+ // the adapterService. Destroying state machine send a -1 event on the handler
+ syncHandler(-1);
syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
syncHandler(MESSAGE_PROFILE_SERVICE_UNREGISTERED);
@@ -678,12 +672,9 @@ public class AdapterServiceTest {
mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
syncHandler(AdapterState.BLE_STOP_TIMEOUT);
- if (Flags.explicitKillFromSystemServer()) {
- // When reaching the OFF state, the cleanup is called that will destroy the state
- // machine of the adapterService. Destroying state machine send a -1 event on the
- // handler
- syncHandler(-1);
- }
+ // When reaching the OFF state, the cleanup is called that will destroy the state machine of
+ // the adapterService. Destroying state machine send a -1 event on the handler
+ syncHandler(-1);
verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
@@ -739,12 +730,9 @@ public class AdapterServiceTest {
verify(mNativeInterface).disable();
mAdapterService.stateChangeCallback(AbstractionLayer.BT_STATE_OFF);
syncHandler(AdapterState.BLE_STOPPED);
- if (Flags.explicitKillFromSystemServer()) {
- // When reaching the OFF state, the cleanup is called that will destroy the state
- // machine of the adapterService. Destroying state machine send a -1 event on the
- // handler
- syncHandler(-1);
- }
+ // When reaching the OFF state, the cleanup is called that will destroy the state machine of
+ // the adapterService. Destroying state machine send a -1 event on the handler
+ syncHandler(-1);
verifyStateChange(callback, STATE_BLE_TURNING_OFF, STATE_OFF);
assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
@@ -890,12 +878,9 @@ public class AdapterServiceTest {
// TODO(b/280518177): The only timeout to fire here should be the BREDR
mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
syncHandler(AdapterState.BLE_STOP_TIMEOUT);
- if (Flags.explicitKillFromSystemServer()) {
- // When reaching the OFF state, the cleanup is called that will destroy the state
- // machine of the adapterService. Destroying state machine send a -1 event on the
- // handler
- syncHandler(-1);
- }
+ // When reaching the OFF state, the cleanup is called that will destroy the state machine of
+ // the adapterService. Destroying state machine send a -1 event on the handler
+ syncHandler(-1);
verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
@@ -938,12 +923,9 @@ public class AdapterServiceTest {
mAdapterService.stateChangeCallback(AbstractionLayer.BT_STATE_OFF);
syncHandler(AdapterState.BLE_STOPPED);
- if (Flags.explicitKillFromSystemServer()) {
- // When reaching the OFF state, the cleanup is called that will destroy the state
- // machine of the adapterService. Destroying state machine send a -1 event on the
- // handler
- syncHandler(-1);
- }
+ // When reaching the OFF state, the cleanup is called that will destroy the state machine of
+ // the adapterService. Destroying state machine send a -1 event on the handler
+ syncHandler(-1);
verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java
index 0be41d1e11..7cd13fe4b4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/CompanionManagerTest.java
@@ -72,8 +72,6 @@ public class CompanionManagerTest {
.when(mAdapterService)
.getSharedPreferences(
eq(CompanionManager.COMPANION_INFO), eq(Context.MODE_PRIVATE));
- // Tell the AdapterService that it is a mock (see isMock documentation)
- doReturn(true).when(mAdapterService).isMock();
// Use the resources in the instrumentation instead of the mocked AdapterService
when(mAdapterService.getResources()).thenReturn(mTargetContext.getResources());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java
index 43975ca1d1..7940da07e0 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java
@@ -116,8 +116,6 @@ public class PhonePolicyTest {
mHandlerThread.start();
// Mock the looper
when(mAdapterService.getMainLooper()).thenReturn(mHandlerThread.getLooper());
- // Tell the AdapterService that it is a mock (see isMock documentation)
- doReturn(true).when(mAdapterService).isMock();
// Must be called to initialize services
mAdapter = BluetoothAdapter.getDefaultAdapter();
PhonePolicy.sConnectOtherProfilesTimeoutMillis = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS;
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
index 1ed290c8b9..5fbea684ba 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
@@ -71,10 +71,11 @@ public class VolumeControlNativeInterfaceTest {
public void onVolumeStateChanged() {
int volume = 3;
boolean mute = false;
+ int flags = 1;
byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
boolean isAutonomous = false;
- mNativeInterface.onVolumeStateChanged(volume, mute, address, isAutonomous);
+ mNativeInterface.onVolumeStateChanged(volume, mute, flags, address, isAutonomous);
ArgumentCaptor<VolumeControlStackEvent> event =
ArgumentCaptor.forClass(VolumeControlStackEvent.class);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
index e082b4ad1b..0d216d3cb5 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
@@ -539,22 +539,18 @@ public class VolumeControlServiceTest {
Assert.assertFalse(mService.getDevices().contains(mDevice));
}
+
/** Test that various Volume Control stack events will broadcast related states. */
@Test
public void testVolumeControlStackEvents() {
int group_id = -1;
int volume = 6;
+ int flags = 0;
boolean mute = false;
+ boolean isAutonomous = false;
// Send a message to trigger volume state changed broadcast
- VolumeControlStackEvent stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
- stackEvent.device = mDevice;
- stackEvent.valueInt1 = group_id;
- stackEvent.valueInt2 = volume;
- stackEvent.valueBool1 = mute;
- mService.messageFromNative(stackEvent);
+ generateVolumeStateChanged(mDevice, group_id, volume, flags, mute, isAutonomous);
}
int getLeAudioVolume(int index, int minIndex, int maxIndex, int streamType) {
@@ -614,29 +610,18 @@ public class VolumeControlServiceTest {
int streamType = AudioManager.STREAM_MUSIC;
int streamVol = getLeAudioVolume(19, MEDIA_MIN_VOL, MEDIA_MAX_VOL, streamType);
- // Send a message to trigger volume state changed broadcast
- final VolumeControlStackEvent stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
- stackEvent.device = null;
- stackEvent.valueInt1 = 1; // groupId
- stackEvent.valueInt2 = streamVol;
- stackEvent.valueBool1 = false; // isMuted
- stackEvent.valueBool2 = true; // isAutonomous
-
doReturn(false).when(mAudioManager).isStreamMute(eq(AudioManager.STREAM_MUSIC));
// Verify that muting LeAudio device, sets the mute state on the audio device
- stackEvent.valueBool1 = true;
- mService.messageFromNative(stackEvent);
+
+ generateVolumeStateChanged(null, 1, streamVol, 0, true, true);
verify(mAudioManager, times(1))
.adjustStreamVolume(eq(streamType), eq(AudioManager.ADJUST_MUTE), anyInt());
doReturn(true).when(mAudioManager).isStreamMute(eq(AudioManager.STREAM_MUSIC));
// Verify that unmuting LeAudio device, unsets the mute state on the audio device
- stackEvent.valueBool1 = false;
- mService.messageFromNative(stackEvent);
+ generateVolumeStateChanged(null, 1, streamVol, 0, false, true);
verify(mAudioManager, times(1))
.adjustStreamVolume(eq(streamType), eq(AudioManager.ADJUST_UNMUTE), anyInt());
}
@@ -655,15 +640,7 @@ public class VolumeControlServiceTest {
volume = 10;
// Send autonomous volume change.
- VolumeControlStackEvent stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
- stackEvent.device = null;
- stackEvent.valueInt1 = groupId;
- stackEvent.valueInt2 = volume;
- stackEvent.valueBool1 = false;
- stackEvent.valueBool2 = true; /* autonomous */
- mService.messageFromNative(stackEvent);
+ generateVolumeStateChanged(null, groupId, volume, 0, false, true);
Assert.assertEquals(volume, mService.getGroupVolume(groupId));
}
@@ -710,15 +687,7 @@ public class VolumeControlServiceTest {
Assert.assertEquals(false, mService.getGroupMute(groupId));
// Send autonomous volume change
- VolumeControlStackEvent stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
- stackEvent.device = null;
- stackEvent.valueInt1 = groupId;
- stackEvent.valueInt2 = volume;
- stackEvent.valueBool1 = false; /* unmuted */
- stackEvent.valueBool2 = true; /* autonomous */
- mService.messageFromNative(stackEvent);
+ generateVolumeStateChanged(null, groupId, volume, 0, false, true);
// Mute
mServiceBinder.muteGroup(groupId, mAttributionSource);
@@ -728,8 +697,7 @@ public class VolumeControlServiceTest {
Assert.assertEquals(volume, mService.getGroupVolume(groupId));
// Send autonomous unmute
- stackEvent.valueBool1 = false; /* unmuted */
- mService.messageFromNative(stackEvent);
+ generateVolumeStateChanged(null, groupId, volume, 0, false, true);
Assert.assertEquals(false, mService.getGroupMute(groupId));
}
@@ -742,16 +710,7 @@ public class VolumeControlServiceTest {
Assert.assertEquals(false, mService.getGroupMute(groupId));
- // Set the initial volume state
- VolumeControlStackEvent stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
- stackEvent.device = null;
- stackEvent.valueInt1 = groupId;
- stackEvent.valueInt2 = volume;
- stackEvent.valueBool1 = false; /* unmuted */
- stackEvent.valueBool2 = true; /* autonomous */
- mService.messageFromNative(stackEvent);
+ generateVolumeStateChanged(null, groupId, volume, 0, false, true);
// Mute
mService.muteGroup(groupId);
@@ -788,6 +747,199 @@ public class VolumeControlServiceTest {
verify(mNativeInterface, times(1)).unmuteGroup(eq(groupId));
}
+ /** Test if phone will set volume which is read from the buds */
+ @Test
+ public void testConnectedDeviceWithUserPersistFlagSet() throws Exception {
+ int groupId = 1;
+ int volumeDevice = 56;
+ int volumeDeviceTwo = 100;
+ int flags = VolumeControlService.VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK;
+ boolean initialMuteState = false;
+ boolean initialAutonomousFlag = true;
+
+ // Both devices are in the same group
+ when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
+ when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
+
+ // Update the device policy so okToConnect() returns true
+ when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
+ when(mDatabaseManager.getProfileConnectionPolicy(
+ any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
+ .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
+ doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
+
+ generateDeviceAvailableMessageFromNative(mDevice, 1);
+ generateConnectionMessageFromNative(
+ mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+ Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
+ Assert.assertTrue(mService.getDevices().contains(mDevice));
+
+ // Group is not active, AF will not be notified
+ generateVolumeStateChanged(
+ mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag);
+ verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt());
+
+ // Make device Active now. This will trigger setting volume to AF
+ when(mLeAudioService.getActiveGroupId()).thenReturn(groupId);
+ mServiceBinder.setGroupActive(groupId, true, mAttributionSource);
+ int expectedAfVol =
+ (int) Math.round((double) (volumeDevice * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
+ verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
+
+ // Connect second device and read different volume. Expect it will be set to AF and to
+ // another set member
+ generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
+ generateConnectionMessageFromNative(
+ mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+ Assert.assertEquals(
+ BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
+ Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+
+ // Group is now active, AF will be notified. Native will take care to sync the volume
+ generateVolumeStateChanged(
+ mDeviceTwo,
+ groupId,
+ volumeDeviceTwo,
+ flags,
+ initialMuteState,
+ initialAutonomousFlag);
+ expectedAfVol =
+ (int) Math.round((double) (volumeDeviceTwo * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
+ verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
+ }
+
+ /** Test if phone will set volume which is read from the buds */
+ @Test
+ public void testConnectedDeviceWithResetFlagSetWithNonZeroVolume() throws Exception {
+ int groupId = 1;
+ int volumeDevice = 56;
+ int volumeDeviceTwo = 100;
+ int flags = 0;
+ boolean initialMuteState = false;
+ boolean initialAutonomousFlag = true;
+
+ // Both devices are in the same group
+ when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
+ when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
+
+ // Update the device policy so okToConnect() returns true
+ when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
+ when(mDatabaseManager.getProfileConnectionPolicy(
+ any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
+ .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
+ doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
+
+ generateDeviceAvailableMessageFromNative(mDevice, 1);
+ generateConnectionMessageFromNative(
+ mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+ Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
+ Assert.assertTrue(mService.getDevices().contains(mDevice));
+
+ // Group is not active, AF will not be notified
+ generateVolumeStateChanged(
+ mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag);
+ verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt());
+
+ // Make device Active now. This will trigger setting volume to AF
+ when(mLeAudioService.getActiveGroupId()).thenReturn(groupId);
+ mServiceBinder.setGroupActive(groupId, true, mAttributionSource);
+ int expectedAfVol =
+ (int) Math.round((double) (volumeDevice * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
+ verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
+
+ // Connect second device and read different volume. Expect it will be set to AF and to
+ // another set member
+ generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
+ generateConnectionMessageFromNative(
+ mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+ Assert.assertEquals(
+ BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
+ Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+
+ // Group is now active, AF will be notified. Native will take care to sync the volume
+ generateVolumeStateChanged(
+ mDeviceTwo,
+ groupId,
+ volumeDeviceTwo,
+ flags,
+ initialMuteState,
+ initialAutonomousFlag);
+ expectedAfVol =
+ (int) Math.round((double) (volumeDeviceTwo * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
+ verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
+ }
+
+ /** Test if phone will set volume to buds which has no volume */
+ @Test
+ public void testConnectedDeviceWithResetFlagSetWithZeroVolume() throws Exception {
+ int groupId = 1;
+ int volumeDevice = 0;
+ int volumeDeviceTwo = 0;
+ int flags = 0;
+ boolean initialMuteState = false;
+ boolean initialAutonomousFlag = true;
+ int streamVolume = 50;
+ int streamMaxVolume = 100;
+
+ // Both devices are in the same group
+ when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
+ when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
+
+ when(mAudioManager.getStreamVolume(anyInt())).thenReturn(streamVolume);
+ when(mAudioManager.getStreamMaxVolume(anyInt())).thenReturn(streamMaxVolume);
+
+ // Update the device policy so okToConnect() returns true
+ when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
+ when(mDatabaseManager.getProfileConnectionPolicy(
+ any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
+ .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
+ doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
+
+ generateDeviceAvailableMessageFromNative(mDevice, 1);
+ generateConnectionMessageFromNative(
+ mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+ Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
+ Assert.assertTrue(mService.getDevices().contains(mDevice));
+
+ // Group is not active, AF will not be notified but device will get phone volume
+ int expectedDeviceVol =
+ (int) Math.round((double) streamVolume * BT_LE_AUDIO_MAX_VOL / streamMaxVolume);
+ generateVolumeStateChanged(
+ mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag);
+ verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt());
+ verify(mNativeInterface, times(1)).setGroupVolume(eq(groupId), eq(expectedDeviceVol));
+
+ // Make device Active now. This will trigger setting volume to AF
+ when(mLeAudioService.getActiveGroupId()).thenReturn(groupId);
+ mServiceBinder.setGroupActive(groupId, true, mAttributionSource);
+
+ verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(streamVolume), anyInt());
+
+ // Connect second device and read different volume. Expect it will be set to AF and to
+ // another set member
+ generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
+ generateConnectionMessageFromNative(
+ mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
+ Assert.assertEquals(
+ BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
+ Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+
+ // Group is now active, AF will be notified. Native will take care to sync the volume
+ generateVolumeStateChanged(
+ mDeviceTwo,
+ groupId,
+ volumeDeviceTwo,
+ flags,
+ initialMuteState,
+ initialAutonomousFlag);
+
+ verify(mAudioManager, times(1)).setStreamVolume(anyInt(), anyInt(), anyInt());
+ verify(mNativeInterface, times(2)).setGroupVolume(eq(groupId), eq(expectedDeviceVol));
+ }
+
/**
* Test setting volume for a group member who connects after the volume level for a group was
* already changed and cached.
@@ -1368,30 +1520,15 @@ public class VolumeControlServiceTest {
when(mLeAudioService.getGroupDevices(groupId))
.thenReturn(Arrays.asList(mDevice, mDeviceTwo));
+
// Send group volume change.
- VolumeControlStackEvent stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
- stackEvent.device = null;
- stackEvent.valueInt1 = groupId;
- stackEvent.valueInt2 = groupVolume;
- stackEvent.valueBool1 = false;
- stackEvent.valueBool2 = true;
- mService.messageFromNative(stackEvent);
+ generateVolumeStateChanged(null, groupId, groupVolume, 0, false, true);
verify(callback).onDeviceVolumeChanged(eq(mDeviceTwo), eq(groupVolume));
verify(callback).onDeviceVolumeChanged(eq(mDevice), eq(groupVolume));
// Send device volume change only for one device
- VolumeControlStackEvent stackEvent2 =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
- stackEvent2.device = mDevice;
- stackEvent2.valueInt1 = -1;
- stackEvent2.valueInt2 = deviceOneVolume;
- stackEvent2.valueBool1 = false;
- stackEvent2.valueBool2 = false;
- mService.messageFromNative(stackEvent2);
+ generateVolumeStateChanged(mDevice, -1, deviceOneVolume, 0, false, false);
verify(callback).onDeviceVolumeChanged(eq(mDevice), eq(deviceOneVolume));
verify(callback, never()).onDeviceVolumeChanged(eq(mDeviceTwo), eq(deviceOneVolume));
@@ -1480,6 +1617,25 @@ public class VolumeControlServiceTest {
mService.messageFromNative(event);
}
+ private void generateVolumeStateChanged(
+ BluetoothDevice device,
+ int group_id,
+ int volume,
+ int flags,
+ boolean mute,
+ boolean isAutonomous) {
+ VolumeControlStackEvent stackEvent =
+ new VolumeControlStackEvent(
+ VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
+ stackEvent.device = device;
+ stackEvent.valueInt1 = group_id;
+ stackEvent.valueInt2 = volume;
+ stackEvent.valueInt3 = flags;
+ stackEvent.valueBool1 = mute;
+ stackEvent.valueBool2 = isAutonomous;
+ mService.messageFromNative(stackEvent);
+ }
+
private void generateDeviceOffsetChangedMessageFromNative(
BluetoothDevice device, int extOffsetIndex, int offset) {
// Send a message to trigger connection completed
diff --git a/flags/Android.bp b/flags/Android.bp
index 091d3787c7..d4a9a7928e 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -43,7 +43,6 @@ aconfig_declarations {
"rnr.aconfig",
"sdp.aconfig",
"security.aconfig",
- "sniff.aconfig",
"sockets.aconfig",
"system_service.aconfig",
"vcp.aconfig",
diff --git a/flags/BUILD.gn b/flags/BUILD.gn
index 6cedf5c7d5..9ea5b5afc1 100644
--- a/flags/BUILD.gn
+++ b/flags/BUILD.gn
@@ -37,7 +37,6 @@ aconfig("bluetooth_flags_c_lib") {
"rnr.aconfig",
"sdp.aconfig",
"security.aconfig",
- "sniff.aconfig",
"sockets.aconfig",
"system_service.aconfig",
"vcp.aconfig",
diff --git a/flags/active_device_manager.aconfig b/flags/active_device_manager.aconfig
index 0835a5fb7e..37f2b65e1c 100644
--- a/flags/active_device_manager.aconfig
+++ b/flags/active_device_manager.aconfig
@@ -6,6 +6,9 @@ flag {
namespace: "bluetooth"
description: "Fallback to other connected device when wired audio device disconnects"
bug: "348124361"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {
@@ -13,4 +16,7 @@ flag {
namespace: "bluetooth"
description: "Fix audio path and always fallback to available device"
bug: "351820274"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/flags/connectivity.aconfig b/flags/connectivity.aconfig
index ef83336d00..2605af718a 100644
--- a/flags/connectivity.aconfig
+++ b/flags/connectivity.aconfig
@@ -14,3 +14,14 @@ flag {
description: "Guard the le shim connection map with a mutex"
bug: "302054609"
}
+
+flag {
+ name: "improve_create_connection_for_already_connecting_device"
+ namespace: "bluetooth"
+ description: "Make sure to not stop controller with create connection cancel when not needed"
+ bug: "356593752"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
diff --git a/flags/gap.aconfig b/flags/gap.aconfig
index 13c3a57f22..25d9fc2014 100644
--- a/flags/gap.aconfig
+++ b/flags/gap.aconfig
@@ -239,3 +239,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "android_os_identifier"
+ namespace: "bluetooth"
+ description: "Add a custom service to provide Android OS identifier"
+ bug: "351860033"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/sniff.aconfig b/flags/sniff.aconfig
deleted file mode 100644
index 5b66d7494a..0000000000
--- a/flags/sniff.aconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-package: "com.android.bluetooth.flags"
-container: "com.android.btservices"
-
-flag {
- name: "enable_sniff_offload"
- namespace: "bluetooth"
- description: "Enable sniff offload feature."
- bug: "318786790"
-}
diff --git a/flags/system_service.aconfig b/flags/system_service.aconfig
index 976f966dce..b59a9c1b4c 100644
--- a/flags/system_service.aconfig
+++ b/flags/system_service.aconfig
@@ -30,16 +30,6 @@ flag {
}
flag {
- name: "explicit_kill_from_system_server"
- namespace: "bluetooth"
- description: "Explicit kill and wait of Bluetooth AdapterService when turning Bluetooth OFF"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
- bug: "339548431"
-}
-
-flag {
name: "fast_bind_to_app"
namespace: "bluetooth"
description: "Remove complexity and non necessary initialization when simply binding"
diff --git a/floss/hcidoc/packets/Cargo.toml b/floss/hcidoc/packets/Cargo.toml
index 6792c71aeb..cd633bb88c 100644
--- a/floss/hcidoc/packets/Cargo.toml
+++ b/floss/hcidoc/packets/Cargo.toml
@@ -26,7 +26,7 @@ edition = "2018"
build = "build.rs"
[dependencies]
-bindgen = "0.64"
+bindgen = "0.69.4"
bytes = "1.0"
num-derive = "0.3"
num-traits = "0.2"
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index de31b2cf25..0b645bccb7 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -99,6 +99,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiFunction;
+import java.util.function.Consumer;
/**
* Represents the local device Bluetooth adapter. The {@link BluetoothAdapter} lets you perform
@@ -888,10 +889,6 @@ public final class BluetoothAdapter {
mMetadataListeners = new HashMap<>();
private final Map<BluetoothConnectionCallback, Executor>
mBluetoothConnectionCallbackExecutorMap = new HashMap<>();
- private final Map<PreferredAudioProfilesChangedCallback, Executor>
- mAudioProfilesChangedCallbackExecutorMap = new HashMap<>();
- private final Map<BluetoothQualityReportReadyCallback, Executor>
- mBluetoothQualityReportReadyCallbackExecutorMap = new HashMap<>();
private static final class ProfileConnection {
int mProfile;
@@ -1106,6 +1103,51 @@ public final class BluetoothAdapter {
} finally {
mServiceLock.writeLock().unlock();
}
+
+ Consumer<IBluetooth> registerQualityReportCallbackConsumer =
+ (IBluetooth service) -> {
+ try {
+ service.registerBluetoothQualityReportReadyCallback(
+ mBluetoothQualityReportReadyCallback, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ };
+ Consumer<IBluetooth> unregisterQualityReportCallbackConsumer =
+ (IBluetooth service) -> {
+ try {
+ service.unregisterBluetoothQualityReportReadyCallback(
+ mBluetoothQualityReportReadyCallback, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ };
+ mQualityCallbackWrapper =
+ new CallbackWrapper(
+ registerQualityReportCallbackConsumer,
+ unregisterQualityReportCallbackConsumer);
+ Consumer<IBluetooth> registerAudioProfilesCallbackConsumer =
+ (IBluetooth service) -> {
+ try {
+ service.registerPreferredAudioProfilesChangedCallback(
+ mPreferredAudioProfilesChangedCallback, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ };
+ Consumer<IBluetooth> unregisterAudioProfilesCallbackConsumer =
+ (IBluetooth service) -> {
+ try {
+ service.unregisterPreferredAudioProfilesChangedCallback(
+ mPreferredAudioProfilesChangedCallback, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ };
+ mAudioProfilesCallbackWrapper =
+ new CallbackWrapper(
+ registerAudioProfilesCallbackConsumer,
+ unregisterAudioProfilesCallbackConsumer);
}
/**
@@ -3740,36 +3782,8 @@ public final class BluetoothAdapter {
}
});
}
- synchronized (mAudioProfilesChangedCallbackExecutorMap) {
- if (!mAudioProfilesChangedCallbackExecutorMap.isEmpty()) {
- try {
- mService.registerPreferredAudioProfilesChangedCallback(
- mPreferredAudioProfilesChangedCallback,
- mAttributionSource);
- } catch (RemoteException e) {
- Log.e(
- TAG,
- "onBluetoothServiceUp: Failed to register bluetooth"
- + "connection callback",
- e);
- }
- }
- }
- synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) {
- if (!mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) {
- try {
- mService.registerBluetoothQualityReportReadyCallback(
- mBluetoothQualityReportReadyCallback,
- mAttributionSource);
- } catch (RemoteException e) {
- Log.e(
- TAG,
- "onBluetoothServiceUp: Failed to register bluetooth"
- + "quality report callback",
- e);
- }
- }
- }
+ mAudioProfilesCallbackWrapper.registerToNewService(mService);
+ mQualityCallbackWrapper.registerToNewService(mService);
} finally {
mServiceLock.readLock().unlock();
}
@@ -5060,23 +5074,18 @@ public final class BluetoothAdapter {
return BluetoothStatusCodes.ERROR_UNKNOWN;
}
- @SuppressLint("AndroidFrameworkBluetoothPermission")
+ private final CallbackWrapper<PreferredAudioProfilesChangedCallback, IBluetooth>
+ mAudioProfilesCallbackWrapper;
+
private final IBluetoothPreferredAudioProfilesCallback mPreferredAudioProfilesChangedCallback =
new IBluetoothPreferredAudioProfilesCallback.Stub() {
@Override
public void onPreferredAudioProfilesChanged(
BluetoothDevice device, Bundle preferredAudioProfiles, int status) {
- for (Map.Entry<PreferredAudioProfilesChangedCallback, Executor>
- callbackExecutorEntry :
- mAudioProfilesChangedCallbackExecutorMap.entrySet()) {
- PreferredAudioProfilesChangedCallback callback =
- callbackExecutorEntry.getKey();
- Executor executor = callbackExecutorEntry.getValue();
- executor.execute(
- () ->
- callback.onPreferredAudioProfilesChanged(
- device, preferredAudioProfiles, status));
- }
+ mAudioProfilesCallbackWrapper.forEach(
+ (cb) ->
+ cb.onPreferredAudioProfilesChanged(
+ device, preferredAudioProfiles, status));
}
};
@@ -5118,36 +5127,20 @@ public final class BluetoothAdapter {
@NonNull @CallbackExecutor Executor executor,
@NonNull PreferredAudioProfilesChangedCallback callback) {
if (DBG) Log.d(TAG, "registerPreferredAudioProfilesChangedCallback()");
- requireNonNull(executor, "executor cannot be null");
- requireNonNull(callback, "callback cannot be null");
-
- synchronized (mAudioProfilesChangedCallbackExecutorMap) {
- // If the callback map is empty, we register the service-to-app callback
- if (mAudioProfilesChangedCallbackExecutorMap.isEmpty()) {
- int serviceCallStatus = BluetoothStatusCodes.ERROR_UNKNOWN;
- mServiceLock.readLock().lock();
- try {
- if (mService != null) {
- serviceCallStatus =
- mService.registerPreferredAudioProfilesChangedCallback(
- mPreferredAudioProfilesChangedCallback, mAttributionSource);
- }
- } catch (RemoteException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } finally {
- mServiceLock.readLock().unlock();
- }
- if (serviceCallStatus != BluetoothStatusCodes.SUCCESS) {
- return serviceCallStatus;
- }
- }
+ requireNonNull(callback);
+ requireNonNull(executor);
- // Adds the passed in callback to our local mapping
- if (mAudioProfilesChangedCallbackExecutorMap.containsKey(callback)) {
- throw new IllegalArgumentException("This callback has already been registered");
- } else {
- mAudioProfilesChangedCallbackExecutorMap.put(callback, executor);
+ mServiceLock.readLock().lock();
+ try {
+ int status = mService.isDualModeAudioEnabled(mAttributionSource);
+ if (status != BluetoothStatusCodes.SUCCESS) {
+ return status;
}
+ mAudioProfilesCallbackWrapper.registerCallback(mService, callback, executor);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ } finally {
+ mServiceLock.readLock().unlock();
}
return BluetoothStatusCodes.SUCCESS;
@@ -5188,32 +5181,15 @@ public final class BluetoothAdapter {
public int unregisterPreferredAudioProfilesChangedCallback(
@NonNull PreferredAudioProfilesChangedCallback callback) {
if (DBG) Log.d(TAG, "unregisterPreferredAudioProfilesChangedCallback()");
- requireNonNull(callback, "callback cannot be null");
- synchronized (mAudioProfilesChangedCallbackExecutorMap) {
- if (mAudioProfilesChangedCallbackExecutorMap.remove(callback) == null) {
- throw new IllegalArgumentException("This callback has not been registered");
- }
- }
-
- if (!mAudioProfilesChangedCallbackExecutorMap.isEmpty()) {
- return BluetoothStatusCodes.SUCCESS;
- }
-
- // If the callback map is empty, we unregister the service-to-app callback
mServiceLock.readLock().lock();
try {
- if (mService != null) {
- return mService.unregisterPreferredAudioProfilesChangedCallback(
- mPreferredAudioProfilesChangedCallback, mAttributionSource);
- }
- } catch (RemoteException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ mAudioProfilesCallbackWrapper.unregisterCallback(mService, callback);
} finally {
mServiceLock.readLock().unlock();
}
- return BluetoothStatusCodes.ERROR_UNKNOWN;
+ return BluetoothStatusCodes.SUCCESS;
}
/**
@@ -5255,27 +5231,20 @@ public final class BluetoothAdapter {
int status);
}
- @SuppressLint("AndroidFrameworkBluetoothPermission")
+ private final CallbackWrapper<BluetoothQualityReportReadyCallback, IBluetooth>
+ mQualityCallbackWrapper;
+
private final IBluetoothQualityReportReadyCallback mBluetoothQualityReportReadyCallback =
new IBluetoothQualityReportReadyCallback.Stub() {
@Override
public void onBluetoothQualityReportReady(
BluetoothDevice device,
- BluetoothQualityReport bluetoothQualityReport,
+ BluetoothQualityReport report,
int status) {
- for (Map.Entry<BluetoothQualityReportReadyCallback, Executor>
- callbackExecutorEntry :
- mBluetoothQualityReportReadyCallbackExecutorMap.entrySet()) {
- BluetoothQualityReportReadyCallback callback =
- callbackExecutorEntry.getKey();
- Executor executor = callbackExecutorEntry.getValue();
- executor.execute(
- () ->
- callback.onBluetoothQualityReportReady(
- device, bluetoothQualityReport, status));
+ mQualityCallbackWrapper.forEach(
+ (cb) -> cb.onBluetoothQualityReportReady(device, report, status));
}
- }
- };
+ };
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -5312,38 +5281,13 @@ public final class BluetoothAdapter {
@NonNull @CallbackExecutor Executor executor,
@NonNull BluetoothQualityReportReadyCallback callback) {
if (DBG) Log.d(TAG, "registerBluetoothQualityReportReadyCallback()");
- requireNonNull(executor, "executor cannot be null");
- requireNonNull(callback, "callback cannot be null");
-
- synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) {
- // If the callback map is empty, we register the service-to-app callback
- if (mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) {
- int serviceCallStatus = BluetoothStatusCodes.ERROR_UNKNOWN;
- mServiceLock.readLock().lock();
- try {
- if (mService != null) {
- serviceCallStatus =
- mService.registerBluetoothQualityReportReadyCallback(
- mBluetoothQualityReportReadyCallback, mAttributionSource);
- }
- } catch (RemoteException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } finally {
- mServiceLock.readLock().unlock();
- }
- if (serviceCallStatus != BluetoothStatusCodes.SUCCESS) {
- return serviceCallStatus;
- }
- }
- // Adds the passed in callback to our local mapping
- if (mBluetoothQualityReportReadyCallbackExecutorMap.containsKey(callback)) {
- throw new IllegalArgumentException("This callback has already been registered");
- } else {
- mBluetoothQualityReportReadyCallbackExecutorMap.put(callback, executor);
- }
+ mServiceLock.readLock().lock();
+ try {
+ mQualityCallbackWrapper.registerCallback(mService, callback, executor);
+ } finally {
+ mServiceLock.readLock().unlock();
}
-
return BluetoothStatusCodes.SUCCESS;
}
@@ -5380,32 +5324,15 @@ public final class BluetoothAdapter {
public int unregisterBluetoothQualityReportReadyCallback(
@NonNull BluetoothQualityReportReadyCallback callback) {
if (DBG) Log.d(TAG, "unregisterBluetoothQualityReportReadyCallback()");
- requireNonNull(callback, "callback cannot be null");
-
- synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) {
- if (mBluetoothQualityReportReadyCallbackExecutorMap.remove(callback) == null) {
- throw new IllegalArgumentException("This callback has not been registered");
- }
- }
-
- if (!mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) {
- return BluetoothStatusCodes.SUCCESS;
- }
- // If the callback map is empty, we unregister the service-to-app callback
mServiceLock.readLock().lock();
try {
- if (mService != null) {
- return mService.unregisterBluetoothQualityReportReadyCallback(
- mBluetoothQualityReportReadyCallback, mAttributionSource);
- }
- } catch (RemoteException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ mQualityCallbackWrapper.unregisterCallback(mService, callback);
} finally {
mServiceLock.readLock().unlock();
}
- return BluetoothStatusCodes.ERROR_UNKNOWN;
+ return BluetoothStatusCodes.SUCCESS;
}
/**
diff --git a/framework/java/android/bluetooth/BluetoothLeCallControl.java b/framework/java/android/bluetooth/BluetoothLeCallControl.java
index c3d68f444e..383b32e927 100644
--- a/framework/java/android/bluetooth/BluetoothLeCallControl.java
+++ b/framework/java/android/bluetooth/BluetoothLeCallControl.java
@@ -55,8 +55,6 @@ import java.util.concurrent.Executor;
*/
public final class BluetoothLeCallControl implements BluetoothProfile {
private static final String TAG = "BluetoothLeCallControl";
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
/** @hide */
@IntDef(
@@ -296,6 +294,7 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
@Override
public void onBearerRegistered(int ccid) {
if (mCallback != null) {
+ Log.d(TAG, "onBearerRegistered: ccid is " + ccid);
mCcid = ccid;
} else {
// registration timeout
@@ -390,9 +389,7 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
/** @hide */
public void close() {
- if (VDBG) {
- Log.d(TAG, "close()");
- }
+ Log.v(TAG, "close()");
mAdapter.closeProfileProxy(this);
}
@@ -489,13 +486,12 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
int technology,
@NonNull Executor executor,
@NonNull Callback callback) {
- if (DBG) {
- Log.d(TAG, "registerBearer");
- }
+ Log.d(TAG, "registerBearer");
if (callback == null) {
throw new IllegalArgumentException("null parameter: " + callback);
}
if (mCcid != 0) {
+ Log.e(TAG, "Ccid is already set to " + mCcid);
return false;
}
@@ -546,9 +542,7 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
*/
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
public void unregisterBearer() {
- if (DBG) {
- Log.d(TAG, "unregisterBearer");
- }
+ Log.d(TAG, "unregisterBearer");
if (mCcid == 0) {
return;
}
@@ -581,9 +575,7 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
*/
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
public void onCallAdded(@NonNull BluetoothLeCall call) {
- if (DBG) {
- Log.d(TAG, "onCallAdded: call=" + call);
- }
+ Log.d(TAG, "onCallAdded: call=" + call);
if (mCcid == 0) {
return;
}
@@ -614,9 +606,7 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
*/
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
public void onCallRemoved(@NonNull UUID callId, @TerminationReason int reason) {
- if (DBG) {
- Log.d(TAG, "callRemoved: callId=" + callId);
- }
+ Log.d(TAG, "callRemoved: callId=" + callId);
if (mCcid == 0) {
return;
}
@@ -646,9 +636,7 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
*/
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
public void onCallStateChanged(@NonNull UUID callId, @BluetoothLeCall.State int state) {
- if (DBG) {
- Log.d(TAG, "callStateChanged: callId=" + callId + " state=" + state);
- }
+ Log.d(TAG, "callStateChanged: callId=" + callId + " state=" + state);
if (mCcid == 0) {
return;
}
@@ -705,9 +693,7 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
*/
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
public void networkStateChanged(@NonNull String provider, int technology) {
- if (DBG) {
- Log.d(TAG, "networkStateChanged: provider=" + provider + ", technology=" + technology);
- }
+ Log.d(TAG, "networkStateChanged: provider=" + provider + ", technology=" + technology);
if (mCcid == 0) {
return;
}
@@ -745,9 +731,7 @@ public final class BluetoothLeCallControl implements BluetoothProfile {
*/
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
public void requestResult(int requestId, @Result int result) {
- if (DBG) {
- Log.d(TAG, "requestResult: requestId=" + requestId + " result=" + result);
- }
+ Log.d(TAG, "requestResult: requestId=" + requestId + " result=" + result);
if (mCcid == 0) {
return;
}
diff --git a/framework/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/framework/java/android/bluetooth/le/PeriodicAdvertisingManager.java
index 3f178c58c5..93e1cf8522 100644
--- a/framework/java/android/bluetooth/le/PeriodicAdvertisingManager.java
+++ b/framework/java/android/bluetooth/le/PeriodicAdvertisingManager.java
@@ -25,6 +25,7 @@ import android.bluetooth.Attributable;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.IBluetoothGatt;
+import android.bluetooth.IBluetoothScan;
import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
import android.bluetooth.annotations.RequiresBluetoothScanPermission;
import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
@@ -34,6 +35,8 @@ import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
+import com.android.bluetooth.flags.Flags;
+
import java.util.IdentityHashMap;
import java.util.Objects;
@@ -149,8 +152,6 @@ public final class PeriodicAdvertisingManager {
"timeout must be between " + TIMEOUT_MIN + " and " + TIMEOUT_MAX);
}
- IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt();
-
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
}
@@ -158,11 +159,22 @@ public final class PeriodicAdvertisingManager {
IPeriodicAdvertisingCallback wrapped = wrap(callback, handler);
mCallbackWrappers.put(callback, wrapped);
- try {
- gatt.registerSync(scanResult, skip, timeout, wrapped, mAttributionSource);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to register sync - ", e);
- return;
+ if (Flags.scanManagerRefactor()) {
+ IBluetoothScan scan = mBluetoothAdapter.getBluetoothScan();
+
+ try {
+ scan.registerSync(scanResult, skip, timeout, wrapped, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register sync - ", e);
+ }
+ } else {
+ IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt();
+
+ try {
+ gatt.registerSync(scanResult, skip, timeout, wrapped, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register sync - ", e);
+ }
}
}
@@ -181,18 +193,27 @@ public final class PeriodicAdvertisingManager {
throw new IllegalArgumentException("callback can't be null");
}
- IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt();
-
IPeriodicAdvertisingCallback wrapper = mCallbackWrappers.remove(callback);
if (wrapper == null) {
throw new IllegalArgumentException("callback was not properly registered");
}
- try {
- gatt.unregisterSync(wrapper, mAttributionSource);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to cancel sync creation - ", e);
- return;
+ if (Flags.scanManagerRefactor()) {
+ IBluetoothScan scan = mBluetoothAdapter.getBluetoothScan();
+
+ try {
+ scan.unregisterSync(wrapper, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to cancel sync creation - ", e);
+ }
+ } else {
+ IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt();
+
+ try {
+ gatt.unregisterSync(wrapper, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to cancel sync creation - ", e);
+ }
}
}
@@ -202,13 +223,22 @@ public final class PeriodicAdvertisingManager {
* @hide
*/
public void transferSync(BluetoothDevice bda, int serviceData, int syncHandle) {
- IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt();
+ if (Flags.scanManagerRefactor()) {
+ IBluetoothScan scan = mBluetoothAdapter.getBluetoothScan();
- try {
- gatt.transferSync(bda, serviceData, syncHandle, mAttributionSource);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to register sync - ", e);
- return;
+ try {
+ scan.transferSync(bda, serviceData, syncHandle, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register sync - ", e);
+ }
+ } else {
+ IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt();
+
+ try {
+ gatt.transferSync(bda, serviceData, syncHandle, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register sync - ", e);
+ }
}
}
@@ -239,19 +269,32 @@ public final class PeriodicAdvertisingManager {
if (callback == null) {
throw new IllegalArgumentException("callback can't be null");
}
- IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt();
+
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
}
+
IPeriodicAdvertisingCallback wrapper = wrap(callback, handler);
if (wrapper == null) {
throw new IllegalArgumentException("callback was not properly registered");
}
- try {
- gatt.transferSetInfo(bda, serviceData, advHandle, wrapper, mAttributionSource);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to register sync - ", e);
- return;
+
+ if (Flags.scanManagerRefactor()) {
+ IBluetoothScan scan = mBluetoothAdapter.getBluetoothScan();
+
+ try {
+ scan.transferSetInfo(bda, serviceData, advHandle, wrapper, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register sync - ", e);
+ }
+ } else {
+ IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt();
+
+ try {
+ gatt.transferSetInfo(bda, serviceData, advHandle, wrapper, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register sync - ", e);
+ }
}
}
diff --git a/framework/tests/bumble/src/android/bluetooth/GattClientTest.java b/framework/tests/bumble/src/android/bluetooth/GattClientTest.java
index b30fdb7c2b..ba6ccf17cf 100644
--- a/framework/tests/bumble/src/android/bluetooth/GattClientTest.java
+++ b/framework/tests/bumble/src/android/bluetooth/GattClientTest.java
@@ -368,11 +368,16 @@ public class GattClientTest {
BluetoothGatt gatt = device.connectGatt(mContext, false, gattCallback);
BluetoothGatt gatt2 = device.connectGatt(mContext, false, gattCallback2);
- gatt.disconnect();
- gatt.close();
+ try {
+ gatt.disconnect();
+ gatt.close();
- verify(gattCallback2, timeout(1000))
- .onConnectionStateChange(eq(gatt2), eq(GATT_SUCCESS), eq(STATE_CONNECTED));
+ verify(gattCallback2, timeout(1000))
+ .onConnectionStateChange(eq(gatt2), eq(GATT_SUCCESS), eq(STATE_CONNECTED));
+ } finally {
+ gatt2.disconnect();
+ gatt2.close();
+ }
}
private void registerWritableGattService() {
diff --git a/framework/tests/bumble/src/android/bluetooth/Host.kt b/framework/tests/bumble/src/android/bluetooth/Host.kt
index 886dcbb37a..af0736df61 100644
--- a/framework/tests/bumble/src/android/bluetooth/Host.kt
+++ b/framework/tests/bumble/src/android/bluetooth/Host.kt
@@ -72,13 +72,17 @@ public class Host(context: Context) : Closeable {
runBlocking(scope.coroutineContext) {
withTimeout(TIMEOUT) {
Truth.assertThat(remoteDevice.createBond()).isTrue()
- flow
- .filter { it.getAction() == BluetoothDevice.ACTION_PAIRING_REQUEST }
- .filter { it.getBluetoothDeviceExtra() == remoteDevice }
- .first()
-
- remoteDevice.setPairingConfirmation(true)
+ val pairingRequestJob = launch {
+ Log.d(TAG, "Waiting for ACTION_PAIRING_REQUEST")
+ flow
+ .filter { it.action == BluetoothDevice.ACTION_PAIRING_REQUEST }
+ .filter { it.getBluetoothDeviceExtra() == remoteDevice }
+ .first()
+
+ remoteDevice.setPairingConfirmation(true)
+ }
+ Log.d(TAG, "Waiting for ACTION_BOND_STATE_CHANGED")
flow
.filter { it.action == BluetoothDevice.ACTION_BOND_STATE_CHANGED }
.filter { it.getBluetoothDeviceExtra() == remoteDevice }
@@ -87,6 +91,11 @@ public class Host(context: Context) : Closeable {
BluetoothDevice.BOND_BONDED
}
.first()
+
+ if (pairingRequestJob.isActive) {
+ pairingRequestJob.cancel()
+ }
+
Log.d(TAG, "createBondAndVerify: bonded")
}
}
@@ -118,6 +127,7 @@ public class Host(context: Context) : Closeable {
val broadcastReceiver: BroadcastReceiver =
object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
+ Log.d(TAG, "intentFlow: onReceive: ${intent.action}")
scope.launch { trySendBlocking(intent) }
}
}
diff --git a/framework/tests/bumble/src/android/bluetooth/SdpClientTest.java b/framework/tests/bumble/src/android/bluetooth/SdpClientTest.java
index 0a45df521e..2d400e44a3 100644
--- a/framework/tests/bumble/src/android/bluetooth/SdpClientTest.java
+++ b/framework/tests/bumble/src/android/bluetooth/SdpClientTest.java
@@ -31,6 +31,8 @@ import com.android.compatibility.common.util.AdoptShellPermissionsRule;
import com.google.common.util.concurrent.SettableFuture;
import com.google.protobuf.ByteString;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -63,16 +65,26 @@ public class SdpClientTest {
ParcelUuid[] parcelUuids =
intent.getParcelableArrayExtra(
BluetoothDevice.EXTRA_UUID, ParcelUuid.class);
- mFutureIntent.set(Arrays.asList(parcelUuids));
+ if (parcelUuids != null) {
+ mFutureIntent.set(Arrays.asList(parcelUuids));
+ }
}
}
};
- @Test
- public void remoteConnectServiceDiscoveryTest() throws Exception {
+ @Before
+ public void setup() {
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_UUID);
mContext.registerReceiver(mConnectionStateReceiver, filter);
+ }
+
+ @After
+ public void tearDown() {
+ mContext.unregisterReceiver(mConnectionStateReceiver);
+ }
+ @Test
+ public void remoteConnectServiceDiscoveryTest() throws Exception {
mFutureIntent = SettableFuture.create();
String local_addr = mAdapter.getAddress();
@@ -89,12 +101,10 @@ public class SdpClientTest {
assertThat(device.fetchUuidsWithSdp()).isTrue();
assertThat(mFutureIntent.get())
- .containsExactly(
+ .containsAtLeast(
BluetoothUuid.HFP,
BluetoothUuid.A2DP_SOURCE,
BluetoothUuid.A2DP_SINK,
BluetoothUuid.AVRCP);
-
- mContext.unregisterReceiver(mConnectionStateReceiver);
}
}
diff --git a/framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java b/framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java
index f6bad4ef21..2a2a20ef18 100644
--- a/framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java
+++ b/framework/tests/bumble/src/android/bluetooth/hid/HidHostTest.java
@@ -54,6 +54,7 @@ import java.util.concurrent.TimeUnit;
/** Test cases for {@link Hid Host}. */
@RunWith(AndroidJUnit4.class)
+@Ignore("b/355328584")
public class HidHostTest {
private static final String TAG = "HidHostTest";
private SettableFuture<Integer> mFutureConnectionIntent,
diff --git a/framework/tests/util/src/BlockingBluetoothAdapter.kt b/framework/tests/util/src/BlockingBluetoothAdapter.kt
index 424beb79aa..49b08c8c43 100644
--- a/framework/tests/util/src/BlockingBluetoothAdapter.kt
+++ b/framework/tests/util/src/BlockingBluetoothAdapter.kt
@@ -79,7 +79,7 @@ object BlockingBluetoothAdapter {
if (adapter.isBleScanAlwaysAvailable()) {
break
}
- Log.d(TAG, "Ble scan not yet available… Sleeping 20 ms $i/5")
+ Log.d(TAG, "Ble scan not yet available... Sleeping 20 ms $i/5")
Thread.sleep(20)
}
if (!adapter.isBleScanAlwaysAvailable()) {
diff --git a/pandora/server/bumble_experimental/hid.py b/pandora/server/bumble_experimental/hid.py
index d68ca1eb3c..6da25ec6e1 100644
--- a/pandora/server/bumble_experimental/hid.py
+++ b/pandora/server/bumble_experimental/hid.py
@@ -355,7 +355,7 @@ def on_hid_control_point_write(_connection, value):
# -----------------------------------------------------------------------------
def sdp_records():
- service_record_handle = 0x00010002
+ service_record_handle = 0x00010006
return {
service_record_handle: [
ServiceAttribute(
diff --git a/pandora/server/bumble_experimental/rfcomm.py b/pandora/server/bumble_experimental/rfcomm.py
index 0680b4a688..bdc0ad5966 100644
--- a/pandora/server/bumble_experimental/rfcomm.py
+++ b/pandora/server/bumble_experimental/rfcomm.py
@@ -42,7 +42,7 @@ from pandora_experimental.rfcomm_pb2 import (
TxResponse,
)
-FIRST_SERVICE_RECORD_HANDLE = 0x00010000
+FIRST_SERVICE_RECORD_HANDLE = 0x00010010
class RFCOMMService(RFCOMMServicer):
diff --git a/service/src/LogTest.kt b/service/src/LogTest.kt
index c1a48642a4..3f59d16e10 100644
--- a/service/src/LogTest.kt
+++ b/service/src/LogTest.kt
@@ -57,7 +57,7 @@ class LogTest {
@Test
fun log_errorThrowable() {
- Log.e(TAG, "Logging error… ", RuntimeException("With a Throwable"))
+ Log.e(TAG, "Logging error... ", RuntimeException("With a Throwable"))
}
@Test
diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
index 4e4aaa9cc0..42abcb5706 100644
--- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
@@ -501,14 +501,14 @@ class BluetoothManagerService {
if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
if (newName != null) {
- Log.d(TAG, "Bluetooth Adapter name changed to " + newName);
+ Log.d(TAG, "Local name changed to: " + newName);
storeNameAndAddress(newName, null);
}
} else if (BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED.equals(action)) {
String newAddress =
intent.getStringExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS);
if (newAddress != null) {
- Log.d(TAG, "Local address changed to …" + logAddress(newAddress));
+ Log.d(TAG, "Local address changed to: " + logAddress(newAddress));
storeNameAndAddress(null, newAddress);
} else {
Log.e(TAG, "No Bluetooth Adapter address parameter found");
@@ -1207,13 +1207,6 @@ class BluetoothManagerService {
Log.e(TAG, "Unable to unregister BluetoothCallback", e);
}
- if (!Flags.explicitKillFromSystemServer()) {
- mAdapter = null;
- mContext.unbindService(mConnection);
- mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
- return;
- }
-
CompletableFuture<Void> binderDead = new CompletableFuture<>();
try {
mAdapter.getAdapterBinder()
diff --git a/system/TEST_MAPPING b/system/TEST_MAPPING
new file mode 100644
index 0000000000..8b04c16b05
--- /dev/null
+++ b/system/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "bluetooth_test_gd_unit"
+ }
+ ]
+}
diff --git a/system/audio_hal_interface/aidl/client_interface_aidl.cc b/system/audio_hal_interface/aidl/client_interface_aidl.cc
index 3db108d206..1bb98b77c8 100644
--- a/system/audio_hal_interface/aidl/client_interface_aidl.cc
+++ b/system/audio_hal_interface/aidl/client_interface_aidl.cc
@@ -620,7 +620,7 @@ void BluetoothAudioClientInterface::SetCodecPriority(CodecId codec_id, int32_t p
log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
auto aidl_retval = provider_->setCodecPriority(codec_id, priority);
if (!aidl_retval.isOk()) {
- log::fatal("BluetoothAudioHal::setCodecPriority failure: {}", aidl_retval.getDescription());
+ log::error("BluetoothAudioHal::setCodecPriority failure: {}", aidl_retval.getDescription());
}
}
@@ -641,14 +641,15 @@ BluetoothAudioClientInterface::GetLeAudioAseConfiguration(
requirements, &configurations);
if (!aidl_retval.isOk()) {
- log::fatal("BluetoothAudioHal::getLeAudioAseConfiguration failure: {}",
+ log::error("BluetoothAudioHal::getLeAudioAseConfiguration failure: {}",
aidl_retval.getDescription());
+ } else {
+ log::info(
+ "BluetoothAudioHal::getLeAudioAseConfiguration returned {} "
+ "configurations.",
+ configurations.size());
}
- log::info(
- "BluetoothAudioHal::getLeAudioAseConfiguration returned {} "
- "configurations.",
- configurations.size());
return configurations;
}
@@ -661,7 +662,7 @@ BluetoothAudioClientInterface::getLeAudioAseQosConfiguration(
auto aidl_retval = provider_->getLeAudioAseQosConfiguration(qosRequirement, &qos_configuration);
if (!aidl_retval.isOk()) {
- log::fatal("BluetoothAudioHal::getLeAudioAseQosConfiguration failure: {}",
+ log::error("BluetoothAudioHal::getLeAudioAseQosConfiguration failure: {}",
aidl_retval.getDescription());
}
return qos_configuration;
@@ -675,7 +676,7 @@ void BluetoothAudioClientInterface::onSinkAseMetadataChanged(
auto aidl_retval = provider_->onSinkAseMetadataChanged(state, cigId, cisId, metadata);
if (!aidl_retval.isOk()) {
- log::fatal("BluetoothAudioHal::onSinkAseMetadataChanged failure: {}",
+ log::error("BluetoothAudioHal::onSinkAseMetadataChanged failure: {}",
aidl_retval.getDescription());
}
}
@@ -688,7 +689,7 @@ void BluetoothAudioClientInterface::onSourceAseMetadataChanged(
auto aidl_retval = provider_->onSourceAseMetadataChanged(state, cigId, cisId, metadata);
if (!aidl_retval.isOk()) {
- log::fatal("BluetoothAudioHal::onSinkAseMetadataChanged failure: {}",
+ log::error("BluetoothAudioHal::onSourceAseMetadataChanged failure: {}",
aidl_retval.getDescription());
}
}
@@ -706,7 +707,7 @@ BluetoothAudioClientInterface::getLeAudioBroadcastConfiguration(
requirement, &setting);
if (!aidl_retval.isOk()) {
- log::fatal("BluetoothAudioHal::onSinkAseMetadataChanged failure: {}",
+ log::error("BluetoothAudioHal::getLeAudioBroadcastConfiguration failure: {}",
aidl_retval.getDescription());
}
diff --git a/system/bta/ag/bta_ag_sco.cc b/system/bta/ag/bta_ag_sco.cc
index 6e33195a77..5804162a24 100644
--- a/system/bta/ag/bta_ag_sco.cc
+++ b/system/bta/ag/bta_ag_sco.cc
@@ -640,6 +640,7 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) {
bta_ag_cb.sco.p_curr_scb = p_scb;
uint8_t* p_rem_feat = get_btm_client_interface().peer.BTM_ReadRemoteFeatures(p_scb->peer_addr);
bool sdp_wbs_support = p_scb->peer_sdp_features & BTA_AG_FEAT_WBS_SUPPORT;
+ bool sdp_swb_support = p_scb->peer_sdp_features & BTA_AG_FEAT_SWB_SUPPORT;
if (p_rem_feat == nullptr) {
log::warn("Skip codec negotiation, failed to read remote features");
@@ -648,7 +649,7 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) {
}
// Workaround for misbehaving HFs, which indicate which one is not support on
- // Transparent Synchronous Data in Remote Supported Features, WBS in SDP and
+ // Transparent Synchronous Data in Remote Supported Features, WBS and SWB in SDP
// and Codec Negotiation in BRSF. Fluoride will assume CVSD codec by default.
// In Sony XAV AX100 car kit and Sony MW600 Headset case, which indicate
// Transparent Synchronous Data and WBS support, but no codec negotiation
@@ -656,7 +657,10 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) {
// In Skullcandy JIB case, which indicate WBS and codec negotiation support,
// but no Transparent Synchronous Data support, using mSBC codec can result
// SCO setup fail by Firmware reject.
- if (!HCI_LMP_TRANSPNT_SUPPORTED(p_rem_feat) || !sdp_wbs_support ||
+ if (!HCI_LMP_TRANSPNT_SUPPORTED(p_rem_feat) ||
+ !(sdp_wbs_support ||
+ (com::android::bluetooth::flags::choose_wrong_hfp_codec_in_specific_config() &&
+ sdp_swb_support)) ||
!(p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
log::info("Assume CVSD by default due to mask mismatch");
p_scb->sco_codec = BTM_SCO_CODEC_CVSD;
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index 0dfe3cb08e..56ecb8fb71 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -89,7 +89,7 @@ static void bta_dm_adjust_roles(bool delay_role_switch);
tBTM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
static void bta_dm_ctrl_features_rd_cmpl_cback(tHCI_STATUS result);
-static const char kPropertySniffOffloadEnabled[] = "bluetooth.sniff_offload.enabled";
+static const char kPropertySniffOffloadEnabled[] = "persist.bluetooth.sniff_offload.enabled";
#ifndef BTA_DM_BLE_ADV_CHNL_MAP
#define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37 | BTM_BLE_ADV_CHNL_38 | BTM_BLE_ADV_CHNL_39)
@@ -288,8 +288,8 @@ void BTA_dm_on_hw_on() {
bta_sys_rm_register(bta_dm_rm_cback);
/* if sniff is offload, no need to handle it in the stack */
- if (com::android::bluetooth::flags::enable_sniff_offload() &&
- osi_property_get_bool(kPropertySniffOffloadEnabled, false)) {
+ if (osi_property_get_bool(kPropertySniffOffloadEnabled, false)) {
+ log::info("Sniff offloaded. Skip bta_dm_init_pm.");
} else {
/* initialize bluetooth low power manager */
bta_dm_init_pm();
@@ -322,9 +322,8 @@ void bta_dm_disable() {
}
/* if sniff is offload, no need to handle it in the stack */
- if (com::android::bluetooth::flags::enable_sniff_offload() &&
- osi_property_get_bool(kPropertySniffOffloadEnabled, false)) {
- log::info("Sniff offloading. Skip bta_dm_disable_pm.");
+ if (osi_property_get_bool(kPropertySniffOffloadEnabled, false)) {
+ log::info("Sniff offloaded. Skip bta_dm_disable_pm.");
} else {
/* Disable bluetooth low power manager */
bta_dm_disable_pm();
diff --git a/system/bta/gatt/bta_gattc_act.cc b/system/bta/gatt/bta_gattc_act.cc
index e2fd540d1c..42f6149e95 100644
--- a/system/bta/gatt/bta_gattc_act.cc
+++ b/system/bta/gatt/bta_gattc_act.cc
@@ -138,13 +138,28 @@ void bta_gattc_disable() {
return;
}
- for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
- if (!bta_gattc_cb.cl_rcb[i].in_use) {
- continue;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ if (!bta_gattc_cb.cl_rcb_map.empty()) {
+ bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING;
+ }
+
+ // An entry can be erased during deregister, use a copied collection
+ std::vector<tGATT_IF> gatt_ifs;
+ for (auto& [gatt_if, p_rcb] : bta_gattc_cb.cl_rcb_map) {
+ gatt_ifs.push_back(gatt_if);
}
+ for (auto& gatt_if : gatt_ifs) {
+ bta_gattc_deregister(bta_gattc_cb.cl_rcb_map[gatt_if].get());
+ }
+ } else {
+ for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
+ if (!bta_gattc_cb.cl_rcb[i].in_use) {
+ continue;
+ }
- bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING;
- bta_gattc_deregister(&bta_gattc_cb.cl_rcb[i]);
+ bta_gattc_cb.state = BTA_GATTC_STATE_DISABLING;
+ bta_gattc_deregister(&bta_gattc_cb.cl_rcb[i]);
+ }
}
/* no registered apps, indicate disable completed */
@@ -177,29 +192,54 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, BtaAppR
log::debug("GATTC module not enabled, enabling it");
bta_gattc_enable();
}
- /* todo need to check duplicate uuid */
- for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i++) {
- if (!bta_gattc_cb.cl_rcb[i].in_use) {
- bta_gattc_cb.cl_rcb[i].client_if =
- GATT_Register(app_uuid, "GattClient", &bta_gattc_cl_cback, eatt_support);
- if (bta_gattc_cb.cl_rcb[i].client_if == 0) {
- log::error("Register with GATT stack failed with index {}, trying next index", i);
- status = GATT_ERROR;
- } else {
- bta_gattc_cb.cl_rcb[i].in_use = true;
- bta_gattc_cb.cl_rcb[i].p_cback = p_cback;
- bta_gattc_cb.cl_rcb[i].app_uuid = app_uuid;
-
- /* BTA use the same client interface as BTE GATT statck */
- client_if = bta_gattc_cb.cl_rcb[i].client_if;
-
- log::debug("Registered GATT client interface {} with uuid={}, starting it on main thread",
- client_if, app_uuid.ToString());
-
- do_in_main_thread(base::BindOnce(&bta_gattc_start_if, client_if));
- status = GATT_SUCCESS;
- break;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ tGATT_IF client_if = GATT_Register(app_uuid, "GattClient", &bta_gattc_cl_cback, eatt_support);
+ if (client_if == 0) {
+ log::error("Register with GATT stack failed");
+ status = GATT_ERROR;
+ } else {
+ auto p_rcb = std::make_unique<tBTA_GATTC_RCB>();
+ p_rcb->in_use = true;
+ p_rcb->p_cback = p_cback;
+ p_rcb->app_uuid = app_uuid;
+ p_rcb->client_if = client_if;
+ bta_gattc_cb.cl_rcb_map.emplace(client_if, std::move(p_rcb));
+
+ log::debug(
+ "Registered GATT client interface {} with uuid={}, starting it on "
+ "main thread",
+ client_if, app_uuid.ToString());
+
+ do_in_main_thread(base::BindOnce(&bta_gattc_start_if, client_if));
+ status = GATT_SUCCESS;
+ }
+ } else {
+ for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i++) {
+ if (!bta_gattc_cb.cl_rcb[i].in_use) {
+ bta_gattc_cb.cl_rcb[i].client_if =
+ GATT_Register(app_uuid, "GattClient", &bta_gattc_cl_cback, eatt_support);
+ if (bta_gattc_cb.cl_rcb[i].client_if == 0) {
+ log::error("Register with GATT stack failed with index {}, trying next index", i);
+ status = GATT_ERROR;
+ } else {
+ bta_gattc_cb.cl_rcb[i].in_use = true;
+ bta_gattc_cb.cl_rcb[i].p_cback = p_cback;
+ bta_gattc_cb.cl_rcb[i].app_uuid = app_uuid;
+
+ /* BTA use the same client interface as BTE GATT statck */
+ client_if = bta_gattc_cb.cl_rcb[i].client_if;
+
+ log::debug(
+ "Registered GATT client interface {} with uuid={}, starting it on "
+ "main thread",
+ client_if, app_uuid.ToString());
+
+ do_in_main_thread(base::BindOnce(&bta_gattc_start_if, client_if));
+
+ status = GATT_SUCCESS;
+ break;
+ }
}
}
}
@@ -224,11 +264,26 @@ void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) {
continue;
}
- if (bta_gattc_cb.bg_track[i].cif_mask & ((tBTA_GATTC_CIF_MASK)1 << (p_clreg->client_if - 1))) {
- bta_gattc_mark_bg_conn(p_clreg->client_if, bta_gattc_cb.bg_track[i].remote_bda, false);
- if (!GATT_CancelConnect(p_clreg->client_if, bta_gattc_cb.bg_track[i].remote_bda, false)) {
- log::warn("Unable to cancel GATT connection client_if:{} peer:{} is_direct:{}",
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ if (bta_gattc_cb.bg_track[i].cif_set.contains(p_clreg->client_if)) {
+ bta_gattc_mark_bg_conn(p_clreg->client_if, bta_gattc_cb.bg_track[i].remote_bda, false);
+ if (!GATT_CancelConnect(p_clreg->client_if, bta_gattc_cb.bg_track[i].remote_bda, false)) {
+ log::warn(
+ "Unable to cancel GATT connection client_if:{} peer:{} "
+ "is_direct:{}",
p_clreg->client_if, bta_gattc_cb.bg_track[i].remote_bda, false);
+ }
+ }
+ } else {
+ if (bta_gattc_cb.bg_track[i].cif_mask &
+ ((tBTA_GATTC_CIF_MASK)1 << (p_clreg->client_if - 1))) {
+ bta_gattc_mark_bg_conn(p_clreg->client_if, bta_gattc_cb.bg_track[i].remote_bda, false);
+ if (!GATT_CancelConnect(p_clreg->client_if, bta_gattc_cb.bg_track[i].remote_bda, false)) {
+ log::warn(
+ "Unable to cancel GATT connection client_if:{} peer:{} "
+ "is_direct:{}",
+ p_clreg->client_if, bta_gattc_cb.bg_track[i].remote_bda, false);
+ }
}
}
}
@@ -239,17 +294,35 @@ void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) {
}
/* close all CLCB related to this app */
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- if (!bta_gattc_cb.clcb[i].in_use || (bta_gattc_cb.clcb[i].p_rcb != p_clreg)) {
- continue;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& p_clcb : bta_gattc_cb.clcb_set) {
+ if (p_clcb->p_rcb != p_clreg) {
+ continue;
+ }
+ p_clreg->dereg_pending = true;
+
+ tBTA_GATTC_DATA gattc_data = {
+ .hdr =
+ {
+ .event = BTA_GATTC_API_CLOSE_EVT,
+ .layer_specific = p_clcb->bta_conn_id,
+ },
+ };
+ bta_gattc_close(p_clcb.get(), &gattc_data);
}
+ } else {
+ for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
+ if (!bta_gattc_cb.clcb[i].in_use || (bta_gattc_cb.clcb[i].p_rcb != p_clreg)) {
+ continue;
+ }
- p_clreg->dereg_pending = true;
+ p_clreg->dereg_pending = true;
- BT_HDR_RIGID buf;
- buf.event = BTA_GATTC_API_CLOSE_EVT;
- buf.layer_specific = bta_gattc_cb.clcb[i].bta_conn_id;
- bta_gattc_close(&bta_gattc_cb.clcb[i], (tBTA_GATTC_DATA*)&buf);
+ BT_HDR_RIGID buf;
+ buf.event = BTA_GATTC_API_CLOSE_EVT;
+ buf.layer_specific = bta_gattc_cb.clcb[i].bta_conn_id;
+ bta_gattc_close(&bta_gattc_cb.clcb[i], (tBTA_GATTC_DATA*)&buf);
+ }
}
}
@@ -671,10 +744,20 @@ void bta_gattc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
/** when a SRCB finished discovery, tell all related clcb */
void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status) {
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
- bta_gattc_cb.clcb[i].status = status;
- bta_gattc_sm_execute(&bta_gattc_cb.clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& p_clcb : bta_gattc_cb.clcb_set) {
+ if (p_clcb->p_srcb != p_srcb) {
+ continue;
+ }
+ p_clcb->status = status;
+ bta_gattc_sm_execute(p_clcb.get(), BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
+ }
+ } else {
+ for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
+ if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
+ bta_gattc_cb.clcb[i].status = status;
+ bta_gattc_sm_execute(&bta_gattc_cb.clcb[i], BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
+ }
}
}
}
@@ -703,11 +786,22 @@ void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data
/** when a SRCB start discovery, tell all related clcb and set the state */
static void bta_gattc_set_discover_st(tBTA_GATTC_SERV* p_srcb) {
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
- bta_gattc_cb.clcb[i].status = GATT_SUCCESS;
- bta_gattc_cb.clcb[i].state = BTA_GATTC_DISCOVER_ST;
- bta_gattc_cb.clcb[i].request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& p_clcb : bta_gattc_cb.clcb_set) {
+ if (p_clcb->p_srcb != p_srcb) {
+ continue;
+ }
+ p_clcb->status = GATT_SUCCESS;
+ p_clcb->state = BTA_GATTC_DISCOVER_ST;
+ p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;
+ }
+ } else {
+ for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
+ if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
+ bta_gattc_cb.clcb[i].status = GATT_SUCCESS;
+ bta_gattc_cb.clcb[i].state = BTA_GATTC_DISCOVER_ST;
+ bta_gattc_cb.clcb[i].request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;
+ }
}
}
}
@@ -1329,7 +1423,13 @@ static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB* p_clreg) {
memset(&cb_data, 0, sizeof(tBTA_GATTC));
GATT_Deregister(p_clreg->client_if);
- memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ if (bta_gattc_cb.cl_rcb_map.erase(p_clreg->client_if) == 0) {
+ log::warn("deregistered unknown rcb client_if={}", p_clreg->client_if);
+ }
+ } else {
+ memset(p_clreg, 0, sizeof(tBTA_GATTC_RCB));
+ }
cb_data.reg_oper.client_if = client_if;
cb_data.reg_oper.status = GATT_SUCCESS;
@@ -1391,10 +1491,19 @@ void bta_gattc_process_api_refresh(const RawAddress& remote_bda) {
if (p_srvc_cb->connected && p_srvc_cb->num_clcb != 0) {
bool found = false;
tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
- if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
- found = true;
- break;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& p_clcb_i : bta_gattc_cb.clcb_set) {
+ if (p_clcb_i->p_srcb == p_srvc_cb) {
+ found = true;
+ break;
+ }
+ }
+ } else {
+ for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
+ if (p_clcb->in_use && p_clcb->p_srcb == p_srvc_cb) {
+ found = true;
+ break;
+ }
}
}
if (found) {
@@ -1454,11 +1563,20 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_c
/* not an opened connection; or connection busy */
/* search for first available clcb and start discovery */
if (p_clcb == NULL || (p_clcb && p_clcb->p_q_cmd != NULL)) {
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- if (bta_gattc_cb.clcb[i].in_use && bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
- bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
- p_clcb = &bta_gattc_cb.clcb[i];
- break;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& p_clcb_i : bta_gattc_cb.clcb_set) {
+ if (p_clcb_i->p_srcb == p_srcb && p_clcb_i->p_q_cmd == NULL) {
+ p_clcb = p_clcb_i.get();
+ break;
+ }
+ }
+ } else {
+ for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
+ if (bta_gattc_cb.clcb[i].in_use && bta_gattc_cb.clcb[i].p_srcb == p_srcb &&
+ bta_gattc_cb.clcb[i].p_q_cmd == NULL) {
+ p_clcb = &bta_gattc_cb.clcb[i];
+ break;
+ }
}
}
}
diff --git a/system/bta/gatt/bta_gattc_int.h b/system/bta/gatt/bta_gattc_int.h
index bf5e4cb56d..d213e68814 100644
--- a/system/bta/gatt/bta_gattc_int.h
+++ b/system/bta/gatt/bta_gattc_int.h
@@ -28,6 +28,7 @@
#include <cstdint>
#include <deque>
+#include <unordered_set>
#include "bta/gatt/database.h"
#include "bta/gatt/database_builder.h"
@@ -322,7 +323,7 @@ typedef struct {
bool in_use;
RawAddress remote_bda;
tBTA_GATTC_CIF_MASK cif_mask;
-
+ std::unordered_set<tGATT_IF> cif_set;
} tBTA_GATTC_BG_TCK;
typedef struct {
@@ -343,8 +344,10 @@ typedef struct {
tBTA_GATTC_CONN conn_track[GATT_MAX_PHY_CHANNEL];
tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX];
tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX];
+ std::unordered_map<tGATT_IF, std::unique_ptr<tBTA_GATTC_RCB>> cl_rcb_map;
tBTA_GATTC_CLCB clcb[BTA_GATTC_CLCB_MAX];
+ std::unordered_set<std::unique_ptr<tBTA_GATTC_CLCB>> clcb_set;
tBTA_GATTC_SERV known_server[BTA_GATTC_KNOWN_SR_MAX];
} tBTA_GATTC_CB;
diff --git a/system/bta/gatt/bta_gattc_utils.cc b/system/bta/gatt/bta_gattc_utils.cc
index 005ef08204..a44e1da9e3 100644
--- a/system/bta/gatt/bta_gattc_utils.cc
+++ b/system/bta/gatt/bta_gattc_utils.cc
@@ -25,6 +25,7 @@
#define LOG_TAG "bt_bta_gattc"
#include <bluetooth/log.h>
+#include <com_android_bluetooth_flags.h>
#include <cstdint>
@@ -57,15 +58,24 @@ static uint8_t ble_acceptlist_size() {
*
******************************************************************************/
tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) {
- uint8_t i = 0;
- tBTA_GATTC_RCB* p_clrcb = &bta_gattc_cb.cl_rcb[0];
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ auto it = bta_gattc_cb.cl_rcb_map.find(client_if);
+ if (it == bta_gattc_cb.cl_rcb_map.end()) {
+ return NULL;
+ } else {
+ return it->second.get();
+ }
+ } else {
+ uint8_t i = 0;
+ tBTA_GATTC_RCB* p_clrcb = &bta_gattc_cb.cl_rcb[0];
- for (i = 0; i < BTA_GATTC_CL_MAX; i++, p_clrcb++) {
- if (p_clrcb->in_use && p_clrcb->client_if == client_if) {
- return p_clrcb;
+ for (i = 0; i < BTA_GATTC_CL_MAX; i++, p_clrcb++) {
+ if (p_clrcb->in_use && p_clrcb->client_if == client_if) {
+ return p_clrcb;
+ }
}
+ return NULL;
}
- return NULL;
}
/*******************************************************************************
*
@@ -77,14 +87,18 @@ tBTA_GATTC_RCB* bta_gattc_cl_get_regcb(uint8_t client_if) {
*
******************************************************************************/
uint8_t bta_gattc_num_reg_app(void) {
- uint8_t i = 0, j = 0;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ return (uint8_t)bta_gattc_cb.cl_rcb_map.size();
+ } else {
+ uint8_t i = 0, j = 0;
- for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
- if (bta_gattc_cb.cl_rcb[i].in_use) {
- j++;
+ for (i = 0; i < BTA_GATTC_CL_MAX; i++) {
+ if (bta_gattc_cb.cl_rcb[i].in_use) {
+ j++;
+ }
}
+ return j;
}
- return j;
}
/*******************************************************************************
*
@@ -97,12 +111,21 @@ uint8_t bta_gattc_num_reg_app(void) {
******************************************************************************/
tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if, const RawAddress& remote_bda,
tBT_TRANSPORT transport) {
- tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& p_clcb : bta_gattc_cb.clcb_set) {
+ if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if &&
+ p_clcb->transport == transport && p_clcb->bda == remote_bda) {
+ return p_clcb.get();
+ }
+ }
+ } else {
+ tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
- if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if && p_clcb->transport == transport &&
- p_clcb->bda == remote_bda) {
- return p_clcb;
+ for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
+ if (p_clcb->in_use && p_clcb->p_rcb->client_if == client_if &&
+ p_clcb->transport == transport && p_clcb->bda == remote_bda) {
+ return p_clcb;
+ }
}
}
return NULL;
@@ -117,11 +140,19 @@ tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_cif(uint8_t client_if, const RawAddress&
*
******************************************************************************/
tBTA_GATTC_CLCB* bta_gattc_find_clcb_by_conn_id(uint16_t conn_id) {
- tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& p_clcb : bta_gattc_cb.clcb_set) {
+ if (p_clcb->bta_conn_id == conn_id) {
+ return p_clcb.get();
+ }
+ }
+ } else {
+ tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[0];
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
- if (p_clcb->in_use && p_clcb->bta_conn_id == conn_id) {
- return p_clcb;
+ for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++, p_clcb++) {
+ if (p_clcb->in_use && p_clcb->bta_conn_id == conn_id) {
+ return p_clcb;
+ }
}
}
return NULL;
@@ -140,34 +171,61 @@ tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if, const RawAddress& remo
tBT_TRANSPORT transport) {
tBTA_GATTC_CLCB* p_clcb = NULL;
- for (int i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) {
- if (!bta_gattc_cb.clcb[i_clcb].in_use) {
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ auto [p_clcb_i, b] = bta_gattc_cb.clcb_set.emplace(std::make_unique<tBTA_GATTC_CLCB>());
+ p_clcb = p_clcb_i->get();
+
+ p_clcb->in_use = true;
+ p_clcb->status = GATT_SUCCESS;
+ p_clcb->transport = transport;
+ p_clcb->bda = remote_bda;
+ p_clcb->p_q_cmd = NULL;
+
+ p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
+
+ p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda);
+ if (p_clcb->p_srcb == NULL) {
+ p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
+ }
+
+ if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
+ p_clcb->p_srcb->num_clcb++;
+ p_clcb->p_rcb->num_clcb++;
+ } else {
+ /* release this clcb if clcb or srcb allocation failed */
+ bta_gattc_cb.clcb_set.erase(p_clcb_i);
+ p_clcb = NULL;
+ }
+ } else {
+ for (int i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) {
+ if (!bta_gattc_cb.clcb[i_clcb].in_use) {
#if (BTA_GATT_DEBUG == TRUE)
- log::verbose("found clcb:{} available", i_clcb);
+ log::verbose("found clcb:{} available", i_clcb);
#endif
- p_clcb = &bta_gattc_cb.clcb[i_clcb];
- p_clcb->in_use = true;
- p_clcb->status = GATT_SUCCESS;
- p_clcb->transport = transport;
- p_clcb->bda = remote_bda;
- p_clcb->p_q_cmd = NULL;
-
- p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
-
- p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda);
- if (p_clcb->p_srcb == NULL) {
- p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
- }
+ p_clcb = &bta_gattc_cb.clcb[i_clcb];
+ p_clcb->in_use = true;
+ p_clcb->status = GATT_SUCCESS;
+ p_clcb->transport = transport;
+ p_clcb->bda = remote_bda;
+ p_clcb->p_q_cmd = NULL;
+
+ p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
+
+ p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda);
+ if (p_clcb->p_srcb == NULL) {
+ p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
+ }
- if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
- p_clcb->p_srcb->num_clcb++;
- p_clcb->p_rcb->num_clcb++;
- } else {
- /* release this clcb if clcb or srcb allocation failed */
- p_clcb->in_use = false;
- p_clcb = NULL;
+ if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
+ p_clcb->p_srcb->num_clcb++;
+ p_clcb->p_rcb->num_clcb++;
+ } else {
+ /* release this clcb if clcb or srcb allocation failed */
+ p_clcb->in_use = false;
+ p_clcb = NULL;
+ }
+ break;
}
- break;
}
}
return p_clcb;
@@ -258,17 +316,26 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) {
/* Clear p_clcb. Some of the fields are already reset e.g. p_q_cmd_queue and
* p_q_cmd. */
- p_clcb->bta_conn_id = 0;
- p_clcb->bda = {};
- p_clcb->transport = BT_TRANSPORT_AUTO;
- p_clcb->p_rcb = NULL;
- p_clcb->p_srcb = NULL;
- p_clcb->request_during_discovery = 0;
- p_clcb->auto_update = 0;
- p_clcb->disc_active = 0;
- p_clcb->in_use = 0;
- p_clcb->state = BTA_GATTC_IDLE_ST;
- p_clcb->status = GATT_SUCCESS;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& p_clcb_i : bta_gattc_cb.clcb_set) {
+ if (p_clcb_i.get() == p_clcb) {
+ bta_gattc_cb.clcb_set.erase(p_clcb_i);
+ break;
+ }
+ }
+ } else {
+ p_clcb->bta_conn_id = 0;
+ p_clcb->bda = {};
+ p_clcb->transport = BT_TRANSPORT_AUTO;
+ p_clcb->p_rcb = NULL;
+ p_clcb->p_srcb = NULL;
+ p_clcb->request_during_discovery = 0;
+ p_clcb->auto_update = 0;
+ p_clcb->disc_active = 0;
+ p_clcb->in_use = 0;
+ p_clcb->state = BTA_GATTC_IDLE_ST;
+ p_clcb->status = GATT_SUCCESS;
+ }
}
/*******************************************************************************
@@ -555,20 +622,38 @@ bool bta_gattc_mark_bg_conn(tGATT_IF client_if, const RawAddress& remote_bda_ptr
for (i = 0; i < ble_acceptlist_size(); i++, p_bg_tck++) {
if (p_bg_tck->in_use &&
((p_bg_tck->remote_bda == remote_bda_ptr) || (p_bg_tck->remote_bda.IsEmpty()))) {
- p_cif_mask = &p_bg_tck->cif_mask;
-
- if (add) { /* mask on the cif bit */
- *p_cif_mask |= (1 << (client_if - 1));
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ auto& p_cif_set = p_bg_tck->cif_set;
+ if (add) { /* mask on the cif bit */
+ p_cif_set.insert(client_if);
+ } else {
+ if (client_if != 0) {
+ p_cif_set.erase(client_if);
+ } else {
+ p_cif_set.clear();
+ }
+ }
+ /* no BG connection for this device, make it available */
+ if (p_bg_tck->cif_set.empty()) {
+ p_bg_tck->in_use = false;
+ p_bg_tck->remote_bda = RawAddress::kEmpty;
+ }
} else {
- if (client_if != 0) {
- *p_cif_mask &= (~(1 << (client_if - 1)));
+ p_cif_mask = &p_bg_tck->cif_mask;
+
+ if (add) { /* mask on the cif bit */
+ *p_cif_mask |= (1 << (client_if - 1));
} else {
- *p_cif_mask = 0;
+ if (client_if != 0) {
+ *p_cif_mask &= (~(1 << (client_if - 1)));
+ } else {
+ *p_cif_mask = 0;
+ }
+ }
+ /* no BG connection for this device, make it available */
+ if (p_bg_tck->cif_mask == 0) {
+ memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
}
- }
- /* no BG connection for this device, make it available */
- if (p_bg_tck->cif_mask == 0) {
- memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
}
return true;
}
@@ -823,32 +908,55 @@ void bta_gatt_client_dump(int fd) {
stream << " -- used: " << entry_count << "\n";
entry_count = 0;
- stream << " ->cl_rcb (BTA_GATTC_CL_MAX=" << BTA_GATTC_CL_MAX << ")\n";
- for (int i = 0; i < BTA_GATTC_CL_MAX; i++) {
- tBTA_GATTC_RCB* p_cl_rcb = &bta_gattc_cb.cl_rcb[i];
- if (!p_cl_rcb->in_use) {
- continue;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ stream << " ->cl_rcb (dynamic)\n";
+ for (auto& [i, p_cl_rcb] : bta_gattc_cb.cl_rcb_map) {
+ entry_count++;
+ stream << " client_if: " << +p_cl_rcb->client_if << " app uuids: " << p_cl_rcb->app_uuid
+ << " clcb_num: " << +p_cl_rcb->num_clcb;
+ stream << "\n";
+ }
+ } else {
+ stream << " ->cl_rcb (BTA_GATTC_CL_MAX=" << BTA_GATTC_CL_MAX << ")\n";
+ for (int i = 0; i < BTA_GATTC_CL_MAX; i++) {
+ tBTA_GATTC_RCB* p_cl_rcb = &bta_gattc_cb.cl_rcb[i];
+ if (!p_cl_rcb->in_use) {
+ continue;
+ }
+ entry_count++;
+ stream << " client_if: " << +p_cl_rcb->client_if << " app uuids: " << p_cl_rcb->app_uuid
+ << " clcb_num: " << +p_cl_rcb->num_clcb;
+ stream << "\n";
}
- entry_count++;
- stream << " client_if: " << +p_cl_rcb->client_if << " app uuids: " << p_cl_rcb->app_uuid
- << " clcb_num: " << +p_cl_rcb->num_clcb;
- stream << "\n";
}
stream << " -- used: " << entry_count << "\n";
entry_count = 0;
- stream << " ->clcb (BTA_GATTC_CLCB_MAX=" << BTA_GATTC_CLCB_MAX << ")\n";
- for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
- tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[i];
- if (!p_clcb->in_use) {
- continue;
+
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ stream << " ->clcb (dynamic)\n";
+ for (auto& p_clcb : bta_gattc_cb.clcb_set) {
+ entry_count++;
+ stream << " conn_id: " << loghex(p_clcb->bta_conn_id)
+ << " address: " << ADDRESS_TO_LOGGABLE_STR(p_clcb->bda)
+ << " transport: " << bt_transport_text(p_clcb->transport)
+ << " state: " << bta_clcb_state_text(p_clcb->state);
+ stream << "\n";
+ }
+ } else {
+ stream << " ->clcb (BTA_GATTC_CLCB_MAX=" << BTA_GATTC_CLCB_MAX << ")\n";
+ for (size_t i = 0; i < BTA_GATTC_CLCB_MAX; i++) {
+ tBTA_GATTC_CLCB* p_clcb = &bta_gattc_cb.clcb[i];
+ if (!p_clcb->in_use) {
+ continue;
+ }
+ entry_count++;
+ stream << " conn_id: " << loghex(p_clcb->bta_conn_id)
+ << " address: " << ADDRESS_TO_LOGGABLE_STR(p_clcb->bda)
+ << " transport: " << bt_transport_text(p_clcb->transport)
+ << " state: " << bta_clcb_state_text(p_clcb->state);
+ stream << "\n";
}
- entry_count++;
- stream << " conn_id: " << loghex(p_clcb->bta_conn_id)
- << " address: " << ADDRESS_TO_LOGGABLE_STR(p_clcb->bda)
- << " transport: " << bt_transport_text(p_clcb->transport)
- << " state: " << bta_clcb_state_text(p_clcb->state);
- stream << "\n";
}
stream << " -- used: " << entry_count << "\n";
diff --git a/system/bta/hh/bta_hh_act.cc b/system/bta/hh/bta_hh_act.cc
index 56d4de0ce3..cb3a3fce98 100644
--- a/system/bta/hh/bta_hh_act.cc
+++ b/system/bta/hh/bta_hh_act.cc
@@ -199,22 +199,30 @@ void bta_hh_disc_cmpl(void) {
* Returns void
*
******************************************************************************/
-static void bta_hh_sdp_cback(tSDP_STATUS result, uint16_t attr_mask, tHID_DEV_SDP_INFO* sdp_rec) {
- tBTA_HH_DEV_CB* p_cb = bta_hh_cb.p_cur;
- uint8_t hdl = 0;
+static void bta_hh_sdp_cback(const RawAddress& bd_addr, tSDP_STATUS result, uint16_t attr_mask,
+ tHID_DEV_SDP_INFO* sdp_rec) {
tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
+ tAclLinkSpec link_spec = {
+ .addrt = {.type = BLE_ADDR_PUBLIC, .bda = bd_addr},
+ .transport = BT_TRANSPORT_BR_EDR,
+ };
+ tBTA_HH_DEV_CB* p_cb = bta_hh_find_cb(link_spec);
+ if (p_cb == nullptr) {
+ log::error("Unknown device {}", bd_addr);
+ return;
+ }
- /* make sure sdp succeeded and hh has not been disabled */
- if ((result == SDP_SUCCESS) && (p_cb != NULL)) {
+ if (result == SDP_SUCCESS) {
/* security is required for the connection, add attr_mask bit*/
attr_mask |= HID_SEC_REQUIRED;
- log::verbose("p_cb:{} result:0x{:02x}, attr_mask:0x{:02x}, handle:0x{:x}", fmt::ptr(p_cb),
- result, attr_mask, p_cb->hid_handle);
+ log::verbose("Device:{} result:0x{:02x}, attr_mask:0x{:02x}, handle:0x{:x}", bd_addr, result,
+ attr_mask, p_cb->hid_handle);
/* check to see type of device is supported , and should not been added
* before */
if (bta_hh_tod_spt(p_cb, sdp_rec->sub_class)) {
+ uint8_t hdl = 0;
/* if not added before */
if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) {
/* add device/update attr_mask information */
@@ -247,14 +255,12 @@ static void bta_hh_sdp_cback(tSDP_STATUS result, uint16_t attr_mask, tHID_DEV_SD
}
/* free disc_db when SDP is completed */
- osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
+ osi_free_and_reset((void**)&p_cb->p_disc_db);
/* send SDP_CMPL_EVT into state machine */
tBTA_HH_DATA bta_hh_data;
bta_hh_data.status = status;
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
-
- return;
}
/*******************************************************************************
*
@@ -265,12 +271,19 @@ static void bta_hh_sdp_cback(tSDP_STATUS result, uint16_t attr_mask, tHID_DEV_SD
* Returns void
*
******************************************************************************/
-static void bta_hh_di_sdp_cback(const RawAddress& /* bd_addr */, tSDP_RESULT result) {
- tBTA_HH_DEV_CB* p_cb = bta_hh_cb.p_cur;
+static void bta_hh_di_sdp_cback(const RawAddress& bd_addr, tSDP_RESULT result) {
tBTA_HH_STATUS status = BTA_HH_ERR_SDP;
- tSDP_DI_GET_RECORD di_rec;
- tHID_STATUS ret;
- log::verbose("p_cb:{} result:0x{:02x}", fmt::ptr(p_cb), result);
+ tAclLinkSpec link_spec = {
+ .addrt = {.type = BLE_ADDR_PUBLIC, .bda = bd_addr},
+ .transport = BT_TRANSPORT_BR_EDR,
+ };
+ tBTA_HH_DEV_CB* p_cb = bta_hh_find_cb(link_spec);
+ if (p_cb == nullptr) {
+ log::error("Unknown device {}", bd_addr);
+ return;
+ }
+
+ log::verbose("device:{} result:0x{:02x}", bd_addr, result);
/* if DI record does not exist on remote device, vendor_id in
* tBTA_HH_DEV_DSCP_INFO will be set to 0xffff and we will allow the
@@ -278,38 +291,38 @@ static void bta_hh_di_sdp_cback(const RawAddress& /* bd_addr */, tSDP_RESULT res
* HID devices do not set this. So for IOP purposes, we allow the connection
* to go through and update the DI record to invalid DI entry.
*/
- if (((result == SDP_SUCCESS) || (result == SDP_NO_RECS_MATCH)) && (p_cb != NULL)) {
+ if (result == SDP_SUCCESS || result == SDP_NO_RECS_MATCH) {
if (result == SDP_SUCCESS &&
- get_legacy_stack_sdp_api()->device_id.SDP_GetNumDiRecords(bta_hh_cb.p_disc_db) != 0) {
+ get_legacy_stack_sdp_api()->device_id.SDP_GetNumDiRecords(p_cb->p_disc_db) != 0) {
+ tSDP_DI_GET_RECORD di_rec;
+
/* always update information with primary DI record */
- if (get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(1, &di_rec, bta_hh_cb.p_disc_db) ==
+ if (get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(1, &di_rec, p_cb->p_disc_db) ==
SDP_SUCCESS) {
bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product, di_rec.rec.version, 0,
0);
}
- } else /* no DI record available */
- {
+ } else /* no DI record available */ {
bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0, 0, 0);
}
- ret = HID_HostGetSDPRecord(p_cb->link_spec.addrt.bda, bta_hh_cb.p_disc_db,
- p_bta_hh_cfg->sdp_db_size, bta_hh_sdp_cback);
+ tHID_STATUS ret = HID_HostGetSDPRecord(p_cb->link_spec.addrt.bda, p_cb->p_disc_db,
+ p_bta_hh_cfg->sdp_db_size, bta_hh_sdp_cback);
if (ret == HID_SUCCESS) {
status = BTA_HH_OK;
} else {
- log::verbose("failure Status 0x{:2x}", ret);
+ log::warn("failure Status 0x{:2x}", ret);
}
}
if (status != BTA_HH_OK) {
- osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
+ osi_free_and_reset((void**)&p_cb->p_disc_db);
/* send SDP_CMPL_EVT into state machine */
tBTA_HH_DATA bta_hh_data;
bta_hh_data.status = status;
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
}
- return;
}
/*******************************************************************************
@@ -324,27 +337,8 @@ static void bta_hh_di_sdp_cback(const RawAddress& /* bd_addr */, tSDP_RESULT res
* Returns void
*
******************************************************************************/
-static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
- if (!bta_hh_cb.p_disc_db) {
- bta_hh_cb.p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(p_bta_hh_cfg->sdp_db_size);
-
- /* Do DI discovery first */
- if (get_legacy_stack_sdp_api()->device_id.SDP_DiDiscover(
- p_data->api_conn.link_spec.addrt.bda, bta_hh_cb.p_disc_db,
- p_bta_hh_cfg->sdp_db_size, bta_hh_di_sdp_cback) == SDP_SUCCESS) {
- /* SDP search started successfully
- * Connection will be triggered at the end of successful SDP search
- */
- } else {
- log::error("SDP_DiDiscover failed");
-
- osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
-
- tBTA_HH_DATA bta_hh_data;
- bta_hh_data.status = BTA_HH_ERR_SDP;
- bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
- }
- } else if (bta_hh_cb.p_disc_db) {
+static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb) {
+ if (p_cb->p_disc_db != nullptr) {
/* Incoming/outgoing collision case. DUT initiated HID connection at the
* same time as the remote connected HID control channel.
* When flow reaches here due to remote initiated connection, DUT may be
@@ -352,6 +346,25 @@ static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
* or failure will handle this case.
*/
log::warn("Ignoring as SDP already in progress");
+ return;
+ }
+
+ p_cb->p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(p_bta_hh_cfg->sdp_db_size);
+
+ /* Do DI discovery first */
+ if (get_legacy_stack_sdp_api()->device_id.SDP_DiDiscover(
+ p_cb->link_spec.addrt.bda, p_cb->p_disc_db, p_bta_hh_cfg->sdp_db_size,
+ bta_hh_di_sdp_cback) == SDP_SUCCESS) {
+ // SDP search started successfully. Connection will be triggered at the end of successful SDP
+ // search
+ } else {
+ log::error("SDP_DiDiscover failed");
+
+ osi_free_and_reset((void**)&p_cb->p_disc_db);
+
+ tBTA_HH_DATA bta_hh_data;
+ bta_hh_data.status = BTA_HH_ERR_SDP;
+ bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
}
}
@@ -447,12 +460,10 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
* Returns void
*
******************************************************************************/
-static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
- bta_hh_cb.p_cur = p_cb;
-
+static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb) {
/* If previously virtually cabled device */
if (p_cb->app_id) {
- tBTA_HH_DATA bta_hh_data;
+ tBTA_HH_DATA bta_hh_data = {};
bta_hh_data.status = BTA_HH_OK;
log::verbose("skip SDP for known devices");
@@ -461,7 +472,7 @@ static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data)
uint8_t hdl;
if (HID_HostAddDev(p_cb->link_spec.addrt.bda, p_cb->attr_mask, &hdl) == HID_SUCCESS) {
/* update device CB with newly register device handle */
- bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL, p_cb->sub_class,
+ bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, nullptr, p_cb->sub_class,
p_cb->dscp_info.ssr_max_latency, p_cb->dscp_info.ssr_min_tout,
p_cb->app_id);
/* update cb_index[] map */
@@ -473,7 +484,7 @@ static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data)
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data);
} else { /* First time connection, start SDP */
- bta_hh_start_sdp(p_cb, p_data);
+ bta_hh_start_sdp(p_cb);
}
}
@@ -487,15 +498,13 @@ static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data)
*
******************************************************************************/
void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
- p_cb->link_spec = p_data->api_conn.link_spec;
p_cb->mode = p_data->api_conn.mode;
- bta_hh_cb.p_cur = p_cb;
// Initiate HID host connection
if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
- bta_hh_le_open_conn(p_cb, p_data->api_conn.link_spec);
+ bta_hh_le_open_conn(p_cb);
} else {
- bta_hh_bredr_conn(p_cb, p_data);
+ bta_hh_bredr_conn(p_cb);
}
}
@@ -601,8 +610,6 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
*
******************************************************************************/
void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
- tBTA_HH_API_CONN conn_data;
-
uint8_t dev_handle = p_data ? (uint8_t)p_data->hid_cback.hdr.layer_specific : p_cb->hid_handle;
log::verbose("Device[{}] connected", dev_handle);
@@ -619,13 +626,8 @@ void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) {
/* store the handle here in case sdp fails - need to disconnect */
p_cb->incoming_hid_handle = dev_handle;
- memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN));
- conn_data.link_spec = p_cb->link_spec;
- bta_hh_cb.p_cur = p_cb;
- bta_hh_bredr_conn(p_cb, (tBTA_HH_DATA*)&conn_data);
+ bta_hh_bredr_conn(p_cb);
}
-
- return;
}
/*******************************************************************************
diff --git a/system/bta/hh/bta_hh_api.cc b/system/bta/hh/bta_hh_api.cc
index ff1ef18e7c..10ca7f2d65 100644
--- a/system/bta/hh/bta_hh_api.cc
+++ b/system/bta/hh/bta_hh_api.cc
@@ -348,3 +348,14 @@ void BTA_HhRemoveDev(uint8_t dev_handle) {
bta_sys_sendmsg(p_buf);
}
+
+/*******************************************************************************
+ *
+ * Function BTA_HhDump
+ *
+ * Description Dump BTA HH control block
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void BTA_HhDump(int fd) { bta_hh_dump(fd); }
diff --git a/system/bta/hh/bta_hh_int.h b/system/bta/hh/bta_hh_int.h
index 7a011b8f51..1929153182 100644
--- a/system/bta/hh/bta_hh_int.h
+++ b/system/bta/hh/bta_hh_int.h
@@ -223,6 +223,8 @@ typedef struct {
#define BTA_HH_LE_SCPS_NOTIFY_ENB 0x02
uint8_t scps_notify; /* scan refresh supported/notification enabled */
bool security_pending;
+
+ tSDP_DISCOVERY_DB* p_disc_db;
} tBTA_HH_DEV_CB;
/******************************************************************************
@@ -230,15 +232,12 @@ typedef struct {
******************************************************************************/
typedef struct {
tBTA_HH_DEV_CB kdev[BTA_HH_MAX_DEVICE]; /* device control block */
- tBTA_HH_DEV_CB* p_cur; /* current device control
- block idx, used in sdp */
uint8_t cb_index[BTA_HH_MAX_KNOWN]; /* maintain a CB index
map to dev handle */
uint8_t le_cb_index[BTA_HH_LE_MAX_KNOWN]; /* maintain a CB index map to LE dev
handle */
tGATT_IF gatt_if;
tBTA_HH_CBACK* p_cback; /* Application callbacks */
- tSDP_DISCOVERY_DB* p_disc_db;
uint8_t cnt_num; /* connected device number */
bool w4_disable; /* w4 disable flag */
} tBTA_HH_CB;
@@ -252,7 +251,7 @@ extern tBTA_HH_CFG* p_bta_hh_cfg;
* Function prototypes
****************************************************************************/
bool bta_hh_hdl_event(const BT_HDR_RIGID* p_msg);
-void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event, const tBTA_HH_DATA* p_data);
+void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, tBTA_HH_INT_EVT event, const tBTA_HH_DATA* p_data);
/* action functions */
void bta_hh_api_disc_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
@@ -270,8 +269,9 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
void bta_hh_open_failure(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
/* utility functions */
-uint8_t bta_hh_find_cb(const tAclLinkSpec& link_spec);
+tBTA_HH_DEV_CB* bta_hh_find_cb(const tAclLinkSpec& link_spec);
tBTA_HH_DEV_CB* bta_hh_get_cb(const tAclLinkSpec& link_spec);
+tBTA_HH_DEV_CB* bta_hh_find_cb_by_handle(uint8_t hid_handle);
bool bta_hh_tod_spt(tBTA_HH_DEV_CB* p_cb, uint8_t sub_class);
void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB* p_cb);
@@ -282,8 +282,6 @@ void bta_hh_update_di_info(tBTA_HH_DEV_CB* p_cb, uint16_t vendor_id, uint16_t pr
uint16_t version, uint8_t flag, uint8_t ctry_code);
void bta_hh_cleanup_disable(tBTA_HH_STATUS status);
-uint8_t bta_hh_dev_handle_to_cb_idx(uint8_t dev_handle);
-
/* action functions used outside state machine */
void bta_hh_api_enable(tBTA_HH_CBACK* p_cback, bool enable_hid, bool enable_hogp);
void bta_hh_api_disable(void);
@@ -295,7 +293,7 @@ tBTA_HH_STATUS bta_hh_read_ssr_param(const tAclLinkSpec& link_spec, uint16_t* p_
/* functions for LE HID */
void bta_hh_le_enable(void);
void bta_hh_le_deregister(void);
-void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const tAclLinkSpec& link_spec);
+void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb);
void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB* p_cb);
void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB* p_cb);
void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data);
@@ -322,6 +320,8 @@ void bta_hh_headtracker_parse_service(tBTA_HH_DEV_CB* p_dev_cb, const gatt::Serv
bool bta_hh_headtracker_supported(tBTA_HH_DEV_CB* p_dev_cb);
uint16_t bta_hh_get_uuid16(tBTA_HH_DEV_CB* p_dev_cb, bluetooth::Uuid uuid);
+void bta_hh_dump(int fd);
+
#if (BTA_HH_DEBUG == TRUE)
void bta_hh_trace_dev_db(void);
#endif
diff --git a/system/bta/hh/bta_hh_le.cc b/system/bta/hh/bta_hh_le.cc
index 542704edd2..04a38d65c3 100644
--- a/system/bta/hh/bta_hh_le.cc
+++ b/system/bta/hh/bta_hh_le.cc
@@ -241,19 +241,16 @@ void bta_hh_le_deregister(void) { BTA_GATTC_AppDeregister(bta_hh_cb.gatt_if); }
*
******************************************************************************/
static uint8_t bta_hh_le_get_le_dev_hdl(uint8_t cb_index) {
- uint8_t i;
- for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
+ uint8_t available_handle = BTA_HH_IDX_INVALID;
+ for (uint8_t i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
if (bta_hh_cb.le_cb_index[i] == cb_index) {
return BTA_HH_GET_LE_DEV_HDL(i);
+ } else if (available_handle == BTA_HH_IDX_INVALID &&
+ bta_hh_cb.le_cb_index[i] == BTA_HH_IDX_INVALID) {
+ available_handle = BTA_HH_GET_LE_DEV_HDL(i);
}
}
-
- for (i = 0; i < ARRAY_SIZE(bta_hh_cb.le_cb_index); i++) {
- if (bta_hh_cb.le_cb_index[i] == BTA_HH_IDX_INVALID) {
- return BTA_HH_GET_LE_DEV_HDL(i);
- }
- }
- return BTA_HH_IDX_INVALID;
+ return available_handle;
}
/*******************************************************************************
@@ -265,21 +262,17 @@ static uint8_t bta_hh_le_get_le_dev_hdl(uint8_t cb_index) {
* Parameters:
*
******************************************************************************/
-void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const tAclLinkSpec& link_spec) {
- tBTA_HH_STATUS status = BTA_HH_ERR_NO_RES;
-
- /* update cb_index[] map */
+void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb) {
p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index);
if (p_cb->hid_handle == BTA_HH_IDX_INVALID) {
+ tBTA_HH_STATUS status = BTA_HH_ERR_NO_RES;
bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA*)&status);
return;
}
- p_cb->link_spec = link_spec;
- bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
- p_cb->in_use = true;
+ bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; // Update index map
- BTA_GATTC_Open(bta_hh_cb.gatt_if, link_spec.addrt.bda, BTM_BLE_DIRECT_CONNECTION, false);
+ BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->link_spec.addrt.bda, BTM_BLE_DIRECT_CONNECTION, false);
}
/*******************************************************************************
@@ -291,15 +284,13 @@ void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const tAclLinkSpec& link_spec) {
*
******************************************************************************/
static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_conn_id(uint16_t conn_id) {
- uint8_t i;
- tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0];
-
- for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) {
+ for (uint8_t i = 0; i < BTA_HH_MAX_DEVICE; i++) {
+ tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[i];
if (p_dev_cb->in_use && p_dev_cb->conn_id == conn_id) {
return p_dev_cb;
}
}
- return NULL;
+ return nullptr;
}
/*******************************************************************************
@@ -311,16 +302,14 @@ static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_conn_id(uint16_t conn_id) {
*
******************************************************************************/
static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda(const tAclLinkSpec& link_spec) {
- uint8_t i;
- tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0];
-
- for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) {
+ for (uint8_t i = 0; i < BTA_HH_MAX_DEVICE; i++) {
+ tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[i];
if (p_dev_cb->in_use && p_dev_cb->link_spec.addrt.bda == link_spec.addrt.bda &&
p_dev_cb->link_spec.transport == BT_TRANSPORT_LE) {
return p_dev_cb;
}
}
- return NULL;
+ return nullptr;
}
/*******************************************************************************
@@ -968,9 +957,9 @@ static void bta_hh_le_encrypt_cback(RawAddress bd_addr, tBT_TRANSPORT transport,
.transport = transport,
};
- tBTA_HH_DEV_CB* p_dev_cb = bta_hh_get_cb(link_spec);
+ tBTA_HH_DEV_CB* p_dev_cb = bta_hh_find_cb(link_spec);
if (p_dev_cb == nullptr) {
- log::error("unexpected encryption callback, ignore");
+ log::error("Unexpected encryption callback for {}", bd_addr);
return;
}
@@ -1085,11 +1074,6 @@ static void bta_hh_clear_service_cache(tBTA_HH_DEV_CB* p_cb) {
******************************************************************************/
void bta_hh_start_security(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* /* p_buf */) {
log::verbose("addr:{}", p_cb->link_spec.addrt.bda);
- if (BTM_SecIsSecurityPending(p_cb->link_spec.addrt.bda)) {
- /* if security collision happened, wait for encryption done */
- p_cb->security_pending = true;
- return;
- }
/* if link has been encrypted */
if (BTM_IsEncrypted(p_cb->link_spec.addrt.bda, BT_TRANSPORT_LE)) {
@@ -1103,9 +1087,12 @@ void bta_hh_start_security(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* /* p_buf */
p_cb->status = BTA_HH_ERR_AUTH_FAILED;
BTM_SetEncryption(p_cb->link_spec.addrt.bda, BT_TRANSPORT_LE, bta_hh_le_encrypt_cback, NULL,
BTM_BLE_SEC_ENCRYPT);
- }
- /* unbonded device, report security error here */
- else {
+ } else if (BTM_SecIsSecurityPending(p_cb->link_spec.addrt.bda)) {
+ /* if security collision happened, wait for encryption done */
+ log::debug("addr:{} security collision", p_cb->link_spec.addrt.bda);
+ p_cb->security_pending = true;
+ } else {
+ /* unbonded device, report security error here */
log::debug("addr:{} not bonded", p_cb->link_spec.addrt.bda);
p_cb->status = BTA_HH_ERR_AUTH_FAILED;
bta_hh_clear_service_cache(p_cb);
diff --git a/system/bta/hh/bta_hh_main.cc b/system/bta/hh/bta_hh_main.cc
index 0b14004c65..e28f24341c 100644
--- a/system/bta/hh/bta_hh_main.cc
+++ b/system/bta/hh/bta_hh_main.cc
@@ -30,6 +30,7 @@
#include <cstdint>
#include "bta/hh/bta_hh_int.h"
+#include "main/shim/dumpsys.h"
#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
@@ -44,14 +45,132 @@ tBTA_HH_CB bta_hh_cb;
/*****************************************************************************
* Static functions
****************************************************************************/
-static const char* bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
-static const char* bta_hh_state_code(tBTA_HH_STATE state_code);
+/*******************************************************************************
+ *
+ * Function bta_hh_evt_code
+ *
+ * Description
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+static const char* bta_hh_evt_code(tBTA_HH_INT_EVT evt_code) {
+ switch (evt_code) {
+ case BTA_HH_API_OPEN_EVT:
+ return "BTA_HH_API_OPEN_EVT";
+ case BTA_HH_API_CLOSE_EVT:
+ return "BTA_HH_API_CLOSE_EVT";
+ case BTA_HH_INT_OPEN_EVT:
+ return "BTA_HH_INT_OPEN_EVT";
+ case BTA_HH_INT_CLOSE_EVT:
+ return "BTA_HH_INT_CLOSE_EVT";
+ case BTA_HH_INT_HANDSK_EVT:
+ return "BTA_HH_INT_HANDSK_EVT";
+ case BTA_HH_INT_DATA_EVT:
+ return "BTA_HH_INT_DATA_EVT";
+ case BTA_HH_INT_CTRL_DATA:
+ return "BTA_HH_INT_CTRL_DATA";
+ case BTA_HH_API_WRITE_DEV_EVT:
+ return "BTA_HH_API_WRITE_DEV_EVT";
+ case BTA_HH_SDP_CMPL_EVT:
+ return "BTA_HH_SDP_CMPL_EVT";
+ case BTA_HH_API_MAINT_DEV_EVT:
+ return "BTA_HH_API_MAINT_DEV_EVT";
+ case BTA_HH_API_GET_DSCP_EVT:
+ return "BTA_HH_API_GET_DSCP_EVT";
+ case BTA_HH_OPEN_CMPL_EVT:
+ return "BTA_HH_OPEN_CMPL_EVT";
+ case BTA_HH_GATT_CLOSE_EVT:
+ return "BTA_HH_GATT_CLOSE_EVT";
+ case BTA_HH_GATT_OPEN_EVT:
+ return "BTA_HH_GATT_OPEN_EVT";
+ case BTA_HH_START_ENC_EVT:
+ return "BTA_HH_START_ENC_EVT";
+ case BTA_HH_ENC_CMPL_EVT:
+ return "BTA_HH_ENC_CMPL_EVT";
+ default:
+ return "unknown HID Host event code";
+ }
+}
+
+/*******************************************************************************
+ *
+ * Function bta_hh_state_code
+ *
+ * Description get string representation of HID host state code.
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+static const char* bta_hh_state_code(tBTA_HH_STATE state_code) {
+ switch (state_code) {
+ case BTA_HH_NULL_ST:
+ return "BTA_HH_NULL_ST";
+ case BTA_HH_IDLE_ST:
+ return "BTA_HH_IDLE_ST";
+ case BTA_HH_W4_CONN_ST:
+ return "BTA_HH_W4_CONN_ST";
+ case BTA_HH_CONN_ST:
+ return "BTA_HH_CONN_ST";
+ case BTA_HH_W4_SEC:
+ return "BTA_HH_W4_SEC";
+ default:
+ return "unknown HID Host state";
+ }
+}
+
+/* Finds the related control block, if any */
+static tBTA_HH_DEV_CB* bta_hh_find_cb_by_event(const BT_HDR_RIGID* p_msg) {
+ tBTA_HH_DEV_CB* p_cb = nullptr;
-static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event,
- const tBTA_HH_DATA* p_data) {
- log::verbose("state:{}, event:{}", bta_hh_state_code(p_cb->state),
- bta_hh_evt_code(static_cast<tBTA_HH_INT_EVT>(event)));
- switch (p_cb->state) {
+ if (p_msg->event == BTA_HH_API_OPEN_EVT) {
+ // Connection requested, find or allocate the control block
+ p_cb = bta_hh_get_cb(((tBTA_HH_API_CONN*)p_msg)->link_spec);
+ } else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT) {
+ if (((tBTA_HH_MAINT_DEV*)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT) {
+ // Device is being added, find or allocate the control block
+ p_cb = bta_hh_get_cb(((tBTA_HH_MAINT_DEV*)p_msg)->link_spec);
+ } else /* else remove device by handle */ {
+ p_cb = bta_hh_find_cb_by_handle((uint8_t)p_msg->layer_specific);
+ /* If BT disable is done while the HID device is connected and
+ * Link_Key uses unauthenticated combination
+ * then we can get into a situation where remove_bonding is called
+ * with the index set to 0 (without getting
+ * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the
+ * index and make it MAX_KNOWN.
+ * So if REMOVE_DEVICE is called and in_use is false then we should
+ * treat this as a NULL p_cb. Hence we
+ * force the index to be IDX_INVALID
+ */
+ if (p_cb != nullptr && !p_cb->in_use) {
+ log::warn("Control block getting removed, device: {}, index: {}, handle: {}",
+ p_cb->link_spec, p_cb->index, p_cb->hid_handle);
+ p_cb = nullptr;
+ }
+ }
+ } else if (p_msg->event == BTA_HH_INT_OPEN_EVT) {
+ p_cb = bta_hh_get_cb(((tBTA_HH_CBACK_DATA*)p_msg)->link_spec);
+ } else {
+ p_cb = bta_hh_find_cb_by_handle((uint8_t)p_msg->layer_specific);
+ }
+
+ return p_cb;
+}
+
+/* Handles events related to connection control blocks */
+void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, tBTA_HH_INT_EVT event, const tBTA_HH_DATA* p_data) {
+ tBTA_HH_STATE in_state = p_cb->state;
+ if (p_cb->state == BTA_HH_NULL_ST || p_cb->state >= BTA_HH_INVALID_ST) {
+ log::error("Invalid state State:{}, Event:{} for {}", bta_hh_state_code(in_state),
+ bta_hh_evt_code(event), p_cb->link_spec);
+ return;
+ }
+
+ bool unexpected_event = false;
+ log::verbose("State {}, Event {} for {}", bta_hh_state_code(in_state), bta_hh_evt_code(event),
+ p_cb->link_spec);
+
+ switch (in_state) {
case BTA_HH_IDLE_ST:
switch (event) {
case BTA_HH_API_OPEN_EVT:
@@ -76,6 +195,9 @@ static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event,
p_cb->state = BTA_HH_W4_CONN_ST;
bta_hh_gatt_open(p_cb, p_data);
break;
+ default:
+ unexpected_event = true;
+ break;
}
break;
case BTA_HH_W4_CONN_ST:
@@ -115,6 +237,9 @@ static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event,
p_cb->state = BTA_HH_W4_SEC;
bta_hh_start_security(p_cb, p_data);
break;
+ default:
+ unexpected_event = true;
+ break;
}
break;
case BTA_HH_CONN_ST:
@@ -151,6 +276,9 @@ static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event,
p_cb->state = BTA_HH_IDLE_ST;
bta_hh_gatt_close(p_cb, p_data);
break;
+ default:
+ unexpected_event = true;
+ break;
}
break;
case BTA_HH_W4_SEC:
@@ -176,117 +304,103 @@ static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event,
case BTA_HH_GATT_ENC_CMPL_EVT:
bta_hh_le_notify_enc_cmpl(p_cb, p_data);
break;
+ default:
+ unexpected_event = true;
+ break;
}
break;
}
+
+ if (unexpected_event) {
+ log::warn("Unexpected event event {} in state {} for {}", bta_hh_evt_code(event),
+ bta_hh_state_code(in_state), p_cb->link_spec);
+ } else if (in_state != p_cb->state) {
+ log::debug("State Change: [{}] -> [{}] after Event [{}]", bta_hh_state_code(in_state),
+ bta_hh_state_code(p_cb->state), bta_hh_evt_code(event));
+ }
}
/*******************************************************************************
*
- * Function bta_hh_sm_execute
- *
- * Description State machine event handling function for HID Host
+ * Function bta_hh_hdl_failure
*
+ * Description Handler for state machine failures
*
* Returns void
*
******************************************************************************/
-void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event, const tBTA_HH_DATA* p_data) {
- tBTA_HH cback_data;
- tBTA_HH_EVT cback_event = 0;
- tBTA_HH_STATE in_state;
- tBTA_HH_INT_EVT debug_event = static_cast<tBTA_HH_INT_EVT>(event);
-
- memset(&cback_data, 0, sizeof(tBTA_HH));
-
- /* handle exception, no valid control block was found */
- if (!p_cb) {
- log::verbose("Event:{}, bta_hh_cb.p_cback:{}", bta_hh_evt_code(debug_event),
- fmt::ptr(bta_hh_cb.p_cback));
- /* BTA HH enabled already? otherwise ignore the event although it's bad*/
- if (bta_hh_cb.p_cback != NULL) {
- switch (event) {
- /* no control block available for new connection */
- case BTA_HH_API_OPEN_EVT:
- cback_event = BTA_HH_OPEN_EVT;
- /* build cback data */
- cback_data.conn.link_spec = ((tBTA_HH_API_CONN*)p_data)->link_spec;
- cback_data.conn.status = BTA_HH_ERR_DB_FULL;
- cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
- break;
- /* DB full, BTA_HhAddDev */
- case BTA_HH_API_MAINT_DEV_EVT:
- cback_event = p_data->api_maintdev.sub_event;
-
- if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) {
- cback_data.dev_info.link_spec = p_data->api_maintdev.link_spec;
- cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
- cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
- } else {
- cback_data.dev_info.status = BTA_HH_ERR_HDL;
- cback_data.dev_info.handle = (uint8_t)p_data->api_maintdev.hdr.layer_specific;
- }
- break;
- case BTA_HH_API_WRITE_DEV_EVT:
- cback_event = (p_data->api_sndcmd.t_type - HID_TRANS_GET_REPORT) + BTA_HH_GET_RPT_EVT;
- osi_free_and_reset((void**)&p_data->api_sndcmd.p_data);
- if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
- p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
- p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE) {
- cback_data.dev_status.status = BTA_HH_ERR_HDL;
- cback_data.dev_status.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
- } else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
- p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
- cback_data.hs_data.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
- cback_data.hs_data.status = BTA_HH_ERR_HDL;
- /* hs_data.rsp_data will be all zero, which is not valid value */
- } else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
- p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
- cback_data.status = BTA_HH_ERR_HDL;
- cback_event = BTA_HH_VC_UNPLUG_EVT;
- } else {
- cback_event = 0;
- }
- break;
-
- case BTA_HH_API_CLOSE_EVT:
- cback_event = BTA_HH_CLOSE_EVT;
+void bta_hh_hdl_failure(tBTA_HH_INT_EVT event, const tBTA_HH_DATA* p_data) {
+ if (bta_hh_cb.p_cback == nullptr) {
+ log::error("No callback handler");
+ return;
+ }
- cback_data.dev_status.status = BTA_HH_ERR_HDL;
- cback_data.dev_status.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
- break;
+ log::verbose("Event:{}", bta_hh_evt_code(event));
+ tBTA_HH cback_data = {};
+ tBTA_HH_EVT cback_event = BTA_HH_EMPTY_EVT;
+ switch (event) {
+ /* no control block available for new connection */
+ case BTA_HH_API_OPEN_EVT:
+ cback_event = BTA_HH_OPEN_EVT;
+ /* build cback data */
+ cback_data.conn.link_spec = ((tBTA_HH_API_CONN*)p_data)->link_spec;
+ cback_data.conn.status = BTA_HH_ERR_DB_FULL;
+ cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
+ break;
+ /* DB full, BTA_HhAddDev */
+ case BTA_HH_API_MAINT_DEV_EVT:
+ cback_event = p_data->api_maintdev.sub_event;
- default:
- /* invalid handle, call bad API event */
- log::error("wrong device handle:{}", p_data->hdr.layer_specific);
- /* Free the callback buffer now */
- if (p_data != NULL) {
- osi_free_and_reset((void**)&p_data->hid_cback.p_data);
- }
- break;
+ if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) {
+ cback_data.dev_info.link_spec = p_data->api_maintdev.link_spec;
+ cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
+ cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
+ } else {
+ cback_data.dev_info.status = BTA_HH_ERR_HDL;
+ cback_data.dev_info.handle = (uint8_t)p_data->api_maintdev.hdr.layer_specific;
}
- if (cback_event) {
- (*bta_hh_cb.p_cback)(cback_event, &cback_data);
+ break;
+ case BTA_HH_API_WRITE_DEV_EVT:
+ cback_event = (p_data->api_sndcmd.t_type - HID_TRANS_GET_REPORT) + BTA_HH_GET_RPT_EVT;
+ osi_free_and_reset((void**)&p_data->api_sndcmd.p_data);
+ if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
+ p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
+ p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE) {
+ cback_data.dev_status.status = BTA_HH_ERR_HDL;
+ cback_data.dev_status.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
+ } else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
+ p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
+ cback_data.hs_data.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
+ cback_data.hs_data.status = BTA_HH_ERR_HDL;
+ /* hs_data.rsp_data will be all zero, which is not valid value */
+ } else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
+ p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
+ cback_data.status = BTA_HH_ERR_HDL;
+ cback_event = BTA_HH_VC_UNPLUG_EVT;
+ } else {
+ cback_event = 0;
}
- }
- }
- /* corresponding CB is found, go to state machine */
- else {
- in_state = p_cb->state;
- log::verbose("State 0x{:02x} [{}], Event [{}]", in_state, bta_hh_state_code(in_state),
- bta_hh_evt_code(debug_event));
+ break;
- if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST)) {
- log::error("Invalid state State=0x{:x}, Event={}", p_cb->state, event);
- return;
- }
+ case BTA_HH_API_CLOSE_EVT:
+ cback_event = BTA_HH_CLOSE_EVT;
+ cback_data.dev_status.status = BTA_HH_ERR_HDL;
+ cback_data.dev_status.handle = (uint8_t)p_data->api_sndcmd.hdr.layer_specific;
+ break;
- bta_hh_better_state_machine(p_cb, event, p_data);
+ default:
+ /* Likely an invalid handle, call bad API event */
+ log::error("wrong device handle:{} in event:{}", p_data->hdr.layer_specific,
+ bta_hh_evt_code(event));
+ /* Free the callback buffer now */
+ if (p_data != nullptr) {
+ osi_free_and_reset((void**)&p_data->hid_cback.p_data);
+ }
+ break;
+ }
- if (in_state != p_cb->state) {
- log::debug("HHID State Change: [{}] -> [{}] after Event [{}]", bta_hh_state_code(in_state),
- bta_hh_state_code(p_cb->state), bta_hh_evt_code(debug_event));
- }
+ if (cback_event) {
+ (*bta_hh_cb.p_cback)(cback_event, &cback_data);
}
}
@@ -301,122 +415,26 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event, const tBTA_HH_DATA*
*
******************************************************************************/
bool bta_hh_hdl_event(const BT_HDR_RIGID* p_msg) {
- uint8_t index = BTA_HH_IDX_INVALID;
- tBTA_HH_DEV_CB* p_cb = NULL;
+ tBTA_HH_DEV_CB* p_cb = bta_hh_find_cb_by_event(p_msg);
+ tBTA_HH_INT_EVT event = static_cast<tBTA_HH_INT_EVT>(p_msg->event);
- /* all events processed in state machine need to find corresponding
- CB before proceed */
- if (p_msg->event == BTA_HH_API_OPEN_EVT) {
- index = bta_hh_find_cb(((tBTA_HH_API_CONN*)p_msg)->link_spec);
- } else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT) {
- /* if add device */
- if (((tBTA_HH_MAINT_DEV*)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT) {
- index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV*)p_msg)->link_spec);
- } else /* else remove device by handle */ {
- index = bta_hh_dev_handle_to_cb_idx((uint8_t)p_msg->layer_specific);
- /* If BT disable is done while the HID device is connected and
- * Link_Key uses unauthenticated combination
- * then we can get into a situation where remove_bonding is called
- * with the index set to 0 (without getting
- * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the
- * index and make it MAX_KNOWN.
- * So if REMOVE_DEVICE is called and in_use is false then we should
- * treat this as a NULL p_cb. Hence we
- * force the index to be IDX_INVALID
- */
- if ((index != BTA_HH_IDX_INVALID) && (!bta_hh_cb.kdev[index].in_use)) {
- index = BTA_HH_IDX_INVALID;
- }
- }
- } else if (p_msg->event == BTA_HH_INT_OPEN_EVT) {
- index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA*)p_msg)->link_spec);
+ if (p_cb != nullptr) {
+ bta_hh_sm_execute(p_cb, event, (tBTA_HH_DATA*)p_msg);
} else {
- index = bta_hh_dev_handle_to_cb_idx((uint8_t)p_msg->layer_specific);
+ bta_hh_hdl_failure(event, (tBTA_HH_DATA*)p_msg);
}
- if (index != BTA_HH_IDX_INVALID) {
- p_cb = &bta_hh_cb.kdev[index];
- }
-
- log::verbose("handle={} dev_cb[{}]", p_msg->layer_specific, index);
- bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA*)p_msg);
-
return true;
}
-/*****************************************************************************
- * Debug Functions
- ****************************************************************************/
-/*******************************************************************************
- *
- * Function bta_hh_evt_code
- *
- * Description
- *
- * Returns void
- *
- ******************************************************************************/
-static const char* bta_hh_evt_code(tBTA_HH_INT_EVT evt_code) {
- switch (evt_code) {
- case BTA_HH_API_OPEN_EVT:
- return "BTA_HH_API_OPEN_EVT";
- case BTA_HH_API_CLOSE_EVT:
- return "BTA_HH_API_CLOSE_EVT";
- case BTA_HH_INT_OPEN_EVT:
- return "BTA_HH_INT_OPEN_EVT";
- case BTA_HH_INT_CLOSE_EVT:
- return "BTA_HH_INT_CLOSE_EVT";
- case BTA_HH_INT_HANDSK_EVT:
- return "BTA_HH_INT_HANDSK_EVT";
- case BTA_HH_INT_DATA_EVT:
- return "BTA_HH_INT_DATA_EVT";
- case BTA_HH_INT_CTRL_DATA:
- return "BTA_HH_INT_CTRL_DATA";
- case BTA_HH_API_WRITE_DEV_EVT:
- return "BTA_HH_API_WRITE_DEV_EVT";
- case BTA_HH_SDP_CMPL_EVT:
- return "BTA_HH_SDP_CMPL_EVT";
- case BTA_HH_API_MAINT_DEV_EVT:
- return "BTA_HH_API_MAINT_DEV_EVT";
- case BTA_HH_API_GET_DSCP_EVT:
- return "BTA_HH_API_GET_DSCP_EVT";
- case BTA_HH_OPEN_CMPL_EVT:
- return "BTA_HH_OPEN_CMPL_EVT";
- case BTA_HH_GATT_CLOSE_EVT:
- return "BTA_HH_GATT_CLOSE_EVT";
- case BTA_HH_GATT_OPEN_EVT:
- return "BTA_HH_GATT_OPEN_EVT";
- case BTA_HH_START_ENC_EVT:
- return "BTA_HH_START_ENC_EVT";
- case BTA_HH_ENC_CMPL_EVT:
- return "BTA_HH_ENC_CMPL_EVT";
- default:
- return "unknown HID Host event code";
- }
-}
-
-/*******************************************************************************
- *
- * Function bta_hh_state_code
- *
- * Description get string representation of HID host state code.
- *
- * Returns void
- *
- ******************************************************************************/
-static const char* bta_hh_state_code(tBTA_HH_STATE state_code) {
- switch (state_code) {
- case BTA_HH_NULL_ST:
- return "BTA_HH_NULL_ST";
- case BTA_HH_IDLE_ST:
- return "BTA_HH_IDLE_ST";
- case BTA_HH_W4_CONN_ST:
- return "BTA_HH_W4_CONN_ST";
- case BTA_HH_CONN_ST:
- return "BTA_HH_CONN_ST";
- case BTA_HH_W4_SEC:
- return "BTA_HH_W4_SEC";
- default:
- return "unknown HID Host state";
+#define DUMPSYS_TAG "shim::legacy::hid"
+void bta_hh_dump(int fd) {
+ for (auto dev : bta_hh_cb.kdev) {
+ if (dev.in_use) {
+ LOG_DUMPSYS(fd, "[%d] Device:%s, handle:%d, state:%s, sub class:%d, ", dev.index,
+ dev.link_spec.ToRedactedStringForLogging().c_str(), dev.hid_handle,
+ bta_hh_state_code(dev.state), dev.sub_class);
+ }
}
}
+#undef DUMPSYS_TAG
diff --git a/system/bta/hh/bta_hh_utils.cc b/system/bta/hh/bta_hh_utils.cc
index 2191f0c056..e924cc59b3 100644
--- a/system/bta/hh/bta_hh_utils.cc
+++ b/system/bta/hh/bta_hh_utils.cc
@@ -51,59 +51,136 @@ constexpr uint16_t kSsrMaxLatency = 18; /* slots * 0.625ms */
/*******************************************************************************
*
- * Function bta_hh_find_cb
+ * Function bta_hh_get_cb_index
+ *
+ * Description Find suitable control block index for ACL link specification
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+static uint8_t bta_hh_get_cb_index(const tAclLinkSpec& link_spec) {
+ if (link_spec.addrt.bda.IsEmpty()) {
+ return BTA_HH_IDX_INVALID;
+ }
+
+ uint8_t available_handle = BTA_HH_IDX_INVALID;
+ for (uint8_t i = 0; i < BTA_HH_MAX_DEVICE; i++) {
+ /* Check if any active/known devices is a match */
+ tBTA_HH_DEV_CB& dev = bta_hh_cb.kdev[i];
+ if (link_spec == dev.link_spec) {
+ log::verbose("Reusing handle {} for {}, ", i, link_spec);
+ return i;
+ } else if (available_handle == BTA_HH_IDX_INVALID && !dev.in_use) {
+ available_handle = i;
+ }
+ }
+
+ if (available_handle != BTA_HH_IDX_INVALID) {
+ log::verbose("Using unused handle {} for {}", available_handle, link_spec);
+ }
+ return available_handle;
+}
+
+/*******************************************************************************
*
- * Description Find best available control block according to ACL link
- * specification.
+ * Function bta_hh_get_cb
*
+ * Description Find or allocate control block for ACL link specification
*
* Returns void
*
******************************************************************************/
-uint8_t bta_hh_find_cb(const tAclLinkSpec& link_spec) {
- uint8_t xx;
+tBTA_HH_DEV_CB* bta_hh_get_cb(const tAclLinkSpec& link_spec) {
+ uint8_t idx = bta_hh_get_cb_index(link_spec);
+ if (idx == BTA_HH_IDX_INVALID) {
+ log::error("No handle available for {}", link_spec);
+ return nullptr;
+ }
+
+ tBTA_HH_DEV_CB& dev = bta_hh_cb.kdev[idx];
+ dev.link_spec = link_spec;
+ dev.in_use = true;
+ return &dev;
+}
+
+/*******************************************************************************
+ *
+ * Function bta_hh_find_cb
+ *
+ * Description Find the existing control block for ACL link specification
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+tBTA_HH_DEV_CB* bta_hh_find_cb(const tAclLinkSpec& link_spec) {
+ if (link_spec.addrt.bda.IsEmpty()) {
+ return nullptr;
+ }
- /* See how many active devices there are. */
- for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
+ for (uint8_t i = 0; i < BTA_HH_MAX_DEVICE; i++) {
/* check if any active/known devices is a match */
- if (link_spec == bta_hh_cb.kdev[xx].link_spec && !link_spec.addrt.bda.IsEmpty()) {
-#if (BTA_HH_DEBUG == TRUE)
- log::verbose("found kdev_cb[{}] hid_handle={}", xx, bta_hh_cb.kdev[xx].hid_handle);
-#endif
- return xx;
+ if (link_spec == bta_hh_cb.kdev[i].link_spec) {
+ return &bta_hh_cb.kdev[i];
}
-#if (BTA_HH_DEBUG == TRUE)
- else
- log::verbose("in_use ? [{}] kdev[{}].hid_handle={} state=[{}]", bta_hh_cb.kdev[xx].in_use, xx,
- bta_hh_cb.kdev[xx].hid_handle, bta_hh_cb.kdev[xx].state);
-#endif
}
+ return nullptr;
+}
+
+/*******************************************************************************
+ *
+ * Function bta_hh_dev_handle_to_cb_idx
+ *
+ * Description convert a HID device handle to the device control block
+ * index.
+ *
+ *
+ * Returns uint8_t: index of the device control block.
+ *
+ ******************************************************************************/
+static uint8_t bta_hh_dev_handle_to_cb_idx(uint8_t dev_handle) {
+ uint8_t index = BTA_HH_IDX_INVALID;
- /* if no active device match, find a spot for it */
- for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
- if (!bta_hh_cb.kdev[xx].in_use) {
- bta_hh_cb.kdev[xx].link_spec = link_spec;
- break;
+ if (BTA_HH_IS_LE_DEV_HDL(dev_handle)) {
+ if (BTA_HH_IS_LE_DEV_HDL_VALID(dev_handle)) {
+ index = bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(dev_handle)];
}
- }
-/* If device list full, report BTA_HH_IDX_INVALID */
-#if (BTA_HH_DEBUG == TRUE)
- log::verbose("index={} while max={}", xx, BTA_HH_MAX_DEVICE);
-#endif
+ } else
+ /* regular HID device checking */
+ if (dev_handle < BTA_HH_MAX_KNOWN) {
+ index = bta_hh_cb.cb_index[dev_handle];
+ }
+
+ return index;
+}
- if (xx == BTA_HH_MAX_DEVICE) {
- xx = BTA_HH_IDX_INVALID;
+/*******************************************************************************
+ *
+ * Function bta_hh_find_cb
+ *
+ * Description Find the existing control block for handle
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+tBTA_HH_DEV_CB* bta_hh_find_cb_by_handle(uint8_t hid_handle) {
+ uint8_t index = bta_hh_dev_handle_to_cb_idx(hid_handle);
+ if (index == BTA_HH_IDX_INVALID) {
+ return nullptr;
}
- return xx;
+ return &bta_hh_cb.kdev[index];
}
-tBTA_HH_DEV_CB* bta_hh_get_cb(const tAclLinkSpec& link_spec) {
- uint8_t idx = bta_hh_find_cb(link_spec);
- if (idx == BTA_HH_IDX_INVALID) {
- return nullptr;
+static void bta_hh_reset_cb(tBTA_HH_DEV_CB* p_cb) {
+ // Free buffer for report descriptor info
+ osi_free_and_reset((void**)&p_cb->dscp_info.descriptor.dsc_list);
+
+ // Cancel SDP if it had been started
+ if (p_cb->p_disc_db != nullptr) {
+ (void)get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(p_cb->p_disc_db);
+ osi_free_and_reset((void**)&p_cb->p_disc_db);
}
- return &bta_hh_cb.kdev[idx];
+ *p_cb = {};
}
/*******************************************************************************
@@ -117,8 +194,6 @@ tBTA_HH_DEV_CB* bta_hh_get_cb(const tAclLinkSpec& link_spec) {
*
******************************************************************************/
void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB* p_cb) {
- uint8_t index;
-
if (p_cb->link_spec.transport == BT_TRANSPORT_LE) {
uint8_t le_hid_handle = BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle);
if (le_hid_handle >= BTA_HH_LE_MAX_KNOWN) {
@@ -134,14 +209,8 @@ void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB* p_cb) {
}
}
- /* reset device control block */
- index = p_cb->index; /* Preserve index for this control block */
-
- /* Free buffer for report descriptor info */
- osi_free_and_reset((void**)&p_cb->dscp_info.descriptor.dsc_list);
-
- memset(p_cb, 0, sizeof(tBTA_HH_DEV_CB)); /* Reset control block */
-
+ uint8_t index = p_cb->index; // Preserve index for this control block
+ bta_hh_reset_cb(p_cb); // Reset control block
p_cb->index = index; /* Restore index for this control block */
p_cb->state = BTA_HH_IDLE_ST;
p_cb->hid_handle = BTA_HH_INVALID_HANDLE;
@@ -244,7 +313,7 @@ bool bta_hh_tod_spt(tBTA_HH_DEV_CB* p_cb, uint8_t sub_class) {
******************************************************************************/
tBTA_HH_STATUS bta_hh_read_ssr_param(const tAclLinkSpec& link_spec, uint16_t* p_max_ssr_lat,
uint16_t* p_min_ssr_tout) {
- tBTA_HH_DEV_CB* p_cb = bta_hh_get_cb(link_spec);
+ tBTA_HH_DEV_CB* p_cb = bta_hh_find_cb(link_spec);
if (p_cb == nullptr) {
log::warn("Unable to find device:{}", link_spec);
return BTA_HH_ERR;
@@ -305,16 +374,9 @@ tBTA_HH_STATUS bta_hh_read_ssr_param(const tAclLinkSpec& link_spec, uint16_t* p_
*
******************************************************************************/
void bta_hh_cleanup_disable(tBTA_HH_STATUS status) {
- uint8_t xx;
/* free buffer in CB holding report descriptors */
- for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
- osi_free_and_reset((void**)&bta_hh_cb.kdev[xx].dscp_info.descriptor.dsc_list);
- }
-
- if (bta_hh_cb.p_disc_db) {
- /* Cancel SDP if it had been started. */
- (void)get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(bta_hh_cb.p_disc_db);
- osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
+ for (uint8_t i = 0; i < BTA_HH_MAX_DEVICE; i++) {
+ bta_hh_reset_cb(&bta_hh_cb.kdev[i]);
}
if (bta_hh_cb.p_cback) {
@@ -326,35 +388,6 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status) {
}
}
-/*******************************************************************************
- *
- * Function bta_hh_dev_handle_to_cb_idx
- *
- * Description convert a HID device handle to the device control block
- * index.
- *
- *
- * Returns uint8_t: index of the device control block.
- *
- ******************************************************************************/
-uint8_t bta_hh_dev_handle_to_cb_idx(uint8_t dev_handle) {
- uint8_t index = BTA_HH_IDX_INVALID;
-
- if (BTA_HH_IS_LE_DEV_HDL(dev_handle)) {
- if (BTA_HH_IS_LE_DEV_HDL_VALID(dev_handle)) {
- index = bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(dev_handle)];
- }
-#if (BTA_HH_DEBUG == TRUE)
- log::verbose("dev_handle={} index={}", dev_handle, index);
-#endif
- } else
- /* regular HID device checking */
- if (dev_handle < BTA_HH_MAX_KNOWN) {
- index = bta_hh_cb.cb_index[dev_handle];
- }
-
- return index;
-}
#if (BTA_HH_DEBUG == TRUE)
/*******************************************************************************
*
@@ -366,17 +399,14 @@ uint8_t bta_hh_dev_handle_to_cb_idx(uint8_t dev_handle) {
*
******************************************************************************/
void bta_hh_trace_dev_db(void) {
- uint8_t xx;
-
- log::verbose("bta_hh_trace_dev_db:: Device DB list********************");
-
- for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
- log::verbose("kdev[{}] in_use[{}] handle[{}]", xx, bta_hh_cb.kdev[xx].in_use,
- bta_hh_cb.kdev[xx].hid_handle);
-
- log::verbose("\t\t\t attr_mask[{:04x}] state [{}] sub_class[{:02x}] index = {}",
- bta_hh_cb.kdev[xx].attr_mask, bta_hh_cb.kdev[xx].state,
- bta_hh_cb.kdev[xx].sub_class, bta_hh_cb.kdev[xx].index);
+ log::verbose("Device DB list*******************************************");
+ for (auto dev : bta_hh_cb.kdev) {
+ if (dev.in_use) {
+ log::verbose(
+ "kdev[{:02x}] handle[{:02x}] attr_mask[{:04x}] sub_class[{:02x}] state [{}] "
+ "device[{}] ",
+ dev.index, dev.hid_handle, dev.attr_mask, dev.sub_class, dev.state, dev.link_spec);
+ }
}
log::verbose("*********************************************************");
}
diff --git a/system/bta/include/bta_hh_api.h b/system/bta/include/bta_hh_api.h
index 8864cf0e38..1de1fa2c85 100644
--- a/system/bta/include/bta_hh_api.h
+++ b/system/bta/include/bta_hh_api.h
@@ -551,6 +551,17 @@ void BTA_HhAddDev(const tAclLinkSpec& link_spec, tBTA_HH_ATTR_MASK attr_mask, ui
******************************************************************************/
void BTA_HhRemoveDev(uint8_t dev_handle);
+/*******************************************************************************
+ *
+ * Function BTA_HhDump
+ *
+ * Description Dump BTA HH control block
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void BTA_HhDump(int fd);
+
namespace fmt {
template <>
struct formatter<tBTA_HH_STATUS> : enum_formatter<tBTA_HH_STATUS> {};
diff --git a/system/bta/include/bta_jv_api.h b/system/bta/include/bta_jv_api.h
index 3eabbad6db..c3e0f9cd5d 100644
--- a/system/bta/include/bta_jv_api.h
+++ b/system/bta/include/bta_jv_api.h
@@ -21,19 +21,19 @@
* This is the public interface file the BTA Java I/F
*
******************************************************************************/
-#ifndef BTA_JV_API_H
-#define BTA_JV_API_H
+#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include "bta/include/bta_api.h"
-#include "bta_sec_api.h"
+#include "bta/include/bta_sec_api.h"
#include "include/macros.h"
#include "internal_include/bt_target.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2c_api.h"
+#include "stack/include/rfcdefs.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
@@ -78,9 +78,8 @@ typedef uint8_t tBTA_JV_L2CAP_REASON;
#define BTA_JV_MAX_UUIDS SDP_MAX_UUID_FILTERS
#define BTA_JV_MAX_ATTRS SDP_MAX_ATTR_FILTERS
#define BTA_JV_MAX_SDP_REC SDP_MAX_RECORDS
-#define BTA_JV_MAX_L2C_CONN \
- GAP_MAX_CONNECTIONS /* GAP handle is used as index, hence do not change this \
- value */
+/* GAP handle is used as index, hence do not change this value */
+#define BTA_JV_MAX_L2C_CONN GAP_MAX_CONNECTIONS
#define BTA_JV_MAX_RFC_CONN MAX_RFC_PORTS
#ifndef BTA_JV_DEF_RFC_MTU
@@ -271,7 +270,6 @@ typedef struct {
int32_t tx_mtu; /* The transmit MTU */
void** p_p_cback; /* set them for new socket */
void** p_user_data; /* set them for new socket */
-
} tBTA_JV_L2CAP_LE_OPEN;
/* data associated with BTA_JV_L2CAP_CLOSE_EVT */
@@ -310,8 +308,7 @@ typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
uint32_t handle; /* The connection handle */
uint32_t req_id; /* The req_id in the associated BTA_JvL2capRead() */
- uint8_t* p_data; /* This points the same location as the p_data
- * parameter in BTA_JvL2capRead () */
+ uint8_t* p_data; /* Points to the same location as p_data parameter in BTA_JvL2capRead() */
uint16_t len; /* The length of the data read. */
} tBTA_JV_L2CAP_READ;
@@ -423,8 +420,7 @@ typedef union {
tBTA_JV_RFCOMM_CL_INIT rfc_cl_init; /* BTA_JV_RFCOMM_CL_INIT_EVT */
tBTA_JV_RFCOMM_CONG rfc_cong; /* BTA_JV_RFCOMM_CONG_EVT */
tBTA_JV_RFCOMM_WRITE rfc_write; /* BTA_JV_RFCOMM_WRITE_EVT */
- tBTA_JV_DATA_IND data_ind; /* BTA_JV_L2CAP_DATA_IND_EVT
- BTA_JV_RFCOMM_DATA_IND_EVT */
+ tBTA_JV_DATA_IND data_ind; /* BTA_JV_L2CAP_DATA_IND_EVT, BTA_JV_RFCOMM_DATA_IND_EVT */
tBTA_JV_LE_DATA_IND le_data_ind; /* BTA_JV_L2CAP_LE_DATA_IND_EVT */
tBTA_JV_L2CAP_LE_OPEN l2c_le_open; /* BTA_JV_L2CAP_OPEN_EVT */
} tBTA_JV;
@@ -760,5 +756,3 @@ tBTA_JV_STATUS BTA_JvSetPmProfile(uint32_t handle, tBTA_JV_PM_ID app_id,
*
******************************************************************************/
uint16_t BTA_JvRfcommGetPortHdl(uint32_t handle);
-
-#endif /* BTA_JV_API_H */
diff --git a/system/bta/jv/bta_jv_act.cc b/system/bta/jv/bta_jv_act.cc
index 5c201230b5..5b8eed6943 100644
--- a/system/bta/jv/bta_jv_act.cc
+++ b/system/bta/jv/bta_jv_act.cc
@@ -50,6 +50,7 @@
#include "stack/include/gap_api.h"
#include "stack/include/l2cdefs.h"
#include "stack/include/port_api.h"
+#include "stack/include/rfcdefs.h"
#include "stack/include/sdp_api.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
@@ -1737,6 +1738,7 @@ static tBTA_JV_PCB* bta_jv_add_rfc_port(tBTA_JV_RFC_CB* p_cb, tBTA_JV_PCB* p_pcb
port_state.fc_type = (PORT_FC_CTS_ON_INPUT | PORT_FC_CTS_ON_OUTPUT);
if (PORT_SetState(p_pcb->port_handle, &port_state) != PORT_SUCCESS) {
+ log::warn("Unable to set RFCOMM server state handle:{}", p_pcb->port_handle);
}
p_pcb->handle = BTA_JV_RFC_H_S_TO_HDL(p_cb->handle, si);
log::verbose("p_pcb->handle=0x{:x}, curr_sess={}", p_pcb->handle, p_cb->curr_sess);
@@ -1804,7 +1806,7 @@ void bta_jv_rfcomm_start_server(tBTA_SEC sec_mask, uint8_t local_scn, uint8_t ma
if (PORT_SetState(handle, &port_state) != PORT_SUCCESS) {
log::warn("Unable to set RFCOMM port state handle:{}", handle);
- };
+ }
} while (0);
tBTA_JV bta_jv;
@@ -1890,8 +1892,7 @@ void bta_jv_set_pm_profile(uint32_t handle, tBTA_JV_PM_ID app_id, tBTA_JV_CONN_S
if (status != tBTA_JV_STATUS::SUCCESS) {
log::warn("free pm cb failed: reason={}", bta_jv_status_text(status));
}
- } else /* set PM control block */
- {
+ } else { /* set PM control block */
p_cb = bta_jv_alloc_set_pm_profile_cb(handle, app_id);
if (NULL != p_cb) {
diff --git a/system/bta/le_audio/audio_set_configurations.json b/system/bta/le_audio/audio_set_configurations.json
index 09708f32d6..7cd9070ec8 100644
--- a/system/bta/le_audio/audio_set_configurations.json
+++ b/system/bta/le_audio/audio_set_configurations.json
@@ -1,7492 +1,8309 @@
{
- "_comments_": [
- " == Audio Set Configurations == ",
- " Contains: ",
- " 1. configurations : ",
- " Maps configuration name with codec and qos config to be used",
- " 2. codec_configurations : ",
- " Array of codec specific configurations",
- " 3. qos_configurations : ",
- " Array of QoS specific configurations",
- " QoS configuration values are as per BAP spec 1.0",
- " Example values which can be used as 'codec_configuration.type'",
- " Codec Configuration parameter types:",
- " SUPPORTED_SAMPLING_FREQUENCY = 1",
- " SUPPORTED_FRAME_DURATION = 2",
- " SUPPORTED_OCTETS_PER_CODEC_FRAME = 4",
- " SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 5",
- " Example values which can be used as 'codec_configuration.compound_value'",
- " Codec Coding formats:",
- " LC3 = 6",
- " Sampling Frequencies: ",
- " 8000Hz = 1",
- " 11025Hz = 2",
- " 16000Hz = 3",
- " 22050Hz = 4",
- " 24000Hz = 5",
- " 32000Hz = 6",
- " 44100Hz = 7",
- " 48000Hz = 8",
- " 88200Hz = 9",
- " 96000Hz = 10",
- " 176400Hz = 11",
- " 192000Hz = 12",
- " 384000Hz = 13",
- " Frame Durations:",
- " 7500us = 0",
- " 10000us = 1"
- ],
- "configurations": [
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_1_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_1_1",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
- "qos_config_name": [
- "QoS_Config_32_1_1"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_1_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
- "qos_config_name": [
- "QoS_Config_32_1_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_2_1",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_1"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_2_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_1_1",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_1_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_2_1",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_2_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_1"
- ]
- },
- {
- "name": "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_48_4_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_48_3_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_32_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_24_1_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_24_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "qos_config_name": [
- "QoS_Config_16_1_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_1"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_16_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_24_1_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_24_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_24_2_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_24_2_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_24_2_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_24_2_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_24_2_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_24_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_1_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_1"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_32_2_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_2_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_48_4_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_48_4_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_3_High_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_3_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_48_3_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_2_High_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_48_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_1_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_48_1_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4_1",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_48_4_1"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_48_4_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_3_High_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_3_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_48_3_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_2_High_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_2_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_48_2_2"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_1_2",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_48_1_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4_High_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4_1",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_48_4_1"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_48_4_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_3_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_3_High_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_3_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_48_3_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_2_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_2_High_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_2_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_48_2_2"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_1_Low_Latency",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_1_High_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_1_2",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_48_1_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4_High_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4_1",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_48_4_1"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
- "qos_config_name": [
- "QoS_Config_48_4_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_3_High_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_3_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_3",
- "qos_config_name": [
- "QoS_Config_48_3_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_2_High_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_2_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_48_2_2"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_1_High_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_1_2",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_48_1_2"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_Low_Latency_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60oct_R3_L22_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
- "qos_config_name": [
- "VND_QoS_Config_R3_L22"
- ]
- },
- {
- "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
- "codec_config_name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
- "codec_config_name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
- "qos_config_name": [
- "VND_QoS_Config_R15_L70"
- ]
- },
- {
- "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
- "codec_config_name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
- "codec_config_name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
- "qos_config_name": [
- "VND_QoS_Config_R15_L70"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
- "qos_config_name": [
- "VND_QoS_Config_R15_L70"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
- "qos_config_name": [
- "QoS_Config_High_Reliability"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
- "qos_config_name": [
- "VND_QoS_Config_R5_L12"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Low_Latency",
- "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
- "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Low_Latency",
- "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_Low_Latency"
- ]
- },
- {
- "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
- "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
- "qos_config_name": [
- "VND_QoS_Config_R11_L40"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
- "qos_config_name": [
- "VND_QoS_Config_R5_L12",
- "VND_QoS_Config_R3_L12"
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1",
- "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
- "qos_config_name": [
- "QoS_Config_Balanced_Reliability"
- ]
+ "_comments_": [
+ " == Audio Set Configurations == ",
+ " Contains: ",
+ " 1. configurations : ",
+ " Maps configuration name with codec and qos config to be used",
+ " 2. codec_configurations : ",
+ " Array of codec specific configurations",
+ " 3. qos_configurations : ",
+ " Array of QoS specific configurations",
+ " QoS configuration values are as per BAP spec 1.0",
+ " Example values which can be used as 'codec_configuration.type'",
+ " Codec Configuration parameter types:",
+ " SUPPORTED_SAMPLING_FREQUENCY = 1",
+ " SUPPORTED_FRAME_DURATION = 2",
+ " SUPPORTED_OCTETS_PER_CODEC_FRAME = 4",
+ " SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 5",
+ " Example values which can be used as 'codec_configuration.compound_value'",
+ " Codec Coding formats:",
+ " LC3 = 6",
+ " Sampling Frequencies: ",
+ " 8000Hz = 1",
+ " 11025Hz = 2",
+ " 16000Hz = 3",
+ " 22050Hz = 4",
+ " 24000Hz = 5",
+ " 32000Hz = 6",
+ " 44100Hz = 7",
+ " 48000Hz = 8",
+ " 88200Hz = 9",
+ " 96000Hz = 10",
+ " 176400Hz = 11",
+ " 192000Hz = 12",
+ " 384000Hz = 13",
+ " Frame Durations:",
+ " 7500us = 0",
+ " 10000us = 1"
+ ],
+ "configurations": [
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_1_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_32_1_1"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_1_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_32_1_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_4_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_3_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_32_1_Low_Latency",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_32_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_24_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_24_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_24_1_Low_Latency",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_24_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SrcAse-Lc3_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_24_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SrcAse-Lc3_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_24_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_24_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_24_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_24_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_24_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_24_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_1",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_3_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_2_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_1_2",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4_High_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4_1",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_3_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_3_High_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_3_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_2_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_2_High_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_2_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_1_Low_Latency",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_1_High_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_1_2",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4_1",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_3_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_2_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_1_2",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_Low_Latency_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60oct_R3_L22_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R3_L22"
+ ]
+ },
+ {
+ "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "codec_config_name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
+ "codec_config_name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R15_L70"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "codec_config_name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
+ "codec_config_name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R15_L70"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R15_L70"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R5_L12"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "codec_config_name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Low_Latency",
+ "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Low_Latency",
+ "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "codec_config_name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R11_L40"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
+ "qos_config_name": [
+ "VND_QoS_Config_R5_L12",
+ "VND_QoS_Config_R3_L12"
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1",
+ "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ }
+ ],
+ "codec_configurations": [
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
}
- ],
- "codec_configurations": [
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "Two-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_48_4",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_48_3",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 90,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_48_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_48_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_32_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_24_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 45,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SrcAse-Lc3_16_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_3",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 90,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_3",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 90,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_3",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 90,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 120,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 40,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 100,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 8
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 75,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 3
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 30,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_24_1",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 45,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_24_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 45,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_24_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 5
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 2,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 2,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- },
- {
- "ase_cnt": 1,
- "direction": "SOURCE",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 1
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_2",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 1
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 80,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
- },
- {
- "name": "One-TwoChan-SnkAse-Lc3_32_1",
- "subconfigurations": [
- {
- "ase_cnt": 1,
- "direction": "SINK",
- "codec_id": {
- "coding_format": 6,
- "vendor_company_id": 0,
- "vendor_codec_id": 0
- },
- "codec_configuration": [
- {
- "name": "sampling_frequency",
- "type": 1,
- "compound_value": {
- "value": [
- 6
- ]
- }
- },
- {
- "name": "frame_duration",
- "type": 2,
- "compound_value": {
- "value": [
- 0
- ]
- }
- },
- {
- "name": "octets_per_codec_frame",
- "type": 4,
- "compound_value": {
- "value": [
- 60,
- 0
- ]
- }
- },
- {
- "name": "codec_frame_blocks_per_sdu",
- "type": 5,
- "compound_value": {
- "value": [
- 1
- ]
- }
- }
- ],
- "ase_channel_cnt": 2
- }
- ]
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
}
- ],
- "qos_configurations": [
- {
- "name": "QoS_Config_16_1_1",
- "retransmission_number": 2,
- "max_transport_latency": 8
- },
- {
- "name": "QoS_Config_16_1_2",
- "retransmission_number": 13,
- "max_transport_latency": 75
- },
- {
- "name": "QoS_Config_16_2_1",
- "retransmission_number": 2,
- "max_transport_latency": 10
- },
- {
- "name": "QoS_Config_16_2_2",
- "retransmission_number": 13,
- "max_transport_latency": 95
- },
- {
- "name": "QoS_Config_24_1_1",
- "retransmission_number": 2,
- "max_transport_latency": 8
- },
- {
- "name": "QoS_Config_24_1_2",
- "retransmission_number": 13,
- "max_transport_latency": 75
- },
- {
- "name": "QoS_Config_24_2_1",
- "retransmission_number": 2,
- "max_transport_latency": 10
- },
- {
- "name": "QoS_Config_24_2_2",
- "retransmission_number": 13,
- "max_transport_latency": 95
- },
- {
- "name": "QoS_Config_32_1_1",
- "retransmission_number": 2,
- "max_transport_latency": 8
- },
- {
- "name": "QoS_Config_32_1_2",
- "retransmission_number": 13,
- "max_transport_latency": 75
- },
- {
- "name": "QoS_Config_32_2_1",
- "retransmission_number": 2,
- "max_transport_latency": 10
- },
- {
- "name": "QoS_Config_32_2_2",
- "retransmission_number": 13,
- "max_transport_latency": 95
- },
- {
- "name": "QoS_Config_48_1_2",
- "retransmission_number": 13,
- "max_transport_latency": 75
- },
- {
- "name": "QoS_Config_48_2_2",
- "retransmission_number": 13,
- "max_transport_latency": 95
- },
- {
- "name": "QoS_Config_48_3_2",
- "retransmission_number": 13,
- "max_transport_latency": 75
- },
- {
- "name": "QoS_Config_48_4_1",
- "retransmission_number": 5,
- "max_transport_latency": 20
- },
- {
- "name": "QoS_Config_48_4_2",
- "retransmission_number": 13,
- "max_transport_latency": 100
- },
- {
- "name": "VND_QoS_Config_R3_L22",
- "retransmission_number": 3,
- "max_transport_latency": 22
- },
- {
- "name": "VND_QoS_Config_R15_L70",
- "retransmission_number": 15,
- "max_transport_latency": 70
- },
- {
- "name": "VND_QoS_Config_R5_L12",
- "retransmission_number": 5,
- "max_transport_latency": 12
- },
- {
- "name": "VND_QoS_Config_R11_L40",
- "retransmission_number": 11,
- "max_transport_latency": 40
- },
- {
- "name": "VND_QoS_Config_R3_L12",
- "retransmission_number": 3,
- "max_transport_latency": 12
- },
- {
- "name": "QoS_Config_Low_Latency",
- "target_latency": "LOW",
- "retransmission_number": 0,
- "max_transport_latency": 0
- },
- {
- "name": "QoS_Config_Balanced_Reliability",
- "target_latency": "BALANCED_RELIABILITY",
- "retransmission_number": 0,
- "max_transport_latency": 0
- },
- {
- "name": "QoS_Config_High_Reliability",
- "target_latency": "HIGH_RELIABILITY",
- "retransmission_number": 0,
- "max_transport_latency": 0
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_24_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_24_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_4",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_3",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_48_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_24_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SrcAse-Lc3_16_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_3",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_3",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_3",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 90,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 40,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 100,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 75,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 30,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_24_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_24_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 45,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_24_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 5
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ },
+ {
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 1
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_2",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
+ }
+ ]
+ },
+ {
+ "name": "One-TwoChan-SnkAse-Lc3_32_1",
+ "subconfigurations": [
+ {
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "codec_id": {
+ "coding_format": 6,
+ "vendor_company_id": 0,
+ "vendor_codec_id": 0
+ },
+ "codec_configuration": [
+ {
+ "name": "sampling_frequency",
+ "type": 1,
+ "compound_value": {
+ "value": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 60,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ],
+ "ase_channel_cnt": 2
}
- ]
+ ]
+ }
+ ],
+ "qos_configurations": [
+ {
+ "name": "QoS_Config_16_1_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 8
+ },
+ {
+ "name": "QoS_Config_16_1_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_16_2_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 10
+ },
+ {
+ "name": "QoS_Config_16_2_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 95
+ },
+ {
+ "name": "QoS_Config_24_1_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 8
+ },
+ {
+ "name": "QoS_Config_24_1_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_24_2_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 10
+ },
+ {
+ "name": "QoS_Config_24_2_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 95
+ },
+ {
+ "name": "QoS_Config_32_1_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 8
+ },
+ {
+ "name": "QoS_Config_32_1_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_32_2_1",
+ "retransmission_number": 2,
+ "max_transport_latency": 10
+ },
+ {
+ "name": "QoS_Config_32_2_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 95
+ },
+ {
+ "name": "QoS_Config_48_1_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_48_2_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 95
+ },
+ {
+ "name": "QoS_Config_48_3_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 75
+ },
+ {
+ "name": "QoS_Config_48_4_1",
+ "retransmission_number": 5,
+ "max_transport_latency": 20
+ },
+ {
+ "name": "QoS_Config_48_4_2",
+ "retransmission_number": 13,
+ "max_transport_latency": 100
+ },
+ {
+ "name": "VND_QoS_Config_R3_L22",
+ "retransmission_number": 3,
+ "max_transport_latency": 22
+ },
+ {
+ "name": "VND_QoS_Config_R15_L70",
+ "retransmission_number": 15,
+ "max_transport_latency": 70
+ },
+ {
+ "name": "VND_QoS_Config_R5_L12",
+ "retransmission_number": 5,
+ "max_transport_latency": 12
+ },
+ {
+ "name": "VND_QoS_Config_R11_L40",
+ "retransmission_number": 11,
+ "max_transport_latency": 40
+ },
+ {
+ "name": "VND_QoS_Config_R3_L12",
+ "retransmission_number": 3,
+ "max_transport_latency": 12
+ },
+ {
+ "name": "QoS_Config_Low_Latency",
+ "target_latency": "LOW",
+ "retransmission_number": 0,
+ "max_transport_latency": 0
+ },
+ {
+ "name": "QoS_Config_Balanced_Reliability",
+ "target_latency": "BALANCED_RELIABILITY",
+ "retransmission_number": 0,
+ "max_transport_latency": 0
+ },
+ {
+ "name": "QoS_Config_High_Reliability",
+ "target_latency": "HIGH_RELIABILITY",
+ "retransmission_number": 0,
+ "max_transport_latency": 0
+ }
+ ]
} \ No newline at end of file
diff --git a/system/bta/le_audio/audio_set_scenarios.json b/system/bta/le_audio/audio_set_scenarios.json
index b29dba516e..52857f3356 100644
--- a/system/bta/le_audio/audio_set_scenarios.json
+++ b/system/bta/le_audio/audio_set_scenarios.json
@@ -1,259 +1,295 @@
{
- "_comments_": [
- "== Audio Set Scenarios ==",
- " Each defined scenario references externally defined audio set",
- " configurations, listed in the order of priority."
- ],
- "scenarios": [
- {
- "name": "Conversational",
- "configurations": [
- "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
- "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
- "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_2",
- "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
- "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_2",
- "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
- "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
- "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_2",
- "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
- "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_2",
- "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_48_4_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_48_3_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_24_1_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability",
- "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60oct_R3_L22_1",
- "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability"
- ]
- },
- {
- "name": "Media",
- "configurations": [
- "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_4_2",
- "Two-OneChan-SnkAse-Lc3_48_2_High_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_2_2",
- "Two-OneChan-SnkAse-Lc3_48_3_High_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_3_2",
- "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_1_2",
- "Two-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
- "Two-OneChan-SnkAse-Lc3_24_2_2",
- "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "Two-OneChan-SnkAse-Lc3_16_2_2",
- "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
- "Two-OneChan-SnkAse-Lc3_16_1_2",
- "One-TwoChan-SnkAse-Lc3_48_4_High_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_4_2",
- "One-TwoChan-SnkAse-Lc3_48_2_High_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_2_2",
- "One-TwoChan-SnkAse-Lc3_48_3_High_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_3_2",
- "One-TwoChan-SnkAse-Lc3_48_1_High_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_1_2",
- "One-TwoChan-SnkAse-Lc3_24_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_24_2_2",
- "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_16_2_2",
- "One-TwoChan-SnkAse-Lc3_16_1_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_16_1_2",
- "One-OneChan-SnkAse-Lc3_48_4_High_Reliability",
- "One-OneChan-SnkAse-Lc3_48_4_2",
- "One-OneChan-SnkAse-Lc3_48_2_High_Reliability",
- "One-OneChan-SnkAse-Lc3_48_2_2",
- "One-OneChan-SnkAse-Lc3_48_3_High_Reliability",
- "One-OneChan-SnkAse-Lc3_48_3_2",
- "One-OneChan-SnkAse-Lc3_48_1_High_Reliability",
- "One-OneChan-SnkAse-Lc3_48_1_2",
- "One-OneChan-SnkAse-Lc3_32_2_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_32_2_2",
- "One-OneChan-SnkAse-Lc3_32_1_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_32_1_2",
- "One-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_24_2_2",
- "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_16_2_2",
- "One-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_16_1_2",
- "VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
- "VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
- "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1",
- "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1",
- "VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
- "VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
- "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability"
- ]
- },
- {
- "name": "Game",
- "configurations": [
- "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
- "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Low_Latency",
- "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1",
- "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1",
- "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1",
- "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1",
- "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_24_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_48_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_48_3_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_48_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_24_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_24_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1_Low_Latency"
- ]
- },
- {
- "name": "VoiceAssistants",
- "configurations": [
- "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
- "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
- "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
- "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
- "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
- "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
- "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
- "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
- "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability"
- ]
- },
- {
- "name": "Live",
- "configurations": [
- "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1",
- "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1",
- "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
- "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
- "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
- "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
- "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
- "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
- "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
- "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
- "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
- "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
- "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
- "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
- "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
- "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
- "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
- "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability"
- ]
- }
- ]
+ "_comments_": [
+ "== Audio Set Scenarios ==",
+ " Each defined scenario references externally defined audio set",
+ " configurations, listed in the order of priority."
+ ],
+ "scenarios": [
+ {
+ "name": "Conversational",
+ "configurations": [
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_2",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_2",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_2",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_2",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_4_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_3_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_24_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability",
+ "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60oct_R3_L22_1",
+ "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Media",
+ "configurations": [
+ "Two-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4_2",
+ "Two-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_2_2",
+ "Two-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_3_2",
+ "Two-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_1_2",
+ "Two-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_24_2_2",
+ "Two-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_16_2_2",
+ "Two-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_16_1_2",
+ "One-TwoChan-SnkAse-Lc3_48_4_High_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4_2",
+ "One-TwoChan-SnkAse-Lc3_48_2_High_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_2_2",
+ "One-TwoChan-SnkAse-Lc3_48_3_High_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_3_2",
+ "One-TwoChan-SnkAse-Lc3_48_1_High_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_1_2",
+ "One-TwoChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_24_2_2",
+ "One-TwoChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_16_2_2",
+ "One-TwoChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_16_1_2",
+ "One-OneChan-SnkAse-Lc3_48_4_High_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_4_2",
+ "One-OneChan-SnkAse-Lc3_48_2_High_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_2_2",
+ "One-OneChan-SnkAse-Lc3_48_3_High_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_3_2",
+ "One-OneChan-SnkAse-Lc3_48_1_High_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_1_2",
+ "One-OneChan-SnkAse-Lc3_32_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_32_2_2",
+ "One-OneChan-SnkAse-Lc3_32_1_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_32_1_2",
+ "One-OneChan-SnkAse-Lc3_24_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_24_2_2",
+ "One-OneChan-SnkAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_16_2_2",
+ "One-OneChan-SnkAse-Lc3_16_1_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_16_1_2",
+ "VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1",
+ "VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1",
+ "VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1",
+ "Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Game",
+ "configurations": [
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Low_Latency",
+ "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_24_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_3_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_24_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_24_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1_Low_Latency"
+ ]
+ },
+ {
+ "name": "VoiceAssistants",
+ "configurations": [
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-Two-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-TwoChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_24_2_Balanced_Reliability",
+ "One-OneChan-SnkAse-Lc3_48_4-One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "Two-OneChan-SnkAse-Lc3_48_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_48_3_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_48_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_32_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_24_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_24_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_3_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_48_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_24_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_24_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SrcAse-Lc3_32_1_Low_Latency",
+ "Two-OneChan-SrcAse-Lc3_24_2_Low_Latency",
+ "Two-OneChan-SrcAse-Lc3_24_1_Low_Latency",
+ "Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SrcAse-Lc3_32_1_Low_Latency",
+ "One-TwoChan-SrcAse-Lc3_24_2_Low_Latency",
+ "One-TwoChan-SrcAse-Lc3_24_1_Low_Latency",
+ "One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SrcAse-Lc3_32_1_Low_Latency",
+ "One-OneChan-SrcAse-Lc3_24_2_Low_Latency",
+ "One-OneChan-SrcAse-Lc3_24_1_Low_Latency",
+ "One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SrcAse-Lc3_16_1_Low_Latency"
+ ]
+ },
+ {
+ "name": "Live",
+ "configurations": [
+ "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-Two-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-Two-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-Two-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-TwoChan-SnkAse-Lc3_48_2-Two-TwoChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "Two-TwoChan-SnkAse-Lc3_48_1-Two-TwoChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-TwoChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-TwoChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-TwoChan-SrcAse-Lc3_16_1_1",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-TwoChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "Two-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "Two-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_32_2-One-OneChan-SrcAse-Lc3_32_2_1",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_2-One-OneChan-SrcAse-Lc3_16_2_1",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_Low_Latency",
+ "One-OneChan-SnkAse-Lc3_16_1-One-OneChan-SrcAse-Lc3_16_1_1",
+ "One-OneChan-SrcAse-Lc3_48_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_48_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_32_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_32_1_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_2_Balanced_Reliability",
+ "One-OneChan-SrcAse-Lc3_16_1_Balanced_Reliability"
+ ]
+ }
+ ]
} \ No newline at end of file
diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc
index d30a9dd255..2cc636cbdb 100644
--- a/system/bta/le_audio/client.cc
+++ b/system/bta/le_audio/client.cc
@@ -317,8 +317,8 @@ public:
}
/* Choose the right configuration context */
- auto new_configuration_context = AdjustForVoiceAssistant(
- group, ChooseConfigurationContextType(local_metadata_context_types_.source));
+ auto new_configuration_context =
+ ChooseConfigurationContextType(local_metadata_context_types_.source);
log::debug("new_configuration_context= {}", ToString(new_configuration_context));
ReconfigureOrUpdateMetadata(group, new_configuration_context,
@@ -4374,9 +4374,6 @@ public:
LeAudioContextType context_priority_list[] = {
/* Highest priority first */
LeAudioContextType::CONVERSATIONAL,
- /* Handling RINGTONE will cause the ringtone volume slider to trigger
- * reconfiguration. This will be fixed in b/283349711.
- */
LeAudioContextType::RINGTONE,
LeAudioContextType::LIVE,
LeAudioContextType::VOICEASSISTANTS,
@@ -4755,46 +4752,6 @@ public:
return remote_metadata;
}
- LeAudioContextType AdjustForVoiceAssistant(LeAudioDeviceGroup* group,
- LeAudioContextType new_configuration_context) {
- if (!com::android::bluetooth::flags::le_audio_support_unidirectional_voice_assistant()) {
- log::debug("Flag le_audio_support_unidirectional_voice_assistant NOT enabled");
- return new_configuration_context;
- }
-
- /* Some remote devices expect VOICE ASSISTANT to be unidirectional Phone is
- * Source and Earbuds are Sink */
- if (new_configuration_context != LeAudioContextType::VOICEASSISTANTS) {
- return new_configuration_context;
- }
-
- auto sink_supported_contexts =
- group->GetSupportedContexts(bluetooth::le_audio::types::kLeAudioDirectionSink);
- auto source_supported_contexts =
- group->GetSupportedContexts(bluetooth::le_audio::types::kLeAudioDirectionSource);
-
- log::debug("group_id: {}, sink_supported: {}, source_supported {}", group->group_id_,
- ToString(sink_supported_contexts), ToString(source_supported_contexts));
- if (sink_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS) &&
- source_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS)) {
- return new_configuration_context;
- }
-
- if (sink_supported_contexts.test(LeAudioContextType::VOICEASSISTANTS)) {
- log::info(
- "group_id {} supports only Sink direction for Voice Assistant. "
- "Selecting configurarion context type {}",
- group->group_id_, ToString(LeAudioContextType::INSTRUCTIONAL));
-
- return LeAudioContextType::INSTRUCTIONAL;
- }
-
- log::warn("group_id: {}, unexpected configuration, sink_supported: {}, source_supported {}",
- group->group_id_, ToString(sink_supported_contexts),
- ToString(source_supported_contexts));
- return new_configuration_context;
- }
-
/* Return true if stream is started */
bool ReconfigureOrUpdateRemote(LeAudioDeviceGroup* group, int remote_direction) {
if (stack_config_get_interface()->get_pts_force_le_audio_multiple_contexts_metadata()) {
@@ -4811,8 +4768,7 @@ public:
local_metadata_context_types_.source.to_string(), override_contexts.to_string());
/* Choose the right configuration context */
- auto new_configuration_context =
- AdjustForVoiceAssistant(group, ChooseConfigurationContextType(override_contexts));
+ auto new_configuration_context = ChooseConfigurationContextType(override_contexts);
log::debug("new_configuration_context= {}.", ToString(new_configuration_context));
BidirectionalPair<AudioContexts> remote_contexts = {.sink = override_contexts,
@@ -4829,8 +4785,7 @@ public:
/* Choose the right configuration context */
auto config_context_candids = get_bidirectional(remote_metadata);
- auto new_config_context =
- AdjustForVoiceAssistant(group, ChooseConfigurationContextType(config_context_candids));
+ auto new_config_context = ChooseConfigurationContextType(config_context_candids);
log::debug("config_context_candids= {}, new_config_context= {}",
ToString(config_context_candids), ToString(new_config_context));
diff --git a/system/bta/le_audio/codec_manager.cc b/system/bta/le_audio/codec_manager.cc
index fda45e7946..aedf5f244d 100644
--- a/system/bta/le_audio/codec_manager.cc
+++ b/system/bta/le_audio/codec_manager.cc
@@ -325,7 +325,7 @@ public:
std::unique_ptr<AudioSetConfiguration> GetCodecConfig(
const CodecManager::UnicastConfigurationRequirements& requirements,
- CodecManager::UnicastConfigurationVerifier verifier) {
+ CodecManager::UnicastConfigurationProvider provider) {
if (IsUsingCodecExtensibility()) {
auto hal_config = unicast_local_source_hal_client->GetUnicastConfig(requirements);
if (hal_config) {
@@ -361,8 +361,7 @@ public:
// configuration with group capabilities. Note that this path only
// supports the LC3 codec format. For the multicodec support we should
// rely on the configuration matcher behind the AIDL interface.
- auto conf = verifier(requirements, &configs);
- return conf ? std::make_unique<AudioSetConfiguration>(*conf) : nullptr;
+ return provider(requirements, &configs);
}
bool CheckCodecConfigIsBiDirSwb(const AudioSetConfiguration& config) {
@@ -1192,9 +1191,9 @@ bool CodecManager::UpdateActiveBroadcastAudioHalClient(
std::unique_ptr<AudioSetConfiguration> CodecManager::GetCodecConfig(
const CodecManager::UnicastConfigurationRequirements& requirements,
- CodecManager::UnicastConfigurationVerifier verifier) {
+ CodecManager::UnicastConfigurationProvider provider) {
if (pimpl_->IsRunning()) {
- return pimpl_->codec_manager_impl_->GetCodecConfig(requirements, verifier);
+ return pimpl_->codec_manager_impl_->GetCodecConfig(requirements, provider);
}
return nullptr;
diff --git a/system/bta/le_audio/codec_manager.h b/system/bta/le_audio/codec_manager.h
index 92c0e0e279..4ba95fbde6 100644
--- a/system/bta/le_audio/codec_manager.h
+++ b/system/bta/le_audio/codec_manager.h
@@ -77,16 +77,16 @@ public:
std::optional<std::vector<DeviceDirectionRequirements>> source_requirements;
};
- /* The verifier function checks each possible configuration (from the set of
+ /* The provider function checks each possible configuration (from the set of
* all possible, supported configuration acquired from
* AudioSetConfigurationProvider for the given scenario), to select a single
* configuration, matching the current streaming audio group requirements.
* Note: Used only with the legacy AudioSetConfigurationProvider.
*/
- typedef std::function<const set_configurations::AudioSetConfiguration*(
+ typedef std::function<std::unique_ptr<set_configurations::AudioSetConfiguration>(
const UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs)>
- UnicastConfigurationVerifier;
+ UnicastConfigurationProvider;
struct BroadcastConfigurationRequirements {
std::vector<std::pair<bluetooth::le_audio::types::LeAudioContextType, uint8_t>>
@@ -119,7 +119,7 @@ public:
std::function<void(const offload_config& config, uint8_t direction)> update_receiver);
virtual std::unique_ptr<::bluetooth::le_audio::set_configurations::AudioSetConfiguration>
GetCodecConfig(const UnicastConfigurationRequirements& requirements,
- UnicastConfigurationVerifier verifier);
+ UnicastConfigurationProvider provider);
virtual bool CheckCodecConfigIsBiDirSwb(
const ::bluetooth::le_audio::set_configurations::AudioSetConfiguration& config) const;
virtual bool CheckCodecConfigIsDualBiDirSwb(
diff --git a/system/bta/le_audio/codec_manager_test.cc b/system/bta/le_audio/codec_manager_test.cc
index 896d257ce8..8d0a1f6aa4 100644
--- a/system/bta/le_audio/codec_manager_test.cc
+++ b/system/bta/le_audio/codec_manager_test.cc
@@ -510,7 +510,7 @@ TEST_F(CodecManagerTestAdsp, test_capabilities_none) {
bool has_null_config = false;
auto match_first_config = [&](const CodecManager::UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs)
- -> const set_configurations::AudioSetConfiguration* {
+ -> std::unique_ptr<set_configurations::AudioSetConfiguration> {
// Don't expect the matcher being called on nullptr
if (confs == nullptr) {
has_null_config = true;
@@ -518,7 +518,7 @@ TEST_F(CodecManagerTestAdsp, test_capabilities_none) {
if (confs && confs->size()) {
// For simplicity return the first element, the real matcher should
// check the group capabilities.
- return confs->at(0);
+ return std::make_unique<AudioSetConfiguration>(*(confs->at(0)));
}
return nullptr;
};
@@ -558,12 +558,12 @@ TEST_F(CodecManagerTestAdsp, test_capabilities) {
[&available_configs_size](
const CodecManager::UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs)
- -> const set_configurations::AudioSetConfiguration* {
+ -> std::unique_ptr<set_configurations::AudioSetConfiguration> {
if (confs && confs->size()) {
available_configs_size = confs->size();
// For simplicity return the first element, the real matcher should
// check the group capabilities.
- return confs->at(0);
+ return std::make_unique<AudioSetConfiguration>(*(confs->at(0)));
}
return nullptr;
};
@@ -989,7 +989,7 @@ TEST_F(CodecManagerTestHost, test_dual_bidir_swb_supported) {
{.audio_context_type = context},
[&](const CodecManager::UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs)
- -> const set_configurations::AudioSetConfiguration* {
+ -> std::unique_ptr<set_configurations::AudioSetConfiguration> {
if (confs == nullptr) {
got_null_cfgs_container = true;
} else {
@@ -1039,7 +1039,7 @@ TEST_F(CodecManagerTestAdsp, test_dual_bidir_swb_supported) {
{.audio_context_type = context},
[&](const CodecManager::UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs)
- -> const set_configurations::AudioSetConfiguration* {
+ -> std::unique_ptr<set_configurations::AudioSetConfiguration> {
if (confs == nullptr) {
got_null_cfgs_container = true;
} else {
@@ -1071,7 +1071,7 @@ TEST_F(CodecManagerTestHostNoSwb, test_dual_bidir_swb_not_supported) {
{.audio_context_type = context},
[&](const CodecManager::UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs)
- -> const set_configurations::AudioSetConfiguration* {
+ -> std::unique_ptr<set_configurations::AudioSetConfiguration> {
if (confs == nullptr) {
got_null_cfgs_container = true;
} else {
@@ -1120,7 +1120,7 @@ TEST_F(CodecManagerTestAdspNoSwb, test_dual_bidir_swb_not_supported) {
{.audio_context_type = context},
[&](const CodecManager::UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs)
- -> const set_configurations::AudioSetConfiguration* {
+ -> std::unique_ptr<set_configurations::AudioSetConfiguration> {
if (confs == nullptr) {
got_null_cfgs_container = true;
} else {
diff --git a/system/bta/le_audio/device_groups.cc b/system/bta/le_audio/device_groups.cc
index 0aa6adc705..cfeb71d265 100644
--- a/system/bta/le_audio/device_groups.cc
+++ b/system/bta/le_audio/device_groups.cc
@@ -828,6 +828,23 @@ LeAudioDeviceGroup::GetAudioSetConfigurationRequirements(types::LeAudioContextTy
continue;
}
+ if ((com::android::bluetooth::flags::le_audio_support_unidirectional_voice_assistant() &&
+ ctx_type == types::LeAudioContextType::VOICEASSISTANTS) ||
+ (com::android::bluetooth::flags::leaudio_multicodec_aidl_support() &&
+ ctx_type == types::LeAudioContextType::GAME)) {
+ // For GAME and VOICE ASSISTANT, ignore direction if it is not supported only on a single
+ // direction.
+ auto group_contexts = GetSupportedContexts(types::kLeAudioDirectionBoth);
+ if (group_contexts.test(ctx_type)) {
+ auto direction_contexs = device->GetSupportedContexts(direction);
+ if (!direction_contexs.test(ctx_type)) {
+ log::warn("Device {} has no {} context support", device->address_,
+ common::ToString(ctx_type));
+ continue;
+ }
+ }
+ }
+
auto& dev_locations = (direction == types::kLeAudioDirectionSink)
? device->snk_audio_locations_
: device->src_audio_locations_;
@@ -1399,6 +1416,22 @@ bool LeAudioDeviceGroup::IsAudioSetConfigurationSupported(
continue;
}
+ if (com::android::bluetooth::flags::le_audio_support_unidirectional_voice_assistant() ||
+ com::android::bluetooth::flags::leaudio_multicodec_aidl_support()) {
+ // Verify the direction requirements.
+ if (direction == types::kLeAudioDirectionSink &&
+ requirements.sink_requirements->size() == 0) {
+ log::debug("There is no requirement for Sink direction.");
+ return false;
+ }
+
+ if (direction == types::kLeAudioDirectionSource &&
+ requirements.source_requirements->size() == 0) {
+ log::debug("There is no requirement for source direction.");
+ return false;
+ }
+ }
+
// In some tests we expect the configuration to be there even when the
// contexts are not supported. Then we might want to configure the device
// but use UNSPECIFIED which is always supported (but can be unavailable)
@@ -1873,7 +1906,7 @@ bool LeAudioDeviceGroup::IsConfiguredForContext(LeAudioContextType context_type)
return stream_conf.conf.get() == GetActiveConfiguration().get();
}
-const set_configurations::AudioSetConfiguration*
+std::unique_ptr<set_configurations::AudioSetConfiguration>
LeAudioDeviceGroup::FindFirstSupportedConfiguration(
const CodecManager::UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs) const {
@@ -1887,7 +1920,7 @@ LeAudioDeviceGroup::FindFirstSupportedConfiguration(
log::assert_that(conf != nullptr, "confs should not be null");
if (IsAudioSetConfigurationSupported(requirements, conf)) {
log::debug("found: {}", conf->name);
- return conf;
+ return std::make_unique<set_configurations::AudioSetConfiguration>(*conf);
}
}
diff --git a/system/bta/le_audio/device_groups.h b/system/bta/le_audio/device_groups.h
index 55dec0ce98..16c4240ca5 100644
--- a/system/bta/le_audio/device_groups.h
+++ b/system/bta/le_audio/device_groups.h
@@ -390,7 +390,7 @@ public:
* configurations. This will not be used for finding best possible vendor
* codec configuration.
*/
- const set_configurations::AudioSetConfiguration* FindFirstSupportedConfiguration(
+ std::unique_ptr<set_configurations::AudioSetConfiguration> FindFirstSupportedConfiguration(
const CodecManager::UnicastConfigurationRequirements& requirements,
const set_configurations::AudioSetConfigurations* confs) const;
diff --git a/system/bta/le_audio/devices_test.cc b/system/bta/le_audio/devices_test.cc
index c41e715d4b..ff2783502f 100644
--- a/system/bta/le_audio/devices_test.cc
+++ b/system/bta/le_audio/devices_test.cc
@@ -610,7 +610,7 @@ protected:
auto num_of_allocations_per_ase =
std::min(target_max_channel_counts_per_ase, (uint8_t)split_allocations.size());
// Note: This is very important to set for the unit test
- // Configuration verifier
+ // Configuration provider
endpoint_cfg.codec.channel_count_per_iso_stream = num_of_allocations_per_ase;
// Consume the `num_of_allocations_per_ase` amount of allocations for
@@ -683,7 +683,7 @@ protected:
.WillByDefault(Invoke(
[&](const bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements&
requirements,
- bluetooth::le_audio::CodecManager::UnicastConfigurationVerifier verifier) {
+ bluetooth::le_audio::CodecManager::UnicastConfigurationProvider provider) {
if (codec_coding_format_ == kLeAudioCodingFormatLC3) {
auto filtered =
*bluetooth::le_audio::AudioSetConfigurationProvider::Get()
@@ -702,7 +702,7 @@ protected:
}),
filtered.end());
}
- auto cfg = verifier(requirements, &filtered);
+ auto cfg = provider(requirements, &filtered);
if (cfg == nullptr) {
return std::unique_ptr<AudioSetConfiguration>(nullptr);
}
@@ -1244,7 +1244,7 @@ protected:
.WillByDefault(Invoke([&configs](const bluetooth::le_audio::CodecManager::
UnicastConfigurationRequirements& requirements,
bluetooth::le_audio::CodecManager::
- UnicastConfigurationVerifier verifier) {
+ UnicastConfigurationProvider provider) {
auto filtered = configs;
// Filter out the dual bidir SWB configurations
if (!bluetooth::le_audio::CodecManager::GetInstance()->IsDualBiDirSwbSupported()) {
@@ -1258,7 +1258,7 @@ protected:
}),
filtered.end());
}
- auto cfg = verifier(requirements, &filtered);
+ auto cfg = provider(requirements, &filtered);
if (cfg == nullptr) {
return std::unique_ptr<AudioSetConfiguration>(nullptr);
}
@@ -1897,7 +1897,7 @@ TEST_P(LeAudioAseConfigurationTest, test_lc3_config_media_codec_extensibility_fb
.WillByDefault(Invoke(
[&](const bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements&
requirements,
- bluetooth::le_audio::CodecManager::UnicastConfigurationVerifier verifier) {
+ bluetooth::le_audio::CodecManager::UnicastConfigurationProvider provider) {
auto filtered = *bluetooth::le_audio::AudioSetConfigurationProvider::Get()
->GetConfigurations(requirements.audio_context_type);
// Filter out the dual bidir SWB configurations
@@ -1914,7 +1914,7 @@ TEST_P(LeAudioAseConfigurationTest, test_lc3_config_media_codec_extensibility_fb
}),
filtered.end());
}
- auto cfg = verifier(requirements, &filtered);
+ auto cfg = provider(requirements, &filtered);
if (cfg == nullptr) {
return std::unique_ptr<AudioSetConfiguration>(nullptr);
}
diff --git a/system/bta/le_audio/le_audio_client_test.cc b/system/bta/le_audio/le_audio_client_test.cc
index fb514c31be..49bd009db1 100644
--- a/system/bta/le_audio/le_audio_client_test.cc
+++ b/system/bta/le_audio/le_audio_client_test.cc
@@ -1452,7 +1452,7 @@ protected:
ON_CALL(*mock_codec_manager_, GetCodecConfig)
.WillByDefault(Invoke([](const CodecManager::UnicastConfigurationRequirements&
requirements,
- CodecManager::UnicastConfigurationVerifier verifier) {
+ CodecManager::UnicastConfigurationProvider provider) {
auto filtered = *le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations(
requirements.audio_context_type);
// Filter out the dual bidir SWB configurations
@@ -1467,9 +1467,7 @@ protected:
}),
filtered.end());
}
- auto cptr = verifier(requirements, &filtered);
- return cptr ? std::make_unique<set_configurations::AudioSetConfiguration>(*cptr)
- : nullptr;
+ return provider(requirements, &filtered);
}));
}
@@ -5840,14 +5838,16 @@ TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Sink) {
types::BidirectionalPair<types::AudioContexts> metadata_contexts = {
.sink = types::AudioContexts(types::LeAudioContextType::VOICEASSISTANTS),
- .source = types::AudioContexts()};
+ .source = types::AudioContexts(types::LeAudioContextType::UNSPECIFIED)};
EXPECT_CALL(mock_state_machine_,
- StartStream(_, types::LeAudioContextType::INSTRUCTIONAL, metadata_contexts, _))
+ StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, metadata_contexts, _))
.Times(1);
+
+ log::info("Connecting LeAudio to {}", test_address0);
ConnectLeAudio(test_address0);
ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
- // Start streaming
+ // We do expect only unidirectional CIS
uint8_t cis_count_out = 1;
uint8_t cis_count_in = 0;
@@ -5885,7 +5885,7 @@ TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Source) {
* Scenario test steps
* 1. Configure group to support VOICEASSISTANT only on SOURCE
* 2. Start stream
- * 5. Verify that bi-direction VOICEASSISTANT has been created
+ * 5. Verify that uni-direction VOICEASSISTANT has been created
*/
available_snk_context_types_ =
@@ -5917,11 +5917,14 @@ TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Source) {
EXPECT_CALL(mock_state_machine_,
StartStream(_, types::LeAudioContextType::VOICEASSISTANTS, metadata_contexts, _))
.Times(1);
+
+ log::info("Connecting LeAudio device {}", test_address0);
+
ConnectLeAudio(test_address0);
ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
- // Start streaming
- uint8_t cis_count_out = 1;
+ // Expected only unidirectional CIS
+ uint8_t cis_count_out = 0;
uint8_t cis_count_in = 1;
// Audio sessions are started only when device gets active
@@ -5930,8 +5933,8 @@ TEST_F(UnicastTest, TestUnidirectionalVoiceAssistant_Source) {
LeAudioClient::Get()->GroupSetActive(group_id);
SyncOnMainLoop();
- StartStreaming(AUDIO_USAGE_ASSISTANT, AUDIO_CONTENT_TYPE_UNKNOWN, group_id,
- AUDIO_SOURCE_VOICE_RECOGNITION);
+ UpdateLocalSinkMetadata(AUDIO_SOURCE_VOICE_RECOGNITION);
+ LocalAudioSinkResume();
// Verify Data transfer on one local audio source cis
TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920);
@@ -10502,13 +10505,13 @@ TEST_F(UnicastTest, CodecFrameBlocks2) {
}
});
- // Add a frame block PAC passing verifier
+ // Add a frame block PAC passing provider
bool is_fb2_passed_as_requirement = false;
ON_CALL(*mock_codec_manager_, GetCodecConfig)
.WillByDefault(Invoke(
[&](const bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements&
requirements,
- bluetooth::le_audio::CodecManager::UnicastConfigurationVerifier verifier) {
+ bluetooth::le_audio::CodecManager::UnicastConfigurationProvider provider) {
auto filtered = *bluetooth::le_audio::AudioSetConfigurationProvider::Get()
->GetConfigurations(requirements.audio_context_type);
// Filter out the dual bidir SWB configurations
@@ -10525,13 +10528,13 @@ TEST_F(UnicastTest, CodecFrameBlocks2) {
}),
filtered.end());
}
- auto cfg = verifier(requirements, &filtered);
+ auto cfg = provider(requirements, &filtered);
if (cfg == nullptr) {
- return std::unique_ptr<set_configurations::AudioSetConfiguration>(nullptr);
+ return std::unique_ptr<
+ bluetooth::le_audio::set_configurations::AudioSetConfiguration>(
+ nullptr);
}
- auto config = *cfg;
-
if (requirements.sink_pacs.has_value()) {
for (auto const& rec : requirements.sink_pacs.value()) {
auto caps = rec.codec_spec_caps.GetAsCoreCodecCapabilities();
@@ -10540,7 +10543,7 @@ TEST_F(UnicastTest, CodecFrameBlocks2) {
max_codec_frames_per_sdu) {
// Inject the proper Codec Frames Per SDU as the json
// configs are conservative and will always give us 1
- for (auto& entry : config.confs.sink) {
+ for (auto& entry : cfg->confs.sink) {
entry.codec.params.Add(
codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
(uint8_t)max_codec_frames_per_sdu);
@@ -10550,7 +10553,7 @@ TEST_F(UnicastTest, CodecFrameBlocks2) {
}
}
}
- return std::make_unique<set_configurations::AudioSetConfiguration>(config);
+ return cfg;
}));
types::BidirectionalPair<stream_parameters> codec_manager_stream_params;
diff --git a/system/bta/le_audio/mock_codec_manager.cc b/system/bta/le_audio/mock_codec_manager.cc
index a3c476a252..53f1f78706 100644
--- a/system/bta/le_audio/mock_codec_manager.cc
+++ b/system/bta/le_audio/mock_codec_manager.cc
@@ -79,7 +79,7 @@ void CodecManager::UpdateActiveAudioConfig(
std::unique_ptr<set_configurations::AudioSetConfiguration> CodecManager::GetCodecConfig(
const CodecManager::UnicastConfigurationRequirements& requirements,
- CodecManager::UnicastConfigurationVerifier verifier) {
+ CodecManager::UnicastConfigurationProvider verifier) {
if (!pimpl_) {
return nullptr;
}
diff --git a/system/bta/le_audio/mock_codec_manager.h b/system/bta/le_audio/mock_codec_manager.h
index ae125a1fe1..8352742a96 100644
--- a/system/bta/le_audio/mock_codec_manager.h
+++ b/system/bta/le_audio/mock_codec_manager.h
@@ -60,7 +60,7 @@ public:
(std::unique_ptr<bluetooth::le_audio::set_configurations::AudioSetConfiguration>),
GetCodecConfig,
(const bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements& requirements,
- bluetooth::le_audio::CodecManager::UnicastConfigurationVerifier),
+ bluetooth::le_audio::CodecManager::UnicastConfigurationProvider),
(const));
MOCK_METHOD((bool), CheckCodecConfigIsBiDirSwb,
(const bluetooth::le_audio::set_configurations::AudioSetConfiguration& config),
diff --git a/system/bta/le_audio/state_machine_test.cc b/system/bta/le_audio/state_machine_test.cc
index b3af9c9321..b3e7024d5f 100644
--- a/system/bta/le_audio/state_machine_test.cc
+++ b/system/bta/le_audio/state_machine_test.cc
@@ -572,7 +572,7 @@ protected:
.WillByDefault(Invoke(
[](const bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements&
requirements,
- bluetooth::le_audio::CodecManager::UnicastConfigurationVerifier verifier) {
+ bluetooth::le_audio::CodecManager::UnicastConfigurationProvider provider) {
auto configs = *bluetooth::le_audio::AudioSetConfigurationProvider::Get()
->GetConfigurations(requirements.audio_context_type);
// Note: This dual bidir SWB exclusion logic has to match the
@@ -590,14 +590,7 @@ protected:
configs.end());
}
- auto cfg = verifier(requirements, &configs);
- if (cfg == nullptr) {
- return std::unique_ptr<
- bluetooth::le_audio::set_configurations::AudioSetConfiguration>(
- nullptr);
- }
- return std::make_unique<
- bluetooth::le_audio::set_configurations::AudioSetConfiguration>(*cfg);
+ return provider(requirements, &configs);
}));
}
@@ -1652,8 +1645,8 @@ TEST_F(StateMachineTest, testConfigureCodecSingleFb2) {
ON_CALL(*mock_codec_manager_, GetCodecConfig)
.WillByDefault(Invoke([&](const bluetooth::le_audio::CodecManager::
UnicastConfigurationRequirements& requirements,
- bluetooth::le_audio::CodecManager::UnicastConfigurationVerifier
- verifier) {
+ bluetooth::le_audio::CodecManager::UnicastConfigurationProvider
+ provider) {
auto configs =
*bluetooth::le_audio::AudioSetConfigurationProvider::Get()->GetConfigurations(
requirements.audio_context_type);
@@ -1671,12 +1664,11 @@ TEST_F(StateMachineTest, testConfigureCodecSingleFb2) {
configs.end());
}
- auto cfg = verifier(requirements, &configs);
+ auto cfg = provider(requirements, &configs);
if (cfg == nullptr) {
return std::unique_ptr<
bluetooth::le_audio::set_configurations::AudioSetConfiguration>(nullptr);
}
- auto config = *cfg;
if (requirements.sink_pacs.has_value()) {
for (auto const& rec : requirements.sink_pacs.value()) {
@@ -1685,7 +1677,7 @@ TEST_F(StateMachineTest, testConfigureCodecSingleFb2) {
if (caps.supported_max_codec_frames_per_sdu.value() ==
codec_frame_blocks_per_sdu_) {
// Scale by Codec Frames Per SDU = 2
- for (auto& entry : config.confs.sink) {
+ for (auto& entry : cfg->confs.sink) {
entry.codec.params.Add(codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
(uint8_t)codec_frame_blocks_per_sdu_);
entry.qos.maxSdu *= codec_frame_blocks_per_sdu_;
@@ -1704,7 +1696,7 @@ TEST_F(StateMachineTest, testConfigureCodecSingleFb2) {
if (caps.supported_max_codec_frames_per_sdu.value() ==
codec_frame_blocks_per_sdu_) {
// Scale by Codec Frames Per SDU = 2
- for (auto& entry : config.confs.source) {
+ for (auto& entry : cfg->confs.source) {
entry.codec.params.Add(codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu,
(uint8_t)codec_frame_blocks_per_sdu_);
entry.qos.maxSdu *= codec_frame_blocks_per_sdu_;
@@ -1717,8 +1709,7 @@ TEST_F(StateMachineTest, testConfigureCodecSingleFb2) {
}
}
- return std::make_unique<bluetooth::le_audio::set_configurations::AudioSetConfiguration>(
- config);
+ return cfg;
}));
/* Device is banded headphones with 1x snk + 0x src ase
diff --git a/system/bta/test/bta_dm_test.cc b/system/bta/test/bta_dm_test.cc
index b12278642d..e3309ecee7 100644
--- a/system/bta/test/bta_dm_test.cc
+++ b/system/bta/test/bta_dm_test.cc
@@ -461,20 +461,19 @@ TEST_F(BtaDmCustomAlarmTest, bta_dm_sniff_cback) {
ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
}
-TEST_F_WITH_FLAGS(BtaDmCustomAlarmTest, sniff_offload_feature__enable_flag,
- REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, enable_sniff_offload))) {
+TEST_F(BtaDmCustomAlarmTest, sniff_offload_feature__test_sysprop) {
bool is_property_enabled = true;
test::mock::osi_properties::osi_property_get_bool.body =
[&](const char* key, bool default_value) -> int { return is_property_enabled; };
- // Expect not to trigger bta_dm_init_pm due to both flag and prop are enabled
+ // Expect not to trigger bta_dm_init_pm due to sysprop enabled
// and reset the value of .srvc_id.
is_property_enabled = true;
bluetooth::legacy::testing::BTA_dm_on_hw_on();
ASSERT_EQ(0, bta_dm_cb.pm_timer[0].srvc_id[0]);
// Expect to trigger bta_dm_init_pm and init the value of .srvc_id to
- // BTA_ID_MAX.
+ // BTA_ID_MAX due to sysprop disabled.
is_property_enabled = false;
bluetooth::legacy::testing::BTA_dm_on_hw_on();
ASSERT_EQ((uint8_t)BTA_ID_MAX, bta_dm_cb.pm_timer[0].srvc_id[0]);
@@ -485,22 +484,3 @@ TEST_F_WITH_FLAGS(BtaDmCustomAlarmTest, sniff_offload_feature__enable_flag,
bta_dm_cb.pm_timer[0].srvc_id[0] = kUnusedTimer;
bta_dm_disable_pm();
}
-
-TEST_F_WITH_FLAGS(BtaDmCustomAlarmTest, sniff_offload_feature__disable_flag,
- REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_BT, enable_sniff_offload))) {
- bool is_property_enabled = true;
- test::mock::osi_properties::osi_property_get_bool.body =
- [&](const char* key, bool default_value) -> int { return is_property_enabled; };
-
- // Expect to trigger bta_dm_init_pm and init the value of .srvc_id to
- // BTA_ID_MAX.
- is_property_enabled = true;
- bluetooth::legacy::testing::BTA_dm_on_hw_on();
- ASSERT_EQ((uint8_t)BTA_ID_MAX, bta_dm_cb.pm_timer[0].srvc_id[0]);
-
- // Expect to trigger bta_dm_init_pm and init the value of .srvc_id to
- // BTA_ID_MAX.
- is_property_enabled = false;
- bluetooth::legacy::testing::BTA_dm_on_hw_on();
- ASSERT_EQ((uint8_t)BTA_ID_MAX, bta_dm_cb.pm_timer[0].srvc_id[0]);
-}
diff --git a/system/bta/vc/vc.cc b/system/bta/vc/vc.cc
index e48934d205..b12a216939 100644
--- a/system/bta/vc/vc.cc
+++ b/system/bta/vc/vc.cc
@@ -366,14 +366,16 @@ public:
auto csis_api = CsisClient::Get();
if (!csis_api) {
log::warn("Csis module is not available");
- callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, true);
+ callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, device->flags,
+ true);
return;
}
auto group_id = csis_api->GetGroupId(device->address, le_audio::uuid::kCapServiceUuid);
if (group_id == bluetooth::groups::kGroupUnknown) {
log::warn("No group for device {}", device->address);
- callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, true);
+ callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, device->flags,
+ true);
return;
}
@@ -438,7 +440,8 @@ public:
/* This is just a read, send single notification */
if (!is_notification) {
- callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, false);
+ callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, device->flags,
+ false);
return;
}
@@ -468,7 +471,8 @@ public:
} else {
/* op->is_autonomous_ will always be false,
since we only make it true for group operations */
- callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, false);
+ callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, device->flags,
+ false);
}
ongoing_operations_.erase(op);
@@ -1067,7 +1071,8 @@ private:
callbacks_->OnConnectionState(ConnectionState::CONNECTED, device->address);
// once profile connected we can notify current states
- callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, false);
+ callbacks_->OnVolumeStateChanged(device->address, device->volume, device->mute, device->flags,
+ true);
for (auto const& offset : device->audio_offsets.volume_offsets) {
callbacks_->OnExtAudioOutVolumeOffsetChanged(device->address, offset.id, offset.offset);
diff --git a/system/bta/vc/vc_test.cc b/system/bta/vc/vc_test.cc
index dfb436e903..708a0a6b65 100644
--- a/system/bta/vc/vc_test.cc
+++ b/system/bta/vc/vc_test.cc
@@ -82,7 +82,8 @@ public:
MOCK_METHOD((void), OnDeviceAvailable, (const RawAddress& address, uint8_t num_offset),
(override));
MOCK_METHOD((void), OnVolumeStateChanged,
- (const RawAddress& address, uint8_t volume, bool mute, bool isAutonomous),
+ (const RawAddress& address, uint8_t volume, bool mute, uint8_t flags,
+ bool isAutonomous),
(override));
MOCK_METHOD((void), OnGroupVolumeStateChanged,
(int group_id, uint8_t volume, bool mute, bool isAutonomous), (override));
@@ -885,7 +886,7 @@ TEST_F(VolumeControlTest, test_subscribe_vocs_output_description) {
TEST_F(VolumeControlTest, test_read_vcs_volume_state) {
const RawAddress test_address = GetTestAddress(0);
- EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, false));
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, _, true)).Times(1);
std::vector<uint16_t> handles({0x0021});
TestReadCharacteristic(test_address, 1, handles);
}
@@ -960,7 +961,7 @@ TEST_F(VolumeControlTest, test_discovery_vocs_broken) {
TEST_F(VolumeControlTest, test_read_vcs_database_out_of_sync) {
const RawAddress test_address = GetTestAddress(0);
- EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, false));
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, _, true));
std::vector<uint16_t> handles({0x0021});
uint16_t conn_id = 1;
@@ -1033,12 +1034,12 @@ protected:
TEST_F(VolumeControlCallbackTest, test_volume_state_changed_stress) {
std::vector<uint8_t> value({0x03, 0x01, 0x02});
- EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, 0x03, true, true));
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, 0x03, true, _, true));
GetNotificationEvent(0x0021, value);
}
TEST_F(VolumeControlCallbackTest, test_volume_state_changed_malformed) {
- EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, _)).Times(0);
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, _, _)).Times(0);
std::vector<uint8_t> too_short({0x03, 0x01});
GetNotificationEvent(0x0021, too_short);
std::vector<uint8_t> too_long({0x03, 0x01, 0x02, 0x03});
@@ -1527,6 +1528,8 @@ TEST_F(VolumeControlCsis, test_set_volume) {
VolumeControl::Get()->SetVolume(test_address_1, 20);
VolumeControl::Get()->SetVolume(test_address_2, 20);
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address_1, 20, false, _, false));
+ EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address_2, 20, false, _, false));
std::vector<uint8_t> value2({20, 0x00, 0x03});
GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value2);
GetNotificationEvent(conn_id_2, test_address_2, 0x0021, value2);
diff --git a/system/btif/src/btif_gatt.cc b/system/btif/src/btif_gatt.cc
index 3292ddbe7a..ed20db4821 100644
--- a/system/btif/src/btif_gatt.cc
+++ b/system/btif/src/btif_gatt.cc
@@ -28,12 +28,14 @@
#include "btif_gatt.h"
+#include <com_android_bluetooth_flags.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>
#include <stdlib.h>
#include <string.h>
-#include "bta_gatt_api.h"
+#include "bta/include/bta_gatt_api.h"
+#include "btif/include/btif_common.h"
#include "main/shim/distance_measurement_manager.h"
#include "main/shim/le_advertising_manager.h"
diff --git a/system/btif/src/btif_gatt_client.cc b/system/btif/src/btif_gatt_client.cc
index 8e9ada0c8c..3589114ab0 100644
--- a/system/btif/src/btif_gatt_client.cc
+++ b/system/btif/src/btif_gatt_client.cc
@@ -30,6 +30,7 @@
#include <base/functional/bind.h>
#include <base/threading/thread.h>
#include <bluetooth/log.h>
+#include <com_android_bluetooth_flags.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_gatt.h>
#include <hardware/bt_gatt_types.h>
@@ -89,7 +90,8 @@ static btif_test_cb_t test_cb;
******************************************************************************/
#define CLI_CBACK_WRAP_IN_JNI(P_CBACK, P_CBACK_WRAP) \
do { \
- if (bt_gatt_callbacks && bt_gatt_callbacks->client->P_CBACK) { \
+ auto callbacks = bt_gatt_callbacks; \
+ if (callbacks && callbacks->client->P_CBACK) { \
log::verbose("HAL bt_gatt_callbacks->client->{}", #P_CBACK); \
do_in_jni_thread(P_CBACK_WRAP); \
} else { \
@@ -97,14 +99,15 @@ static btif_test_cb_t test_cb;
} \
} while (0)
-#define CLI_CBACK_IN_JNI(P_CBACK, ...) \
- do { \
- if (bt_gatt_callbacks && bt_gatt_callbacks->client->P_CBACK) { \
- log::verbose("HAL bt_gatt_callbacks->client->{}", #P_CBACK); \
- do_in_jni_thread(Bind(bt_gatt_callbacks->client->P_CBACK, __VA_ARGS__)); \
- } else { \
- ASSERTC(0, "Callback is NULL", 0); \
- } \
+#define CLI_CBACK_IN_JNI(P_CBACK, ...) \
+ do { \
+ auto callbacks = bt_gatt_callbacks; \
+ if (callbacks && callbacks->client->P_CBACK) { \
+ log::verbose("HAL bt_gatt_callbacks->client->{}", #P_CBACK); \
+ do_in_jni_thread(Bind(callbacks->client->P_CBACK, __VA_ARGS__)); \
+ } else { \
+ ASSERTC(0, "Callback is NULL", 0); \
+ } \
} while (0)
#define CHECK_BTGATT_INIT() \
@@ -139,16 +142,17 @@ uint8_t rssi_request_client_if;
static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
log::debug("Event {} [{}]", gatt_client_event_text(static_cast<tBTA_GATTC_EVT>(event)), event);
+ auto callbacks = bt_gatt_callbacks;
tBTA_GATTC* p_data = (tBTA_GATTC*)p_param;
switch (event) {
case BTA_GATTC_EXEC_EVT: {
- HAL_CBACK(bt_gatt_callbacks, client->execute_write_cb, p_data->exec_cmpl.conn_id,
+ HAL_CBACK(callbacks, client->execute_write_cb, p_data->exec_cmpl.conn_id,
p_data->exec_cmpl.status);
break;
}
case BTA_GATTC_SEARCH_CMPL_EVT: {
- HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb, p_data->search_cmpl.conn_id,
+ HAL_CBACK(callbacks, client->search_complete_cb, p_data->search_cmpl.conn_id,
p_data->search_cmpl.status);
break;
}
@@ -163,7 +167,7 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
data.is_notify = p_data->notify.is_notify;
data.len = p_data->notify.len;
- HAL_CBACK(bt_gatt_callbacks, client->notify_cb, p_data->notify.conn_id, data);
+ HAL_CBACK(callbacks, client->notify_cb, p_data->notify.conn_id, data);
if (!p_data->notify.is_notify) {
BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.cid);
@@ -174,12 +178,12 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
case BTA_GATTC_OPEN_EVT: {
log::debug("BTA_GATTC_OPEN_EVT {}", p_data->open.remote_bda);
- HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id, p_data->open.status,
+ HAL_CBACK(callbacks, client->open_cb, p_data->open.conn_id, p_data->open.status,
p_data->open.client_if, p_data->open.remote_bda);
if (GATT_DEF_BLE_MTU_SIZE != p_data->open.mtu && p_data->open.mtu) {
- HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb, p_data->open.conn_id,
- p_data->open.status, p_data->open.mtu);
+ HAL_CBACK(callbacks, client->configure_mtu_cb, p_data->open.conn_id, p_data->open.status,
+ p_data->open.mtu);
}
if (p_data->open.status == GATT_SUCCESS) {
@@ -190,7 +194,7 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
case BTA_GATTC_CLOSE_EVT: {
log::debug("BTA_GATTC_CLOSE_EVT {}", p_data->close.remote_bda);
- HAL_CBACK(bt_gatt_callbacks, client->close_cb, p_data->close.conn_id, p_data->close.status,
+ HAL_CBACK(callbacks, client->close_cb, p_data->close.conn_id, p_data->close.status,
p_data->close.client_if, p_data->close.remote_bda);
break;
}
@@ -203,33 +207,33 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) {
break;
case BTA_GATTC_CFG_MTU_EVT: {
- HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb, p_data->cfg_mtu.conn_id,
+ HAL_CBACK(callbacks, client->configure_mtu_cb, p_data->cfg_mtu.conn_id,
p_data->cfg_mtu.status, p_data->cfg_mtu.mtu);
break;
}
case BTA_GATTC_CONGEST_EVT:
- HAL_CBACK(bt_gatt_callbacks, client->congestion_cb, p_data->congest.conn_id,
+ HAL_CBACK(callbacks, client->congestion_cb, p_data->congest.conn_id,
p_data->congest.congested);
break;
case BTA_GATTC_PHY_UPDATE_EVT:
- HAL_CBACK(bt_gatt_callbacks, client->phy_updated_cb, p_data->phy_update.conn_id,
+ HAL_CBACK(callbacks, client->phy_updated_cb, p_data->phy_update.conn_id,
p_data->phy_update.tx_phy, p_data->phy_update.rx_phy, p_data->phy_update.status);
break;
case BTA_GATTC_CONN_UPDATE_EVT:
- HAL_CBACK(bt_gatt_callbacks, client->conn_updated_cb, p_data->conn_update.conn_id,
+ HAL_CBACK(callbacks, client->conn_updated_cb, p_data->conn_update.conn_id,
p_data->conn_update.interval, p_data->conn_update.latency,
p_data->conn_update.timeout, p_data->conn_update.status);
break;
case BTA_GATTC_SRVC_CHG_EVT:
- HAL_CBACK(bt_gatt_callbacks, client->service_changed_cb, p_data->service_changed.conn_id);
+ HAL_CBACK(callbacks, client->service_changed_cb, p_data->service_changed.conn_id);
break;
case BTA_GATTC_SUBRATE_CHG_EVT:
- HAL_CBACK(bt_gatt_callbacks, client->subrate_chg_cb, p_data->subrate_chg.conn_id,
+ HAL_CBACK(callbacks, client->subrate_chg_cb, p_data->subrate_chg.conn_id,
p_data->subrate_chg.subrate_factor, p_data->subrate_chg.latency,
p_data->subrate_chg.cont_num, p_data->subrate_chg.timeout,
p_data->subrate_chg.status);
@@ -274,8 +278,9 @@ static bt_status_t btif_gattc_register_app(const Uuid& uuid, bool eatt_support)
[](const Uuid& uuid, uint8_t client_id, uint8_t status) {
do_in_jni_thread(Bind(
[](const Uuid& uuid, uint8_t client_id, uint8_t status) {
- HAL_CBACK(bt_gatt_callbacks, client->register_client_cb,
- status, client_id, uuid);
+ auto callbacks = bt_gatt_callbacks;
+ HAL_CBACK(callbacks, client->register_client_cb, status,
+ client_id, uuid);
},
uuid, client_id, status));
},
@@ -319,7 +324,8 @@ void btif_gattc_open_impl(int client_if, RawAddress address, tBLE_ADDR_TYPE addr
tBTM_BLE_VSC_CB vnd_capabilities;
BTM_BleGetVendorCapabilities(&vnd_capabilities);
if (!vnd_capabilities.rpa_offloading) {
- HAL_CBACK(bt_gatt_callbacks, client->open_cb, 0, BT_STATUS_UNSUPPORTED, client_if, address);
+ auto callbacks = bt_gatt_callbacks;
+ HAL_CBACK(callbacks, client->open_cb, 0, BT_STATUS_UNSUPPORTED, client_if, address);
return;
}
}
@@ -404,7 +410,8 @@ void btif_gattc_get_gatt_db_impl(int conn_id) {
int count = 0;
BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, &count);
- HAL_CBACK(bt_gatt_callbacks, client->get_gatt_db_cb, conn_id, db, count);
+ auto callbacks = bt_gatt_callbacks;
+ HAL_CBACK(callbacks, client->get_gatt_db_cb, conn_id, db, count);
osi_free(db);
}
@@ -469,7 +476,6 @@ void read_desc_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16
if (len > 0) {
memcpy(params.value.value, value, len);
}
-
CLI_CBACK_IN_JNI(read_descriptor_cb, conn_id, status, params);
}
@@ -546,7 +552,8 @@ static void btif_gattc_reg_for_notification_impl(tGATT_IF client_if, const RawAd
tGATT_STATUS status = BTA_GATTC_RegisterForNotifications(client_if, bda, handle);
// TODO(jpawlowski): conn_id is currently unused
- HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
+ auto callbacks = bt_gatt_callbacks;
+ HAL_CBACK(callbacks, client->register_for_notification_cb,
/* conn_id */ 0, 1, status, handle);
}
@@ -563,7 +570,8 @@ static void btif_gattc_dereg_for_notification_impl(tGATT_IF client_if, const Raw
tGATT_STATUS status = BTA_GATTC_DeregisterForNotifications(client_if, bda, handle);
// TODO(jpawlowski): conn_id is currently unused
- HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
+ auto callbacks = bt_gatt_callbacks;
+ HAL_CBACK(callbacks, client->register_for_notification_cb,
/* conn_id */ 0, 0, status, handle);
}
diff --git a/system/btif/src/btif_gatt_server.cc b/system/btif/src/btif_gatt_server.cc
index a273f8d9d7..3714269c23 100644
--- a/system/btif/src/btif_gatt_server.cc
+++ b/system/btif/src/btif_gatt_server.cc
@@ -147,10 +147,11 @@ static void btapp_gatts_free_req_data(uint16_t event, tBTA_GATTS* p_data) {
static void btapp_gatts_handle_cback(uint16_t event, char* p_param) {
log::verbose("Event {}", event);
+ auto callbacks = bt_gatt_callbacks;
tBTA_GATTS* p_data = (tBTA_GATTS*)p_param;
switch (event) {
case BTA_GATTS_REG_EVT: {
- HAL_CBACK(bt_gatt_callbacks, server->register_server_cb, p_data->reg_oper.status,
+ HAL_CBACK(callbacks, server->register_server_cb, p_data->reg_oper.status,
p_data->reg_oper.server_if, p_data->reg_oper.uuid);
break;
}
@@ -161,29 +162,29 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param) {
case BTA_GATTS_CONNECT_EVT: {
btif_gatt_check_encrypted_link(p_data->conn.remote_bda, p_data->conn.transport);
- HAL_CBACK(bt_gatt_callbacks, server->connection_cb, p_data->conn.conn_id,
- p_data->conn.server_if, true, p_data->conn.remote_bda);
+ HAL_CBACK(callbacks, server->connection_cb, p_data->conn.conn_id, p_data->conn.server_if,
+ true, p_data->conn.remote_bda);
break;
}
case BTA_GATTS_DISCONNECT_EVT: {
- HAL_CBACK(bt_gatt_callbacks, server->connection_cb, p_data->conn.conn_id,
- p_data->conn.server_if, false, p_data->conn.remote_bda);
+ HAL_CBACK(callbacks, server->connection_cb, p_data->conn.conn_id, p_data->conn.server_if,
+ false, p_data->conn.remote_bda);
break;
}
case BTA_GATTS_STOP_EVT:
- HAL_CBACK(bt_gatt_callbacks, server->service_stopped_cb, p_data->srvc_oper.status,
+ HAL_CBACK(callbacks, server->service_stopped_cb, p_data->srvc_oper.status,
p_data->srvc_oper.server_if, p_data->srvc_oper.service_id);
break;
case BTA_GATTS_DELETE_EVT:
- HAL_CBACK(bt_gatt_callbacks, server->service_deleted_cb, p_data->srvc_oper.status,
+ HAL_CBACK(callbacks, server->service_deleted_cb, p_data->srvc_oper.status,
p_data->srvc_oper.server_if, p_data->srvc_oper.service_id);
break;
case BTA_GATTS_READ_CHARACTERISTIC_EVT: {
- HAL_CBACK(bt_gatt_callbacks, server->request_read_characteristic_cb, p_data->req_data.conn_id,
+ HAL_CBACK(callbacks, server->request_read_characteristic_cb, p_data->req_data.conn_id,
p_data->req_data.trans_id, p_data->req_data.remote_bda,
p_data->req_data.p_data->read_req.handle, p_data->req_data.p_data->read_req.offset,
p_data->req_data.p_data->read_req.is_long);
@@ -191,7 +192,7 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param) {
}
case BTA_GATTS_READ_DESCRIPTOR_EVT: {
- HAL_CBACK(bt_gatt_callbacks, server->request_read_descriptor_cb, p_data->req_data.conn_id,
+ HAL_CBACK(callbacks, server->request_read_descriptor_cb, p_data->req_data.conn_id,
p_data->req_data.trans_id, p_data->req_data.remote_bda,
p_data->req_data.p_data->read_req.handle, p_data->req_data.p_data->read_req.offset,
p_data->req_data.p_data->read_req.is_long);
@@ -200,39 +201,39 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param) {
case BTA_GATTS_WRITE_CHARACTERISTIC_EVT: {
const auto& req = p_data->req_data.p_data->write_req;
- HAL_CBACK(bt_gatt_callbacks, server->request_write_characteristic_cb,
- p_data->req_data.conn_id, p_data->req_data.trans_id, p_data->req_data.remote_bda,
- req.handle, req.offset, req.need_rsp, req.is_prep, req.value, req.len);
+ HAL_CBACK(callbacks, server->request_write_characteristic_cb, p_data->req_data.conn_id,
+ p_data->req_data.trans_id, p_data->req_data.remote_bda, req.handle, req.offset,
+ req.need_rsp, req.is_prep, req.value, req.len);
break;
}
case BTA_GATTS_WRITE_DESCRIPTOR_EVT: {
const auto& req = p_data->req_data.p_data->write_req;
- HAL_CBACK(bt_gatt_callbacks, server->request_write_descriptor_cb, p_data->req_data.conn_id,
+ HAL_CBACK(callbacks, server->request_write_descriptor_cb, p_data->req_data.conn_id,
p_data->req_data.trans_id, p_data->req_data.remote_bda, req.handle, req.offset,
req.need_rsp, req.is_prep, req.value, req.len);
break;
}
case BTA_GATTS_EXEC_WRITE_EVT: {
- HAL_CBACK(bt_gatt_callbacks, server->request_exec_write_cb, p_data->req_data.conn_id,
+ HAL_CBACK(callbacks, server->request_exec_write_cb, p_data->req_data.conn_id,
p_data->req_data.trans_id, p_data->req_data.remote_bda,
p_data->req_data.p_data->exec_write);
break;
}
case BTA_GATTS_CONF_EVT:
- HAL_CBACK(bt_gatt_callbacks, server->indication_sent_cb, p_data->req_data.conn_id,
+ HAL_CBACK(callbacks, server->indication_sent_cb, p_data->req_data.conn_id,
p_data->req_data.status);
break;
case BTA_GATTS_CONGEST_EVT:
- HAL_CBACK(bt_gatt_callbacks, server->congestion_cb, p_data->congest.conn_id,
+ HAL_CBACK(callbacks, server->congestion_cb, p_data->congest.conn_id,
p_data->congest.congested);
break;
case BTA_GATTS_MTU_EVT:
- HAL_CBACK(bt_gatt_callbacks, server->mtu_changed_cb, p_data->req_data.conn_id,
+ HAL_CBACK(callbacks, server->mtu_changed_cb, p_data->req_data.conn_id,
p_data->req_data.p_data->mtu);
break;
@@ -243,18 +244,18 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param) {
break;
case BTA_GATTS_PHY_UPDATE_EVT:
- HAL_CBACK(bt_gatt_callbacks, server->phy_updated_cb, p_data->phy_update.conn_id,
+ HAL_CBACK(callbacks, server->phy_updated_cb, p_data->phy_update.conn_id,
p_data->phy_update.tx_phy, p_data->phy_update.rx_phy, p_data->phy_update.status);
break;
case BTA_GATTS_CONN_UPDATE_EVT:
- HAL_CBACK(bt_gatt_callbacks, server->conn_updated_cb, p_data->conn_update.conn_id,
+ HAL_CBACK(callbacks, server->conn_updated_cb, p_data->conn_update.conn_id,
p_data->conn_update.interval, p_data->conn_update.latency,
p_data->conn_update.timeout, p_data->conn_update.status);
break;
case BTA_GATTS_SUBRATE_CHG_EVT:
- HAL_CBACK(bt_gatt_callbacks, server->subrate_chg_cb, p_data->subrate_chg.conn_id,
+ HAL_CBACK(callbacks, server->subrate_chg_cb, p_data->subrate_chg.conn_id,
p_data->subrate_chg.subrate_factor, p_data->subrate_chg.latency,
p_data->subrate_chg.cont_num, p_data->subrate_chg.timeout,
p_data->subrate_chg.status);
@@ -390,8 +391,8 @@ static bt_status_t btif_gatts_close(int server_if, const RawAddress& bd_addr, in
static void on_service_added_cb(tGATT_STATUS status, int server_if,
vector<btgatt_db_element_t> service) {
- HAL_CBACK(bt_gatt_callbacks, server->service_added_cb, status, server_if, service.data(),
- service.size());
+ auto callbacks = bt_gatt_callbacks;
+ HAL_CBACK(callbacks, server->service_added_cb, status, server_if, service.data(), service.size());
}
static void add_service_impl(int server_if, vector<btgatt_db_element_t> service) {
@@ -401,7 +402,8 @@ static void add_service_impl(int server_if, vector<btgatt_db_element_t> service)
if (service[0].uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER) ||
service[0].uuid == Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER)) {
log::error("Attept to register restricted service");
- HAL_CBACK(bt_gatt_callbacks, server->service_added_cb, BT_STATUS_AUTH_REJECTED, server_if,
+ auto callbacks = bt_gatt_callbacks;
+ HAL_CBACK(callbacks, server->service_added_cb, BT_STATUS_AUTH_REJECTED, server_if,
service.data(), service.size());
return;
}
@@ -448,7 +450,8 @@ static void btif_gatts_send_response_impl(int conn_id, int trans_id, int status,
BTA_GATTS_SendRsp(conn_id, trans_id, static_cast<tGATT_STATUS>(status), &rsp_struct);
- HAL_CBACK(bt_gatt_callbacks, server->response_confirmation_cb, 0, rsp_struct.attr_value.handle);
+ auto callbacks = bt_gatt_callbacks;
+ HAL_CBACK(callbacks, server->response_confirmation_cb, 0, rsp_struct.attr_value.handle);
}
static bt_status_t btif_gatts_send_response(int conn_id, int trans_id, int status,
diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc
index 47907ae833..0114d2b42a 100644
--- a/system/btif/src/btif_hh.cc
+++ b/system/btif/src/btif_hh.cc
@@ -2186,6 +2186,7 @@ void DumpsysHid(int fd) {
p_dev->reconnect_allowed ? "T" : "F");
}
}
+ BTA_HhDump(fd);
}
namespace bluetooth {
diff --git a/system/btif/src/btif_vc.cc b/system/btif/src/btif_vc.cc
index 150141f118..9ff8db312a 100644
--- a/system/btif/src/btif_vc.cc
+++ b/system/btif/src/btif_vc.cc
@@ -60,10 +60,10 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, public VolumeC
address));
}
- void OnVolumeStateChanged(const RawAddress& address, uint8_t volume, bool mute,
+ void OnVolumeStateChanged(const RawAddress& address, uint8_t volume, bool mute, uint8_t flags,
bool isAutonomous) override {
do_in_jni_thread(Bind(&VolumeControlCallbacks::OnVolumeStateChanged, Unretained(callbacks_),
- address, volume, mute, isAutonomous));
+ address, volume, mute, flags, isAutonomous));
}
void OnGroupVolumeStateChanged(int group_id, uint8_t volume, bool mute,
diff --git a/system/btif/src/stack_manager.cc b/system/btif/src/stack_manager.cc
index 3af74062d6..61099d65d8 100644
--- a/system/btif/src/stack_manager.cc
+++ b/system/btif/src/stack_manager.cc
@@ -63,6 +63,7 @@
#include "internal_include/stack_config.h"
#include "rust/src/core/ffi/module.h"
#include "stack/btm/btm_ble_int.h"
+#include "stack/include/ais_api.h"
#include "stack/include/smp_api.h"
#ifndef BT_STACK_CLEANUP_WAIT_MS
@@ -301,6 +302,7 @@ static void event_start_up_stack(bluetooth::core::CoreInterface* interface,
RFCOMM_Init();
GAP_Init();
+ AIS_Init();
startProfiles();
diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h
index 70b9962495..c88a1d62be 100644
--- a/system/gd/hci/acl_manager/le_impl.h
+++ b/system/gd/hci/acl_manager/le_impl.h
@@ -321,12 +321,18 @@ public:
}
}
+ void set_connectability_state(ConnectabilityState state) {
+ log::debug("{} --> {}", connectability_state_machine_text(connectability_state_),
+ connectability_state_machine_text(state));
+ connectability_state_ = state;
+ }
+
// connection canceled by LeAddressManager.OnPause(), will auto reconnect by
// LeAddressManager.OnResume()
void on_le_connection_canceled_on_pause() {
log::assert_that(pause_connection, "Connection must be paused to ack the le address manager");
arm_on_resume_ = true;
- connectability_state_ = ConnectabilityState::DISARMED;
+ set_connectability_state(ConnectabilityState::DISARMED);
le_address_manager_->AckPause(this);
}
@@ -394,7 +400,7 @@ public:
const bool in_filter_accept_list = is_device_in_accept_list(remote_address);
if (role == hci::Role::CENTRAL) {
- connectability_state_ = ConnectabilityState::DISARMED;
+ set_connectability_state(ConnectabilityState::DISARMED);
if (status == ErrorCode::UNKNOWN_CONNECTION && pause_connection) {
on_le_connection_canceled_on_pause();
return;
@@ -652,9 +658,11 @@ public:
}
void direct_connect_add(AddressWithType address_with_type) {
+ log::debug("{}", address_with_type);
direct_connections_.insert(address_with_type);
if (create_connection_timeout_alarms_.find(address_with_type) !=
create_connection_timeout_alarms_.end()) {
+ log::verbose("Timer already added for {}", address_with_type);
return;
}
@@ -672,6 +680,7 @@ public:
}
void direct_connect_remove(AddressWithType address_with_type) {
+ log::debug("{}", address_with_type);
auto it = create_connection_timeout_alarms_.find(address_with_type);
if (it != create_connection_timeout_alarms_.end()) {
it->second.Cancel();
@@ -691,6 +700,7 @@ public:
return;
}
+ log::debug("Adding device to accept list {}", address_with_type);
accept_list.insert(address_with_type);
register_with_address_manager();
le_address_manager_->AddDeviceToFilterAcceptList(
@@ -752,8 +762,8 @@ public:
if (status != ErrorCode::SUCCESS) {
log::error("Le connection state machine armed failed status:{}", ErrorCodeText(status));
}
- connectability_state_ = (status == ErrorCode::SUCCESS) ? ConnectabilityState::ARMED
- : ConnectabilityState::DISARMED;
+ set_connectability_state((status == ErrorCode::SUCCESS) ? ConnectabilityState::ARMED
+ : ConnectabilityState::DISARMED);
log::info("Le connection state machine armed state:{} status:{}",
connectability_state_machine_text(connectability_state_), ErrorCodeText(status));
if (disarmed_while_arming_) {
@@ -791,7 +801,7 @@ public:
return;
}
AddressWithType empty(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS);
- connectability_state_ = ConnectabilityState::ARMING;
+ set_connectability_state(ConnectabilityState::ARMING);
connecting_le_ = accept_list;
uint16_t le_scan_interval =
@@ -905,7 +915,7 @@ public:
switch (connectability_state_) {
case ConnectabilityState::ARMED:
log::info("Disarming LE connection state machine with create connection cancel");
- connectability_state_ = ConnectabilityState::DISARMING;
+ set_connectability_state(ConnectabilityState::DISARMING);
le_acl_connection_interface_->EnqueueCommand(
LeCreateConnectionCancelBuilder::Create(),
handler_->BindOnce(&le_impl::on_create_connection_cancel_complete,
@@ -964,6 +974,10 @@ public:
return;
}
+ log::verbose("{}, already_in_accept_list: {}, pause_connection {}, state: {}",
+ address_with_type, already_in_accept_list, pause_connection,
+ connectability_state_machine_text(connectability_state_));
+
switch (connectability_state_) {
case ConnectabilityState::ARMED:
case ConnectabilityState::ARMING:
diff --git a/system/gd/hci/acl_manager/le_impl_test.cc b/system/gd/hci/acl_manager/le_impl_test.cc
index e7756ea79f..67c6c8c8ea 100644
--- a/system/gd/hci/acl_manager/le_impl_test.cc
+++ b/system/gd/hci/acl_manager/le_impl_test.cc
@@ -19,6 +19,7 @@
#include <bluetooth/log.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <log/log.h>
#include <chrono>
#include <future>
@@ -237,6 +238,7 @@ public:
class LeImplTest : public ::testing::Test {
protected:
void SetUp() override {
+ __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
thread_ = new Thread("thread", Thread::Priority::NORMAL);
handler_ = new Handler(thread_);
controller_ = new TestController();
@@ -1422,7 +1424,8 @@ TEST_F(LeImplTest, direct_connection_after_background_connection) {
hci::AddressWithType address({0x21, 0x22, 0x23, 0x24, 0x25, 0x26},
AddressType::PUBLIC_DEVICE_ADDRESS);
- // arrange: Create background connection
+ // arrange: Create background connection. Remember that acl_manager adds device background list
+ le_impl_->add_device_to_background_connection_list(address);
le_impl_->create_le_connection(address, true, /* is_direct */ false);
hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST);
hci_layer_->IncomingEvent(
@@ -1455,6 +1458,112 @@ TEST_F(LeImplTest, direct_connection_after_background_connection) {
EXPECT_TRUE(direct_create_connection.IsValid());
log::info("Scan Interval {}", direct_create_connection.GetLeScanInterval());
ASSERT_NE(direct_create_connection.GetLeScanInterval(), bg_create_connection.GetLeScanInterval());
+
+ hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
+ sync_handler();
+
+ // Check state is ARMED
+ ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_);
+
+ // Simulate timeout on direct connect. Verify background connect is still in place
+ EXPECT_CALL(mock_le_connection_callbacks_,
+ OnLeConnectFail(_, ErrorCode::CONNECTION_ACCEPT_TIMEOUT))
+ .Times(1);
+ le_impl_->on_create_connection_timeout(address);
+ sync_handler();
+ cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL);
+ hci_layer_->IncomingEvent(
+ LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
+ hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create(
+ ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL,
+ AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000,
+ ClockAccuracy::PPM_30));
+ EXPECT_TRUE(cancel_connection.IsValid());
+ raw_bg_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION);
+ bg_create_connection = LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create(
+ AclCommandView::Create(raw_bg_create_connection)));
+ EXPECT_TRUE(bg_create_connection.IsValid());
+ sync_handler();
+ ASSERT_TRUE(le_impl_->create_connection_timeout_alarms_.empty());
+
+ hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
+ sync_handler();
+
+ // Check state is ARMED
+ ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_);
+}
+
+TEST_F(LeImplTest, direct_connection_after_direct_connection) {
+ set_random_device_address_policy();
+
+ hci::AddressWithType address({0x21, 0x22, 0x23, 0x24, 0x25, 0x26},
+ AddressType::PUBLIC_DEVICE_ADDRESS);
+
+ // Create first direct connection
+ le_impl_->create_le_connection(address, true, /* is_direct */ true);
+ hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST);
+ hci_layer_->IncomingEvent(
+ LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
+ auto raw_direct_1_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION);
+ hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
+ sync_handler();
+
+ // Check state is ARMED
+ ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_);
+
+ log::info("Second direct connect to the same device");
+
+ // Create second direct connection
+ le_impl_->create_le_connection(address, true, /* is_direct */ true);
+ sync_handler();
+
+ auto cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL);
+ if (cancel_connection.IsValid()) {
+ hci_layer_->IncomingEvent(
+ LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
+ hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create(
+ ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL,
+ AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000,
+ ClockAccuracy::PPM_30));
+ }
+
+ auto raw_direct_2_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION);
+
+ // assert
+ auto direct_1_create_connection =
+ LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create(
+ AclCommandView::Create(raw_direct_1_create_connection)));
+ EXPECT_TRUE(direct_1_create_connection.IsValid());
+ auto direct_2_create_connection =
+ LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create(
+ AclCommandView::Create(raw_direct_2_create_connection)));
+ EXPECT_TRUE(direct_2_create_connection.IsValid());
+ hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
+ sync_handler();
+
+ log::info("Simulate timeout");
+
+ EXPECT_CALL(mock_le_connection_callbacks_,
+ OnLeConnectFail(_, ErrorCode::CONNECTION_ACCEPT_TIMEOUT))
+ .Times(1);
+ le_impl_->on_create_connection_timeout(address);
+ sync_handler();
+ cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL);
+ EXPECT_TRUE(cancel_connection.IsValid());
+ hci_layer_->IncomingEvent(
+ LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
+ hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create(
+ ErrorCode::UNKNOWN_CONNECTION, kHciHandle, Role::CENTRAL,
+ AddressType::PUBLIC_DEVICE_ADDRESS, Address::kEmpty, 0x0000, 0x0000, 0x0000,
+ ClockAccuracy::PPM_30));
+ sync_handler();
+ ASSERT_TRUE(le_impl_->create_connection_timeout_alarms_.empty());
+
+ hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST);
+ hci_layer_->IncomingEvent(
+ LeRemoveDeviceFromFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
+ hci_layer_->AssertNoQueuedCommand();
+ ASSERT_EQ(ConnectabilityState::DISARMED, le_impl_->connectability_state_);
}
} // namespace acl_manager
diff --git a/system/gd/hci/acl_manager/round_robin_scheduler.cc b/system/gd/hci/acl_manager/round_robin_scheduler.cc
index 77707f8b22..d7fda71edb 100644
--- a/system/gd/hci/acl_manager/round_robin_scheduler.cc
+++ b/system/gd/hci/acl_manager/round_robin_scheduler.cc
@@ -18,6 +18,9 @@
#include <bluetooth/log.h>
+#include <memory>
+#include <utility>
+
#include "hci/acl_manager/acl_fragmenter.h"
namespace bluetooth {
namespace hci {
@@ -49,7 +52,10 @@ void RoundRobinScheduler::Register(ConnectionType connection_type, uint16_t hand
acl_queue_handler acl_queue_handler = {connection_type, std::move(queue), false, 0};
acl_queue_handlers_.insert(
std::pair<uint16_t, RoundRobinScheduler::acl_queue_handler>(handle, acl_queue_handler));
+ log::info("registering acl_queue handle={}, acl_credits={}, le_credits={}", handle,
+ acl_packet_credits_, le_acl_packet_credits_);
if (fragments_to_send_.size() == 0) {
+ log::info("start round robin");
start_round_robin();
}
}
@@ -58,6 +64,8 @@ void RoundRobinScheduler::Unregister(uint16_t handle) {
log::assert_that(acl_queue_handlers_.count(handle) == 1,
"assert failed: acl_queue_handlers_.count(handle) == 1");
auto acl_queue_handler = acl_queue_handlers_.find(handle)->second;
+ log::info("unregistering acl_queue handle={}, sent_packets={}", handle,
+ acl_queue_handler.number_of_sent_packets_);
// Reclaim outstanding packets
if (acl_queue_handler.connection_type_ == ConnectionType::CLASSIC) {
acl_packet_credits_ += acl_queue_handler.number_of_sent_packets_;
@@ -89,6 +97,7 @@ uint16_t RoundRobinScheduler::GetLeCredits() { return le_acl_packet_credits_; }
void RoundRobinScheduler::start_round_robin() {
if (acl_packet_credits_ == 0 && le_acl_packet_credits_ == 0) {
+ log::warn("Both buffers are full");
return;
}
if (!fragments_to_send_.empty()) {
diff --git a/system/gd/hci/hci_layer_fake.cc b/system/gd/hci/hci_layer_fake.cc
index eb350acc39..ca13230d31 100644
--- a/system/gd/hci/hci_layer_fake.cc
+++ b/system/gd/hci/hci_layer_fake.cc
@@ -57,11 +57,26 @@ static std::unique_ptr<AclBuilder> NextAclPacket(uint16_t handle) {
return AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, NextPayload(handle));
}
+static void DebugPrintCommandOpcode(std::string prefix,
+ const std::unique_ptr<CommandBuilder>& command) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
+ BitInserter it(*packet_bytes);
+ command->Serialize(it);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto temp_cmd_view = CommandView::Create(packet_bytes_view);
+ temp_cmd_view.IsValid();
+ auto op_code = temp_cmd_view.GetOpCode();
+
+ log::info("{} op_code: {}", prefix, OpCodeText(op_code));
+}
+
void HciLayerFake::EnqueueCommand(
std::unique_ptr<CommandBuilder> command,
common::ContextualOnceCallback<void(CommandStatusView)> on_status) {
std::lock_guard<std::mutex> lock(mutex_);
+ DebugPrintCommandOpcode(std::string("Sending with command status, "), command);
+
command_queue_.push(std::move(command));
command_status_callbacks.push_back(std::move(on_status));
@@ -76,6 +91,8 @@ void HciLayerFake::EnqueueCommand(
common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) {
std::lock_guard<std::mutex> lock(mutex_);
+ DebugPrintCommandOpcode(std::string("Sending with command complete, "), command);
+
command_queue_.push(std::move(command));
command_complete_callbacks.push_back(std::move(on_complete));
diff --git a/system/gd/rust/topshim/Cargo.toml b/system/gd/rust/topshim/Cargo.toml
index 73a8b37623..bc54e63a70 100644
--- a/system/gd/rust/topshim/Cargo.toml
+++ b/system/gd/rust/topshim/Cargo.toml
@@ -36,7 +36,7 @@ tokio-stream = "0.1"
bitflags ="2.4.0"
[build-dependencies]
-bindgen = "0.64"
+bindgen = "0.69.4"
pkg-config = "0.3"
[lib]
diff --git a/system/gd/rust/topshim/vc/vc_shim.cc b/system/gd/rust/topshim/vc/vc_shim.cc
index 4f17a16830..b7f9c80825 100644
--- a/system/gd/rust/topshim/vc/vc_shim.cc
+++ b/system/gd/rust/topshim/vc/vc_shim.cc
@@ -98,10 +98,10 @@ public:
topshim::rust::internal::connection_state_cb(state, address);
}
- void OnVolumeStateChanged(const RawAddress& address, uint8_t volume, bool mute,
+ void OnVolumeStateChanged(const RawAddress& address, uint8_t volume, bool mute, uint8_t flags,
bool is_autonomous) override {
- log::info("address={}, volume={}, mute={}, is_autonomous={}", ADDRESS_TO_LOGGABLE_CSTR(address),
- volume, mute, is_autonomous);
+ log::info("address={}, volume={}, mute={}, flags={}, is_autonomous={}",
+ ADDRESS_TO_LOGGABLE_CSTR(address), volume, mute, flags, is_autonomous);
topshim::rust::internal::volume_state_cb(address, volume, mute, is_autonomous);
}
diff --git a/system/include/hardware/bt_vc.h b/system/include/hardware/bt_vc.h
index 74ed814002..36aa2617ef 100644
--- a/system/include/hardware/bt_vc.h
+++ b/system/include/hardware/bt_vc.h
@@ -36,7 +36,7 @@ public:
/* Callback for the volume change changed on the device */
virtual void OnVolumeStateChanged(const RawAddress& address, uint8_t volume, bool mute,
- bool isAutonomous) = 0;
+ uint8_t flags, bool isAutonomous) = 0;
/* Callback for the volume change changed on the group*/
virtual void OnGroupVolumeStateChanged(int group_id, uint8_t volume, bool mute,
diff --git a/system/internal_include/bt_target.h b/system/internal_include/bt_target.h
index 609dd68c6e..24e1cb32e0 100644
--- a/system/internal_include/bt_target.h
+++ b/system/internal_include/bt_target.h
@@ -17,8 +17,7 @@
*
******************************************************************************/
-#ifndef BT_TARGET_H
-#define BT_TARGET_H
+#pragma once
#ifndef FALSE
#define FALSE false
@@ -39,10 +38,6 @@
#define BTUI_OPS_FORMATS (BTA_OP_VCARD21_MASK | BTA_OP_ANY_MASK)
#endif
-#ifndef BTA_RFC_MTU_SIZE
-#define BTA_RFC_MTU_SIZE (L2CAP_MTU_SIZE - L2CAP_MIN_OFFSET - RFCOMM_DATA_OVERHEAD)
-#endif
-
#ifndef BTA_PAN_INCLUDED
#define BTA_PAN_INCLUDED TRUE
#endif
@@ -117,16 +112,6 @@
#define SDP_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE
#endif
-/* Sends RFCOMM command packets. */
-#ifndef RFCOMM_CMD_BUF_SIZE
-#define RFCOMM_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE
-#endif
-
-/* Sends RFCOMM data packets. */
-#ifndef RFCOMM_DATA_BUF_SIZE
-#define RFCOMM_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE
-#endif
-
/* Sends L2CAP packets to the peer and HCI messages to the controller. */
#ifndef L2CAP_CMD_BUF_SIZE
#define L2CAP_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE
@@ -489,72 +474,6 @@
/******************************************************************************
*
- * RFCOMM
- *
- *****************************************************************************/
-
-/* The maximum number of ports supported. */
-#ifndef MAX_RFC_PORTS
-#define MAX_RFC_PORTS 30
-#endif
-
-/* The maximum simultaneous links to different devices. */
-#ifndef MAX_BD_CONNECTIONS
-#define MAX_BD_CONNECTIONS 16
-#endif
-
-/* The port receive queue low watermark level, in bytes. */
-#ifndef PORT_RX_LOW_WM
-#define PORT_RX_LOW_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_LOW_WM)
-#endif
-
-/* The port receive queue high watermark level, in bytes. */
-#ifndef PORT_RX_HIGH_WM
-#define PORT_RX_HIGH_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_HIGH_WM)
-#endif
-
-/* The port receive queue critical watermark level, in bytes. */
-#ifndef PORT_RX_CRITICAL_WM
-#define PORT_RX_CRITICAL_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_CRITICAL_WM)
-#endif
-
-/* The port receive queue low watermark level, in number of buffers. */
-#ifndef PORT_RX_BUF_LOW_WM
-#define PORT_RX_BUF_LOW_WM 4
-#endif
-
-/* The port receive queue high watermark level, in number of buffers. */
-#ifndef PORT_RX_BUF_HIGH_WM
-#define PORT_RX_BUF_HIGH_WM 10
-#endif
-
-/* The port receive queue critical watermark level, in number of buffers. */
-#ifndef PORT_RX_BUF_CRITICAL_WM
-#define PORT_RX_BUF_CRITICAL_WM 15
-#endif
-
-/* The port transmit queue high watermark level, in bytes. */
-#ifndef PORT_TX_HIGH_WM
-#define PORT_TX_HIGH_WM (BTA_RFC_MTU_SIZE * PORT_TX_BUF_HIGH_WM)
-#endif
-
-/* The port transmit queue critical watermark level, in bytes. */
-#ifndef PORT_TX_CRITICAL_WM
-#define PORT_TX_CRITICAL_WM (BTA_RFC_MTU_SIZE * PORT_TX_BUF_CRITICAL_WM)
-#endif
-
-/* The port transmit queue high watermark level, in number of buffers. */
-#ifndef PORT_TX_BUF_HIGH_WM
-#define PORT_TX_BUF_HIGH_WM 10
-#endif
-
-/* The port transmit queue high watermark level, in number of buffers. */
-#ifndef PORT_TX_BUF_CRITICAL_WM
-#define PORT_TX_BUF_CRITICAL_WM 15
-#endif
-
-/******************************************************************************
- *
* BNEP
*
*****************************************************************************/
@@ -766,11 +685,3 @@
#ifndef BTA_EIR_SERVER_NUM_CUSTOM_UUID
#define BTA_EIR_SERVER_NUM_CUSTOM_UUID 8
#endif
-
-/******************************************************************************
- *
- * Tracing: Include trace header file here.
- *
- *****************************************************************************/
-
-#endif /* BT_TARGET_H */
diff --git a/system/profile/avrcp/device.cc b/system/profile/avrcp/device.cc
index fc0f3cd921..d34f6abbb0 100644
--- a/system/profile/avrcp/device.cc
+++ b/system/profile/avrcp/device.cc
@@ -1505,8 +1505,8 @@ void Device::SetBrowsedPlayerResponse(uint8_t label, std::shared_ptr<SetBrowsedP
current_path_ = std::stack<std::string>();
current_path_.push(root_id);
- auto response =
- SetBrowsedPlayerResponseBuilder::MakeBuilder(Status::NO_ERROR, 0x0000, num_items, 0, "");
+ auto response = SetBrowsedPlayerResponseBuilder::MakeBuilder(Status::NO_ERROR, 0x0000, num_items,
+ 0, root_id);
send_message(label, true, std::move(response));
}
diff --git a/system/rust/src/connection/ffi.rs b/system/rust/src/connection/ffi.rs
index 012045f0e3..587ff3b460 100644
--- a/system/rust/src/connection/ffi.rs
+++ b/system/rust/src/connection/ffi.rs
@@ -56,8 +56,10 @@ mod inner {
/// Register Rust callbacks for connection events
///
/// # Safety
+ ///
/// `callbacks` must be Send + Sync, since C++ moves it to a different thread and
/// invokes it from several others (GD + legacy threads).
+ #[allow(clippy::missing_safety_doc)]
#[cxx_name = "RegisterRustCallbacks"]
unsafe fn unchecked_register_rust_callbacks(
self: Pin<&mut Self>,
diff --git a/system/rust/src/core/ffi/module.cc b/system/rust/src/core/ffi/module.cc
index cfee5cf84e..f43e19a1f8 100644
--- a/system/rust/src/core/ffi/module.cc
+++ b/system/rust/src/core/ffi/module.cc
@@ -53,7 +53,8 @@ namespace {
future_t* Start() {
auto fut = future_new();
- if (bt_gatt_callbacks == nullptr) {
+ auto callbacks = bt_gatt_callbacks;
+ if (callbacks == nullptr) {
// We can't crash here since some adapter tests mis-use the stack
// startup/cleanup logic and start the stack without GATT, but don't fully
// mock out the native layer.
@@ -64,7 +65,7 @@ future_t* Start() {
return fut;
}
bluetooth::rust_shim::start(
- std::make_unique<bluetooth::gatt::GattServerCallbacks>(*bt_gatt_callbacks->server),
+ std::make_unique<bluetooth::gatt::GattServerCallbacks>(*callbacks->server),
std::make_unique<bluetooth::connection::LeAclManagerShim>(), *fut);
return fut;
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index 1d6376c90d..d6c88e0dfa 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -38,6 +38,7 @@ cc_library_static {
name: "libbt-stack",
defaults: ["fluoride_defaults"],
local_include_dirs: [
+ "ais",
"avct",
"avdt",
"avrc",
@@ -180,6 +181,7 @@ cc_library_static {
name: "libbt-stack-core",
defaults: ["fluoride_defaults"],
local_include_dirs: [
+ "ais",
"avct",
"avdt",
"avrc",
@@ -213,6 +215,7 @@ cc_library_static {
"acl/ble_acl.cc",
"acl/btm_acl.cc",
"acl/btm_pm.cc",
+ "ais/ais_ble.cc",
"arbiter/acl_arbiter.cc",
"btm/ble_scanner_hci_interface.cc",
"btm/btm_ble.cc",
@@ -517,6 +520,7 @@ cc_fuzz {
":TestMockStackL2cap",
":TestMockStackMetrics",
":TestMockStackSdp",
+ "ais/*.cc",
"eatt/*.cc",
"fuzzers/gatt_fuzzer.cc",
"gatt/*.cc",
@@ -1973,6 +1977,7 @@ cc_test {
":TestMockStackL2cap",
":TestMockStackSdp",
":TestMockStackSmp",
+ "ais/ais_ble.cc",
"arbiter/acl_arbiter.cc",
"eatt/eatt.cc",
"gatt/att_protocol.cc",
diff --git a/system/stack/BUILD.gn b/system/stack/BUILD.gn
index 2581035379..68d5136db0 100644
--- a/system/stack/BUILD.gn
+++ b/system/stack/BUILD.gn
@@ -53,6 +53,7 @@ source_set("nonstandard_codecs") {
source_set("stack") {
sources = [
+ "ais/ais_ble.cc",
"a2dp/a2dp_api.cc",
"a2dp/a2dp_codec_config.cc",
"a2dp/a2dp_ext.cc",
@@ -187,6 +188,7 @@ source_set("stack") {
include_dirs = [
".",
"include",
+ "ais",
"avct",
"btm",
"avrc",
diff --git a/system/stack/ais/ais_ble.cc b/system/stack/ais/ais_ble.cc
new file mode 100644
index 0000000000..f545fc7981
--- /dev/null
+++ b/system/stack/ais/ais_ble.cc
@@ -0,0 +1,144 @@
+/******************************************************************************
+ *
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <bluetooth/log.h>
+#include <com_android_bluetooth_flags.h>
+#include <string.h>
+
+#include <array>
+
+#include "os/system_properties.h"
+#include "stack/include/ais_api.h"
+#include "stack/include/bt_types.h"
+#include "stack/include/gatt_api.h"
+#include "types/bluetooth/uuid.h"
+
+using bluetooth::Uuid;
+using bluetooth::log::error;
+using bluetooth::log::warn;
+
+static const char kPropertyAndroidAPILevel[] = "ro.build.version.sdk";
+static const uint32_t kPropertyAndroidAPILevelDefault = 0;
+
+const Uuid ANDROID_INFORMATION_SERVICE_UUID =
+ Uuid::FromString(ANDROID_INFORMATION_SERVICE_UUID_STRING);
+const Uuid GATT_UUID_AIS_API_LEVEL = Uuid::FromString(GATT_UUID_AIS_API_LEVEL_STRING);
+
+/* LE AIS attribute handle */
+static uint16_t attr_api_level_handle;
+
+static uint32_t api_level;
+
+void ais_request_cback(uint16_t, uint32_t, tGATTS_REQ_TYPE, tGATTS_DATA*);
+
+static tGATT_CBACK ais_cback = {
+ .p_conn_cb = nullptr,
+ .p_cmpl_cb = nullptr,
+ .p_disc_res_cb = nullptr,
+ .p_disc_cmpl_cb = nullptr,
+ .p_req_cb = ais_request_cback,
+ .p_enc_cmpl_cb = nullptr,
+ .p_congestion_cb = nullptr,
+ .p_phy_update_cb = nullptr,
+ .p_conn_update_cb = nullptr,
+ .p_subrate_chg_cb = nullptr,
+};
+
+/** AIS ATT server attribute access request callback */
+void ais_request_cback(uint16_t conn_id, uint32_t trans_id, tGATTS_REQ_TYPE type,
+ tGATTS_DATA* p_data) {
+ tGATT_STATUS status = GATT_INVALID_PDU;
+ tGATTS_RSP rsp_msg = {};
+ uint16_t handle = p_data->read_req.handle;
+ tGATT_VALUE* p_value = &rsp_msg.attr_value;
+ uint8_t* p = p_value->value;
+
+ if (type == GATTS_REQ_TYPE_READ_CHARACTERISTIC) {
+ p_value->handle = handle;
+
+ if (handle == attr_api_level_handle) {
+ if (p_data->read_req.is_long) {
+ p_value->offset = p_data->read_req.offset;
+ status = GATT_NOT_LONG;
+ } else {
+ UINT32_TO_STREAM(p, api_level);
+ p_value->len = 4;
+ status = GATT_SUCCESS;
+ }
+ } else {
+ status = GATT_NOT_FOUND;
+ }
+ } else {
+ warn("Unknown/unexpected LE AIS ATT request: 0x{:02x}", type);
+ }
+
+ if (GATTS_SendRsp(conn_id, trans_id, status, &rsp_msg) != GATT_SUCCESS) {
+ warn("Unable to send GATT server response conn_id:{}", conn_id);
+ }
+}
+
+/*******************************************************************************
+ *
+ * Function ais_attr_db_init
+ *
+ * Description AIS ATT database initialization.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+void ais_attr_db_init(void) {
+ if (!com::android::bluetooth::flags::android_os_identifier()) {
+ return;
+ }
+ api_level = bluetooth::os::GetSystemPropertyUint32(kPropertyAndroidAPILevel,
+ kPropertyAndroidAPILevelDefault);
+ // Add Android OS identifier if API level is defined.
+ if (api_level != kPropertyAndroidAPILevelDefault) {
+ std::array<uint8_t, Uuid::kNumBytes128> tmp;
+ tmp.fill(0xc5); // any number is fine here
+ Uuid app_uuid = Uuid::From128BitBE(tmp);
+
+ tGATT_IF gatt_if = GATT_Register(app_uuid, "Ais", &ais_cback, false);
+
+ GATT_StartIf(gatt_if);
+
+ btgatt_db_element_t android_information_service[] = {
+ {
+ .uuid = ANDROID_INFORMATION_SERVICE_UUID,
+ .type = BTGATT_DB_PRIMARY_SERVICE,
+ },
+ {
+ .uuid = GATT_UUID_AIS_API_LEVEL,
+ .type = BTGATT_DB_CHARACTERISTIC,
+ .properties = GATT_CHAR_PROP_BIT_READ,
+ .permissions = GATT_PERM_READ_IF_ENCRYPTED_OR_DISCOVERABLE,
+ }};
+ if (GATTS_AddService(gatt_if, android_information_service,
+ sizeof(android_information_service) / sizeof(btgatt_db_element_t)) !=
+ GATT_SERVICE_STARTED) {
+ error("Unable to add Android Information Server gatt_if:{}", gatt_if);
+ }
+
+ attr_api_level_handle = android_information_service[1].attribute_handle;
+ }
+}
+
+/*
+ * This routine should not be called except once per stack invocation.
+ */
+void AIS_Init(void) { ais_attr_db_init(); }
diff --git a/system/stack/fuzzers/gatt_fuzzer.cc b/system/stack/fuzzers/gatt_fuzzer.cc
index a98f674e72..409e62c1da 100644
--- a/system/stack/fuzzers/gatt_fuzzer.cc
+++ b/system/stack/fuzzers/gatt_fuzzer.cc
@@ -49,6 +49,9 @@ namespace os {
bool GetSystemPropertyBool(const std::string& property, bool default_value) {
return default_value;
}
+uint32_t GetSystemPropertyUint32(const std::string& property, uint32_t default_value) {
+ return default_value;
+}
} // namespace os
} // namespace bluetooth
diff --git a/system/stack/gatt/connection_manager.cc b/system/stack/gatt/connection_manager.cc
index deddf506f7..ccd902da00 100644
--- a/system/stack/gatt/connection_manager.cc
+++ b/system/stack/gatt/connection_manager.cc
@@ -366,7 +366,11 @@ bool background_connect_remove(uint8_t app_id, const RawAddress& address) {
}
bool is_background_connection(const RawAddress& address) {
- return bgconn_dev.find(address) != bgconn_dev.end();
+ auto it = bgconn_dev.find(address);
+ if (it == bgconn_dev.end()) {
+ return false;
+ }
+ return it->second.is_in_accept_list;
}
/** deregister all related background connetion device. */
diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc
index bc9fcc622c..dff5e42974 100644
--- a/system/stack/gatt/gatt_api.cc
+++ b/system/stack/gatt/gatt_api.cc
@@ -41,6 +41,7 @@
#include "stack/btm/btm_dev.h"
#include "stack/gatt/connection_manager.h"
#include "stack/gatt/gatt_int.h"
+#include "stack/include/ais_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/l2cap_acl_interface.h"
@@ -72,6 +73,9 @@ tGATT_HDL_LIST_ELEM& gatt_add_an_item_to_list(uint16_t s_handle) {
return *rit;
}
+static tGATT_IF GATT_Register_Dynamic(const Uuid& app_uuid128, const std::string& name,
+ tGATT_CBACK* p_cb_info, bool eatt_support);
+
/*****************************************************************************
*
* GATT SERVER API
@@ -320,8 +324,10 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, in
Uuid* p_uuid = gatts_get_service_uuid(elem.p_db);
if (*p_uuid != Uuid::From16Bit(UUID_SERVCLASS_GMCS_SERVER) &&
*p_uuid != Uuid::From16Bit(UUID_SERVCLASS_GTBS_SERVER)) {
- if (com::android::bluetooth::flags::channel_sounding_in_stack() &&
- *p_uuid == Uuid::From16Bit(UUID_SERVCLASS_RAS)) {
+ if ((com::android::bluetooth::flags::channel_sounding_in_stack() &&
+ *p_uuid == Uuid::From16Bit(UUID_SERVCLASS_RAS)) ||
+ (com::android::bluetooth::flags::android_os_identifier() &&
+ *p_uuid == ANDROID_INFORMATION_SERVICE_UUID)) {
elem.sdp_handle = 0;
} else {
elem.sdp_handle = gatt_add_sdp_record(*p_uuid, elem.s_hdl, elem.e_hdl);
@@ -1216,6 +1222,9 @@ void GATT_SetIdleTimeout(const RawAddress& bd_addr, uint16_t idle_tout, tBT_TRAN
******************************************************************************/
tGATT_IF GATT_Register(const Uuid& app_uuid128, const std::string& name, tGATT_CBACK* p_cb_info,
bool eatt_support) {
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ return GATT_Register_Dynamic(app_uuid128, name, p_cb_info, eatt_support);
+ }
tGATT_REG* p_reg;
uint8_t i_gatt_if = 0;
tGATT_IF gatt_if = 0;
@@ -1252,6 +1261,54 @@ tGATT_IF GATT_Register(const Uuid& app_uuid128, const std::string& name, tGATT_C
return 0;
}
+static tGATT_IF GATT_Register_Dynamic(const Uuid& app_uuid128, const std::string& name,
+ tGATT_CBACK* p_cb_info, bool eatt_support) {
+ for (auto& [gatt_if, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->app_uuid128 == app_uuid128) {
+ log::error("Application already registered, uuid={}", app_uuid128.ToString());
+ return 0;
+ }
+ }
+
+ if (stack_config_get_interface()->get_pts_use_eatt_for_all_services()) {
+ log::info("PTS: Force to use EATT for servers");
+ eatt_support = true;
+ }
+
+ if (gatt_cb.cl_rcb_map.size() >= GATT_CL_RCB_MAX) {
+ log::error("Unable to register GATT client, MAX client reached: {}", gatt_cb.cl_rcb_map.size());
+ return 0;
+ }
+
+ uint8_t i_gatt_if = gatt_cb.next_gatt_if;
+ for (int i = 0; i < GATT_CL_RCB_MAX; i++) {
+ if (gatt_cb.cl_rcb_map.find(static_cast<tGATT_IF>(i_gatt_if)) == gatt_cb.cl_rcb_map.end()) {
+ gatt_cb.cl_rcb_map.emplace(i_gatt_if, std::make_unique<tGATT_REG>());
+ tGATT_REG* p_reg = gatt_cb.cl_rcb_map[i_gatt_if].get();
+ p_reg->app_uuid128 = app_uuid128;
+ p_reg->gatt_if = (tGATT_IF)i_gatt_if;
+ p_reg->app_cb = *p_cb_info;
+ p_reg->in_use = true;
+ p_reg->eatt_support = eatt_support;
+ p_reg->name = name;
+ log::info("Allocated name:{} uuid:{} gatt_if:{} eatt_support:{}", name,
+ app_uuid128.ToString(), p_reg->gatt_if, eatt_support);
+
+ gatt_cb.next_gatt_if = (tGATT_IF)(i_gatt_if + 1);
+ if (gatt_cb.next_gatt_if == 0) {
+ gatt_cb.next_gatt_if = 1;
+ }
+ }
+ i_gatt_if++;
+ if (i_gatt_if == 0) {
+ i_gatt_if = 1;
+ }
+ }
+
+ log::error("Unable to register GATT client, MAX client reached: {}", gatt_cb.cl_rcb_map.size());
+ return 0;
+}
+
/*******************************************************************************
*
* Function GATT_Deregister
@@ -1319,7 +1376,11 @@ void GATT_Deregister(tGATT_IF gatt_if) {
connection_manager::on_app_deregistered(gatt_if);
}
- *p_reg = {};
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ gatt_cb.cl_rcb_map.erase(gatt_if);
+ } else {
+ *p_reg = {};
+ }
}
/*******************************************************************************
diff --git a/system/stack/gatt/gatt_auth.cc b/system/stack/gatt/gatt_auth.cc
index 5d47fc1555..8b893e2354 100644
--- a/system/stack/gatt/gatt_auth.cc
+++ b/system/stack/gatt/gatt_auth.cc
@@ -23,6 +23,7 @@
******************************************************************************/
#include <bluetooth/log.h>
+#include <com_android_bluetooth_flags.h>
#include <string.h>
#include "gatt_api.h"
@@ -214,9 +215,17 @@ void gatt_notify_enc_cmpl(const RawAddress& bd_addr) {
return;
}
- for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
- if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb) {
- (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if, bd_addr);
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_rcb] : gatt_cb.cl_rcb_map) {
+ if (p_rcb->app_cb.p_enc_cmpl_cb) {
+ (*p_rcb->app_cb.p_enc_cmpl_cb)(p_rcb->gatt_if, bd_addr);
+ }
+ }
+ } else {
+ for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+ if (gatt_cb.cl_rcb[i].in_use && gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb) {
+ (*gatt_cb.cl_rcb[i].app_cb.p_enc_cmpl_cb)(gatt_cb.cl_rcb[i].gatt_if, bd_addr);
+ }
}
}
diff --git a/system/stack/gatt/gatt_cl.cc b/system/stack/gatt/gatt_cl.cc
index 3975c92098..9d4577eda1 100644
--- a/system/stack/gatt/gatt_cl.cc
+++ b/system/stack/gatt/gatt_cl.cc
@@ -25,6 +25,7 @@
#define LOG_TAG "bluetooth"
#include <bluetooth/log.h>
+#include <com_android_bluetooth_flags.h>
#include <string.h>
#include "gatt_int.h"
@@ -696,9 +697,17 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, ui
// notification/indication
// Note: need to do the indication count and start timer first then do
// callback
- for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
- if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
- tcb.ind_count++;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
+ tcb.ind_count++;
+ }
+ }
+ } else {
+ for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
+ if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
+ tcb.ind_count++;
+ }
}
}
@@ -718,10 +727,19 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, ui
gatt_cl_complete.att_value = value;
gatt_cl_complete.cid = cid;
- for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
- if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
- conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
- (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status, &gatt_cl_complete);
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
+ conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status, &gatt_cl_complete);
+ }
+ }
+ } else {
+ for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
+ if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
+ conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status, &gatt_cl_complete);
+ }
}
}
@@ -759,10 +777,19 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, ui
gatt_cl_complete.att_value = value;
gatt_cl_complete.cid = cid;
- for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
- if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
- conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
- (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status, &gatt_cl_complete);
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
+ conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status, &gatt_cl_complete);
+ }
+ }
+ } else {
+ for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
+ if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
+ conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_cmpl_cb)(conn_id, event, encrypt_status, &gatt_cl_complete);
+ }
}
}
}
diff --git a/system/stack/gatt/gatt_int.h b/system/stack/gatt/gatt_int.h
index 998e401371..5ab2bf8454 100644
--- a/system/stack/gatt/gatt_int.h
+++ b/system/stack/gatt/gatt_int.h
@@ -43,6 +43,7 @@
#define GATT_GET_GATT_IF(conn_id) ((tGATT_IF)((uint8_t)(conn_id)))
#define GATT_TRANS_ID_MAX 0x0fffffff /* 4 MSB is reserved */
+#define GATT_CL_RCB_MAX 255 /* Maximum number of cl_rcb */
/* security action for GATT write and read request */
typedef enum : uint8_t {
@@ -228,6 +229,7 @@ typedef struct {
uint8_t op_code;
uint8_t status;
uint8_t cback_cnt[GATT_MAX_APPS];
+ std::unordered_map<tGATT_IF, uint8_t> cback_cnt_map;
uint16_t cid;
} tGATT_SR_CMD;
@@ -315,6 +317,7 @@ typedef struct {
alarm_t* conf_timer; /* peer confirm to indication timer */
uint8_t prep_cnt[GATT_MAX_APPS];
+ std::unordered_map<tGATT_IF, uint8_t> prep_cnt_map;
uint8_t ind_count;
std::deque<tGATT_CMD_Q> cl_cmd_q;
@@ -414,6 +417,9 @@ typedef struct {
fixed_queue_t* srv_chg_clt_q; /* service change clients queue */
tGATT_REG cl_rcb[GATT_MAX_APPS];
+ tGATT_IF next_gatt_if; /* potential next gatt if, should be greater than 0 */
+ std::unordered_map<tGATT_IF, std::unique_ptr<tGATT_REG>> cl_rcb_map;
+
/* list of connection link control blocks.
* Since clcbs are also keep in the channels (ATT and EATT) queues while
* processing, we want to make sure that references to elements are not
@@ -461,6 +467,7 @@ void gatt_set_err_rsp(bool enable, uint8_t req_op_code, uint8_t err_status);
/* from gatt_main.cc */
bool gatt_disconnect(tGATT_TCB* p_tcb);
+void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport);
bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr, tBT_TRANSPORT transport,
int8_t initiating_phys);
bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
diff --git a/system/stack/gatt/gatt_main.cc b/system/stack/gatt/gatt_main.cc
index 88ef13fe01..f8d6406610 100644
--- a/system/stack/gatt/gatt_main.cc
+++ b/system/stack/gatt/gatt_main.cc
@@ -113,6 +113,9 @@ void gatt_init(void) {
connection_manager::reset(true);
memset(&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));
+ // To catch a potential OOB.
+ gatt_cb.next_gatt_if = 40;
+
gatt_cb.sign_op_queue = fixed_queue_new(SIZE_MAX);
gatt_cb.srv_chg_clt_q = fixed_queue_new(SIZE_MAX);
/* First, register fixed L2CAP channel for ATT over BLE */
@@ -235,6 +238,39 @@ bool gatt_connect(const RawAddress& rem_bda, tGATT_TCB* p_tcb, tBT_TRANSPORT tra
uint8_t initiating_phys, tGATT_IF gatt_if) {
return gatt_connect(rem_bda, BLE_ADDR_PUBLIC, p_tcb, transport, initiating_phys, gatt_if);
}
+
+/*******************************************************************************
+ *
+ * Function gatt_cancel_connect
+ *
+ * Description This will remove device from allow list and cancel connection
+ *
+ * Parameter bd_addr: peer device address.
+ * transport: transport
+ *
+ *
+ ******************************************************************************/
+void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
+ /* This shall be call only when device is not connected */
+ log::debug("{}, transport {}", bd_addr, transport);
+
+ if (bluetooth::common::init_flags::use_unified_connection_manager_is_enabled()) {
+ // TODO(aryarahul): this might not be necessary now that the connection
+ // manager handles GATT client closure correctly in GATT_Deregister
+ bluetooth::connection::GetConnectionManager().stop_all_connections_to_device(
+ bluetooth::connection::ResolveRawAddress(bd_addr));
+ } else {
+ if (!connection_manager::direct_connect_remove(CONN_MGR_ID_L2CAP, bd_addr)) {
+ BTM_AcceptlistRemove(bd_addr);
+ log::info(
+ "GATT connection manager has no record but removed filter "
+ "acceptlist gatt_if:{} peer:{}",
+ static_cast<uint8_t>(CONN_MGR_ID_L2CAP), bd_addr);
+ }
+ }
+ gatt_cleanup_upon_disc(bd_addr, GATT_CONN_TERMINATE_LOCAL_HOST, transport);
+}
+
/*******************************************************************************
*
* Function gatt_disconnect
@@ -269,22 +305,7 @@ bool gatt_disconnect(tGATT_TCB* p_tcb) {
}
gatt_set_ch_state(p_tcb, GATT_CH_CLOSING);
} else {
- if (bluetooth::common::init_flags::use_unified_connection_manager_is_enabled()) {
- // TODO(aryarahul): this might not be necessary now that the connection
- // manager handles GATT client closure correctly in GATT_Deregister
- bluetooth::connection::GetConnectionManager().stop_all_connections_to_device(
- bluetooth::connection::ResolveRawAddress(p_tcb->peer_bda));
- } else {
- if (!connection_manager::direct_connect_remove(CONN_MGR_ID_L2CAP, p_tcb->peer_bda)) {
- BTM_AcceptlistRemove(p_tcb->peer_bda);
- log::info(
- "GATT connection manager has no record but removed filter "
- "acceptlist gatt_if:{} peer:{}",
- static_cast<uint8_t>(CONN_MGR_ID_L2CAP), p_tcb->peer_bda);
- }
- }
-
- gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_TERMINATE_LOCAL_HOST, p_tcb->transport);
+ gatt_cancel_connect(p_tcb->peer_bda, p_tcb->transport);
}
} else {
if ((ch_state == GATT_CH_OPEN) || (ch_state == GATT_CH_CFG)) {
@@ -607,13 +628,22 @@ static void gatt_channel_congestion(tGATT_TCB* p_tcb, bool congested) {
gatt_cl_send_next_cmd_inq(*p_tcb);
}
/* notifying all applications for the connection up event */
- for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
- if (p_reg->in_use) {
- if (p_reg->app_cb.p_congestion_cb) {
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use && p_reg->app_cb.p_congestion_cb) {
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
(*p_reg->app_cb.p_congestion_cb)(conn_id, congested);
}
}
+ } else {
+ for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
+ if (p_reg->in_use) {
+ if (p_reg->app_cb.p_congestion_cb) {
+ conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_congestion_cb)(conn_id, congested);
+ }
+ }
+ }
}
}
@@ -632,11 +662,20 @@ void gatt_notify_phy_updated(tHCI_STATUS status, uint16_t handle, uint8_t tx_phy
// TODO: Clean up this status conversion.
tGATT_STATUS gatt_status = static_cast<tGATT_STATUS>(status);
- for (int i = 0; i < GATT_MAX_APPS; i++) {
- tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
- if (p_reg->in_use && p_reg->app_cb.p_phy_update_cb) {
- uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
- (*p_reg->app_cb.p_phy_update_cb)(p_reg->gatt_if, conn_id, tx_phy, rx_phy, gatt_status);
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use && p_reg->app_cb.p_phy_update_cb) {
+ uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_phy_update_cb)(p_reg->gatt_if, conn_id, tx_phy, rx_phy, gatt_status);
+ }
+ }
+ } else {
+ for (int i = 0; i < GATT_MAX_APPS; i++) {
+ tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
+ if (p_reg->in_use && p_reg->app_cb.p_phy_update_cb) {
+ uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_phy_update_cb)(p_reg->gatt_if, conn_id, tx_phy, rx_phy, gatt_status);
+ }
}
}
}
@@ -649,12 +688,22 @@ void gatt_notify_conn_update(const RawAddress& remote, uint16_t interval, uint16
return;
}
- for (int i = 0; i < GATT_MAX_APPS; i++) {
- tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
- if (p_reg->in_use && p_reg->app_cb.p_conn_update_cb) {
- uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
- (*p_reg->app_cb.p_conn_update_cb)(p_reg->gatt_if, conn_id, interval, latency, timeout,
- static_cast<tGATT_STATUS>(status));
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use && p_reg->app_cb.p_conn_update_cb) {
+ uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_conn_update_cb)(p_reg->gatt_if, conn_id, interval, latency, timeout,
+ static_cast<tGATT_STATUS>(status));
+ }
+ }
+ } else {
+ for (int i = 0; i < GATT_MAX_APPS; i++) {
+ tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
+ if (p_reg->in_use && p_reg->app_cb.p_conn_update_cb) {
+ uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_conn_update_cb)(p_reg->gatt_if, conn_id, interval, latency, timeout,
+ static_cast<tGATT_STATUS>(status));
+ }
}
}
}
@@ -672,12 +721,22 @@ void gatt_notify_subrate_change(uint16_t handle, uint16_t subrate_factor, uint16
return;
}
- for (int i = 0; i < GATT_MAX_APPS; i++) {
- tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
- if (p_reg->in_use && p_reg->app_cb.p_subrate_chg_cb) {
- uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
- (*p_reg->app_cb.p_subrate_chg_cb)(p_reg->gatt_if, conn_id, subrate_factor, latency, cont_num,
- timeout, static_cast<tGATT_STATUS>(status));
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use && p_reg->app_cb.p_subrate_chg_cb) {
+ uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_subrate_chg_cb)(p_reg->gatt_if, conn_id, subrate_factor, latency,
+ cont_num, timeout, static_cast<tGATT_STATUS>(status));
+ }
+ }
+ } else {
+ for (int i = 0; i < GATT_MAX_APPS; i++) {
+ tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
+ if (p_reg->in_use && p_reg->app_cb.p_subrate_chg_cb) {
+ uint16_t conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_subrate_chg_cb)(p_reg->gatt_if, conn_id, subrate_factor, latency,
+ cont_num, timeout, static_cast<tGATT_STATUS>(status));
+ }
}
}
}
@@ -927,28 +986,56 @@ static void gatt_send_conn_cback(tGATT_TCB* p_tcb) {
}
/* notifying all applications for the connection up event */
- for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
- if (!p_reg->in_use) {
- continue;
- }
- if (apps.find(p_reg->gatt_if) != apps.end()) {
- gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, true);
- }
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (!p_reg->in_use) {
+ continue;
+ }
- if (com::android::bluetooth::flags::gatt_reconnect_on_bt_on_fix()) {
- if (p_reg->direct_connect_request.count(p_tcb->peer_bda) > 0) {
+ if (apps.find(p_reg->gatt_if) != apps.end()) {
gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, true);
- log::info("Removing device {} from the direct connect list of gatt_if {}", p_tcb->peer_bda,
- p_reg->gatt_if);
- p_reg->direct_connect_request.erase(p_tcb->peer_bda);
+ }
+
+ if (com::android::bluetooth::flags::gatt_reconnect_on_bt_on_fix()) {
+ if (p_reg->direct_connect_request.count(p_tcb->peer_bda) > 0) {
+ gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, true);
+ log::info("Removing device {} from the direct connect list of gatt_if {}",
+ p_tcb->peer_bda, p_reg->gatt_if);
+ p_reg->direct_connect_request.erase(p_tcb->peer_bda);
+ }
+ }
+
+ if (p_reg->app_cb.p_conn_cb) {
+ conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, kGattConnected,
+ GATT_CONN_OK, p_tcb->transport);
}
}
+ } else {
+ for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
+ if (!p_reg->in_use) {
+ continue;
+ }
- if (p_reg->app_cb.p_conn_cb) {
- conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
- (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, kGattConnected,
- GATT_CONN_OK, p_tcb->transport);
+ if (apps.find(p_reg->gatt_if) != apps.end()) {
+ gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, true);
+ }
+
+ if (com::android::bluetooth::flags::gatt_reconnect_on_bt_on_fix()) {
+ if (p_reg->direct_connect_request.count(p_tcb->peer_bda) > 0) {
+ gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, true);
+ log::info("Removing device {} from the direct connect list of gatt_if {}",
+ p_tcb->peer_bda, p_reg->gatt_if);
+ p_reg->direct_connect_request.erase(p_tcb->peer_bda);
+ }
+ }
+
+ if (p_reg->app_cb.p_conn_cb) {
+ conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
+ (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, kGattConnected,
+ GATT_CONN_OK, p_tcb->transport);
+ }
}
}
diff --git a/system/stack/gatt/gatt_sr.cc b/system/stack/gatt/gatt_sr.cc
index 6506ec47fa..c85949f02e 100644
--- a/system/stack/gatt/gatt_sr.cc
+++ b/system/stack/gatt/gatt_sr.cc
@@ -23,6 +23,7 @@
******************************************************************************/
#include <bluetooth/log.h>
+#include <com_android_bluetooth_flags.h>
#include <string.h>
#include <algorithm>
@@ -208,7 +209,7 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) {
len = std::min((size_t)p_rsp->attr_value.len, mtu - total_len);
- if (len == 0) {
+ if (total_len == mtu && p_rsp->attr_value.len > 0) {
log::verbose("Buffer space not enough for this data item, skipping");
break;
}
@@ -401,14 +402,26 @@ void gatt_process_exec_write_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code,
trans_id = gatt_sr_enqueue_cmd(tcb, cid, op_code, 0);
gatt_sr_copy_prep_cnt_to_cback_cnt(tcb);
- for (i = 0; i < GATT_MAX_APPS; i++) {
- if (tcb.prep_cnt[i]) {
- gatt_if = (tGATT_IF)(i + 1);
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ auto prep_cnt_it = tcb.prep_cnt_map.begin();
+ while (prep_cnt_it != tcb.prep_cnt_map.end()) {
+ gatt_if = i;
conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, gatt_if);
tGATTS_DATA gatts_data;
gatts_data.exec_write = flag;
gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_WRITE_EXEC, &gatts_data);
- tcb.prep_cnt[i] = 0;
+ prep_cnt_it = tcb.prep_cnt_map.erase(prep_cnt_it);
+ }
+ } else {
+ for (i = 0; i < GATT_MAX_APPS; i++) {
+ if (tcb.prep_cnt[i]) {
+ gatt_if = (tGATT_IF)(i + 1);
+ conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, gatt_if);
+ tGATTS_DATA gatts_data;
+ gatts_data.exec_write = flag;
+ gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_WRITE_EXEC, &gatts_data);
+ tcb.prep_cnt[i] = 0;
+ }
}
}
} else /* nothing needs to be executed , send response now */
@@ -865,12 +878,21 @@ static void gatts_process_mtu_req(tGATT_TCB& tcb, uint16_t cid, uint16_t len, ui
tGATTS_DATA gatts_data;
gatts_data.mtu = tcb.payload_size;
- /* Notify all registered application with new MTU size. Us a transaction ID */
- /* of 0, as no response is allowed from application */
- for (int i = 0; i < GATT_MAX_APPS; i++) {
- if (gatt_cb.cl_rcb[i].in_use) {
- uint16_t conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, gatt_cb.cl_rcb[i].gatt_if);
- gatt_sr_send_req_callback(conn_id, 0, GATTS_REQ_TYPE_MTU, &gatts_data);
+ /* Notify all registered application with new MTU size. Use a transaction ID */
+ /* of 0, as no response is allowed from applications */
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use) {
+ uint16_t conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, p_reg->gatt_if);
+ gatt_sr_send_req_callback(conn_id, 0, GATTS_REQ_TYPE_MTU, &gatts_data);
+ }
+ }
+ } else {
+ for (int i = 0; i < GATT_MAX_APPS; i++) {
+ if (gatt_cb.cl_rcb[i].in_use) {
+ uint16_t conn_id = GATT_CREATE_CONN_ID(tcb.tcb_idx, gatt_cb.cl_rcb[i].gatt_if);
+ gatt_sr_send_req_callback(conn_id, 0, GATTS_REQ_TYPE_MTU, &gatts_data);
+ }
}
}
}
diff --git a/system/stack/gatt/gatt_utils.cc b/system/stack/gatt/gatt_utils.cc
index f974a6acfa..ef3b888e04 100644
--- a/system/stack/gatt/gatt_utils.cc
+++ b/system/stack/gatt/gatt_utils.cc
@@ -1034,14 +1034,22 @@ tGATT_REG* gatt_get_regcb(tGATT_IF gatt_if) {
uint8_t ii = (uint8_t)gatt_if;
tGATT_REG* p_reg = NULL;
- if (ii < 1 || ii > GATT_MAX_APPS) {
- log::warn("gatt_if out of range = {}", ii);
- return NULL;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ auto it = gatt_cb.cl_rcb_map.find(gatt_if);
+ if (it == gatt_cb.cl_rcb_map.end()) {
+ log::warn("unknown gatt_if = {}", ii);
+ return NULL;
+ }
+ p_reg = it->second.get();
+ } else {
+ // Index for cl_rcb is always 1 less than gatt_if.
+ if (ii < 1 || ii > GATT_MAX_APPS) {
+ log::warn("gatt_if out of range = {}", ii);
+ return NULL;
+ }
+ p_reg = &gatt_cb.cl_rcb[ii - 1];
}
- // Index for cl_rcb is always 1 less than gatt_if.
- p_reg = &gatt_cb.cl_rcb[ii - 1];
-
if (!p_reg->in_use) {
log::warn("gatt_if found but not in use.");
return NULL;
@@ -1315,9 +1323,15 @@ tGATT_TCB* gatt_find_tcb_by_cid(uint16_t lcid) {
}
void gatt_sr_copy_prep_cnt_to_cback_cnt(tGATT_TCB& tcb) {
- for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
- if (tcb.prep_cnt[i]) {
- tcb.sr_cmd.cback_cnt[i] = 1;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, cnt] : tcb.prep_cnt_map) {
+ tcb.sr_cmd.cback_cnt_map[i] = 1;
+ }
+ } else {
+ for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+ if (tcb.prep_cnt[i]) {
+ tcb.sr_cmd.cback_cnt[i] = 1;
+ }
}
}
}
@@ -1350,12 +1364,16 @@ tGATT_SR_CMD* gatt_sr_get_cmd_by_trans_id(tGATT_TCB* p_tcb, uint32_t trans_id) {
*
******************************************************************************/
bool gatt_sr_is_cback_cnt_zero(tGATT_TCB& tcb) {
- for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
- if (tcb.sr_cmd.cback_cnt[i]) {
- return false;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ return tcb.sr_cmd.cback_cnt_map.empty();
+ } else {
+ for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+ if (tcb.sr_cmd.cback_cnt[i]) {
+ return false;
+ }
}
+ return true;
}
- return true;
}
/*******************************************************************************
@@ -1368,12 +1386,16 @@ bool gatt_sr_is_cback_cnt_zero(tGATT_TCB& tcb) {
*
******************************************************************************/
bool gatt_sr_is_prep_cnt_zero(tGATT_TCB& tcb) {
- for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
- if (tcb.prep_cnt[i]) {
- return false;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ return tcb.prep_cnt_map.empty();
+ } else {
+ for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+ if (tcb.prep_cnt[i]) {
+ return false;
+ }
}
+ return true;
}
- return true;
}
/*******************************************************************************
@@ -1386,16 +1408,30 @@ bool gatt_sr_is_prep_cnt_zero(tGATT_TCB& tcb) {
*
******************************************************************************/
void gatt_sr_reset_cback_cnt(tGATT_TCB& tcb, uint16_t cid) {
- for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
if (cid == tcb.att_lcid) {
- tcb.sr_cmd.cback_cnt[i] = 0;
+ tcb.sr_cmd.cback_cnt_map.clear();
} else {
EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
if (channel == nullptr) {
log::warn("{}, cid 0x{:02x} already disconnected", tcb.peer_bda, cid);
return;
}
- channel->server_outstanding_cmd_.cback_cnt[i] = 0;
+ channel->server_outstanding_cmd_.cback_cnt_map.clear();
+ }
+ } else {
+ for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+ if (cid == tcb.att_lcid) {
+ tcb.sr_cmd.cback_cnt[i] = 0;
+ } else {
+ EattChannel* channel =
+ EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid);
+ if (channel == nullptr) {
+ log::warn("{}, cid 0x{:02x} already disconnected", tcb.peer_bda, cid);
+ return;
+ }
+ channel->server_outstanding_cmd_.cback_cnt[i] = 0;
+ }
}
}
}
@@ -1482,11 +1518,25 @@ void gatt_sr_update_cback_cnt(tGATT_TCB& tcb, uint16_t cid, tGATT_IF gatt_if, bo
if (is_reset_first) {
gatt_sr_reset_cback_cnt(tcb, cid);
}
- if (is_inc) {
- sr_cmd_p->cback_cnt[idx]++;
+
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ if (is_inc) {
+ sr_cmd_p->cback_cnt_map[idx]++;
+ } else {
+ auto cback_cnt_it = sr_cmd_p->cback_cnt_map.find(idx);
+ if (cback_cnt_it != sr_cmd_p->cback_cnt_map.end()) {
+ if ((--cback_cnt_it->second) <= 0) {
+ sr_cmd_p->cback_cnt_map.erase(cback_cnt_it);
+ }
+ }
+ }
} else {
- if (sr_cmd_p->cback_cnt[idx]) {
- sr_cmd_p->cback_cnt[idx]--;
+ if (is_inc) {
+ sr_cmd_p->cback_cnt[idx]++;
+ } else {
+ if (sr_cmd_p->cback_cnt[idx]) {
+ sr_cmd_p->cback_cnt[idx]--;
+ }
}
}
}
@@ -1509,13 +1559,42 @@ void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if, bool is_inc, bool
if (is_reset_first) {
gatt_sr_reset_prep_cnt(tcb);
}
- if (is_inc) {
- tcb.prep_cnt[idx]++;
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ if (is_inc) {
+ tcb.prep_cnt_map[gatt_if]++;
+ } else {
+ auto prep_cnt_i = tcb.prep_cnt_map.find(gatt_if);
+ if (prep_cnt_i != tcb.prep_cnt_map.end()) {
+ if (--prep_cnt_i->second <= 0) {
+ tcb.prep_cnt_map.erase(prep_cnt_i);
+ }
+ }
+ }
} else {
- if (tcb.prep_cnt[idx]) {
- tcb.prep_cnt[idx]--;
+ if (is_inc) {
+ tcb.prep_cnt[idx]++;
+ } else {
+ if (tcb.prep_cnt[idx]) {
+ tcb.prep_cnt[idx]--;
+ }
+ }
+ }
+}
+
+static bool gatt_is_anybody_interested_in_connection(const RawAddress& bda) {
+ if (connection_manager::is_background_connection(bda)) {
+ log::debug("{} is in background connection", bda);
+ return true;
+ }
+
+ for (size_t i = 1; i <= GATT_MAX_APPS; i++) {
+ tGATT_REG* p_reg = &gatt_cb.cl_rcb[i - 1];
+ if (p_reg->in_use && p_reg->direct_connect_request.count(bda) > 0) {
+ log::debug("gatt_if {} interested in connection to {}", i, bda);
+ return true;
}
}
+ return false;
}
/** Cancel LE Create Connection request */
@@ -1535,6 +1614,9 @@ bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) {
log::info("Removing {} from direct list", bda);
p_reg->direct_connect_request.erase(bda);
}
+ if (!gatt_is_anybody_interested_in_connection(bda)) {
+ gatt_cancel_connect(bda, static_cast<tBT_TRANSPORT>(BT_TRANSPORT_LE));
+ }
return true;
}
@@ -1749,20 +1831,39 @@ static void gatt_le_disconnect_complete_notify_user(const RawAddress& bda,
tBT_TRANSPORT transport) {
tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, transport);
- for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
- tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
- if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
- uint16_t conn_id =
- p_tcb ? GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if) : GATT_INVALID_CONN_ID;
- (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, kGattDisconnected, reason,
- transport);
+ if (com::android::bluetooth::flags::gatt_client_dynamic_allocation()) {
+ for (auto& [i, p_reg] : gatt_cb.cl_rcb_map) {
+ if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
+ uint16_t conn_id =
+ p_tcb ? GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if) : GATT_INVALID_CONN_ID;
+ (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, kGattDisconnected, reason,
+ transport);
+ }
+
+ if (com::android::bluetooth::flags::gatt_reconnect_on_bt_on_fix()) {
+ if (p_reg->direct_connect_request.count(bda) > 0) {
+ log::info("Removing device {} from the direct connect list of gatt_if {}", bda,
+ p_reg->gatt_if);
+ p_reg->direct_connect_request.erase(bda);
+ }
+ }
}
+ } else {
+ for (uint8_t i = 0; i < GATT_MAX_APPS; i++) {
+ tGATT_REG* p_reg = &gatt_cb.cl_rcb[i];
+ if (p_reg->in_use && p_reg->app_cb.p_conn_cb) {
+ uint16_t conn_id =
+ p_tcb ? GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if) : GATT_INVALID_CONN_ID;
+ (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, bda, conn_id, kGattDisconnected, reason,
+ transport);
+ }
- if (com::android::bluetooth::flags::gatt_reconnect_on_bt_on_fix()) {
- if (p_reg->direct_connect_request.count(bda) > 0) {
- log::info("Removing device {} from the direct connect list of gatt_if {}", bda,
- p_reg->gatt_if);
- p_reg->direct_connect_request.erase(bda);
+ if (com::android::bluetooth::flags::gatt_reconnect_on_bt_on_fix()) {
+ if (p_reg->direct_connect_request.count(bda) > 0) {
+ log::info("Removing device {} from the direct connect list of gatt_if {}", bda,
+ p_reg->gatt_if);
+ p_reg->direct_connect_request.erase(bda);
+ }
}
}
}
diff --git a/system/stack/hid/hidh_api.cc b/system/stack/hid/hidh_api.cc
index 7090a837dc..d0df9997bf 100644
--- a/system/stack/hid/hidh_api.cc
+++ b/system/stack/hid/hidh_api.cc
@@ -110,7 +110,7 @@ void hidh_get_str_attr(tSDP_DISC_REC* p_rec, uint16_t attr_id, uint16_t max_len,
}
}
-static void hidh_search_callback(const RawAddress& /* bd_addr */, tSDP_RESULT sdp_result) {
+static void hidh_search_callback(const RawAddress& bd_addr, tSDP_RESULT sdp_result) {
tSDP_DISCOVERY_DB* p_db = hh_cb.p_sdp_db;
tSDP_DISC_REC* p_rec;
tSDP_DISC_ATTR *p_attr, *p_subattr1, *p_subattr2, *p_repdesc;
@@ -120,14 +120,14 @@ static void hidh_search_callback(const RawAddress& /* bd_addr */, tSDP_RESULT sd
hh_cb.sdp_busy = false;
if (sdp_result != SDP_SUCCESS) {
- hh_cb.sdp_cback(sdp_result, 0, NULL);
+ hh_cb.sdp_cback(bd_addr, sdp_result, 0, NULL);
return;
}
Uuid hid_uuid = Uuid::From16Bit(UUID_SERVCLASS_HUMAN_INTERFACE);
p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceUUIDInDb(p_db, hid_uuid, NULL);
if (p_rec == NULL) {
- hh_cb.sdp_cback(HID_SDP_NO_SERV_UUID, 0, NULL);
+ hh_cb.sdp_cback(bd_addr, HID_SDP_NO_SERV_UUID, 0, NULL);
return;
}
@@ -142,7 +142,7 @@ static void hidh_search_callback(const RawAddress& /* bd_addr */, tSDP_RESULT sd
((p_subattr2 = p_subattr1->attr_value.v.p_sub_attr) == NULL) ||
((p_repdesc = p_subattr2->p_next_attr) == NULL) ||
(SDP_DISC_ATTR_TYPE(p_repdesc->attr_len_type) != TEXT_STR_DESC_TYPE)) {
- hh_cb.sdp_cback(HID_SDP_MANDATORY_MISSING, 0, NULL);
+ hh_cb.sdp_cback(bd_addr, HID_SDP_MANDATORY_MISSING, 0, NULL);
return;
}
@@ -255,7 +255,7 @@ static void hidh_search_callback(const RawAddress& /* bd_addr */, tSDP_RESULT sd
}
hh_cb.sdp_rec.p_sdp_layer_rec = p_rec;
- hh_cb.sdp_cback(SDP_SUCCESS, attr_mask, &hh_cb.sdp_rec);
+ hh_cb.sdp_cback(bd_addr, SDP_SUCCESS, attr_mask, &hh_cb.sdp_rec);
}
/*******************************************************************************
diff --git a/system/stack/include/ais_api.h b/system/stack/include/ais_api.h
new file mode 100644
index 0000000000..41dad8242b
--- /dev/null
+++ b/system/stack/include/ais_api.h
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef SYSTEM_STACK_INCLUDE_AIS_API_H_
+#define SYSTEM_STACK_INCLUDE_AIS_API_H_
+
+#include "types/bluetooth/uuid.h"
+
+#define ANDROID_INFORMATION_SERVICE_UUID_STRING "e73e0001-ef1b-4e74-8291-2e4f3164f3b5"
+/* Android Information Service characteristic */
+#define GATT_UUID_AIS_API_LEVEL_STRING "e73e0002-ef1b-4e74-8291-2e4f3164f3b5"
+
+extern const bluetooth::Uuid ANDROID_INFORMATION_SERVICE_UUID;
+extern const bluetooth::Uuid GATT_UUID_AIS_API_LEVEL;
+
+/*******************************************************************************
+ *
+ * Function AIS_Init
+ *
+ * Description Initializes the control blocks used by AIS.
+ * This routine should not be called except once per
+ * stack invocation.
+ *
+ * Returns Nothing
+ *
+ ******************************************************************************/
+void AIS_Init(void);
+
+#endif // SYSTEM_STACK_INCLUDE_AIS_API_H_
diff --git a/system/stack/include/hidh_api.h b/system/stack/include/hidh_api.h
index da7c43356b..f8d55775ce 100644
--- a/system/stack/include/hidh_api.h
+++ b/system/stack/include/hidh_api.h
@@ -47,8 +47,8 @@
* Type Definitions
****************************************************************************/
-typedef void(tHID_HOST_SDP_CALLBACK)(tSDP_STATUS result, uint16_t attr_mask,
- tHID_DEV_SDP_INFO* sdp_rec);
+typedef void(tHID_HOST_SDP_CALLBACK)(const RawAddress& bd_add, tSDP_STATUS result,
+ uint16_t attr_mask, tHID_DEV_SDP_INFO* sdp_rec);
/* HID-HOST returns the events in the following table to the application via
* tHID_HOST_DEV_CALLBACK
diff --git a/system/stack/include/rfcdefs.h b/system/stack/include/rfcdefs.h
index 7c5249c6ec..c778492a91 100644
--- a/system/stack/include/rfcdefs.h
+++ b/system/stack/include/rfcdefs.h
@@ -22,19 +22,35 @@
*
****************************************************************************/
-#ifndef RFCDEFS_H
-#define RFCDEFS_H
+#pragma once
+
/*
* Server Channel Numbers (SCN) range between 1 and 30, inclusive
*/
#define RFCOMM_MAX_SCN 30
/*
+ * The maximum number of ports supported.
+ */
+#define MAX_RFC_PORTS 30
+
+/*
+ * The maximum simultaneous links to different devices.
+ */
+#define MAX_BD_CONNECTIONS 16
+
+/*
* If nothing is negotiated MTU should be 127
*/
#define RFCOMM_DEFAULT_MTU 127
/*
+ * RFCOMM buffer sizes
+ */
+#define RFCOMM_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE // command packet buffer size
+#define RFCOMM_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE // data packet buffer size
+
+/*
* Define used by RFCOMM TS frame types
*/
#define RFCOMM_SABME 0x2F // Start Asynchronous Balanced Mode (startup command)
@@ -235,4 +251,39 @@
#define RFCOMM_MX_RLS 0x50
#define RFCOMM_MX_RLS_LEN 2
-#endif
+
+/*
+ * Define RFCOMM port rx and tx queue watermarks
+ */
+// MTU size used to calculate watermark levels
+#define BTA_RFC_MTU_SIZE (L2CAP_MTU_SIZE - L2CAP_MIN_OFFSET - RFCOMM_DATA_OVERHEAD)
+
+// The port receive queue low watermark level, in number of buffers.
+#define PORT_RX_BUF_LOW_WM 4
+
+// The port receive queue high watermark level, in number of buffers.
+#define PORT_RX_BUF_HIGH_WM 10
+
+// The port receive queue critical watermark level, in number of buffers.
+#define PORT_RX_BUF_CRITICAL_WM 15
+
+// The port receive queue low watermark level, in bytes.
+#define PORT_RX_LOW_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_LOW_WM)
+
+// The port receive queue high watermark level, in bytes.
+#define PORT_RX_HIGH_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_HIGH_WM)
+
+// The port receive queue critical watermark level, in bytes.
+#define PORT_RX_CRITICAL_WM (BTA_RFC_MTU_SIZE * PORT_RX_BUF_CRITICAL_WM)
+
+// The port transmit queue high watermark level, in number of buffers.
+#define PORT_TX_BUF_HIGH_WM 10
+
+// The port transmit queue high watermark level, in number of buffers.
+#define PORT_TX_BUF_CRITICAL_WM 15
+
+// The port transmit queue high watermark level, in bytes.
+#define PORT_TX_HIGH_WM (BTA_RFC_MTU_SIZE * PORT_TX_BUF_HIGH_WM)
+
+// The port transmit queue critical watermark level, in bytes.
+#define PORT_TX_CRITICAL_WM (BTA_RFC_MTU_SIZE * PORT_TX_BUF_CRITICAL_WM)
diff --git a/system/stack/rfcomm/port_api.cc b/system/stack/rfcomm/port_api.cc
index 1eed863a84..b8a8e35b11 100644
--- a/system/stack/rfcomm/port_api.cc
+++ b/system/stack/rfcomm/port_api.cc
@@ -31,7 +31,6 @@
#include <cstdint>
-#include "internal_include/bt_target.h"
#include "internal_include/bt_trace.h"
#include "os/logging/log_adapter.h"
#include "osi/include/allocator.h"
@@ -40,6 +39,7 @@
#include "stack/include/bt_types.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/btm_log_history.h"
+#include "stack/include/rfcdefs.h"
#include "stack/rfcomm/rfc_int.h"
#include "types/raw_address.h"
@@ -925,9 +925,7 @@ int PORT_WriteDataCO(uint16_t handle, int* p_len) {
// if(recv(fd, (uint8_t *)(p_buf + 1) + p_buf->offset + p_buf->len,
// available, 0) != available)
if (!p_port->p_data_co_callback(handle, (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len,
- available, DATA_CO_CALLBACK_TYPE_OUTGOING))
-
- {
+ available, DATA_CO_CALLBACK_TYPE_OUTGOING)) {
log::error("p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, available:{}",
available);
mutex_global_unlock();
diff --git a/system/stack/rfcomm/rfc_ts_frames.cc b/system/stack/rfcomm/rfc_ts_frames.cc
index e73bab5cf6..3a44afd061 100644
--- a/system/stack/rfcomm/rfc_ts_frames.cc
+++ b/system/stack/rfcomm/rfc_ts_frames.cc
@@ -28,7 +28,6 @@
#include <cstdint>
-#include "internal_include/bt_target.h"
#include "os/logging/log_adapter.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/test/gatt/gatt_sr_test.cc b/system/stack/test/gatt/gatt_sr_test.cc
index 110c1291c6..29e83725bc 100644
--- a/system/stack/test/gatt/gatt_sr_test.cc
+++ b/system/stack/test/gatt/gatt_sr_test.cc
@@ -73,6 +73,7 @@ tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_msg) { ret
void gatt_act_discovery(tGATT_CLCB* p_clcb) {}
bool gatt_disconnect(tGATT_TCB* p_tcb) { return false; }
+void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport) {}
tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) { return GATT_CH_CLOSE; }
tGATT_STATUS gatts_db_read_attr_value_by_type(tGATT_TCB& tcb, uint16_t cid, tGATT_SVC_DB* p_db,
uint8_t op_code, BT_HDR* p_rsp, uint16_t s_handle,
diff --git a/system/stack/test/gatt/mock_gatt_utils_ref.cc b/system/stack/test/gatt/mock_gatt_utils_ref.cc
index b4310ccac1..cab85bcfa6 100644
--- a/system/stack/test/gatt/mock_gatt_utils_ref.cc
+++ b/system/stack/test/gatt/mock_gatt_utils_ref.cc
@@ -50,6 +50,7 @@ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb, bool is_a
bool check_acl_link) {}
void gatts_proc_srv_chg_ind_ack(tGATT_TCB) {}
bool gatt_disconnect(tGATT_TCB* p_tcb) { return false; }
+void gatt_cancel_connect(const RawAddress& bd_addr, tBT_TRANSPORT transport) {}
tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) { return GATT_CH_CLOSE; }
void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) {}
diff --git a/system/test/mock/mock_bta_hh_api.cc b/system/test/mock/mock_bta_hh_api.cc
index e201324175..0eecdc6d67 100644
--- a/system/test/mock/mock_bta_hh_api.cc
+++ b/system/test/mock/mock_bta_hh_api.cc
@@ -72,3 +72,4 @@ void BTA_HhSetReport(uint8_t /* dev_handle */, tBTA_HH_RPT_TYPE /* r_type */,
BT_HDR* /* p_data */) {
inc_func_call_count(__func__);
}
+void BTA_HhDump(int /* fd */) { inc_func_call_count(__func__); }
diff --git a/system/test/mock/mock_bta_hh_utils.cc b/system/test/mock/mock_bta_hh_utils.cc
index b48524f4fb..e45da05966 100644
--- a/system/test/mock/mock_bta_hh_utils.cc
+++ b/system/test/mock/mock_bta_hh_utils.cc
@@ -38,7 +38,6 @@ namespace bta_hh_utils {
struct bta_hh_add_device_to_list bta_hh_add_device_to_list;
struct bta_hh_clean_up_kdev bta_hh_clean_up_kdev;
struct bta_hh_cleanup_disable bta_hh_cleanup_disable;
-struct bta_hh_dev_handle_to_cb_idx bta_hh_dev_handle_to_cb_idx;
struct bta_hh_find_cb bta_hh_find_cb;
struct bta_hh_get_cb bta_hh_get_cb;
struct bta_hh_read_ssr_param bta_hh_read_ssr_param;
@@ -67,11 +66,7 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status) {
inc_func_call_count(__func__);
test::mock::bta_hh_utils::bta_hh_cleanup_disable(status);
}
-uint8_t bta_hh_dev_handle_to_cb_idx(uint8_t dev_handle) {
- inc_func_call_count(__func__);
- return test::mock::bta_hh_utils::bta_hh_dev_handle_to_cb_idx(dev_handle);
-}
-uint8_t bta_hh_find_cb(const tAclLinkSpec& link_spec) {
+tBTA_HH_DEV_CB* bta_hh_find_cb(const tAclLinkSpec& link_spec) {
inc_func_call_count(__func__);
return test::mock::bta_hh_utils::bta_hh_find_cb(link_spec);
}
diff --git a/system/test/mock/mock_bta_hh_utils.h b/system/test/mock/mock_bta_hh_utils.h
index 2e587af1dd..a46d616732 100644
--- a/system/test/mock/mock_bta_hh_utils.h
+++ b/system/test/mock/mock_bta_hh_utils.h
@@ -73,25 +73,14 @@ struct bta_hh_cleanup_disable {
};
extern struct bta_hh_cleanup_disable bta_hh_cleanup_disable;
-// Name: bta_hh_dev_handle_to_cb_idx
-// Params: uint8_t dev_handle
-// Return: uint8_t
-struct bta_hh_dev_handle_to_cb_idx {
- uint8_t return_value{0};
- std::function<uint8_t(uint8_t dev_handle)> body{
- [this](uint8_t /* dev_handle */) { return return_value; }};
- uint8_t operator()(uint8_t dev_handle) { return body(dev_handle); }
-};
-extern struct bta_hh_dev_handle_to_cb_idx bta_hh_dev_handle_to_cb_idx;
-
// Name: bta_hh_find_cb
// Params: const tAclLinkSpec& link_spec
// Return: uint8_t
struct bta_hh_find_cb {
- uint8_t return_value{0};
- std::function<uint8_t(const tAclLinkSpec& link_spec)> body{
+ tBTA_HH_DEV_CB* return_value{nullptr};
+ std::function<tBTA_HH_DEV_CB*(const tAclLinkSpec& link_spec)> body{
[this](const tAclLinkSpec& /* link_spec */) { return return_value; }};
- uint8_t operator()(const tAclLinkSpec& link_spec) { return body(link_spec); }
+ tBTA_HH_DEV_CB* operator()(const tAclLinkSpec& link_spec) { return body(link_spec); }
};
extern struct bta_hh_find_cb bta_hh_find_cb;
diff --git a/system/test/mock/mock_stack_ais_ble.cc b/system/test/mock/mock_stack_ais_ble.cc
new file mode 100644
index 0000000000..29630207b4
--- /dev/null
+++ b/system/test/mock/mock_stack_ais_ble.cc
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stack/include/ais_api.h"
+#include "test/common/mock_functions.h"
+
+void AIS_Init(void) { inc_func_call_count(__func__); }
diff --git a/system/test/mock/mock_stack_gatt_main.cc b/system/test/mock/mock_stack_gatt_main.cc
index d59a56f304..b6476d0e4b 100644
--- a/system/test/mock/mock_stack_gatt_main.cc
+++ b/system/test/mock/mock_stack_gatt_main.cc
@@ -38,6 +38,9 @@ bool gatt_connect(const RawAddress& /* rem_bda */, tGATT_TCB* /* p_tcb */,
inc_func_call_count(__func__);
return false;
}
+void gatt_cancel_connect(const RawAddress& /* bd_addr */, tBT_TRANSPORT /* transport*/) {
+ inc_func_call_count(__func__);
+}
bool gatt_disconnect(tGATT_TCB* /* p_tcb */) {
inc_func_call_count(__func__);
return false;