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