1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define STREAM_TO_UINT8(u8, p) \
18   {                            \
19     (u8) = (uint8_t)(*(p));    \
20     (p) += 1;                  \
21   }
22 #define STREAM_TO_UINT16(u16, p)                                  \
23   {                                                               \
24     (u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \
25     (p) += 2;                                                     \
26   }
27 #define STREAM_TO_UINT32(u32, p)                                      \
28   {                                                                   \
29     (u32) = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + \
30              ((((uint32_t)(*((p) + 2)))) << 16) +                     \
31              ((((uint32_t)(*((p) + 3)))) << 24));                     \
32     (p) += 4;                                                         \
33   }
34 
35 #define LOG_TAG "BTAudioAseConfigAidl"
36 
37 #include "BluetoothLeAudioAseConfigurationSettingProvider.h"
38 
39 #include <aidl/android/hardware/bluetooth/audio/AudioConfiguration.h>
40 #include <aidl/android/hardware/bluetooth/audio/AudioContext.h>
41 #include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
42 #include <aidl/android/hardware/bluetooth/audio/CodecId.h>
43 #include <aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.h>
44 #include <aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.h>
45 #include <aidl/android/hardware/bluetooth/audio/ConfigurationFlags.h>
46 #include <aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.h>
47 #include <aidl/android/hardware/bluetooth/audio/Phy.h>
48 #include <android-base/logging.h>
49 
50 #include "flatbuffers/idl.h"
51 #include "flatbuffers/util.h"
52 
53 namespace aidl {
54 namespace android {
55 namespace hardware {
56 namespace bluetooth {
57 namespace audio {
58 
59 /* Internal structure definition */
60 std::map<std::string,
61          std::tuple<std::vector<std::optional<AseDirectionConfiguration>>,
62                     std::vector<std::optional<AseDirectionConfiguration>>,
63                     ConfigurationFlags>>
64     configurations_;
65 
66 std::vector<LeAudioAseConfigurationSetting> ase_configuration_settings_;
67 
68 constexpr uint8_t kIsoDataPathHci = 0x00;
69 constexpr uint8_t kIsoDataPathPlatformDefault = 0x01;
70 constexpr uint8_t kIsoDataPathDisabled = 0xFF;
71 
72 constexpr uint8_t kLeAudioDirectionSink = 0x01;
73 constexpr uint8_t kLeAudioDirectionSource = 0x02;
74 constexpr uint8_t kLeAudioDirectionBoth =
75     kLeAudioDirectionSink | kLeAudioDirectionSource;
76 
77 /* Sampling Frequencies */
78 constexpr uint8_t kLeAudioSamplingFreq8000Hz = 0x01;
79 constexpr uint8_t kLeAudioSamplingFreq11025Hz = 0x02;
80 constexpr uint8_t kLeAudioSamplingFreq16000Hz = 0x03;
81 constexpr uint8_t kLeAudioSamplingFreq22050Hz = 0x04;
82 constexpr uint8_t kLeAudioSamplingFreq24000Hz = 0x05;
83 constexpr uint8_t kLeAudioSamplingFreq32000Hz = 0x06;
84 constexpr uint8_t kLeAudioSamplingFreq44100Hz = 0x07;
85 constexpr uint8_t kLeAudioSamplingFreq48000Hz = 0x08;
86 constexpr uint8_t kLeAudioSamplingFreq88200Hz = 0x09;
87 constexpr uint8_t kLeAudioSamplingFreq96000Hz = 0x0A;
88 constexpr uint8_t kLeAudioSamplingFreq176400Hz = 0x0B;
89 constexpr uint8_t kLeAudioSamplingFreq192000Hz = 0x0C;
90 constexpr uint8_t kLeAudioSamplingFreq384000Hz = 0x0D;
91 
92 /* Frame Durations */
93 constexpr uint8_t kLeAudioCodecFrameDur7500us = 0x00;
94 constexpr uint8_t kLeAudioCodecFrameDur10000us = 0x01;
95 constexpr uint8_t kLeAudioCodecFrameDur20000us = 0x02;
96 
97 /* Audio Allocations */
98 constexpr uint32_t kLeAudioLocationMonoAudio = 0x00000000;
99 constexpr uint32_t kLeAudioLocationFrontLeft = 0x00000001;
100 constexpr uint32_t kLeAudioLocationFrontRight = 0x00000002;
101 constexpr uint32_t kLeAudioLocationFrontCenter = 0x00000004;
102 constexpr uint32_t kLeAudioLocationLowFreqEffects1 = 0x00000008;
103 constexpr uint32_t kLeAudioLocationBackLeft = 0x00000010;
104 constexpr uint32_t kLeAudioLocationBackRight = 0x00000020;
105 constexpr uint32_t kLeAudioLocationFrontLeftOfCenter = 0x00000040;
106 constexpr uint32_t kLeAudioLocationFrontRightOfCenter = 0x00000080;
107 constexpr uint32_t kLeAudioLocationBackCenter = 0x00000100;
108 constexpr uint32_t kLeAudioLocationLowFreqEffects2 = 0x00000200;
109 constexpr uint32_t kLeAudioLocationSideLeft = 0x00000400;
110 constexpr uint32_t kLeAudioLocationSideRight = 0x00000800;
111 constexpr uint32_t kLeAudioLocationTopFrontLeft = 0x00001000;
112 constexpr uint32_t kLeAudioLocationTopFrontRight = 0x00002000;
113 constexpr uint32_t kLeAudioLocationTopFrontCenter = 0x00004000;
114 constexpr uint32_t kLeAudioLocationTopCenter = 0x00008000;
115 constexpr uint32_t kLeAudioLocationTopBackLeft = 0x00010000;
116 constexpr uint32_t kLeAudioLocationTopBackRight = 0x00020000;
117 constexpr uint32_t kLeAudioLocationTopSideLeft = 0x00040000;
118 constexpr uint32_t kLeAudioLocationTopSideRight = 0x00080000;
119 constexpr uint32_t kLeAudioLocationTopBackCenter = 0x00100000;
120 constexpr uint32_t kLeAudioLocationBottomFrontCenter = 0x00200000;
121 constexpr uint32_t kLeAudioLocationBottomFrontLeft = 0x00400000;
122 constexpr uint32_t kLeAudioLocationBottomFrontRight = 0x00800000;
123 constexpr uint32_t kLeAudioLocationFrontLeftWide = 0x01000000;
124 constexpr uint32_t kLeAudioLocationFrontRightWide = 0x02000000;
125 constexpr uint32_t kLeAudioLocationLeftSurround = 0x04000000;
126 constexpr uint32_t kLeAudioLocationRightSurround = 0x08000000;
127 
128 constexpr uint32_t kLeAudioLocationAnyLeft =
129     kLeAudioLocationFrontLeft | kLeAudioLocationBackLeft |
130     kLeAudioLocationFrontLeftOfCenter | kLeAudioLocationSideLeft |
131     kLeAudioLocationTopFrontLeft | kLeAudioLocationTopBackLeft |
132     kLeAudioLocationTopSideLeft | kLeAudioLocationBottomFrontLeft |
133     kLeAudioLocationFrontLeftWide | kLeAudioLocationLeftSurround;
134 
135 constexpr uint32_t kLeAudioLocationAnyRight =
136     kLeAudioLocationFrontRight | kLeAudioLocationBackRight |
137     kLeAudioLocationFrontRightOfCenter | kLeAudioLocationSideRight |
138     kLeAudioLocationTopFrontRight | kLeAudioLocationTopBackRight |
139     kLeAudioLocationTopSideRight | kLeAudioLocationBottomFrontRight |
140     kLeAudioLocationFrontRightWide | kLeAudioLocationRightSurround;
141 
142 constexpr uint32_t kLeAudioLocationStereo =
143     kLeAudioLocationFrontLeft | kLeAudioLocationFrontRight;
144 
145 /* Octets Per Frame */
146 constexpr uint16_t kLeAudioCodecFrameLen30 = 30;
147 constexpr uint16_t kLeAudioCodecFrameLen40 = 40;
148 constexpr uint16_t kLeAudioCodecFrameLen60 = 60;
149 constexpr uint16_t kLeAudioCodecFrameLen80 = 80;
150 constexpr uint16_t kLeAudioCodecFrameLen100 = 100;
151 constexpr uint16_t kLeAudioCodecFrameLen120 = 120;
152 
153 /* Helper map for matching various sampling frequency notations */
154 const std::map<uint8_t, CodecSpecificConfigurationLtv::SamplingFrequency>
155     sampling_freq_map = {
156         {kLeAudioSamplingFreq8000Hz,
157          CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000},
158         {kLeAudioSamplingFreq16000Hz,
159          CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000},
160         {kLeAudioSamplingFreq24000Hz,
161          CodecSpecificConfigurationLtv::SamplingFrequency::HZ24000},
162         {kLeAudioSamplingFreq32000Hz,
163          CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000},
164         {kLeAudioSamplingFreq44100Hz,
165          CodecSpecificConfigurationLtv::SamplingFrequency::HZ44100},
166         {kLeAudioSamplingFreq48000Hz,
167          CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000}};
168 
169 /* Helper map for matching various frame durations notations */
170 const std::map<uint8_t, CodecSpecificConfigurationLtv::FrameDuration>
171     frame_duration_map = {
172         {kLeAudioCodecFrameDur7500us,
173          CodecSpecificConfigurationLtv::FrameDuration::US7500},
174         {kLeAudioCodecFrameDur10000us,
175          CodecSpecificConfigurationLtv::FrameDuration::US10000},
176         {kLeAudioCodecFrameDur20000us,
177          CodecSpecificConfigurationLtv::FrameDuration::US20000}};
178 
179 /* Helper map for matching various audio channel allocation notations */
180 std::map<uint32_t, uint32_t> audio_channel_allocation_map = {
181     {kLeAudioLocationMonoAudio,
182      CodecSpecificConfigurationLtv::AudioChannelAllocation::MONO},
183     {kLeAudioLocationFrontLeft,
184      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT},
185     {kLeAudioLocationFrontRight,
186      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT},
187     {kLeAudioLocationFrontCenter,
188      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER},
189     {kLeAudioLocationLowFreqEffects1,
190      CodecSpecificConfigurationLtv::AudioChannelAllocation::
191          LOW_FREQUENCY_EFFECTS_1},
192     {kLeAudioLocationBackLeft,
193      CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_LEFT},
194     {kLeAudioLocationBackRight,
195      CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_RIGHT},
196     {kLeAudioLocationFrontLeftOfCenter,
197      CodecSpecificConfigurationLtv::AudioChannelAllocation::
198          FRONT_LEFT_OF_CENTER},
199     {kLeAudioLocationFrontRightOfCenter,
200      CodecSpecificConfigurationLtv::AudioChannelAllocation::
201          FRONT_RIGHT_OF_CENTER},
202     {kLeAudioLocationBackCenter,
203      CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_CENTER},
204     {kLeAudioLocationLowFreqEffects2,
205      CodecSpecificConfigurationLtv::AudioChannelAllocation::
206          LOW_FREQUENCY_EFFECTS_2},
207     {kLeAudioLocationSideLeft,
208      CodecSpecificConfigurationLtv::AudioChannelAllocation::SIDE_LEFT},
209     {kLeAudioLocationSideRight,
210      CodecSpecificConfigurationLtv::AudioChannelAllocation::SIDE_RIGHT},
211     {kLeAudioLocationTopFrontLeft,
212      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_LEFT},
213     {kLeAudioLocationTopFrontRight,
214      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_RIGHT},
215     {kLeAudioLocationTopFrontCenter,
216      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_CENTER},
217     {kLeAudioLocationTopCenter,
218      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_CENTER},
219     {kLeAudioLocationTopBackLeft,
220      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_LEFT},
221     {kLeAudioLocationTopBackRight,
222      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_RIGHT},
223     {kLeAudioLocationTopSideLeft,
224      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_SIDE_LEFT},
225     {kLeAudioLocationTopSideRight,
226      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_SIDE_RIGHT},
227     {kLeAudioLocationTopBackCenter,
228      CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_CENTER},
229     {kLeAudioLocationBottomFrontCenter,
230      CodecSpecificConfigurationLtv::AudioChannelAllocation::
231          BOTTOM_FRONT_CENTER},
232     {kLeAudioLocationBottomFrontLeft,
233      CodecSpecificConfigurationLtv::AudioChannelAllocation::BOTTOM_FRONT_LEFT},
234     {kLeAudioLocationBottomFrontRight,
235      CodecSpecificConfigurationLtv::AudioChannelAllocation::BOTTOM_FRONT_RIGHT},
236     {kLeAudioLocationFrontLeftWide,
237      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT_WIDE},
238     {kLeAudioLocationFrontRightWide,
239      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT_WIDE},
240     {kLeAudioLocationLeftSurround,
241      CodecSpecificConfigurationLtv::AudioChannelAllocation::LEFT_SURROUND},
242     {kLeAudioLocationRightSurround,
243      CodecSpecificConfigurationLtv::AudioChannelAllocation::RIGHT_SURROUND},
244 };
245 
246 // Set configuration and scenario files with fallback default
247 static const std::vector<
248     std::pair<const char* /*schema*/, const char* /*content*/>>
249     kLeAudioSetConfigs = {
250         {"/vendor/etc/aidl/le_audio/"
251          "aidl_audio_set_configurations.bfbs",
252          "/vendor/etc/aidl/le_audio/"
253          "aidl_audio_set_configurations.json"},
254 
255         {"/vendor/etc/aidl/le_audio/"
256          "aidl_audio_set_configurations.bfbs",
257          "/vendor/etc/aidl/le_audio/"
258          "aidl_default_audio_set_configurations.json"},
259 };
260 static const std::vector<
261     std::pair<const char* /*schema*/, const char* /*content*/>>
262     kLeAudioSetScenarios = {{"/vendor/etc/aidl/le_audio/"
263                              "aidl_audio_set_scenarios.bfbs",
264                              "/vendor/etc/aidl/le_audio/"
265                              "aidl_audio_set_scenarios.json"},
266 
267                             {"/vendor/etc/aidl/le_audio/"
268                              "aidl_audio_set_scenarios.bfbs",
269                              "/vendor/etc/aidl/le_audio/"
270                              "aidl_default_audio_set_scenarios.json"}};
271 
272 /* Implementation */
273 
274 std::vector<LeAudioAseConfigurationSetting>
GetLeAudioAseConfigurationSettings()275 AudioSetConfigurationProviderJson::GetLeAudioAseConfigurationSettings() {
276   AudioSetConfigurationProviderJson::LoadAudioSetConfigurationProviderJson();
277   return ase_configuration_settings_;
278 }
279 
280 void AudioSetConfigurationProviderJson::
LoadAudioSetConfigurationProviderJson()281     LoadAudioSetConfigurationProviderJson() {
282   if (configurations_.empty() || ase_configuration_settings_.empty()) {
283     ase_configuration_settings_.clear();
284     configurations_.clear();
285     auto loaded = LoadContent(kLeAudioSetConfigs, kLeAudioSetScenarios,
286                               CodecLocation::ADSP);
287     if (!loaded)
288       LOG(ERROR) << ": Unable to load le audio set configuration files.";
289   } else
290     LOG(INFO) << ": Reusing loaded le audio set configuration";
291 }
292 
293 const le_audio::CodecSpecificConfiguration*
LookupCodecSpecificParam(const flatbuffers::Vector<flatbuffers::Offset<le_audio::CodecSpecificConfiguration>> * flat_codec_specific_params,le_audio::CodecSpecificLtvGenericTypes type)294 AudioSetConfigurationProviderJson::LookupCodecSpecificParam(
295     const flatbuffers::Vector<flatbuffers::Offset<
296         le_audio::CodecSpecificConfiguration>>* flat_codec_specific_params,
297     le_audio::CodecSpecificLtvGenericTypes type) {
298   auto it = std::find_if(
299       flat_codec_specific_params->cbegin(), flat_codec_specific_params->cend(),
300       [&type](const auto& csc) { return (csc->type() == type); });
301   return (it != flat_codec_specific_params->cend()) ? *it : nullptr;
302 }
303 
populateAudioChannelAllocation(CodecSpecificConfigurationLtv::AudioChannelAllocation & audio_channel_allocation,uint32_t audio_location)304 void AudioSetConfigurationProviderJson::populateAudioChannelAllocation(
305     CodecSpecificConfigurationLtv::AudioChannelAllocation&
306         audio_channel_allocation,
307     uint32_t audio_location) {
308   audio_channel_allocation.bitmask = 0;
309   for (auto [allocation, bitmask] : audio_channel_allocation_map) {
310     if (audio_location & allocation)
311       audio_channel_allocation.bitmask |= bitmask;
312   }
313 }
314 
populateConfigurationData(LeAudioAseConfiguration & ase,const flatbuffers::Vector<flatbuffers::Offset<le_audio::CodecSpecificConfiguration>> * flat_codec_specific_params)315 void AudioSetConfigurationProviderJson::populateConfigurationData(
316     LeAudioAseConfiguration& ase,
317     const flatbuffers::Vector<
318         flatbuffers::Offset<le_audio::CodecSpecificConfiguration>>*
319         flat_codec_specific_params) {
320   uint8_t sampling_frequency = 0;
321   uint8_t frame_duration = 0;
322   uint32_t audio_channel_allocation = 0;
323   uint16_t octets_per_codec_frame = 0;
324   uint8_t codec_frames_blocks_per_sdu = 0;
325 
326   auto param = LookupCodecSpecificParam(
327       flat_codec_specific_params,
328       le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_SAMPLING_FREQUENCY);
329   if (param) {
330     auto ptr = param->compound_value()->value()->data();
331     STREAM_TO_UINT8(sampling_frequency, ptr);
332   }
333 
334   param = LookupCodecSpecificParam(
335       flat_codec_specific_params,
336       le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_FRAME_DURATION);
337   if (param) {
338     auto ptr = param->compound_value()->value()->data();
339     STREAM_TO_UINT8(frame_duration, ptr);
340   }
341 
342   param = LookupCodecSpecificParam(
343       flat_codec_specific_params,
344       le_audio::
345           CodecSpecificLtvGenericTypes_SUPPORTED_AUDIO_CHANNEL_ALLOCATION);
346   if (param) {
347     auto ptr = param->compound_value()->value()->data();
348     STREAM_TO_UINT32(audio_channel_allocation, ptr);
349   }
350 
351   param = LookupCodecSpecificParam(
352       flat_codec_specific_params,
353       le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_OCTETS_PER_CODEC_FRAME);
354   if (param) {
355     auto ptr = param->compound_value()->value()->data();
356     STREAM_TO_UINT16(octets_per_codec_frame, ptr);
357   }
358 
359   param = LookupCodecSpecificParam(
360       flat_codec_specific_params,
361       le_audio::
362           CodecSpecificLtvGenericTypes_SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU);
363   if (param) {
364     auto ptr = param->compound_value()->value()->data();
365     STREAM_TO_UINT8(codec_frames_blocks_per_sdu, ptr);
366   }
367 
368   // Make the correct value
369   ase.codecConfiguration = std::vector<CodecSpecificConfigurationLtv>();
370 
371   auto sampling_freq_it = sampling_freq_map.find(sampling_frequency);
372   if (sampling_freq_it != sampling_freq_map.end())
373     ase.codecConfiguration.push_back(sampling_freq_it->second);
374   auto frame_duration_it = frame_duration_map.find(frame_duration);
375   if (frame_duration_it != frame_duration_map.end())
376     ase.codecConfiguration.push_back(frame_duration_it->second);
377 
378   CodecSpecificConfigurationLtv::AudioChannelAllocation channel_allocation;
379   populateAudioChannelAllocation(channel_allocation, audio_channel_allocation);
380   ase.codecConfiguration.push_back(channel_allocation);
381 
382   auto octet_structure = CodecSpecificConfigurationLtv::OctetsPerCodecFrame();
383   octet_structure.value = octets_per_codec_frame;
384   ase.codecConfiguration.push_back(octet_structure);
385 
386   auto frame_sdu_structure =
387       CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU();
388   frame_sdu_structure.value = codec_frames_blocks_per_sdu;
389   ase.codecConfiguration.push_back(frame_sdu_structure);
390 }
391 
populateAseConfiguration(const std::string & name,LeAudioAseConfiguration & ase,const le_audio::AudioSetSubConfiguration * flat_subconfig,const le_audio::QosConfiguration * qos_cfg)392 void AudioSetConfigurationProviderJson::populateAseConfiguration(
393     const std::string& name, LeAudioAseConfiguration& ase,
394     const le_audio::AudioSetSubConfiguration* flat_subconfig,
395     const le_audio::QosConfiguration* qos_cfg) {
396   // Target latency
397   switch (qos_cfg->target_latency()) {
398     case le_audio::AudioSetConfigurationTargetLatency::
399         AudioSetConfigurationTargetLatency_BALANCED_RELIABILITY:
400       ase.targetLatency =
401           LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY;
402       break;
403     case le_audio::AudioSetConfigurationTargetLatency::
404         AudioSetConfigurationTargetLatency_HIGH_RELIABILITY:
405       ase.targetLatency =
406           LeAudioAseConfiguration::TargetLatency::HIGHER_RELIABILITY;
407       break;
408     case le_audio::AudioSetConfigurationTargetLatency::
409         AudioSetConfigurationTargetLatency_LOW:
410       ase.targetLatency = LeAudioAseConfiguration::TargetLatency::LOWER;
411       break;
412     default:
413       ase.targetLatency = LeAudioAseConfiguration::TargetLatency::UNDEFINED;
414       break;
415   };
416 
417   ase.targetPhy = Phy::TWO_M;
418   // Making CodecId
419   if (flat_subconfig->codec_id()->coding_format() ==
420       (uint8_t)CodecId::Core::LC3) {
421     ase.codecId = CodecId::Core::LC3;
422   } else {
423     auto vendorC = CodecId::Vendor();
424     vendorC.codecId = flat_subconfig->codec_id()->vendor_codec_id();
425     vendorC.id = flat_subconfig->codec_id()->vendor_company_id();
426     ase.codecId = vendorC;
427   }
428   // Codec configuration data
429   populateConfigurationData(ase, flat_subconfig->codec_configuration());
430   // Populate the config name for easier debug
431   auto meta = std::vector<std::optional<MetadataLtv>>();
432   MetadataLtv::VendorSpecific cfg_name;
433   cfg_name.opaqueValue = std::vector<uint8_t>(name.begin(), name.end());
434   meta.push_back(cfg_name);
435   ase.metadata = meta;
436 }
437 
populateAseQosConfiguration(LeAudioAseQosConfiguration & qos,const le_audio::QosConfiguration * qos_cfg,LeAudioAseConfiguration & ase,uint8_t ase_channel_cnt)438 void AudioSetConfigurationProviderJson::populateAseQosConfiguration(
439     LeAudioAseQosConfiguration& qos, const le_audio::QosConfiguration* qos_cfg,
440     LeAudioAseConfiguration& ase, uint8_t ase_channel_cnt) {
441   std::optional<CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU>
442       frameBlock = std::nullopt;
443   std::optional<CodecSpecificConfigurationLtv::FrameDuration> frameDuration =
444       std::nullopt;
445   std::optional<CodecSpecificConfigurationLtv::OctetsPerCodecFrame> octet =
446       std::nullopt;
447 
448   // Hack to put back allocation
449   CodecSpecificConfigurationLtv::AudioChannelAllocation allocation =
450       CodecSpecificConfigurationLtv::AudioChannelAllocation();
451   if (ase_channel_cnt == 1) {
452     allocation.bitmask |=
453         CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER;
454 
455   } else {
456     allocation.bitmask |=
457         CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT |
458         CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT;
459   }
460   for (auto& cfg_ltv : ase.codecConfiguration) {
461     auto tag = cfg_ltv.getTag();
462     if (tag == CodecSpecificConfigurationLtv::codecFrameBlocksPerSDU) {
463       frameBlock =
464           cfg_ltv.get<CodecSpecificConfigurationLtv::codecFrameBlocksPerSDU>();
465     } else if (tag == CodecSpecificConfigurationLtv::frameDuration) {
466       frameDuration =
467           cfg_ltv.get<CodecSpecificConfigurationLtv::frameDuration>();
468     } else if (tag == CodecSpecificConfigurationLtv::octetsPerCodecFrame) {
469       octet = cfg_ltv.get<CodecSpecificConfigurationLtv::octetsPerCodecFrame>();
470     } else if (tag == CodecSpecificConfigurationLtv::audioChannelAllocation) {
471       // Change to the old hack allocation
472       cfg_ltv.set<CodecSpecificConfigurationLtv::audioChannelAllocation>(
473           allocation);
474     }
475   }
476 
477   int frameBlockValue = 1;
478   if (frameBlock.has_value()) frameBlockValue = frameBlock.value().value;
479 
480   // Populate maxSdu
481   if (octet.has_value()) {
482     qos.maxSdu = ase_channel_cnt * octet.value().value * frameBlockValue;
483   }
484   // Populate sduIntervalUs
485   if (frameDuration.has_value()) {
486     switch (frameDuration.value()) {
487       case CodecSpecificConfigurationLtv::FrameDuration::US7500:
488         qos.sduIntervalUs = 7500;
489         break;
490       case CodecSpecificConfigurationLtv::FrameDuration::US10000:
491         qos.sduIntervalUs = 10000;
492         break;
493       case CodecSpecificConfigurationLtv::FrameDuration::US20000:
494         qos.sduIntervalUs = 20000;
495         break;
496     }
497     qos.sduIntervalUs *= frameBlockValue;
498   }
499   qos.maxTransportLatencyMs = qos_cfg->max_transport_latency();
500   qos.retransmissionNum = qos_cfg->retransmission_number();
501 }
502 
503 // Parse into AseDirectionConfiguration
504 AseDirectionConfiguration
SetConfigurationFromFlatSubconfig(const std::string & name,const le_audio::AudioSetSubConfiguration * flat_subconfig,const le_audio::QosConfiguration * qos_cfg,CodecLocation location)505 AudioSetConfigurationProviderJson::SetConfigurationFromFlatSubconfig(
506     const std::string& name,
507     const le_audio::AudioSetSubConfiguration* flat_subconfig,
508     const le_audio::QosConfiguration* qos_cfg, CodecLocation location) {
509   AseDirectionConfiguration direction_conf;
510 
511   LeAudioAseConfiguration ase;
512   LeAudioAseQosConfiguration qos;
513   LeAudioDataPathConfiguration path;
514 
515   // Translate into LeAudioAseConfiguration
516   populateAseConfiguration(name, ase, flat_subconfig, qos_cfg);
517 
518   // Translate into LeAudioAseQosConfiguration
519   populateAseQosConfiguration(qos, qos_cfg, ase,
520                               flat_subconfig->ase_channel_cnt());
521 
522   // Translate location to data path id
523   switch (location) {
524     case CodecLocation::ADSP:
525       path.isoDataPathConfiguration.isTransparent = true;
526       path.dataPathId = kIsoDataPathPlatformDefault;
527       break;
528     case CodecLocation::HOST:
529       path.isoDataPathConfiguration.isTransparent = true;
530       path.dataPathId = kIsoDataPathHci;
531       break;
532     case CodecLocation::CONTROLLER:
533       path.isoDataPathConfiguration.isTransparent = false;
534       path.dataPathId = kIsoDataPathPlatformDefault;
535       break;
536   }
537   // Move codecId to iso data path
538   path.isoDataPathConfiguration.codecId = ase.codecId.value();
539 
540   direction_conf.aseConfiguration = ase;
541   direction_conf.qosConfiguration = qos;
542   direction_conf.dataPathConfiguration = path;
543 
544   return direction_conf;
545 }
546 
547 // Parse into AseDirectionConfiguration and the ConfigurationFlags
548 // and put them in the given list.
processSubconfig(const std::string & name,const le_audio::AudioSetSubConfiguration * subconfig,const le_audio::QosConfiguration * qos_cfg,std::vector<std::optional<AseDirectionConfiguration>> & directionAseConfiguration,CodecLocation location)549 void AudioSetConfigurationProviderJson::processSubconfig(
550     const std::string& name,
551     const le_audio::AudioSetSubConfiguration* subconfig,
552     const le_audio::QosConfiguration* qos_cfg,
553     std::vector<std::optional<AseDirectionConfiguration>>&
554         directionAseConfiguration,
555     CodecLocation location) {
556   auto ase_cnt = subconfig->ase_cnt();
557   auto config =
558       SetConfigurationFromFlatSubconfig(name, subconfig, qos_cfg, location);
559   directionAseConfiguration.push_back(config);
560   // Put the same setting again.
561   if (ase_cnt == 2) directionAseConfiguration.push_back(config);
562 }
563 
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 &)564 void AudioSetConfigurationProviderJson::PopulateAseConfigurationFromFlat(
565     const le_audio::AudioSetConfiguration* flat_cfg,
566     std::vector<const le_audio::CodecConfiguration*>* codec_cfgs,
567     std::vector<const le_audio::QosConfiguration*>* qos_cfgs,
568     CodecLocation location,
569     std::vector<std::optional<AseDirectionConfiguration>>&
570         sourceAseConfiguration,
571     std::vector<std::optional<AseDirectionConfiguration>>& sinkAseConfiguration,
572     ConfigurationFlags& /*configurationFlags*/) {
573   if (flat_cfg == nullptr) {
574     LOG(ERROR) << "flat_cfg cannot be null";
575     return;
576   }
577   std::string codec_config_key = flat_cfg->codec_config_name()->str();
578   auto* qos_config_key_array = flat_cfg->qos_config_name();
579 
580   constexpr std::string_view default_qos = "QoS_Config_Balanced_Reliability";
581 
582   std::string qos_sink_key(default_qos);
583   std::string qos_source_key(default_qos);
584 
585   /* We expect maximum two QoS settings. First for Sink and second for Source
586    */
587   if (qos_config_key_array->size() > 0) {
588     qos_sink_key = qos_config_key_array->Get(0)->str();
589     if (qos_config_key_array->size() > 1) {
590       qos_source_key = qos_config_key_array->Get(1)->str();
591     } else {
592       qos_source_key = qos_sink_key;
593     }
594   }
595 
596   LOG(INFO) << "Audio set config " << flat_cfg->name()->c_str()
597             << ": codec config " << codec_config_key.c_str() << ", qos_sink "
598             << qos_sink_key.c_str() << ", qos_source "
599             << qos_source_key.c_str();
600 
601   // Find the first qos config that match the name
602   const le_audio::QosConfiguration* qos_sink_cfg = nullptr;
603   for (auto i = qos_cfgs->begin(); i != qos_cfgs->end(); ++i) {
604     if ((*i)->name()->str() == qos_sink_key) {
605       qos_sink_cfg = *i;
606       break;
607     }
608   }
609 
610   const le_audio::QosConfiguration* qos_source_cfg = nullptr;
611   for (auto i = qos_cfgs->begin(); i != qos_cfgs->end(); ++i) {
612     if ((*i)->name()->str() == qos_source_key) {
613       qos_source_cfg = *i;
614       break;
615     }
616   }
617 
618   // First codec_cfg with the same name
619   const le_audio::CodecConfiguration* codec_cfg = nullptr;
620   for (auto i = codec_cfgs->begin(); i != codec_cfgs->end(); ++i) {
621     if ((*i)->name()->str() == codec_config_key) {
622       codec_cfg = *i;
623       break;
624     }
625   }
626 
627   // Process each subconfig and put it into the correct list
628   if (codec_cfg != nullptr && codec_cfg->subconfigurations()) {
629     /* Load subconfigurations */
630     for (auto subconfig : *codec_cfg->subconfigurations()) {
631       if (subconfig->direction() == kLeAudioDirectionSink) {
632         processSubconfig(flat_cfg->name()->str(), subconfig, qos_sink_cfg,
633                          sinkAseConfiguration, location);
634       } else {
635         processSubconfig(flat_cfg->name()->str(), subconfig, qos_source_cfg,
636                          sourceAseConfiguration, location);
637       }
638     }
639   } else {
640     if (codec_cfg == nullptr) {
641       LOG(ERROR) << "No codec config matching key " << codec_config_key.c_str()
642                  << " found";
643     } else {
644       LOG(ERROR) << "Configuration '" << flat_cfg->name()->c_str()
645                  << "' has no valid subconfigurations.";
646     }
647   }
648 
649   // TODO: Populate information for ConfigurationFlags
650 }
651 
LoadConfigurationsFromFiles(const char * schema_file,const char * content_file,CodecLocation location)652 bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles(
653     const char* schema_file, const char* content_file, CodecLocation location) {
654   flatbuffers::Parser configurations_parser_;
655   std::string configurations_schema_binary_content;
656   bool ok = flatbuffers::LoadFile(schema_file, true,
657                                   &configurations_schema_binary_content);
658   LOG(INFO) << __func__ << ": Loading file " << schema_file;
659   if (!ok) return ok;
660 
661   /* Load the binary schema */
662   ok = configurations_parser_.Deserialize(
663       (uint8_t*)configurations_schema_binary_content.c_str(),
664       configurations_schema_binary_content.length());
665   if (!ok) return ok;
666 
667   /* Load the content from JSON */
668   std::string configurations_json_content;
669   LOG(INFO) << __func__ << ": Loading file " << content_file;
670   ok = flatbuffers::LoadFile(content_file, false, &configurations_json_content);
671   if (!ok) return ok;
672 
673   /* Parse */
674   LOG(INFO) << __func__ << ": Parse JSON content";
675   ok = configurations_parser_.Parse(configurations_json_content.c_str());
676   if (!ok) return ok;
677 
678   /* Import from flatbuffers */
679   LOG(INFO) << __func__ << ": Build flat buffer structure";
680   auto configurations_root = le_audio::GetAudioSetConfigurations(
681       configurations_parser_.builder_.GetBufferPointer());
682   if (!configurations_root) return false;
683 
684   auto flat_qos_configs = configurations_root->qos_configurations();
685   if ((flat_qos_configs == nullptr) || (flat_qos_configs->size() == 0))
686     return false;
687 
688   LOG(DEBUG) << ": Updating " << flat_qos_configs->size()
689              << " qos config entries.";
690   std::vector<const le_audio::QosConfiguration*> qos_cfgs;
691   for (auto const& flat_qos_cfg : *flat_qos_configs) {
692     qos_cfgs.push_back(flat_qos_cfg);
693   }
694 
695   auto flat_codec_configs = configurations_root->codec_configurations();
696   if ((flat_codec_configs == nullptr) || (flat_codec_configs->size() == 0))
697     return false;
698 
699   LOG(DEBUG) << ": Updating " << flat_codec_configs->size()
700              << " codec config entries.";
701   std::vector<const le_audio::CodecConfiguration*> codec_cfgs;
702   for (auto const& flat_codec_cfg : *flat_codec_configs) {
703     codec_cfgs.push_back(flat_codec_cfg);
704   }
705 
706   auto flat_configs = configurations_root->configurations();
707   if ((flat_configs == nullptr) || (flat_configs->size() == 0)) return false;
708 
709   LOG(DEBUG) << ": Updating " << flat_configs->size() << " config entries.";
710   for (auto const& flat_cfg : *flat_configs) {
711     // Create 3 vector to use
712     std::vector<std::optional<AseDirectionConfiguration>>
713         sourceAseConfiguration;
714     std::vector<std::optional<AseDirectionConfiguration>> sinkAseConfiguration;
715     ConfigurationFlags configurationFlags;
716     PopulateAseConfigurationFromFlat(flat_cfg, &codec_cfgs, &qos_cfgs, location,
717                                      sourceAseConfiguration,
718                                      sinkAseConfiguration, configurationFlags);
719     if (sourceAseConfiguration.empty() && sinkAseConfiguration.empty())
720       continue;
721     configurations_[flat_cfg->name()->str()] = std::make_tuple(
722         sourceAseConfiguration, sinkAseConfiguration, configurationFlags);
723   }
724 
725   return true;
726 }
727 
LoadScenariosFromFiles(const char * schema_file,const char * content_file)728 bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles(
729     const char* schema_file, const char* content_file) {
730   flatbuffers::Parser scenarios_parser_;
731   std::string scenarios_schema_binary_content;
732   bool ok = flatbuffers::LoadFile(schema_file, true,
733                                   &scenarios_schema_binary_content);
734   LOG(INFO) << __func__ << ": Loading file " << schema_file;
735   if (!ok) return ok;
736 
737   /* Load the binary schema */
738   ok = scenarios_parser_.Deserialize(
739       (uint8_t*)scenarios_schema_binary_content.c_str(),
740       scenarios_schema_binary_content.length());
741   if (!ok) return ok;
742 
743   /* Load the content from JSON */
744   LOG(INFO) << __func__ << ": Loading file " << content_file;
745   std::string scenarios_json_content;
746   ok = flatbuffers::LoadFile(content_file, false, &scenarios_json_content);
747   if (!ok) return ok;
748 
749   /* Parse */
750   LOG(INFO) << __func__ << ": Parse json content";
751   ok = scenarios_parser_.Parse(scenarios_json_content.c_str());
752   if (!ok) return ok;
753 
754   /* Import from flatbuffers */
755   LOG(INFO) << __func__ << ": Build flat buffer structure";
756   auto scenarios_root = le_audio::GetAudioSetScenarios(
757       scenarios_parser_.builder_.GetBufferPointer());
758   if (!scenarios_root) return false;
759 
760   auto flat_scenarios = scenarios_root->scenarios();
761   if ((flat_scenarios == nullptr) || (flat_scenarios->size() == 0))
762     return false;
763 
764   LOG(INFO) << __func__ << ": Turn flat buffer into structure";
765   AudioContext media_context = AudioContext();
766   media_context.bitmask =
767       (AudioContext::ALERTS | AudioContext::INSTRUCTIONAL |
768        AudioContext::NOTIFICATIONS | AudioContext::EMERGENCY_ALARM |
769        AudioContext::UNSPECIFIED | AudioContext::MEDIA |
770        AudioContext::SOUND_EFFECTS);
771 
772   AudioContext conversational_context = AudioContext();
773   conversational_context.bitmask =
774       (AudioContext::RINGTONE_ALERTS | AudioContext::CONVERSATIONAL);
775 
776   AudioContext live_context = AudioContext();
777   live_context.bitmask = AudioContext::LIVE_AUDIO;
778 
779   AudioContext game_context = AudioContext();
780   game_context.bitmask = AudioContext::GAME;
781 
782   AudioContext voice_assistants_context = AudioContext();
783   voice_assistants_context.bitmask = AudioContext::VOICE_ASSISTANTS;
784 
785   LOG(DEBUG) << "Updating " << flat_scenarios->size() << " scenarios.";
786   for (auto const& scenario : *flat_scenarios) {
787     if (!scenario->configurations()) continue;
788     std::string scenario_name = scenario->name()->c_str();
789     AudioContext context;
790     if (scenario_name == "Media")
791       context = AudioContext(media_context);
792     else if (scenario_name == "Conversational")
793       context = AudioContext(conversational_context);
794     else if (scenario_name == "Live")
795       context = AudioContext(live_context);
796     else if (scenario_name == "Game")
797       context = AudioContext(game_context);
798     else if (scenario_name == "VoiceAssistants")
799       context = AudioContext(voice_assistants_context);
800     LOG(DEBUG) << "Scenario " << scenario->name()->c_str()
801                << " configs: " << scenario->configurations()->size()
802                << " context: " << context.toString();
803 
804     for (auto it = scenario->configurations()->begin();
805          it != scenario->configurations()->end(); ++it) {
806       auto config_name = it->str();
807       auto configuration = configurations_.find(config_name);
808       if (configuration == configurations_.end()) continue;
809       LOG(DEBUG) << "Getting configuration with name: " << config_name;
810       auto [source, sink, flags] = configuration->second;
811       // Each configuration will create a LeAudioAseConfigurationSetting
812       // with the same {context, packing}
813       // and different data
814       LeAudioAseConfigurationSetting setting;
815       setting.audioContext = context;
816       // TODO: Packing
817       setting.sourceAseConfiguration = source;
818       setting.sinkAseConfiguration = sink;
819       setting.flags = flags;
820       // Add to list of setting
821       LOG(DEBUG) << "Pushing configuration to list: " << config_name;
822       ase_configuration_settings_.push_back(setting);
823     }
824   }
825 
826   return true;
827 }
828 
LoadContent(std::vector<std::pair<const char *,const char * >> config_files,std::vector<std::pair<const char *,const char * >> scenario_files,CodecLocation location)829 bool AudioSetConfigurationProviderJson::LoadContent(
830     std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
831         config_files,
832     std::vector<std::pair<const char* /*schema*/, const char* /*content*/>>
833         scenario_files,
834     CodecLocation location) {
835   bool is_loaded_config = false;
836   for (auto [schema, content] : config_files) {
837     if (LoadConfigurationsFromFiles(schema, content, location)) {
838       is_loaded_config = true;
839       break;
840     }
841   }
842 
843   bool is_loaded_scenario = false;
844   for (auto [schema, content] : scenario_files) {
845     if (LoadScenariosFromFiles(schema, content)) {
846       is_loaded_scenario = true;
847       break;
848     }
849   }
850   return is_loaded_config && is_loaded_scenario;
851 }
852 
853 }  // namespace audio
854 }  // namespace bluetooth
855 }  // namespace hardware
856 }  // namespace android
857 }  // namespace aidl
858