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