Merge changes Iddbd2a14,I2556e784 into main
* changes:
Add TaskType to ScheduleInfo.
Add enter garage mode bootup reason.
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 2a8e58f..baaa55f 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -32,6 +32,7 @@
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioGainConfig;
+using aidl::android::media::audio::common::AudioInputFlags;
using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioOutputFlags;
using aidl::android::media::audio::common::AudioPort;
@@ -321,20 +322,25 @@
//
// Mix ports:
// * "r_submix output", maximum 10 opened streams, maximum 10 active streams
-// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
// * "r_submix input", maximum 10 opened streams, maximum 10 active streams
-// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
+// * "r_submix output direct", DIRECT|IEC958_NONAUDIO, 1 max open, 1 max active
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
+// * "r_submix input direct", DIRECT, 1 max open, 1 max active
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
+
//
// Routes:
-// "r_submix output" -> "Remote Submix Out"
-// "Remote Submix In" -> "r_submix input"
+// "r_submix output", "r_submix output direct" -> "Remote Submix Out"
+// "Remote Submix In" -> "r_submix input", "r_submix input direct"
//
std::unique_ptr<Configuration> getRSubmixConfiguration() {
static const Configuration configuration = []() {
Configuration c;
const std::vector<AudioProfile> remoteSubmixPcmAudioProfiles{
createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO},
- {8000, 11025, 16000, 32000, 44100, 48000})};
+ {8000, 11025, 16000, 32000, 44100, 48000, 192000})};
// Device ports
@@ -359,13 +365,41 @@
rsubmixOutMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixOutMix);
+ // Adding a DIRECT flag to rsubmixInMix breaks the mixer paths, so we need separate
+ // non direct and direct paths. It is added because for IEC61937 encapsulated over PCM, we
+ // need the DIRECT and IEC958_NONAUDIO flags as AudioFlinger adds them.
+ AudioPort rsubmixOutDirectMix =
+ createPort(c.nextPortId++, "r_submix output direct",
+ makeBitPositionFlagMask({
+ AudioOutputFlags::DIRECT,
+ AudioOutputFlags::IEC958_NONAUDIO}),
+ false /* isInput */,
+ createPortMixExt(1 /* maxOpenStreamCount */,
+ 1 /* maxActiveStreamCount */));
+ rsubmixOutDirectMix.profiles = remoteSubmixPcmAudioProfiles;
+ c.ports.push_back(rsubmixOutDirectMix);
+
AudioPort rsubmixInMix =
createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(10, 10));
rsubmixInMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixInMix);
- c.routes.push_back(createRoute({rsubmixOutMix}, rsubmixOutDevice));
+ // Adding a DIRECT flag to rsubmixInMix breaks the capture paths, so we need separate
+ // non direct and direct paths. It is added because for IEC61937 encapsulated over PCM, we
+ // need the DIRECT flag for the capability so AudioFlinger can find a DIRECT input match.
+ AudioPort rsubmixInDirectMix =
+ createPort(c.nextPortId++, "r_submix input direct",
+ makeBitPositionFlagMask({AudioInputFlags::DIRECT}),
+ true /* isInput */,
+ createPortMixExt(1 /* maxOpenStreamCount */,
+ 1 /* maxActiveStreamCount */));
+ rsubmixInDirectMix.profiles = remoteSubmixPcmAudioProfiles;
+ c.ports.push_back(rsubmixInDirectMix);
+
+ c.routes.push_back(createRoute(
+ {rsubmixOutMix, rsubmixOutDirectMix}, rsubmixOutDevice));
c.routes.push_back(createRoute({rsubmixInDevice}, rsubmixInMix));
+ c.routes.push_back(createRoute({rsubmixInDevice}, rsubmixInDirectMix));
return c;
}();
diff --git a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
index 2f42889..f3965ba 100644
--- a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
@@ -27,6 +27,7 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioOffloadInfo;
using aidl::android::media::audio::common::AudioPort;
using aidl::android::media::audio::common::AudioPortConfig;
@@ -47,6 +48,10 @@
ndk::ScopedAStatus ModuleRemoteSubmix::createInputStream(
StreamContext&& context, const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) {
+ if (context.getFormat().type != AudioFormatType::PCM) {
+ LOG(DEBUG) << __func__ << ": not supported for format " << context.getFormat().toString();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
return createStreamInstance<StreamInRemoteSubmix>(result, std::move(context), sinkMetadata,
microphones);
}
@@ -54,6 +59,10 @@
ndk::ScopedAStatus ModuleRemoteSubmix::createOutputStream(
StreamContext&& context, const SourceMetadata& sourceMetadata,
const std::optional<AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) {
+ if (context.getFormat().type != AudioFormatType::PCM) {
+ LOG(DEBUG) << __func__ << ": not supported for format " << context.getFormat().toString();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
return createStreamInstance<StreamOutRemoteSubmix>(result, std::move(context), sourceMetadata,
offloadInfo);
}
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index ba44e07..a8effcb 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -125,6 +125,7 @@
{VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HW_KEY_INPUT, VehiclePropertyAccess::READ},
{VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyAccess::READ},
{VehicleProperty::HW_MOTION_INPUT, VehiclePropertyAccess::READ},
@@ -199,6 +200,12 @@
{VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_POSITION, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyAccess::READ},
+ {VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyAccess::READ},
{VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess::READ},
@@ -293,6 +300,8 @@
{VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
index a720f2d..3321c20 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -125,6 +125,7 @@
{VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_KEY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_MOTION_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
@@ -199,6 +200,12 @@
{VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_POSITION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode::ON_CHANGE},
@@ -293,6 +300,8 @@
{VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index be849f5..e55f4dc 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -117,6 +117,7 @@
Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyAccess.READ),
@@ -191,6 +192,12 @@
Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_POSITION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess.READ),
@@ -284,7 +291,9 @@
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess.READ_WRITE),
- Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess.READ)
+ Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ)
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
index 780eaa3..e351a3f 100644
--- a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -117,6 +117,7 @@
Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HEAD_UP_DISPLAY_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
@@ -191,6 +192,12 @@
Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_POSITION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode.ON_CHANGE),
@@ -284,7 +291,9 @@
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
- Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE)
+ Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE)
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
index b4f24a6..4b8060f 100644
--- a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
@@ -103,7 +103,8 @@
Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, List.of(DriverDistractionState.class, ErrorState.class)),
Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, List.of(DriverDistractionWarning.class, ErrorState.class)),
Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, List.of(LowSpeedCollisionWarningState.class, ErrorState.class)),
- Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, List.of(CrossTrafficMonitoringWarningState.class, ErrorState.class))
+ Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, List.of(CrossTrafficMonitoringWarningState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, List.of(LowSpeedAutomaticEmergencyBrakingState.class, ErrorState.class))
);
}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
index 146da69..3e6e7dc 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -63,6 +63,7 @@
using ::aidl::android::hardware::automotive::vehicle::LaneDepartureWarningState;
using ::aidl::android::hardware::automotive::vehicle::LaneKeepAssistState;
using ::aidl::android::hardware::automotive::vehicle::LocationCharacterization;
+using ::aidl::android::hardware::automotive::vehicle::LowSpeedAutomaticEmergencyBrakingState;
using ::aidl::android::hardware::automotive::vehicle::LowSpeedCollisionWarningState;
using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
using ::aidl::android::hardware::automotive::vehicle::VehicleAirbagLocation;
@@ -297,6 +298,8 @@
std::make_unique<ConstantParser<ElectronicStabilityControlState>>();
mConstantParsersByType["CrossTrafficMonitoringWarningState"] =
std::make_unique<ConstantParser<CrossTrafficMonitoringWarningState>>();
+ mConstantParsersByType["LowSpeedAutomaticEmergencyBrakingState"] =
+ std::make_unique<ConstantParser<LowSpeedAutomaticEmergencyBrakingState>>();
mConstantParsersByType["Constants"] = std::make_unique<LocalVariableParser>();
#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
mConstantParsersByType["TestVendorProperty"] =
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index 665c10e..56d8b4b 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -3219,6 +3219,19 @@
}
},
{
+ "property": "VehicleProperty::HEAD_UP_DISPLAY_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT"
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::OBD2_LIVE_FRAME",
"configArray": [
0,
@@ -4191,6 +4204,36 @@
]
}
]
+ },
+ {
+ "property": "VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "LowSpeedAutomaticEmergencyBrakingState::ENABLED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "LowSpeedAutomaticEmergencyBrakingState::ENABLED",
+ "LowSpeedAutomaticEmergencyBrakingState::ACTIVATED",
+ "LowSpeedAutomaticEmergencyBrakingState::USER_OVERRIDE"
+ ]
+ }
+ ]
}
]
}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index dced624..385f616 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -246,6 +246,13 @@
toInt(VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE),
},
},
+ // LSAEB
+ {
+ toInt(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED),
+ {
+ toInt(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE),
+ },
+ },
};
} // namespace
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index bbd88da..0c8ebbd 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -50,6 +50,7 @@
#include <aidl/android/hardware/automotive/vehicle/LaneDepartureWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/LaneKeepAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/LocationCharacterization.h>
+#include <aidl/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.h>
#include <aidl/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
similarity index 90%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
index cc07f9b..70014e1 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
@@ -31,12 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
+package android.hardware.automotive.vehicle;
@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+enum LowSpeedAutomaticEmergencyBrakingState {
+ OTHER = 0,
+ ENABLED = 1,
+ ACTIVATED = 2,
+ USER_OVERRIDE = 3,
}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index b6bfb04..52876d1 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -123,6 +123,7 @@
DISPLAY_BRIGHTNESS = (((0x0A03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409539 */,
PER_DISPLAY_BRIGHTNESS = (((0x0A04 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475076 */,
VALET_MODE_ENABLED = (((0x0A05 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312389 */,
+ HEAD_UP_DISPLAY_ENABLED = (((0x0A06 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421254 */,
HW_KEY_INPUT = (((0x0A10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475088 */,
HW_KEY_INPUT_V2 = (((0x0A11 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004177 */,
HW_MOTION_INPUT = (((0x0A12 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004178 */,
@@ -197,6 +198,12 @@
GLOVE_BOX_LOCKED = (((0x0BF1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421745 */,
VEHICLE_MAP_SERVICE = (((0x0C00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299895808 */,
LOCATION_CHARACTERIZATION = (((0x0C10 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410064 */,
+ ULTRASONICS_SENSOR_POSITION = (((0x0C20 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916128 */,
+ ULTRASONICS_SENSOR_ORIENTATION = (((0x0C21 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916129 */,
+ ULTRASONICS_SENSOR_FIELD_OF_VIEW = (((0x0C22 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916130 */,
+ ULTRASONICS_SENSOR_DETECTION_RANGE = (((0x0C23 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916131 */,
+ ULTRASONICS_SENSOR_SUPPORTED_RANGES = (((0x0C24 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916132 */,
+ ULTRASONICS_SENSOR_MEASURED_DISTANCE = (((0x0C25 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.VENDOR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 406916133 */,
OBD2_LIVE_FRAME = (((0x0D00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896064 */,
OBD2_FREEZE_FRAME = (((0x0D01 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896065 */,
OBD2_FREEZE_FRAME_INFO = (((0x0D02 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896066 */,
@@ -291,4 +298,6 @@
LOW_SPEED_COLLISION_WARNING_STATE = (((0x1022 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411106 */,
CROSS_TRAFFIC_MONITORING_ENABLED = (((0x1023 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313955 */,
CROSS_TRAFFIC_MONITORING_WARNING_STATE = (((0x1024 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411108 */,
+ LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED = (((0x1025 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313957 */,
+ LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE = (((0x1026 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411110 */,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
new file mode 100644
index 0000000..978da25
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Low Speed Automatic Emergency Braking.
+ */
+@VintfStability
+@Backing(type="int")
+enum LowSpeedAutomaticEmergencyBrakingState {
+
+ /**
+ * This state is used as an alternative to any LowSpeedAutomaticEmergencyBrakingState value that
+ * is not defined in the platform. Ideally, implementations of
+ * VehicleProperty#LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE should not use this state. The
+ * framework can use this field to remain backwards compatible if
+ * LowSpeedAutomaticEmergencyBrakingState is extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * Low Speed Automatic Emergency Braking is enabled and monitoring safety, but brakes are not
+ * activated.
+ */
+ ENABLED = 1,
+ /**
+ * Low Speed Automatic Emergency Braking is enabled and currently has the brakes applied for the
+ * vehicle.
+ */
+ ACTIVATED = 2,
+ /**
+ * Many Low Speed Automatic Emergency Braking implementations allow the driver to override Low
+ * Speed Automatic Emergency Braking. This means that the car has determined it should brake,
+ * but a user decides to take over and do something else. This is often done for safety reasons
+ * and to ensure that the driver can always take control of the vehicle. This state should be
+ * set when the user is actively overriding the low speed automatic emergency braking system.
+ */
+ USER_OVERRIDE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
index 923d42a..966ff65 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
@@ -20,33 +20,41 @@
@Backing(type="int")
enum VehicleApPowerStateShutdownParam {
/**
- * AP must shutdown immediately. Postponing is not allowed.
+ * AP must shutdown without Garage mode. Postponing is not allowed.
+ * If AP need to shutdown as soon as possible, EMERGENCY_SHUTDOWN shall be used.
*/
SHUTDOWN_IMMEDIATELY = 1,
/**
* AP can enter deep sleep instead of shutting down completely.
+ * AP can postpone entering deep sleep to run Garage mode.
*/
CAN_SLEEP = 2,
/**
- * AP can only shutdown with postponing allowed.
+ * AP can only shutdown.
+ * AP can postpone shutdown to run Garage mode.
*/
SHUTDOWN_ONLY = 3,
/**
- * AP may enter deep sleep, but must either sleep or shut down immediately.
+ * AP can enter deep sleep, without Garage mode.
* Postponing is not allowed.
+ * Depending on the actual implementation, it may shut down immediately
*/
SLEEP_IMMEDIATELY = 4,
/**
- * AP must hibernate (suspend to disk) immediately. Postponing is not allowed.
- * Depending on the actual implementation, it may shut down immediately
+ * AP can hibernate (suspend to disk) without Garage mode.
+ * Postponing is not allowed.
+ * Depending on the actual implementation, it may shut down immediately.
*/
HIBERNATE_IMMEDIATELY = 5,
/**
* AP can enter hibernation (suspend to disk) instead of shutting down completely.
+ * AP can postpone hibernation to run Garage mode.
*/
CAN_HIBERNATE = 6,
/**
- * AP must shutdown (gracefully) without a delay.
+ * AP must shutdown (gracefully) without a delay. AP cannot run Garage mode.
+ * This type must be used only in critical situations when AP must shutdown as soon as possible.
+ * CarService will only notify listeners, but will not wait for completion reports.
*/
EMERGENCY_SHUTDOWN = 7,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 3d63a06..fb8f730 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -1590,6 +1590,22 @@
VALET_MODE_ENABLED =
0x0A05 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
/**
+ * Head up display (HUD) enabled
+ *
+ * This property allows the user to turn on/off the HUD for their seat.
+ *
+ * Each HUD in the vehicle should be assigned to the seat that is intended to use it. For
+ * example, if there is a single HUD in the vehicle that is used by the driver so that they no
+ * longer need to continuously look at the instrument cluster, then this property should be
+ * defined with a single area ID equal to the driver's seat area value.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ HEAD_UP_DISPLAY_ENABLED =
+ 0x0A06 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+ /**
* Property to feed H/W input events to android
*
* int32Values[0] : action defined by VehicleHwKeyInputAction
@@ -3327,6 +3343,177 @@
*/
LOCATION_CHARACTERIZATION =
0x0C10 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Static data for the position of each ultrasonic sensor installed on the vehicle.
+ *
+ * Each individual sensor is identified by its unique VehicleAreaConfig#areaId and returns the
+ * sensor's position formatted as [x, y, z] where:
+ *
+ * int32Values[0] = x, the position of the sensor along the x-axis relative to the origin of
+ * the Android Automotive sensor coordinate frame in millimeters
+ * int32Values[1] = y, the position of the sensor along the y-axis relative to the origin of
+ * the Android Automotive sensor coordinate frame in millimeters.
+ * int32Values[2] = z, the position of the sensor along the z-axis relative to the origin of
+ * the Android Automotive sensor coordinate frame in millimeters.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ ULTRASONICS_SENSOR_POSITION = 0x0C20 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * Static data for the orientation of each ultrasonic sensor installed on the vehicle.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * orientation formatted as [qw, qx, qy, qz] where:
+ *
+ * int32Values[0] = qw, the quaternion coefficient w within the quaterinion (w + xi + yj +
+ * zk) describing the rotation of the sensor relative to the Android
+ * Automotive sensor coordinate frame.
+ * int32Values[1] = qx, the quaternion coefficient x within the quaterinion (w + xi + yj +
+ * zk) describing the rotation of the sensor relative to the Android
+ * Automotive sensor coordinate frame.
+ * int32Values[2] = qy, the quaternion coefficient y within the quaterinion (w + xi + yj +
+ * zk) describing the rotation of the sensor relative to the Android
+ * Automotive sensor coordinate frame.
+ * int32Values[3] = qz, the quaternion coefficient z within the quaterinion (w + xi + yj +
+ * zk) describing the rotation of the sensor relative to the Android
+ * Automotive sensor coordinate frame.
+ *
+ * This assumes each sensor uses the same axes conventions as Android Automotive.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ ULTRASONICS_SENSOR_ORIENTATION = 0x0C21 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * Static data for the field of view of each ultrasonic sensor in degrees.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * field of view formatted as [horizontal, vertical] where:
+ *
+ * int32Values[0] = horizontal, the horizontal field of view for the specified ultrasonic
+ * sensor in degrees.
+ * int32Values[1] = vertical, the vertical field of view for the associated specified
+ * ultrasonic sensor in degrees.
+ *
+ * This assumes each sensor uses the same axes conventions as Android Automotive.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ ULTRASONICS_SENSOR_FIELD_OF_VIEW = 0x0C22 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * Static data for the detection range of each ultrasonic sensor in millimeters.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * detection range formatted as [minimum, maximum] where:
+ *
+ * int32Values[0] = minimum, the minimum range detectable by the ultrasonic sensor in
+ * millimeters.
+ * int32Values[1] = maximum, the maximum range detectable by the ultrasonic sensor in
+ * millimeters.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ ULTRASONICS_SENSOR_DETECTION_RANGE = 0x0C23 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * Static data for the supported ranges of each ultrasonic sensor in millimeters.
+ *
+ * For ultrasonic sensors that only support readings within a specific range. For example, if
+ * an ultrasonic sensor detects an object at 700mm, but can only report that an object has been
+ * detected between 500mm and 1000mm.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * supported ranges formatted as [range_min_1, range_max_1, range_min_2, range_max_2, ...]
+ * where:
+ *
+ * int32Values[0] = range_min_1, the minimum of one supported range by the specified sensor
+ * in millimeters, inclusive.
+ * int32Values[1] = range_max_1, the maximum of one supported range by the specified sensor
+ * in millimeters, inclusive.
+ * int32Values[2] = range_min_2, the minimum of another supported range by the specified
+ * sensor in millimeters, inclusive.
+ * int32Values[3] = range_max_2, the maximum of another supported range by the specified
+ sensor in millimeters, inclusive.
+ *
+ * Example:
+ * - Ultrasonic sensor supports the following ranges:
+ * - 150mm to 499mm
+ * - 500mm to 999mm
+ * - 1000mm to 1500mm
+ * - The associated supported ranges should be formatted as:
+ * - int32Values[0] = 150
+ * - int32Values[1] = 499
+ * - int32Values[2] = 500
+ * - int32Values[3] = 999
+ * - int32Values[4] = 1000
+ * - int32Values[5] = 1500
+ *
+ * If this property is not defined, all the values within the ULTRASONICS_SENSOR_DETECTION_RANGE
+ * for the specified sensor are assumed to be supported.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ ULTRASONICS_SENSOR_SUPPORTED_RANGES = 0x0C24 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
+ /**
+ * The distance reading of the nearest detected object per sensor in millimeters.
+ *
+ * Each individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's
+ * measured distance formatted as [distance, distance_error] where:
+ *
+ * int32Values[0] = distance, the measured distance of the nearest object in millimeters.
+ * If only a range is supported, this value must be set to the minimum
+ * supported distance in the detected range as specified in
+ * ULTRASONICS_SENSOR_SUPPORTED_RANGES.
+ * int32Values[1] = distance_error, the error of the measured distance value in
+ * millimeters.
+ *
+ * If no object is detected, an empty vector must be returned. If distance_error is not
+ * available then an array of only the measured distance must be returned.
+ *
+ * If the data is aggregated by another ECU, then OEMs have the option of reporting the same
+ * reading across all included sensors or reporting a virtual representation of all the included
+ * sensors as if they were one sensor.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ */
+ ULTRASONICS_SENSOR_MEASURED_DISTANCE = 0x0C25 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
+ + VehiclePropertyType.INT32_VEC,
+
/**
* OBD2 Live Sensor Data
*
@@ -4664,7 +4851,9 @@
* Enable or disable Automatic Emergency Braking (AEB).
*
* Set true to enable AEB and false to disable AEB. When AEB is enabled, the ADAS system in the
- * vehicle should be turned on and monitoring to avoid potential collisions.
+ * vehicle should be turned on and monitoring to avoid potential collisions. This property
+ * should apply for higher speed applications only. For enabling low speed automatic emergency
+ * braking, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED should be used.
*
* In general, AUTOMATIC_EMERGENCY_BRAKING_ENABLED should always return true or false. If the
* feature is not available due to some temporary state, such as the vehicle speed being too
@@ -4686,7 +4875,9 @@
*
* Returns the current state of AEB. This property must always return a valid state defined in
* AutomaticEmergencyBrakingState or ErrorState. It must not surface errors through StatusCode
- * and must use the supported error states instead.
+ * and must use the supported error states instead. This property should apply for higher speed
+ * applications only. For representing the state of the low speed automatic emergency braking
+ * system, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE should be used.
*
* If AEB includes forward collision warnings before activating the brakes, those warnings must
* be surfaced through the Forward Collision Warning (FCW) properties.
@@ -5511,6 +5702,58 @@
CROSS_TRAFFIC_MONITORING_WARNING_STATE =
0x1024 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Enable or disable Low Speed Automatic Emergency Braking.
+ *
+ * Set true to enable Low Speed Automatic Emergency Braking or false to disable Low Speed
+ * Automatic Emergency Braking. When Low Speed Automatic Emergency Braking is enabled, the ADAS
+ * system in the vehicle should be turned on and monitoring to avoid potential collisions in low
+ * speed conditions. This property is different from the pre-existing
+ * AUTOMATIC_EMERGENCY_BRAKING_ENABLED, which should apply to higher speed applications only. If
+ * the vehicle doesn't have a separate collision avoidance system for low speed environments,
+ * this property should not be implemented.
+ *
+ * In general, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED should always return true or false.
+ * If the feature is not available due to some temporary state, such as the vehicle speed being
+ * too low, that information must be conveyed through the ErrorState values in the
+ * LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED =
+ 0x1025 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Low Speed Automatic Emergency Braking state.
+ *
+ * Returns the current state of Low Speed Automatic Emergency Braking. This property must always
+ * return a valid state defined in LowSpeedAutomaticEmergencyBrakingState or ErrorState. It must
+ * not surface errors through StatusCode and must use the supported error states instead. This
+ * property is different from the pre-existing AUTOMATIC_EMERGENCY_BRAKING_STATE, which should
+ * apply to higher speed applications only. If the vehicle doesn't have a separate collision
+ * avoidance system for low speed environments, this property should not be implemented.
+ *
+ * If Low Speed Automatic Emergency Braking includes collision warnings before activating the
+ * brakes, those warnings must be surfaced through use of LOW_SPEED_COLLISION_WARNING_ENABLED
+ * and LOW_SPEED_COLLISION_WARNING_STATE.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both LowSpeedAutomaticEmergencyBrakingState (including OTHER, which is
+ * not recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum LowSpeedAutomaticEmergencyBrakingState
+ * @data_enum ErrorState
+ */
+ LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE =
+ 0x1026 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
/***************************************************************************
* End of ADAS Properties
**************************************************************************/
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index ba36f29..b5ee335 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -548,6 +548,44 @@
VehicleArea::GLOBAL, VehiclePropertyType::INT32);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorPositionConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_POSITION, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::VENDOR, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorOrientationConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::VENDOR, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorFieldOfViewConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::VENDOR, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorDetectionRangeConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::VENDOR, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorSupportedRangesConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::STATIC,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::VENDOR,
+ VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyUltrasonicsSensorMeasuredDistanceConfig) {
+ verifyProperty(VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::CONTINUOUS,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::VENDOR,
+ VehiclePropertyType::INT32_VEC);
+}
+
TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEmergencyLaneKeepAssistEnabledConfig) {
verifyProperty(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED,
VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
@@ -1011,6 +1049,24 @@
VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHeadUpDisplayEnabledConfig) {
+ verifyProperty(VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLowSpeedAutomaticEmergencyBrakingEnabledConfig) {
+ verifyProperty(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLowSpeedAutomaticEmergencyBrakingStateConfig) {
+ verifyProperty(VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
bool VtsHalAutomotiveVehicleTargetTest::checkIsSupported(int32_t propertyId) {
auto result = mVhalClient->getPropConfigs({propertyId});
return result.ok();
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
index 2ca9d96..2727d6e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
@@ -49,7 +49,15 @@
int outputDataPath = 1;
boolean useControllerCodec = true;
}
+ parcelable LeAudio {
+ android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+ int[] samplingFrequencyHz;
+ int[] frameDurationUs;
+ int[] bitdepth;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ }
union Transport {
+ android.hardware.bluetooth.audio.CodecInfo.LeAudio leAudio;
android.hardware.bluetooth.audio.CodecInfo.A2dp a2dp;
android.hardware.bluetooth.audio.CodecInfo.Hfp hfp;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl
new file mode 100644
index 0000000..1049d98
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2023 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@VintfStability
+union CodecSpecificCapabilitiesLtv {
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedSamplingFrequencies supportedSamplingFrequencies;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedFrameDurations supportedFrameDurations;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedAudioChannelCounts supportedAudioChannelCounts;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedOctetsPerCodecFrame supportedOctetsPerCodecFrame;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedMaxCodecFramesPerSDU supportedMaxCodecFramesPerSDU;
+ parcelable SupportedSamplingFrequencies {
+ int bitmask;
+ const int HZ8000 = 0x0001;
+ const int HZ11025 = 0x0002;
+ const int HZ16000 = 0x0004;
+ const int HZ22050 = 0x0008;
+ const int HZ24000 = 0x0010;
+ const int HZ32000 = 0x0020;
+ const int HZ44100 = 0x0040;
+ const int HZ48000 = 0x0080;
+ const int HZ88200 = 0x0100;
+ const int HZ96000 = 0x0200;
+ const int HZ176400 = 0x0400;
+ const int HZ192000 = 0x0800;
+ const int HZ384000 = 0x1000;
+ }
+ parcelable SupportedFrameDurations {
+ int bitmask;
+ const int US7500 = 0x01;
+ const int US10000 = 0x02;
+ const int US7500PREFERRED = 0x10;
+ const int US10000PREFERRED = 0x20;
+ }
+ parcelable SupportedAudioChannelCounts {
+ int bitmask;
+ const int ONE = 0x01;
+ const int TWO = 0x02;
+ const int THREE = 0x04;
+ const int FOUR = 0x08;
+ const int FIVE = 0x10;
+ const int SIX = 0x20;
+ const int SEVEN = 0x40;
+ const int EIGHT = 0x80;
+ }
+ parcelable SupportedOctetsPerCodecFrame {
+ int minimum;
+ int maximum;
+ }
+ parcelable SupportedMaxCodecFramesPerSDU {
+ int value;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl
new file mode 100644
index 0000000..943d396
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2023 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.bluetooth.audio;
+@VintfStability
+union CodecSpecificConfigurationLtv {
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.CodecFrameBlocksPerSDU codecFrameBlocksPerSDU;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.SamplingFrequency samplingFrequency;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.FrameDuration frameDuration;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.AudioChannelAllocation audioChannelAllocation;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.OctetsPerCodecFrame octetsPerCodecFrame;
+ @Backing(type="byte")
+ enum SamplingFrequency {
+ HZ8000 = 0x01,
+ HZ11025 = 0x02,
+ HZ16000 = 0x03,
+ HZ22050 = 0x04,
+ HZ24000 = 0x05,
+ HZ32000 = 0x06,
+ HZ44100 = 0x07,
+ HZ48000 = 0x08,
+ HZ88200 = 0x09,
+ HZ96000 = 0x0A,
+ HZ176400 = 0x0B,
+ HZ192000 = 0x0C,
+ HZ384000 = 0x0D,
+ }
+ @Backing(type="byte")
+ enum FrameDuration {
+ US7500 = 0x00,
+ US10000 = 0x01,
+ }
+ parcelable AudioChannelAllocation {
+ int bitmask;
+ const int NOT_ALLOWED = 0x00000000;
+ const int FRONT_LEFT = 0x00000001;
+ const int FRONT_RIGHT = 0x00000002;
+ const int FRONT_CENTER = 0x00000004;
+ const int LOW_FREQUENCY_EFFECTS_1 = 0x00000008;
+ const int BACK_LEFT = 0x00000010;
+ const int BACK_RIGHT = 0x00000020;
+ const int FRONT_LEFT_OF_CENTER = 0x00000040;
+ const int FRONT_RIGHT_OF_CENTER = 0x00000080;
+ const int BACK_CENTER = 0x00000100;
+ const int LOW_FREQUENCY_EFFECTS_2 = 0x00000200;
+ const int SIDE_LEFT = 0x00000400;
+ const int SIDE_RIGHT = 0x00000800;
+ const int TOP_FRONT_LEFT = 0x00001000;
+ const int TOP_FRONT_RIGHT = 0x00002000;
+ const int TOP_FRONT_CENTER = 0x00004000;
+ const int TOP_CENTER = 0x00008000;
+ const int TOP_BACK_LEFT = 0x00010000;
+ const int TOP_BACK_RIGHT = 0x00020000;
+ const int TOP_SIDE_LEFT = 0x00040000;
+ const int TOP_SIDE_RIGHT = 0x00080000;
+ const int TOP_BACK_CENTER = 0x00100000;
+ const int BOTTOM_FRONT_CENTER = 0x00200000;
+ const int BOTTOM_FRONT_LEFT = 0x00400000;
+ const int BOTTOM_FRONT_RIGHT = 0x00800000;
+ const int FRONT_LEFT_WIDE = 0x01000000;
+ const int FRONT_RIGHT_WIDE = 0x02000000;
+ const int LEFT_SURROUND = 0x04000000;
+ const int RIGHT_SURROUND = 0x08000000;
+ }
+ parcelable OctetsPerCodecFrame {
+ int value;
+ }
+ parcelable CodecFrameBlocksPerSDU {
+ int value;
+ }
+}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
similarity index 78%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
index cc07f9b..baf0a4e 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 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.
@@ -31,12 +31,15 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable ConfigurationFlags {
+ int bitmask;
+ const int NONE = 0x0000;
+ const int LOSSLESS = 0x0001;
+ const int LOW_LATENCY = 0x0002;
+ const int ALLOW_ASYMMETRIC_CONFIGURATIONS = 0x0003;
+ const int SPATIAL_AUDIO = 0x0004;
+ const int PROVIDE_ASE_METADATA = 0x0005;
+ const int MONO_MIC_CONFIGURATION = 0x0006;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index ccf5524..f155634 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -42,4 +42,152 @@
void setLowLatencyModeAllowed(in boolean allowed);
android.hardware.bluetooth.audio.A2dpStatus parseA2dpConfiguration(in android.hardware.bluetooth.audio.CodecId codecId, in byte[] configuration, out android.hardware.bluetooth.audio.CodecParameters codecParameters);
@nullable android.hardware.bluetooth.audio.A2dpConfiguration getA2dpConfiguration(in List<android.hardware.bluetooth.audio.A2dpRemoteCapabilities> remoteA2dpCapabilities, in android.hardware.bluetooth.audio.A2dpConfigurationHint hint);
+ void setCodecPriority(in android.hardware.bluetooth.audio.CodecId codecId, int priority);
+ List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseConfigurationSetting> getLeAudioAseConfiguration(in @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities> remoteSinkAudioCapabilities, in @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities> remoteSourceAudioCapabilities, in List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioConfigurationRequirement> requirements);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationPair getLeAudioAseQosConfiguration(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement qosRequirement);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(in android.hardware.bluetooth.audio.AudioContext context, in android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap);
+ void onSinkAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata);
+ void onSourceAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastConfigurationSetting getLeAudioBroadcastConfiguration(in @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities> remoteSinkAudioCapabilities, in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastConfigurationRequirement requirement);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration getLeAudioBroadcastDatapathConfiguration(in android.hardware.bluetooth.audio.AudioContext context, in android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration.BroadcastStreamMap[] streamMap);
+ @VintfStability
+ parcelable LeAudioDeviceCapabilities {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv[] codecSpecificCapabilities;
+ @nullable byte[] vendorCodecSpecificCapabilities;
+ @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata;
+ }
+ @VintfStability
+ parcelable LeAudioDataPathConfiguration {
+ int dataPathId;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration.DataPathConfiguration dataPathConfiguration;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration.IsoDataPathConfiguration isoDataPathConfiguration;
+ @VintfStability
+ parcelable IsoDataPathConfiguration {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ boolean isTransparent;
+ int controllerDelayUs;
+ @nullable byte[] configuration;
+ }
+ @VintfStability
+ parcelable DataPathConfiguration {
+ @nullable byte[] configuration;
+ }
+ }
+ @VintfStability
+ parcelable LeAudioAseQosConfiguration {
+ int sduIntervalUs;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing;
+ android.hardware.bluetooth.audio.Phy[] phy;
+ int maxTransportLatencyMs;
+ int maxSdu;
+ int retransmissionNum;
+ }
+ @Backing(type="byte") @VintfStability
+ enum Packing {
+ SEQUENTIAL = 0x00,
+ INTERLEAVED = 0x01,
+ }
+ @Backing(type="byte") @VintfStability
+ enum Framing {
+ UNFRAMED = 0x00,
+ FRAMED = 0x01,
+ }
+ @VintfStability
+ parcelable LeAudioAseConfigurationSetting {
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Packing packing;
+ @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseConfigurationSetting.AseDirectionConfiguration> sinkAseConfiguration;
+ @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseConfigurationSetting.AseDirectionConfiguration> sourceAseConfiguration;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ @VintfStability
+ parcelable AseDirectionConfiguration {
+ android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration qosConfiguration;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration dataPathConfiguration;
+ }
+ }
+ @VintfStability
+ parcelable LeAudioConfigurationRequirement {
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioConfigurationRequirement.AseDirectionRequirement> sinkAseRequirement;
+ @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioConfigurationRequirement.AseDirectionRequirement> sourceAseRequirement;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ @VintfStability
+ parcelable AseDirectionRequirement {
+ android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration;
+ }
+ }
+ @VintfStability
+ parcelable LeAudioAseQosConfigurationRequirement {
+ android.hardware.bluetooth.audio.AudioContext contextType;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement.AseQosDirectionRequirement sinkAseQosRequirement;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement.AseQosDirectionRequirement sourceAseQosRequirement;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ @VintfStability
+ parcelable AseQosDirectionRequirement {
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing;
+ android.hardware.bluetooth.audio.Phy[] preferredPhy;
+ int preferredRetransmissionNum;
+ int maxTransportLatencyMs;
+ int presentationDelayMinUs;
+ int presentationDelayMaxUs;
+ int preferredPresentationDelayMinUs;
+ int preferredPresentationDelayMaxUs;
+ android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration;
+ }
+ }
+ @VintfStability
+ parcelable LeAudioAseQosConfigurationPair {
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration sinkQosConfiguration;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration sourceQosConfiguration;
+ }
+ parcelable LeAudioDataPathConfigurationPair {
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration inputConfig;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration outputConfig;
+ }
+ @Backing(type="byte") @VintfStability
+ enum AseState {
+ ENABLING = 0x00,
+ STREAMING = 0x01,
+ DISABLING = 0x02,
+ }
+ @Backing(type="byte") @VintfStability
+ enum BroadcastQuality {
+ STANDARD,
+ HIGH,
+ }
+ @VintfStability
+ parcelable LeAudioBroadcastSubgroupConfigurationRequirement {
+ android.hardware.bluetooth.audio.AudioContext context;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.BroadcastQuality quality;
+ int bisNumPerSubgroup;
+ }
+ @VintfStability
+ parcelable LeAudioBroadcastConfigurationRequirement {
+ List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastSubgroupConfigurationRequirement> subgroupConfigurationRequirements;
+ }
+ @VintfStability
+ parcelable LeAudioSubgroupBisConfiguration {
+ int numBis;
+ android.hardware.bluetooth.audio.LeAudioBisConfiguration bisConfiguration;
+ }
+ @VintfStability
+ parcelable LeAudioBroadcastSubgroupConfiguration {
+ List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioSubgroupBisConfiguration> bisConfigurations;
+ @nullable byte[] vendorCodecConfiguration;
+ }
+ @VintfStability
+ parcelable LeAudioBroadcastConfigurationSetting {
+ int sduIntervalUs;
+ int numBis;
+ int maxSduOctets;
+ int maxTransportLatencyMs;
+ int retransmitionNum;
+ android.hardware.bluetooth.audio.Phy[] phy;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Packing packing;
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing;
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration dataPathConfiguration;
+ List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastSubgroupConfiguration> subgroupsConfigurations;
+ }
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index c806b0a..edb79a3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -41,5 +41,6 @@
parcelable ProviderInfo {
String name;
android.hardware.bluetooth.audio.CodecInfo[] codecInfos;
+ boolean supportsMultidirectionalCapabilities;
}
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
similarity index 68%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
index cc07f9b..bffc88b 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 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.
@@ -31,12 +31,20 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable LeAudioAseConfiguration {
+ android.hardware.bluetooth.audio.LeAudioAseConfiguration.TargetLatency targetLatency;
+ android.hardware.bluetooth.audio.Phy targetPhy;
+ @nullable android.hardware.bluetooth.audio.CodecId codecId;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv[] codecConfiguration;
+ @nullable byte[] vendorCodecConfiguration;
+ @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata;
+ @Backing(type="byte") @VintfStability
+ enum TargetLatency {
+ UNDEFINED = 0x00,
+ LOWER = 0x01,
+ BALANCED_LATENCY_RELIABILITY = 0x02,
+ HIGHER_RELIABILITY = 0x03,
+ }
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
similarity index 80%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
index cc07f9b..b09d34f 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 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.
@@ -31,12 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable LeAudioBisConfiguration {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv[] codecConfiguration;
+ byte[] vendorCodecConfiguration;
+ @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index 2945710..efd3b02 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -42,5 +42,7 @@
int audioChannelAllocation;
android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
char pcmStreamId;
+ @nullable android.hardware.bluetooth.audio.LeAudioBisConfiguration bisConfiguration;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
}
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 2d9ebae..25a9797 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -44,5 +44,16 @@
char streamHandle;
int audioChannelAllocation;
boolean isStreamActive;
+ @nullable android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration;
+ @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags;
+ @nullable android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap.BluetoothDeviceAddress bluetoothDeviceAddress;
+ parcelable BluetoothDeviceAddress {
+ byte[6] deviceAddress;
+ android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap.BluetoothDeviceAddress.DeviceAddressType deviceAddressType;
+ enum DeviceAddressType {
+ BLE_ADDRESS_PUBLIC = 0x00,
+ BLE_ADDRESS_RANDOM = 0x01,
+ }
+ }
}
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl
similarity index 70%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl
index cc07f9b..5e8a2ae 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 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.
@@ -31,12 +31,20 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.bluetooth.audio;
+@VintfStability
+union MetadataLtv {
+ android.hardware.bluetooth.audio.MetadataLtv.PreferredAudioContexts preferredAudioContexts;
+ android.hardware.bluetooth.audio.MetadataLtv.StreamingAudioContexts streamingAudioContexts;
+ android.hardware.bluetooth.audio.MetadataLtv.VendorSpecific vendorSpecific;
+ parcelable PreferredAudioContexts {
+ android.hardware.bluetooth.audio.AudioContext values;
+ }
+ parcelable StreamingAudioContexts {
+ android.hardware.bluetooth.audio.AudioContext values;
+ }
+ parcelable VendorSpecific {
+ int companyId;
+ byte[] opaqueValue;
+ }
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl
similarity index 86%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl
index cc07f9b..bfeabcd 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 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.
@@ -31,12 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum Phy {
+ UNDEFINED = 0x00,
+ ONE_M = 0x01,
+ TWO_M = 0x02,
+ CODED = 0x03,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
index 127cd7c..33f0c04 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
@@ -18,6 +18,7 @@
import android.hardware.bluetooth.audio.ChannelMode;
import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.ConfigurationFlags;
/**
* General information about a Codec
@@ -87,10 +88,46 @@
}
/**
+ * LE Audio Context
+ */
+ parcelable LeAudio {
+ /**
+ * Channel configuration: Mono, Dual-Mono or Stereo
+ */
+ ChannelMode[] channelMode;
+
+ /**
+ * Supported sampling frequencies, in Hz.
+ */
+ int[] samplingFrequencyHz;
+
+ /*
+ * FrameDuration in microseconds.
+ */
+ int[] frameDurationUs;
+
+ /**
+ * - Fixed point resolution, basically 16, 24 or 32 bits by samples.
+ * The value 32 should be used for floating point representation.
+ *
+ * When the bitdepth is not an encoding/decoding parameter (don't take
+ * part in the interoperability), the `bitdepth` list shall have a
+ * single element indicating the bitdepth selected for the platform.
+ */
+ int[] bitdepth;
+
+ /**
+ * Additional configuration flags
+ */
+ @nullable ConfigurationFlags flags;
+ }
+
+ /**
* Specific informations,
* depending on transport.
*/
union Transport {
+ LeAudio leAudio;
A2dp a2dp;
Hfp hfp;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl
new file mode 100644
index 0000000..ceb90ba
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2023 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.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used to exchange generic remote device codec specific capabilities between
+ * the stack and the provider. As defined in Bluetooth Assigned Numbers,
+ * Sec. 6.12.4.
+ */
+@VintfStability
+union CodecSpecificCapabilitiesLtv {
+ parcelable SupportedSamplingFrequencies {
+ const int HZ8000 = 0x0001;
+ const int HZ11025 = 0x0002;
+ const int HZ16000 = 0x0004;
+ const int HZ22050 = 0x0008;
+ const int HZ24000 = 0x0010;
+ const int HZ32000 = 0x0020;
+ const int HZ44100 = 0x0040;
+ const int HZ48000 = 0x0080;
+ const int HZ88200 = 0x0100;
+ const int HZ96000 = 0x0200;
+ const int HZ176400 = 0x0400;
+ const int HZ192000 = 0x0800;
+ const int HZ384000 = 0x1000;
+
+ /* 16 bits wide bit mask */
+ int bitmask;
+ }
+ parcelable SupportedFrameDurations {
+ const int US7500 = 0x01;
+ const int US10000 = 0x02;
+ // Bits 2-3 are RFU
+ const int US7500PREFERRED = 0x10;
+ const int US10000PREFERRED = 0x20;
+
+ /* 8 bit wide bit mask */
+ int bitmask;
+ }
+ parcelable SupportedAudioChannelCounts {
+ const int ONE = 0x01;
+ const int TWO = 0x02;
+ const int THREE = 0x04;
+ const int FOUR = 0x08;
+ const int FIVE = 0x10;
+ const int SIX = 0x20;
+ const int SEVEN = 0x40;
+ const int EIGHT = 0x80;
+
+ /* 8 bit wide bit mask */
+ int bitmask;
+ }
+ parcelable SupportedOctetsPerCodecFrame {
+ int minimum;
+ int maximum;
+ }
+ parcelable SupportedMaxCodecFramesPerSDU {
+ int value;
+ }
+
+ SupportedSamplingFrequencies supportedSamplingFrequencies;
+ SupportedFrameDurations supportedFrameDurations;
+ SupportedAudioChannelCounts supportedAudioChannelCounts;
+ SupportedOctetsPerCodecFrame supportedOctetsPerCodecFrame;
+ SupportedMaxCodecFramesPerSDU supportedMaxCodecFramesPerSDU;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl
new file mode 100644
index 0000000..c099ebe
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2023 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.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used to exchange generic remote device configuration between the stack and
+ * the provider. As defined in Bluetooth Assigned Numbers, Sec. 6.12.5.
+ */
+@VintfStability
+union CodecSpecificConfigurationLtv {
+ @Backing(type="byte")
+ enum SamplingFrequency {
+ HZ8000 = 0x01,
+ HZ11025 = 0x02,
+ HZ16000 = 0x03,
+ HZ22050 = 0x04,
+ HZ24000 = 0x05,
+ HZ32000 = 0x06,
+ HZ44100 = 0x07,
+ HZ48000 = 0x08,
+ HZ88200 = 0x09,
+ HZ96000 = 0x0A,
+ HZ176400 = 0x0B,
+ HZ192000 = 0x0C,
+ HZ384000 = 0x0D,
+ }
+
+ @Backing(type="byte")
+ enum FrameDuration {
+ US7500 = 0x00,
+ US10000 = 0x01,
+ }
+
+ parcelable AudioChannelAllocation {
+ const int NOT_ALLOWED = 0x00000000;
+ const int FRONT_LEFT = 0x00000001;
+ const int FRONT_RIGHT = 0x00000002;
+ const int FRONT_CENTER = 0x00000004;
+ const int LOW_FREQUENCY_EFFECTS_1 = 0x00000008;
+ const int BACK_LEFT = 0x00000010;
+ const int BACK_RIGHT = 0x00000020;
+ const int FRONT_LEFT_OF_CENTER = 0x00000040;
+ const int FRONT_RIGHT_OF_CENTER = 0x00000080;
+ const int BACK_CENTER = 0x00000100;
+ const int LOW_FREQUENCY_EFFECTS_2 = 0x00000200;
+ const int SIDE_LEFT = 0x00000400;
+ const int SIDE_RIGHT = 0x00000800;
+ const int TOP_FRONT_LEFT = 0x00001000;
+ const int TOP_FRONT_RIGHT = 0x00002000;
+ const int TOP_FRONT_CENTER = 0x00004000;
+ const int TOP_CENTER = 0x00008000;
+ const int TOP_BACK_LEFT = 0x00010000;
+ const int TOP_BACK_RIGHT = 0x00020000;
+ const int TOP_SIDE_LEFT = 0x00040000;
+ const int TOP_SIDE_RIGHT = 0x00080000;
+ const int TOP_BACK_CENTER = 0x00100000;
+ const int BOTTOM_FRONT_CENTER = 0x00200000;
+ const int BOTTOM_FRONT_LEFT = 0x00400000;
+ const int BOTTOM_FRONT_RIGHT = 0x00800000;
+ const int FRONT_LEFT_WIDE = 0x01000000;
+ const int FRONT_RIGHT_WIDE = 0x02000000;
+ const int LEFT_SURROUND = 0x04000000;
+ const int RIGHT_SURROUND = 0x08000000;
+
+ // Bit mask of Audio Locations
+ int bitmask;
+ }
+
+ parcelable OctetsPerCodecFrame {
+ int value;
+ }
+
+ parcelable CodecFrameBlocksPerSDU {
+ int value;
+ }
+
+ CodecFrameBlocksPerSDU codecFrameBlocksPerSDU;
+ SamplingFrequency samplingFrequency;
+ FrameDuration frameDuration;
+ AudioChannelAllocation audioChannelAllocation;
+ OctetsPerCodecFrame octetsPerCodecFrame;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
new file mode 100644
index 0000000..57c8be5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2023 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.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Coding fetures
+ */
+@VintfStability
+parcelable ConfigurationFlags {
+ const int NONE = 0x0000;
+ /*
+ * Set for the lossless configurations
+ */
+ const int LOSSLESS = 0x0001;
+ /*
+ * Set for the low latency configurations
+ */
+ const int LOW_LATENCY = 0x0002;
+ /*
+ * When set, asymmetric configuration for SINK and SOURCE can be used.
+ * e.g. in GAMING mode stream for 32kHz and back channel for 16 kHz
+ */
+ const int ALLOW_ASYMMETRIC_CONFIGURATIONS = 0x0003;
+ /*
+ * Set for the spatial audio configurations
+ */
+ const int SPATIAL_AUDIO = 0x0004;
+ /*
+ * When set, BluetoothAudioProvider requests to receive ASE metadata.
+ * In such case onSinkAseMetadataChanged() and onSourceAseMetadataChanged
+ * will be called.
+ */
+ const int PROVIDE_ASE_METADATA = 0x0005;
+ /*
+ * Set for mono microphone configurations
+ */
+ const int MONO_MIC_CONFIGURATION = 0x0006;
+
+ int bitmask;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index b5c8a31..2e16f4e 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -21,11 +21,21 @@
import android.hardware.bluetooth.audio.A2dpRemoteCapabilities;
import android.hardware.bluetooth.audio.A2dpStatus;
import android.hardware.bluetooth.audio.AudioConfiguration;
+import android.hardware.bluetooth.audio.AudioContext;
import android.hardware.bluetooth.audio.BluetoothAudioStatus;
import android.hardware.bluetooth.audio.CodecId;
import android.hardware.bluetooth.audio.CodecParameters;
+import android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv;
+import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv;
+import android.hardware.bluetooth.audio.ConfigurationFlags;
import android.hardware.bluetooth.audio.IBluetoothAudioPort;
import android.hardware.bluetooth.audio.LatencyMode;
+import android.hardware.bluetooth.audio.LeAudioAseConfiguration;
+import android.hardware.bluetooth.audio.LeAudioBisConfiguration;
+import android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration.BroadcastStreamMap;
+import android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap;
+import android.hardware.bluetooth.audio.MetadataLtv;
+import android.hardware.bluetooth.audio.Phy;
import android.hardware.common.fmq.MQDescriptor;
import android.hardware.common.fmq.SynchronizedReadWrite;
@@ -124,4 +134,575 @@
*/
@nullable A2dpConfiguration getA2dpConfiguration(
in List<A2dpRemoteCapabilities> remoteA2dpCapabilities, in A2dpConfigurationHint hint);
+
+ /**
+ * Set specific codec priority
+ *
+ * It should be assumed that the external module will start with all its
+ * integrated codecs priority 0 by default.
+ *
+ * @param codecId: codecId
+ * @param priority: 0 for no priority, -1 for codec disabled,
+ * from 1 to N, where 1 is highest.
+ */
+ void setCodecPriority(in CodecId codecId, int priority);
+
+ /**
+ * LE Audio device Capabilities - as defined in Bluetooth Published Audio
+ * Capabilities Service specification, v1.0.1, Sec. 3.1: "Sink PAC", and
+ * Sec. 3.3: "Source PAC".
+ */
+ @VintfStability
+ parcelable LeAudioDeviceCapabilities {
+ /**
+ * Codec Identifier
+ */
+ CodecId codecId;
+ /**
+ * Codec capabilities, packed as LTV.
+ */
+ CodecSpecificCapabilitiesLtv[] codecSpecificCapabilities;
+ /**
+ * Vendor codec specific capabilities.
+ *
+ * This will not be parsed by the BT stack, but passed to the vendor
+ * module who can interpret this and based on that select the proper
+ * vendor specific codec configuration.
+ */
+ @nullable byte[] vendorCodecSpecificCapabilities;
+ /**
+ * Audio capabilities metadata, packed as LTV.
+ */
+ @nullable MetadataLtv[] metadata;
+ }
+
+ @VintfStability
+ parcelable LeAudioDataPathConfiguration {
+ /**
+ * Vendor specific data path identifier
+ */
+ int dataPathId;
+
+ /**
+ * Used in the HCI_LE_Setup_ISO_Data_Path (0x006E).
+ * As defined in Bluetooth Core Specification Version
+ * 5.3, Vol 4, Part E, Sec. 7.8.109: "LE Setup ISO Data Path command".
+ */
+ @VintfStability
+ parcelable IsoDataPathConfiguration {
+ /**
+ * Codec ID - Valid Codec Identifier matching the selected codec
+ */
+ CodecId codecId;
+ /**
+ * Whether the transparent air mode should be set as a coding format
+ * in the HCI_LE_Setup_ISO_Data_Path command, indicating that the
+ * codec is not in the controller.
+ *
+ * If set to true, 0x03 (transparent air mode) will be used as a
+ * Codec_ID coding format and the `byte[] configuration` field shall
+ * remain empty. Otherwise the Codec_ID field will be set to
+ * according to BT specification (0xFF coding format, company ID,
+ * codec ID for vendor codecs, or according to Codec_ID identifiers
+ * defined in the Assigned Numbers for the non-vendor codecs).
+ */
+ boolean isTransparent;
+ /**
+ * Controller delay (in microseconds)
+ */
+ int controllerDelayUs;
+ /**
+ * Codec specific LE Audio ISO data path configuration
+ * must be null when codec ID is 0x03 transparent
+ */
+ @nullable byte[] configuration;
+ }
+
+ /**
+ * Used in HCI_Configure_Data_Path (0x0083)
+ * As defined in Bluetooth Core Specification Version
+ * 5.3, Vol 4, Part E, Sec. 7.3.101: "Configure Data Path command".
+ */
+ @VintfStability
+ parcelable DataPathConfiguration {
+ /**
+ * Vendor specific data path configuration
+ */
+ @nullable byte[] configuration;
+ }
+ /**
+ * Data path configuration
+ */
+ DataPathConfiguration dataPathConfiguration;
+ /**
+ * ISO data path configuration
+ */
+ IsoDataPathConfiguration isoDataPathConfiguration;
+ }
+
+ /* All the LeAudioAseQosConfiguration parameters are defined by the
+ * Bluetooth Audio Stream Control Service specification v.1.0, Sec. 5: "ASE
+ * Control Operations".
+ */
+ @VintfStability
+ parcelable LeAudioAseQosConfiguration {
+ /**
+ * SDU Interval (in microseconds) used in Set CIG Parameters command and
+ * Configure QoS.
+ */
+ int sduIntervalUs;
+ /**
+ * Framing used in Set CIG Parameters command and Configure QoS
+ */
+ Framing framing;
+ /**
+ * Phy used in Set CIG Parameters command and Configure QoS
+ */
+ Phy[] phy;
+ /**
+ * Max transport latency (in milliseconds) used in Set CIG Parameters
+ * command and Configure QoS.
+ */
+ int maxTransportLatencyMs;
+ /**
+ * Max SDU used in Set CIG Parameters command and Configure QoS
+ */
+ int maxSdu;
+ /**
+ * Retransmission number used in Set CIG Parameters command and
+ * Configure QoS
+ */
+ int retransmissionNum;
+ }
+
+ /**
+ * Connected Isochronous Channel arrangement within the Connected
+ * Isochronous Group. As defined in Bluetooth Core Specification Version
+ * 5.3, Vol 4, Part E, Sec. 7.8.97.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum Packing {
+ SEQUENTIAL = 0x00,
+ INTERLEAVED = 0x01,
+ }
+
+ /**
+ * Isochronous Data PDU framing parameter. As defined in Bluetooth Core
+ * Specification Version 5.3, Vol 4, Part E, Sec. 7.8.97.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum Framing {
+ UNFRAMED = 0x00,
+ FRAMED = 0x01,
+ }
+
+ @VintfStability
+ parcelable LeAudioAseConfigurationSetting {
+ /**
+ * Audio Context that this configuration apply to
+ */
+ AudioContext audioContext;
+ /**
+ * Sequential or interleave packing used in Set CIG Parameters command
+ */
+ Packing packing;
+
+ @VintfStability
+ parcelable AseDirectionConfiguration {
+ /**
+ * ASE configuration
+ */
+ LeAudioAseConfiguration aseConfiguration;
+ /**
+ * QoS Configuration
+ */
+ @nullable LeAudioAseQosConfiguration qosConfiguration;
+ /**
+ * Data path configuration
+ * If not provided, getLeAudioAseDatapathConfiguration() will be
+ * called during the configuration, increasing the stream
+ * establishment time (not recommended).
+ */
+ @nullable LeAudioDataPathConfiguration dataPathConfiguration;
+ }
+ /**
+ * Sink ASEs configuration
+ */
+ @nullable List<AseDirectionConfiguration> sinkAseConfiguration;
+ /**
+ * Source ASEs configuration
+ */
+ @nullable List<AseDirectionConfiguration> sourceAseConfiguration;
+ /**
+ * Additional flags, used for configurations with special features
+ */
+ @nullable ConfigurationFlags flags;
+ }
+
+ /**
+ * ASE configuration requirements set by the BT stack.
+ */
+ @VintfStability
+ parcelable LeAudioConfigurationRequirement {
+ /**
+ * Audio Contect that this requirements apply to
+ */
+ AudioContext audioContext;
+
+ @VintfStability
+ parcelable AseDirectionRequirement {
+ /**
+ * Optional ASE configurations requirements
+ *
+ * Note that the Host can set as many or as little parameters in
+ * the `aseConfiguration.codecConfiguration` field as needed, to
+ * closely or loosely specify the requirements. If any parameter
+ * is not specified, the offloader can choose it freely. The
+ * offloader should put all the specified parameters into the
+ * `aseConfiguration.codecConfiguration` field of the returned
+ * configuration to let the BT stack verify if the requirements
+ * were met. The mandatory requirement set by the BT stack will be
+ * the Audio Location.
+ */
+ LeAudioAseConfiguration aseConfiguration;
+ }
+ /**
+ * Sink ASEs configuration setting
+ */
+ @nullable List<AseDirectionRequirement> sinkAseRequirement;
+ /**
+ * Source ASEs configuration setting
+ */
+ @nullable List<AseDirectionRequirement> sourceAseRequirement;
+ /**
+ * Additional flags, used to request configurations with special
+ * features
+ */
+ @nullable ConfigurationFlags flags;
+ }
+
+ /**
+ * Method that returns a proposed ASE configuration settings for each
+ * requested audio context type
+ *
+ * Note: _ENCODING session provides SINK ASE configuration
+ * and _DECODING session provides SOURCE ASE configuration unless
+ * BluetoothAudioProvider sets supportsMultidirectionalCapabilities to
+ * true in ProviderInfo.
+ * If supportsMultidirectionalCapabilities is set to true then the
+ * BluetoothStack expects to get configuration list for SINK and SOURCE
+ * on either _ENCODING or _DECODING session.
+ *
+ * @param remoteSinkAudioCapabilities List of remote sink capabilities
+ * supported by an active group devices.
+ * @param remoteSourceAudioCapabilities List of remote source capabilities
+ * supported by an active group devices.
+ * @param requirements ASE configuration requirements
+ *
+ * @return List<LeAudioAseConfigurationSetting>
+ */
+ List<LeAudioAseConfigurationSetting> getLeAudioAseConfiguration(
+ in @nullable List<LeAudioDeviceCapabilities> remoteSinkAudioCapabilities,
+ in @nullable List<LeAudioDeviceCapabilities> remoteSourceAudioCapabilities,
+ in List<LeAudioConfigurationRequirement> requirements);
+
+ @VintfStability
+ parcelable LeAudioAseQosConfigurationRequirement {
+ /**
+ * Audio Contect Type that this requirements apply to
+ */
+ AudioContext contextType;
+
+ /**
+ * QoS preferences received in Codec Configured ASE state. As defined in
+ * bluetooth service specification: Audio Stream Control Service" V1.0,
+ * Sec. 4.1 Audio Stream Endpoints, Table 4.3:"Additional_ASE_Parameters
+ * format when ASE_State = 0x01 (Codec Configured)".
+ */
+ @VintfStability
+ parcelable AseQosDirectionRequirement {
+ /**
+ * Support for unframed Isochronous Adaptation Layer PDUs.
+ * When set to FRAMED, the unframed PDUs are not supported.
+ */
+ Framing framing;
+ /**
+ * Preferred value for the PHY parameter to be written by the client
+ * for this ASE in the Config QoS operation
+ */
+ Phy[] preferredPhy;
+ /**
+ * Preferred value for the Retransmission Number parameter to be
+ * written by the client for this ASE in the Config QoS operation.
+ */
+ int preferredRetransmissionNum;
+ /**
+ * Preferred value for the Max Transport Latency parameter to be
+ * written by the client for this ASE in the Config QoS operation.
+ */
+ int maxTransportLatencyMs;
+ /**
+ * Minimum server supported Presentation Delay (in microseconds) for
+ * an ASE.
+ */
+ int presentationDelayMinUs;
+ /**
+ * Maximum server supported Presentation Delay (in microseconds) for
+ * an ASE.
+ */
+ int presentationDelayMaxUs;
+ /**
+ * Preferred minimum Presentation Delay (in microseconds) for an
+ * ASE.
+ */
+ int preferredPresentationDelayMinUs;
+ /**
+ * Preferred maximum Presentation Delay (in microseconds) for an
+ * ASE.
+ */
+ int preferredPresentationDelayMaxUs;
+
+ /**
+ * ASE configuration
+ */
+ LeAudioAseConfiguration aseConfiguration;
+ }
+ /**
+ * Sink ASEs configuration setting
+ */
+ @nullable AseQosDirectionRequirement sinkAseQosRequirement;
+ /**
+ * Source ASEs configuration setting
+ */
+ @nullable AseQosDirectionRequirement sourceAseQosRequirement;
+ /**
+ * Additional configuration flags requirements
+ */
+ @nullable ConfigurationFlags flags;
+ }
+
+ /**
+ * A directional pair for QoS configuration. Either one or both directions
+ * can be set, depending on the audio context and the requirements provided
+ * to getLeAudioAseQosConfiguration().
+ */
+ @VintfStability
+ parcelable LeAudioAseQosConfigurationPair {
+ @nullable LeAudioAseQosConfiguration sinkQosConfiguration;
+ @nullable LeAudioAseQosConfiguration sourceQosConfiguration;
+ }
+
+ /**
+ * Method that returns an ASE QoS configuration settings for the given ASE
+ * configuration,taking an ASE preferenced QoS parameters. It should be used
+ * to negotiaite the QoS parameters, when the initialy received QoS
+ * parameters are not within the boundaries received from the remote device
+ * after configuring the ASEs.
+ *
+ * @param qosRequirement ASE QoS configurations requirements
+ *
+ * @return LeAudioAseQosConfigurationPair
+ */
+ LeAudioAseQosConfigurationPair getLeAudioAseQosConfiguration(
+ in LeAudioAseQosConfigurationRequirement qosRequirement);
+
+ /**
+ * Audio data path configuration.
+ */
+ parcelable LeAudioDataPathConfigurationPair {
+ /* Host to Controller data path */
+ @nullable LeAudioDataPathConfiguration inputConfig;
+ /* Controller to Host data path */
+ @nullable LeAudioDataPathConfiguration outputConfig;
+ }
+
+ /**
+ * Used to get a data path configuration which dynamically depends on CIS
+ * connection handles in StreamMap. This is used if non-dynamic data path
+ * was not provided in LeAudioAseConfigurationSetting. Calling this during
+ * the unicast audio stream establishment might slightly delay the stream
+ * start.
+ */
+ LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(
+ in AudioContext context, in StreamMap[] streamMap);
+
+ /*
+ * Audio Stream Endpoint state used to report Metadata changes on the remote
+ * device audio endpoints.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum AseState {
+ ENABLING = 0x00,
+ STREAMING = 0x01,
+ DISABLING = 0x02,
+ }
+
+ /**
+ * Used to report metadata changes to the provider. This allows for a
+ * pseudo communication channel between the remote device and the provider,
+ * using the vendor specific metadata of the changing ASE state.
+ * It is used only when ASE is using configurations marked with the
+ * `PROVIDE_ASE_METADATA` flag.
+ */
+ void onSinkAseMetadataChanged(
+ in AseState state, int cigId, int cisId, in @nullable MetadataLtv[] metadata);
+ void onSourceAseMetadataChanged(
+ in AseState state, int cigId, int cisId, in @nullable MetadataLtv[] metadata);
+
+ /**
+ * Broadcast quality index
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum BroadcastQuality {
+ STANDARD,
+ HIGH,
+ }
+
+ /**
+ * It is used in LeAudioBroadcastConfigurationRequirement
+ */
+ @VintfStability
+ parcelable LeAudioBroadcastSubgroupConfigurationRequirement {
+ /**
+ * Streaming Audio Context for the given subgroup.
+ * This can serve as a hint for selecting the proper configuration by
+ * the offloader.
+ */
+ AudioContext context;
+ /**
+ * Streaming Broadcast Audio Quality
+ */
+ BroadcastQuality quality;
+ /**
+ * Number of BISes for the given subgroup
+ */
+ int bisNumPerSubgroup;
+ }
+
+ /**
+ * It is used in getLeAudioBroadcastConfiguration method
+ * If any group id is provided, the Provider should check Pacs capabilities
+ * of the group(s) and provide Broadcast configuration supported by the
+ * group.
+ */
+ @VintfStability
+ parcelable LeAudioBroadcastConfigurationRequirement {
+ List<LeAudioBroadcastSubgroupConfigurationRequirement> subgroupConfigurationRequirements;
+ }
+
+ /**
+ * Subgroup BIS configuration
+ *
+ */
+ @VintfStability
+ parcelable LeAudioSubgroupBisConfiguration {
+ /**
+ * The number of BISes with the given configuration
+ */
+ int numBis;
+ /**
+ * LE Audio BIS configuration for the `numBis` number of BISes
+ */
+ LeAudioBisConfiguration bisConfiguration;
+ }
+
+ /**
+ * Subgroup configuration with a list of BIS configurations
+ *
+ */
+ @VintfStability
+ parcelable LeAudioBroadcastSubgroupConfiguration {
+ List<LeAudioSubgroupBisConfiguration> bisConfigurations;
+
+ /**
+ * Vendor specific codec configuration for all the BISes inside this
+ * subgroup. Only the vendor specific part is needed, since the BT stack
+ * can derive the common subgroup configuration by intersecting the LTV
+ * formatted configuration of every BIS inside the subgroup.
+ * This will not be parsed by the BT stack but will be set as the codec
+ * specific configuration for the ongoing audio stream at the subgroup
+ * level of the audio announcement,The remote device will receive this
+ * information when being configured for receiveing a brodcast audio
+ * stream.
+ */
+ @nullable byte[] vendorCodecConfiguration;
+ }
+
+ /**
+ * LeAudioBroadcastConfigurationSetting is a result of
+ * getLeAudioBroadcastConfiguration. It is used in HCI_LE_Create_BIG command
+ * and for creating the Broadcast Announcements.
+ *
+ */
+ @VintfStability
+ parcelable LeAudioBroadcastConfigurationSetting {
+ /**
+ * SDU Interval (in microseconds) used in LE Create BIG command
+ */
+ int sduIntervalUs;
+ /**
+ * Total number of BISes in the BIG
+ */
+ int numBis;
+ /**
+ * Maximum size of an SDU in octets
+ */
+ int maxSduOctets;
+ /**
+ * Maximum transport latency (in milliseconds)
+ */
+ int maxTransportLatencyMs;
+ /**
+ * The number of times every PDU should be retransmitted
+ */
+ int retransmitionNum;
+ /**
+ * A list of PHYs used for transmission of PDUs of BISes in the BIG.
+ */
+ Phy[] phy;
+ /**
+ * The preferred method of arranging subevents of multiple BISes
+ */
+ Packing packing;
+ /**
+ * format for sending BIS Data PDUs
+ */
+ Framing framing;
+
+ /**
+ * Data path configuration
+ * If not provided, getLeAudioBroadcastDatapathConfiguration() will be
+ * called during the configuration, increasing the stream establishment
+ * time (not recommended).
+ */
+ @nullable LeAudioDataPathConfiguration dataPathConfiguration;
+
+ /**
+ * A list of subgroup configurations in the broadcast.
+ */
+ List<LeAudioBroadcastSubgroupConfiguration> subgroupsConfigurations;
+ }
+
+ /**
+ * Get Broadcast configuration. Output of this function will be used
+ * in HCI_LE_Create_BIG (0x0068) command and also to create BIG INFO
+ *
+ */
+ LeAudioBroadcastConfigurationSetting getLeAudioBroadcastConfiguration(
+ in @nullable List<LeAudioDeviceCapabilities> remoteSinkAudioCapabilities,
+ in LeAudioBroadcastConfigurationRequirement requirement);
+
+ /**
+ * Used to get a data path configuration which dynamically depends on BIS
+ * handles in BroadcastStreamMap. This is used if non-dynamic data path was
+ * not provided in LeAudioBroadcastConfigurationSetting. Calling this during
+ * the broadcast audio stream establishment might slightly delay the stream
+ * start.
+ */
+ LeAudioDataPathConfiguration getLeAudioBroadcastDatapathConfiguration(
+ in AudioContext context, in BroadcastStreamMap[] streamMap);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index b9cec2d..ea9c4e1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -69,19 +69,33 @@
* General information relative to a provider
* - An optional name
* - A list of codec information
+ * - supportsMultidirectionalCapabilities if is set to false it means each
+ * session i.e. _ENCODING and _DECODING is responsible to provide
+ * configuration for a single direction:
+ * _ENCODING for SINK ASE
+ * _DECODING for SOURCE ASE
+ *
+ * If supportsMultidirectionalCapabilities is set to true, then either
+ * _ENCODING or _DECODING session can provide the configurations for either
+ * direction.
*/
@VintfStability
parcelable ProviderInfo {
String name;
CodecInfo[] codecInfos;
+ boolean supportsMultidirectionalCapabilities;
}
/**
* Get general information relative to a provider.
*
+ * This can be called at any time, or just once during the BT stack
+ * initialization.
+ *
* @param sessionType Hardware Offload provider (*_HARDWARE_OFFLOAD_*)
* @return General information relative to the provider.
- * The `null` value can be returned when the provider is not available
+ * The `null` value can be returned when the provider is not
+ * available
*/
@nullable ProviderInfo getProviderInfo(in SessionType sessionType);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
new file mode 100644
index 0000000..9fb2ecf
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2023 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.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv;
+import android.hardware.bluetooth.audio.MetadataLtv;
+import android.hardware.bluetooth.audio.Phy;
+
+/**
+ * All the LeAudioAseConfiguration parameters are defined by the Bluetooth Audio
+ * Stream Control Service specification v.1.0, Sec. 5: "ASE Control Operations".
+ */
+@VintfStability
+parcelable LeAudioAseConfiguration {
+ @VintfStability
+ @Backing(type="byte")
+ enum TargetLatency {
+ UNDEFINED = 0x00,
+ LOWER = 0x01,
+ BALANCED_LATENCY_RELIABILITY = 0x02,
+ HIGHER_RELIABILITY = 0x03,
+ }
+
+ /**
+ * Target latency used in Configure Codec command - Can be UNDEFINED when
+ * used inside the AseDirectionRequirement, but shall not be UNDEFINED when
+ * used inside LeAudioAseConfigurationSetting.
+ */
+ TargetLatency targetLatency;
+
+ /**
+ * Target PHY used in Configure Codec command - Can be UNDEFINED when used
+ * inside the AseDirectionRequirement, but shall not be UNDEFINED when used
+ * inside LeAudioAseConfigurationSetting.
+ */
+ Phy targetPhy;
+
+ /**
+ * Codec ID - Can be Null when used inside the AseDirectionRequirement, but
+ * shall not be Null when used inside LeAudioAseConfigurationSetting.
+ */
+ @nullable CodecId codecId;
+
+ /**
+ * Codec configuration for ASE represented in the LTV types defined by
+ * Bluetooth SIG. Regardless of vendor specific configuration being used or
+ * not, this shall contain Bluetooth LTV types describing the common stream
+ * parameters, at least CodecSpecificConfigurationLtv.SamplingFrequency and
+ * CodecSpecificConfigurationLtv.AudioChannelAllocation. In addition, it
+ * should match aseConfiguration provided in LeAudioConfigurationRequirement
+ * as this will also be used to verify the requirements on the known LTV
+ * types.
+ */
+ CodecSpecificConfigurationLtv[] codecConfiguration;
+
+ /**
+ * Vendor specific codec configuration for ASE.
+ *
+ * This will not be parsed by the BT stack but will be written to the remote
+ * device as the codec specific configuration as part of the codec configure
+ * control point operation. If this is populated, only the
+ * `vendorCodecConfiguration` will be used for the ASE configuration,
+ * otherwise `codecConfiguration` will be used. The BT stack will not merge
+ * it with the codecConfiguration for any purpose.
+ */
+ @nullable byte[] vendorCodecConfiguration;
+
+ /**
+ * Metadata, packed as LTV - used to enable ASE. This is optional
+ */
+ @nullable MetadataLtv[] metadata;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
new file mode 100644
index 0000000..4d6cfde
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 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.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv;
+import android.hardware.bluetooth.audio.MetadataLtv;
+
+/**
+ * LE Audio BIS configuration. This will be part of the streaming broadcast
+ * audio announcement advertised by the BT stack during the broadcast audio
+ * stream to inform the remote devices about the broadcast audio configuration.
+ * It will also be passed back to the vendor module as part of the currently
+ * active LeAudioBroadcastConfiguration for the encoder setup.
+ * As defined in Bluetooth Basic Audio Profile Specification, v.1.0.1,
+ * Sec. 3.7.2.2, Table 3.15, Level 3.
+ */
+@VintfStability
+parcelable LeAudioBisConfiguration {
+ /**
+ * Codec ID
+ */
+ CodecId codecId;
+
+ /**
+ * Codec configuration for BIS or group of BISes represented in the LTV
+ * types defined by Bluetooht SIG. Regardless of vendor specific
+ * configuration being used or not, this shall contain Bluetooth LTV types
+ * describing the common stream parameters, at least
+ * CodecSpecificConfigurationLtv.SamplingFrequency and
+ * CodecSpecificConfigurationLtv.AudioChannelAllocation.
+ * This will also be used to verify the requirements on the known LTV types.
+ */
+ CodecSpecificConfigurationLtv[] codecConfiguration;
+
+ /**
+ * Vendor specific codec configuration.
+ * This will not be parsed by the BT stack but will be set as the codec
+ * specific configuration for the ongoing audio stream, encoded by the
+ * vendor module. The remote device will receive this information when being
+ * configured for receiveing a brodcast audio stream. If this is populated,
+ * only the `vendorCodecConfiguration` will be used when configuring the
+ * remote device, otherwise `codecConfiguration` will be used.
+ */
+ byte[] vendorCodecConfiguration;
+
+ /**
+ * Metadata for the particular BIS or group of BISes. This is optional.
+ */
+ @nullable MetadataLtv[] metadata;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index 16503fb..da90373 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -17,6 +17,8 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.ConfigurationFlags;
+import android.hardware.bluetooth.audio.LeAudioBisConfiguration;
import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
@VintfStability
@@ -39,6 +41,15 @@
* Pcm stream id to identify the source for given streamHandle.
*/
char pcmStreamId;
+ /*
+ * LE Audio BIS configuration
+ */
+ @nullable LeAudioBisConfiguration bisConfiguration;
+ /*
+ * Additional flags, used to request configurations with special
+ * features
+ */
+ @nullable ConfigurationFlags flags;
}
CodecType codecType;
BroadcastStreamMap[] streamMap;
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 7302aea..db753ad 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -17,6 +17,8 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.ConfigurationFlags;
+import android.hardware.bluetooth.audio.LeAudioAseConfiguration;
import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
@VintfStability
@@ -29,16 +31,40 @@
*/
char streamHandle;
/*
- * Audio channel allocation is a bit field, each enabled bit means that given audio
- * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
- * least significant bit to the most significant bit. The valus follows the Bluetooth SIG
- * Audio Location assigned number.
+ * Audio channel allocation is a bit field, each enabled bit means that
+ * given audio direction, i.e. "left", or "right" is used. Ordering of
+ * audio channels comes from the least significant bit to the most
+ * significant bit. The valus follows the Bluetooth SIG Audio Location
+ * assigned number.
*/
int audioChannelAllocation;
/*
* The stream handle status
*/
boolean isStreamActive;
+ /*
+ * LE Audio device ASE configuration
+ */
+ @nullable LeAudioAseConfiguration aseConfiguration;
+ /*
+ * Additional flags, used for configurations with special features
+ */
+ @nullable ConfigurationFlags flags;
+ parcelable BluetoothDeviceAddress {
+ enum DeviceAddressType {
+ BLE_ADDRESS_PUBLIC = 0x00,
+ BLE_ADDRESS_RANDOM = 0x01,
+ }
+ /**
+ * Peer device address. It should be non zero when isStreamActive is true
+ */
+ byte[6] deviceAddress;
+ /**
+ * Peer device address type.
+ */
+ DeviceAddressType deviceAddressType;
+ }
+ @nullable BluetoothDeviceAddress bluetoothDeviceAddress;
}
CodecType codecType;
StreamMap[] streamMap;
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl
new file mode 100644
index 0000000..b0befc1
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 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.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioContext;
+
+/**
+ * Used to exchange generic metadata between the stack and the provider.
+ * As defined in Bluetooth Assigned Numbers, Sec. 6.12.6.
+ */
+@VintfStability
+union MetadataLtv {
+ parcelable PreferredAudioContexts {
+ AudioContext values;
+ }
+ parcelable StreamingAudioContexts {
+ AudioContext values;
+ }
+ /* This is an opaque container for passing metadata between the provider and
+ * the remote device. It must not be interpreted by the BT stack.
+ */
+ parcelable VendorSpecific {
+ int companyId;
+ byte[] opaqueValue;
+ }
+
+ PreferredAudioContexts preferredAudioContexts;
+ StreamingAudioContexts streamingAudioContexts;
+ VendorSpecific vendorSpecific;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl
new file mode 100644
index 0000000..cbffdd5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 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.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used to exchange generic Phy parameter between the stack and the provider.
+ */
+@VintfStability
+@Backing(type="byte")
+enum Phy {
+ UNDEFINED = 0x00,
+ ONE_M = 0x01,
+ TWO_M = 0x02,
+ CODED = 0x03,
+}
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index b88e66a..bdba898 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -187,6 +187,120 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
+ndk::ScopedAStatus BluetoothAudioProvider::setCodecPriority(
+ const ::aidl::android::hardware::bluetooth::audio::CodecId& in_codecId,
+ int32_t in_priority) {
+ /* TODO: Implement */
+ (void)in_codecId;
+ (void)in_priority;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseConfiguration(
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSourceAudioCapabilities,
+ const std::vector<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioConfigurationRequirement>& in_requirements,
+ std::vector<::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
+ _aidl_return) {
+ /* TODO: Implement */
+ (void)in_remoteSinkAudioCapabilities;
+ (void)in_remoteSourceAudioCapabilities;
+ (void)in_requirements;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseQosConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationRequirement& in_qosRequirement,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationPair* _aidl_return) {
+ /* TODO: Implement */
+ (void)in_qosRequirement;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseDatapathConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::AudioContext& in_context,
+ const std::vector<::aidl::android::hardware::bluetooth::audio::
+ LeAudioConfiguration::StreamMap>& in_streamMap,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDataPathConfigurationPair* _aidl_return) {
+ /* TODO: Implement */
+ (void)in_context;
+ (void)in_streamMap;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::onSinkAseMetadataChanged(
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ AseState in_state,
+ int32_t cigId, int32_t cisId,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
+ in_metadata) {
+ /* TODO: Implement */
+ (void)in_state;
+ (void)cigId;
+ (void)cisId;
+ (void)in_metadata;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::onSourceAseMetadataChanged(
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ AseState in_state,
+ int32_t cigId, int32_t cisId,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
+ in_metadata) {
+ /* TODO: Implement */
+ (void)in_state;
+ (void)cigId;
+ (void)cisId;
+ (void)in_metadata;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioBroadcastConfiguration(
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
+ const ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioBroadcastConfigurationRequirement& in_requirement,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioBroadcastConfigurationSetting* _aidl_return) {
+ /* TODO: Implement */
+ (void)in_remoteSinkAudioCapabilities;
+ (void)in_requirement;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus
+BluetoothAudioProvider::getLeAudioBroadcastDatapathConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::AudioContext& in_context,
+ const std::vector<::aidl::android::hardware::bluetooth::audio::
+ LeAudioBroadcastConfiguration::BroadcastStreamMap>&
+ in_streamMap,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDataPathConfiguration* _aidl_return) {
+ /* TODO: Implement */
+ (void)in_context;
+ (void)in_streamMap;
+ (void)_aidl_return;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index 27ab13f..5064869 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -41,14 +41,73 @@
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
- const std::vector<LatencyMode>& latency_modes,
- DataMQDesc* _aidl_return);
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
ndk::ScopedAStatus endSession();
ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status);
ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status);
ndk::ScopedAStatus updateAudioConfiguration(
const AudioConfiguration& audio_config);
ndk::ScopedAStatus setLowLatencyModeAllowed(bool allowed);
+ ndk::ScopedAStatus setCodecPriority(
+ const ::aidl::android::hardware::bluetooth::audio::CodecId& in_codecId,
+ int32_t in_priority) override;
+ ndk::ScopedAStatus getLeAudioAseConfiguration(
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSourceAudioCapabilities,
+ const std::vector<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioConfigurationRequirement>& in_requirements,
+ std::vector<::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
+ _aidl_return) override;
+ ndk::ScopedAStatus getLeAudioAseQosConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+ in_qosRequirement,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationPair* _aidl_return) override;
+ ndk::ScopedAStatus getLeAudioAseDatapathConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::AudioContext&
+ in_context,
+ const std::vector<::aidl::android::hardware::bluetooth::audio::
+ LeAudioConfiguration::StreamMap>& in_streamMap,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDataPathConfigurationPair* _aidl_return) override;
+ ndk::ScopedAStatus onSinkAseMetadataChanged(
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ AseState in_state,
+ int32_t cigId, int32_t cisId,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
+ in_metadata) override;
+ ndk::ScopedAStatus onSourceAseMetadataChanged(
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ AseState in_state,
+ int32_t cigId, int32_t cisId,
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::MetadataLtv>>>&
+ in_metadata) override;
+ ndk::ScopedAStatus getLeAudioBroadcastConfiguration(
+ const std::optional<std::vector<std::optional<
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDeviceCapabilities>>>& in_remoteSinkAudioCapabilities,
+ const ::aidl::android::hardware::bluetooth::audio::
+ IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
+ in_requirement,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioBroadcastConfigurationSetting* _aidl_return) override;
+ ndk::ScopedAStatus getLeAudioBroadcastDatapathConfiguration(
+ const ::aidl::android::hardware::bluetooth::audio::AudioContext&
+ in_context,
+ const std::vector<::aidl::android::hardware::bluetooth::audio::
+ LeAudioBroadcastConfiguration::BroadcastStreamMap>&
+ in_streamMap,
+ ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
+ LeAudioDataPathConfiguration* _aidl_return) override;
ndk::ScopedAStatus parseA2dpConfiguration(
const CodecId& codec_id, const std::vector<uint8_t>& configuration,
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
index 3a64c4d..e55a434 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -37,6 +37,9 @@
namespace bluetooth {
namespace audio {
+static const std::string kLeAudioOffloadProviderName =
+ "LE_AUDIO_OFFLOAD_HARDWARE_OFFLOAD_PROVIDER";
+
BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {}
ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider(
@@ -151,6 +154,8 @@
SessionType session_type, std::optional<ProviderInfo>* _aidl_return) {
*_aidl_return = std::nullopt;
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type);
+
if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
auto& provider_info = _aidl_return->emplace();
@@ -160,6 +165,23 @@
provider_info.codecInfos.push_back(codec->info);
}
+ if (session_type ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type ==
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+ std::vector<CodecInfo> db_codec_info =
+ BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(session_type);
+ if (!db_codec_info.empty()) {
+ auto& provider_info = _aidl_return->emplace();
+ provider_info.name = kLeAudioOffloadProviderName;
+ provider_info.codecInfos = db_codec_info;
+ *_aidl_return = provider_info;
+ return ndk::ScopedAStatus::ok();
+ }
+ }
+
return ndk::ScopedAStatus::ok();
}
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 7f610ef..cff3b25 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -28,6 +28,73 @@
namespace bluetooth {
namespace audio {
+constexpr uint8_t kLeAudioDirectionSink = 0x01;
+constexpr uint8_t kLeAudioDirectionSource = 0x02;
+
+const std::map<CodecSpecificConfigurationLtv::SamplingFrequency, uint32_t>
+ freq_to_support_bitmask_map = {
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ11025},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ22050,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ22050},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ24000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ24000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ32000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ48000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ88200,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ88200},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ96000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ96000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ176400,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ176400},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ192000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ192000},
+ {CodecSpecificConfigurationLtv::SamplingFrequency::HZ384000,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ384000},
+};
+
+// Helper map from capability's tag to configuration's tag
+std::map<CodecSpecificCapabilitiesLtv::Tag, CodecSpecificConfigurationLtv::Tag>
+ cap_to_cfg_tag_map = {
+ {CodecSpecificCapabilitiesLtv::Tag::supportedSamplingFrequencies,
+ CodecSpecificConfigurationLtv::Tag::samplingFrequency},
+ {CodecSpecificCapabilitiesLtv::Tag::supportedMaxCodecFramesPerSDU,
+ CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU},
+ {CodecSpecificCapabilitiesLtv::Tag::supportedFrameDurations,
+ CodecSpecificConfigurationLtv::Tag::frameDuration},
+ {CodecSpecificCapabilitiesLtv::Tag::supportedAudioChannelCounts,
+ CodecSpecificConfigurationLtv::Tag::audioChannelAllocation},
+ {CodecSpecificCapabilitiesLtv::Tag::supportedOctetsPerCodecFrame,
+ CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame},
+};
+
+const std::map<CodecSpecificConfigurationLtv::FrameDuration, uint32_t>
+ fduration_to_support_fduration_map = {
+ {CodecSpecificConfigurationLtv::FrameDuration::US7500,
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500},
+ {CodecSpecificConfigurationLtv::FrameDuration::US10000,
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000},
+};
+
+std::map<int32_t, CodecSpecificConfigurationLtv::SamplingFrequency>
+ sampling_freq_map = {
+ {16000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000},
+ {48000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000},
+ {96000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ96000},
+};
+
+std::map<int32_t, CodecSpecificConfigurationLtv::FrameDuration>
+ frame_duration_map = {
+ {7500, CodecSpecificConfigurationLtv::FrameDuration::US7500},
+ {10000, CodecSpecificConfigurationLtv::FrameDuration::US10000},
+};
+
LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider()
: LeAudioOffloadAudioProvider() {
session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
@@ -70,8 +137,8 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- return BluetoothAudioProvider::startSession(
- host_if, audio_config, latency_modes, _aidl_return);
+ return BluetoothAudioProvider::startSession(host_if, audio_config,
+ latency_modes, _aidl_return);
}
ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady(
@@ -81,6 +148,644 @@
*_aidl_return = DataMQDesc();
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::setCodecPriority(
+ const CodecId& in_codecId, int32_t in_priority) {
+ codec_priority_map_[in_codecId] = in_priority;
+ return ndk::ScopedAStatus::ok();
+};
+
+bool LeAudioOffloadAudioProvider::isMatchedValidCodec(CodecId cfg_codec,
+ CodecId req_codec) {
+ auto priority = codec_priority_map_.find(cfg_codec);
+ if (priority != codec_priority_map_.end() && priority->second == -1)
+ return false;
+ return cfg_codec == req_codec;
+}
+
+bool LeAudioOffloadAudioProvider::isCapabilitiesMatchedContext(
+ AudioContext setting_context,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) {
+ // If has no metadata, assume match
+ if (!capabilities.metadata.has_value()) return true;
+
+ for (auto metadata : capabilities.metadata.value()) {
+ if (!metadata.has_value()) continue;
+ if (metadata.value().getTag() == MetadataLtv::Tag::preferredAudioContexts) {
+ // Check all pref audio context to see if anything matched
+ auto& context = metadata.value()
+ .get<MetadataLtv::Tag::preferredAudioContexts>()
+ .values;
+ if (setting_context.bitmask & context.bitmask) return true;
+ }
+ }
+
+ return false;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedSamplingFreq(
+ CodecSpecificConfigurationLtv::SamplingFrequency& cfg_freq,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies&
+ capability_freq) {
+ for (auto [freq, bitmask] : freq_to_support_bitmask_map)
+ if (cfg_freq == freq) return (capability_freq.bitmask & bitmask);
+ return false;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedFrameDuration(
+ CodecSpecificConfigurationLtv::FrameDuration& cfg_fduration,
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations&
+ capability_fduration) {
+ for (auto [fduration, bitmask] : fduration_to_support_fduration_map)
+ if (cfg_fduration == fduration)
+ return (capability_fduration.bitmask & bitmask);
+ return false;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedAudioChannel(
+ CodecSpecificConfigurationLtv::AudioChannelAllocation&
+ /*cfg_channel*/,
+ CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts&
+ /*capability_channel*/) {
+ bool isMatched = true;
+ // TODO: how to match?
+ return isMatched;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedCodecFramesPerSDU(
+ CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU& cfg_frame_sdu,
+ CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU&
+ capability_frame_sdu) {
+ return cfg_frame_sdu.value <= capability_frame_sdu.value;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedOctetsPerCodecFrame(
+ CodecSpecificConfigurationLtv::OctetsPerCodecFrame& cfg_octets,
+ CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame&
+ capability_octets) {
+ return cfg_octets.value >= capability_octets.minimum &&
+ cfg_octets.value <= capability_octets.maximum;
+}
+
+bool LeAudioOffloadAudioProvider::isCapabilitiesMatchedCodecConfiguration(
+ std::vector<CodecSpecificConfigurationLtv>& codec_cfg,
+ std::vector<CodecSpecificCapabilitiesLtv> codec_capabilities) {
+ // Convert all codec_cfg into a map of tags -> correct data
+ std::map<CodecSpecificConfigurationLtv::Tag, CodecSpecificConfigurationLtv>
+ cfg_tag_map;
+ for (auto codec_cfg_data : codec_cfg)
+ cfg_tag_map[codec_cfg_data.getTag()] = codec_cfg_data;
+
+ for (auto& codec_capability : codec_capabilities) {
+ auto cfg = cfg_tag_map.find(cap_to_cfg_tag_map[codec_capability.getTag()]);
+ // Cannot find tag for the capability:
+ if (cfg == cfg_tag_map.end()) return false;
+
+ // Matching logic for sampling frequency
+ if (codec_capability.getTag() ==
+ CodecSpecificCapabilitiesLtv::Tag::supportedSamplingFrequencies) {
+ if (!isMatchedSamplingFreq(
+ cfg->second
+ .get<CodecSpecificConfigurationLtv::Tag::samplingFrequency>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedSamplingFrequencies>()))
+ return false;
+ } else if (codec_capability.getTag() ==
+ CodecSpecificCapabilitiesLtv::Tag::supportedFrameDurations) {
+ if (!isMatchedFrameDuration(
+ cfg->second
+ .get<CodecSpecificConfigurationLtv::Tag::frameDuration>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedFrameDurations>()))
+ return false;
+ } else if (codec_capability.getTag() ==
+ CodecSpecificCapabilitiesLtv::Tag::supportedAudioChannelCounts) {
+ if (!isMatchedAudioChannel(
+ cfg->second.get<
+ CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedAudioChannelCounts>()))
+ return false;
+ } else if (codec_capability.getTag() == CodecSpecificCapabilitiesLtv::Tag::
+ supportedMaxCodecFramesPerSDU) {
+ if (!isMatchedCodecFramesPerSDU(
+ cfg->second.get<
+ CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedMaxCodecFramesPerSDU>()))
+ return false;
+ } else if (codec_capability.getTag() == CodecSpecificCapabilitiesLtv::Tag::
+ supportedOctetsPerCodecFrame) {
+ if (!isMatchedOctetsPerCodecFrame(
+ cfg->second.get<
+ CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame>(),
+ codec_capability.get<CodecSpecificCapabilitiesLtv::Tag::
+ supportedOctetsPerCodecFrame>()))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedAseConfiguration(
+ LeAudioAseConfiguration setting_cfg,
+ LeAudioAseConfiguration requirement_cfg) {
+ // Check matching for codec configuration <=> requirement ASE codec
+ // Also match if no CodecId requirement
+ if (requirement_cfg.codecId.has_value()) {
+ if (!setting_cfg.codecId.has_value()) return false;
+ if (!isMatchedValidCodec(setting_cfg.codecId.value(),
+ requirement_cfg.codecId.value()))
+ return false;
+ }
+
+ if (setting_cfg.targetLatency != requirement_cfg.targetLatency) return false;
+ // Ignore PHY requirement
+
+ // Check all codec configuration
+ std::map<CodecSpecificConfigurationLtv::Tag, CodecSpecificConfigurationLtv>
+ cfg_tag_map;
+ for (auto cfg : setting_cfg.codecConfiguration)
+ cfg_tag_map[cfg.getTag()] = cfg;
+
+ for (auto requirement_cfg : requirement_cfg.codecConfiguration) {
+ // Directly compare CodecSpecificConfigurationLtv
+ auto cfg = cfg_tag_map.find(requirement_cfg.getTag());
+ if (cfg == cfg_tag_map.end()) return false;
+
+ if (cfg->second != requirement_cfg) return false;
+ }
+ // Ignore vendor configuration and metadata requirement
+
+ return true;
+}
+
+bool LeAudioOffloadAudioProvider::isMatchedBISConfiguration(
+ LeAudioBisConfiguration bis_cfg,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) {
+ if (!isMatchedValidCodec(bis_cfg.codecId, capabilities.codecId)) return false;
+ if (!isCapabilitiesMatchedCodecConfiguration(
+ bis_cfg.codecConfiguration, capabilities.codecSpecificCapabilities))
+ return false;
+ return true;
+}
+
+void LeAudioOffloadAudioProvider::filterCapabilitiesAseDirectionConfiguration(
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ direction_configurations,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ valid_direction_configurations) {
+ for (auto direction_configuration : direction_configurations) {
+ if (!direction_configuration.has_value()) continue;
+ if (!direction_configuration.value().aseConfiguration.codecId.has_value())
+ continue;
+ if (!isMatchedValidCodec(
+ direction_configuration.value().aseConfiguration.codecId.value(),
+ capabilities.codecId))
+ continue;
+ // Check matching for codec configuration <=> codec capabilities
+ if (!isCapabilitiesMatchedCodecConfiguration(
+ direction_configuration.value().aseConfiguration.codecConfiguration,
+ capabilities.codecSpecificCapabilities))
+ continue;
+ valid_direction_configurations.push_back(direction_configuration);
+ }
+}
+
+void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration(
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ direction_configurations,
+ const std::optional<std::vector<std::optional<AseDirectionRequirement>>>&
+ requirements,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ valid_direction_configurations) {
+ for (auto direction_configuration : direction_configurations) {
+ if (!requirements.has_value()) {
+ // If there's no requirement, all are valid
+ valid_direction_configurations.push_back(direction_configuration);
+ continue;
+ }
+ if (!direction_configuration.has_value()) continue;
+
+ for (auto& requirement : requirements.value()) {
+ if (!requirement.has_value()) continue;
+ if (!isMatchedAseConfiguration(
+ direction_configuration.value().aseConfiguration,
+ requirement.value().aseConfiguration))
+ continue;
+ // Valid if match any requirement.
+ valid_direction_configurations.push_back(direction_configuration);
+ break;
+ }
+ }
+}
+
+/* Get a new LeAudioAseConfigurationSetting by matching a setting with a
+ * capabilities. The new setting will have a filtered list of
+ * AseDirectionConfiguration that matched the capabilities */
+std::optional<LeAudioAseConfigurationSetting>
+LeAudioOffloadAudioProvider::getCapabilitiesMatchedAseConfigurationSettings(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
+ uint8_t direction) {
+ // Try to match context in metadata.
+ if (!isCapabilitiesMatchedContext(setting.audioContext, capabilities))
+ return std::nullopt;
+
+ // Get a list of all matched AseDirectionConfiguration
+ // for the input direction
+ std::vector<std::optional<AseDirectionConfiguration>>*
+ direction_configuration = nullptr;
+ if (direction == kLeAudioDirectionSink) {
+ if (!setting.sinkAseConfiguration.has_value()) return std::nullopt;
+ direction_configuration = &setting.sinkAseConfiguration.value();
+ } else {
+ if (!setting.sourceAseConfiguration.has_value()) return std::nullopt;
+ direction_configuration = &setting.sourceAseConfiguration.value();
+ }
+ std::vector<std::optional<AseDirectionConfiguration>>
+ valid_direction_configuration;
+ filterCapabilitiesAseDirectionConfiguration(
+ *direction_configuration, capabilities, valid_direction_configuration);
+ if (valid_direction_configuration.empty()) return std::nullopt;
+
+ // Create a new LeAudioAseConfigurationSetting and return
+ LeAudioAseConfigurationSetting filtered_setting;
+ filtered_setting.audioContext = setting.audioContext;
+ filtered_setting.packing = setting.packing;
+ if (direction == kLeAudioDirectionSink) {
+ filtered_setting.sinkAseConfiguration = valid_direction_configuration;
+ } else {
+ filtered_setting.sourceAseConfiguration = valid_direction_configuration;
+ }
+ filtered_setting.flags = setting.flags;
+
+ return filtered_setting;
+}
+
+/* Get a new LeAudioAseConfigurationSetting by matching a setting with a
+ * requirement. The new setting will have a filtered list of
+ * AseDirectionConfiguration that matched the requirement */
+std::optional<LeAudioAseConfigurationSetting>
+LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
+ requirement) {
+ // Try to match context in metadata.
+ if (setting.audioContext != requirement.audioContext) return std::nullopt;
+
+ // Check requirement for the correct direction
+ const std::optional<std::vector<std::optional<AseDirectionRequirement>>>*
+ direction_requirement;
+ std::vector<std::optional<AseDirectionConfiguration>>*
+ direction_configuration;
+ if (setting.sinkAseConfiguration.has_value()) {
+ direction_configuration = &setting.sinkAseConfiguration.value();
+ direction_requirement = &requirement.sinkAseRequirement;
+ } else {
+ direction_configuration = &setting.sourceAseConfiguration.value();
+ direction_requirement = &requirement.sourceAseRequirement;
+ }
+
+ std::vector<std::optional<AseDirectionConfiguration>>
+ valid_direction_configuration;
+ filterRequirementAseDirectionConfiguration(*direction_configuration,
+ *direction_requirement,
+ valid_direction_configuration);
+ if (valid_direction_configuration.empty()) return std::nullopt;
+
+ // Create a new LeAudioAseConfigurationSetting and return
+ LeAudioAseConfigurationSetting filtered_setting;
+ filtered_setting.audioContext = setting.audioContext;
+ filtered_setting.packing = setting.packing;
+ if (setting.sinkAseConfiguration.has_value())
+ filtered_setting.sinkAseConfiguration = valid_direction_configuration;
+ else
+ filtered_setting.sourceAseConfiguration = valid_direction_configuration;
+ filtered_setting.flags = setting.flags;
+
+ return filtered_setting;
+}
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration(
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSinkAudioCapabilities,
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSourceAudioCapabilities,
+ const std::vector<IBluetoothAudioProvider::LeAudioConfigurationRequirement>&
+ in_requirements,
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
+ _aidl_return) {
+ // Get all configuration settings
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ ase_configuration_settings =
+ BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
+
+ // Currently won't handle case where both sink and source capabilities
+ // are passed in. Only handle one of them.
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>*
+ in_remoteAudioCapabilities;
+ uint8_t direction = 0;
+ if (in_remoteSinkAudioCapabilities.has_value()) {
+ direction = kLeAudioDirectionSink;
+ in_remoteAudioCapabilities = &in_remoteSinkAudioCapabilities;
+ } else {
+ direction = kLeAudioDirectionSource;
+ in_remoteAudioCapabilities = &in_remoteSourceAudioCapabilities;
+ }
+
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ capability_matched_ase_configuration_settings;
+ // Matching with remote capabilities
+ for (auto& setting : ase_configuration_settings) {
+ for (auto& capability : in_remoteAudioCapabilities->value()) {
+ if (!capability.has_value()) continue;
+ auto filtered_ase_configuration_setting =
+ getCapabilitiesMatchedAseConfigurationSettings(
+ setting, capability.value(), direction);
+ if (filtered_ase_configuration_setting.has_value()) {
+ capability_matched_ase_configuration_settings.push_back(
+ filtered_ase_configuration_setting.value());
+ }
+ }
+ }
+
+ // Matching with requirements
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting> result;
+ for (auto& setting : capability_matched_ase_configuration_settings) {
+ for (auto& requirement : in_requirements) {
+ auto filtered_ase_configuration_setting =
+ getRequirementMatchedAseConfigurationSettings(setting, requirement);
+ if (filtered_ase_configuration_setting.has_value()) {
+ result.push_back(filtered_ase_configuration_setting.value());
+ }
+ }
+ }
+
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+};
+
+bool LeAudioOffloadAudioProvider::isMatchedQosRequirement(
+ LeAudioAseQosConfiguration setting_qos,
+ AseQosDirectionRequirement requirement_qos) {
+ if (setting_qos.retransmissionNum !=
+ requirement_qos.preferredRetransmissionNum)
+ return false;
+ if (setting_qos.maxTransportLatencyMs > requirement_qos.maxTransportLatencyMs)
+ return false;
+ // Ignore other parameters, as they are not populated in the setting_qos
+ return true;
+}
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration(
+ const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+ in_qosRequirement,
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return) {
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+ // Get all configuration settings
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+ ase_configuration_settings =
+ BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
+
+ // Direction QoS matching
+ // Only handle one direction input case
+ uint8_t direction = 0;
+ std::optional<AseQosDirectionRequirement> direction_qos_requirement =
+ std::nullopt;
+ if (in_qosRequirement.sinkAseQosRequirement.has_value()) {
+ direction_qos_requirement = in_qosRequirement.sinkAseQosRequirement.value();
+ direction = kLeAudioDirectionSink;
+ } else if (in_qosRequirement.sourceAseQosRequirement.has_value()) {
+ direction_qos_requirement =
+ in_qosRequirement.sourceAseQosRequirement.value();
+ direction = kLeAudioDirectionSource;
+ }
+
+ for (auto& setting : ase_configuration_settings) {
+ // Context matching
+ if (setting.audioContext != in_qosRequirement.contextType) continue;
+
+ // Match configuration flags
+ // Currently configuration flags are not populated, ignore.
+
+ // Get a list of all matched AseDirectionConfiguration
+ // for the input direction
+ std::vector<std::optional<AseDirectionConfiguration>>*
+ direction_configuration = nullptr;
+ if (direction == kLeAudioDirectionSink) {
+ if (!setting.sinkAseConfiguration.has_value()) continue;
+ direction_configuration = &setting.sinkAseConfiguration.value();
+ } else {
+ if (!setting.sourceAseConfiguration.has_value()) continue;
+ direction_configuration = &setting.sourceAseConfiguration.value();
+ }
+
+ for (auto cfg : *direction_configuration) {
+ if (!cfg.has_value()) continue;
+ // If no requirement, return the first QoS
+ if (!direction_qos_requirement.has_value()) {
+ result.sinkQosConfiguration = cfg.value().qosConfiguration;
+ result.sourceQosConfiguration = cfg.value().qosConfiguration;
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ // If has requirement, return the first matched QoS
+ // Try to match the ASE configuration
+ // and QoS with requirement
+ if (!cfg.value().qosConfiguration.has_value()) continue;
+ if (isMatchedAseConfiguration(
+ cfg.value().aseConfiguration,
+ direction_qos_requirement.value().aseConfiguration) &&
+ isMatchedQosRequirement(cfg.value().qosConfiguration.value(),
+ direction_qos_requirement.value())) {
+ if (direction == kLeAudioDirectionSink)
+ result.sinkQosConfiguration = cfg.value().qosConfiguration;
+ else
+ result.sourceQosConfiguration = cfg.value().qosConfiguration;
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+ }
+ }
+ }
+
+ // No match, return empty QoS
+ *_aidl_return = result;
+ return ndk::ScopedAStatus::ok();
+};
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSinkAseMetadataChanged(
+ IBluetoothAudioProvider::AseState in_state, int32_t /*in_cigId*/,
+ int32_t /*in_cisId*/,
+ const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata) {
+ (void)in_state;
+ (void)in_metadata;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSourceAseMetadataChanged(
+ IBluetoothAudioProvider::AseState in_state, int32_t /*in_cigId*/,
+ int32_t /*in_cisId*/,
+ const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata) {
+ (void)in_state;
+ (void)in_metadata;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+};
+
+void LeAudioOffloadAudioProvider::getBroadcastSettings() {
+ if (!broadcast_settings.empty()) return;
+
+ LOG(INFO) << __func__ << ": Loading broadcast settings from provider info";
+
+ std::vector<CodecInfo> db_codec_info =
+ BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ broadcast_settings.clear();
+ CodecSpecificConfigurationLtv::AudioChannelAllocation default_allocation;
+ default_allocation.bitmask =
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER;
+
+ for (auto& codec_info : db_codec_info) {
+ if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
+ continue;
+ auto& transport = codec_info.transport.get<CodecInfo::Transport::leAudio>();
+ LeAudioBroadcastConfigurationSetting setting;
+ // Default setting
+ setting.numBis = 1;
+ setting.phy = {Phy::TWO_M};
+ // Populate BIS configuration info using codec_info
+ LeAudioBisConfiguration bis_cfg;
+ bis_cfg.codecId = codec_info.id;
+
+ CodecSpecificConfigurationLtv::OctetsPerCodecFrame octets;
+ octets.value = transport.bitdepth[0];
+
+ bis_cfg.codecConfiguration = {
+ sampling_freq_map[transport.samplingFrequencyHz[0]], octets,
+ frame_duration_map[transport.frameDurationUs[0]], default_allocation};
+
+ // Add information to structure
+ IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration sub_bis_cfg;
+ sub_bis_cfg.numBis = 1;
+ sub_bis_cfg.bisConfiguration = bis_cfg;
+ IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration sub_cfg;
+ sub_cfg.bisConfigurations = {sub_bis_cfg};
+ setting.subgroupsConfigurations = {sub_cfg};
+
+ broadcast_settings.push_back(setting);
+ }
+
+ LOG(INFO) << __func__
+ << ": Done loading broadcast settings from provider info";
+}
+
+/* Get a new LeAudioAseConfigurationSetting by matching a setting with a
+ * capabilities. The new setting will have a filtered list of
+ * AseDirectionConfiguration that matched the capabilities */
+std::optional<LeAudioBroadcastConfigurationSetting>
+LeAudioOffloadAudioProvider::
+ getCapabilitiesMatchedBroadcastConfigurationSettings(
+ LeAudioBroadcastConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities&
+ capabilities) {
+ std::vector<IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration>
+ filter_subgroup;
+ for (auto& sub_cfg : setting.subgroupsConfigurations) {
+ std::vector<IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration>
+ filtered_bis_cfg;
+ for (auto& bis_cfg : sub_cfg.bisConfigurations)
+ if (isMatchedBISConfiguration(bis_cfg.bisConfiguration, capabilities)) {
+ filtered_bis_cfg.push_back(bis_cfg);
+ }
+ if (!filtered_bis_cfg.empty()) {
+ IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration
+ subgroup_cfg;
+ subgroup_cfg.bisConfigurations = filtered_bis_cfg;
+ filter_subgroup.push_back(subgroup_cfg);
+ }
+ }
+ if (filter_subgroup.empty()) return std::nullopt;
+
+ // Create a new LeAudioAseConfigurationSetting and return
+ LeAudioBroadcastConfigurationSetting filtered_setting(setting);
+ filtered_setting.subgroupsConfigurations = filter_subgroup;
+
+ return filtered_setting;
+}
+
+ndk::ScopedAStatus
+LeAudioOffloadAudioProvider::getLeAudioBroadcastConfiguration(
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSinkAudioCapabilities,
+ const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
+ in_requirement,
+ LeAudioBroadcastConfigurationSetting* _aidl_return) {
+ getBroadcastSettings();
+ _aidl_return = nullptr;
+
+ // Match and filter capability
+ std::vector<LeAudioBroadcastConfigurationSetting> filtered_settings;
+ if (!in_remoteSinkAudioCapabilities.has_value()) {
+ LOG(WARNING) << __func__ << ": Empty capability";
+ return ndk::ScopedAStatus::ok();
+ }
+ for (auto& setting : broadcast_settings) {
+ for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
+ if (!capability.has_value()) continue;
+ auto filtered_setting =
+ getCapabilitiesMatchedBroadcastConfigurationSettings(
+ setting, capability.value());
+ if (filtered_setting.has_value())
+ filtered_settings.push_back(filtered_setting.value());
+ }
+ }
+
+ if (filtered_settings.empty()) {
+ LOG(WARNING) << __func__ << ": Cannot match any remote capability";
+ return ndk::ScopedAStatus::ok();
+ }
+
+ // Match and return the first matched requirement
+ if (in_requirement.subgroupConfigurationRequirements.empty()) {
+ LOG(INFO) << __func__ << ": Empty requirement";
+ *_aidl_return = filtered_settings[0];
+ return ndk::ScopedAStatus::ok();
+ }
+
+ for (auto& setting : filtered_settings) {
+ // Further filter out bis configuration
+ LeAudioBroadcastConfigurationSetting filtered_setting(setting);
+ filtered_setting.subgroupsConfigurations.clear();
+ for (auto& sub_cfg : setting.subgroupsConfigurations) {
+ bool isMatched = false;
+ for (auto& sub_req : in_requirement.subgroupConfigurationRequirements) {
+ // Matching number of BIS
+ if (sub_req.bisNumPerSubgroup != sub_cfg.bisConfigurations.size())
+ continue;
+ // Currently will ignore quality and context hint.
+ isMatched = true;
+ break;
+ }
+ if (isMatched)
+ filtered_setting.subgroupsConfigurations.push_back(sub_cfg);
+ }
+ // Return the first match
+ if (!filtered_setting.subgroupsConfigurations.empty()) {
+ LOG(INFO) << __func__ << ": Matched requirement";
+ *_aidl_return = filtered_setting;
+ return ndk::ScopedAStatus::ok();
+ }
+ }
+
+ LOG(WARNING) << __func__ << ": Cannot match any requirement";
+ return ndk::ScopedAStatus::ok();
+};
} // namespace audio
} // namespace bluetooth
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
index 614c794..2785e7f 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -16,7 +16,12 @@
#pragma once
+#include <map>
+
#include "BluetoothAudioProvider.h"
+#include "aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.h"
+#include "aidl/android/hardware/bluetooth/audio/MetadataLtv.h"
+#include "aidl/android/hardware/bluetooth/audio/SessionType.h"
namespace aidl {
namespace android {
@@ -24,6 +29,19 @@
namespace bluetooth {
namespace audio {
+using LeAudioAseConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
+using AseDirectionRequirement = IBluetoothAudioProvider::
+ LeAudioConfigurationRequirement::AseDirectionRequirement;
+using AseDirectionConfiguration = IBluetoothAudioProvider::
+ LeAudioAseConfigurationSetting::AseDirectionConfiguration;
+using AseQosDirectionRequirement = IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
+using LeAudioAseQosConfiguration =
+ IBluetoothAudioProvider::LeAudioAseQosConfiguration;
+using LeAudioBroadcastConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting;
+
class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
public:
LeAudioOffloadAudioProvider();
@@ -33,11 +51,112 @@
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
- const std::vector<LatencyMode>& latency_modes,
- DataMQDesc* _aidl_return);
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
+ ndk::ScopedAStatus setCodecPriority(const CodecId& in_codecId,
+ int32_t in_priority) override;
+ ndk::ScopedAStatus getLeAudioAseConfiguration(
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSinkAudioCapabilities,
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSourceAudioCapabilities,
+ const std::vector<
+ IBluetoothAudioProvider::LeAudioConfigurationRequirement>&
+ in_requirements,
+ std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
+ _aidl_return) override;
+ ndk::ScopedAStatus getLeAudioAseQosConfiguration(
+ const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
+ in_qosRequirement,
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return)
+ override;
+ ndk::ScopedAStatus onSourceAseMetadataChanged(
+ IBluetoothAudioProvider::AseState in_state, int32_t in_cigId,
+ int32_t in_cisId,
+ const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata)
+ override;
+ ndk::ScopedAStatus onSinkAseMetadataChanged(
+ IBluetoothAudioProvider::AseState in_state, int32_t in_cigId,
+ int32_t in_cisId,
+ const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata)
+ override;
+ ndk::ScopedAStatus getLeAudioBroadcastConfiguration(
+ const std::optional<std::vector<
+ std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
+ in_remoteSinkAudioCapabilities,
+ const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
+ in_requirement,
+ LeAudioBroadcastConfigurationSetting* _aidl_return) override;
private:
ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+ std::map<CodecId, uint32_t> codec_priority_map_;
+ std::vector<LeAudioBroadcastConfigurationSetting> broadcast_settings;
+
+ // Private matching function definitions
+ bool isMatchedValidCodec(CodecId cfg_codec, CodecId req_codec);
+ bool isCapabilitiesMatchedContext(
+ AudioContext setting_context,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
+ bool isMatchedSamplingFreq(
+ CodecSpecificConfigurationLtv::SamplingFrequency& cfg_freq,
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies&
+ capability_freq);
+ bool isMatchedFrameDuration(
+ CodecSpecificConfigurationLtv::FrameDuration& cfg_fduration,
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations&
+ capability_fduration);
+ bool isMatchedAudioChannel(
+ CodecSpecificConfigurationLtv::AudioChannelAllocation& cfg_channel,
+ CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts&
+ capability_channel);
+ bool isMatchedCodecFramesPerSDU(
+ CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU& cfg_frame_sdu,
+ CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU&
+ capability_frame_sdu);
+ bool isMatchedOctetsPerCodecFrame(
+ CodecSpecificConfigurationLtv::OctetsPerCodecFrame& cfg_octets,
+ CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame&
+ capability_octets);
+ bool isCapabilitiesMatchedCodecConfiguration(
+ std::vector<CodecSpecificConfigurationLtv>& codec_cfg,
+ std::vector<CodecSpecificCapabilitiesLtv> codec_capabilities);
+ bool isMatchedAseConfiguration(LeAudioAseConfiguration setting_cfg,
+ LeAudioAseConfiguration requirement_cfg);
+ bool isMatchedBISConfiguration(
+ LeAudioBisConfiguration bis_cfg,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
+ void filterCapabilitiesAseDirectionConfiguration(
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ direction_configurations,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ valid_direction_configurations);
+ void filterRequirementAseDirectionConfiguration(
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ direction_configurations,
+ const std::optional<std::vector<std::optional<AseDirectionRequirement>>>&
+ requirements,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ valid_direction_configurations);
+ std::optional<LeAudioAseConfigurationSetting>
+ getCapabilitiesMatchedAseConfigurationSettings(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities,
+ uint8_t direction);
+ std::optional<LeAudioAseConfigurationSetting>
+ getRequirementMatchedAseConfigurationSettings(
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
+ requirement);
+ bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos,
+ AseQosDirectionRequirement requirement_qos);
+ std::optional<LeAudioBroadcastConfigurationSetting>
+ getCapabilitiesMatchedBroadcastConfigurationSettings(
+ LeAudioBroadcastConfigurationSetting& setting,
+ const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
+ void getBroadcastSettings();
};
class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 17be7be..88f2f97 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -46,6 +46,7 @@
using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
+using aidl::android::hardware::bluetooth::audio::AudioContext;
using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
using aidl::android::hardware::bluetooth::audio::ChannelMode;
@@ -54,6 +55,8 @@
using aidl::android::hardware::bluetooth::audio::CodecId;
using aidl::android::hardware::bluetooth::audio::CodecInfo;
using aidl::android::hardware::bluetooth::audio::CodecParameters;
+using aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv;
+using aidl::android::hardware::bluetooth::audio::CodecSpecificConfigurationLtv;
using aidl::android::hardware::bluetooth::audio::CodecType;
using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
@@ -64,11 +67,13 @@
using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
+using aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration;
using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
using aidl::android::hardware::bluetooth::audio::
LeAudioCodecCapabilitiesSetting;
using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
+using aidl::android::hardware::bluetooth::audio::MetadataLtv;
using aidl::android::hardware::bluetooth::audio::OpusCapabilities;
using aidl::android::hardware::bluetooth::audio::OpusConfiguration;
using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
@@ -92,6 +97,21 @@
using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
+using LeAudioAseConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
+using AseDirectionRequirement = IBluetoothAudioProvider::
+ LeAudioConfigurationRequirement::AseDirectionRequirement;
+using AseDirectionConfiguration = IBluetoothAudioProvider::
+ LeAudioAseConfigurationSetting::AseDirectionConfiguration;
+using AseQosDirectionRequirement = IBluetoothAudioProvider::
+ LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
+using LeAudioAseQosConfiguration =
+ IBluetoothAudioProvider::LeAudioAseQosConfiguration;
+using LeAudioDeviceCapabilities =
+ IBluetoothAudioProvider::LeAudioDeviceCapabilities;
+using LeAudioConfigurationRequirement =
+ IBluetoothAudioProvider::LeAudioConfigurationRequirement;
+
// Constants
static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
@@ -197,6 +217,13 @@
virtual void TearDown() override { provider_factory_ = nullptr; }
+ void GetProviderInfoHelper(const SessionType& session_type) {
+ temp_provider_info_ = std::nullopt;
+ auto aidl_reval =
+ provider_factory_->getProviderInfo(session_type, &temp_provider_info_);
+ ASSERT_TRUE(aidl_reval.isOk());
+ }
+
void GetProviderCapabilitiesHelper(const SessionType& session_type) {
temp_provider_capabilities_.clear();
auto aidl_retval = provider_factory_->getProviderCapabilities(
@@ -576,6 +603,8 @@
std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
std::shared_ptr<IBluetoothAudioPort> audio_port_;
std::vector<AudioCapabilities> temp_provider_capabilities_;
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
+ temp_provider_info_;
// temp storage saves the specified codec capability by
// GetOffloadCodecCapabilityHelper()
@@ -1486,7 +1515,7 @@
}
bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
- ChannelMode channel_mode, int32_t data_interval_us) {
+ ChannelMode channel_mode, int32_t data_interval_us) {
PcmConfiguration pcm_config{
.sampleRateHz = sample_rate,
.channelMode = channel_mode,
@@ -1523,9 +1552,9 @@
for (auto sample_rate : hfp_sample_rates_) {
for (auto bits_per_sample : hfp_bits_per_samples_) {
for (auto channel_mode : hfp_channel_modes_) {
- for (auto data_interval_us: hfp_data_interval_us_) {
- EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
- channel_mode, data_interval_us));
+ for (auto data_interval_us : hfp_data_interval_us_) {
+ EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
+ data_interval_us));
EXPECT_TRUE(audio_provider_->endSession().isOk());
}
}
@@ -1553,7 +1582,7 @@
}
bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
- ChannelMode channel_mode, int32_t data_interval_us) {
+ ChannelMode channel_mode, int32_t data_interval_us) {
PcmConfiguration pcm_config{
.sampleRateHz = sample_rate,
.channelMode = channel_mode,
@@ -1587,10 +1616,10 @@
for (auto sample_rate : hfp_sample_rates_) {
for (auto bits_per_sample : hfp_bits_per_samples_) {
for (auto channel_mode : hfp_channel_modes_) {
- for (auto data_interval_us: hfp_data_interval_us_) {
- EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
- channel_mode, data_interval_us));
- EXPECT_TRUE(audio_provider_->endSession().isOk());
+ for (auto data_interval_us : hfp_data_interval_us_) {
+ EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
+ data_interval_us));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
}
}
}
@@ -1870,7 +1899,7 @@
}
bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
- bool controller_codec) {
+ bool controller_codec) {
// Check if can open session with a Hfp configuration
HfpConfiguration hfp_configuration{
.codecId = codec_id,
@@ -2126,6 +2155,8 @@
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ GetProviderInfoHelper(
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@@ -2152,6 +2183,99 @@
return false;
}
+ bool IsOffloadOutputProviderInfoSupported() {
+ if (!temp_provider_info_.has_value()) return false;
+ if (temp_provider_info_.value().codecInfos.empty()) return false;
+ // Check if all codec info is of LeAudio type
+ for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+ if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
+ return false;
+ }
+ return true;
+ }
+
+ std::vector<Lc3Configuration> GetUnicastLc3SupportedListFromProviderInfo() {
+ std::vector<Lc3Configuration> le_audio_codec_configs;
+ for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+ // Only gets LC3 codec information
+ if (codec_info.id != CodecId::Core::LC3) continue;
+ // Combine those parameters into one list of Lc3Configuration
+ auto& transport =
+ codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
+ for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
+ for (int32_t frameDurationUs : transport.frameDurationUs) {
+ for (int32_t octetsPerFrame : transport.bitdepth) {
+ Lc3Configuration lc3_config = {
+ .samplingFrequencyHz = samplingFrequencyHz,
+ .frameDurationUs = frameDurationUs,
+ .octetsPerFrame = octetsPerFrame,
+ };
+ le_audio_codec_configs.push_back(lc3_config);
+ }
+ }
+ }
+ }
+
+ return le_audio_codec_configs;
+ }
+
+ AudioContext GetAudioContext(int32_t bitmask) {
+ AudioContext media_audio_context;
+ media_audio_context.bitmask = bitmask;
+ return media_audio_context;
+ }
+
+ LeAudioDeviceCapabilities GetDefaultRemoteCapability() {
+ // Create a capability
+ LeAudioDeviceCapabilities capability;
+
+ capability.codecId = CodecId::Core::LC3;
+
+ auto pref_context_metadata = MetadataLtv::PreferredAudioContexts();
+ pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA);
+ capability.metadata = {pref_context_metadata};
+
+ auto sampling_rate =
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies();
+ sampling_rate.bitmask =
+ CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000;
+ auto frame_duration =
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations();
+ frame_duration.bitmask =
+ CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500;
+ auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame();
+ octets.minimum = 0;
+ octets.maximum = 60;
+ auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU();
+ frames.value = 2;
+ capability.codecSpecificCapabilities = {sampling_rate, frame_duration,
+ octets, frames};
+ return capability;
+ }
+
+ LeAudioConfigurationRequirement GetDefaultRequirement(
+ bool is_source_requriement) {
+ // Create a requirements
+ LeAudioConfigurationRequirement requirement;
+ requirement.audioContext = GetAudioContext(AudioContext::MEDIA);
+
+ auto direction_ase_requriement = AseDirectionRequirement();
+ direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3;
+ direction_ase_requriement.aseConfiguration.targetLatency =
+ LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
+
+ // Mismatch sampling frequency
+ direction_ase_requriement.aseConfiguration.codecConfiguration = {
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025,
+ CodecSpecificConfigurationLtv::FrameDuration::US7500,
+ };
+ if (is_source_requriement)
+ requirement.sourceAseRequirement = {direction_ase_requriement};
+ else
+ requirement.sinkAseRequirement = {direction_ase_requriement};
+ return requirement;
+ }
+
std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
bool supported) {
std::vector<Lc3Configuration> le_audio_codec_configs;
@@ -2269,6 +2393,14 @@
}
LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
+ std::vector<int32_t> all_context_bitmasks = {
+ AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL,
+ AudioContext::MEDIA, AudioContext::GAME,
+ AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS,
+ AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS,
+ AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS,
+ AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM,
+ };
};
/**
@@ -2282,6 +2414,101 @@
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config taken from provider info
+ */
+TEST_P(
+ BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) {
+ if (!IsOffloadOutputProviderInfoSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
+ LeAudioConfiguration le_audio_config = {
+ .codecType = CodecType::LC3,
+ .peerDelayUs = 0,
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ GetEmptyAseConfigurationEmptyCapability) {
+ std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
+ std::vector<LeAudioConfigurationRequirement> empty_requirement;
+ std::vector<LeAudioAseConfigurationSetting> configurations;
+
+ // Check empty capability for source direction
+ auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+ std::nullopt, empty_capability, empty_requirement, &configurations);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configurations.empty());
+
+ // Check empty capability for sink direction
+ aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+ empty_capability, std::nullopt, empty_requirement, &configurations);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configurations.empty());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ GetEmptyAseConfigurationMismatchedRequirement) {
+ std::vector<std::optional<LeAudioDeviceCapabilities>> capabilities = {
+ GetDefaultRemoteCapability()};
+
+ // Check empty capability for source direction
+ std::vector<LeAudioAseConfigurationSetting> configurations;
+ std::vector<LeAudioConfigurationRequirement> source_requirements = {
+ GetDefaultRequirement(true)};
+ auto aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+ std::nullopt, capabilities, source_requirements, &configurations);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configurations.empty());
+
+ // Check empty capability for sink direction
+ std::vector<LeAudioConfigurationRequirement> sink_requirements = {
+ GetDefaultRequirement(false)};
+ aidl_retval = audio_provider_->getLeAudioAseConfiguration(
+ capabilities, std::nullopt, source_requirements, &configurations);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configurations.empty());
+}
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) {
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement;
+ std::vector<IBluetoothAudioProvider::LeAudioAseQosConfiguration>
+ QoSConfigurations;
+ for (auto bitmask : all_context_bitmasks) {
+ requirement.contextType = GetAudioContext(bitmask);
+ IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
+ auto aidl_retval =
+ audio_provider_->getLeAudioAseQosConfiguration(requirement, &result);
+ ASSERT_TRUE(aidl_retval.isOk());
+ if (result.sinkQosConfiguration.has_value())
+ QoSConfigurations.push_back(result.sinkQosConfiguration.value());
+ if (result.sourceQosConfiguration.has_value())
+ QoSConfigurations.push_back(result.sourceQosConfiguration.value());
+ }
+ // QoS Configurations should not be empty, as we searched for all contexts
+ ASSERT_FALSE(QoSConfigurations.empty());
+}
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config
*/
TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
@@ -2435,6 +2662,8 @@
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+ GetProviderInfoHelper(
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@@ -2464,7 +2693,7 @@
/**
* Test whether each provider of type
- * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped
*/
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
@@ -2472,7 +2701,38 @@
/**
* Test whether each provider of type
- * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config taken from provider info
+ */
+TEST_P(
+ BluetoothAudioProviderLeAudioInputHardwareAidl,
+ StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) {
+ if (!IsOffloadOutputProviderInfoSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo();
+ LeAudioConfiguration le_audio_config = {
+ .codecType = CodecType::LC3,
+ .peerDelayUs = 0,
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config
*/
TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
@@ -2503,7 +2763,7 @@
/**
* Test whether each provider of type
- * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and
* stopped with Unicast hardware encoding config
*
* Disabled since offload codec checking is not ready
@@ -2621,6 +2881,8 @@
BluetoothAudioProviderFactoryAidl::SetUp();
GetProviderCapabilitiesHelper(
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ GetProviderInfoHelper(
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
OpenProviderHelper(
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
ASSERT_TRUE(temp_provider_capabilities_.empty() ||
@@ -2647,6 +2909,42 @@
return false;
}
+ bool IsBroadcastOffloadProviderInfoSupported() {
+ if (!temp_provider_info_.has_value()) return false;
+ if (temp_provider_info_.value().codecInfos.empty()) return false;
+ // Check if all codec info is of LeAudio type
+ for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+ if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
+ return false;
+ }
+ return true;
+ }
+
+ std::vector<Lc3Configuration> GetBroadcastLc3SupportedListFromProviderInfo() {
+ std::vector<Lc3Configuration> le_audio_codec_configs;
+ for (auto& codec_info : temp_provider_info_.value().codecInfos) {
+ // Only gets LC3 codec information
+ if (codec_info.id != CodecId::Core::LC3) continue;
+ // Combine those parameters into one list of Lc3Configuration
+ auto& transport =
+ codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
+ for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) {
+ for (int32_t frameDurationUs : transport.frameDurationUs) {
+ for (int32_t octetsPerFrame : transport.bitdepth) {
+ Lc3Configuration lc3_config = {
+ .samplingFrequencyHz = samplingFrequencyHz,
+ .frameDurationUs = frameDurationUs,
+ .octetsPerFrame = octetsPerFrame,
+ };
+ le_audio_codec_configs.push_back(lc3_config);
+ }
+ }
+ }
+ }
+
+ return le_audio_codec_configs;
+ }
+
std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
std::vector<Lc3Configuration> le_audio_codec_configs;
if (!supported) {
@@ -2708,6 +3006,60 @@
/**
* Test whether each provider of type
* SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
+ * started and stopped with broadcast hardware encoding config taken from
+ * provider info
+ */
+TEST_P(
+ BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+ StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) {
+ if (!IsBroadcastOffloadProviderInfoSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo();
+ LeAudioBroadcastConfiguration le_audio_broadcast_config = {
+ .codecType = CodecType::LC3,
+ .streamMap = {},
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_broadcast_config.streamMap.resize(1);
+ le_audio_broadcast_config.streamMap[0]
+ .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
+ lc3_config);
+ le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
+ le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
+ le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
+
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_broadcast_config),
+ latency_modes, &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+ GetEmptyBroadcastConfigurationEmptyCapability) {
+ std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
+ IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
+ empty_requirement;
+
+ IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
+ new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();
+
+ // Check empty capability for source direction
+ auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
+ empty_capability, empty_requirement, configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
* started and stopped with broadcast hardware encoding config
*/
TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
diff --git a/bluetooth/audio/flags/Android.bp b/bluetooth/audio/flags/Android.bp
new file mode 100644
index 0000000..0d18a4d
--- /dev/null
+++ b/bluetooth/audio/flags/Android.bp
@@ -0,0 +1,12 @@
+aconfig_declarations {
+ name: "btaudiohal_flags",
+ package: "com.android.btaudio.hal.flags",
+ srcs: ["btaudiohal.aconfig"],
+}
+
+cc_aconfig_library {
+ name: "btaudiohal_flags_c_lib",
+ aconfig_declarations: "btaudiohal_flags",
+ vendor: true,
+ host_supported: true,
+}
diff --git a/bluetooth/audio/flags/btaudiohal.aconfig b/bluetooth/audio/flags/btaudiohal.aconfig
new file mode 100644
index 0000000..763777e
--- /dev/null
+++ b/bluetooth/audio/flags/btaudiohal.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.btaudio.hal.flags"
+
+flag {
+ name: "dsa_lea"
+ namespace: "pixel_bluetooth"
+ description: "Flag for DSA Over LEA"
+ bug: "270987427"
+}
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index e7659a4..c0817f5 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -42,6 +42,7 @@
"aidl_session/BluetoothAudioSession.cpp",
"aidl_session/HidlToAidlMiddleware.cpp",
"aidl_session/BluetoothLeAudioCodecsProvider.cpp",
+ "aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp",
],
export_include_dirs: ["aidl_session/"],
header_libs: [
@@ -61,9 +62,23 @@
"liblog",
"libhidlbase",
"libxml2",
+ "libflatbuffers-cpp",
+ "server_configurable_flags",
+ ],
+ static_libs: [
+ "btaudiohal_flags_c_lib",
],
generated_sources: ["le_audio_codec_capabilities"],
- generated_headers: ["le_audio_codec_capabilities"],
+ generated_headers: [
+ "le_audio_codec_capabilities",
+ "AIDLLeAudioSetConfigSchemas_h",
+ ],
+ required: [
+ "aidl_audio_set_configurations_bfbs",
+ "aidl_audio_set_configurations_json",
+ "aidl_audio_set_scenarios_bfbs",
+ "aidl_audio_set_scenarios_json",
+ ],
}
cc_test {
@@ -98,3 +113,81 @@
api_dir: "le_audio_codec_capabilities/schema",
root_elements: ["leAudioOffloadSetting"],
}
+
+genrule {
+ name: "AIDLLeAudioSetConfigSchemas_h",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -o $(genDir) --cpp $(in) ",
+ srcs: [
+ "le_audio_configuration_set/audio_set_configurations.fbs",
+ "le_audio_configuration_set/audio_set_scenarios.fbs",
+ ],
+ out: [
+ "audio_set_configurations_generated.h",
+ "audio_set_scenarios_generated.h",
+ ],
+}
+
+// Binary generation
+genrule {
+ name: "AIDLLeAudioSetScenariosSchema_bfbs",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -b --schema -o $(genDir) $(in) ",
+ srcs: [
+ "le_audio_configuration_set/audio_set_scenarios.fbs",
+ ],
+ out: [
+ "audio_set_scenarios.bfbs",
+ ],
+}
+
+genrule {
+ name: "AIDLLeAudioSetConfigsSchema_bfbs",
+ tools: [
+ "flatc",
+ ],
+ cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -b --schema -o $(genDir) $(in) ",
+ srcs: [
+ "le_audio_configuration_set/audio_set_configurations.fbs",
+ ],
+ out: [
+ "audio_set_configurations.bfbs",
+ ],
+}
+
+// Add to prebuilt etc
+prebuilt_etc {
+ name: "aidl_audio_set_scenarios_bfbs",
+ src: ":AIDLLeAudioSetScenariosSchema_bfbs",
+ filename: "aidl_audio_set_scenarios.bfbs",
+ sub_dir: "aidl/le_audio",
+ vendor: true,
+}
+
+prebuilt_etc {
+ name: "aidl_audio_set_scenarios_json",
+ src: "le_audio_configuration_set/audio_set_scenarios.json",
+ filename: "aidl_audio_set_scenarios.json",
+ sub_dir: "aidl/le_audio",
+ vendor: true,
+}
+
+prebuilt_etc {
+ name: "aidl_audio_set_configurations_bfbs",
+ src: ":AIDLLeAudioSetConfigsSchema_bfbs",
+ filename: "aidl_audio_set_configurations.bfbs",
+ sub_dir: "aidl/le_audio",
+ vendor: true,
+}
+
+prebuilt_etc {
+ name: "aidl_audio_set_configurations_json",
+ src: "le_audio_configuration_set/audio_set_configurations.json",
+ filename: "aidl_audio_set_configurations.json",
+ sub_dir: "aidl/le_audio",
+ vendor: true,
+}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index 6e15b3b..216e169 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -32,6 +32,7 @@
#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
#include <android-base/logging.h>
+#include "BluetoothLeAudioAseConfigurationSettingProvider.h"
#include "BluetoothLeAudioCodecsProvider.h"
namespace aidl {
@@ -97,6 +98,8 @@
{.codecType = CodecType::OPUS, .capabilities = {}}};
std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
+std::unordered_map<SessionType, std::vector<CodecInfo>>
+ kDefaultOffloadLeAudioCodecInfoMap;
template <class T>
bool BluetoothAudioCodecs::ContainedInVector(
@@ -411,6 +414,37 @@
return kDefaultOffloadLeAudioCapabilities;
}
+std::vector<CodecInfo> BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
+ const SessionType& session_type) {
+ if (session_type !=
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type !=
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
+ session_type !=
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+ return std::vector<CodecInfo>();
+ }
+
+ if (kDefaultOffloadLeAudioCodecInfoMap.empty()) {
+ auto le_audio_offload_setting =
+ BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
+ auto kDefaultOffloadLeAudioCodecInfoMap =
+ BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo(
+ le_audio_offload_setting);
+ }
+ auto codec_info_map_iter =
+ kDefaultOffloadLeAudioCodecInfoMap.find(session_type);
+ if (codec_info_map_iter == kDefaultOffloadLeAudioCodecInfoMap.end())
+ return std::vector<CodecInfo>();
+ return codec_info_map_iter->second;
+}
+
+std::vector<LeAudioAseConfigurationSetting>
+BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings() {
+ return AudioSetConfigurationProviderJson::
+ GetLeAudioAseConfigurationSettings();
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
index e3d657b..057b9a7 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
@@ -18,6 +18,8 @@
#include <aidl/android/hardware/bluetooth/audio/CodecCapabilities.h>
#include <aidl/android/hardware/bluetooth/audio/CodecConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecInfo.h>
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h>
#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h>
#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/OpusConfiguration.h>
@@ -33,6 +35,9 @@
namespace bluetooth {
namespace audio {
+using LeAudioAseConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
+
class BluetoothAudioCodecs {
public:
static std::vector<PcmCapabilities> GetSoftwarePcmCapabilities();
@@ -46,6 +51,11 @@
static std::vector<LeAudioCodecCapabilitiesSetting>
GetLeAudioOffloadCodecCapabilities(const SessionType& session_type);
+ static std::vector<CodecInfo> GetLeAudioOffloadCodecInfo(
+ const SessionType& session_type);
+
+ static std::vector<LeAudioAseConfigurationSetting>
+ GetLeAudioAseConfigurationSettings();
private:
template <typename T>
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index 3519ace..c057505 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android/binder_manager.h>
+#include <com_android_btaudio_hal_flags.h>
#include <hardware/audio.h>
#include "BluetoothAudioSession.h"
@@ -36,6 +37,14 @@
static constexpr int kWritePollMs = 1; // polled non-blocking interval
static constexpr int kReadPollMs = 1; // polled non-blocking interval
+static std::string toString(const std::vector<LatencyMode>& latencies) {
+ std::stringstream latencyModesStr;
+ for (LatencyMode mode : latencies) {
+ latencyModesStr << " " << toString(mode);
+ }
+ return latencyModesStr.str();
+}
+
BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type)
: session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) {}
@@ -65,6 +74,7 @@
stack_iface_ = stack_iface;
latency_modes_ = latency_modes;
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " - All LatencyModes=" << toString(latency_modes)
<< ", AudioConfiguration=" << audio_config.toString();
ReportSessionStatus();
}
@@ -604,31 +614,46 @@
return std::vector<LatencyMode>();
}
- std::vector<LatencyMode> supported_latency_modes;
- if (session_type_ ==
- SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
- for (LatencyMode mode : latency_modes_) {
- if (mode == LatencyMode::LOW_LATENCY) {
- // LOW_LATENCY is not supported for LE_HARDWARE_OFFLOAD_ENC sessions
- continue;
+ if (com::android::btaudio::hal::flags::dsa_lea()) {
+ std::vector<LatencyMode> supported_latency_modes;
+ if (session_type_ ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+ for (LatencyMode mode : latency_modes_) {
+ if (mode == LatencyMode::LOW_LATENCY) {
+ // LOW_LATENCY is not supported for LE_HARDWARE_OFFLOAD_ENC sessions
+ continue;
+ }
+ supported_latency_modes.push_back(mode);
}
- supported_latency_modes.push_back(mode);
+ } else {
+ for (LatencyMode mode : latency_modes_) {
+ if (!low_latency_allowed_ && mode == LatencyMode::LOW_LATENCY) {
+ // ignore LOW_LATENCY mode if Bluetooth stack doesn't allow
+ continue;
+ }
+ if (mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE ||
+ mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE) {
+ // DSA_SW and DSA_HW only supported for LE_HARDWARE_OFFLOAD_ENC
+ // sessions
+ continue;
+ }
+ supported_latency_modes.push_back(mode);
+ }
}
- } else {
- for (LatencyMode mode : latency_modes_) {
- if (!low_latency_allowed_ && mode == LatencyMode::LOW_LATENCY) {
- // ignore LOW_LATENCY mode if Bluetooth stack doesn't allow
- continue;
- }
- if (mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE ||
- mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE) {
- // DSA_SW and DSA_HW only supported for LE_HARDWARE_OFFLOAD_ENC sessions
- continue;
- }
- supported_latency_modes.push_back(mode);
- }
+ LOG(DEBUG) << __func__ << " - Supported LatencyMode="
+ << toString(supported_latency_modes);
+ return supported_latency_modes;
}
- return supported_latency_modes;
+
+ if (low_latency_allowed_) return latency_modes_;
+ std::vector<LatencyMode> modes;
+ for (LatencyMode mode : latency_modes_) {
+ if (mode == LatencyMode::LOW_LATENCY)
+ // ignore those low latency mode if Bluetooth stack doesn't allow
+ continue;
+ modes.push_back(mode);
+ }
+ return modes;
}
void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) {
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
new file mode 100644
index 0000000..5429a8f
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
@@ -0,0 +1,760 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#define STREAM_TO_UINT8(u8, p) \
+ { \
+ (u8) = (uint8_t)(*(p)); \
+ (p) += 1; \
+ }
+#define STREAM_TO_UINT16(u16, p) \
+ { \
+ (u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \
+ (p) += 2; \
+ }
+#define STREAM_TO_UINT32(u32, p) \
+ { \
+ (u32) = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + \
+ ((((uint32_t)(*((p) + 2)))) << 16) + \
+ ((((uint32_t)(*((p) + 3)))) << 24)); \
+ (p) += 4; \
+ }
+
+#define LOG_TAG "BTAudioAseConfigAidl"
+
+#include "BluetoothLeAudioAseConfigurationSettingProvider.h"
+
+#include <aidl/android/hardware/bluetooth/audio/AudioConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/AudioContext.h>
+#include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecId.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.h>
+#include <aidl/android/hardware/bluetooth/audio/ConfigurationFlags.h>
+#include <aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/Phy.h>
+#include <android-base/logging.h>
+
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+/* Internal structure definition */
+std::map<std::string,
+ std::tuple<std::vector<std::optional<AseDirectionConfiguration>>,
+ std::vector<std::optional<AseDirectionConfiguration>>,
+ ConfigurationFlags>>
+ configurations_;
+
+std::vector<LeAudioAseConfigurationSetting> ase_configuration_settings_;
+
+constexpr uint8_t kIsoDataPathHci = 0x00;
+constexpr uint8_t kIsoDataPathPlatformDefault = 0x01;
+constexpr uint8_t kIsoDataPathDisabled = 0xFF;
+
+constexpr uint8_t kLeAudioDirectionSink = 0x01;
+constexpr uint8_t kLeAudioDirectionSource = 0x02;
+constexpr uint8_t kLeAudioDirectionBoth =
+ kLeAudioDirectionSink | kLeAudioDirectionSource;
+
+/* Sampling Frequencies */
+constexpr uint8_t kLeAudioSamplingFreq8000Hz = 0x01;
+constexpr uint8_t kLeAudioSamplingFreq11025Hz = 0x02;
+constexpr uint8_t kLeAudioSamplingFreq16000Hz = 0x03;
+constexpr uint8_t kLeAudioSamplingFreq22050Hz = 0x04;
+constexpr uint8_t kLeAudioSamplingFreq24000Hz = 0x05;
+constexpr uint8_t kLeAudioSamplingFreq32000Hz = 0x06;
+constexpr uint8_t kLeAudioSamplingFreq44100Hz = 0x07;
+constexpr uint8_t kLeAudioSamplingFreq48000Hz = 0x08;
+constexpr uint8_t kLeAudioSamplingFreq88200Hz = 0x09;
+constexpr uint8_t kLeAudioSamplingFreq96000Hz = 0x0A;
+constexpr uint8_t kLeAudioSamplingFreq176400Hz = 0x0B;
+constexpr uint8_t kLeAudioSamplingFreq192000Hz = 0x0C;
+constexpr uint8_t kLeAudioSamplingFreq384000Hz = 0x0D;
+
+/* Frame Durations */
+constexpr uint8_t kLeAudioCodecFrameDur7500us = 0x00;
+constexpr uint8_t kLeAudioCodecFrameDur10000us = 0x01;
+
+/* Audio Allocations */
+constexpr uint32_t kLeAudioLocationNotAllowed = 0x00000000;
+constexpr uint32_t kLeAudioLocationFrontLeft = 0x00000001;
+constexpr uint32_t kLeAudioLocationFrontRight = 0x00000002;
+constexpr uint32_t kLeAudioLocationFrontCenter = 0x00000004;
+constexpr uint32_t kLeAudioLocationLowFreqEffects1 = 0x00000008;
+constexpr uint32_t kLeAudioLocationBackLeft = 0x00000010;
+constexpr uint32_t kLeAudioLocationBackRight = 0x00000020;
+constexpr uint32_t kLeAudioLocationFrontLeftOfCenter = 0x00000040;
+constexpr uint32_t kLeAudioLocationFrontRightOfCenter = 0x00000080;
+constexpr uint32_t kLeAudioLocationBackCenter = 0x00000100;
+constexpr uint32_t kLeAudioLocationLowFreqEffects2 = 0x00000200;
+constexpr uint32_t kLeAudioLocationSideLeft = 0x00000400;
+constexpr uint32_t kLeAudioLocationSideRight = 0x00000800;
+constexpr uint32_t kLeAudioLocationTopFrontLeft = 0x00001000;
+constexpr uint32_t kLeAudioLocationTopFrontRight = 0x00002000;
+constexpr uint32_t kLeAudioLocationTopFrontCenter = 0x00004000;
+constexpr uint32_t kLeAudioLocationTopCenter = 0x00008000;
+constexpr uint32_t kLeAudioLocationTopBackLeft = 0x00010000;
+constexpr uint32_t kLeAudioLocationTopBackRight = 0x00020000;
+constexpr uint32_t kLeAudioLocationTopSideLeft = 0x00040000;
+constexpr uint32_t kLeAudioLocationTopSideRight = 0x00080000;
+constexpr uint32_t kLeAudioLocationTopBackCenter = 0x00100000;
+constexpr uint32_t kLeAudioLocationBottomFrontCenter = 0x00200000;
+constexpr uint32_t kLeAudioLocationBottomFrontLeft = 0x00400000;
+constexpr uint32_t kLeAudioLocationBottomFrontRight = 0x00800000;
+constexpr uint32_t kLeAudioLocationFrontLeftWide = 0x01000000;
+constexpr uint32_t kLeAudioLocationFrontRightWide = 0x02000000;
+constexpr uint32_t kLeAudioLocationLeftSurround = 0x04000000;
+constexpr uint32_t kLeAudioLocationRightSurround = 0x08000000;
+
+constexpr uint32_t kLeAudioLocationAnyLeft =
+ kLeAudioLocationFrontLeft | kLeAudioLocationBackLeft |
+ kLeAudioLocationFrontLeftOfCenter | kLeAudioLocationSideLeft |
+ kLeAudioLocationTopFrontLeft | kLeAudioLocationTopBackLeft |
+ kLeAudioLocationTopSideLeft | kLeAudioLocationBottomFrontLeft |
+ kLeAudioLocationFrontLeftWide | kLeAudioLocationLeftSurround;
+
+constexpr uint32_t kLeAudioLocationAnyRight =
+ kLeAudioLocationFrontRight | kLeAudioLocationBackRight |
+ kLeAudioLocationFrontRightOfCenter | kLeAudioLocationSideRight |
+ kLeAudioLocationTopFrontRight | kLeAudioLocationTopBackRight |
+ kLeAudioLocationTopSideRight | kLeAudioLocationBottomFrontRight |
+ kLeAudioLocationFrontRightWide | kLeAudioLocationRightSurround;
+
+constexpr uint32_t kLeAudioLocationStereo =
+ kLeAudioLocationFrontLeft | kLeAudioLocationFrontRight;
+
+/* Octets Per Frame */
+constexpr uint16_t kLeAudioCodecFrameLen30 = 30;
+constexpr uint16_t kLeAudioCodecFrameLen40 = 40;
+constexpr uint16_t kLeAudioCodecFrameLen60 = 60;
+constexpr uint16_t kLeAudioCodecFrameLen80 = 80;
+constexpr uint16_t kLeAudioCodecFrameLen100 = 100;
+constexpr uint16_t kLeAudioCodecFrameLen120 = 120;
+
+/* Helper map for matching various sampling frequency notations */
+const std::map<uint8_t, CodecSpecificConfigurationLtv::SamplingFrequency>
+ sampling_freq_map = {
+ {kLeAudioSamplingFreq8000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000},
+ {kLeAudioSamplingFreq16000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000},
+ {kLeAudioSamplingFreq24000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ24000},
+ {kLeAudioSamplingFreq32000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000},
+ {kLeAudioSamplingFreq44100Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ44100},
+ {kLeAudioSamplingFreq48000Hz,
+ CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000}};
+
+/* Helper map for matching various frame durations notations */
+const std::map<uint8_t, CodecSpecificConfigurationLtv::FrameDuration>
+ frame_duration_map = {
+ {kLeAudioCodecFrameDur7500us,
+ CodecSpecificConfigurationLtv::FrameDuration::US7500},
+ {kLeAudioCodecFrameDur10000us,
+ CodecSpecificConfigurationLtv::FrameDuration::US10000}};
+
+/* Helper map for matching various audio channel allocation notations */
+std::map<uint32_t, uint32_t> audio_channel_allocation_map = {
+ {kLeAudioLocationNotAllowed,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::NOT_ALLOWED},
+ {kLeAudioLocationFrontLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT},
+ {kLeAudioLocationFrontRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT},
+ {kLeAudioLocationFrontCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER},
+ {kLeAudioLocationLowFreqEffects1,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ LOW_FREQUENCY_EFFECTS_1},
+ {kLeAudioLocationBackLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_LEFT},
+ {kLeAudioLocationBackRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_RIGHT},
+ {kLeAudioLocationFrontLeftOfCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ FRONT_LEFT_OF_CENTER},
+ {kLeAudioLocationFrontRightOfCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ FRONT_RIGHT_OF_CENTER},
+ {kLeAudioLocationBackCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_CENTER},
+ {kLeAudioLocationLowFreqEffects2,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ LOW_FREQUENCY_EFFECTS_2},
+ {kLeAudioLocationSideLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::SIDE_LEFT},
+ {kLeAudioLocationSideRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::SIDE_RIGHT},
+ {kLeAudioLocationTopFrontLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_LEFT},
+ {kLeAudioLocationTopFrontRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_RIGHT},
+ {kLeAudioLocationTopFrontCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_CENTER},
+ {kLeAudioLocationTopCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_CENTER},
+ {kLeAudioLocationTopBackLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_LEFT},
+ {kLeAudioLocationTopBackRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_RIGHT},
+ {kLeAudioLocationTopSideLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_SIDE_LEFT},
+ {kLeAudioLocationTopSideRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_SIDE_RIGHT},
+ {kLeAudioLocationTopBackCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_CENTER},
+ {kLeAudioLocationBottomFrontCenter,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::
+ BOTTOM_FRONT_CENTER},
+ {kLeAudioLocationBottomFrontLeft,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BOTTOM_FRONT_LEFT},
+ {kLeAudioLocationBottomFrontRight,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::BOTTOM_FRONT_RIGHT},
+ {kLeAudioLocationFrontLeftWide,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT_WIDE},
+ {kLeAudioLocationFrontRightWide,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT_WIDE},
+ {kLeAudioLocationLeftSurround,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::LEFT_SURROUND},
+ {kLeAudioLocationRightSurround,
+ CodecSpecificConfigurationLtv::AudioChannelAllocation::RIGHT_SURROUND},
+};
+
+static const std::vector<
+ std::pair<const char* /*schema*/, const char* /*content*/>>
+ kLeAudioSetConfigs = {{"/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_configurations.bfbs",
+ "/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_configurations.json"}};
+static const std::vector<
+ std::pair<const char* /*schema*/, const char* /*content*/>>
+ kLeAudioSetScenarios = {{"/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_scenarios.bfbs",
+ "/vendor/etc/aidl/le_audio/"
+ "aidl_audio_set_scenarios.json"}};
+
+/* Implementation */
+
+std::vector<LeAudioAseConfigurationSetting>
+AudioSetConfigurationProviderJson::GetLeAudioAseConfigurationSettings() {
+ AudioSetConfigurationProviderJson::LoadAudioSetConfigurationProviderJson();
+ return ase_configuration_settings_;
+}
+
+void AudioSetConfigurationProviderJson::
+ LoadAudioSetConfigurationProviderJson() {
+ if (configurations_.empty() || ase_configuration_settings_.empty()) {
+ ase_configuration_settings_.clear();
+ configurations_.clear();
+ auto loaded = LoadContent(kLeAudioSetConfigs, kLeAudioSetScenarios,
+ CodecLocation::HOST);
+ if (!loaded)
+ LOG(ERROR) << ": Unable to load le audio set configuration files.";
+ } else
+ LOG(INFO) << ": Reusing loaded le audio set configuration";
+}
+
+const le_audio::CodecSpecificConfiguration*
+AudioSetConfigurationProviderJson::LookupCodecSpecificParam(
+ const flatbuffers::Vector<flatbuffers::Offset<
+ le_audio::CodecSpecificConfiguration>>* flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes type) {
+ auto it = std::find_if(
+ flat_codec_specific_params->cbegin(), flat_codec_specific_params->cend(),
+ [&type](const auto& csc) { return (csc->type() == type); });
+ return (it != flat_codec_specific_params->cend()) ? *it : nullptr;
+}
+
+void AudioSetConfigurationProviderJson::populateAudioChannelAllocation(
+ CodecSpecificConfigurationLtv::AudioChannelAllocation&
+ audio_channel_allocation,
+ uint32_t audio_location) {
+ audio_channel_allocation.bitmask = 0;
+ for (auto [allocation, bitmask] : audio_channel_allocation_map) {
+ if (audio_location & allocation)
+ audio_channel_allocation.bitmask |= bitmask;
+ }
+}
+
+void AudioSetConfigurationProviderJson::populateConfigurationData(
+ LeAudioAseConfiguration& ase,
+ const flatbuffers::Vector<
+ flatbuffers::Offset<le_audio::CodecSpecificConfiguration>>*
+ flat_codec_specific_params) {
+ uint8_t sampling_frequency = 0;
+ uint8_t frame_duration = 0;
+ uint32_t audio_channel_allocation = 0;
+ uint16_t octets_per_codec_frame = 0;
+ uint8_t codec_frames_blocks_per_sdu = 0;
+
+ auto param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_SAMPLING_FREQUENCY);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(sampling_frequency, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_FRAME_DURATION);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(frame_duration, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_AUDIO_CHANNEL_ALLOCATION);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT32(audio_channel_allocation, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_OCTETS_PER_CODEC_FRAME);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT16(octets_per_codec_frame, ptr);
+ }
+
+ param = LookupCodecSpecificParam(
+ flat_codec_specific_params,
+ le_audio::
+ CodecSpecificLtvGenericTypes_SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU);
+ if (param) {
+ auto ptr = param->compound_value()->value()->data();
+ STREAM_TO_UINT8(codec_frames_blocks_per_sdu, ptr);
+ }
+
+ // Make the correct value
+ ase.codecConfiguration = std::vector<CodecSpecificConfigurationLtv>();
+
+ auto sampling_freq_it = sampling_freq_map.find(sampling_frequency);
+ if (sampling_freq_it != sampling_freq_map.end())
+ ase.codecConfiguration.push_back(sampling_freq_it->second);
+ auto frame_duration_it = frame_duration_map.find(frame_duration);
+ if (frame_duration_it != frame_duration_map.end())
+ ase.codecConfiguration.push_back(frame_duration_it->second);
+
+ CodecSpecificConfigurationLtv::AudioChannelAllocation channel_allocation;
+ populateAudioChannelAllocation(channel_allocation, audio_channel_allocation);
+ ase.codecConfiguration.push_back(channel_allocation);
+
+ auto octet_structure = CodecSpecificConfigurationLtv::OctetsPerCodecFrame();
+ octet_structure.value = octets_per_codec_frame;
+ ase.codecConfiguration.push_back(octet_structure);
+
+ auto frame_sdu_structure =
+ CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU();
+ frame_sdu_structure.value = codec_frames_blocks_per_sdu;
+ ase.codecConfiguration.push_back(frame_sdu_structure);
+ // TODO: Channel count
+}
+
+void AudioSetConfigurationProviderJson::populateAseConfiguration(
+ LeAudioAseConfiguration& ase,
+ const le_audio::AudioSetSubConfiguration* flat_subconfig,
+ const le_audio::QosConfiguration* qos_cfg) {
+ // Target latency
+ switch (qos_cfg->target_latency()) {
+ case le_audio::AudioSetConfigurationTargetLatency::
+ AudioSetConfigurationTargetLatency_BALANCED_RELIABILITY:
+ ase.targetLatency =
+ LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
+ break;
+ case le_audio::AudioSetConfigurationTargetLatency::
+ AudioSetConfigurationTargetLatency_HIGH_RELIABILITY:
+ ase.targetLatency =
+ LeAudioAseConfiguration::TargetLatency::HIGHER_RELIABILITY;
+ break;
+ case le_audio::AudioSetConfigurationTargetLatency::
+ AudioSetConfigurationTargetLatency_LOW:
+ ase.targetLatency = LeAudioAseConfiguration::TargetLatency::LOWER;
+ break;
+ default:
+ ase.targetLatency = LeAudioAseConfiguration::TargetLatency::UNDEFINED;
+ break;
+ };
+
+ ase.targetPhy = Phy::TWO_M;
+ // Making CodecId
+ if (flat_subconfig->codec_id()->coding_format() ==
+ (uint8_t)CodecId::Core::LC3) {
+ ase.codecId = CodecId::Core::LC3;
+ } else {
+ auto vendorC = CodecId::Vendor();
+ vendorC.codecId = flat_subconfig->codec_id()->vendor_codec_id();
+ vendorC.id = flat_subconfig->codec_id()->vendor_company_id();
+ ase.codecId = vendorC;
+ }
+ // Codec configuration data
+ populateConfigurationData(ase, flat_subconfig->codec_configuration());
+}
+
+void AudioSetConfigurationProviderJson::populateAseQosConfiguration(
+ LeAudioAseQosConfiguration& qos,
+ const le_audio::QosConfiguration* qos_cfg) {
+ qos.maxTransportLatencyMs = qos_cfg->max_transport_latency();
+ qos.retransmissionNum = qos_cfg->retransmission_number();
+}
+
+// Parse into AseDirectionConfiguration
+AseDirectionConfiguration
+AudioSetConfigurationProviderJson::SetConfigurationFromFlatSubconfig(
+ const le_audio::AudioSetSubConfiguration* flat_subconfig,
+ const le_audio::QosConfiguration* qos_cfg, CodecLocation location) {
+ AseDirectionConfiguration direction_conf;
+
+ LeAudioAseConfiguration ase;
+ LeAudioAseQosConfiguration qos;
+ LeAudioDataPathConfiguration path;
+
+ // Translate into LeAudioAseConfiguration
+ populateAseConfiguration(ase, flat_subconfig, qos_cfg);
+
+ // Translate into LeAudioAseQosConfiguration
+ populateAseQosConfiguration(qos, qos_cfg);
+
+ // Translate location to data path id
+ switch (location) {
+ case CodecLocation::ADSP:
+ path.isoDataPathConfiguration.isTransparent = true;
+ path.dataPathId = kIsoDataPathPlatformDefault;
+ break;
+ case CodecLocation::HOST:
+ path.isoDataPathConfiguration.isTransparent = true;
+ path.dataPathId = kIsoDataPathHci;
+ break;
+ case CodecLocation::CONTROLLER:
+ path.isoDataPathConfiguration.isTransparent = false;
+ path.dataPathId = kIsoDataPathPlatformDefault;
+ break;
+ }
+
+ direction_conf.aseConfiguration = ase;
+ direction_conf.qosConfiguration = qos;
+ direction_conf.dataPathConfiguration = path;
+
+ return direction_conf;
+}
+
+// Parse into AseDirectionConfiguration and the ConfigurationFlags
+// and put them in the given list.
+void AudioSetConfigurationProviderJson::processSubconfig(
+ const le_audio::AudioSetSubConfiguration* subconfig,
+ const le_audio::QosConfiguration* qos_cfg,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ directionAseConfiguration,
+ CodecLocation location) {
+ directionAseConfiguration.push_back(
+ SetConfigurationFromFlatSubconfig(subconfig, qos_cfg, location));
+}
+
+void AudioSetConfigurationProviderJson::PopulateAseConfigurationFromFlat(
+ const le_audio::AudioSetConfiguration* flat_cfg,
+ std::vector<const le_audio::CodecConfiguration*>* codec_cfgs,
+ std::vector<const le_audio::QosConfiguration*>* qos_cfgs,
+ CodecLocation location,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ sourceAseConfiguration,
+ std::vector<std::optional<AseDirectionConfiguration>>& sinkAseConfiguration,
+ ConfigurationFlags& /*configurationFlags*/) {
+ if (flat_cfg == nullptr) {
+ LOG(ERROR) << "flat_cfg cannot be null";
+ return;
+ }
+ std::string codec_config_key = flat_cfg->codec_config_name()->str();
+ auto* qos_config_key_array = flat_cfg->qos_config_name();
+
+ constexpr std::string_view default_qos = "QoS_Config_Balanced_Reliability";
+
+ std::string qos_sink_key(default_qos);
+ std::string qos_source_key(default_qos);
+
+ /* We expect maximum two QoS settings. First for Sink and second for Source
+ */
+ if (qos_config_key_array->size() > 0) {
+ qos_sink_key = qos_config_key_array->Get(0)->str();
+ if (qos_config_key_array->size() > 1) {
+ qos_source_key = qos_config_key_array->Get(1)->str();
+ } else {
+ qos_source_key = qos_sink_key;
+ }
+ }
+
+ LOG(INFO) << "Audio set config " << flat_cfg->name()->c_str()
+ << ": codec config " << codec_config_key.c_str() << ", qos_sink "
+ << qos_sink_key.c_str() << ", qos_source "
+ << qos_source_key.c_str();
+
+ // Find the first qos config that match the name
+ const le_audio::QosConfiguration* qos_sink_cfg = nullptr;
+ for (auto i = qos_cfgs->begin(); i != qos_cfgs->end(); ++i) {
+ if ((*i)->name()->str() == qos_sink_key) {
+ qos_sink_cfg = *i;
+ break;
+ }
+ }
+
+ const le_audio::QosConfiguration* qos_source_cfg = nullptr;
+ for (auto i = qos_cfgs->begin(); i != qos_cfgs->end(); ++i) {
+ if ((*i)->name()->str() == qos_source_key) {
+ qos_source_cfg = *i;
+ break;
+ }
+ }
+
+ // First codec_cfg with the same name
+ const le_audio::CodecConfiguration* codec_cfg = nullptr;
+ for (auto i = codec_cfgs->begin(); i != codec_cfgs->end(); ++i) {
+ if ((*i)->name()->str() == codec_config_key) {
+ codec_cfg = *i;
+ break;
+ }
+ }
+
+ // Process each subconfig and put it into the correct list
+ if (codec_cfg != nullptr && codec_cfg->subconfigurations()) {
+ /* Load subconfigurations */
+ for (auto subconfig : *codec_cfg->subconfigurations()) {
+ if (subconfig->direction() == kLeAudioDirectionSink) {
+ processSubconfig(subconfig, qos_sink_cfg, sinkAseConfiguration,
+ location);
+ } else {
+ processSubconfig(subconfig, qos_source_cfg, sourceAseConfiguration,
+ location);
+ }
+ }
+ } else {
+ if (codec_cfg == nullptr) {
+ LOG(ERROR) << "No codec config matching key " << codec_config_key.c_str()
+ << " found";
+ } else {
+ LOG(ERROR) << "Configuration '" << flat_cfg->name()->c_str()
+ << "' has no valid subconfigurations.";
+ }
+ }
+
+ // TODO: Populate information for ConfigurationFlags
+}
+
+bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles(
+ const char* schema_file, const char* content_file, CodecLocation location) {
+ flatbuffers::Parser configurations_parser_;
+ std::string configurations_schema_binary_content;
+ bool ok = flatbuffers::LoadFile(schema_file, true,
+ &configurations_schema_binary_content);
+ LOG(INFO) << __func__ << ": Loading file " << schema_file;
+ if (!ok) return ok;
+
+ /* Load the binary schema */
+ ok = configurations_parser_.Deserialize(
+ (uint8_t*)configurations_schema_binary_content.c_str(),
+ configurations_schema_binary_content.length());
+ if (!ok) return ok;
+
+ /* Load the content from JSON */
+ std::string configurations_json_content;
+ LOG(INFO) << __func__ << ": Loading file " << content_file;
+ ok = flatbuffers::LoadFile(content_file, false, &configurations_json_content);
+ if (!ok) return ok;
+
+ /* Parse */
+ LOG(INFO) << __func__ << ": Parse JSON content";
+ ok = configurations_parser_.Parse(configurations_json_content.c_str());
+ if (!ok) return ok;
+
+ /* Import from flatbuffers */
+ LOG(INFO) << __func__ << ": Build flat buffer structure";
+ auto configurations_root = le_audio::GetAudioSetConfigurations(
+ configurations_parser_.builder_.GetBufferPointer());
+ if (!configurations_root) return false;
+
+ auto flat_qos_configs = configurations_root->qos_configurations();
+ if ((flat_qos_configs == nullptr) || (flat_qos_configs->size() == 0))
+ return false;
+
+ LOG(DEBUG) << ": Updating " << flat_qos_configs->size()
+ << " qos config entries.";
+ std::vector<const le_audio::QosConfiguration*> qos_cfgs;
+ for (auto const& flat_qos_cfg : *flat_qos_configs) {
+ qos_cfgs.push_back(flat_qos_cfg);
+ }
+
+ auto flat_codec_configs = configurations_root->codec_configurations();
+ if ((flat_codec_configs == nullptr) || (flat_codec_configs->size() == 0))
+ return false;
+
+ LOG(DEBUG) << ": Updating " << flat_codec_configs->size()
+ << " codec config entries.";
+ std::vector<const le_audio::CodecConfiguration*> codec_cfgs;
+ for (auto const& flat_codec_cfg : *flat_codec_configs) {
+ codec_cfgs.push_back(flat_codec_cfg);
+ }
+
+ auto flat_configs = configurations_root->configurations();
+ if ((flat_configs == nullptr) || (flat_configs->size() == 0)) return false;
+
+ LOG(DEBUG) << ": Updating " << flat_configs->size() << " config entries.";
+ for (auto const& flat_cfg : *flat_configs) {
+ // Create 3 vector to use
+ std::vector<std::optional<AseDirectionConfiguration>>
+ sourceAseConfiguration;
+ std::vector<std::optional<AseDirectionConfiguration>> sinkAseConfiguration;
+ ConfigurationFlags configurationFlags;
+ PopulateAseConfigurationFromFlat(flat_cfg, &codec_cfgs, &qos_cfgs, location,
+ sourceAseConfiguration,
+ sinkAseConfiguration, configurationFlags);
+ if (sourceAseConfiguration.empty() && sinkAseConfiguration.empty())
+ continue;
+ configurations_[flat_cfg->name()->str()] = std::make_tuple(
+ sourceAseConfiguration, sinkAseConfiguration, configurationFlags);
+ }
+
+ return true;
+}
+
+bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles(
+ const char* schema_file, const char* content_file) {
+ flatbuffers::Parser scenarios_parser_;
+ std::string scenarios_schema_binary_content;
+ bool ok = flatbuffers::LoadFile(schema_file, true,
+ &scenarios_schema_binary_content);
+ LOG(INFO) << __func__ << ": Loading file " << schema_file;
+ if (!ok) return ok;
+
+ /* Load the binary schema */
+ ok = scenarios_parser_.Deserialize(
+ (uint8_t*)scenarios_schema_binary_content.c_str(),
+ scenarios_schema_binary_content.length());
+ if (!ok) return ok;
+
+ /* Load the content from JSON */
+ LOG(INFO) << __func__ << ": Loading file " << content_file;
+ std::string scenarios_json_content;
+ ok = flatbuffers::LoadFile(content_file, false, &scenarios_json_content);
+ if (!ok) return ok;
+
+ /* Parse */
+ LOG(INFO) << __func__ << ": Parse json content";
+ ok = scenarios_parser_.Parse(scenarios_json_content.c_str());
+ if (!ok) return ok;
+
+ /* Import from flatbuffers */
+ LOG(INFO) << __func__ << ": Build flat buffer structure";
+ auto scenarios_root = le_audio::GetAudioSetScenarios(
+ scenarios_parser_.builder_.GetBufferPointer());
+ if (!scenarios_root) return false;
+
+ auto flat_scenarios = scenarios_root->scenarios();
+ if ((flat_scenarios == nullptr) || (flat_scenarios->size() == 0))
+ return false;
+
+ LOG(INFO) << __func__ << ": Turn flat buffer into structure";
+ AudioContext media_context = AudioContext();
+ media_context.bitmask =
+ (AudioContext::ALERTS | AudioContext::INSTRUCTIONAL |
+ AudioContext::NOTIFICATIONS | AudioContext::EMERGENCY_ALARM |
+ AudioContext::UNSPECIFIED | AudioContext::MEDIA);
+
+ AudioContext conversational_context = AudioContext();
+ conversational_context.bitmask =
+ (AudioContext::RINGTONE_ALERTS | AudioContext::CONVERSATIONAL);
+
+ AudioContext live_context = AudioContext();
+ live_context.bitmask = AudioContext::LIVE_AUDIO;
+
+ AudioContext game_context = AudioContext();
+ game_context.bitmask = AudioContext::GAME;
+
+ AudioContext voice_assistants_context = AudioContext();
+ voice_assistants_context.bitmask = AudioContext::VOICE_ASSISTANTS;
+
+ LOG(DEBUG) << "Updating " << flat_scenarios->size() << " scenarios.";
+ for (auto const& scenario : *flat_scenarios) {
+ LOG(DEBUG) << "Scenario " << scenario->name()->c_str()
+ << " configs: " << scenario->configurations()->size();
+
+ if (!scenario->configurations()) continue;
+ std::string scenario_name = scenario->name()->c_str();
+ AudioContext context;
+ if (scenario_name == "Media")
+ context = AudioContext(media_context);
+ else if (scenario_name == "Conversational")
+ context = AudioContext(conversational_context);
+ else if (scenario_name == "Live")
+ context = AudioContext(live_context);
+ else if (scenario_name == "Game")
+ context = AudioContext(game_context);
+ else if (scenario_name == "VoiceAssistants")
+ context = AudioContext(voice_assistants_context);
+
+ for (auto it = scenario->configurations()->begin();
+ it != scenario->configurations()->end(); ++it) {
+ auto config_name = it->str();
+ auto configuration = configurations_.find(config_name);
+ if (configuration == configurations_.end()) continue;
+ LOG(DEBUG) << "Getting configuration with name: " << config_name;
+ auto [source, sink, flags] = configuration->second;
+ // Each configuration will create a LeAudioAseConfigurationSetting
+ // with the same {context, packing}
+ // and different data
+ LeAudioAseConfigurationSetting setting;
+ setting.audioContext = context;
+ // TODO: Packing
+ setting.sourceAseConfiguration = source;
+ setting.sinkAseConfiguration = sink;
+ setting.flags = flags;
+ // Add to list of setting
+ LOG(DEBUG) << "Pushing configuration to list: " << config_name;
+ ase_configuration_settings_.push_back(setting);
+ }
+ }
+
+ return true;
+}
+
+bool AudioSetConfigurationProviderJson::LoadContent(
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ config_files,
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ scenario_files,
+ CodecLocation location) {
+ for (auto [schema, content] : config_files) {
+ if (!LoadConfigurationsFromFiles(schema, content, location)) return false;
+ }
+
+ for (auto [schema, content] : scenario_files) {
+ if (!LoadScenariosFromFiles(schema, content)) return false;
+ }
+ return true;
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
new file mode 100644
index 0000000..ce91fca
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
@@ -0,0 +1,125 @@
+
+/*
+ * Copyright (C) 2023 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 <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h>
+
+#include <map>
+#include <mutex>
+#include <optional>
+#include <string>
+#include <string_view>
+#include <tuple>
+
+#include "audio_set_configurations_generated.h"
+#include "audio_set_scenarios_generated.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using LeAudioAseConfigurationSetting =
+ IBluetoothAudioProvider::LeAudioAseConfigurationSetting;
+using AseDirectionConfiguration = IBluetoothAudioProvider::
+ LeAudioAseConfigurationSetting::AseDirectionConfiguration;
+using LeAudioAseQosConfiguration =
+ IBluetoothAudioProvider::LeAudioAseQosConfiguration;
+using LeAudioDataPathConfiguration =
+ IBluetoothAudioProvider::LeAudioDataPathConfiguration;
+
+enum class CodecLocation {
+ HOST,
+ ADSP,
+ CONTROLLER,
+};
+
+class AudioSetConfigurationProviderJson {
+ public:
+ static std::vector<LeAudioAseConfigurationSetting>
+ GetLeAudioAseConfigurationSettings();
+
+ private:
+ static void LoadAudioSetConfigurationProviderJson();
+
+ static const le_audio::CodecSpecificConfiguration* LookupCodecSpecificParam(
+ const flatbuffers::Vector<flatbuffers::Offset<
+ le_audio::CodecSpecificConfiguration>>* flat_codec_specific_params,
+ le_audio::CodecSpecificLtvGenericTypes type);
+
+ static void populateAudioChannelAllocation(
+ CodecSpecificConfigurationLtv::AudioChannelAllocation&
+ audio_channel_allocation,
+ uint32_t audio_location);
+
+ static void populateConfigurationData(
+ LeAudioAseConfiguration& ase,
+ const flatbuffers::Vector<
+ flatbuffers::Offset<le_audio::CodecSpecificConfiguration>>*
+ flat_codec_specific_params);
+
+ static void populateAseConfiguration(
+ LeAudioAseConfiguration& ase,
+ const le_audio::AudioSetSubConfiguration* flat_subconfig,
+ const le_audio::QosConfiguration* qos_cfg);
+
+ static void populateAseQosConfiguration(
+ LeAudioAseQosConfiguration& qos,
+ const le_audio::QosConfiguration* qos_cfg);
+
+ static AseDirectionConfiguration SetConfigurationFromFlatSubconfig(
+ const le_audio::AudioSetSubConfiguration* flat_subconfig,
+ const le_audio::QosConfiguration* qos_cfg, CodecLocation location);
+
+ static void processSubconfig(
+ const le_audio::AudioSetSubConfiguration* subconfig,
+ const le_audio::QosConfiguration* qos_cfg,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ directionAseConfiguration,
+ CodecLocation location);
+
+ static void PopulateAseConfigurationFromFlat(
+ const le_audio::AudioSetConfiguration* flat_cfg,
+ std::vector<const le_audio::CodecConfiguration*>* codec_cfgs,
+ std::vector<const le_audio::QosConfiguration*>* qos_cfgs,
+ CodecLocation location,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ sourceAseConfiguration,
+ std::vector<std::optional<AseDirectionConfiguration>>&
+ sinkAseConfiguration,
+ ConfigurationFlags& configurationFlags);
+
+ static bool LoadConfigurationsFromFiles(const char* schema_file,
+ const char* content_file,
+ CodecLocation location);
+
+ static bool LoadScenariosFromFiles(const char* schema_file,
+ const char* content_file);
+
+ static bool LoadContent(
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ config_files,
+ std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
+ scenario_files,
+ CodecLocation location);
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
index 26da5fb..b6df67e 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
@@ -14,6 +14,11 @@
* limitations under the License.
*/
+#include <set>
+
+#include "aidl/android/hardware/bluetooth/audio/ChannelMode.h"
+#include "aidl/android/hardware/bluetooth/audio/CodecId.h"
+#include "aidl_android_hardware_bluetooth_audio_setting_enums.h"
#define LOG_TAG "BTAudioCodecsProviderAidl"
#include "BluetoothLeAudioCodecsProvider.h"
@@ -50,6 +55,123 @@
return le_audio_offload_setting;
}
+std::unordered_map<SessionType, std::vector<CodecInfo>>
+BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo(
+ const std::optional<setting::LeAudioOffloadSetting>&
+ le_audio_offload_setting) {
+ // Load from previous storage if present
+ if (!session_codecs_map_.empty()) return session_codecs_map_;
+
+ isInvalidFileContent = true;
+ if (!le_audio_offload_setting.has_value()) return {};
+
+ // Load scenario, configuration, codec configuration and strategy
+ LoadConfigurationToMap(le_audio_offload_setting);
+ if (supported_scenarios_.empty() || configuration_map_.empty() ||
+ codec_configuration_map_.empty() || strategy_configuration_map_.empty())
+ return {};
+
+ // Map each configuration into a CodecInfo
+ std::unordered_map<std::string, CodecInfo> config_codec_info_map_;
+
+ for (auto& p : configuration_map_) {
+ // Initialize new CodecInfo for the config
+ auto config_name = p.first;
+ if (config_codec_info_map_.count(config_name) == 0)
+ config_codec_info_map_[config_name] = CodecInfo();
+
+ // Getting informations from codecConfig and strategyConfig
+ const auto codec_config_name = p.second.getCodecConfiguration();
+ const auto strategy_config_name = p.second.getStrategyConfiguration();
+ const auto codec_configuration_map_iter =
+ codec_configuration_map_.find(codec_config_name);
+ if (codec_configuration_map_iter == codec_configuration_map_.end())
+ continue;
+ const auto strategy_configuration_map_iter =
+ strategy_configuration_map_.find(strategy_config_name);
+ if (strategy_configuration_map_iter == strategy_configuration_map_.end())
+ continue;
+
+ const auto& codec_config = codec_configuration_map_iter->second;
+ const auto codec = codec_config.getCodec();
+ const auto& strategy_config = strategy_configuration_map_iter->second;
+ const auto strategy_config_channel_count =
+ strategy_config.getChannelCount();
+
+ // Initiate information
+ auto& codec_info = config_codec_info_map_[config_name];
+ switch (codec) {
+ case setting::CodecType::LC3:
+ codec_info.name = "LC3";
+ codec_info.id = CodecId::Core::LC3;
+ break;
+ default:
+ codec_info.name = "UNDEFINE";
+ codec_info.id = CodecId::Vendor();
+ break;
+ }
+ codec_info.transport =
+ CodecInfo::Transport::make<CodecInfo::Transport::Tag::leAudio>();
+
+ // Mapping codec configuration information
+ auto& transport =
+ codec_info.transport.get<CodecInfo::Transport::Tag::leAudio>();
+ transport.samplingFrequencyHz.push_back(
+ codec_config.getSamplingFrequency());
+ // Mapping octetsPerCodecFrame to bitdepth for easier comparison.
+ transport.bitdepth.push_back(codec_config.getOctetsPerCodecFrame());
+ transport.frameDurationUs.push_back(codec_config.getFrameDurationUs());
+ switch (strategy_config.getAudioLocation()) {
+ case setting::AudioLocation::MONO:
+ if (strategy_config_channel_count == 1)
+ transport.channelMode.push_back(ChannelMode::MONO);
+ else
+ transport.channelMode.push_back(ChannelMode::DUALMONO);
+ break;
+ case setting::AudioLocation::STEREO:
+ transport.channelMode.push_back(ChannelMode::STEREO);
+ break;
+ default:
+ transport.channelMode.push_back(ChannelMode::UNKNOWN);
+ break;
+ }
+ }
+
+ // Goes through every scenario, deduplicate configuration
+ std::set<std::string> encoding_config, decoding_config, broadcast_config;
+ for (auto& s : supported_scenarios_) {
+ if (s.hasEncode()) encoding_config.insert(s.getEncode());
+ if (s.hasDecode()) decoding_config.insert(s.getDecode());
+ if (s.hasBroadcast()) broadcast_config.insert(s.getBroadcast());
+ }
+
+ // Split by session types and add results
+ const auto encoding_path =
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
+ const auto decoding_path =
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
+ const auto broadcast_path =
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
+ session_codecs_map_ =
+ std::unordered_map<SessionType, std::vector<CodecInfo>>();
+ session_codecs_map_[encoding_path] = std::vector<CodecInfo>();
+ session_codecs_map_[decoding_path] = std::vector<CodecInfo>();
+ session_codecs_map_[broadcast_path] = std::vector<CodecInfo>();
+ session_codecs_map_[encoding_path].reserve(encoding_config.size());
+ session_codecs_map_[decoding_path].reserve(decoding_config.size());
+ session_codecs_map_[broadcast_path].reserve(broadcast_config.size());
+ for (auto& c : encoding_config)
+ session_codecs_map_[encoding_path].push_back(config_codec_info_map_[c]);
+ for (auto& c : decoding_config)
+ session_codecs_map_[decoding_path].push_back(config_codec_info_map_[c]);
+ for (auto& c : broadcast_config)
+ session_codecs_map_[broadcast_path].push_back(config_codec_info_map_[c]);
+
+ isInvalidFileContent = session_codecs_map_.empty();
+
+ return session_codecs_map_;
+}
+
std::vector<LeAudioCodecCapabilitiesSetting>
BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
const std::optional<setting::LeAudioOffloadSetting>&
@@ -58,6 +180,8 @@
return leAudioCodecCapabilities;
}
+ isInvalidFileContent = true;
+
if (!le_audio_offload_setting.has_value()) {
LOG(ERROR)
<< __func__
@@ -65,40 +189,13 @@
return {};
}
- ClearLeAudioCodecCapabilities();
- isInvalidFileContent = true;
-
- std::vector<setting::Scenario> supported_scenarios =
- GetScenarios(le_audio_offload_setting);
- if (supported_scenarios.empty()) {
- LOG(ERROR) << __func__ << ": No scenarios in "
- << kLeAudioCodecCapabilitiesFile;
+ LoadConfigurationToMap(le_audio_offload_setting);
+ if (supported_scenarios_.empty() || configuration_map_.empty() ||
+ codec_configuration_map_.empty() || strategy_configuration_map_.empty())
return {};
- }
-
- UpdateConfigurationsToMap(le_audio_offload_setting);
- if (configuration_map_.empty()) {
- LOG(ERROR) << __func__ << ": No configurations in "
- << kLeAudioCodecCapabilitiesFile;
- return {};
- }
-
- UpdateCodecConfigurationsToMap(le_audio_offload_setting);
- if (codec_configuration_map_.empty()) {
- LOG(ERROR) << __func__ << ": No codec configurations in "
- << kLeAudioCodecCapabilitiesFile;
- return {};
- }
-
- UpdateStrategyConfigurationsToMap(le_audio_offload_setting);
- if (strategy_configuration_map_.empty()) {
- LOG(ERROR) << __func__ << ": No strategy configurations in "
- << kLeAudioCodecCapabilitiesFile;
- return {};
- }
leAudioCodecCapabilities =
- ComposeLeAudioCodecCapabilities(supported_scenarios);
+ ComposeLeAudioCodecCapabilities(supported_scenarios_);
isInvalidFileContent = leAudioCodecCapabilities.empty();
return leAudioCodecCapabilities;
@@ -109,6 +206,8 @@
configuration_map_.clear();
codec_configuration_map_.clear();
strategy_configuration_map_.clear();
+ session_codecs_map_.clear();
+ supported_scenarios_.clear();
}
std::vector<setting::Scenario> BluetoothLeAudioCodecsProvider::GetScenarios(
@@ -191,6 +290,40 @@
}
}
+void BluetoothLeAudioCodecsProvider::LoadConfigurationToMap(
+ const std::optional<setting::LeAudioOffloadSetting>&
+ le_audio_offload_setting) {
+ ClearLeAudioCodecCapabilities();
+
+ supported_scenarios_ = GetScenarios(le_audio_offload_setting);
+ if (supported_scenarios_.empty()) {
+ LOG(ERROR) << __func__ << ": No scenarios in "
+ << kLeAudioCodecCapabilitiesFile;
+ return;
+ }
+
+ UpdateConfigurationsToMap(le_audio_offload_setting);
+ if (configuration_map_.empty()) {
+ LOG(ERROR) << __func__ << ": No configurations in "
+ << kLeAudioCodecCapabilitiesFile;
+ return;
+ }
+
+ UpdateCodecConfigurationsToMap(le_audio_offload_setting);
+ if (codec_configuration_map_.empty()) {
+ LOG(ERROR) << __func__ << ": No codec configurations in "
+ << kLeAudioCodecCapabilitiesFile;
+ return;
+ }
+
+ UpdateStrategyConfigurationsToMap(le_audio_offload_setting);
+ if (strategy_configuration_map_.empty()) {
+ LOG(ERROR) << __func__ << ": No strategy configurations in "
+ << kLeAudioCodecCapabilitiesFile;
+ return;
+ }
+}
+
std::vector<LeAudioCodecCapabilitiesSetting>
BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities(
const std::vector<setting::Scenario>& supported_scenarios) {
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
index 654e70c..5bf67e2 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
@@ -22,6 +22,8 @@
#include <unordered_map>
#include <vector>
+#include "aidl/android/hardware/bluetooth/audio/CodecInfo.h"
+#include "aidl/android/hardware/bluetooth/audio/SessionType.h"
#include "aidl_android_hardware_bluetooth_audio_setting.h"
namespace aidl {
@@ -39,14 +41,20 @@
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting);
static void ClearLeAudioCodecCapabilities();
+ static std::unordered_map<SessionType, std::vector<CodecInfo>>
+ GetLeAudioCodecInfo(const std::optional<setting::LeAudioOffloadSetting>&
+ le_audio_offload_setting);
private:
+ static inline std::vector<setting::Scenario> supported_scenarios_;
static inline std::unordered_map<std::string, setting::Configuration>
configuration_map_;
static inline std::unordered_map<std::string, setting::CodecConfiguration>
codec_configuration_map_;
static inline std::unordered_map<std::string, setting::StrategyConfiguration>
strategy_configuration_map_;
+ static inline std::unordered_map<SessionType, std::vector<CodecInfo>>
+ session_codecs_map_;
static std::vector<setting::Scenario> GetScenarios(
const std::optional<setting::LeAudioOffloadSetting>&
@@ -60,6 +68,9 @@
static void UpdateStrategyConfigurationsToMap(
const std::optional<setting::LeAudioOffloadSetting>&
le_audio_offload_setting);
+ static void LoadConfigurationToMap(
+ const std::optional<setting::LeAudioOffloadSetting>&
+ le_audio_offload_setting);
static std::vector<LeAudioCodecCapabilitiesSetting>
ComposeLeAudioCodecCapabilities(
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs
new file mode 100644
index 0000000..bde467d
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2022 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.
+ *
+ */
+namespace aidl.android.hardware.bluetooth.audio.le_audio;
+enum CodecSpecificLtvGenericTypes : byte {
+ SUPPORTED_SAMPLING_FREQUENCY = 0x01,
+ SUPPORTED_FRAME_DURATION = 0x02,
+ SUPPORTED_AUDIO_CHANNEL_ALLOCATION = 0x03,
+ SUPPORTED_OCTETS_PER_CODEC_FRAME = 0x04,
+ SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 0x05,
+}
+/// Note: Holds either a single value (when `value_width == 0`) or multiple
+/// values if `value.length()` is no-remainder divisible by the non-zero
+/// `value_width`.
+/// Note: Consider extending it with `flags` field, to hold additional info like
+/// IsBitfield, IsRange, etc. if we need these type-specific validations.
+table CompoundValue {
+ value: [ubyte] (required);
+ value_width: ubyte = 0;
+}
+table CodecSpecificConfiguration {
+ name: string;
+ type: ubyte (key);
+ compound_value: CompoundValue;
+}
+struct CodecId {
+ coding_format: ubyte;
+ vendor_company_id : ushort;
+ vendor_codec_id : ushort;
+}
+enum AudioSetConfigurationStrategy : byte {
+ MONO_ONE_CIS_PER_DEVICE = 0x00,
+ STEREO_TWO_CISES_PER_DEVICE = 0x01,
+ STEREO_ONE_CIS_PER_DEVICE = 0x02,
+}
+enum AudioSetConfigurationDirection : byte {
+ SINK = 0x01,
+ SOURCE = 0x02,
+}
+enum AudioSetConfigurationTargetLatency : byte {
+ LOW = 0x01,
+ BALANCED_RELIABILITY = 0x02,
+ HIGH_RELIABILITY = 0x03,
+}
+table AudioSetSubConfiguration {
+ device_cnt: ubyte;
+ ase_cnt: ubyte;
+ direction: AudioSetConfigurationDirection = SINK;
+ configuration_strategy: AudioSetConfigurationStrategy;
+ codec_id : CodecId (required);
+ codec_configuration: [CodecSpecificConfiguration] (required);
+}
+table CodecConfiguration {
+ name: string (key, required);
+ subconfigurations: [AudioSetSubConfiguration] (required);
+}
+table QosConfiguration {
+ name: string (key, required);
+ target_latency: AudioSetConfigurationTargetLatency = BALANCED_RELIABILITY;
+ retransmission_number: ubyte;
+ max_transport_latency : ushort;
+}
+/// Each set configration can contain multiple logical subconfigurations, which
+/// all must be configurable with the current set of audio devices. For example,
+/// one can define multiple output stream configurations with different
+/// qualities, or assign different configurations to each stream direction.
+table AudioSetConfiguration {
+ name: string (key, required);
+ codec_config_name: string (required);
+ qos_config_name: [string] (required);
+}
+table AudioSetConfigurations {
+ _comments_: [string];
+ configurations: [AudioSetConfiguration] (required);
+ codec_configurations: [CodecConfiguration] (required);
+ qos_configurations: [QosConfiguration] (required);
+}
+root_type AudioSetConfigurations;
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json
new file mode 100644
index 0000000..404a48a
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json
@@ -0,0 +1,11382 @@
+{
+ "_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_AUDIO_CHANNEL_ALLOCATION = 3",
+ " 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",
+ " ASE Configuration strategies:",
+ " MONO_ONE_CIS_PER_DEVICE = 0",
+ " STEREO_TWO_CISES_PER_DEVICE = 1",
+ " STEREO_ONE_CIS_PER_DEVICE = 2",
+ " 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": "DualDev_OneChanStereoSnk_16_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_1_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_32_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_2_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanMonoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanMonoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_4_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_48_4",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_3_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_48_3",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_48_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_48_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_32_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_24_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "qos_config_name": [
+ "QoS_Config_16_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_16_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_24_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_2_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_24_2_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_24_2",
+ "qos_config_name": [
+ "QoS_Config_24_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_32_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_32_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_32_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_32_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_32_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_32_2_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_32_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_32_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_High_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_1",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_3_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_3_High_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_3_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_2_High_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_2_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_1_High_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_1_2",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_1",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_3_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_3_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_3_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_2_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_2_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_2_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_1_Low_Latency",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_1_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_1_2",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_1",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_3_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_3_High_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_3_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_2_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_2_High_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_2_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_1_Low_Latency",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_1_High_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_1_2",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_48_1_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_1",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_1"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4",
+ "qos_config_name": [
+ "QoS_Config_48_4_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_3_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_3_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_3",
+ "qos_config_name": [
+ "QoS_Config_48_3_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_2_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_2_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_2",
+ "qos_config_name": [
+ "QoS_Config_48_2_2"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_1_High_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_1",
+ "qos_config_name": [
+ "QoS_Config_High_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_1_2",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_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": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_1_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_24_2_1_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
+ "qos_config_name": [
+ "QoS_Config_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Low_Latency",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2",
+ "qos_config_name": [
+ "QoS_Config_Low_Latency"
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
+ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_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": "DualDev_OneChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanMonoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 3
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_4",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_3",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_2",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_48_1",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 8
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_32_1",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_24_1",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSrc_16_1",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_3",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 120,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": [
+ 0
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SOURCE",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_24_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_24_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_24_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_24_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_cnt": 2,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_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": [
+ 6
+ ]
+ }
+ },
+ {
+ "name": "frame_duration",
+ "type": 2,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ },
+ {
+ "name": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 2,
+ "ase_cnt": 4,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "device_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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_TwoChanStereoSnk_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 1,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 3,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_32_2",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "octets_per_codec_frame",
+ "type": 4,
+ "compound_value": {
+ "value": [
+ 80,
+ 0
+ ]
+ }
+ },
+ {
+ "name": "codec_frame_blocks_per_sdu",
+ "type": 5,
+ "compound_value": {
+ "value": [
+ 1
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "SingleDev_OneChanStereoSnk_32_1",
+ "subconfigurations": [
+ {
+ "device_cnt": 1,
+ "ase_cnt": 2,
+ "direction": "SINK",
+ "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE",
+ "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": "audio_channel_allocation",
+ "type": 3,
+ "compound_value": {
+ "value": [
+ 1,
+ 0,
+ 0,
+ 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
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "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
+ }
+
+ ]
+}
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs
new file mode 100644
index 0000000..e898bdc
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 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.
+ *
+ */
+namespace aidl.android.hardware.bluetooth.audio.le_audio;
+/// Scenario represents the use case such as "Media", "Conversation", etc.
+/// Each scenario can list any number of codec configurations by their names in
+/// the order of preference. That means if the first entry does not meet all
+/// the current requirements (such as peer device capabilities etc.) next
+/// configurations are being checked.
+///
+/// The referenced codec configurations are defined by the
+/// audio_set_configurations.fbs schema and loaded from a different source file.
+/// Multiple scenarios can reference same codec configurations.
+table AudioSetScenario {
+ _comments_: [string];
+ name: string (key, required);
+ configurations: [string] (required);
+}
+table AudioSetScenarios {
+ _comments_: [string];
+ scenarios: [AudioSetScenario] (required);
+}
+root_type AudioSetScenarios;
diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json
new file mode 100644
index 0000000..a28c6cd
--- /dev/null
+++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json
@@ -0,0 +1,304 @@
+{
+ "_comments_": [
+ "== Audio Set Scenarios ==",
+ " Each defined scenario references externally defined audio set",
+ " configurations, listed in the order of priority."
+ ],
+ "scenarios": [
+ {
+ "name": "Conversational",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_2",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_2",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_2",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_2",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
+ "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_4_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_3_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_24_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability",
+ "VND_SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32khz_Server_Prefered_1",
+ "VND_SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32khz_60oct_R3_L22_1",
+ "DualDev_OneChanMonoSnk_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Media",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_48_4_High_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_2",
+ "DualDev_OneChanStereoSnk_48_2_High_Reliability",
+ "DualDev_OneChanStereoSnk_48_2_2",
+ "DualDev_OneChanStereoSnk_48_3_High_Reliability",
+ "DualDev_OneChanStereoSnk_48_3_2",
+ "DualDev_OneChanStereoSnk_48_1_High_Reliability",
+ "DualDev_OneChanStereoSnk_48_1_2",
+ "DualDev_OneChanStereoSnk_24_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_24_2_2",
+ "DualDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_16_2_2",
+ "DualDev_OneChanStereoSnk_16_1_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_16_1_2",
+ "SingleDev_OneChanStereoSnk_48_4_High_Reliability",
+ "SingleDev_OneChanStereoSnk_48_4_2",
+ "SingleDev_OneChanStereoSnk_48_2_High_Reliability",
+ "SingleDev_OneChanStereoSnk_48_2_2",
+ "SingleDev_OneChanStereoSnk_48_3_High_Reliability",
+ "SingleDev_OneChanStereoSnk_48_3_2",
+ "SingleDev_OneChanStereoSnk_48_1_High_Reliability",
+ "SingleDev_OneChanStereoSnk_48_1_2",
+ "SingleDev_OneChanStereoSnk_24_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_24_2_2",
+ "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_16_2_2",
+ "SingleDev_OneChanStereoSnk_16_1_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_16_1_2",
+ "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_2",
+ "SingleDev_TwoChanStereoSnk_48_4_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_2",
+ "SingleDev_TwoChanStereoSnk_48_2_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_2_2",
+ "SingleDev_TwoChanStereoSnk_48_3_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_3_2",
+ "SingleDev_TwoChanStereoSnk_48_1_High_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_1_2",
+ "SingleDev_TwoChanStereoSnk_24_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_24_2_2",
+ "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_16_2_2",
+ "SingleDev_TwoChanStereoSnk_16_1_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_16_1_2",
+ "SingleDev_OneChanMonoSnk_48_4_High_Reliability",
+ "SingleDev_OneChanMonoSnk_48_4_2",
+ "SingleDev_OneChanMonoSnk_48_2_High_Reliability",
+ "SingleDev_OneChanMonoSnk_48_2_2",
+ "SingleDev_OneChanMonoSnk_48_3_High_Reliability",
+ "SingleDev_OneChanMonoSnk_48_3_2",
+ "SingleDev_OneChanMonoSnk_48_1_High_Reliability",
+ "SingleDev_OneChanMonoSnk_48_1_2",
+ "SingleDev_OneChanMonoSnk_32_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_32_2_2",
+ "SingleDev_OneChanMonoSnk_32_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_32_1_2",
+ "SingleDev_OneChanMonoSnk_24_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_24_2_2",
+ "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_16_2_2",
+ "SingleDev_OneChanMonoSnk_16_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_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",
+ "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Game",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_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",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_48_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_48_3_Low_Latency",
+ "DualDev_OneChanStereoSnk_48_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_32_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_24_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_24_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_48_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_48_3_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_48_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_32_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_24_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_24_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_16_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_48_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_48_3_Low_Latency",
+ "SingleDev_OneChanStereoSnk_48_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_32_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_32_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_24_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_24_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_16_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_16_1_Low_Latency"
+ ]
+ },
+ {
+ "name": "VoiceAssistants",
+ "configurations": [
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
+ "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability"
+ ]
+ },
+ {
+ "name": "Live",
+ "configurations": [
+ "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1",
+ "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability",
+ "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency",
+ "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1",
+ "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability",
+ "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability"
+ ]
+ }
+ ]
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
index e7fad4d..8fc77ae 100644
--- a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
@@ -35,6 +35,7 @@
@VintfStability
parcelable ChannelSoudingRawData {
int procedureCounter;
+ int[] frequencyCompensation;
boolean aborted;
android.hardware.bluetooth.ranging.ChannelSoundingSingleSideData initiatorData;
android.hardware.bluetooth.ranging.ChannelSoundingSingleSideData reflectorData;
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
index 9fe85da..ddaba72 100644
--- a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
@@ -38,6 +38,7 @@
@nullable byte[] packetQuality;
@nullable byte[] packetRssiDbm;
@nullable android.hardware.bluetooth.ranging.Nadm[] packetNadm;
+ @nullable int[] measuredFreqOffset;
@nullable List<android.hardware.bluetooth.ranging.ComplexNumber> packetPct1;
@nullable List<android.hardware.bluetooth.ranging.ComplexNumber> packetPct2;
byte referencePowerDbm;
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl
index a51ba37..4125748 100644
--- a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl
@@ -36,6 +36,7 @@
parcelable StepTonePct {
List<android.hardware.bluetooth.ranging.ComplexNumber> tonePcts;
byte[] toneQualityIndicator;
+ byte toneExtensionAntennaIndex;
const int TONE_QUALITY_GOOD = 0;
const int TONE_QUALITY_MEDIUM = 1;
const int TONE_QUALITY_LOW = 2;
@@ -44,4 +45,9 @@
const int EXTENSION_SLOT_TONE_NOT_EXPECTED_TO_BE_PRESENT = 1;
const int EXTENSION_SLOT_TONE_EXPECTED_TO_BE_PRESENT = 2;
const int EXTENSION_SLOT_SHIFT_AMOUNT = 4;
+ const byte TONE_EXTENSION_ANTENNA_1 = 0x0;
+ const byte TONE_EXTENSION_ANTENNA_2 = 0x1;
+ const byte TONE_EXTENSION_ANTENNA_3 = 0x2;
+ const byte TONE_EXTENSION_ANTENNA_4 = 0x3;
+ const byte TONE_EXTENSION_UNUSED = 0xFFu8;
}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
index 3c8a62f..0106865 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
@@ -29,6 +29,11 @@
*/
int procedureCounter;
/**
+ * Frequency Compensation indicates fractional frequency
+ * offset (FFO) value of initiator, in 0.01ppm
+ */
+ int[] frequencyCompensation;
+ /**
* Indicate if the procedure aborted.
*/
boolean aborted;
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
index 2c3f201..942fc0d 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
@@ -42,6 +42,10 @@
*/
@nullable Nadm[] packetNadm;
/**
+ * Measured Frequency Offset from mode 0, relative to the remote device, in 0.01ppm
+ */
+ @nullable int[] measuredFreqOffset;
+ /**
* Packet_PCT1 or packet_PCT2 of mode-1 or mode-3, if sounding sequence is used and sounding
* phase-based ranging is supported.
*/
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl
index 99c6d65..4650861 100644
--- a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl
@@ -23,6 +23,10 @@
*/
@VintfStability
parcelable StepTonePct {
+ /**
+ * PCT measured from mode-2 or mode-3 steps
+ * (in ascending order of antenna position with tone extension data at the end).
+ */
List<ComplexNumber> tonePcts;
const int TONE_QUALITY_GOOD = 0;
const int TONE_QUALITY_MEDIUM = 1;
@@ -52,4 +56,20 @@
* See: https://bluetooth.com/specifications/specs/channel-sounding-cr-pr/
*/
byte[] toneQualityIndicator;
+
+ const byte TONE_EXTENSION_ANTENNA_1 = 0x0;
+ const byte TONE_EXTENSION_ANTENNA_2 = 0x1;
+ const byte TONE_EXTENSION_ANTENNA_3 = 0x2;
+ const byte TONE_EXTENSION_ANTENNA_4 = 0x3;
+ const byte TONE_EXTENSION_UNUSED = 0xFFu8;
+ /**
+ * Tone Extension Antenna Index indicates the Antenna position used in tone extension slot
+ *
+ * 0x00 = A1
+ * 0x01 = A2
+ * 0x02 = A3
+ * 0x03 = A4
+ * 0xFF = Tone extension not used
+ */
+ byte toneExtensionAntennaIndex;
}
diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp
index 7643926..8900fb8 100644
--- a/power/aidl/Android.bp
+++ b/power/aidl/Android.bp
@@ -28,11 +28,20 @@
"android/hardware/power/*.aidl",
],
stability: "vintf",
+ imports: [
+ "android.hardware.common.fmq-V1",
+ "android.hardware.common-V2",
+ ],
backend: {
cpp: {
+ enabled: false,
+ },
+ ndk: {
enabled: true,
},
java: {
+ sdk_version: "module_current",
+ enabled: true,
platform_apis: true,
},
},
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl
similarity index 80%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl
index cc07f9b..d3caca4 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl
@@ -31,12 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.power;
+@VintfStability
+parcelable ChannelConfig {
+ android.hardware.common.fmq.MQDescriptor<android.hardware.power.ChannelMessage,android.hardware.common.fmq.SynchronizedReadWrite> channelDescriptor;
+ @nullable android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> eventFlagDescriptor;
+ int readFlagBitmask;
+ int writeFlagBitmask;
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl
similarity index 64%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl
index cc07f9b..25f01c0 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl
@@ -31,12 +31,22 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.power;
+@FixedSize @VintfStability
+parcelable ChannelMessage {
+ int sessionID;
+ android.hardware.power.ChannelMessage.ChannelMessageContents data;
+ @FixedSize @VintfStability
+ union ChannelMessageContents {
+ int[20] tids = {(-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */};
+ long targetDuration;
+ android.hardware.power.SessionHint hint;
+ android.hardware.power.ChannelMessage.ChannelMessageContents.SessionModeSetter mode;
+ android.hardware.power.WorkDurationFixedV1 workDuration;
+ @FixedSize @VintfStability
+ parcelable SessionModeSetter {
+ android.hardware.power.SessionMode modeInt;
+ boolean enabled;
+ }
+ }
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
index ae03313..8acdaf2 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
@@ -40,4 +40,7 @@
boolean isBoostSupported(in android.hardware.power.Boost type);
android.hardware.power.IPowerHintSession createHintSession(in int tgid, in int uid, in int[] threadIds, in long durationNanos);
long getHintSessionPreferredRate();
+ android.hardware.power.IPowerHintSession createHintSessionWithConfig(in int tgid, in int uid, in int[] threadIds, in long durationNanos, in android.hardware.power.SessionTag tag, out android.hardware.power.SessionConfig config);
+ android.hardware.power.ChannelConfig getSessionChannel(in int tgid, in int uid);
+ oneway void closeSessionChannel(in int tgid, in int uid);
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
index 6bc663e..010f815 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
@@ -42,4 +42,5 @@
oneway void sendHint(android.hardware.power.SessionHint hint);
void setThreads(in int[] threadIds);
oneway void setMode(android.hardware.power.SessionMode type, boolean enabled);
+ android.hardware.power.SessionConfig getSessionConfig();
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl
similarity index 89%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl
index cc07f9b..b03cfb2 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl
@@ -31,12 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.power;
+@VintfStability
+parcelable SessionConfig {
+ long id;
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
similarity index 91%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
index cc07f9b..80848a4 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
@@ -31,12 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
+package android.hardware.power;
@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+enum SessionTag {
+ OTHER,
+ SURFACEFLINGER,
+ HWUI,
+ GAME,
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl
similarity index 87%
copy from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl
index cc07f9b..8cd246d 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl
@@ -31,12 +31,12 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.security.secretkeeper;
-/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+package android.hardware.power;
+@FixedSize @VintfStability
+parcelable WorkDurationFixedV1 {
+ long timeStampNanos;
+ long durationNanos;
+ long workPeriodStartTimestampNanos;
+ long cpuDurationNanos;
+ long gpuDurationNanos;
}
diff --git a/power/aidl/android/hardware/power/ChannelConfig.aidl b/power/aidl/android/hardware/power/ChannelConfig.aidl
new file mode 100644
index 0000000..4da292e
--- /dev/null
+++ b/power/aidl/android/hardware/power/ChannelConfig.aidl
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright (C) 2023 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.
+ */
+
+package android.hardware.power;
+
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.power.ChannelMessage;
+
+@VintfStability
+parcelable ChannelConfig {
+ /**
+ * The message queue descriptor that provides the information necessary for
+ * a client to write to this channel.
+ */
+ MQDescriptor<ChannelMessage, SynchronizedReadWrite> channelDescriptor;
+
+ /**
+ * A message queue descriptor used to pass an optional event flag to clients,
+ * used to synchronize multiple message queues using the same flag. If not
+ * defined, the flag from the channelDescriptor should be used.
+ */
+ @nullable MQDescriptor<byte, SynchronizedReadWrite> eventFlagDescriptor;
+
+ /**
+ * The read flag bitmask to be used with the event flag, specifying the
+ * bits used by this channel to mark that the buffer has been read from.
+ * If set to 0, the default bitmask will be used.
+ */
+ int readFlagBitmask;
+
+ /**
+ * The write flag bitmask to be used with the event flag, specifying the
+ * bits used by this channel to mark that the buffer has been written to.
+ * If set to 0, the default bitmask will be used.
+ */
+ int writeFlagBitmask;
+}
diff --git a/power/aidl/android/hardware/power/ChannelMessage.aidl b/power/aidl/android/hardware/power/ChannelMessage.aidl
new file mode 100644
index 0000000..4747d90
--- /dev/null
+++ b/power/aidl/android/hardware/power/ChannelMessage.aidl
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+package android.hardware.power;
+
+import android.hardware.power.SessionHint;
+import android.hardware.power.SessionMode;
+import android.hardware.power.WorkDurationFixedV1;
+
+/**
+ * Data sent through the FMQ must follow this structure. It's important to note
+ * that such data may come from the app itself, so the HAL must validate all
+ * data received through this interface, and reject any calls not guaranteed to be
+ * valid. Each of the types defined in the inner union maps to an equivalent call
+ * on IPowerHintSession, and is merely being used to expedite the use of that API
+ * in cases where it is safe to bypass the HintManagerService.
+ */
+@FixedSize
+@VintfStability
+parcelable ChannelMessage {
+ /**
+ * The ID of the specific session sending the hint, used to enable a single
+ * channel to be multiplexed across all sessions in a single process.
+ */
+ int sessionID;
+
+ /**
+ * A union defining the different messages that can be passed through the
+ * channel. Each type corresponds to a different call in IPowerHintSession.
+ */
+ ChannelMessageContents data;
+
+ @FixedSize
+ @VintfStability
+ union ChannelMessageContents {
+ /**
+ * List of TIDs for this session to change to. Can be used in cases
+ * where HintManagerService is not needed to validate the TIDs, such as
+ * when all TIDs directly belong to the process that owns the session.
+ */
+ int[20] tids = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+
+ /**
+ * Setting this field will update the session’s target duration, equivalent
+ * to calling updateTargetWorkDuration(targetDuration).
+ */
+ long targetDuration;
+
+ /**
+ * Setting this field will send a hint to the session, equivalent to
+ * calling sendHint(hint).
+ */
+ SessionHint hint;
+
+ /**
+ * Setting this field will send a hint to the session, equivalent to
+ * calling setMode(mode.modeInt, mode.enabled).
+ */
+ SessionModeSetter mode;
+
+ /**
+ * Setting this field will update the session’s actual duration, equivalent
+ * to calling reportActualWorkDuration([workDuration]). Only one duration
+ * can be passed at a time; this API expects durations to be reported
+ * immediately each frame, since the overhead of this call is much lower.
+ */
+ WorkDurationFixedV1 workDuration;
+
+ /**
+ * This structure is used to fit both the mode and the state within one
+ * entry in the union.
+ */
+ @FixedSize
+ @VintfStability
+ parcelable SessionModeSetter {
+ SessionMode modeInt;
+ boolean enabled;
+ }
+ }
+}
diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl
index ee8e5a3..e25714f 100644
--- a/power/aidl/android/hardware/power/IPower.aidl
+++ b/power/aidl/android/hardware/power/IPower.aidl
@@ -17,8 +17,11 @@
package android.hardware.power;
import android.hardware.power.Boost;
+import android.hardware.power.ChannelConfig;
import android.hardware.power.IPowerHintSession;
import android.hardware.power.Mode;
+import android.hardware.power.SessionConfig;
+import android.hardware.power.SessionTag;
@VintfStability
interface IPower {
@@ -103,4 +106,42 @@
* EX_UNSUPPORTED_OPERATION if hint session is not supported.
*/
long getHintSessionPreferredRate();
+
+ /**
+ * A version of createHintSession that returns an additional bundle of session
+ * data, useful to help the session immediately communicate via an FMQ channel
+ * for more efficient updates.
+ *
+ * @return the new session if it is supported on this device, otherwise return
+ * with EX_UNSUPPORTED_OPERATION error if hint session is not
+ * supported on this device.
+ * @param tgid The TGID to be associated with this session.
+ * @param uid The UID to be associated with this session.
+ * @param threadIds The list of threads to be associated with this session.
+ * @param durationNanos The desired duration in nanoseconds for this session.
+ * @param config Extra session metadata to be returned to the caller.
+ */
+ IPowerHintSession createHintSessionWithConfig(in int tgid, in int uid, in int[] threadIds,
+ in long durationNanos, in SessionTag tag, out SessionConfig config);
+
+ /**
+ * Used to get an FMQ channel, per-process. The channel should be unique to
+ * that process, and should return the same ChannelConfig if called multiple
+ * times from that same process.
+ *
+ * @return the channel config if hint sessions are supported on this device,
+ * otherwise return with EX_UNSUPPORTED_OPERATION.
+ * @param tgid The TGID to be associated with this channel.
+ * @param uid The UID to be associated with this channel.
+ */
+ ChannelConfig getSessionChannel(in int tgid, in int uid);
+
+ /**
+ * Used to close a channel once it is no longer needed by a process, or that
+ * process dies.
+ *
+ * @param tgid The TGID to be associated with this channel.
+ * @param uid The UID to be associated with this channel.
+ */
+ oneway void closeSessionChannel(in int tgid, in int uid);
}
diff --git a/power/aidl/android/hardware/power/IPowerHintSession.aidl b/power/aidl/android/hardware/power/IPowerHintSession.aidl
index 62263c8..9dd251f 100644
--- a/power/aidl/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/android/hardware/power/IPowerHintSession.aidl
@@ -16,6 +16,7 @@
package android.hardware.power;
+import android.hardware.power.SessionConfig;
import android.hardware.power.SessionHint;
import android.hardware.power.SessionMode;
import android.hardware.power.WorkDuration;
@@ -91,4 +92,11 @@
* @param enabled True to enable the mode, false to disable it
*/
oneway void setMode(SessionMode type, boolean enabled);
+
+ /**
+ * This method provides direct access to a session's config data.
+ *
+ * @return the config data for this session
+ */
+ SessionConfig getSessionConfig();
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl b/power/aidl/android/hardware/power/SessionConfig.aidl
similarity index 63%
copy from security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to power/aidl/android/hardware/power/SessionConfig.aidl
index e9cce09..93dc9a2 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/power/aidl/android/hardware/power/SessionConfig.aidl
@@ -14,20 +14,17 @@
* limitations under the License.
*/
-package android.hardware.security.secretkeeper;
+package android.hardware.power;
/**
- * Secretkeeper unencrypted error code, returned via AIDL as service specific errors in
- * EX_SERVICE_SPECIFIC.
- * @hide
+ * Additional session to be passed to the hint session during creation, or acquired
+ * after creation from the session directly.
*/
@VintfStability
-@Backing(type="int")
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
-
- // TODO(b/291224769): Create a more exhaustive set of error code values.
+parcelable SessionConfig {
+ /**
+ * The session's unique ID, used to identify the session for debugging and
+ * for multiplexing on the per-process FMQ channel.
+ */
+ long id;
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl b/power/aidl/android/hardware/power/SessionTag.aidl
similarity index 62%
copy from security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl
copy to power/aidl/android/hardware/power/SessionTag.aidl
index e9cce09..c1d48e4 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/power/aidl/android/hardware/power/SessionTag.aidl
@@ -14,20 +14,28 @@
* limitations under the License.
*/
-package android.hardware.security.secretkeeper;
+package android.hardware.power;
-/**
- * Secretkeeper unencrypted error code, returned via AIDL as service specific errors in
- * EX_SERVICE_SPECIFIC.
- * @hide
- */
@VintfStability
@Backing(type="int")
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+enum SessionTag {
+ /**
+ * This tag is used to mark uncategorized hint sessions.
+ */
+ OTHER,
- // TODO(b/291224769): Create a more exhaustive set of error code values.
+ /**
+ * This tag is used to mark the SurfaceFlinger hint session.
+ */
+ SURFACEFLINGER,
+
+ /**
+ * This tag is used to mark HWUI hint sessions.
+ */
+ HWUI,
+
+ /**
+ * This tag is used to mark Game hint sessions.
+ */
+ GAME,
}
diff --git a/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl b/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl
new file mode 100644
index 0000000..2d202ff
--- /dev/null
+++ b/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+package android.hardware.power;
+
+@FixedSize
+@VintfStability
+parcelable WorkDurationFixedV1 {
+ /**
+ * Timestamp in nanoseconds based on CLOCK_MONOTONIC when the duration
+ * sample was measured.
+ */
+ long timeStampNanos;
+
+ /**
+ * Total work duration in nanoseconds.
+ */
+ long durationNanos;
+
+ /**
+ * Timestamp in nanoseconds based on CLOCK_MONOTONIC when the work starts.
+ * The work period start timestamp could be zero if the call is from
+ * the legacy SDK/NDK reportActualWorkDuration API.
+ */
+ long workPeriodStartTimestampNanos;
+
+ /**
+ * CPU work duration in nanoseconds.
+ * The CPU work duration could be the same as the total work duration if
+ * the call is from the legacy SDK/NDK reportActualWorkDuration API.
+ */
+ long cpuDurationNanos;
+
+ /**
+ * GPU work duration in nanoseconds.
+ * The GPU work duration could be zero if the call is from the legacy
+ * SDK/NDK reportActualWorkDuration API.
+ */
+ long gpuDurationNanos;
+}
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index e3af179..b4ccc7d 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -29,8 +29,12 @@
vintf_fragments: [":android.hardware.power.xml"],
vendor: true,
shared_libs: [
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
"libbase",
"libbinder_ndk",
+ "libcutils",
+ "libfmq",
],
srcs: [
"main.cpp",
diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp
index 8fe370c..8f15663 100644
--- a/power/aidl/default/Power.cpp
+++ b/power/aidl/default/Power.cpp
@@ -18,6 +18,8 @@
#include "PowerHintSession.h"
#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
namespace aidl {
namespace android {
@@ -27,6 +29,10 @@
namespace example {
using namespace std::chrono_literals;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::aidl::android::hardware::power::ChannelMessage;
+using ::android::AidlMessageQueue;
using ndk::ScopedAStatus;
@@ -70,6 +76,27 @@
return ScopedAStatus::ok();
}
+ndk::ScopedAStatus Power::createHintSessionWithConfig(
+ int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds, int64_t durationNanos,
+ SessionTag, SessionConfig* config, std::shared_ptr<IPowerHintSession>* _aidl_return) {
+ auto out = createHintSession(tgid, uid, threadIds, durationNanos, _aidl_return);
+ static_cast<PowerHintSession*>(_aidl_return->get())->getSessionConfig(config);
+ return out;
+}
+
+ndk::ScopedAStatus Power::getSessionChannel(int32_t, int32_t, ChannelConfig* _aidl_return) {
+ static AidlMessageQueue<ChannelMessage, SynchronizedReadWrite> stubQueue{1, true};
+ _aidl_return->channelDescriptor = stubQueue.dupeDesc();
+ _aidl_return->readFlagBitmask = 0;
+ _aidl_return->writeFlagBitmask = 0;
+ _aidl_return->eventFlagDescriptor = std::nullopt;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::closeSessionChannel(int32_t, int32_t) {
+ return ndk::ScopedAStatus::ok();
+}
+
ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
*outNanoseconds = std::chrono::nanoseconds(1ms).count();
return ScopedAStatus::ok();
diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h
index 7f8405e..baabaa7 100644
--- a/power/aidl/default/Power.h
+++ b/power/aidl/default/Power.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/power/BnPower.h>
+#include "aidl/android/hardware/power/SessionTag.h"
namespace aidl {
namespace android {
@@ -35,7 +36,14 @@
const std::vector<int32_t>& threadIds,
int64_t durationNanos,
std::shared_ptr<IPowerHintSession>* _aidl_return) override;
+ ndk::ScopedAStatus createHintSessionWithConfig(
+ int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds, int64_t durationNanos,
+ SessionTag tag, SessionConfig* config,
+ std::shared_ptr<IPowerHintSession>* _aidl_return) override;
ndk::ScopedAStatus getHintSessionPreferredRate(int64_t* outNanoseconds) override;
+ ndk::ScopedAStatus getSessionChannel(int32_t tgid, int32_t uid,
+ ChannelConfig* _aidl_return) override;
+ ndk::ScopedAStatus closeSessionChannel(int32_t tgid, int32_t uid) override;
private:
std::vector<std::shared_ptr<IPowerHintSession>> mPowerHintSessions;
diff --git a/power/aidl/default/PowerHintSession.cpp b/power/aidl/default/PowerHintSession.cpp
index 452e435..847a42e 100644
--- a/power/aidl/default/PowerHintSession.cpp
+++ b/power/aidl/default/PowerHintSession.cpp
@@ -17,6 +17,7 @@
#include "PowerHintSession.h"
#include <android-base/logging.h>
+#include "android/binder_auto_utils.h"
namespace aidl::android::hardware::power::impl::example {
@@ -63,4 +64,9 @@
return ScopedAStatus::ok();
}
+ScopedAStatus PowerHintSession::getSessionConfig(SessionConfig* _aidl_return) {
+ _aidl_return->id = 1;
+ return ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/default/PowerHintSession.h b/power/aidl/default/PowerHintSession.h
index b488bf1..2ed5588 100644
--- a/power/aidl/default/PowerHintSession.h
+++ b/power/aidl/default/PowerHintSession.h
@@ -35,6 +35,7 @@
ndk::ScopedAStatus sendHint(SessionHint hint) override;
ndk::ScopedAStatus setThreads(const std::vector<int32_t>& threadIds) override;
ndk::ScopedAStatus setMode(SessionMode mode, bool enabled) override;
+ ndk::ScopedAStatus getSessionConfig(SessionConfig* _aidl_return) override;
};
} // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp
index eb98b8b..c9285f4 100644
--- a/power/aidl/vts/Android.bp
+++ b/power/aidl/vts/Android.bp
@@ -31,6 +31,11 @@
srcs: ["VtsHalPowerTargetTest.cpp"],
shared_libs: [
"libbinder_ndk",
+ "libfmq",
+ ],
+ static_libs: [
+ "android.hardware.common.fmq-V1-ndk",
+ "android.hardware.common-V2-ndk",
],
test_suites: [
"general-tests",
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 96995a0..11d44b8 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -24,12 +24,22 @@
#include <android/binder_process.h>
#include <android/binder_status.h>
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
+
#include <unistd.h>
+#include <cstdint>
+#include "aidl/android/hardware/common/fmq/SynchronizedReadWrite.h"
+#include "fmq/EventFlag.h"
namespace aidl::android::hardware::power {
namespace {
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
using android::hardware::power::Boost;
+using android::hardware::power::ChannelConfig;
+using android::hardware::power::ChannelMessage;
using android::hardware::power::IPower;
using android::hardware::power::IPowerHintSession;
using android::hardware::power::Mode;
@@ -37,6 +47,8 @@
using android::hardware::power::SessionMode;
using android::hardware::power::WorkDuration;
+using SessionMessageQueue = AidlMessageQueue<ChannelMessage, SynchronizedReadWrite>;
+
const std::vector<Boost> kBoosts{ndk::enum_range<Boost>().begin(), ndk::enum_range<Boost>().end()};
const std::vector<Mode> kModes{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
@@ -190,6 +202,31 @@
ASSERT_GE(rate, 1000000);
}
+TEST_P(PowerAidl, createHintSessionWithConfig) {
+ if (mServiceVersion < 5) {
+ GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+ }
+ std::shared_ptr<IPowerHintSession> session;
+ SessionConfig config;
+
+ auto status = power->createHintSessionWithConfig(getpid(), getuid(), kSelfTids, 16666666L,
+ SessionTag::OTHER, &config, &session);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_NE(nullptr, session);
+}
+
+TEST_P(PowerAidl, getAndCloseSessionChannel) {
+ if (mServiceVersion < 5) {
+ GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+ }
+ ChannelConfig config;
+ auto status = power->getSessionChannel(getpid(), getuid(), &config);
+ ASSERT_TRUE(status.isOk());
+ auto messageQueue = std::make_shared<SessionMessageQueue>(config.channelDescriptor, true);
+ ASSERT_TRUE(messageQueue->isValid());
+ ASSERT_TRUE(power->closeSessionChannel(getpid(), getuid()).isOk());
+}
+
TEST_P(HintSessionAidl, createAndCloseHintSession) {
ASSERT_TRUE(mSession->pause().isOk());
ASSERT_TRUE(mSession->resume().isOk());
@@ -252,6 +289,14 @@
}
}
+TEST_P(HintSessionAidl, getSessionConfig) {
+ if (mServiceVersion < 5) {
+ GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+ }
+ SessionConfig config;
+ ASSERT_TRUE(mSession->getSessionConfig(&config).isOk());
+}
+
// FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
// or later
TEST_P(PowerAidl, hasFixedPerformance) {
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
index 6dbf09d..9846006 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
@@ -39,5 +39,5 @@
TRIGGER_PLMN_BLOCK,
TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
TRIGGER_RAT_BLOCK,
- TRIGGER_CLEAR_RAT_BLOCK,
+ TRIGGER_CLEAR_RAT_BLOCKS,
}
diff --git a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
index f0e28fc..73c57fa 100644
--- a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
+++ b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
@@ -37,9 +37,10 @@
TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
/**
* Indicates that the IMS registration on current RAT failed multiple times.
- * The radio shall block the current RAT and search for other available RATs in the
- * background. If no other RAT is available that meets the carrier requirements, the
- * radio may remain on the current RAT for internet service. The radio clears all
+ * The radio shall block the {@link AccessNetwork} included with this and
+ * search for other available RATs in the background.
+ * If no other RAT is available that meets the carrier requirements, the
+ * radio may remain on the blocked RAT for internet service. The radio clears all
* RATs marked as unavailable if {@link IRadioIms#updateImsRegistrationInfo()} API
* with REGISTERED state is invoked.
*/
@@ -48,5 +49,5 @@
* Indicates that the radio clears all RATs marked as unavailable and tries to find
* an available RAT that meets the carrier requirements.
*/
- TRIGGER_CLEAR_RAT_BLOCK,
+ TRIGGER_CLEAR_RAT_BLOCKS,
}
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index e2df8dd..5f26195 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -649,8 +649,8 @@
/**
* Get whether pre-auth cellular identifier in-the-clear transparency is enabled. If
* IRadioNetworkInterface.setCellularIdentifierTransparencyEnabled has been called, this should
- * return the value of the `enabled` parameter of the last successful call. If it hasn't been
- * called this should return the default value of true.
+ * return the value of the `enabled` parameter of the last successful call and false if
+ * IRadioNetworkInterface.setCellularIdentifierTransparencyEnabled has not been called yet.
*
* @param serial Serial number of request
*
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index 023fc8f..8ce37cd 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -36,4 +36,9 @@
interface ISecretkeeper {
android.hardware.security.authgraph.IAuthGraphKeyExchange getAuthGraphKe();
byte[] processSecretManagementRequest(in byte[] request);
+ void deleteIds(in android.hardware.security.secretkeeper.SecretId[] ids);
+ void deleteAll();
+ const int ERROR_UNKNOWN_KEY_ID = 1;
+ const int ERROR_INTERNAL_ERROR = 2;
+ const int ERROR_REQUEST_MALFORMED = 3;
}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl
similarity index 92%
rename from security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
rename to security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl
index cc07f9b..87d0233 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl
@@ -33,10 +33,7 @@
package android.hardware.security.secretkeeper;
/* @hide */
-@Backing(type="int") @VintfStability
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
+@VintfStability
+parcelable SecretId {
+ byte[] id;
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index cb3e9b9..49c3446 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -17,6 +17,7 @@
package android.hardware.security.secretkeeper;
import android.hardware.security.authgraph.IAuthGraphKeyExchange;
+import android.hardware.security.secretkeeper.SecretId;
@VintfStability
/**
@@ -30,14 +31,12 @@
* - A trusted execution environment such as ARM TrustZone.
* - A completely separate, purpose-built and certified secure CPU.
*
- * TODO(b/291224769): Extend the HAL interface to include:
- * 1. Dice policy operation - These allow sealing of the secrets with a class of Dice chains.
- * Typical operations are (securely) updating the dice policy sealing the Secrets above. These
- * operations are core to AntiRollback protected secrets - ie, ensuring secrets of a pVM are only
- * accessible to same or higher versions of the images.
- * 2. Maintenance API: This is required for removing the Secretkeeper entries for obsolete pVMs.
*/
interface ISecretkeeper {
+ const int ERROR_UNKNOWN_KEY_ID = 1;
+ const int ERROR_INTERNAL_ERROR = 2;
+ const int ERROR_REQUEST_MALFORMED = 3;
+
/**
* Retrieve the instance of the `IAuthGraphKeyExchange` HAL that should be used for shared
* session key establishment. These keys are used to perform encryption of messages as
@@ -60,8 +59,8 @@
* Virtual Machines). For this, service (& client) must implement a key exchange protocol, which
* is critical for establishing the secure channel.
*
- * If an encrypted response cannot be generated, then a service-specific Binder error using an
- * error code from ErrorCode.aidl will be returned.
+ * If an encrypted response cannot be generated, then a service-specific Binder error using one
+ * of the ERROR_ codes above will be returned.
*
* Secretkeeper database should guarantee the following properties:
*
@@ -82,4 +81,19 @@
* @return CBOR-encoded ProtectedResponsePacket. See SecretManagement.cddl for its definition
*/
byte[] processSecretManagementRequest(in byte[] request);
+
+ /**
+ * Delete the data corresponding to a collection of IDs.
+ *
+ * Note that unlike `processSecretManagementRequest`, the contents of this method are in
+ * plaintext, and no client authentication is required.
+ *
+ * @param Secret identifiers to delete.
+ */
+ void deleteIds(in SecretId[] ids);
+
+ /**
+ * Delete data of all clients.
+ */
+ void deleteAll();
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
similarity index 69%
rename from security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl
rename to security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
index e9cce09..bd982e7 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
@@ -17,17 +17,13 @@
package android.hardware.security.secretkeeper;
/**
- * Secretkeeper unencrypted error code, returned via AIDL as service specific errors in
- * EX_SERVICE_SPECIFIC.
+ * SecretId contains an identifier for a secret held by Secretkeeper.
* @hide
*/
@VintfStability
-@Backing(type="int")
-enum ErrorCode {
- OK = 0,
- UNKNOWN_KEY_ID = 1,
- INTERNAL_ERROR = 2,
- REQUEST_MALFORMED = 3,
-
- // TODO(b/291224769): Create a more exhaustive set of error code values.
+parcelable SecretId {
+ /**
+ * 64-byte identifier for a secret.
+ */
+ byte[] id;
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
index 66ca8ed..3d08078 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
@@ -9,8 +9,8 @@
CryptoPayload<Payload, Key> = [ ; COSE_Encrypt0 (untagged), [RFC 9052 s5.2]
protected: bstr .cbor {
1 : 3, ; Algorithm: AES-GCM mode w/ 256-bit key, 128-bit tag
- 4 : bstr ; key identifier, uniquely identifies the session
- ; TODO(b/291228560): Refer to the Key Exchange spec.
+ 4 : bstr ; key identifier set to session ID produced
+ ; by AuthGraph key exchange.
},
unprotected: {
5 : bstr .size 12 ; IV
@@ -32,8 +32,11 @@
StoreSecretOpcode = 2 ; Store a secret
GetSecretOpcode = 3 ; Get the secret
+; Retrieve Secretkeeper version.
GetVersionParams = ()
+; Store a secret identified by the given ID, with access to the secret policed
+; by the associated sealing policy.
StoreSecretParams = (
id : SecretId,
secret : Secret,
@@ -42,6 +45,9 @@
; INCLUDE DicePolicy.cddl for: DicePolicy
+; Retrieve a secret identified by the given ID, policed according to the sealing
+; policy that was associated with the secret. If successful, optionally also
+; update the sealing policy for the secret.
GetSecretParams = (
id : SecretId,
; Retrieving the value of a secret may optionally also update the sealing
@@ -68,7 +74,6 @@
; An error code in the inner response message indicates a failure in
; secret management processing.
-; TODO(b/291224769): Create a more exhaustive set of ErrorCodes
ErrorCode = &(
; Use this as if no other error code can be used.
ErrorCode_UnexpectedServerError: 1,
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index c130a3a..7fc7a70 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -25,6 +25,7 @@
"general-tests",
"vts",
],
+ test_config: "AndroidTest.xml",
rustlibs: [
"libsecretkeeper_comm_nostd",
"libsecretkeeper_core_nostd",
@@ -36,6 +37,7 @@
"libbinder_rs",
"libcoset",
"liblog_rust",
+ "liblogger",
],
require_root: true,
}
diff --git a/security/secretkeeper/aidl/vts/AndroidTest.xml b/security/secretkeeper/aidl/vts/AndroidTest.xml
new file mode 100644
index 0000000..4fee78f
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+<configuration description="Config for Secretkeeper VTS tests.">
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file" key="VtsSecretkeeperTargetTest" value="/data/local/tmp/VtsSecretkeeperTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+ <option name="test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsSecretkeeperTargetTest" />
+ <!-- Rust tests are run in parallel by default. Run these ones
+ single-threaded, so that one test's secrets don't affect
+ the behaviour of a different test. -->
+ <option name="native-test-flag" value="--test-threads=1" />
+ </test>
+</configuration>
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index a473bd0..6a70d02 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -14,26 +14,28 @@
* limitations under the License.
*/
-#[cfg(test)]
+#![cfg(test)]
+
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::SecretId::SecretId;
+use authgraph_vts_test as ag_vts;
+use authgraph_boringssl as boring;
+use authgraph_core::key;
use binder::StatusCode;
use coset::{CborSerializable, CoseEncrypt0};
-use log::warn;
+use log::{info, warn};
use secretkeeper_core::cipher;
use secretkeeper_comm::data_types::error::SecretkeeperError;
use secretkeeper_comm::data_types::request::Request;
use secretkeeper_comm::data_types::request_response_impl::{
GetVersionRequest, GetVersionResponse, GetSecretRequest, GetSecretResponse, StoreSecretRequest,
StoreSecretResponse };
-use secretkeeper_comm::data_types::{Id, ID_SIZE, Secret, SECRET_SIZE};
+use secretkeeper_comm::data_types::{Id, Secret};
use secretkeeper_comm::data_types::response::Response;
use secretkeeper_comm::data_types::packet::{ResponsePacket, ResponseType};
-use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
-use authgraph_vts_test as ag_vts;
-use authgraph_boringssl as boring;
-use authgraph_core::key;
-const SECRETKEEPER_IDENTIFIER: &str =
- "android.hardware.security.secretkeeper.ISecretkeeper/nonsecure";
+const SECRETKEEPER_SERVICE: &str = "android.hardware.security.secretkeeper.ISecretkeeper";
+const SECRETKEEPER_INSTANCES: [&'static str; 2] = ["nonsecure", "default"];
const CURRENT_VERSION: u64 = 1;
// TODO(b/291238565): This will change once libdice_policy switches to Explicit-key DiceCertChain
@@ -46,32 +48,62 @@
];
// Random bytes (of ID_SIZE/SECRET_SIZE) generated for tests.
-const ID_EXAMPLE: [u8; ID_SIZE] = [
+const ID_EXAMPLE: Id = Id([
0xF1, 0xB2, 0xED, 0x3B, 0xD1, 0xBD, 0xF0, 0x7D, 0xE1, 0xF0, 0x01, 0xFC, 0x61, 0x71, 0xD3, 0x42,
0xE5, 0x8A, 0xAF, 0x33, 0x6C, 0x11, 0xDC, 0xC8, 0x6F, 0xAE, 0x12, 0x5C, 0x26, 0x44, 0x6B, 0x86,
0xCC, 0x24, 0xFD, 0xBF, 0x91, 0x4A, 0x54, 0x84, 0xF9, 0x01, 0x59, 0x25, 0x70, 0x89, 0x38, 0x8D,
0x5E, 0xE6, 0x91, 0xDF, 0x68, 0x60, 0x69, 0x26, 0xBE, 0xFE, 0x79, 0x58, 0xF7, 0xEA, 0x81, 0x7D,
-];
-const ID_NOT_STORED: [u8; ID_SIZE] = [
+]);
+const ID_EXAMPLE_2: Id = Id([
+ 0x6A, 0xCC, 0xB1, 0xEB, 0xBB, 0xAB, 0xE3, 0xEA, 0x44, 0xBD, 0xDC, 0x75, 0x75, 0x7D, 0xC0, 0xE5,
+ 0xC7, 0x86, 0x41, 0x56, 0x39, 0x66, 0x96, 0x10, 0xCB, 0x43, 0x10, 0x79, 0x03, 0xDC, 0xE6, 0x9F,
+ 0x12, 0x2B, 0xEF, 0x28, 0x9C, 0x1E, 0x32, 0x46, 0x5F, 0xA3, 0xE7, 0x8D, 0x53, 0x63, 0xE8, 0x30,
+ 0x5A, 0x17, 0x6F, 0xEF, 0x42, 0xD6, 0x58, 0x7A, 0xF0, 0xCB, 0xD4, 0x40, 0x58, 0x96, 0x32, 0xF4,
+]);
+const ID_NOT_STORED: Id = Id([
0x56, 0xD0, 0x4E, 0xAA, 0xC1, 0x7B, 0x55, 0x6B, 0xA0, 0x2C, 0x65, 0x43, 0x39, 0x0A, 0x6C, 0xE9,
0x1F, 0xD0, 0x0E, 0x20, 0x3E, 0xFB, 0xF5, 0xF9, 0x3F, 0x5B, 0x11, 0x1B, 0x18, 0x73, 0xF6, 0xBB,
0xAB, 0x9F, 0xF2, 0xD6, 0xBD, 0xBA, 0x25, 0x68, 0x22, 0x30, 0xF2, 0x1F, 0x90, 0x05, 0xF3, 0x64,
0xE7, 0xEF, 0xC6, 0xB6, 0xA0, 0x85, 0xC9, 0x40, 0x40, 0xF0, 0xB4, 0xB9, 0xD8, 0x28, 0xEE, 0x9C,
-];
-const SECRET_EXAMPLE: [u8; SECRET_SIZE] = [
+]);
+const SECRET_EXAMPLE: Secret = Secret([
0xA9, 0x89, 0x97, 0xFE, 0xAE, 0x97, 0x55, 0x4B, 0x32, 0x35, 0xF0, 0xE8, 0x93, 0xDA, 0xEA, 0x24,
0x06, 0xAC, 0x36, 0x8B, 0x3C, 0x95, 0x50, 0x16, 0x67, 0x71, 0x65, 0x26, 0xEB, 0xD0, 0xC3, 0x98,
-];
+]);
-fn get_connection() -> Option<binder::Strong<dyn ISecretkeeper>> {
- match binder::get_interface(SECRETKEEPER_IDENTIFIER) {
- Ok(sk) => Some(sk),
- Err(StatusCode::NAME_NOT_FOUND) => None,
- Err(e) => {
- panic!(
- "unexpected error while fetching connection to Secretkeeper {:?}",
- e
- );
+fn get_connection() -> Option<(binder::Strong<dyn ISecretkeeper>, String)> {
+ // Initialize logging (which is OK to call multiple times).
+ logger::init(logger::Config::default().with_min_level(log::Level::Debug));
+
+ // TODO: replace this with a parameterized set of tests that run for each available instance of
+ // ISecretkeeper (rather than having a fixed set of instance names to look for).
+ for instance in &SECRETKEEPER_INSTANCES {
+ let name = format!("{SECRETKEEPER_SERVICE}/{instance}");
+ match binder::get_interface(&name) {
+ Ok(sk) => {
+ info!("Running test against /{instance}");
+ return Some((sk, name));
+ }
+ Err(StatusCode::NAME_NOT_FOUND) => {
+ info!("No /{instance} instance of ISecretkeeper present");
+ }
+ Err(e) => {
+ panic!("unexpected error while fetching connection to Secretkeeper {:?}", e);
+ }
+ }
+ }
+ None
+}
+
+/// Macro to perform test setup. Invokes `return` if no Secretkeeper instance available.
+macro_rules! setup_client {
+ {} => {
+ match SkClient::new() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
}
}
}
@@ -79,42 +111,86 @@
/// Secretkeeper client information.
struct SkClient {
sk: binder::Strong<dyn ISecretkeeper>,
+ name: String,
aes_keys: [key::AesKey; 2],
session_id: Vec<u8>,
}
+impl Drop for SkClient {
+ fn drop(&mut self) {
+ // Delete any IDs that may be left over.
+ self.delete(&[&ID_EXAMPLE, &ID_EXAMPLE_2]);
+ }
+}
+
impl SkClient {
fn new() -> Option<Self> {
- let sk = get_connection()?;
+ let (sk, name) = get_connection()?;
let (aes_keys, session_id) = authgraph_key_exchange(sk.clone());
- Some(Self {
- sk,
- aes_keys,
- session_id,
- })
+ Some(Self { sk, name, aes_keys, session_id })
}
+
/// Wrapper around `ISecretkeeper::processSecretManagementRequest` that handles
/// encryption and decryption.
fn secret_management_request(&self, req_data: &[u8]) -> Vec<u8> {
let aes_gcm = boring::BoringAes;
let rng = boring::BoringRng;
- let request_bytes = cipher::encrypt_message(
- &aes_gcm,
- &rng,
- &self.aes_keys[0],
- &self.session_id,
- &req_data,
- )
- .unwrap();
+ let request_bytes =
+ cipher::encrypt_message(&aes_gcm, &rng, &self.aes_keys[0], &self.session_id, &req_data)
+ .unwrap();
- let response_bytes = self
- .sk
- .processSecretManagementRequest(&request_bytes)
- .unwrap();
+ let response_bytes = self.sk.processSecretManagementRequest(&request_bytes).unwrap();
let response_encrypt0 = CoseEncrypt0::from_slice(&response_bytes).unwrap();
cipher::decrypt_message(&aes_gcm, &self.aes_keys[1], &response_encrypt0).unwrap()
}
+
+ /// Helper method to store a secret.
+ fn store(&self, id: &Id, secret: &Secret) {
+ let store_request = StoreSecretRequest {
+ id: id.clone(),
+ secret: secret.clone(),
+ sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
+ };
+ let store_request = store_request.serialize_to_packet().to_vec().unwrap();
+
+ let store_response = self.secret_management_request(&store_request);
+ let store_response = ResponsePacket::from_slice(&store_response).unwrap();
+
+ assert_eq!(store_response.response_type().unwrap(), ResponseType::Success);
+ // Really just checking that the response is indeed StoreSecretResponse
+ let _ = StoreSecretResponse::deserialize_from_packet(store_response).unwrap();
+ }
+
+ /// Helper method to get a secret.
+ fn get(&self, id: &Id) -> Option<Secret> {
+ let get_request = GetSecretRequest { id: id.clone(), updated_sealing_policy: None };
+ let get_request = get_request.serialize_to_packet().to_vec().unwrap();
+
+ let get_response = self.secret_management_request(&get_request);
+ let get_response = ResponsePacket::from_slice(&get_response).unwrap();
+
+ if get_response.response_type().unwrap() == ResponseType::Success {
+ let get_response = *GetSecretResponse::deserialize_from_packet(get_response).unwrap();
+ Some(Secret(get_response.secret.0))
+ } else {
+ // Only expect a not-found failure.
+ let err = *SecretkeeperError::deserialize_from_packet(get_response).unwrap();
+ assert_eq!(err, SecretkeeperError::EntryNotFound);
+ None
+ }
+ }
+
+ /// Helper method to delete secrets.
+ fn delete(&self, ids: &[&Id]) {
+ let ids: Vec<SecretId> = ids.iter().map(|id| SecretId { id: id.0.to_vec() }).collect();
+ self.sk.deleteIds(&ids).unwrap();
+ }
+
+ /// Helper method to delete everything.
+ fn delete_all(&self) {
+ self.sk.deleteAll().unwrap();
+ }
}
/// Perform AuthGraph key exchange, returning the session keys and session ID.
@@ -128,7 +204,7 @@
/// mainline key exchange against a local source implementation.
#[test]
fn authgraph_mainline() {
- let sk = match get_connection() {
+ let (sk, _) = match get_connection() {
Some(sk) => sk,
None => {
warn!("Secretkeeper HAL is unavailable, skipping test");
@@ -142,7 +218,7 @@
/// a corrupted session ID signature.
#[test]
fn authgraph_corrupt_sig() {
- let sk = match get_connection() {
+ let (sk, _) = match get_connection() {
Some(sk) => sk,
None => {
warn!("Secretkeeper HAL is unavailable, skipping test");
@@ -158,7 +234,7 @@
/// when corrupted keys are returned to it.
#[test]
fn authgraph_corrupt_keys() {
- let sk = match get_connection() {
+ let (sk, _) = match get_connection() {
Some(sk) => sk,
None => {
warn!("Secretkeeper HAL is unavailable, skipping test");
@@ -175,13 +251,7 @@
#[test]
fn secret_management_get_version() {
- let sk_client = match SkClient::new() {
- Some(sk) => sk,
- None => {
- warn!("Secretkeeper HAL is unavailable, skipping test");
- return;
- }
- };
+ let sk_client = setup_client!();
let request = GetVersionRequest {};
let request_packet = request.serialize_to_packet();
@@ -190,10 +260,7 @@
let response_bytes = sk_client.secret_management_request(&request_bytes);
let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
- assert_eq!(
- response_packet.response_type().unwrap(),
- ResponseType::Success
- );
+ assert_eq!(response_packet.response_type().unwrap(), ResponseType::Success);
let get_version_response =
*GetVersionResponse::deserialize_from_packet(response_packet).unwrap();
assert_eq!(get_version_response.version, CURRENT_VERSION);
@@ -201,13 +268,7 @@
#[test]
fn secret_management_malformed_request() {
- let sk_client = match SkClient::new() {
- Some(sk) => sk,
- None => {
- warn!("Secretkeeper HAL is unavailable, skipping test");
- return;
- }
- };
+ let sk_client = setup_client!();
let request = GetVersionRequest {};
let request_packet = request.serialize_to_packet();
@@ -219,93 +280,112 @@
let response_bytes = sk_client.secret_management_request(&request_bytes);
let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
- assert_eq!(
- response_packet.response_type().unwrap(),
- ResponseType::Error
- );
+ assert_eq!(response_packet.response_type().unwrap(), ResponseType::Error);
let err = *SecretkeeperError::deserialize_from_packet(response_packet).unwrap();
assert_eq!(err, SecretkeeperError::RequestMalformed);
}
#[test]
fn secret_management_store_get_secret_found() {
- let sk_client = match SkClient::new() {
- Some(sk) => sk,
- None => {
- warn!("Secretkeeper HAL is unavailable, skipping test");
- return;
- }
- };
+ let sk_client = setup_client!();
- let store_request = StoreSecretRequest {
- id: Id(ID_EXAMPLE),
- secret: Secret(SECRET_EXAMPLE),
- sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
- };
-
- let store_request = store_request.serialize_to_packet().to_vec().unwrap();
-
- let store_response = sk_client.secret_management_request(&store_request);
- let store_response = ResponsePacket::from_slice(&store_response).unwrap();
-
- assert_eq!(
- store_response.response_type().unwrap(),
- ResponseType::Success
- );
- // Really just checking that the response is indeed StoreSecretResponse
- let _ = StoreSecretResponse::deserialize_from_packet(store_response).unwrap();
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
// Get the secret that was just stored
- let get_request = GetSecretRequest {
- id: Id(ID_EXAMPLE),
- updated_sealing_policy: None,
- };
- let get_request = get_request.serialize_to_packet().to_vec().unwrap();
-
- let get_response = sk_client.secret_management_request(&get_request);
- let get_response = ResponsePacket::from_slice(&get_response).unwrap();
- assert_eq!(get_response.response_type().unwrap(), ResponseType::Success);
- let get_response = *GetSecretResponse::deserialize_from_packet(get_response).unwrap();
- assert_eq!(get_response.secret.0, SECRET_EXAMPLE);
+ assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
}
#[test]
fn secret_management_store_get_secret_not_found() {
- let sk_client = match SkClient::new() {
- Some(sk) => sk,
- None => {
- warn!("Secretkeeper HAL is unavailable, skipping test");
- return;
- }
- };
+ let sk_client = setup_client!();
// Store a secret (corresponding to an id).
- let store_request = StoreSecretRequest {
- id: Id(ID_EXAMPLE),
- secret: Secret(SECRET_EXAMPLE),
- sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
- };
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
- let store_request = store_request.serialize_to_packet().to_vec().unwrap();
- let store_response = sk_client.secret_management_request(&store_request);
- let store_response = ResponsePacket::from_slice(&store_response).unwrap();
+ // Get the secret that was never stored
+ assert_eq!(sk_client.get(&ID_NOT_STORED), None);
+}
- assert_eq!(
- store_response.response_type().unwrap(),
- ResponseType::Success
- );
+#[test]
+fn secretkeeper_store_delete_ids() {
+ let sk_client = setup_client!();
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+ sk_client.delete(&[&ID_EXAMPLE]);
+
+ assert_eq!(sk_client.get(&ID_EXAMPLE), None);
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
+
+ sk_client.delete(&[&ID_EXAMPLE_2]);
+
+ assert_eq!(sk_client.get(&ID_EXAMPLE), None);
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
+}
+
+#[test]
+fn secretkeeper_store_delete_multiple_ids() {
+ let sk_client = setup_client!();
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+ sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE_2]);
+
+ assert_eq!(sk_client.get(&ID_EXAMPLE), None);
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
+}
+
+#[test]
+fn secretkeeper_store_delete_duplicate_ids() {
+ let sk_client = setup_client!();
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+ // Delete the same secret twice.
+ sk_client.delete(&[&ID_EXAMPLE, &ID_EXAMPLE]);
+
+ assert_eq!(sk_client.get(&ID_EXAMPLE), None);
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
+}
+
+#[test]
+fn secretkeeper_store_delete_nonexistent() {
+ let sk_client = setup_client!();
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+ sk_client.delete(&[&ID_NOT_STORED]);
+
+ assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2), Some(SECRET_EXAMPLE));
+ assert_eq!(sk_client.get(&ID_NOT_STORED), None);
+}
+
+#[test]
+fn secretkeeper_store_delete_all() {
+ let sk_client = setup_client!();
+
+ if sk_client.name != "nonsecure" {
+ // Don't run deleteAll() on a secure device, as it might affect
+ // real secrets.
+ warn!("skipping deleteAll test due to real impl");
+ return;
+ }
+
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+ sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
+
+ sk_client.delete_all();
+
+ assert_eq!(sk_client.get(&ID_EXAMPLE), None);
+ assert_eq!(sk_client.get(&ID_EXAMPLE_2), None);
+
+ // Store a new secret (corresponding to an id).
+ sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
+
+ // Get the restored secret.
+ assert_eq!(sk_client.get(&ID_EXAMPLE), Some(SECRET_EXAMPLE));
// (Try to) Get the secret that was never stored
- let get_request = GetSecretRequest {
- id: Id(ID_NOT_STORED),
- updated_sealing_policy: None,
- };
- let get_request = get_request.serialize_to_packet().to_vec().unwrap();
- let get_response = sk_client.secret_management_request(&get_request);
-
- // Check that response is `SecretkeeperError::EntryNotFound`
- let get_response = ResponsePacket::from_slice(&get_response).unwrap();
- assert_eq!(get_response.response_type().unwrap(), ResponseType::Error);
- let err = *SecretkeeperError::deserialize_from_packet(get_response).unwrap();
- assert_eq!(err, SecretkeeperError::EntryNotFound);
+ assert_eq!(sk_client.get(&ID_NOT_STORED), None);
}
diff --git a/security/secretkeeper/default/src/store.rs b/security/secretkeeper/default/src/store.rs
index 7b2d0b9..a7fb3b7 100644
--- a/security/secretkeeper/default/src/store.rs
+++ b/security/secretkeeper/default/src/store.rs
@@ -33,4 +33,14 @@
let optional_val = self.0.get(key);
Ok(optional_val.cloned())
}
+
+ fn delete(&mut self, key: &[u8]) -> Result<(), Error> {
+ self.0.remove(key);
+ Ok(())
+ }
+
+ fn delete_all(&mut self) -> Result<(), Error> {
+ self.0.clear();
+ Ok(())
+ }
}
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 08ee773..e93c391 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -97,12 +97,5 @@
prebuilts: [
"sensors-default.rc", // init rc
"sensors-default.xml", // vintf fragment
- "android.hardware.sensor.ambient_temperature.prebuilt.xml",
- "android.hardware.sensor.barometer.prebuilt.xml",
- "android.hardware.sensor.gyroscope.prebuilt.xml",
- "android.hardware.sensor.hinge_angle.prebuilt.xml",
- "android.hardware.sensor.light.prebuilt.xml",
- "android.hardware.sensor.proximity.prebuilt.xml",
- "android.hardware.sensor.relative_humidity.prebuilt.xml",
],
}
diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
index 746ae1e..7e095f1 100644
--- a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
+++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "tv_input_aidl_hal_test"
+
#include "VtsHalTvInputTargetTest.h"
#include <android-base/properties.h>
@@ -181,7 +183,9 @@
ALOGD("OpenAndCloseStreamTest: open stream, device_id=%d, stream_id=%d", device_id,
stream_id);
ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).isOk());
- ASSERT_TRUE(isValidHandle(handle));
+ if (VERIFY_SIDEBAND_STREAM_HANDLE) {
+ ASSERT_TRUE(isValidHandle(handle));
+ }
ALOGD("OpenAndCloseStreamTest: close stream, device_id=%d, stream_id=%d", device_id,
stream_id);
@@ -283,7 +287,9 @@
ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id);
ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).isOk());
- ASSERT_TRUE(isValidHandle(handle));
+ if (VERIFY_SIDEBAND_STREAM_HANDLE) {
+ ASSERT_TRUE(isValidHandle(handle));
+ }
ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id);
ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).getServiceSpecificError() ==
diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
index 7e66a88..fd98a18 100644
--- a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
+++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
@@ -43,6 +43,7 @@
#define WAIT_FOR_EVENT_TIMEOUT 5
#define DEFAULT_ID INT32_MIN
+#define VERIFY_SIDEBAND_STREAM_HANDLE 1
namespace VtsHalTvInputTargetTest {
diff --git a/uwb/aidl/default/Android.bp b/uwb/aidl/default/Android.bp
index f9b79de..8af1678 100644
--- a/uwb/aidl/default/Android.bp
+++ b/uwb/aidl/default/Android.bp
@@ -24,6 +24,8 @@
"libtokio_util",
"libnix",
"libanyhow",
+ "libpdl_runtime",
+ "libuwb_uci_packets",
],
proc_macros: [
"libasync_trait",
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index efb2454..d749147 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -16,6 +16,9 @@
use std::io::{self, Read, Write};
use std::os::unix::fs::OpenOptionsExt;
+use pdl_runtime::Packet;
+use uwb_uci_packets::{DeviceResetCmdBuilder, ResetConfig, UciControlPacket, UciControlPacketHal};
+
enum State {
Closed,
Opened {
@@ -46,11 +49,23 @@
impl State {
/// Terminate the reader task.
async fn close(&mut self) -> Result<()> {
- if let State::Opened { ref mut token, ref callbacks, ref mut death_recipient, ref mut handle, .. } = *self {
+ if let State::Opened {
+ ref mut token,
+ ref callbacks,
+ ref mut death_recipient,
+ ref mut handle,
+ ref mut serial,
+ } = *self
+ {
log::info!("waiting for task cancellation");
callbacks.as_binder().unlink_to_death(death_recipient)?;
token.cancel();
handle.await.unwrap();
+ consume_device_reset_rsp_and_ntf(
+ &mut serial
+ .try_clone()
+ .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?,
+ );
log::info!("task successfully cancelled");
callbacks.onHalEvent(UwbEvent::CLOSE_CPLT, UwbStatus::OK)?;
*self = State::Closed;
@@ -59,6 +74,20 @@
}
}
+fn consume_device_reset_rsp_and_ntf(reader: &mut File) {
+ // Poll the DeviceResetRsp and DeviceStatusNtf before hal is closed to prevent
+ // the host from getting response and notifications from a 'powered down' UWBS.
+ // Do nothing when these packets are received.
+ const DEVICE_RESET_RSP: [u8; 5] = [64, 0, 0, 1, 0];
+ const DEVICE_STATUS_NTF: [u8; 5] = [96, 1, 0, 1, 1];
+ let mut buffer = vec![0; DEVICE_RESET_RSP.len() + DEVICE_STATUS_NTF.len()];
+ read_exact(reader, &mut buffer).unwrap();
+
+ // Make sure received packets are the expected ones.
+ assert_eq!(&buffer[0..DEVICE_RESET_RSP.len()], &DEVICE_RESET_RSP);
+ assert_eq!(&buffer[DEVICE_RESET_RSP.len()..], &DEVICE_STATUS_NTF);
+}
+
pub fn makeraw(file: File) -> io::Result<File> {
// Configure the file descriptor as raw fd.
use nix::sys::termios::*;
@@ -209,7 +238,21 @@
let mut state = self.state.lock().await;
- if matches!(*state, State::Opened { .. }) {
+ if let State::Opened { ref mut serial, .. } = *state {
+ let packet: UciControlPacket = DeviceResetCmdBuilder {
+ reset_config: ResetConfig::UwbsReset,
+ }
+ .build()
+ .into();
+ // DeviceResetCmd need to be send to reset the device to stop all running
+ // activities on UWBS.
+ let packet_vec: Vec<UciControlPacketHal> = packet.into();
+ for hal_packet in packet_vec.into_iter() {
+ serial
+ .write(&hal_packet.to_vec())
+ .map(|written| written as i32)
+ .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
+ }
state.close().await
} else {
Err(binder::ExceptionCode::ILLEGAL_STATE.into())
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
index 56ef2d2..83f3f7e 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
@@ -46,5 +46,4 @@
android.hardware.wifi.RttBw azBwSupport;
boolean ntbInitiatorSupported;
boolean ntbResponderSupported;
- int maxTxLtfRepetitionCount;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
index b7830bd..b53ff9b 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
@@ -48,7 +48,6 @@
int burstDuration;
android.hardware.wifi.RttPreamble preamble;
android.hardware.wifi.RttBw bw;
- int ntbMinMeasurementTimeMillis;
- int ntbMaxMeasurementTimeMillis;
- int txLtfRepetitionCount;
+ long ntbMinMeasurementTime;
+ long ntbMaxMeasurementTime;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
index 30f5f58..9c6ad26 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
@@ -59,7 +59,8 @@
android.hardware.wifi.WifiInformationElement lcr;
int channelFreqMHz;
android.hardware.wifi.RttBw packetBw;
- int txLtfRepetitionCount;
- int ntbMinMeasurementTimeMillis;
- int ntbMaxMeasurementTimeMillis;
+ byte i2rTxLtfRepetitionCount;
+ byte r2iTxLtfRepetitionCount;
+ long ntbMinMeasurementTime;
+ long ntbMaxMeasurementTime;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
index d8e73fb..d6ed62e 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
@@ -40,6 +40,6 @@
boolean isFlexibleTwtScheduleSupported;
int minWakeDurationMicros;
int maxWakeDurationMicros;
- int minWakeIntervalMicros;
- int maxWakeIntervalMicros;
+ long minWakeIntervalMicros;
+ long maxWakeIntervalMicros;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
index 3051b94..06c7ae2 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
@@ -37,6 +37,6 @@
int mloLinkId;
int minWakeDurationMicros;
int maxWakeDurationMicros;
- int minWakeIntervalMicros;
- int maxWakeIntervalMicros;
+ long minWakeIntervalMicros;
+ long maxWakeIntervalMicros;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
index 92c2533..4e5ca44 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
@@ -37,7 +37,7 @@
int sessionId;
int mloLinkId;
int wakeDurationMicros;
- int wakeIntervalMicros;
+ long wakeIntervalMicros;
android.hardware.wifi.TwtSession.TwtNegotiationType negotiationType;
boolean isTriggerEnabled;
boolean isAnnounced;
diff --git a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
index 0352ec8..c4b7d24 100644
--- a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
@@ -78,9 +78,4 @@
* Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported.
*/
boolean ntbResponderSupported;
- /**
- * Maximum HE LTF repetitions the IEEE 802.11az initiator is capable of transmitting in the
- * preamble of I2R NDP.
- */
- int maxTxLtfRepetitionCount;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
index e970656..7b18708 100644
--- a/wifi/aidl/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
@@ -121,16 +121,17 @@
*/
RttBw bw;
/**
- * IEEE 802.11az Non-Trigger-based (non-TB) minimum measurement time in milliseconds.
+ * IEEE 802.11az Non-Trigger-based (non-TB) minimum measurement time in units of 100
+ * microseconds.
+ *
+ * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
*/
- int ntbMinMeasurementTimeMillis;
+ long ntbMinMeasurementTime;
/**
- * IEEE 802.11az Non-Trigger-based (non-TB) maximum measurement time in milliseconds.
+ * IEEE 802.11az Non-Trigger-based (non-TB) maximum measurement time in units of 10
+ * milliseconds.
+ *
+ * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
*/
- int ntbMaxMeasurementTimeMillis;
- /**
- * Multiple transmissions of HE-LTF symbols in an HE Ranging NDP. A value of 1 indicates no
- * repetition.
- */
- int txLtfRepetitionCount;
+ long ntbMaxMeasurementTime;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
index 2cb0afa..ab9abb5 100644
--- a/wifi/aidl/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -146,12 +146,18 @@
*/
RttBw packetBw;
/**
- * IEEE 802.11az Transmit LTF repetitions used to get this result.
+ * Multiple transmissions of HE-LTF symbols in an HE (I2R) Ranging NDP. An HE-LTF repetition
+ * value of 1 indicates no repetitions.
*/
- int txLtfRepetitionCount;
+ byte i2rTxLtfRepetitionCount;
/**
- * Minimum non-trigger based (non-TB) dynamic measurement time in milliseconds assigned by the
- * IEEE 802.11az responder.
+ * Multiple transmissions of HE-LTF symbols in an HE (R2I) Ranging NDP. An HE-LTF repetition
+ * value of 1 indicates no repetitions.
+ */
+ byte r2iTxLtfRepetitionCount;
+ /**
+ * Minimum non-trigger based (non-TB) dynamic measurement time in units of 100 microseconds
+ * assigned by the IEEE 802.11az responder.
*
* After initial non-TB negotiation, if the next ranging request for this peer comes in between
* [ntbMinMeasurementTime, ntbMaxMeasurementTime], vendor software shall do the NDPA sounding
@@ -160,11 +166,13 @@
* If the ranging request for this peer comes sooner than minimum measurement time, vendor
* software shall return the cached result of the last measurement including the time stamp
* |RttResult.timestamp|.
+ *
+ * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
*/
- int ntbMinMeasurementTimeMillis;
+ long ntbMinMeasurementTime;
/**
- * Maximum non-trigger based (non-TB) dynamic measurement time in milliseconds assigned by the
- * IEEE 802.11az responder.
+ * Maximum non-trigger based (non-TB) dynamic measurement time in units of 10 milliseconds
+ * assigned by the IEEE 802.11az responder.
*
* After initial non-TB negotiation, if the next ranging request for this peer comes in between
* [ntbMinMeasurementTime, ntbMaxMeasurementTime], vendor software shall do the NDPA sounding
@@ -173,6 +181,8 @@
* If the ranging request for this peer comes later than the maximum measurement time, vendor
* software shall clean up any existing IEEE 802.11ax non-TB ranging session and re-do the
* non-TB ranging negotiation.
+ *
+ * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
*/
- int ntbMaxMeasurementTimeMillis;
+ long ntbMaxMeasurementTime;
}
diff --git a/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl b/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
index 9007d0e..4012c3e 100644
--- a/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
@@ -48,9 +48,9 @@
/**
* Minimum TWT wake interval in microseconds.
*/
- int minWakeIntervalMicros;
+ long minWakeIntervalMicros;
/**
* Maximum TWT wake interval in microseconds.
*/
- int maxWakeIntervalMicros;
+ long maxWakeIntervalMicros;
}
diff --git a/wifi/aidl/android/hardware/wifi/TwtRequest.aidl b/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
index 5191713..b063da3 100644
--- a/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
@@ -36,9 +36,9 @@
/**
* Minimum TWT wake interval in microseconds.
*/
- int minWakeIntervalMicros;
+ long minWakeIntervalMicros;
/**
* Maximum TWT wake interval in microseconds.
*/
- int maxWakeIntervalMicros;
+ long maxWakeIntervalMicros;
}
diff --git a/wifi/aidl/android/hardware/wifi/TwtSession.aidl b/wifi/aidl/android/hardware/wifi/TwtSession.aidl
index 5a7ddb1..6b780f8 100644
--- a/wifi/aidl/android/hardware/wifi/TwtSession.aidl
+++ b/wifi/aidl/android/hardware/wifi/TwtSession.aidl
@@ -46,7 +46,7 @@
/**
* Time interval in microseconds between two successive TWT service periods.
*/
- int wakeIntervalMicros;
+ long wakeIntervalMicros;
/**
* TWT negotiation type.
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index b62b3a0..7e7929d 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -2741,9 +2741,8 @@
if (!convertAidlRttConfigToLegacy(aidl_config, &(legacy_config->rtt_config))) {
return false;
}
- legacy_config->tx_ltf_repetition_count = aidl_config.txLtfRepetitionCount;
- legacy_config->ntb_min_measurement_time_millis = aidl_config.ntbMinMeasurementTimeMillis;
- legacy_config->ntb_max_measurement_time_millis = aidl_config.ntbMaxMeasurementTimeMillis;
+ legacy_config->ntb_min_measurement_time = aidl_config.ntbMinMeasurementTime;
+ legacy_config->ntb_max_measurement_time = aidl_config.ntbMaxMeasurementTime;
return true;
}
@@ -2891,7 +2890,6 @@
aidl_capabilities->azBwSupport = RttBw::BW_UNSPECIFIED;
aidl_capabilities->ntbInitiatorSupported = false;
aidl_capabilities->ntbResponderSupported = false;
- aidl_capabilities->maxTxLtfRepetitionCount = 0;
return true;
}
@@ -2919,7 +2917,6 @@
convertLegacyRttBwBitmapToAidl(legacy_capabilities_v3.az_bw_support);
aidl_capabilities->ntbInitiatorSupported = legacy_capabilities_v3.ntb_initiator_supported;
aidl_capabilities->ntbResponderSupported = legacy_capabilities_v3.ntb_responder_supported;
- aidl_capabilities->maxTxLtfRepetitionCount = legacy_capabilities_v3.max_tx_ltf_repetition_count;
return true;
}
@@ -2994,9 +2991,10 @@
}
aidl_result.channelFreqMHz = 0;
aidl_result.packetBw = RttBw::BW_UNSPECIFIED;
- aidl_result.txLtfRepetitionCount = 0;
- aidl_result.ntbMinMeasurementTimeMillis = 0;
- aidl_result.ntbMaxMeasurementTimeMillis = 0;
+ aidl_result.i2rTxLtfRepetitionCount = 0;
+ aidl_result.r2iTxLtfRepetitionCount = 0;
+ aidl_result.ntbMinMeasurementTime = 0;
+ aidl_result.ntbMaxMeasurementTime = 0;
aidl_results->push_back(aidl_result);
}
return true;
@@ -3017,9 +3015,10 @@
aidl_result.channelFreqMHz =
legacy_result->frequency != UNSPECIFIED ? legacy_result->frequency : 0;
aidl_result.packetBw = convertLegacyRttBwToAidl(legacy_result->packet_bw);
- aidl_result.txLtfRepetitionCount = 0;
- aidl_result.ntbMinMeasurementTimeMillis = 0;
- aidl_result.ntbMaxMeasurementTimeMillis = 0;
+ aidl_result.i2rTxLtfRepetitionCount = 0;
+ aidl_result.r2iTxLtfRepetitionCount = 0;
+ aidl_result.ntbMinMeasurementTime = 0;
+ aidl_result.ntbMaxMeasurementTime = 0;
aidl_results->push_back(aidl_result);
}
return true;
@@ -3041,9 +3040,10 @@
? legacy_result->rtt_result.frequency
: 0;
aidl_result.packetBw = convertLegacyRttBwToAidl(legacy_result->rtt_result.packet_bw);
- aidl_result.txLtfRepetitionCount = legacy_result->tx_ltf_repetition_count;
- aidl_result.ntbMinMeasurementTimeMillis = legacy_result->ntb_min_measurement_time_millis;
- aidl_result.ntbMaxMeasurementTimeMillis = legacy_result->ntb_max_measurement_time_millis;
+ aidl_result.i2rTxLtfRepetitionCount = legacy_result->i2r_tx_ltf_repetition_count;
+ aidl_result.r2iTxLtfRepetitionCount = legacy_result->r2i_tx_ltf_repetition_count;
+ aidl_result.ntbMinMeasurementTime = legacy_result->ntb_min_measurement_time;
+ aidl_result.ntbMaxMeasurementTime = legacy_result->ntb_max_measurement_time;
aidl_results->push_back(aidl_result);
}
return true;
diff --git a/wifi/aidl/vts/functional/Android.bp b/wifi/aidl/vts/functional/Android.bp
index 1277182..6896110 100644
--- a/wifi/aidl/vts/functional/Android.bp
+++ b/wifi/aidl/vts/functional/Android.bp
@@ -39,7 +39,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -64,7 +65,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -89,7 +91,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -114,7 +117,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -139,7 +143,8 @@
],
static_libs: [
"VtsHalWifiTargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
test_suites: [
@@ -163,7 +168,8 @@
"libnativehelper",
],
static_libs: [
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system-iface",
],
}
diff --git a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
index 740f833..a1b9ce1 100644
--- a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
@@ -872,6 +872,36 @@
EXPECT_EQ(instances_after_remove.size(), 1);
}
+/*
+ * SetVoipMode_off
+ * Tests the setVoipMode() API with VoIP mode OFF.
+ */
+TEST_P(WifiChipAidlTest, SetVoipMode_off) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_VOIP_MODE)) {
+ auto status = wifi_chip_->setVoipMode(IWifiChip::VoipMode::OFF);
+ EXPECT_TRUE(status.isOk());
+ } else {
+ GTEST_SKIP() << "setVoipMode() is not supported by vendor.";
+ }
+}
+
+/*
+ * SetVoipMode_voice
+ * Tests the setVoipMode() API with VoIP mode VOICE.
+ */
+TEST_P(WifiChipAidlTest, SetVoipMode_voice) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_VOIP_MODE)) {
+ auto status = wifi_chip_->setVoipMode(IWifiChip::VoipMode::VOICE);
+ EXPECT_TRUE(status.isOk());
+ } else {
+ GTEST_SKIP() << "setVoipMode() is not supported by vendor.";
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipAidlTest);
INSTANTIATE_TEST_SUITE_P(WifiTest, WifiChipAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index ff35056..87eee82 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -36,7 +36,8 @@
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
"android.hardware.wifi@1.6",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"libwifi-system",
"libwifi-system-iface",
"VtsHalWifiTargetTestUtil",
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
index 5465a86..e19ae44 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -45,4 +45,5 @@
byte[6] goInterfaceAddress;
boolean isP2pClientEapolIpAddressInfoPresent;
android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo p2pClientIpInfo;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
index 90e9f5e..5c7c393 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
@@ -37,4 +37,5 @@
String groupInterfaceName;
byte[6] clientInterfaceAddress;
byte[6] clientDeviceAddress;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
index 800f5b3..40c8ff6 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
@@ -38,4 +38,5 @@
byte[6] clientInterfaceAddress;
byte[6] clientDeviceAddress;
int clientIpAddress;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
index 587c7c6..0ff0653 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
@@ -40,4 +40,5 @@
android.hardware.wifi.supplicant.WpsConfigMethods configMethods;
String generatedPin;
String groupInterfaceName;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
index 96f1e16..9db7a1e 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo;
/**
@@ -63,4 +64,10 @@
* The value is undefined if isP2pClientEapolIpAddressInfoPresent is false.
*/
P2pClientEapolIpAddressInfo p2pClientIpInfo;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
index 936efd1..6e3350f 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientDisconnectedEventParams.aidl
@@ -16,6 +16,8 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
+
/**
* Parameters passed as a part of P2P peer client disconnected event.
*/
@@ -29,4 +31,10 @@
/** P2P device interface MAC address of the client that disconnected. */
byte[6] clientDeviceAddress;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
index 7eae2e5..4f46d70 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
@@ -16,6 +16,8 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
+
/**
* Parameters passed as a part of P2P peer client joined event.
*/
@@ -39,4 +41,10 @@
* The value is set to zero if the IP address is not allocated via EAPOL exchange.
*/
int clientIpAddress;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
index 7fa7f22..b559216 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
import android.hardware.wifi.supplicant.WpsConfigMethods;
@@ -45,4 +46,9 @@
* Refer to WFA Wi-Fi_Direct_Specification_v1.9 section 3.2.1 for more details.
*/
String groupInterfaceName;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
index b2356a0..96c13e7 100644
--- a/wifi/supplicant/aidl/vts/functional/Android.bp
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -51,7 +51,8 @@
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"VtsHalWifiTargetTestUtil",
],
test_suites: [
@@ -88,7 +89,8 @@
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"VtsHalWifiTargetTestUtil",
],
test_suites: [
@@ -125,7 +127,8 @@
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
- "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi.common-V1-ndk",
+ "android.hardware.wifi-V2-ndk",
"VtsHalWifiTargetTestUtil",
],
test_suites: [