1 /*
2  * Copyright 2016 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 /**
18  * A2DP Codecs Configuration
19  */
20 
21 #define LOG_TAG "bluetooth-a2dp"
22 
23 #include <bluetooth/log.h>
24 
25 #include "a2dp_aac.h"
26 #include "a2dp_codec_api.h"
27 #include "a2dp_ext.h"
28 #include "a2dp_sbc.h"
29 #include "a2dp_vendor.h"
30 
31 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
32 #include "a2dp_vendor_aptx.h"
33 #include "a2dp_vendor_aptx_hd.h"
34 #include "a2dp_vendor_ldac.h"
35 #include "a2dp_vendor_opus.h"
36 #endif
37 
38 #include "audio_hal_interface/a2dp_encoding.h"
39 #include "bta/av/bta_av_int.h"
40 #include "device/include/device_iot_config.h"
41 #include "internal_include/bt_trace.h"
42 #include "osi/include/properties.h"
43 #include "stack/include/bt_hdr.h"
44 
45 /* The Media Type offset within the codec info byte array */
46 #define A2DP_MEDIA_TYPE_OFFSET 1
47 
48 // Initializes the codec config.
49 // |codec_config| is the codec config to initialize.
50 // |codec_index| and |codec_priority| are the codec type and priority to use
51 // for the initialization.
52 
53 using namespace bluetooth;
54 
init_btav_a2dp_codec_config(btav_a2dp_codec_config_t * codec_config,btav_a2dp_codec_index_t codec_index,btav_a2dp_codec_priority_t codec_priority)55 static void init_btav_a2dp_codec_config(
56     btav_a2dp_codec_config_t* codec_config, btav_a2dp_codec_index_t codec_index,
57     btav_a2dp_codec_priority_t codec_priority) {
58   memset(codec_config, 0, sizeof(btav_a2dp_codec_config_t));
59   codec_config->codec_type = codec_index;
60   codec_config->codec_priority = codec_priority;
61 }
62 
A2dpCodecConfig(btav_a2dp_codec_index_t codec_index,uint64_t codec_id,const std::string & name,btav_a2dp_codec_priority_t codec_priority)63 A2dpCodecConfig::A2dpCodecConfig(btav_a2dp_codec_index_t codec_index,
64                                  uint64_t codec_id, const std::string& name,
65                                  btav_a2dp_codec_priority_t codec_priority)
66     : codec_index_(codec_index),
67       codec_id_(codec_id),
68       name_(name),
69       default_codec_priority_(codec_priority) {
70   setCodecPriority(codec_priority);
71 
72   init_btav_a2dp_codec_config(&codec_config_, codec_index_, codecPriority());
73   init_btav_a2dp_codec_config(&codec_capability_, codec_index_,
74                               codecPriority());
75   init_btav_a2dp_codec_config(&codec_local_capability_, codec_index_,
76                               codecPriority());
77   init_btav_a2dp_codec_config(&codec_selectable_capability_, codec_index_,
78                               codecPriority());
79   init_btav_a2dp_codec_config(&codec_user_config_, codec_index_,
80                               BTAV_A2DP_CODEC_PRIORITY_DEFAULT);
81   init_btav_a2dp_codec_config(&codec_audio_config_, codec_index_,
82                               BTAV_A2DP_CODEC_PRIORITY_DEFAULT);
83 
84   memset(ota_codec_config_, 0, sizeof(ota_codec_config_));
85   memset(ota_codec_peer_capability_, 0, sizeof(ota_codec_peer_capability_));
86   memset(ota_codec_peer_config_, 0, sizeof(ota_codec_peer_config_));
87 }
88 
~A2dpCodecConfig()89 A2dpCodecConfig::~A2dpCodecConfig() {}
90 
setCodecPriority(btav_a2dp_codec_priority_t codec_priority)91 void A2dpCodecConfig::setCodecPriority(
92     btav_a2dp_codec_priority_t codec_priority) {
93   if (codec_priority == BTAV_A2DP_CODEC_PRIORITY_DEFAULT) {
94     // Compute the default codec priority
95     setDefaultCodecPriority();
96   } else {
97     codec_priority_ = codec_priority;
98   }
99   codec_config_.codec_priority = codec_priority_;
100 }
101 
setDefaultCodecPriority()102 void A2dpCodecConfig::setDefaultCodecPriority() {
103   if (default_codec_priority_ != BTAV_A2DP_CODEC_PRIORITY_DEFAULT) {
104     codec_priority_ = default_codec_priority_;
105   } else {
106     // Compute the default codec priority
107     uint32_t priority = 1000 * (codec_index_ + 1) + 1;
108     codec_priority_ = static_cast<btav_a2dp_codec_priority_t>(priority);
109   }
110   codec_config_.codec_priority = codec_priority_;
111 }
112 
createCodec(btav_a2dp_codec_index_t codec_index,btav_a2dp_codec_priority_t codec_priority)113 A2dpCodecConfig* A2dpCodecConfig::createCodec(
114     btav_a2dp_codec_index_t codec_index,
115     btav_a2dp_codec_priority_t codec_priority) {
116   log::info("{}", A2DP_CodecIndexStr(codec_index));
117 
118   // Hardware offload codec extensibility:
119   // management of the codec is moved under the ProviderInfo
120   // class of the aidl audio HAL client.
121   if (::bluetooth::audio::a2dp::provider::supports_codec(codec_index)) {
122     return new A2dpCodecConfigExt(codec_index, true);
123   }
124 
125   A2dpCodecConfig* codec_config = nullptr;
126   switch (codec_index) {
127     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
128       codec_config = new A2dpCodecConfigSbcSource(codec_priority);
129       break;
130     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
131       codec_config = new A2dpCodecConfigSbcSink(codec_priority);
132       break;
133 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
134     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
135       codec_config = new A2dpCodecConfigAacSource(codec_priority);
136       break;
137     case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
138       codec_config = new A2dpCodecConfigAacSink(codec_priority);
139       break;
140     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
141       codec_config = new A2dpCodecConfigAptx(codec_priority);
142       break;
143     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
144       codec_config = new A2dpCodecConfigAptxHd(codec_priority);
145       break;
146     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
147       codec_config = new A2dpCodecConfigLdacSource(codec_priority);
148       break;
149     case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
150       codec_config = new A2dpCodecConfigLdacSink(codec_priority);
151       break;
152     case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
153       codec_config = new A2dpCodecConfigOpusSource(codec_priority);
154       break;
155     case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
156       codec_config = new A2dpCodecConfigOpusSink(codec_priority);
157       break;
158 #endif
159     case BTAV_A2DP_CODEC_INDEX_MAX:
160     default:
161       break;
162   }
163 
164   if (codec_config != nullptr) {
165     if (!codec_config->init()) {
166       delete codec_config;
167       codec_config = nullptr;
168     }
169   }
170 
171   return codec_config;
172 }
173 
getTrackBitRate() const174 int A2dpCodecConfig::getTrackBitRate() const {
175   uint8_t p_codec_info[AVDT_CODEC_SIZE];
176   memcpy(p_codec_info, ota_codec_config_, sizeof(ota_codec_config_));
177   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
178 
179   switch (codec_type) {
180     case A2DP_MEDIA_CT_SBC:
181       return A2DP_GetBitrateSbc();
182 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
183     case A2DP_MEDIA_CT_AAC:
184       return A2DP_GetBitRateAac(p_codec_info);
185     case A2DP_MEDIA_CT_NON_A2DP:
186       return A2DP_VendorGetBitRate(p_codec_info);
187 #endif
188     default:
189       break;
190   }
191 
192   log::error("unsupported codec type 0x{:x}", codec_type);
193   return -1;
194 }
195 
getCodecSpecificConfig(tBT_A2DP_OFFLOAD * p_a2dp_offload)196 bool A2dpCodecConfig::getCodecSpecificConfig(tBT_A2DP_OFFLOAD* p_a2dp_offload) {
197   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
198 
199   uint8_t codec_config[AVDT_CODEC_SIZE];
200   uint32_t vendor_id;
201   uint16_t codec_id;
202 
203   memset(p_a2dp_offload->codec_info, 0, sizeof(p_a2dp_offload->codec_info));
204 
205   if (!A2DP_IsSourceCodecValid(ota_codec_config_)) {
206     return false;
207   }
208 
209   memcpy(codec_config, ota_codec_config_, sizeof(ota_codec_config_));
210   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(codec_config);
211   switch (codec_type) {
212     case A2DP_MEDIA_CT_SBC:
213       p_a2dp_offload->codec_info[0] =
214           codec_config[4];  // blk_len | subbands | Alloc Method
215       p_a2dp_offload->codec_info[1] = codec_config[5];  // Min bit pool
216       p_a2dp_offload->codec_info[2] = codec_config[6];  // Max bit pool
217       p_a2dp_offload->codec_info[3] =
218           codec_config[3];  // Sample freq | channel mode
219       break;
220 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
221     case A2DP_MEDIA_CT_AAC:
222       p_a2dp_offload->codec_info[0] = codec_config[3];  // object type
223       p_a2dp_offload->codec_info[1] = codec_config[6];  // VBR | BR
224       break;
225     case A2DP_MEDIA_CT_NON_A2DP:
226       vendor_id = A2DP_VendorCodecGetVendorId(codec_config);
227       codec_id = A2DP_VendorCodecGetCodecId(codec_config);
228       p_a2dp_offload->codec_info[0] = (vendor_id & 0x000000FF);
229       p_a2dp_offload->codec_info[1] = (vendor_id & 0x0000FF00) >> 8;
230       p_a2dp_offload->codec_info[2] = (vendor_id & 0x00FF0000) >> 16;
231       p_a2dp_offload->codec_info[3] = (vendor_id & 0xFF000000) >> 24;
232       p_a2dp_offload->codec_info[4] = (codec_id & 0x000000FF);
233       p_a2dp_offload->codec_info[5] = (codec_id & 0x0000FF00) >> 8;
234       if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
235         if (codec_config_.codec_specific_1 == 0) {  // default is 0, ABR
236           p_a2dp_offload->codec_info[6] =
237               A2DP_LDAC_QUALITY_ABR_OFFLOAD;  // ABR in offload
238         } else {
239           switch (codec_config_.codec_specific_1 % 10) {
240             case 0:
241               p_a2dp_offload->codec_info[6] =
242                   A2DP_LDAC_QUALITY_HIGH;  // High bitrate
243               break;
244             case 1:
245               p_a2dp_offload->codec_info[6] =
246                   A2DP_LDAC_QUALITY_MID;  // Mid birate
247               break;
248             case 2:
249               p_a2dp_offload->codec_info[6] =
250                   A2DP_LDAC_QUALITY_LOW;  // Low birate
251               break;
252             case 3:
253               FALLTHROUGH_INTENDED; /* FALLTHROUGH */
254             default:
255               p_a2dp_offload->codec_info[6] =
256                   A2DP_LDAC_QUALITY_ABR_OFFLOAD;  // ABR in offload
257               break;
258           }
259         }
260         p_a2dp_offload->codec_info[7] =
261             codec_config[10];  // LDAC specific channel mode
262         log::verbose("Ldac specific channelmode ={}",
263                      p_a2dp_offload->codec_info[7]);
264       }
265       break;
266 #endif
267     default:
268       break;
269   }
270   return true;
271 }
272 
isValid() const273 bool A2dpCodecConfig::isValid() const { return true; }
274 
copyOutOtaCodecConfig(uint8_t * p_codec_info)275 bool A2dpCodecConfig::copyOutOtaCodecConfig(uint8_t* p_codec_info) {
276   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
277 
278   // TODO: We should use a mechanism to verify codec config,
279   // not codec capability.
280   if (!A2DP_IsSourceCodecValid(ota_codec_config_)) {
281     return false;
282   }
283   memcpy(p_codec_info, ota_codec_config_, sizeof(ota_codec_config_));
284   return true;
285 }
286 
getCodecConfig()287 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecConfig() {
288   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
289 
290   // TODO: We should check whether the codec config is valid
291   return codec_config_;
292 }
293 
getCodecCapability()294 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecCapability() {
295   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
296 
297   // TODO: We should check whether the codec capability is valid
298   return codec_capability_;
299 }
300 
getCodecLocalCapability()301 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecLocalCapability() {
302   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
303 
304   // TODO: We should check whether the codec capability is valid
305   return codec_local_capability_;
306 }
307 
getCodecSelectableCapability()308 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecSelectableCapability() {
309   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
310 
311   // TODO: We should check whether the codec capability is valid
312   return codec_selectable_capability_;
313 }
314 
getCodecUserConfig()315 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecUserConfig() {
316   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
317 
318   return codec_user_config_;
319 }
320 
getCodecAudioConfig()321 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecAudioConfig() {
322   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
323 
324   return codec_audio_config_;
325 }
326 
getAudioBitsPerSample()327 uint8_t A2dpCodecConfig::getAudioBitsPerSample() {
328   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
329 
330   switch (codec_config_.bits_per_sample) {
331     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
332       return 16;
333     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
334       return 24;
335     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
336       return 32;
337     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
338       break;
339   }
340   return 0;
341 }
342 
isCodecConfigEmpty(const btav_a2dp_codec_config_t & codec_config)343 bool A2dpCodecConfig::isCodecConfigEmpty(
344     const btav_a2dp_codec_config_t& codec_config) {
345   return (
346       (codec_config.codec_priority == BTAV_A2DP_CODEC_PRIORITY_DEFAULT) &&
347       (codec_config.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) &&
348       (codec_config.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) &&
349       (codec_config.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) &&
350       (codec_config.codec_specific_1 == 0) &&
351       (codec_config.codec_specific_2 == 0) &&
352       (codec_config.codec_specific_3 == 0) &&
353       (codec_config.codec_specific_4 == 0));
354 }
355 
setCodecUserConfig(const btav_a2dp_codec_config_t & codec_user_config,const btav_a2dp_codec_config_t & codec_audio_config,const tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params,const uint8_t * p_peer_codec_info,bool is_capability,uint8_t * p_result_codec_config,bool * p_restart_input,bool * p_restart_output,bool * p_config_updated)356 bool A2dpCodecConfig::setCodecUserConfig(
357     const btav_a2dp_codec_config_t& codec_user_config,
358     const btav_a2dp_codec_config_t& codec_audio_config,
359     const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params,
360     const uint8_t* p_peer_codec_info, bool is_capability,
361     uint8_t* p_result_codec_config, bool* p_restart_input,
362     bool* p_restart_output, bool* p_config_updated) {
363   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
364   *p_restart_input = false;
365   *p_restart_output = false;
366   *p_config_updated = false;
367 
368   // Save copies of the current codec config, and the OTA codec config, so they
369   // can be compared for changes.
370   btav_a2dp_codec_config_t saved_codec_config = getCodecConfig();
371   uint8_t saved_ota_codec_config[AVDT_CODEC_SIZE];
372   memcpy(saved_ota_codec_config, ota_codec_config_, sizeof(ota_codec_config_));
373 
374   btav_a2dp_codec_config_t saved_codec_user_config = codec_user_config_;
375   codec_user_config_ = codec_user_config;
376   btav_a2dp_codec_config_t saved_codec_audio_config = codec_audio_config_;
377   codec_audio_config_ = codec_audio_config;
378   bool success =
379       setCodecConfig(p_peer_codec_info, is_capability, p_result_codec_config);
380   if (!success) {
381     // Restore the local copy of the user and audio config
382     codec_user_config_ = saved_codec_user_config;
383     codec_audio_config_ = saved_codec_audio_config;
384     return false;
385   }
386 
387   //
388   // The input (audio data) should be restarted if the audio format has changed
389   //
390   btav_a2dp_codec_config_t new_codec_config = getCodecConfig();
391   if ((saved_codec_config.sample_rate != new_codec_config.sample_rate) ||
392       (saved_codec_config.bits_per_sample !=
393        new_codec_config.bits_per_sample) ||
394       (saved_codec_config.channel_mode != new_codec_config.channel_mode)) {
395     *p_restart_input = true;
396   }
397 
398   //
399   // The output (the connection) should be restarted if OTA codec config
400   // has changed.
401   //
402   if (!A2DP_CodecEquals(saved_ota_codec_config, p_result_codec_config)) {
403     *p_restart_output = true;
404   }
405 
406   if (*p_restart_input || *p_restart_output) *p_config_updated = true;
407 
408   return true;
409 }
410 
codecConfigIsValid(const btav_a2dp_codec_config_t & codec_config)411 bool A2dpCodecConfig::codecConfigIsValid(
412     const btav_a2dp_codec_config_t& codec_config) {
413   return (codec_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) &&
414          (codec_config.sample_rate != BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) &&
415          (codec_config.bits_per_sample !=
416           BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) &&
417          (codec_config.channel_mode != BTAV_A2DP_CODEC_CHANNEL_MODE_NONE);
418 }
419 
codecConfig2Str(const btav_a2dp_codec_config_t & codec_config)420 std::string A2dpCodecConfig::codecConfig2Str(
421     const btav_a2dp_codec_config_t& codec_config) {
422   std::string result;
423 
424   if (!codecConfigIsValid(codec_config)) return "Invalid";
425 
426   result.append("Rate=");
427   result.append(codecSampleRate2Str(codec_config.sample_rate));
428   result.append(" Bits=");
429   result.append(codecBitsPerSample2Str(codec_config.bits_per_sample));
430   result.append(" Mode=");
431   result.append(codecChannelMode2Str(codec_config.channel_mode));
432 
433   return result;
434 }
435 
codecSampleRate2Str(btav_a2dp_codec_sample_rate_t codec_sample_rate)436 std::string A2dpCodecConfig::codecSampleRate2Str(
437     btav_a2dp_codec_sample_rate_t codec_sample_rate) {
438   std::string result;
439 
440   if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_44100) {
441     if (!result.empty()) result += "|";
442     result += "44100";
443   }
444   if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_48000) {
445     if (!result.empty()) result += "|";
446     result += "48000";
447   }
448   if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_88200) {
449     if (!result.empty()) result += "|";
450     result += "88200";
451   }
452   if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_96000) {
453     if (!result.empty()) result += "|";
454     result += "96000";
455   }
456   if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_176400) {
457     if (!result.empty()) result += "|";
458     result += "176400";
459   }
460   if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_192000) {
461     if (!result.empty()) result += "|";
462     result += "192000";
463   }
464   if (result.empty()) {
465     std::stringstream ss;
466     ss << "UnknownSampleRate(0x" << std::hex << codec_sample_rate << ")";
467     ss >> result;
468   }
469 
470   return result;
471 }
472 
codecBitsPerSample2Str(btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample)473 std::string A2dpCodecConfig::codecBitsPerSample2Str(
474     btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample) {
475   std::string result;
476 
477   if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16) {
478     if (!result.empty()) result += "|";
479     result += "16";
480   }
481   if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24) {
482     if (!result.empty()) result += "|";
483     result += "24";
484   }
485   if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32) {
486     if (!result.empty()) result += "|";
487     result += "32";
488   }
489   if (result.empty()) {
490     std::stringstream ss;
491     ss << "UnknownBitsPerSample(0x" << std::hex << codec_bits_per_sample << ")";
492     ss >> result;
493   }
494 
495   return result;
496 }
497 
codecChannelMode2Str(btav_a2dp_codec_channel_mode_t codec_channel_mode)498 std::string A2dpCodecConfig::codecChannelMode2Str(
499     btav_a2dp_codec_channel_mode_t codec_channel_mode) {
500   std::string result;
501 
502   if (codec_channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_MONO) {
503     if (!result.empty()) result += "|";
504     result += "MONO";
505   }
506   if (codec_channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO) {
507     if (!result.empty()) result += "|";
508     result += "STEREO";
509   }
510   if (result.empty()) {
511     std::stringstream ss;
512     ss << "UnknownChannelMode(0x" << std::hex << codec_channel_mode << ")";
513     ss >> result;
514   }
515 
516   return result;
517 }
518 
debug_codec_dump(int fd)519 void A2dpCodecConfig::debug_codec_dump(int fd) {
520   std::string result;
521   dprintf(fd, "\nA2DP %s State:\n", name().c_str());
522   dprintf(fd, "  Priority: %d\n", codecPriority());
523 
524   result = codecConfig2Str(getCodecConfig());
525   dprintf(fd, "  Config: %s\n", result.c_str());
526 
527   result = codecConfig2Str(getCodecSelectableCapability());
528   dprintf(fd, "  Selectable: %s\n", result.c_str());
529 
530   result = codecConfig2Str(getCodecLocalCapability());
531   dprintf(fd, "  Local capability: %s\n", result.c_str());
532 }
533 
A2DP_IotGetPeerSinkCodecType(const uint8_t * p_codec_info)534 int A2DP_IotGetPeerSinkCodecType(const uint8_t* p_codec_info) {
535   int peer_codec_type = 0;
536   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
537   log::verbose("codec_type = 0x{:x}", codec_type);
538   switch (codec_type) {
539     case A2DP_MEDIA_CT_SBC:
540       peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_SBC;
541       break;
542 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
543     case A2DP_MEDIA_CT_NON_A2DP: {
544       uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
545       uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
546 
547       log::verbose("codec_id = {}", codec_id);
548       log::verbose("vendor_id = {:x}", vendor_id);
549 
550       if (codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH &&
551           vendor_id == A2DP_APTX_VENDOR_ID) {
552         peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_APTX;
553       } else if (codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH &&
554                  vendor_id == A2DP_APTX_HD_VENDOR_ID) {
555         peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_APTXHD;
556       } else if (codec_id == A2DP_LDAC_CODEC_ID &&
557                  vendor_id == A2DP_LDAC_VENDOR_ID) {
558         peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_LDAC;
559       }
560       break;
561     }
562     case A2DP_MEDIA_CT_AAC:
563       peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_AAC;
564       break;
565 #endif
566     default:
567       break;
568   }
569   return peer_codec_type;
570 }
571 
572 //
573 // Compares two codecs |lhs| and |rhs| based on their priority.
574 // Returns true if |lhs| has higher priority (larger priority value).
575 // If |lhs| and |rhs| have same priority, the unique codec index is used
576 // as a tie-breaker: larger codec index value means higher priority.
577 //
compare_codec_priority(const A2dpCodecConfig * lhs,const A2dpCodecConfig * rhs)578 static bool compare_codec_priority(const A2dpCodecConfig* lhs,
579                                    const A2dpCodecConfig* rhs) {
580   if (lhs->codecPriority() > rhs->codecPriority()) return true;
581   if (lhs->codecPriority() < rhs->codecPriority()) return false;
582   return (lhs->codecIndex() > rhs->codecIndex());
583 }
584 
A2dpCodecs(const std::vector<btav_a2dp_codec_config_t> & codec_priorities)585 A2dpCodecs::A2dpCodecs(
586     const std::vector<btav_a2dp_codec_config_t>& codec_priorities)
587     : current_codec_config_(nullptr) {
588   for (auto config : codec_priorities) {
589     codec_priorities_.insert(
590         std::make_pair(config.codec_type, config.codec_priority));
591   }
592 }
593 
~A2dpCodecs()594 A2dpCodecs::~A2dpCodecs() {
595   std::unique_lock<std::recursive_mutex> lock(codec_mutex_);
596   for (const auto& iter : indexed_codecs_) {
597     delete iter.second;
598   }
599   for (const auto& iter : disabled_codecs_) {
600     delete iter.second;
601   }
602   lock.unlock();
603 }
604 
init()605 bool A2dpCodecs::init() {
606   log::info("");
607   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
608 
609   bool opus_enabled =
610       osi_property_get_bool("persist.bluetooth.opus.enabled", false);
611 
612   for (int i = BTAV_A2DP_CODEC_INDEX_MIN; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
613     btav_a2dp_codec_index_t codec_index =
614         static_cast<btav_a2dp_codec_index_t>(i);
615 
616     // Select the codec priority if explicitly configured
617     btav_a2dp_codec_priority_t codec_priority =
618         BTAV_A2DP_CODEC_PRIORITY_DEFAULT;
619     auto cp_iter = codec_priorities_.find(codec_index);
620     if (cp_iter != codec_priorities_.end()) {
621       codec_priority = cp_iter->second;
622     }
623 
624 #if !defined(UNIT_TESTS)
625     if (codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS) {
626       if (!bluetooth::audio::a2dp::is_opus_supported()) {
627         // We are using HIDL HAL which does not support OPUS codec
628         // Mark OPUS as disabled
629         opus_enabled = false;
630       }
631     }
632 #endif
633 
634     // If OPUS is not supported it is disabled
635     if (codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS && !opus_enabled) {
636       codec_priority = BTAV_A2DP_CODEC_PRIORITY_DISABLED;
637       log::info("OPUS codec disabled, updated priority to {}", codec_priority);
638     }
639 
640     A2dpCodecConfig* codec_config =
641         A2dpCodecConfig::createCodec(codec_index, codec_priority);
642     if (codec_config == nullptr) continue;
643 
644     if (codec_priority != BTAV_A2DP_CODEC_PRIORITY_DEFAULT) {
645       log::info("updated {} codec priority to {}", codec_config->name(),
646                 codec_priority);
647     }
648 
649     // Test if the codec is disabled
650     if (codec_config->codecPriority() == BTAV_A2DP_CODEC_PRIORITY_DISABLED) {
651       disabled_codecs_.insert(std::make_pair(codec_index, codec_config));
652       continue;
653     }
654 
655     indexed_codecs_.insert(std::make_pair(codec_index, codec_config));
656 
657     if (codec_index < BTAV_A2DP_CODEC_INDEX_SOURCE_MAX) {
658       ordered_source_codecs_.push_back(codec_config);
659       ordered_source_codecs_.sort(compare_codec_priority);
660     } else {
661       ordered_sink_codecs_.push_back(codec_config);
662       ordered_sink_codecs_.sort(compare_codec_priority);
663     }
664   }
665 
666   if (ordered_source_codecs_.empty()) {
667     log::error("no Source codecs were initialized");
668   } else {
669     for (auto iter : ordered_source_codecs_) {
670       log::info("initialized Source codec {}, idx {}", iter->name(),
671                 iter->codecIndex());
672     }
673   }
674   if (ordered_sink_codecs_.empty()) {
675     log::error("no Sink codecs were initialized");
676   } else {
677     for (auto iter : ordered_sink_codecs_) {
678       log::info("initialized Sink codec {}, idx {}", iter->name(),
679                 iter->codecIndex());
680     }
681   }
682 
683   return (!ordered_source_codecs_.empty() && !ordered_sink_codecs_.empty());
684 }
685 
findSourceCodecConfig(const uint8_t * p_codec_info)686 A2dpCodecConfig* A2dpCodecs::findSourceCodecConfig(
687     const uint8_t* p_codec_info) {
688   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
689   btav_a2dp_codec_index_t codec_index = A2DP_SourceCodecIndex(p_codec_info);
690   if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) return nullptr;
691 
692   auto iter = indexed_codecs_.find(codec_index);
693   if (iter == indexed_codecs_.end()) return nullptr;
694   return iter->second;
695 }
696 
findSourceCodecConfig(btav_a2dp_codec_index_t codec_index)697 A2dpCodecConfig* A2dpCodecs::findSourceCodecConfig(
698     btav_a2dp_codec_index_t codec_index) {
699   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
700 
701   auto iter = indexed_codecs_.find(codec_index);
702   if (iter == indexed_codecs_.end()) return nullptr;
703   return iter->second;
704 }
705 
findSinkCodecConfig(const uint8_t * p_codec_info)706 A2dpCodecConfig* A2dpCodecs::findSinkCodecConfig(const uint8_t* p_codec_info) {
707   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
708   btav_a2dp_codec_index_t codec_index = A2DP_SinkCodecIndex(p_codec_info);
709   if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) return nullptr;
710 
711   auto iter = indexed_codecs_.find(codec_index);
712   if (iter == indexed_codecs_.end()) return nullptr;
713   return iter->second;
714 }
715 
isSupportedCodec(btav_a2dp_codec_index_t codec_index)716 bool A2dpCodecs::isSupportedCodec(btav_a2dp_codec_index_t codec_index) {
717   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
718   return indexed_codecs_.find(codec_index) != indexed_codecs_.end();
719 }
720 
setCodecConfig(const uint8_t * p_peer_codec_info,bool is_capability,uint8_t * p_result_codec_config,bool select_current_codec)721 bool A2dpCodecs::setCodecConfig(const uint8_t* p_peer_codec_info,
722                                 bool is_capability,
723                                 uint8_t* p_result_codec_config,
724                                 bool select_current_codec) {
725   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
726   A2dpCodecConfig* a2dp_codec_config = findSourceCodecConfig(p_peer_codec_info);
727   if (a2dp_codec_config == nullptr) return false;
728   if (!a2dp_codec_config->setCodecConfig(p_peer_codec_info, is_capability,
729                                          p_result_codec_config)) {
730     return false;
731   }
732   if (select_current_codec) {
733     current_codec_config_ = a2dp_codec_config;
734   }
735   return true;
736 }
737 
setSinkCodecConfig(const uint8_t * p_peer_codec_info,bool is_capability,uint8_t * p_result_codec_config,bool select_current_codec)738 bool A2dpCodecs::setSinkCodecConfig(const uint8_t* p_peer_codec_info,
739                                     bool is_capability,
740                                     uint8_t* p_result_codec_config,
741                                     bool select_current_codec) {
742   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
743   A2dpCodecConfig* a2dp_codec_config = findSinkCodecConfig(p_peer_codec_info);
744   if (a2dp_codec_config == nullptr) return false;
745   if (!a2dp_codec_config->setCodecConfig(p_peer_codec_info, is_capability,
746                                          p_result_codec_config)) {
747     return false;
748   }
749   if (select_current_codec) {
750     current_codec_config_ = a2dp_codec_config;
751   }
752   return true;
753 }
754 
setCodecUserConfig(const btav_a2dp_codec_config_t & codec_user_config,const tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params,const uint8_t * p_peer_sink_capabilities,uint8_t * p_result_codec_config,bool * p_restart_input,bool * p_restart_output,bool * p_config_updated)755 bool A2dpCodecs::setCodecUserConfig(
756     const btav_a2dp_codec_config_t& codec_user_config,
757     const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params,
758     const uint8_t* p_peer_sink_capabilities, uint8_t* p_result_codec_config,
759     bool* p_restart_input, bool* p_restart_output, bool* p_config_updated) {
760   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
761   btav_a2dp_codec_config_t codec_audio_config;
762   A2dpCodecConfig* a2dp_codec_config = nullptr;
763   A2dpCodecConfig* last_codec_config = current_codec_config_;
764   *p_restart_input = false;
765   *p_restart_output = false;
766   *p_config_updated = false;
767 
768   log::info("Configuring: {}", codec_user_config.ToString());
769 
770   if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) {
771     auto iter = indexed_codecs_.find(codec_user_config.codec_type);
772     if (iter == indexed_codecs_.end()) goto fail;
773     a2dp_codec_config = iter->second;
774   } else {
775     // Update the default codec
776     a2dp_codec_config = current_codec_config_;
777   }
778   if (a2dp_codec_config == nullptr) goto fail;
779 
780   // Reuse the existing codec audio config
781   codec_audio_config = a2dp_codec_config->getCodecAudioConfig();
782   if (!a2dp_codec_config->setCodecUserConfig(
783           codec_user_config, codec_audio_config, p_peer_params,
784           p_peer_sink_capabilities, true, p_result_codec_config,
785           p_restart_input, p_restart_output, p_config_updated)) {
786     goto fail;
787   }
788 
789   // Update the codec priorities, and eventually restart the connection
790   // if a new codec needs to be selected.
791   do {
792     // Update the codec priority
793     btav_a2dp_codec_priority_t old_priority =
794         a2dp_codec_config->codecPriority();
795     btav_a2dp_codec_priority_t new_priority = codec_user_config.codec_priority;
796     a2dp_codec_config->setCodecPriority(new_priority);
797     // Get the actual (recomputed) priority
798     new_priority = a2dp_codec_config->codecPriority();
799 
800     // Check if there was no previous codec
801     if (last_codec_config == nullptr) {
802       current_codec_config_ = a2dp_codec_config;
803       *p_restart_input = true;
804       *p_restart_output = true;
805       break;
806     }
807 
808     // Check if the priority of the current codec was updated
809     if (a2dp_codec_config == last_codec_config) {
810       if (old_priority == new_priority) break;  // No change in priority
811 
812       *p_config_updated = true;
813       if (new_priority < old_priority) {
814         // The priority has become lower - restart the connection to
815         // select a new codec.
816         *p_restart_output = true;
817       }
818       break;
819     }
820 
821     if (new_priority <= old_priority) {
822       // No change in priority, or the priority has become lower.
823       // This wasn't the current codec, so we shouldn't select a new codec.
824       if (*p_restart_input || *p_restart_output ||
825           (old_priority != new_priority)) {
826         *p_config_updated = true;
827       }
828       *p_restart_input = false;
829       *p_restart_output = false;
830       break;
831     }
832 
833     *p_config_updated = true;
834     if (new_priority >= last_codec_config->codecPriority()) {
835       // The new priority is higher than the current codec. Restart the
836       // connection to select a new codec.
837       current_codec_config_ = a2dp_codec_config;
838       last_codec_config->setDefaultCodecPriority();
839       *p_restart_input = true;
840       *p_restart_output = true;
841     }
842   } while (false);
843   ordered_source_codecs_.sort(compare_codec_priority);
844 
845   if (*p_restart_input || *p_restart_output) *p_config_updated = true;
846 
847   log::info(
848       "Configured: restart_input = {} restart_output = {} config_updated = {}",
849       *p_restart_input, *p_restart_output, *p_config_updated);
850 
851   return true;
852 
853 fail:
854   current_codec_config_ = last_codec_config;
855   return false;
856 }
857 
setCodecAudioConfig(const btav_a2dp_codec_config_t & codec_audio_config,const tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params,const uint8_t * p_peer_sink_capabilities,uint8_t * p_result_codec_config,bool * p_restart_output,bool * p_config_updated)858 bool A2dpCodecs::setCodecAudioConfig(
859     const btav_a2dp_codec_config_t& codec_audio_config,
860     const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params,
861     const uint8_t* p_peer_sink_capabilities, uint8_t* p_result_codec_config,
862     bool* p_restart_output, bool* p_config_updated) {
863   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
864   btav_a2dp_codec_config_t codec_user_config;
865   A2dpCodecConfig* a2dp_codec_config = current_codec_config_;
866   *p_restart_output = false;
867   *p_config_updated = false;
868 
869   if (a2dp_codec_config == nullptr) return false;
870 
871   // Reuse the existing codec user config
872   codec_user_config = a2dp_codec_config->getCodecUserConfig();
873   bool restart_input = false;  // Flag ignored - input was just restarted
874   if (!a2dp_codec_config->setCodecUserConfig(
875           codec_user_config, codec_audio_config, p_peer_params,
876           p_peer_sink_capabilities, true, p_result_codec_config, &restart_input,
877           p_restart_output, p_config_updated)) {
878     return false;
879   }
880 
881   return true;
882 }
883 
setCodecOtaConfig(const uint8_t * p_ota_codec_config,const tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params,uint8_t * p_result_codec_config,bool * p_restart_input,bool * p_restart_output,bool * p_config_updated)884 bool A2dpCodecs::setCodecOtaConfig(
885     const uint8_t* p_ota_codec_config,
886     const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params,
887     uint8_t* p_result_codec_config, bool* p_restart_input,
888     bool* p_restart_output, bool* p_config_updated) {
889   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
890   btav_a2dp_codec_index_t codec_type;
891   btav_a2dp_codec_config_t codec_user_config;
892   btav_a2dp_codec_config_t codec_audio_config;
893   A2dpCodecConfig* a2dp_codec_config = nullptr;
894   A2dpCodecConfig* last_codec_config = current_codec_config_;
895   *p_restart_input = false;
896   *p_restart_output = false;
897   *p_config_updated = false;
898 
899   // Check whether the current codec config is explicitly configured by
900   // user configuration. If yes, then the OTA codec configuration is ignored.
901   if (current_codec_config_ != nullptr) {
902     codec_user_config = current_codec_config_->getCodecUserConfig();
903     if (!A2dpCodecConfig::isCodecConfigEmpty(codec_user_config)) {
904       log::warn(
905           "ignoring peer OTA configuration for codec {}: existing user "
906           "configuration for current codec {}",
907           A2DP_CodecName(p_ota_codec_config), current_codec_config_->name());
908       goto fail;
909     }
910   }
911 
912   // Check whether the codec config for the same codec is explicitly configured
913   // by user configuration. If yes, then the OTA codec configuration is
914   // ignored.
915   codec_type = A2DP_SourceCodecIndex(p_ota_codec_config);
916   if (codec_type == BTAV_A2DP_CODEC_INDEX_MAX) {
917     log::warn("ignoring peer OTA codec configuration: invalid codec");
918     goto fail;  // Invalid codec
919   } else {
920     auto iter = indexed_codecs_.find(codec_type);
921     if (iter == indexed_codecs_.end()) {
922       log::warn("cannot find codec configuration for peer OTA codec {}",
923                 A2DP_CodecName(p_ota_codec_config));
924       goto fail;
925     }
926     a2dp_codec_config = iter->second;
927   }
928   if (a2dp_codec_config == nullptr) goto fail;
929   codec_user_config = a2dp_codec_config->getCodecUserConfig();
930   if (!A2dpCodecConfig::isCodecConfigEmpty(codec_user_config)) {
931     log::warn(
932         "ignoring peer OTA configuration for codec {}: existing user "
933         "configuration for same codec",
934         A2DP_CodecName(p_ota_codec_config));
935     goto fail;
936   }
937   current_codec_config_ = a2dp_codec_config;
938 
939   // Reuse the existing codec user config and codec audio config
940   codec_audio_config = a2dp_codec_config->getCodecAudioConfig();
941   if (!a2dp_codec_config->setCodecUserConfig(
942           codec_user_config, codec_audio_config, p_peer_params,
943           p_ota_codec_config, false, p_result_codec_config, p_restart_input,
944           p_restart_output, p_config_updated)) {
945     log::warn("cannot set codec configuration for peer OTA codec {}",
946               A2DP_CodecName(p_ota_codec_config));
947     goto fail;
948   }
949   log::assert_that(current_codec_config_ != nullptr,
950                    "assert failed: current_codec_config_ != nullptr");
951 
952   if (*p_restart_input || *p_restart_output) *p_config_updated = true;
953 
954   return true;
955 
956 fail:
957   current_codec_config_ = last_codec_config;
958   return false;
959 }
960 
setPeerSinkCodecCapabilities(const uint8_t * p_peer_codec_capabilities)961 bool A2dpCodecs::setPeerSinkCodecCapabilities(
962     const uint8_t* p_peer_codec_capabilities) {
963   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
964 
965   A2dpCodecConfig* a2dp_codec_config =
966       findSourceCodecConfig(p_peer_codec_capabilities);
967   if (a2dp_codec_config == nullptr) return false;
968 
969   // Bypass the validation for codecs that are offloaded:
970   // the stack does not need to know about the peer capabilities,
971   // since the validation and selection will be performed by the
972   // bluetooth audio HAL for offloaded codecs.
973   if (!::bluetooth::audio::a2dp::provider::supports_codec(
974           a2dp_codec_config->codecIndex()) &&
975       !A2DP_IsPeerSinkCodecValid(p_peer_codec_capabilities))
976     return false;
977 
978   return a2dp_codec_config->setPeerCodecCapabilities(p_peer_codec_capabilities);
979 }
980 
setPeerSourceCodecCapabilities(const uint8_t * p_peer_codec_capabilities)981 bool A2dpCodecs::setPeerSourceCodecCapabilities(
982     const uint8_t* p_peer_codec_capabilities) {
983   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
984 
985   if (!A2DP_IsPeerSourceCodecValid(p_peer_codec_capabilities)) return false;
986   A2dpCodecConfig* a2dp_codec_config =
987       findSinkCodecConfig(p_peer_codec_capabilities);
988   if (a2dp_codec_config == nullptr) return false;
989   return a2dp_codec_config->setPeerCodecCapabilities(p_peer_codec_capabilities);
990 }
991 
getCodecConfigAndCapabilities(btav_a2dp_codec_config_t * p_codec_config,std::vector<btav_a2dp_codec_config_t> * p_codecs_local_capabilities,std::vector<btav_a2dp_codec_config_t> * p_codecs_selectable_capabilities)992 bool A2dpCodecs::getCodecConfigAndCapabilities(
993     btav_a2dp_codec_config_t* p_codec_config,
994     std::vector<btav_a2dp_codec_config_t>* p_codecs_local_capabilities,
995     std::vector<btav_a2dp_codec_config_t>* p_codecs_selectable_capabilities) {
996   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
997 
998   if (current_codec_config_ != nullptr) {
999     *p_codec_config = current_codec_config_->getCodecConfig();
1000   } else {
1001     btav_a2dp_codec_config_t codec_config;
1002     memset(&codec_config, 0, sizeof(codec_config));
1003     *p_codec_config = codec_config;
1004   }
1005 
1006   std::vector<btav_a2dp_codec_config_t> codecs_capabilities;
1007   for (auto codec : orderedSourceCodecs()) {
1008     codecs_capabilities.push_back(codec->getCodecLocalCapability());
1009   }
1010   *p_codecs_local_capabilities = codecs_capabilities;
1011 
1012   codecs_capabilities.clear();
1013   for (auto codec : orderedSourceCodecs()) {
1014     btav_a2dp_codec_config_t codec_capability =
1015         codec->getCodecSelectableCapability();
1016     // Don't add entries that cannot be used
1017     if ((codec_capability.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) ||
1018         (codec_capability.bits_per_sample ==
1019          BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) ||
1020         (codec_capability.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE)) {
1021       continue;
1022     }
1023     codecs_capabilities.push_back(codec_capability);
1024   }
1025   *p_codecs_selectable_capabilities = codecs_capabilities;
1026 
1027   return true;
1028 }
1029 
debug_codec_dump(int fd)1030 void A2dpCodecs::debug_codec_dump(int fd) {
1031   std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
1032   dprintf(fd, "\nA2DP Codecs State:\n");
1033 
1034   // Print the current codec name
1035   if (current_codec_config_ != nullptr) {
1036     dprintf(fd, "  Current Codec: %s\n", current_codec_config_->name().c_str());
1037   } else {
1038     dprintf(fd, "  Current Codec: None\n");
1039   }
1040 
1041   // Print the codec-specific state
1042   for (auto codec_config : ordered_source_codecs_) {
1043     codec_config->debug_codec_dump(fd);
1044   }
1045 }
1046 
A2DP_GetCodecType(const uint8_t * p_codec_info)1047 tA2DP_CODEC_TYPE A2DP_GetCodecType(const uint8_t* p_codec_info) {
1048   return (tA2DP_CODEC_TYPE)(p_codec_info[AVDT_CODEC_TYPE_INDEX]);
1049 }
1050 
A2DP_IsSourceCodecValid(const uint8_t * p_codec_info)1051 bool A2DP_IsSourceCodecValid(const uint8_t* p_codec_info) {
1052   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1053 
1054   switch (codec_type) {
1055     case A2DP_MEDIA_CT_SBC:
1056       return A2DP_IsSourceCodecValidSbc(p_codec_info);
1057 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1058     case A2DP_MEDIA_CT_AAC:
1059       return A2DP_IsSourceCodecValidAac(p_codec_info);
1060     case A2DP_MEDIA_CT_NON_A2DP:
1061       return A2DP_IsVendorSourceCodecValid(p_codec_info);
1062 #endif
1063     default:
1064       break;
1065   }
1066 
1067   return false;
1068 }
1069 
A2DP_IsSinkCodecValid(const uint8_t * p_codec_info)1070 bool A2DP_IsSinkCodecValid(const uint8_t* p_codec_info) {
1071   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1072 
1073   switch (codec_type) {
1074     case A2DP_MEDIA_CT_SBC:
1075       return A2DP_IsSinkCodecValidSbc(p_codec_info);
1076 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1077     case A2DP_MEDIA_CT_AAC:
1078       return A2DP_IsSinkCodecValidAac(p_codec_info);
1079     case A2DP_MEDIA_CT_NON_A2DP:
1080       return A2DP_IsVendorSinkCodecValid(p_codec_info);
1081 #endif
1082     default:
1083       break;
1084   }
1085 
1086   return false;
1087 }
1088 
A2DP_IsPeerSourceCodecValid(const uint8_t * p_codec_info)1089 bool A2DP_IsPeerSourceCodecValid(const uint8_t* p_codec_info) {
1090   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1091 
1092   switch (codec_type) {
1093     case A2DP_MEDIA_CT_SBC:
1094       return A2DP_IsPeerSourceCodecValidSbc(p_codec_info);
1095 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1096     case A2DP_MEDIA_CT_AAC:
1097       return A2DP_IsPeerSourceCodecValidAac(p_codec_info);
1098     case A2DP_MEDIA_CT_NON_A2DP:
1099       return A2DP_IsVendorPeerSourceCodecValid(p_codec_info);
1100 #endif
1101     default:
1102       break;
1103   }
1104 
1105   return false;
1106 }
1107 
A2DP_IsPeerSinkCodecValid(const uint8_t * p_codec_info)1108 bool A2DP_IsPeerSinkCodecValid(const uint8_t* p_codec_info) {
1109   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1110 
1111   switch (codec_type) {
1112     case A2DP_MEDIA_CT_SBC:
1113       return A2DP_IsPeerSinkCodecValidSbc(p_codec_info);
1114 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1115     case A2DP_MEDIA_CT_AAC:
1116       return A2DP_IsPeerSinkCodecValidAac(p_codec_info);
1117     case A2DP_MEDIA_CT_NON_A2DP:
1118       return A2DP_IsVendorPeerSinkCodecValid(p_codec_info);
1119 #endif
1120     default:
1121       break;
1122   }
1123 
1124   return false;
1125 }
1126 
A2DP_IsSinkCodecSupported(const uint8_t * p_codec_info)1127 bool A2DP_IsSinkCodecSupported(const uint8_t* p_codec_info) {
1128   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1129 
1130   switch (codec_type) {
1131     case A2DP_MEDIA_CT_SBC:
1132       return A2DP_IsSinkCodecSupportedSbc(p_codec_info);
1133 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1134     case A2DP_MEDIA_CT_AAC:
1135       return A2DP_IsSinkCodecSupportedAac(p_codec_info);
1136     case A2DP_MEDIA_CT_NON_A2DP:
1137       return A2DP_IsVendorSinkCodecSupported(p_codec_info);
1138 #endif
1139     default:
1140       break;
1141   }
1142 
1143   log::error("unsupported codec type 0x{:x}", codec_type);
1144   return false;
1145 }
1146 
A2DP_IsPeerSourceCodecSupported(const uint8_t * p_codec_info)1147 bool A2DP_IsPeerSourceCodecSupported(const uint8_t* p_codec_info) {
1148   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1149 
1150   switch (codec_type) {
1151     case A2DP_MEDIA_CT_SBC:
1152       return A2DP_IsPeerSourceCodecSupportedSbc(p_codec_info);
1153 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1154     case A2DP_MEDIA_CT_AAC:
1155       return A2DP_IsPeerSourceCodecSupportedAac(p_codec_info);
1156     case A2DP_MEDIA_CT_NON_A2DP:
1157       return A2DP_IsVendorPeerSourceCodecSupported(p_codec_info);
1158 #endif
1159     default:
1160       break;
1161   }
1162 
1163   log::error("unsupported codec type 0x{:x}", codec_type);
1164   return false;
1165 }
1166 
A2DP_InitDefaultCodec(uint8_t * p_codec_info)1167 void A2DP_InitDefaultCodec(uint8_t* p_codec_info) {
1168   A2DP_InitDefaultCodecSbc(p_codec_info);
1169 }
1170 
A2DP_UsesRtpHeader(bool content_protection_enabled,const uint8_t * p_codec_info)1171 bool A2DP_UsesRtpHeader(bool content_protection_enabled,
1172                         const uint8_t* p_codec_info) {
1173   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1174 
1175   if (codec_type != A2DP_MEDIA_CT_NON_A2DP) return true;
1176 
1177 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1178   return A2DP_VendorUsesRtpHeader(content_protection_enabled, p_codec_info);
1179 #else
1180   return true;
1181 #endif
1182 }
1183 
A2DP_GetMediaType(const uint8_t * p_codec_info)1184 uint8_t A2DP_GetMediaType(const uint8_t* p_codec_info) {
1185   uint8_t media_type = (p_codec_info[A2DP_MEDIA_TYPE_OFFSET] >> 4) & 0x0f;
1186   return media_type;
1187 }
1188 
A2DP_CodecName(const uint8_t * p_codec_info)1189 const char* A2DP_CodecName(const uint8_t* p_codec_info) {
1190   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1191 
1192   switch (codec_type) {
1193     case A2DP_MEDIA_CT_SBC:
1194       return A2DP_CodecNameSbc(p_codec_info);
1195 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1196     case A2DP_MEDIA_CT_AAC:
1197       return A2DP_CodecNameAac(p_codec_info);
1198     case A2DP_MEDIA_CT_NON_A2DP:
1199       return A2DP_VendorCodecName(p_codec_info);
1200 #endif
1201     default:
1202       break;
1203   }
1204 
1205   log::error("unsupported codec type 0x{:x}", codec_type);
1206   return "UNKNOWN CODEC";
1207 }
1208 
A2DP_CodecTypeEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)1209 bool A2DP_CodecTypeEquals(const uint8_t* p_codec_info_a,
1210                           const uint8_t* p_codec_info_b) {
1211   tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
1212   tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
1213 
1214   if (codec_type_a != codec_type_b) return false;
1215 
1216   switch (codec_type_a) {
1217     case A2DP_MEDIA_CT_SBC:
1218       return A2DP_CodecTypeEqualsSbc(p_codec_info_a, p_codec_info_b);
1219 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1220     case A2DP_MEDIA_CT_AAC:
1221       return A2DP_CodecTypeEqualsAac(p_codec_info_a, p_codec_info_b);
1222     case A2DP_MEDIA_CT_NON_A2DP:
1223       return A2DP_VendorCodecTypeEquals(p_codec_info_a, p_codec_info_b);
1224 #endif
1225     default:
1226       break;
1227   }
1228 
1229   log::error("unsupported codec type 0x{:x}", codec_type_a);
1230   return false;
1231 }
1232 
A2DP_CodecEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)1233 bool A2DP_CodecEquals(const uint8_t* p_codec_info_a,
1234                       const uint8_t* p_codec_info_b) {
1235   tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
1236   tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
1237 
1238   if (codec_type_a != codec_type_b) return false;
1239 
1240   switch (codec_type_a) {
1241     case A2DP_MEDIA_CT_SBC:
1242       return A2DP_CodecEqualsSbc(p_codec_info_a, p_codec_info_b);
1243 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1244     case A2DP_MEDIA_CT_AAC:
1245       return A2DP_CodecEqualsAac(p_codec_info_a, p_codec_info_b);
1246     case A2DP_MEDIA_CT_NON_A2DP:
1247       return A2DP_VendorCodecEquals(p_codec_info_a, p_codec_info_b);
1248 #endif
1249     default:
1250       break;
1251   }
1252 
1253   log::error("unsupported codec type 0x{:x}", codec_type_a);
1254   return false;
1255 }
1256 
A2DP_GetTrackSampleRate(const uint8_t * p_codec_info)1257 int A2DP_GetTrackSampleRate(const uint8_t* p_codec_info) {
1258   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1259 
1260   switch (codec_type) {
1261     case A2DP_MEDIA_CT_SBC:
1262       return A2DP_GetTrackSampleRateSbc(p_codec_info);
1263 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1264     case A2DP_MEDIA_CT_AAC:
1265       return A2DP_GetTrackSampleRateAac(p_codec_info);
1266     case A2DP_MEDIA_CT_NON_A2DP:
1267       return A2DP_VendorGetTrackSampleRate(p_codec_info);
1268 #endif
1269     default:
1270       break;
1271   }
1272 
1273   log::error("unsupported codec type 0x{:x}", codec_type);
1274   return -1;
1275 }
1276 
A2DP_GetTrackBitsPerSample(const uint8_t * p_codec_info)1277 int A2DP_GetTrackBitsPerSample(const uint8_t* p_codec_info) {
1278   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1279 
1280   switch (codec_type) {
1281     case A2DP_MEDIA_CT_SBC:
1282       return A2DP_GetTrackBitsPerSampleSbc(p_codec_info);
1283 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1284     case A2DP_MEDIA_CT_AAC:
1285       return A2DP_GetTrackBitsPerSampleAac(p_codec_info);
1286     case A2DP_MEDIA_CT_NON_A2DP:
1287       return A2DP_VendorGetTrackBitsPerSample(p_codec_info);
1288 #endif
1289     default:
1290       break;
1291   }
1292 
1293   log::error("unsupported codec type 0x{:x}", codec_type);
1294   return -1;
1295 }
1296 
A2DP_GetTrackChannelCount(const uint8_t * p_codec_info)1297 int A2DP_GetTrackChannelCount(const uint8_t* p_codec_info) {
1298   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1299 
1300   switch (codec_type) {
1301     case A2DP_MEDIA_CT_SBC:
1302       return A2DP_GetTrackChannelCountSbc(p_codec_info);
1303 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1304     case A2DP_MEDIA_CT_AAC:
1305       return A2DP_GetTrackChannelCountAac(p_codec_info);
1306     case A2DP_MEDIA_CT_NON_A2DP:
1307       return A2DP_VendorGetTrackChannelCount(p_codec_info);
1308 #endif
1309     default:
1310       break;
1311   }
1312 
1313   log::error("unsupported codec type 0x{:x}", codec_type);
1314   return -1;
1315 }
1316 
A2DP_GetSinkTrackChannelType(const uint8_t * p_codec_info)1317 int A2DP_GetSinkTrackChannelType(const uint8_t* p_codec_info) {
1318   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1319 
1320   switch (codec_type) {
1321     case A2DP_MEDIA_CT_SBC:
1322       return A2DP_GetSinkTrackChannelTypeSbc(p_codec_info);
1323 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1324     case A2DP_MEDIA_CT_AAC:
1325       return A2DP_GetSinkTrackChannelTypeAac(p_codec_info);
1326     case A2DP_MEDIA_CT_NON_A2DP:
1327       return A2DP_VendorGetSinkTrackChannelType(p_codec_info);
1328 #endif
1329     default:
1330       break;
1331   }
1332 
1333   log::error("unsupported codec type 0x{:x}", codec_type);
1334   return -1;
1335 }
1336 
A2DP_GetPacketTimestamp(const uint8_t * p_codec_info,const uint8_t * p_data,uint32_t * p_timestamp)1337 bool A2DP_GetPacketTimestamp(const uint8_t* p_codec_info, const uint8_t* p_data,
1338                              uint32_t* p_timestamp) {
1339   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1340 
1341   switch (codec_type) {
1342     case A2DP_MEDIA_CT_SBC:
1343       return A2DP_GetPacketTimestampSbc(p_codec_info, p_data, p_timestamp);
1344 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1345     case A2DP_MEDIA_CT_AAC:
1346       return A2DP_GetPacketTimestampAac(p_codec_info, p_data, p_timestamp);
1347     case A2DP_MEDIA_CT_NON_A2DP:
1348       return A2DP_VendorGetPacketTimestamp(p_codec_info, p_data, p_timestamp);
1349 #endif
1350     default:
1351       break;
1352   }
1353 
1354   log::error("unsupported codec type 0x{:x}", codec_type);
1355   return false;
1356 }
1357 
A2DP_BuildCodecHeader(const uint8_t * p_codec_info,BT_HDR * p_buf,uint16_t frames_per_packet)1358 bool A2DP_BuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf,
1359                            uint16_t frames_per_packet) {
1360   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1361 
1362   switch (codec_type) {
1363     case A2DP_MEDIA_CT_SBC:
1364       return A2DP_BuildCodecHeaderSbc(p_codec_info, p_buf, frames_per_packet);
1365 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1366     case A2DP_MEDIA_CT_AAC:
1367       return A2DP_BuildCodecHeaderAac(p_codec_info, p_buf, frames_per_packet);
1368     case A2DP_MEDIA_CT_NON_A2DP:
1369       return A2DP_VendorBuildCodecHeader(p_codec_info, p_buf,
1370                                          frames_per_packet);
1371 #endif
1372     default:
1373       break;
1374   }
1375 
1376   log::error("unsupported codec type 0x{:x}", codec_type);
1377   return false;
1378 }
1379 
A2DP_GetEncoderInterface(const uint8_t * p_codec_info)1380 const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterface(
1381     const uint8_t* p_codec_info) {
1382   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1383 
1384   if (::bluetooth::audio::a2dp::provider::supports_codec(
1385           A2DP_SourceCodecIndex(p_codec_info))) {
1386     return A2DP_GetEncoderInterfaceExt(p_codec_info);
1387   }
1388 
1389   switch (codec_type) {
1390     case A2DP_MEDIA_CT_SBC:
1391       return A2DP_GetEncoderInterfaceSbc(p_codec_info);
1392 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1393     case A2DP_MEDIA_CT_AAC:
1394       return A2DP_GetEncoderInterfaceAac(p_codec_info);
1395     case A2DP_MEDIA_CT_NON_A2DP:
1396       return A2DP_VendorGetEncoderInterface(p_codec_info);
1397 #endif
1398     default:
1399       break;
1400   }
1401 
1402   log::error("unsupported codec type 0x{:x}", codec_type);
1403   return NULL;
1404 }
1405 
A2DP_GetDecoderInterface(const uint8_t * p_codec_info)1406 const tA2DP_DECODER_INTERFACE* A2DP_GetDecoderInterface(
1407     const uint8_t* p_codec_info) {
1408   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1409 
1410   switch (codec_type) {
1411     case A2DP_MEDIA_CT_SBC:
1412       return A2DP_GetDecoderInterfaceSbc(p_codec_info);
1413 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1414     case A2DP_MEDIA_CT_AAC:
1415       return A2DP_GetDecoderInterfaceAac(p_codec_info);
1416     case A2DP_MEDIA_CT_NON_A2DP:
1417       return A2DP_VendorGetDecoderInterface(p_codec_info);
1418 #endif
1419     default:
1420       break;
1421   }
1422 
1423   log::error("unsupported codec type 0x{:x}", codec_type);
1424   return NULL;
1425 }
1426 
A2DP_AdjustCodec(uint8_t * p_codec_info)1427 bool A2DP_AdjustCodec(uint8_t* p_codec_info) {
1428   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1429 
1430   switch (codec_type) {
1431     case A2DP_MEDIA_CT_SBC:
1432       return A2DP_AdjustCodecSbc(p_codec_info);
1433 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1434     case A2DP_MEDIA_CT_AAC:
1435       return A2DP_AdjustCodecAac(p_codec_info);
1436     case A2DP_MEDIA_CT_NON_A2DP:
1437       return A2DP_VendorAdjustCodec(p_codec_info);
1438 #endif
1439     default:
1440       break;
1441   }
1442 
1443   log::error("unsupported codec type 0x{:x}", codec_type);
1444   return false;
1445 }
1446 
A2DP_SourceCodecIndex(const uint8_t * p_codec_info)1447 btav_a2dp_codec_index_t A2DP_SourceCodecIndex(const uint8_t* p_codec_info) {
1448   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1449 
1450   auto ext_codec_index =
1451       bluetooth::audio::a2dp::provider::source_codec_index(p_codec_info);
1452   if (ext_codec_index.has_value()) {
1453     return ext_codec_index.value();
1454   }
1455 
1456   switch (codec_type) {
1457     case A2DP_MEDIA_CT_SBC:
1458       return A2DP_SourceCodecIndexSbc(p_codec_info);
1459 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1460     case A2DP_MEDIA_CT_AAC:
1461       return A2DP_SourceCodecIndexAac(p_codec_info);
1462     case A2DP_MEDIA_CT_NON_A2DP:
1463       return A2DP_VendorSourceCodecIndex(p_codec_info);
1464 #endif
1465     default:
1466       break;
1467   }
1468 
1469   log::error("unsupported codec type 0x{:x}", codec_type);
1470   return BTAV_A2DP_CODEC_INDEX_MAX;
1471 }
1472 
A2DP_SinkCodecIndex(const uint8_t * p_codec_info)1473 btav_a2dp_codec_index_t A2DP_SinkCodecIndex(const uint8_t* p_codec_info) {
1474   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1475 
1476   auto ext_codec_index =
1477       bluetooth::audio::a2dp::provider::sink_codec_index(p_codec_info);
1478   if (ext_codec_index.has_value()) {
1479     return ext_codec_index.value();
1480   }
1481 
1482   switch (codec_type) {
1483     case A2DP_MEDIA_CT_SBC:
1484       return A2DP_SinkCodecIndexSbc(p_codec_info);
1485 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1486     case A2DP_MEDIA_CT_AAC:
1487       return A2DP_SinkCodecIndexAac(p_codec_info);
1488     case A2DP_MEDIA_CT_NON_A2DP:
1489       return A2DP_VendorSinkCodecIndex(p_codec_info);
1490 #endif
1491     default:
1492       break;
1493   }
1494 
1495   log::error("unsupported codec type 0x{:x}", codec_type);
1496   return BTAV_A2DP_CODEC_INDEX_MAX;
1497 }
1498 
A2DP_CodecIndexStr(btav_a2dp_codec_index_t codec_index)1499 const char* A2DP_CodecIndexStr(btav_a2dp_codec_index_t codec_index) {
1500   if ((codec_index >= BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN &&
1501        codec_index < BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX) ||
1502       (codec_index >= BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN &&
1503        codec_index < BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX)) {
1504     auto codec_index_str =
1505         bluetooth::audio::a2dp::provider::codec_index_str(codec_index);
1506     if (codec_index_str.has_value()) {
1507       return codec_index_str.value();
1508     }
1509   }
1510 
1511   switch (codec_index) {
1512     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
1513       return A2DP_CodecIndexStrSbc();
1514     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
1515       return A2DP_CodecIndexStrSbcSink();
1516 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1517     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
1518       return A2DP_CodecIndexStrAac();
1519     case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
1520       return A2DP_CodecIndexStrAacSink();
1521 #endif
1522     default:
1523       break;
1524   }
1525 
1526 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1527   if (codec_index < BTAV_A2DP_CODEC_INDEX_MAX)
1528     return A2DP_VendorCodecIndexStr(codec_index);
1529 #endif
1530 
1531   return "UNKNOWN CODEC INDEX";
1532 }
1533 
A2DP_InitCodecConfig(btav_a2dp_codec_index_t codec_index,AvdtpSepConfig * p_cfg)1534 bool A2DP_InitCodecConfig(btav_a2dp_codec_index_t codec_index,
1535                           AvdtpSepConfig* p_cfg) {
1536   log::verbose("codec {}", A2DP_CodecIndexStr(codec_index));
1537 
1538   /* Default: no content protection info */
1539   p_cfg->num_protect = 0;
1540   p_cfg->protect_info[0] = 0;
1541 
1542   if (::bluetooth::audio::a2dp::provider::supports_codec(codec_index)) {
1543     return ::bluetooth::audio::a2dp::provider::codec_info(
1544         codec_index, nullptr, p_cfg->codec_info, nullptr);
1545   }
1546 
1547   switch (codec_index) {
1548     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
1549       return A2DP_InitCodecConfigSbc(p_cfg);
1550     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
1551       return A2DP_InitCodecConfigSbcSink(p_cfg);
1552 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1553     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
1554       return A2DP_InitCodecConfigAac(p_cfg);
1555     case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
1556       return A2DP_InitCodecConfigAacSink(p_cfg);
1557 #endif
1558     default:
1559       break;
1560   }
1561 
1562 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1563   if (codec_index < BTAV_A2DP_CODEC_INDEX_MAX)
1564     return A2DP_VendorInitCodecConfig(codec_index, p_cfg);
1565 #endif
1566 
1567   return false;
1568 }
1569 
A2DP_CodecInfoString(const uint8_t * p_codec_info)1570 std::string A2DP_CodecInfoString(const uint8_t* p_codec_info) {
1571   tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1572 
1573   switch (codec_type) {
1574     case A2DP_MEDIA_CT_SBC:
1575       return A2DP_CodecInfoStringSbc(p_codec_info);
1576 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1577     case A2DP_MEDIA_CT_AAC:
1578       return A2DP_CodecInfoStringAac(p_codec_info);
1579     case A2DP_MEDIA_CT_NON_A2DP:
1580       return A2DP_VendorCodecInfoString(p_codec_info);
1581 #endif
1582     default:
1583       break;
1584   }
1585 
1586   return "Unsupported codec type: " + loghex(codec_type);
1587 }
1588 
A2DP_GetEecoderEffectiveFrameSize(const uint8_t * p_codec_info)1589 int A2DP_GetEecoderEffectiveFrameSize(const uint8_t* p_codec_info) {
1590   const tA2DP_ENCODER_INTERFACE* a2dp_encoder_interface =
1591       A2DP_GetEncoderInterface(p_codec_info);
1592   return a2dp_encoder_interface
1593              ? a2dp_encoder_interface->get_effective_frame_size()
1594              : 0;
1595 }
1596