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 
27 #include "audio_hal_client/audio_hal_client.h"
28 #include "bt_types.h"
29 #include "bta_api.h"
30 #include "bta_le_audio_api.h"
31 #include "client_parser.h"
32 #include "gd/common/strings.h"
33 
34 namespace le_audio {
35 using types::acs_ac_record;
36 using types::LeAudioContextType;
37 
38 namespace set_configurations {
39 using set_configurations::CodecCapabilitySetting;
40 using types::CodecLocation;
41 using types::kLeAudioCodingFormatLC3;
42 using types::kLeAudioDirectionSink;
43 using types::kLeAudioDirectionSource;
44 using types::LeAudioLc3Config;
45 
min_req_devices_cnt(const AudioSetConfiguration * audio_set_conf)46 static uint8_t min_req_devices_cnt(
47     const AudioSetConfiguration* audio_set_conf) {
48   std::pair<uint8_t /* sink */, uint8_t /* source */> snk_src_pair(0, 0);
49 
50   for (auto ent : (*audio_set_conf).confs) {
51     if (ent.direction == kLeAudioDirectionSink)
52       snk_src_pair.first += ent.device_cnt;
53     if (ent.direction == kLeAudioDirectionSource)
54       snk_src_pair.second += ent.device_cnt;
55   }
56 
57   return std::max(snk_src_pair.first, snk_src_pair.second);
58 }
59 
min_req_devices_cnt(const AudioSetConfigurations * audio_set_confs)60 static uint8_t min_req_devices_cnt(
61     const AudioSetConfigurations* audio_set_confs) {
62   uint8_t curr_min_req_devices_cnt = 0xff;
63 
64   for (auto ent : *audio_set_confs) {
65     uint8_t req_devices_cnt = min_req_devices_cnt(ent);
66     if (req_devices_cnt < curr_min_req_devices_cnt)
67       curr_min_req_devices_cnt = req_devices_cnt;
68   }
69 
70   return curr_min_req_devices_cnt;
71 }
72 
get_cis_count(const AudioSetConfiguration & audio_set_conf,int expected_device_cnt,types::LeAudioConfigurationStrategy strategy,int avail_group_sink_ase_count,int avail_group_source_ase_count,uint8_t & out_current_cis_count_bidir,uint8_t & out_current_cis_count_unidir_sink,uint8_t & out_current_cis_count_unidir_source)73 inline void get_cis_count(const AudioSetConfiguration& audio_set_conf,
74                           int expected_device_cnt,
75                           types::LeAudioConfigurationStrategy strategy,
76                           int avail_group_sink_ase_count,
77                           int avail_group_source_ase_count,
78                           uint8_t& out_current_cis_count_bidir,
79                           uint8_t& out_current_cis_count_unidir_sink,
80                           uint8_t& out_current_cis_count_unidir_source) {
81   LOG_INFO("%s", audio_set_conf.name.c_str());
82 
83   /* Sum up the requirements from all subconfigs. They usually have different
84    * directions.
85    */
86   types::BidirectionalPair<uint8_t> config_ase_count = {0, 0};
87   int config_device_cnt = 0;
88 
89   for (auto ent : audio_set_conf.confs) {
90     if ((ent.direction == kLeAudioDirectionSink) &&
91         (ent.strategy != strategy)) {
92       LOG_DEBUG("Strategy does not match (%d != %d)- skip this configuration",
93                 static_cast<int>(ent.strategy), static_cast<int>(strategy));
94       return;
95     }
96 
97     /* Sum up sink and source ases */
98     if (ent.direction == kLeAudioDirectionSink) {
99       config_ase_count.sink += ent.ase_cnt;
100     }
101     if (ent.direction == kLeAudioDirectionSource) {
102       config_ase_count.source += ent.ase_cnt;
103     }
104 
105     /* Calculate the max device count */
106     config_device_cnt =
107         std::max(static_cast<uint8_t>(config_device_cnt), ent.device_cnt);
108   }
109 
110   LOG_DEBUG("Config sink ases: %d, source ases: %d, device count: %d",
111             config_ase_count.sink, config_ase_count.source, config_device_cnt);
112 
113   /* Reject configurations not matching our device count */
114   if (expected_device_cnt != config_device_cnt) {
115     LOG_DEBUG(" Device cnt %d != %d", expected_device_cnt, config_device_cnt);
116     return;
117   }
118 
119   /* Reject configurations requiring sink ASES if our group has none */
120   if ((avail_group_sink_ase_count == 0) && (config_ase_count.sink > 0)) {
121     LOG_DEBUG("Group does not have sink ASEs");
122     return;
123   }
124 
125   /* Reject configurations requiring source ASES if our group has none */
126   if ((avail_group_source_ase_count == 0) && (config_ase_count.source > 0)) {
127     LOG_DEBUG("Group does not have source ASEs");
128     return;
129   }
130 
131   /* If expected group size is 1, then make sure device has enough ASEs */
132   if (expected_device_cnt == 1) {
133     if ((config_ase_count.sink > avail_group_sink_ase_count) ||
134         (config_ase_count.source > avail_group_source_ase_count)) {
135       LOG_DEBUG("Single device group with not enought sink/source ASEs");
136       return;
137     }
138   }
139 
140   /* Configuration list is set in the prioritized order.
141    * it might happen that a higher prio configuration can be supported
142    * and is already taken into account (out_current_cis_count_* is non zero).
143    * Now let's try to ignore ortogonal configuration which would just
144    * increase our demant on number of CISes but will never happen
145    */
146   if (config_ase_count.sink == 0 && (out_current_cis_count_unidir_sink > 0 ||
147                                      out_current_cis_count_bidir > 0)) {
148     LOG_INFO(
149         "Higher prio configuration using sink ASEs has been taken into "
150         "account");
151     return;
152   }
153 
154   if (config_ase_count.source == 0 &&
155       (out_current_cis_count_unidir_source > 0 ||
156        out_current_cis_count_bidir > 0)) {
157     LOG_INFO(
158         "Higher prio configuration using source ASEs has been taken into "
159         "account");
160     return;
161   }
162 
163   /* Check how many bidirectional cises we can use */
164   uint8_t config_bidir_cis_count =
165       std::min(config_ase_count.sink, config_ase_count.source);
166   /* Count the remaining unidirectional cises */
167   uint8_t config_unidir_sink_cis_count =
168       config_ase_count.sink - config_bidir_cis_count;
169   uint8_t config_unidir_source_cis_count =
170       config_ase_count.source - config_bidir_cis_count;
171 
172   /* WARNING: Minipolicy which prioritizes bidirectional configs */
173   if (config_bidir_cis_count > out_current_cis_count_bidir) {
174     /* Correct all counters to represent this single config */
175     out_current_cis_count_bidir = config_bidir_cis_count;
176     out_current_cis_count_unidir_sink = config_unidir_sink_cis_count;
177     out_current_cis_count_unidir_source = config_unidir_source_cis_count;
178 
179   } else if (out_current_cis_count_bidir == 0) {
180     /* No bidirectionals possible yet. Calculate for unidirectional cises. */
181     if ((out_current_cis_count_unidir_sink == 0) &&
182         (out_current_cis_count_unidir_source == 0)) {
183       out_current_cis_count_unidir_sink = config_unidir_sink_cis_count;
184       out_current_cis_count_unidir_source = config_unidir_source_cis_count;
185     }
186   }
187 }
188 
get_cis_count(const AudioSetConfigurations & audio_set_confs,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)189 void get_cis_count(const AudioSetConfigurations& audio_set_confs,
190                    int expected_device_cnt,
191                    types::LeAudioConfigurationStrategy strategy,
192                    int avail_group_ase_snk_cnt, int avail_group_ase_src_count,
193                    uint8_t& out_cis_count_bidir,
194                    uint8_t& out_cis_count_unidir_sink,
195                    uint8_t& out_cis_count_unidir_source) {
196   LOG_INFO(
197       " strategy %d, group avail sink ases: %d, group avail source ases %d "
198       "expected_device_count %d",
199       static_cast<int>(strategy), avail_group_ase_snk_cnt,
200       avail_group_ase_src_count, expected_device_cnt);
201 
202   /* Look for the most optimal configuration and store the needed cis counts */
203   for (auto audio_set_conf : audio_set_confs) {
204     get_cis_count(*audio_set_conf, expected_device_cnt, strategy,
205                   avail_group_ase_snk_cnt, avail_group_ase_src_count,
206                   out_cis_count_bidir, out_cis_count_unidir_sink,
207                   out_cis_count_unidir_source);
208 
209     LOG_DEBUG(
210         "Intermediate step:  Bi-Directional: %d,"
211         " Uni-Directional Sink: %d, Uni-Directional Source: %d ",
212         out_cis_count_bidir, out_cis_count_unidir_sink,
213         out_cis_count_unidir_source);
214   }
215 
216   LOG_INFO(
217       " Maximum CIS count, Bi-Directional: %d,"
218       " Uni-Directional Sink: %d, Uni-Directional Source: %d",
219       out_cis_count_bidir, out_cis_count_unidir_sink,
220       out_cis_count_unidir_source);
221 }
222 
check_if_may_cover_scenario(const AudioSetConfigurations * audio_set_confs,uint8_t group_size)223 bool check_if_may_cover_scenario(const AudioSetConfigurations* audio_set_confs,
224                                  uint8_t group_size) {
225   if (!audio_set_confs) {
226     LOG(ERROR) << __func__ << ", no audio requirements for group";
227     return false;
228   }
229 
230   return group_size >= min_req_devices_cnt(audio_set_confs);
231 }
232 
check_if_may_cover_scenario(const AudioSetConfiguration * audio_set_conf,uint8_t group_size)233 bool check_if_may_cover_scenario(const AudioSetConfiguration* audio_set_conf,
234                                  uint8_t group_size) {
235   if (!audio_set_conf) {
236     LOG(ERROR) << __func__ << ", no audio requirement for group";
237     return false;
238   }
239 
240   return group_size >= min_req_devices_cnt(audio_set_conf);
241 }
242 
get_num_of_devices_in_configuration(const AudioSetConfiguration * audio_set_conf)243 uint8_t get_num_of_devices_in_configuration(
244     const AudioSetConfiguration* audio_set_conf) {
245   return min_req_devices_cnt(audio_set_conf);
246 }
247 
IsCodecConfigurationSupported(const types::LeAudioLtvMap & pacs,const LeAudioLc3Config & lc3_config)248 static bool IsCodecConfigurationSupported(const types::LeAudioLtvMap& pacs,
249                                           const LeAudioLc3Config& lc3_config) {
250   const auto& reqs = lc3_config.GetAsLtvMap();
251   uint8_t u8_req_val, u8_pac_val;
252   uint16_t u16_req_val, u16_pac_val;
253 
254   /* Sampling frequency */
255   auto req = reqs.Find(codec_spec_conf::kLeAudioCodecLC3TypeSamplingFreq);
256   auto pac = pacs.Find(codec_spec_caps::kLeAudioCodecLC3TypeSamplingFreq);
257   if (!req || !pac) {
258     LOG_DEBUG(", lack of sampling frequency fields");
259     return false;
260   }
261 
262   u8_req_val = VEC_UINT8_TO_UINT8(req.value());
263   u16_pac_val = VEC_UINT8_TO_UINT16(pac.value());
264 
265   /* TODO: Integrate with codec capabilities */
266   if (!(u16_pac_val &
267         codec_spec_caps::SamplingFreqConfig2Capability(u8_req_val))) {
268     /*
269      * Note: Requirements are in the codec configuration specification which
270      * are values coming from Assigned Numbers: Codec_Specific_Configuration
271      */
272     LOG_DEBUG(
273         " Req:SamplFreq= 0x%04x (Assigned Numbers: "
274         "Codec_Specific_Configuration)",
275         u8_req_val);
276     /* NOTE: Below is Codec specific cababilities comes from Assigned Numbers:
277      * Codec_Specific_Capabilities
278      */
279     LOG_DEBUG(
280         " Pac:SamplFreq= 0x%04x  (Assigned numbers: "
281         "Codec_Specific_Capabilities - bitfield)",
282         u16_pac_val);
283 
284     LOG_DEBUG(", sampling frequency not supported");
285     return false;
286   }
287 
288   /* Frame duration */
289   req = reqs.Find(codec_spec_conf::kLeAudioCodecLC3TypeFrameDuration);
290   pac = pacs.Find(codec_spec_caps::kLeAudioCodecLC3TypeFrameDuration);
291   if (!req || !pac) {
292     LOG_DEBUG(", lack of frame duration fields");
293     return false;
294   }
295 
296   u8_req_val = VEC_UINT8_TO_UINT8(req.value());
297   u8_pac_val = VEC_UINT8_TO_UINT8(pac.value());
298 
299   if ((u8_req_val != codec_spec_conf::kLeAudioCodecLC3FrameDur7500us &&
300        u8_req_val != codec_spec_conf::kLeAudioCodecLC3FrameDur10000us) ||
301       !(u8_pac_val &
302         (codec_spec_caps::FrameDurationConfig2Capability(u8_req_val)))) {
303     LOG_DEBUG(" Req:FrameDur=0x%04x", u8_req_val);
304     LOG_DEBUG(" Pac:FrameDur=0x%04x", u8_pac_val);
305     LOG_DEBUG(", frame duration not supported");
306     return false;
307   }
308 
309   uint8_t required_audio_chan_num = lc3_config.GetChannelCount();
310   pac = pacs.Find(codec_spec_caps::kLeAudioCodecLC3TypeAudioChannelCounts);
311 
312   /*
313    * BAP_Validation_r07 1.9.2 Audio channel support requirements
314    * "The Unicast Server shall support an Audio_Channel_Counts value of 0x01
315    * (0b00000001 = one channel) and may support other values defined by an
316    * implementation or by a higher-layer specification."
317    *
318    * Thus if Audio_Channel_Counts is not present in PAC LTV structure, we assume
319    * the Unicast Server supports mandatory one channel.
320    */
321   if (!pac) {
322     LOG_DEBUG(", no Audio_Channel_Counts field in PAC, using default 0x01");
323     u8_pac_val = 0x01;
324   } else {
325     u8_pac_val = VEC_UINT8_TO_UINT8(pac.value());
326   }
327 
328   if (!((1 << (required_audio_chan_num - 1)) & u8_pac_val)) {
329     LOG_DEBUG(" Req:AudioChanCnt=0x%04x", 1 << (required_audio_chan_num - 1));
330     LOG_DEBUG(" Pac:AudioChanCnt=0x%04x", u8_pac_val);
331     LOG_DEBUG(", channel count warning");
332     return false;
333   }
334 
335   /* Octets per frame */
336   req = reqs.Find(codec_spec_conf::kLeAudioCodecLC3TypeOctetPerFrame);
337   pac = pacs.Find(codec_spec_caps::kLeAudioCodecLC3TypeOctetPerFrame);
338 
339   if (!req || !pac) {
340     LOG_DEBUG(", lack of octet per frame fields");
341     return false;
342   }
343 
344   u16_req_val = VEC_UINT8_TO_UINT16(req.value());
345   /* Minimal value 0-1 byte */
346   u16_pac_val = VEC_UINT8_TO_UINT16(pac.value());
347   if (u16_req_val < u16_pac_val) {
348     LOG_DEBUG(" Req:OctetsPerFrame=%d", int(u16_req_val));
349     LOG_DEBUG(" Pac:MinOctetsPerFrame=%d", int(u16_pac_val));
350     LOG_DEBUG(", octet per frame below minimum");
351     return false;
352   }
353 
354   /* Maximal value 2-3 byte */
355   u16_pac_val = OFF_VEC_UINT8_TO_UINT16(pac.value(), 2);
356   if (u16_req_val > u16_pac_val) {
357     LOG_DEBUG(" Req:MaxOctetsPerFrame=%d", int(u16_req_val));
358     LOG_DEBUG(" Pac:MaxOctetsPerFrame=%d", int(u16_pac_val));
359     LOG_DEBUG(", octet per frame above maximum");
360     return false;
361   }
362 
363   return true;
364 }
365 
IsCodecCapabilitySettingSupported(const acs_ac_record & pac,const CodecCapabilitySetting & codec_capability_setting)366 bool IsCodecCapabilitySettingSupported(
367     const acs_ac_record& pac,
368     const CodecCapabilitySetting& codec_capability_setting) {
369   const auto& codec_id = codec_capability_setting.id;
370 
371   if (codec_id != pac.codec_id) return false;
372 
373   LOG_DEBUG(": Settings for format: 0x%02x ", codec_id.coding_format);
374 
375   switch (codec_id.coding_format) {
376     case kLeAudioCodingFormatLC3:
377       return IsCodecConfigurationSupported(
378           pac.codec_spec_caps,
379           std::get<LeAudioLc3Config>(codec_capability_setting.config));
380     default:
381       return false;
382   }
383 }
384 
GetConfigSamplingFrequency() const385 uint32_t CodecCapabilitySetting::GetConfigSamplingFrequency() const {
386   switch (id.coding_format) {
387     case kLeAudioCodingFormatLC3:
388       return std::get<types::LeAudioLc3Config>(config).GetSamplingFrequencyHz();
389     default:
390       LOG_WARN(", invalid codec id: 0x%02x", id.coding_format);
391       return 0;
392   }
393 };
394 
GetConfigDataIntervalUs() const395 uint32_t CodecCapabilitySetting::GetConfigDataIntervalUs() const {
396   switch (id.coding_format) {
397     case kLeAudioCodingFormatLC3:
398       return std::get<types::LeAudioLc3Config>(config).GetFrameDurationUs();
399     default:
400       LOG_WARN(", invalid codec id: 0x%02x", id.coding_format);
401       return 0;
402   }
403 };
404 
GetConfigBitsPerSample() const405 uint8_t CodecCapabilitySetting::GetConfigBitsPerSample() const {
406   switch (id.coding_format) {
407     case kLeAudioCodingFormatLC3:
408       /* XXX LC3 supports 16, 24, 32 */
409       return 16;
410     default:
411       LOG_WARN(", invalid codec id: 0x%02x", id.coding_format);
412       return 0;
413   }
414 };
415 
GetConfigChannelCount() const416 uint8_t CodecCapabilitySetting::GetConfigChannelCount() const {
417   switch (id.coding_format) {
418     case kLeAudioCodingFormatLC3:
419       LOG_DEBUG("count = %d",
420                 static_cast<int>(
421                     std::get<types::LeAudioLc3Config>(config).channel_count));
422       return std::get<types::LeAudioLc3Config>(config).channel_count;
423     default:
424       LOG_WARN(", invalid codec id: 0x%02x", id.coding_format);
425       return 0;
426   }
427 }
428 }  // namespace set_configurations
429 
430 namespace types {
431 /* Helper map for matching various frequency notations */
432 const std::map<uint8_t, uint32_t> LeAudioLc3Config::sampling_freq_map = {
433     {codec_spec_conf::kLeAudioSamplingFreq8000Hz,
434      LeAudioCodecConfiguration::kSampleRate8000},
435     {codec_spec_conf::kLeAudioSamplingFreq16000Hz,
436      LeAudioCodecConfiguration::kSampleRate16000},
437     {codec_spec_conf::kLeAudioSamplingFreq24000Hz,
438      LeAudioCodecConfiguration::kSampleRate24000},
439     {codec_spec_conf::kLeAudioSamplingFreq32000Hz,
440      LeAudioCodecConfiguration::kSampleRate32000},
441     {codec_spec_conf::kLeAudioSamplingFreq44100Hz,
442      LeAudioCodecConfiguration::kSampleRate44100},
443     {codec_spec_conf::kLeAudioSamplingFreq48000Hz,
444      LeAudioCodecConfiguration::kSampleRate48000}};
445 
446 /* Helper map for matching various frame durations notations */
447 const std::map<uint8_t, uint32_t> LeAudioLc3Config::frame_duration_map = {
448     {codec_spec_conf::kLeAudioCodecLC3FrameDur7500us,
449      LeAudioCodecConfiguration::kInterval7500Us},
450     {codec_spec_conf::kLeAudioCodecLC3FrameDur10000us,
451      LeAudioCodecConfiguration::kInterval10000Us}};
452 
CapabilityTypeToStr(const uint8_t & type)453 std::string CapabilityTypeToStr(const uint8_t& type) {
454   switch (type) {
455     case codec_spec_caps::kLeAudioCodecLC3TypeSamplingFreq:
456       return "Supported Sampling Frequencies";
457     case codec_spec_caps::kLeAudioCodecLC3TypeFrameDuration:
458       return "Supported Frame Durations";
459     case codec_spec_caps::kLeAudioCodecLC3TypeAudioChannelCounts:
460       return "Supported Audio Channel Count";
461     case codec_spec_caps::kLeAudioCodecLC3TypeOctetPerFrame:
462       return "Supported Octets Per Codec Frame";
463     case codec_spec_caps::kLeAudioCodecLC3TypeMaxCodecFramesPerSdu:
464       return "Supported Max Codec Frames Per SDU";
465     default:
466       return "Unknown";
467   }
468 }
469 
CapabilityValueToStr(const uint8_t & type,const std::vector<uint8_t> & value)470 std::string CapabilityValueToStr(const uint8_t& type,
471                                  const std::vector<uint8_t>& value) {
472   std::string string = "";
473 
474   switch (type) {
475     case codec_spec_conf::kLeAudioCodecLC3TypeSamplingFreq: {
476       if (value.size() != 2) {
477         return "Invalid size";
478       }
479 
480       uint16_t u16_val = VEC_UINT8_TO_UINT16(value);
481 
482       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq8000Hz) {
483         string += "8";
484       }
485       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq11025Hz) {
486         string += std::string((string.empty() ? "" : "|")) + "11.025";
487       }
488       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq16000Hz) {
489         string += std::string((string.empty() ? "" : "|")) + "16";
490       }
491       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq22050Hz) {
492         string += std::string((string.empty() ? "" : "|")) + "22.050";
493       }
494       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq24000Hz) {
495         string += std::string((string.empty() ? "" : "|")) + "24";
496       }
497       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq32000Hz) {
498         string += std::string((string.empty() ? "" : "|")) + "32";
499       }
500       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq44100Hz) {
501         string += std::string((string.empty() ? "" : "|")) + "44.1";
502       }
503       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq48000Hz) {
504         string += std::string((string.empty() ? "" : "|")) + "48";
505       }
506       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq88200Hz) {
507         string += std::string((string.empty() ? "" : "|")) + "88.2";
508       }
509       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq96000Hz) {
510         string += std::string((string.empty() ? "" : "|")) + "96";
511       }
512       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq176400Hz) {
513         string += std::string((string.empty() ? "" : "|")) + "176.4";
514       }
515       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq192000Hz) {
516         string += std::string((string.empty() ? "" : "|")) + "192";
517       }
518       if (u16_val & codec_spec_caps::kLeAudioSamplingFreq384000Hz) {
519         string += std::string((string.empty() ? "" : "|")) + "384";
520       }
521 
522       return string += " [kHz]\n";
523     }
524     case codec_spec_conf::kLeAudioCodecLC3TypeFrameDuration: {
525       if (value.size() != 1) {
526         return "Invalid size";
527       }
528 
529       uint8_t u8_val = VEC_UINT8_TO_UINT8(value);
530 
531       if (u8_val & codec_spec_caps::kLeAudioCodecLC3FrameDur7500us) {
532         string += "7.5";
533       }
534       if (u8_val & codec_spec_caps::kLeAudioCodecLC3FrameDur10000us) {
535         string += std::string((string.empty() ? "" : "|")) + "10";
536       }
537       if (u8_val & codec_spec_caps::kLeAudioCodecLC3FrameDurPrefer7500us) {
538         string += std::string((string.empty() ? "" : "|")) + "7.5 preferred";
539       }
540       if (u8_val & codec_spec_caps::kLeAudioCodecLC3FrameDurPrefer10000us) {
541         string += std::string((string.empty() ? "" : "|")) + "10 preferred";
542       }
543 
544       return string += " [ms]\n";
545     }
546     case codec_spec_conf::kLeAudioCodecLC3TypeAudioChannelAllocation: {
547       if (value.size() != 1) {
548         return "Invalid size";
549       }
550 
551       uint8_t u8_val = VEC_UINT8_TO_UINT8(value);
552 
553       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountNone) {
554         string += "0";
555       }
556       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountSingleChannel) {
557         string += std::string((string.empty() ? "" : "|")) + "1";
558       }
559       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountTwoChannel) {
560         string += std::string((string.empty() ? "" : "|")) + "2";
561       }
562       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountThreeChannel) {
563         string += std::string((string.empty() ? "" : "|")) + "3";
564       }
565       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountFourChannel) {
566         string += std::string((string.empty() ? "" : "|")) + "4";
567       }
568       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountFiveChannel) {
569         string += std::string((string.empty() ? "" : "|")) + "5";
570       }
571       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountSixChannel) {
572         string += std::string((string.empty() ? "" : "|")) + "6";
573       }
574       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountSevenChannel) {
575         string += std::string((string.empty() ? "" : "|")) + "7";
576       }
577       if (u8_val & codec_spec_caps::kLeAudioCodecLC3ChannelCountEightChannel) {
578         string += std::string((string.empty() ? "" : "|")) + "8";
579       }
580 
581       return string += " channel/s\n";
582     }
583     case codec_spec_conf::kLeAudioCodecLC3TypeOctetPerFrame: {
584       if (value.size() != 4) {
585         return "Invalid size";
586       }
587 
588       uint16_t u16_min_number_of_octets = VEC_UINT8_TO_UINT16(value);
589       uint16_t u16_max_number_of_octets =
590           OFF_VEC_UINT8_TO_UINT16(value, sizeof(u16_min_number_of_octets));
591 
592       string += "Minimum: " + std::to_string(u16_min_number_of_octets);
593       string += ", Maximum: " + std::to_string(u16_max_number_of_octets) + "\n";
594 
595       return string;
596     }
597     case codec_spec_conf::kLeAudioCodecLC3TypeCodecFrameBlocksPerSdu: {
598       if (value.size() != 1) {
599         return "Invalid size";
600       }
601 
602       uint8_t u8_val = VEC_UINT8_TO_UINT8(value);
603 
604       string += std::to_string(u8_val) + " frame/s\n";
605 
606       return string;
607     }
608     default:
609       return base::HexEncode(value.data(), value.size()) + "\n";
610   }
611 }
612 
CodecCapabilitiesLtvFormat(const uint8_t & type,const std::vector<uint8_t> & value)613 std::string CodecCapabilitiesLtvFormat(const uint8_t& type,
614                                        const std::vector<uint8_t>& value) {
615   std::string string = "";
616 
617   string += CapabilityTypeToStr(type) + ": ";
618   string += CapabilityValueToStr(type, value);
619 
620   return string;
621 }
622 
Find(uint8_t type) const623 std::optional<std::vector<uint8_t>> LeAudioLtvMap::Find(uint8_t type) const {
624   auto iter =
625       std::find_if(values.cbegin(), values.cend(),
626                    [type](const auto& value) { return value.first == type; });
627 
628   if (iter == values.cend()) return std::nullopt;
629 
630   return iter->second;
631 }
632 
RawPacket(uint8_t * p_buf) const633 uint8_t* LeAudioLtvMap::RawPacket(uint8_t* p_buf) const {
634   for (auto const& value : values) {
635     UINT8_TO_STREAM(p_buf, value.second.size() + 1);
636     UINT8_TO_STREAM(p_buf, value.first);
637     ARRAY_TO_STREAM(p_buf, value.second.data(),
638                     static_cast<int>(value.second.size()));
639   }
640 
641   return p_buf;
642 }
643 
RawPacket() const644 std::vector<uint8_t> LeAudioLtvMap::RawPacket() const {
645   std::vector<uint8_t> data(RawPacketSize());
646   RawPacket(data.data());
647   return data;
648 }
649 
Append(const LeAudioLtvMap & other)650 void LeAudioLtvMap::Append(const LeAudioLtvMap& other) {
651   /* This will override values for the already existing keys */
652   for (auto& el : other.values) {
653     values[el.first] = el.second;
654   }
655 }
656 
Parse(const uint8_t * p_value,uint8_t len,bool & success)657 LeAudioLtvMap LeAudioLtvMap::Parse(const uint8_t* p_value, uint8_t len,
658                                    bool& success) {
659   LeAudioLtvMap ltv_map;
660 
661   if (len > 0) {
662     const auto p_value_end = p_value + len;
663 
664     while ((p_value_end - p_value) > 0) {
665       uint8_t ltv_len;
666       STREAM_TO_UINT8(ltv_len, p_value);
667 
668       // Unusual, but possible case
669       if (ltv_len == 0) continue;
670 
671       if (p_value_end < (p_value + ltv_len)) {
672         LOG(ERROR) << __func__
673                    << " Invalid ltv_len: " << static_cast<int>(ltv_len);
674         success = false;
675         return LeAudioLtvMap();
676       }
677 
678       uint8_t ltv_type;
679       STREAM_TO_UINT8(ltv_type, p_value);
680       ltv_len -= sizeof(ltv_type);
681 
682       const auto p_temp = p_value;
683       p_value += ltv_len;
684 
685       std::vector<uint8_t> ltv_value(p_temp, p_value);
686       ltv_map.values.emplace(ltv_type, std::move(ltv_value));
687     }
688   }
689 
690   success = true;
691   return ltv_map;
692 }
693 
RawPacketSize() const694 size_t LeAudioLtvMap::RawPacketSize() const {
695   size_t bytes = 0;
696 
697   for (auto const& value : values) {
698     bytes += (/* ltv_len + ltv_type */ 2 + value.second.size());
699   }
700 
701   return bytes;
702 }
703 
ToString(const std::string & indent_string,std::string (* format)(const uint8_t &,const std::vector<uint8_t> &)) const704 std::string LeAudioLtvMap::ToString(
705     const std::string& indent_string,
706     std::string (*format)(const uint8_t&, const std::vector<uint8_t>&)) const {
707   std::string debug_str;
708 
709   for (const auto& value : values) {
710     std::stringstream sstream;
711 
712     if (format == nullptr) {
713       sstream << indent_string + "type: " << std::to_string(value.first)
714               << "\tlen: " << std::to_string(value.second.size()) << "\tdata: "
715               << base::HexEncode(value.second.data(), value.second.size()) +
716                      "\n";
717     } else {
718       sstream << indent_string + format(value.first, value.second);
719     }
720 
721     debug_str += sstream.str();
722   }
723 
724   return debug_str;
725 }
726 
727 }  // namespace types
728 
AppendMetadataLtvEntryForCcidList(std::vector<uint8_t> & metadata,const std::vector<uint8_t> & ccid_list)729 void AppendMetadataLtvEntryForCcidList(std::vector<uint8_t>& metadata,
730                                        const std::vector<uint8_t>& ccid_list) {
731   if (ccid_list.size() == 0) {
732     LOG_WARN("Empty CCID list.");
733     return;
734   }
735 
736   metadata.push_back(
737       static_cast<uint8_t>(types::kLeAudioMetadataTypeLen + ccid_list.size()));
738   metadata.push_back(static_cast<uint8_t>(types::kLeAudioMetadataTypeCcidList));
739 
740   metadata.insert(metadata.end(), ccid_list.begin(), ccid_list.end());
741 }
742 
AppendMetadataLtvEntryForStreamingContext(std::vector<uint8_t> & metadata,types::AudioContexts context_type)743 void AppendMetadataLtvEntryForStreamingContext(
744     std::vector<uint8_t>& metadata, types::AudioContexts context_type) {
745   std::vector<uint8_t> streaming_context_ltv_entry;
746 
747   streaming_context_ltv_entry.resize(
748       types::kLeAudioMetadataTypeLen + types::kLeAudioMetadataLenLen +
749       types::kLeAudioMetadataStreamingAudioContextLen);
750   uint8_t* streaming_context_ltv_entry_buf = streaming_context_ltv_entry.data();
751 
752   UINT8_TO_STREAM(streaming_context_ltv_entry_buf,
753                   types::kLeAudioMetadataTypeLen +
754                       types::kLeAudioMetadataStreamingAudioContextLen);
755   UINT8_TO_STREAM(streaming_context_ltv_entry_buf,
756                   types::kLeAudioMetadataTypeStreamingAudioContext);
757   UINT16_TO_STREAM(streaming_context_ltv_entry_buf, context_type.value());
758 
759   metadata.insert(metadata.end(), streaming_context_ltv_entry.begin(),
760                   streaming_context_ltv_entry.end());
761 }
762 
GetMaxCodecFramesPerSduFromPac(const acs_ac_record * pac)763 uint8_t GetMaxCodecFramesPerSduFromPac(const acs_ac_record* pac) {
764   auto tlv_ent = pac->codec_spec_caps.Find(
765       codec_spec_caps::kLeAudioCodecLC3TypeMaxCodecFramesPerSdu);
766 
767   if (tlv_ent) return VEC_UINT8_TO_UINT8(tlv_ent.value());
768 
769   return 1;
770 }
771 
AdjustAllocationForOffloader(uint32_t allocation)772 uint32_t AdjustAllocationForOffloader(uint32_t allocation) {
773   if ((allocation & codec_spec_conf::kLeAudioLocationAnyLeft) &&
774       (allocation & codec_spec_conf::kLeAudioLocationAnyRight)) {
775     return codec_spec_conf::kLeAudioLocationStereo;
776   }
777   if (allocation & codec_spec_conf::kLeAudioLocationAnyLeft) {
778     return codec_spec_conf::kLeAudioLocationFrontLeft;
779   }
780 
781   if (allocation & codec_spec_conf::kLeAudioLocationAnyRight) {
782     return codec_spec_conf::kLeAudioLocationFrontRight;
783   }
784   return 0;
785 }
786 
787 namespace types {
operator <<(std::ostream & os,const AudioStreamDataPathState & state)788 std::ostream& operator<<(std::ostream& os,
789                          const AudioStreamDataPathState& state) {
790   static const char* char_value_[6] = {
791       "IDLE",        "CIS_DISCONNECTING", "CIS_ASSIGNED",
792       "CIS_PENDING", "CIS_ESTABLISHED",   "DATA_PATH_ESTABLISHED"};
793 
794   os << char_value_[static_cast<uint8_t>(state)] << " ("
795      << "0x" << std::setfill('0') << std::setw(2) << static_cast<int>(state)
796      << ")";
797   return os;
798 }
operator <<(std::ostream & os,const types::CigState & state)799 std::ostream& operator<<(std::ostream& os, const types::CigState& state) {
800   static const char* char_value_[5] = {"NONE", "CREATING", "CREATED",
801                                        "REMOVING", "RECOVERING"};
802 
803   os << char_value_[static_cast<uint8_t>(state)] << " ("
804      << "0x" << std::setfill('0') << std::setw(2) << static_cast<int>(state)
805      << ")";
806   return os;
807 }
operator <<(std::ostream & os,const types::AseState & state)808 std::ostream& operator<<(std::ostream& os, const types::AseState& state) {
809   static const char* char_value_[7] = {
810       "IDLE",      "CODEC_CONFIGURED", "QOS_CONFIGURED", "ENABLING",
811       "STREAMING", "DISABLING",        "RELEASING",
812   };
813 
814   os << char_value_[static_cast<uint8_t>(state)] << " ("
815      << "0x" << std::setfill('0') << std::setw(2) << static_cast<int>(state)
816      << ")";
817   return os;
818 }
819 
operator <<(std::ostream & os,const types::LeAudioLc3Config & config)820 std::ostream& operator<<(std::ostream& os,
821                          const types::LeAudioLc3Config& config) {
822   os << " LeAudioLc3Config(SamplFreq=" << loghex(*config.sampling_frequency)
823      << ", FrameDur=" << loghex(*config.frame_duration)
824      << ", OctetsPerFrame=" << int(*config.octets_per_codec_frame)
825      << ", CodecFramesBlocksPerSDU=" << int(*config.codec_frames_blocks_per_sdu)
826      << ", AudioChanLoc=" << loghex(*config.audio_channel_allocation) << ")";
827   return os;
828 }
829 
contextTypeToStr(const LeAudioContextType & context)830 std::string contextTypeToStr(const LeAudioContextType& context) {
831   switch (context) {
832     case LeAudioContextType::UNINITIALIZED:
833       return "UNINITIALIZED";
834     case LeAudioContextType::UNSPECIFIED:
835       return "UNSPECIFIED";
836     case LeAudioContextType::CONVERSATIONAL:
837       return "CONVERSATIONAL";
838     case LeAudioContextType::MEDIA:
839       return "MEDIA";
840     case LeAudioContextType::GAME:
841       return "GAME";
842     case LeAudioContextType::INSTRUCTIONAL:
843       return "INSTRUCTIONAL";
844     case LeAudioContextType::VOICEASSISTANTS:
845       return "VOICEASSISTANTS";
846     case LeAudioContextType::LIVE:
847       return "LIVE";
848     case LeAudioContextType::SOUNDEFFECTS:
849       return "SOUNDEFFECTS";
850     case LeAudioContextType::NOTIFICATIONS:
851       return "NOTIFICATIONS";
852     case LeAudioContextType::RINGTONE:
853       return "RINGTONE";
854     case LeAudioContextType::ALERTS:
855       return "ALERTS";
856     case LeAudioContextType::EMERGENCYALARM:
857       return "EMERGENCYALARM";
858     default:
859       return "UNKNOWN";
860   }
861 }
862 
operator <<(std::ostream & os,const LeAudioContextType & context)863 std::ostream& operator<<(std::ostream& os, const LeAudioContextType& context) {
864   os << contextTypeToStr(context);
865   return os;
866 }
867 
operator |(std::underlying_type<LeAudioContextType>::type lhs,const LeAudioContextType rhs)868 AudioContexts operator|(std::underlying_type<LeAudioContextType>::type lhs,
869                         const LeAudioContextType rhs) {
870   using T = std::underlying_type<LeAudioContextType>::type;
871   return AudioContexts(lhs | static_cast<T>(rhs));
872 }
873 
operator |=(AudioContexts & lhs,AudioContexts const & rhs)874 AudioContexts& operator|=(AudioContexts& lhs, AudioContexts const& rhs) {
875   lhs = AudioContexts(lhs.value() | rhs.value());
876   return lhs;
877 }
878 
operator &=(AudioContexts & lhs,AudioContexts const & rhs)879 AudioContexts& operator&=(AudioContexts& lhs, AudioContexts const& rhs) {
880   lhs = AudioContexts(lhs.value() & rhs.value());
881   return lhs;
882 }
883 
ToHexString(const LeAudioContextType & value)884 std::string ToHexString(const LeAudioContextType& value) {
885   using T = std::underlying_type<LeAudioContextType>::type;
886   return bluetooth::common::ToHexString(static_cast<T>(value));
887 }
888 
to_string() const889 std::string AudioContexts::to_string() const {
890   std::stringstream s;
891   for (auto ctx : le_audio::types::kLeAudioContextAllTypesArray) {
892     if (test(ctx)) {
893       if (s.tellp() != 0) s << " | ";
894       s << ctx;
895     }
896   }
897   s << " (" << bluetooth::common::ToHexString(mValue) << ")";
898   return s.str();
899 }
900 
operator <<(std::ostream & os,const AudioContexts & contexts)901 std::ostream& operator<<(std::ostream& os, const AudioContexts& contexts) {
902   os << contexts.to_string();
903   return os;
904 }
905 
906 /* Bidirectional getter trait for AudioContexts bidirectional pair */
907 template <>
get_bidirectional(BidirectionalPair<AudioContexts> p)908 AudioContexts get_bidirectional(BidirectionalPair<AudioContexts> p) {
909   return p.sink | p.source;
910 }
911 
912 template <>
get_bidirectional(BidirectionalPair<std::vector<uint8_t>> bidir)913 std::vector<uint8_t> get_bidirectional(
914     BidirectionalPair<std::vector<uint8_t>> bidir) {
915   std::vector<uint8_t> res = bidir.sink;
916   res.insert(std::end(res), std::begin(bidir.source), std::end(bidir.source));
917   return res;
918 }
919 
920 template <>
get_bidirectional(BidirectionalPair<AudioLocations> bidir)921 AudioLocations get_bidirectional(BidirectionalPair<AudioLocations> bidir) {
922   return bidir.sink | bidir.source;
923 }
924 
925 template struct BidirectionalPair<AudioContexts>;
926 template struct BidirectionalPair<AudioLocations>;
927 template struct BidirectionalPair<std::vector<uint8_t>>;
928 
929 }  // namespace types
930 }  // namespace le_audio
931