From 11178a6e8ec81d8fa9022c38236aae2d17caa3f2 Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Tue, 18 Jun 2024 10:07:26 +0000 Subject: [PATCH] LeAudio: Verify codec frame blocks pers SDU parameter Bug: 308428644 Bug: 346568041 Test: atest VtsHalBluetoothAudioTargetTest Change-Id: I6567950d24d1df8cabec2855c907c5611ca5bf6d --- .../vts/VtsHalBluetoothAudioTargetTest.cpp | 132 ++++++++++++++---- 1 file changed, 101 insertions(+), 31 deletions(-) diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp index e83cb9ed78..110a628882 100644 --- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp +++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp @@ -195,6 +195,17 @@ void copy_codec_specific(CodecConfiguration::CodecSpecific& dst, } } +static std::optional GetConfigurationLtv( + const std::vector& configurationLtvs, + CodecSpecificConfigurationLtv::Tag tag) { + for (const auto ltv : configurationLtvs) { + if (ltv.getTag() == tag) { + return ltv; + } + } + return std::nullopt; +} + class BluetoothAudioPort : public BnBluetoothAudioPort { public: BluetoothAudioPort() {} @@ -2393,17 +2404,6 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl return capability; } - std::optional GetConfigurationLtv( - const std::vector& configurationLtvs, - CodecSpecificConfigurationLtv::Tag tag) { - for (const auto ltv : configurationLtvs) { - if (ltv.getTag() == tag) { - return ltv; - } - } - return std::nullopt; - } - bool IsAseRequirementSatisfiedWithUnknownChannelCount( const std::vector>& ase_requirements, @@ -2560,6 +2560,67 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl return (num_of_satisfied_ase_requirements == ase_requirements.size()); } + static void VerifyCodecParameters( + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioAseConfigurationSetting::AseDirectionConfiguration config) { + ASSERT_NE(config.aseConfiguration.codecConfiguration.size(), 0lu); + ASSERT_TRUE(config.qosConfiguration.has_value()); + + int32_t frame_blocks = 1; // by default 1 if not set + int8_t frame_duration = 0; + int32_t octets_per_frame = 0; + std::bitset<32> allocation_bitmask = 0; + + for (auto const& param : config.aseConfiguration.codecConfiguration) { + if (param.getTag() == + ::aidl::android::hardware::bluetooth::audio:: + CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU) { + frame_blocks = param + .get<::aidl::android::hardware::bluetooth::audio:: + CodecSpecificConfigurationLtv::Tag:: + codecFrameBlocksPerSDU>() + .value; + } else if (param.getTag() == + ::aidl::android::hardware::bluetooth::audio:: + CodecSpecificConfigurationLtv::Tag::frameDuration) { + frame_duration = static_cast( + param.get<::aidl::android::hardware::bluetooth::audio:: + CodecSpecificConfigurationLtv::Tag::frameDuration>()); + } else if (param.getTag() == + ::aidl::android::hardware::bluetooth::audio:: + CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame) { + octets_per_frame = static_cast( + param + .get<::aidl::android::hardware::bluetooth::audio:: + CodecSpecificConfigurationLtv::Tag:: + octetsPerCodecFrame>() + .value); + } else if (param.getTag() == ::aidl::android::hardware::bluetooth::audio:: + CodecSpecificConfigurationLtv::Tag:: + audioChannelAllocation) { + allocation_bitmask = static_cast( + param + .get<::aidl::android::hardware::bluetooth::audio:: + CodecSpecificConfigurationLtv::Tag:: + audioChannelAllocation>() + .bitmask); + } + } + + ASSERT_NE(frame_blocks, 0); + ASSERT_NE(frame_duration, 0); + ASSERT_NE(octets_per_frame, 0); + + auto const num_channels_per_cis = allocation_bitmask.count(); + ASSERT_NE(num_channels_per_cis, 0); + + // Verify if QoS takes the codec frame blocks per SDU into the account + ASSERT_TRUE(config.qosConfiguration->sduIntervalUs >= + frame_blocks * frame_duration); + ASSERT_TRUE(config.qosConfiguration->maxSdu >= + (frame_blocks * num_channels_per_cis * octets_per_frame)); + } + void VerifyIfRequirementsSatisfied( const std::vector& requirements, const std::vector& configurations) { @@ -2592,32 +2653,52 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl continue; } + bool sink_req_satisfied = false; + if (req.sinkAseRequirement) { + ASSERT_TRUE(conf.sinkAseConfiguration.has_value()); + sink_req_satisfied = IsAseRequirementSatisfied( + *req.sinkAseRequirement, *conf.sinkAseConfiguration); + + ASSERT_NE(conf.sinkAseConfiguration->size(), 0lu); + for (auto const& cfg : conf.sinkAseConfiguration.value()) { + ASSERT_TRUE(cfg.has_value()); + VerifyCodecParameters(cfg.value()); + } + } + + bool source_req_satisfied = false; + if (req.sourceAseRequirement) { + ASSERT_TRUE(conf.sourceAseConfiguration.has_value()); + source_req_satisfied = IsAseRequirementSatisfied( + *req.sourceAseRequirement, *conf.sourceAseConfiguration); + + ASSERT_NE(conf.sourceAseConfiguration->size(), 0lu); + for (auto const& cfg : conf.sourceAseConfiguration.value()) { + ASSERT_TRUE(cfg.has_value()); + VerifyCodecParameters(cfg.value()); + } + } + if (req.sinkAseRequirement && req.sourceAseRequirement) { if (!conf.sinkAseConfiguration || !conf.sourceAseConfiguration) { continue; } - if (!IsAseRequirementSatisfied(*req.sinkAseRequirement, - *conf.sinkAseConfiguration) || - !IsAseRequirementSatisfied(*req.sourceAseRequirement, - *conf.sourceAseConfiguration)) { + if (!sink_req_satisfied || !source_req_satisfied) { continue; } num_of_satisfied_requirements += std::bitset<32>(req.audioContext.bitmask).count(); - break; } else if (req.sinkAseRequirement) { - if (!IsAseRequirementSatisfied(*req.sinkAseRequirement, - *conf.sinkAseConfiguration)) { + if (!sink_req_satisfied) { continue; } num_of_satisfied_requirements += std::bitset<32>(req.audioContext.bitmask).count(); break; } else if (req.sourceAseRequirement) { - if (!IsAseRequirementSatisfied(*req.sourceAseRequirement, - *conf.sourceAseConfiguration)) { + if (!source_req_satisfied) { continue; } num_of_satisfied_requirements += @@ -4089,17 +4170,6 @@ class BluetoothAudioProviderLeAudioBroadcastHardwareAidl return media_audio_context; } - std::optional GetConfigurationLtv( - const std::vector& configurationLtvs, - CodecSpecificConfigurationLtv::Tag tag) { - for (const auto ltv : configurationLtvs) { - if (ltv.getTag() == tag) { - return ltv; - } - } - return std::nullopt; - } - std::optional GetBisSampleFreq(const LeAudioBisConfiguration& bis_conf) { auto sample_freq_ltv = GetConfigurationLtv(