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