1 /*
2  * Copyright 2020 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
3  * www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /*
19  * This file contains definitions for Basic Audio Profile / Audio Stream Control
20  * and Published Audio Capabilities definitions, structures etc.
21  */
22 
23 #include "le_audio_types.h"
24 
25 #include <base/strings/string_number_conversions.h>
26 #include <bluetooth/log.h>
27 
28 #include "audio_hal_client/audio_hal_client.h"
29 #include "common/strings.h"
30 #include "internal_include/bt_trace.h"
31 #include "le_audio_utils.h"
32 #include "stack/include/bt_types.h"
33 
34 namespace bluetooth::le_audio {
35 using types::acs_ac_record;
36 using types::LeAudioContextType;
37 
38 namespace set_configurations {
39 using set_configurations::CodecConfigSetting;
40 using types::CodecLocation;
41 using types::kLeAudioCodingFormatLC3;
42 using types::kLeAudioDirectionSink;
43 using types::kLeAudioDirectionSource;
44 using types::LeAudioCoreCodecConfig;
45 
get_cis_count(LeAudioContextType context_type,int expected_device_cnt,types::LeAudioConfigurationStrategy strategy,int avail_group_ase_snk_cnt,int avail_group_ase_src_count,uint8_t & out_cis_count_bidir,uint8_t & out_cis_count_unidir_sink,uint8_t & out_cis_count_unidir_source)46 void get_cis_count(LeAudioContextType context_type, int expected_device_cnt,
47                    types::LeAudioConfigurationStrategy strategy,
48                    int avail_group_ase_snk_cnt, int avail_group_ase_src_count,
49                    uint8_t& out_cis_count_bidir,
50                    uint8_t& out_cis_count_unidir_sink,
51                    uint8_t& out_cis_count_unidir_source) {
52   log::info(
53       "{} strategy {}, group avail sink ases: {}, group avail source ases {} "
54       "expected_device_count {}",
55       bluetooth::common::ToString(context_type), static_cast<int>(strategy),
56       avail_group_ase_snk_cnt, avail_group_ase_src_count, expected_device_cnt);
57 
58   bool is_bidirectional = types::kLeAudioContextAllBidir.test(context_type);
59 
60   switch (strategy) {
61     case types::LeAudioConfigurationStrategy::MONO_ONE_CIS_PER_DEVICE:
62     /* This strategy is for the CSIS topology, e.g. two earbuds which are both
63      * connected with a Phone
64      */
65     case types::LeAudioConfigurationStrategy::STEREO_ONE_CIS_PER_DEVICE:
66       /* This strategy is for e.g. the banded headphones */
67       if (is_bidirectional) {
68         if ((avail_group_ase_snk_cnt > 0) && (avail_group_ase_src_count) > 0) {
69           /* Prepare CIG to enable all microphones */
70           out_cis_count_bidir = expected_device_cnt;
71         } else {
72           if (avail_group_ase_snk_cnt > 0) {
73             out_cis_count_unidir_sink = expected_device_cnt;
74           } else if (avail_group_ase_src_count > 0) {
75             out_cis_count_unidir_source = expected_device_cnt;
76           }
77         }
78       } else {
79         out_cis_count_unidir_sink = expected_device_cnt;
80       }
81 
82       break;
83     case types::LeAudioConfigurationStrategy::STEREO_TWO_CISES_PER_DEVICE:
84       /* This strategy is for the old TWS topology. e.g. one earbud connected to
85        * the Phone but each channel is carried in separate CIS
86        */
87       if (is_bidirectional) {
88         if ((avail_group_ase_snk_cnt > 0) && (avail_group_ase_src_count) > 0) {
89           /* Prepare CIG to enable all microphones per device */
90           /* TODO: Support TWS style device with two source ASEs - two
91            * bidirectional CISes
92            */
93           out_cis_count_bidir = expected_device_cnt;
94           out_cis_count_unidir_sink = expected_device_cnt;
95         } else {
96           if (avail_group_ase_snk_cnt > 0) {
97             out_cis_count_unidir_sink = 2 * expected_device_cnt;
98           } else if (avail_group_ase_src_count > 0) {
99             out_cis_count_unidir_source = 2 * expected_device_cnt;
100           }
101         }
102       } else {
103         out_cis_count_unidir_sink = 2 * expected_device_cnt;
104       }
105       break;
106     case types::LeAudioConfigurationStrategy::RFU:
107       log::error("Should not happen;");
108       break;
109   }
110 
111   log::info(
112       "Required cis count: Bi-Directional: {}, Uni-Directional Sink: {}, "
113       "Uni-Directional Source: {}",
114       out_cis_count_bidir, out_cis_count_unidir_sink,
115       out_cis_count_unidir_source);
116 }
117 
GetOctectsPerFrame() const118 uint16_t CodecConfigSetting::GetOctectsPerFrame() const {
119   switch (id.coding_format) {
120     case kLeAudioCodingFormatLC3:
121       return params.GetAsCoreCodecConfig().GetOctectsPerFrame();
122     default:
123       log::warn(", invalid codec id: 0x{:02x}", id.coding_format);
124       return 0;
125   }
126 };
127 
GetSamplingFrequencyHz() const128 uint32_t CodecConfigSetting::GetSamplingFrequencyHz() const {
129   // We also mandate the sampling frequency parameter for vendor spec. codecs
130   return params.GetAsCoreCodecConfig().GetSamplingFrequencyHz();
131 };
132 
GetDataIntervalUs() const133 uint32_t CodecConfigSetting::GetDataIntervalUs() const {
134   switch (id.coding_format) {
135     case kLeAudioCodingFormatLC3:
136       return params.GetAsCoreCodecConfig().GetFrameDurationUs();
137     default:
138       log::warn(", invalid codec id: 0x{:02x}", id.coding_format);
139       return 0;
140   }
141 };
142 
GetBitsPerSample() const143 uint8_t CodecConfigSetting::GetBitsPerSample() const {
144   switch (id.coding_format) {
145     case kLeAudioCodingFormatLC3:
146       /* XXX LC3 supports 16, 24, 32 */
147       return 16;
148     default:
149       log::warn(", invalid codec id: 0x{:02x}", id.coding_format);
150       return 0;
151   }
152 };
153 
operator <<(std::ostream & os,const QosConfigSetting & config)154 std::ostream& operator<<(std::ostream& os, const QosConfigSetting& config) {
155   os << "QosConfigSetting{";
156   os << "targetLatency: " << (int)config.target_latency;
157   os << ", retransmissionNum: " << (int)config.retransmission_number;
158   os << ", maxTransportLatency: " << (int)config.max_transport_latency;
159   os << ", sduIntervalUs: " << (int)config.sduIntervalUs;
160   os << ", maxSdu: " << (int)config.maxSdu;
161   os << "}";
162   return os;
163 }
164 
operator <<(std::ostream & os,const AseConfiguration & config)165 std::ostream& operator<<(std::ostream& os, const AseConfiguration& config) {
166   os << "AseConfiguration{";
167   os << "dataPath: " << config.data_path_configuration;
168   os << ", codec: " << config.codec;
169   os << ", qos: " << config.qos;
170   os << "}";
171   return os;
172 }
173 
operator <<(std::ostream & os,const AudioSetConfiguration & config)174 std::ostream& operator<<(std::ostream& os,
175                          const AudioSetConfiguration& config) {
176   os << "AudioSetConfiguration{";
177   os << "name: " << config.name;
178   os << ", packing: " << (int)config.packing;
179   os << ", sinkConfs: [";
180   for (auto const& conf : config.confs.sink) {
181     os << conf;
182     os << ", ";
183   }
184   os << "], sourceConfs: [";
185   for (auto const& conf : config.confs.source) {
186     os << conf;
187     os << ", ";
188   }
189   os << "]}";
190   return os;
191 }
192 
operator <<(std::ostream & os,const CodecConfigSetting & config)193 std::ostream& operator<<(std::ostream& os, const CodecConfigSetting& config) {
194   os << "CodecConfigSetting{";
195   os << ", id: " << config.id;
196   os << ", codecSpecParams: " << config.params.GetAsCoreCodecConfig();
197   os << ", bitsPerSample: " << (int)config.GetBitsPerSample();
198   os << ", channelCountPerIsoStream: "
199      << (int)config.GetChannelCountPerIsoStream();
200   if (!config.vendor_params.empty()) {
201     os << ", vendorParams: "
202        << base::HexEncode(config.vendor_params.data(),
203                           config.vendor_params.size());
204   }
205   os << "}";
206   return os;
207 }
208 
209 }  // namespace set_configurations
210 
211 namespace types {
212 /* Helper map for matching various frequency notations */
213 const std::map<uint8_t, uint32_t> LeAudioCoreCodecConfig::sampling_freq_map = {
214     {codec_spec_conf::kLeAudioSamplingFreq8000Hz,
215      LeAudioCodecConfiguration::kSampleRate8000},
216     {codec_spec_conf::kLeAudioSamplingFreq16000Hz,
217      LeAudioCodecConfiguration::kSampleRate16000},
218     {codec_spec_conf::kLeAudioSamplingFreq24000Hz,
219      LeAudioCodecConfiguration::kSampleRate24000},
220     {codec_spec_conf::kLeAudioSamplingFreq32000Hz,
221      LeAudioCodecConfiguration::kSampleRate32000},
222     {codec_spec_conf::kLeAudioSamplingFreq44100Hz,
223      LeAudioCodecConfiguration::kSampleRate44100},
224     {codec_spec_conf::kLeAudioSamplingFreq48000Hz,
225      LeAudioCodecConfiguration::kSampleRate48000}};
226 
227 /* Helper map for matching various frequency notations */
228 const std::map<uint32_t, uint8_t> LeAudioCoreCodecConfig::sample_rate_map = {
229     {LeAudioCodecConfiguration::kSampleRate8000,
230      codec_spec_conf::kLeAudioSamplingFreq8000Hz},
231     {LeAudioCodecConfiguration::kSampleRate16000,
232      codec_spec_conf::kLeAudioSamplingFreq16000Hz},
233     {LeAudioCodecConfiguration::kSampleRate24000,
234      codec_spec_conf::kLeAudioSamplingFreq24000Hz},
235     {LeAudioCodecConfiguration::kSampleRate32000,
236      codec_spec_conf::kLeAudioSamplingFreq32000Hz},
237     {LeAudioCodecConfiguration::kSampleRate44100,
238      codec_spec_conf::kLeAudioSamplingFreq44100Hz},
239     {LeAudioCodecConfiguration::kSampleRate48000,
240      codec_spec_conf::kLeAudioSamplingFreq48000Hz},
241 };
242 
243 /* Helper map for matching various frame durations notations */
244 const std::map<uint8_t, uint32_t> LeAudioCoreCodecConfig::frame_duration_map = {
245     {codec_spec_conf::kLeAudioCodecFrameDur7500us,
246      LeAudioCodecConfiguration::kInterval7500Us},
247     {codec_spec_conf::kLeAudioCodecFrameDur10000us,
248      LeAudioCodecConfiguration::kInterval10000Us}};
249 
250 /* Helper map for matching various frame durations notations */
251 const std::map<uint32_t, uint8_t> LeAudioCoreCodecConfig::data_interval_map = {
252     {LeAudioCodecConfiguration::kInterval7500Us,
253      codec_spec_conf::kLeAudioCodecFrameDur7500us},
254     {LeAudioCodecConfiguration::kInterval10000Us,
255      codec_spec_conf::kLeAudioCodecFrameDur10000us},
256 };
257 
CapabilityTypeToStr(const uint8_t & type)258 std::string CapabilityTypeToStr(const uint8_t& type) {
259   switch (type) {
260     case codec_spec_caps::kLeAudioLtvTypeSupportedSamplingFrequencies:
261       return "Supported Sampling Frequencies";
262     case codec_spec_caps::kLeAudioLtvTypeSupportedFrameDurations:
263       return "Supported Frame Durations";
264     case codec_spec_caps::kLeAudioLtvTypeSupportedAudioChannelCounts:
265       return "Supported Audio Channel Count";
266     case codec_spec_caps::kLeAudioLtvTypeSupportedOctetsPerCodecFrame:
267       return "Supported Octets Per Codec Frame";
268     case codec_spec_caps::kLeAudioLtvTypeSupportedMaxCodecFramesPerSdu:
269       return "Supported Max Codec Frames Per SDU";
270     default:
271       return "Unknown";
272   }
273 }
274 
CapabilityValueToStr(const uint8_t & type,const std::vector<uint8_t> & value)275 std::string CapabilityValueToStr(const uint8_t& type,
276                                  const std::vector<uint8_t>& value) {
277   std::string string = "";
278 
279   switch (type) {
280     case codec_spec_conf::kLeAudioLtvTypeSamplingFreq: {
281       if (value.size() != 2) {
282         return "Invalid size";
283       }
284 
285       uint16_t u16_val = VEC_UINT8_TO_UINT16(value);
286 
287       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq8000Hz) {
288         string += "8";
289       }
290       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq11025Hz) {
291         string += std::string((string.empty() ? "" : "|")) + "11.025";
292       }
293       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq16000Hz) {
294         string += std::string((string.empty() ? "" : "|")) + "16";
295       }
296       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq22050Hz) {
297         string += std::string((string.empty() ? "" : "|")) + "22.050";
298       }
299       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq24000Hz) {
300         string += std::string((string.empty() ? "" : "|")) + "24";
301       }
302       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq32000Hz) {
303         string += std::string((string.empty() ? "" : "|")) + "32";
304       }
305       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq44100Hz) {
306         string += std::string((string.empty() ? "" : "|")) + "44.1";
307       }
308       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq48000Hz) {
309         string += std::string((string.empty() ? "" : "|")) + "48";
310       }
311       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq88200Hz) {
312         string += std::string((string.empty() ? "" : "|")) + "88.2";
313       }
314       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq96000Hz) {
315         string += std::string((string.empty() ? "" : "|")) + "96";
316       }
317       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq176400Hz) {
318         string += std::string((string.empty() ? "" : "|")) + "176.4";
319       }
320       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq192000Hz) {
321         string += std::string((string.empty() ? "" : "|")) + "192";
322       }
323       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq384000Hz) {
324         string += std::string((string.empty() ? "" : "|")) + "384";
325       }
326 
327       return string += " [kHz]\n";
328     }
329     case codec_spec_conf::kLeAudioLtvTypeFrameDuration: {
330       if (value.size() != 1) {
331         return "Invalid size";
332       }
333 
334       uint8_t u8_val = VEC_UINT8_TO_UINT8(value);
335 
336       if (u8_val & codec_spec_caps::kLeAudioCodecFrameDur7500us) {
337         string += "7.5";
338       }
339       if (u8_val & codec_spec_caps::kLeAudioCodecFrameDur10000us) {
340         string += std::string((string.empty() ? "" : "|")) + "10";
341       }
342       if (u8_val & codec_spec_caps::kLeAudioCodecFrameDurPrefer7500us) {
343         string += std::string((string.empty() ? "" : "|")) + "7.5 preferred";
344       }
345       if (u8_val & codec_spec_caps::kLeAudioCodecFrameDurPrefer10000us) {
346         string += std::string((string.empty() ? "" : "|")) + "10 preferred";
347       }
348 
349       return string += " [ms]\n";
350     }
351     case codec_spec_conf::kLeAudioLtvTypeAudioChannelAllocation: {
352       if (value.size() != 1) {
353         return "Invalid size";
354       }
355 
356       uint8_t u8_val = VEC_UINT8_TO_UINT8(value);
357 
358       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountNone) {
359         string += "0";
360       }
361       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountSingleChannel) {
362         string += std::string((string.empty() ? "" : "|")) + "1";
363       }
364       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountTwoChannel) {
365         string += std::string((string.empty() ? "" : "|")) + "2";
366       }
367       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountThreeChannel) {
368         string += std::string((string.empty() ? "" : "|")) + "3";
369       }
370       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountFourChannel) {
371         string += std::string((string.empty() ? "" : "|")) + "4";
372       }
373       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountFiveChannel) {
374         string += std::string((string.empty() ? "" : "|")) + "5";
375       }
376       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountSixChannel) {
377         string += std::string((string.empty() ? "" : "|")) + "6";
378       }
379       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountSevenChannel) {
380         string += std::string((string.empty() ? "" : "|")) + "7";
381       }
382       if (u8_val & codec_spec_caps::kLeAudioCodecChannelCountEightChannel) {
383         string += std::string((string.empty() ? "" : "|")) + "8";
384       }
385 
386       return string += " channel/s\n";
387     }
388     case codec_spec_conf::kLeAudioLtvTypeOctetsPerCodecFrame: {
389       if (value.size() != 4) {
390         return "Invalid size";
391       }
392 
393       uint16_t u16_min_number_of_octets = VEC_UINT8_TO_UINT16(value);
394       uint16_t u16_max_number_of_octets =
395           OFF_VEC_UINT8_TO_UINT16(value, sizeof(u16_min_number_of_octets));
396 
397       string += "Minimum: " + std::to_string(u16_min_number_of_octets);
398       string += ", Maximum: " + std::to_string(u16_max_number_of_octets) + "\n";
399 
400       return string;
401     }
402     case codec_spec_conf::kLeAudioLtvTypeCodecFrameBlocksPerSdu: {
403       if (value.size() != 1) {
404         return "Invalid size";
405       }
406 
407       uint8_t u8_val = VEC_UINT8_TO_UINT8(value);
408 
409       string += std::to_string(u8_val) + " frame/s\n";
410 
411       return string;
412     }
413     default:
414       return base::HexEncode(value.data(), value.size()) + "\n";
415   }
416 }
417 
CodecCapabilitiesLtvFormat(const uint8_t & type,const std::vector<uint8_t> & value)418 std::string CodecCapabilitiesLtvFormat(const uint8_t& type,
419                                        const std::vector<uint8_t>& value) {
420   std::string string = "";
421 
422   string += CapabilityTypeToStr(type) + ": ";
423   string += CapabilityValueToStr(type, value);
424 
425   return string;
426 }
427 
Find(uint8_t type) const428 std::optional<std::vector<uint8_t>> LeAudioLtvMap::Find(uint8_t type) const {
429   auto iter =
430       std::find_if(values.cbegin(), values.cend(),
431                    [type](const auto& value) { return value.first == type; });
432 
433   if (iter == values.cend()) return std::nullopt;
434 
435   return iter->second;
436 }
437 
RawPacket(uint8_t * p_buf) const438 uint8_t* LeAudioLtvMap::RawPacket(uint8_t* p_buf) const {
439   for (auto const& value : values) {
440     UINT8_TO_STREAM(p_buf, value.second.size() + 1);
441     UINT8_TO_STREAM(p_buf, value.first);
442     ARRAY_TO_STREAM(p_buf, value.second.data(),
443                     static_cast<int>(value.second.size()));
444   }
445 
446   return p_buf;
447 }
448 
RawPacket() const449 std::vector<uint8_t> LeAudioLtvMap::RawPacket() const {
450   std::vector<uint8_t> data(RawPacketSize());
451   RawPacket(data.data());
452   return data;
453 }
454 
Append(const LeAudioLtvMap & other)455 void LeAudioLtvMap::Append(const LeAudioLtvMap& other) {
456   /* This will override values for the already existing keys */
457   for (auto& el : other.values) {
458     values[el.first] = el.second;
459   }
460 
461   invalidate();
462 }
463 
Parse(const uint8_t * p_value,uint8_t len,bool & success)464 LeAudioLtvMap LeAudioLtvMap::Parse(const uint8_t* p_value, uint8_t len,
465                                    bool& success) {
466   LeAudioLtvMap ltv_map;
467   success = ltv_map.Parse(p_value, len);
468   if (!success) {
469     log::error("Error parsing LTV map");
470   }
471   return ltv_map;
472 }
473 
Parse(const uint8_t * p_value,uint8_t len)474 bool LeAudioLtvMap::Parse(const uint8_t* p_value, uint8_t len) {
475   if (len > 0) {
476     const auto p_value_end = p_value + len;
477 
478     while ((p_value_end - p_value) > 0) {
479       uint8_t ltv_len;
480       STREAM_TO_UINT8(ltv_len, p_value);
481 
482       // Unusual, but possible case
483       if (ltv_len == 0) continue;
484 
485       if (p_value_end < (p_value + ltv_len)) {
486         log::error("Invalid ltv_len: {}", static_cast<int>(ltv_len));
487         invalidate();
488         return false;
489       }
490 
491       uint8_t ltv_type;
492       STREAM_TO_UINT8(ltv_type, p_value);
493       ltv_len -= sizeof(ltv_type);
494 
495       const auto p_temp = p_value;
496       p_value += ltv_len;
497 
498       std::vector<uint8_t> ltv_value(p_temp, p_value);
499       values.emplace(ltv_type, std::move(ltv_value));
500     }
501   }
502   invalidate();
503 
504   return true;
505 }
506 
RawPacketSize() const507 size_t LeAudioLtvMap::RawPacketSize() const {
508   size_t bytes = 0;
509 
510   for (auto const& value : values) {
511     bytes += (/* ltv_len + ltv_type */ 2 + value.second.size());
512   }
513 
514   return bytes;
515 }
516 
ToString(const std::string & indent_string,std::string (* format)(const uint8_t &,const std::vector<uint8_t> &)) const517 std::string LeAudioLtvMap::ToString(
518     const std::string& indent_string,
519     std::string (*format)(const uint8_t&, const std::vector<uint8_t>&)) const {
520   std::string debug_str;
521 
522   for (const auto& value : values) {
523     std::stringstream sstream;
524 
525     if (format == nullptr) {
526       sstream << indent_string + "type: " << std::to_string(value.first)
527               << "\tlen: " << std::to_string(value.second.size()) << "\tdata: "
528               << base::HexEncode(value.second.data(), value.second.size()) +
529                      "\n";
530     } else {
531       sstream << indent_string + format(value.first, value.second);
532     }
533 
534     debug_str += sstream.str();
535   }
536 
537   return debug_str;
538 }
539 
GetAsCoreCodecConfig() const540 const struct LeAudioCoreCodecConfig& LeAudioLtvMap::GetAsCoreCodecConfig()
541     const {
542   log::assert_that(!core_capabilities,
543                    "LTVs were already parsed for capabilities!");
544   log::assert_that(!metadata, "LTVs were already parsed for metadata!");
545 
546   if (!core_config) {
547     core_config = LtvMapToCoreCodecConfig(*this);
548   }
549   return *core_config;
550 }
551 
552 const struct LeAudioCoreCodecCapabilities&
GetAsCoreCodecCapabilities() const553 LeAudioLtvMap::GetAsCoreCodecCapabilities() const {
554   log::assert_that(!core_config,
555                    "LTVs were already parsed for configurations!");
556   log::assert_that(!metadata, "LTVs were already parsed for metadata!");
557 
558   if (!core_capabilities) {
559     core_capabilities = LtvMapToCoreCodecCapabilities(*this);
560   }
561   return *core_capabilities;
562 }
563 
GetAsLeAudioMetadata() const564 const struct LeAudioMetadata& LeAudioLtvMap::GetAsLeAudioMetadata() const {
565   log::assert_that(!core_config,
566                    "LTVs were already parsed for configurations!");
567   log::assert_that(!core_capabilities,
568                    "LTVs were already parsed for capabilities!");
569 
570   if (!metadata) {
571     metadata = LtvMapToMetadata(*this);
572   }
573   return *metadata;
574 }
575 
RemoveAllTypes(const LeAudioLtvMap & other)576 void LeAudioLtvMap::RemoveAllTypes(const LeAudioLtvMap& other) {
577   for (auto const& [key, _] : other.values) {
578     Remove(key);
579   }
580 }
581 
GetIntersection(const LeAudioLtvMap & other) const582 LeAudioLtvMap LeAudioLtvMap::GetIntersection(const LeAudioLtvMap& other) const {
583   LeAudioLtvMap result;
584   for (auto const& [key, value] : values) {
585     auto entry = other.Find(key);
586     if (entry->size() != value.size()) continue;
587     if (memcmp(entry->data(), value.data(), value.size()) == 0) {
588       result.Add(key, value);
589     }
590   }
591   return result;
592 }
593 
594 }  // namespace types
595 
AppendMetadataLtvEntryForCcidList(std::vector<uint8_t> & metadata,const std::vector<uint8_t> & ccid_list)596 void AppendMetadataLtvEntryForCcidList(std::vector<uint8_t>& metadata,
597                                        const std::vector<uint8_t>& ccid_list) {
598   if (ccid_list.size() == 0) {
599     log::warn("Empty CCID list.");
600     return;
601   }
602 
603   metadata.push_back(
604       static_cast<uint8_t>(types::kLeAudioMetadataTypeLen + ccid_list.size()));
605   metadata.push_back(static_cast<uint8_t>(types::kLeAudioMetadataTypeCcidList));
606 
607   metadata.insert(metadata.end(), ccid_list.begin(), ccid_list.end());
608 }
609 
AppendMetadataLtvEntryForStreamingContext(std::vector<uint8_t> & metadata,types::AudioContexts context_type)610 void AppendMetadataLtvEntryForStreamingContext(
611     std::vector<uint8_t>& metadata, types::AudioContexts context_type) {
612   std::vector<uint8_t> streaming_context_ltv_entry;
613 
614   streaming_context_ltv_entry.resize(
615       types::kLeAudioMetadataTypeLen + types::kLeAudioMetadataLenLen +
616       types::kLeAudioMetadataStreamingAudioContextLen);
617   uint8_t* streaming_context_ltv_entry_buf = streaming_context_ltv_entry.data();
618 
619   UINT8_TO_STREAM(streaming_context_ltv_entry_buf,
620                   types::kLeAudioMetadataTypeLen +
621                       types::kLeAudioMetadataStreamingAudioContextLen);
622   UINT8_TO_STREAM(streaming_context_ltv_entry_buf,
623                   types::kLeAudioMetadataTypeStreamingAudioContext);
624   UINT16_TO_STREAM(streaming_context_ltv_entry_buf, context_type.value());
625 
626   metadata.insert(metadata.end(), streaming_context_ltv_entry.begin(),
627                   streaming_context_ltv_entry.end());
628 }
629 
GetMaxCodecFramesPerSduFromPac(const acs_ac_record * pac)630 uint8_t GetMaxCodecFramesPerSduFromPac(const acs_ac_record* pac) {
631   if (utils::IsCodecUsingLtvFormat(pac->codec_id)) {
632     auto tlv_ent = pac->codec_spec_caps.Find(
633         codec_spec_caps::kLeAudioLtvTypeSupportedMaxCodecFramesPerSdu);
634 
635     if (tlv_ent) return VEC_UINT8_TO_UINT8(tlv_ent.value());
636   }
637 
638   return 1;
639 }
640 
641 namespace types {
operator <<(std::ostream & os,const CisState & state)642 std::ostream& operator<<(std::ostream& os, const CisState& state) {
643   static const char* char_value_[5] = {"IDLE", "ASSIGNED", "CONNECTING",
644                                        "CONNECTED", "DISCONNECTING"};
645 
646   os << char_value_[static_cast<uint8_t>(state)] << " ("
647      << "0x" << std::setfill('0') << std::setw(2) << static_cast<int>(state)
648      << ")";
649   return os;
650 }
operator <<(std::ostream & os,const DataPathState & state)651 std::ostream& operator<<(std::ostream& os, const DataPathState& state) {
652   static const char* char_value_[4] = {"IDLE", "CONFIGURING", "CONFIGURED",
653                                        "REMOVING"};
654 
655   os << char_value_[static_cast<uint8_t>(state)] << " ("
656      << "0x" << std::setfill('0') << std::setw(2) << static_cast<int>(state)
657      << ")";
658   return os;
659 }
operator <<(std::ostream & os,const types::CigState & state)660 std::ostream& operator<<(std::ostream& os, const types::CigState& state) {
661   static const char* char_value_[5] = {"NONE", "CREATING", "CREATED",
662                                        "REMOVING", "RECOVERING"};
663 
664   os << char_value_[static_cast<uint8_t>(state)] << " ("
665      << "0x" << std::setfill('0') << std::setw(2) << static_cast<int>(state)
666      << ")";
667   return os;
668 }
operator <<(std::ostream & os,const types::AseState & state)669 std::ostream& operator<<(std::ostream& os, const types::AseState& state) {
670   static const char* char_value_[7] = {
671       "IDLE",      "CODEC_CONFIGURED", "QOS_CONFIGURED", "ENABLING",
672       "STREAMING", "DISABLING",        "RELEASING",
673   };
674 
675   os << char_value_[static_cast<uint8_t>(state)] << " ("
676      << "0x" << std::setfill('0') << std::setw(2) << static_cast<int>(state)
677      << ")";
678   return os;
679 }
680 
operator <<(std::ostream & os,const LeAudioCodecId & codec_id)681 std::ostream& operator<<(std::ostream& os, const LeAudioCodecId& codec_id) {
682   os << "LeAudioCodecId{CodingFormat: " << loghex(codec_id.coding_format)
683      << ", CompanyId: " << loghex(codec_id.vendor_company_id)
684      << ", CodecId: " << loghex(codec_id.vendor_codec_id) << "}";
685   return os;
686 }
687 
operator <<(std::ostream & os,const types::LeAudioCoreCodecConfig & config)688 std::ostream& operator<<(std::ostream& os,
689                          const types::LeAudioCoreCodecConfig& config) {
690   os << "LeAudioCoreCodecConfig{SamplFreq: "
691      << loghex(*config.sampling_frequency)
692      << ", FrameDur: " << loghex(*config.frame_duration)
693      << ", OctetsPerFrame: " << int(*config.octets_per_codec_frame)
694      << ", CodecFramesBlocksPerSDU: "
695      << int(*config.codec_frames_blocks_per_sdu)
696      << ", AudioChanLoc: " << loghex(*config.audio_channel_allocation) << "}";
697   return os;
698 }
699 
contextTypeToStr(const LeAudioContextType & context)700 std::string contextTypeToStr(const LeAudioContextType& context) {
701   switch (context) {
702     case LeAudioContextType::UNINITIALIZED:
703       return "UNINITIALIZED";
704     case LeAudioContextType::UNSPECIFIED:
705       return "UNSPECIFIED";
706     case LeAudioContextType::CONVERSATIONAL:
707       return "CONVERSATIONAL";
708     case LeAudioContextType::MEDIA:
709       return "MEDIA";
710     case LeAudioContextType::GAME:
711       return "GAME";
712     case LeAudioContextType::INSTRUCTIONAL:
713       return "INSTRUCTIONAL";
714     case LeAudioContextType::VOICEASSISTANTS:
715       return "VOICEASSISTANTS";
716     case LeAudioContextType::LIVE:
717       return "LIVE";
718     case LeAudioContextType::SOUNDEFFECTS:
719       return "SOUNDEFFECTS";
720     case LeAudioContextType::NOTIFICATIONS:
721       return "NOTIFICATIONS";
722     case LeAudioContextType::RINGTONE:
723       return "RINGTONE";
724     case LeAudioContextType::ALERTS:
725       return "ALERTS";
726     case LeAudioContextType::EMERGENCYALARM:
727       return "EMERGENCYALARM";
728     default:
729       return "UNKNOWN";
730   }
731 }
732 
operator <<(std::ostream & os,const LeAudioContextType & context)733 std::ostream& operator<<(std::ostream& os, const LeAudioContextType& context) {
734   os << contextTypeToStr(context);
735   return os;
736 }
737 
operator |(std::underlying_type<LeAudioContextType>::type lhs,const LeAudioContextType rhs)738 AudioContexts operator|(std::underlying_type<LeAudioContextType>::type lhs,
739                         const LeAudioContextType rhs) {
740   using T = std::underlying_type<LeAudioContextType>::type;
741   return AudioContexts(lhs | static_cast<T>(rhs));
742 }
743 
operator |=(AudioContexts & lhs,AudioContexts const & rhs)744 AudioContexts& operator|=(AudioContexts& lhs, AudioContexts const& rhs) {
745   lhs = AudioContexts(lhs.value() | rhs.value());
746   return lhs;
747 }
748 
operator &=(AudioContexts & lhs,AudioContexts const & rhs)749 AudioContexts& operator&=(AudioContexts& lhs, AudioContexts const& rhs) {
750   lhs = AudioContexts(lhs.value() & rhs.value());
751   return lhs;
752 }
753 
ToHexString(const LeAudioContextType & value)754 std::string ToHexString(const LeAudioContextType& value) {
755   using T = std::underlying_type<LeAudioContextType>::type;
756   return bluetooth::common::ToHexString(static_cast<T>(value));
757 }
758 
to_string() const759 std::string AudioContexts::to_string() const {
760   std::stringstream s;
761   for (auto ctx : bluetooth::le_audio::types::kLeAudioContextAllTypesArray) {
762     if (test(ctx)) {
763       if (s.tellp() != 0) s << " | ";
764       s << ctx;
765     }
766   }
767   s << " (" << bluetooth::common::ToHexString(mValue) << ")";
768   return s.str();
769 }
770 
operator <<(std::ostream & os,const AudioContexts & contexts)771 std::ostream& operator<<(std::ostream& os, const AudioContexts& contexts) {
772   os << contexts.to_string();
773   return os;
774 }
775 
776 template <typename T>
get(uint8_t direction) const777 const T& BidirectionalPair<T>::get(uint8_t direction) const {
778   log::assert_that(direction < types::kLeAudioDirectionBoth,
779                    "Unsupported complex direction. Consider using "
780                    "get_bidirectional<>() instead.");
781   return (direction == types::kLeAudioDirectionSink) ? sink : source;
782 }
783 
784 template <typename T>
get(uint8_t direction)785 T& BidirectionalPair<T>::get(uint8_t direction) {
786   log::assert_that(direction < types::kLeAudioDirectionBoth,
787                    "Unsupported complex direction. Reference to a single "
788                    "complex direction value is not supported.");
789   return (direction == types::kLeAudioDirectionSink) ? sink : source;
790 }
791 
792 /* Bidirectional getter trait for AudioContexts bidirectional pair */
793 template <>
get_bidirectional(BidirectionalPair<AudioContexts> p)794 AudioContexts get_bidirectional(BidirectionalPair<AudioContexts> p) {
795   return p.sink | p.source;
796 }
797 
798 template <>
get_bidirectional(BidirectionalPair<std::vector<uint8_t>> bidir)799 std::vector<uint8_t> get_bidirectional(
800     BidirectionalPair<std::vector<uint8_t>> bidir) {
801   std::vector<uint8_t> res = bidir.sink;
802   res.insert(std::end(res), std::begin(bidir.source), std::end(bidir.source));
803   return res;
804 }
805 
806 template <>
get_bidirectional(BidirectionalPair<AudioLocations> bidir)807 AudioLocations get_bidirectional(BidirectionalPair<AudioLocations> bidir) {
808   return bidir.sink | bidir.source;
809 }
810 
operator <<(std::ostream & os,const le_audio::types::IsoDataPathConfiguration & config)811 std::ostream& operator<<(
812     std::ostream& os, const le_audio::types::IsoDataPathConfiguration& config) {
813   os << "IsoDataPathCfg{codecId: " << config.codecId
814      << ", isTransparent: " << config.isTransparent
815      << ", controllerDelayUs: " << config.controllerDelayUs
816      << ", configuration.size: " << config.configuration.size() << "}";
817   return os;
818 }
819 
operator <<(std::ostream & os,const le_audio::types::DataPathConfiguration & config)820 std::ostream& operator<<(std::ostream& os,
821                          const le_audio::types::DataPathConfiguration& config) {
822   os << "DataPathCfg{datapathId: " << +config.dataPathId
823      << ", dataPathCfg.size: " << +config.dataPathConfig.size()
824      << ", isoDataPathCfg: " << config.isoDataPathConfig << "}";
825   return os;
826 }
827 
operator <<(std::ostream & os,const LeAudioMetadata & config)828 std::ostream& operator<<(std::ostream& os, const LeAudioMetadata& config) {
829   os << "LeAudioMetadata{";
830   if (config.preferred_audio_context) {
831     os << "preferred_audio_context: ";
832     os << AudioContexts(config.preferred_audio_context.value());
833   }
834   if (config.streaming_audio_context) {
835     os << ", streaming_audio_context: ";
836     os << AudioContexts(config.streaming_audio_context.value());
837   }
838   if (config.program_info) {
839     os << ", program_info: ";
840     os << config.program_info.value();
841   }
842   if (config.language) {
843     os << ", language: ";
844     os << config.language.value();
845   }
846   if (config.ccid_list) {
847     os << ", ccid_list: ";
848     os << base::HexEncode(config.ccid_list.value().data(),
849                           config.ccid_list.value().size());
850   }
851   if (config.parental_rating) {
852     os << ", parental_rating: ";
853     os << (int)config.parental_rating.value();
854   }
855   if (config.program_info_uri) {
856     os << ", program_info_uri: ";
857     os << config.program_info_uri.value();
858   }
859   if (config.extended_metadata) {
860     os << ", extended_metadata: ";
861     os << base::HexEncode(config.extended_metadata.value().data(),
862                           config.extended_metadata.value().size());
863   }
864   if (config.vendor_specific) {
865     os << ", vendor_specific: ";
866     os << base::HexEncode(config.vendor_specific.value().data(),
867                           config.vendor_specific.value().size());
868   }
869   if (config.audio_active_state) {
870     os << ", audio_active_state: ";
871     os << config.audio_active_state.value();
872   }
873   if (config.broadcast_audio_immediate_rendering) {
874     os << ", broadcast_audio_immediate_rendering: ";
875     os << config.broadcast_audio_immediate_rendering.value();
876   }
877   os << "}";
878   return os;
879 }
880 
881 template struct BidirectionalPair<AudioContexts>;
882 template struct BidirectionalPair<AudioLocations>;
883 template struct BidirectionalPair<CisType>;
884 template struct BidirectionalPair<LeAudioConfigurationStrategy>;
885 template struct BidirectionalPair<ase*>;
886 template struct BidirectionalPair<std::string>;
887 template struct BidirectionalPair<std::vector<uint8_t>>;
888 template struct BidirectionalPair<stream_configuration>;
889 template struct BidirectionalPair<stream_parameters>;
890 template struct BidirectionalPair<uint16_t>;
891 template struct BidirectionalPair<uint8_t>;
892 template struct BidirectionalPair<bool>;
893 template struct BidirectionalPair<int>;
894 template struct BidirectionalPair<
895     std::vector<set_configurations::AseConfiguration>>;
896 template struct BidirectionalPair<set_configurations::QosConfigSetting>;
897 
898 }  // namespace types
899 }  // namespace bluetooth::le_audio
900