1 /******************************************************************************
2  *
3  *  Copyright 2004-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This is the advanced audio/video call-out function implementation for
22  *  BTIF.
23  *
24  ******************************************************************************/
25 
26 #define LOG_TAG "bluetooth-a2dp"
27 
28 #include "btif/include/bta_av_co.h"
29 
30 #include <bluetooth/log.h>
31 #include <com_android_bluetooth_flags.h>
32 
33 #include <mutex>
34 #include <optional>
35 #include <vector>
36 
37 #include "audio_hal_interface/a2dp_encoding.h"
38 #include "bta/include/bta_av_api.h"
39 #include "bta/include/bta_av_ci.h"
40 #include "btif/include/bta_av_co_peer.h"
41 #include "btif/include/btif_a2dp_source.h"
42 #include "btif/include/btif_av.h"
43 #include "device/include/device_iot_config.h"
44 #include "include/hardware/bt_av.h"
45 #include "internal_include/bt_trace.h"
46 #include "osi/include/allocator.h"
47 #include "stack/include/a2dp_codec_api.h"
48 #include "stack/include/a2dp_error_codes.h"
49 #include "stack/include/a2dp_ext.h"
50 #include "stack/include/avdt_api.h"
51 #include "stack/include/bt_hdr.h"
52 #include "stack/include/bt_types.h"
53 #include "stack/include/bt_uuid16.h"
54 #include "types/raw_address.h"
55 
56 using namespace bluetooth;
57 
58 // SCMS-T protect info
59 const uint8_t bta_av_co_cp_scmst[AVDT_CP_INFO_LEN] = {0x02, 0x02, 0x00};
60 
61 // Control block instance
62 static const bool kContentProtectEnabled = false;
63 static BtaAvCo bta_av_co_cb(kContentProtectEnabled, new BtaAvCoPeerCache());
64 
setActivePeer(BtaAvCoPeer * peer)65 void BtaAvCoState::setActivePeer(BtaAvCoPeer* peer) { active_peer_ = peer; }
66 
getActivePeer() const67 BtaAvCoPeer* BtaAvCoState::getActivePeer() const { return active_peer_; }
68 
getCodecConfig()69 uint8_t* BtaAvCoState::getCodecConfig() { return codec_config_; }
70 
setCodecConfig(const uint8_t * codec_config)71 void BtaAvCoState::setCodecConfig(const uint8_t* codec_config) {
72   memcpy(codec_config_, codec_config, AVDT_CODEC_SIZE);
73 }
74 
clearCodecConfig()75 void BtaAvCoState::clearCodecConfig() {
76   memset(codec_config_, 0, AVDT_CODEC_SIZE);
77 }
78 
Reset()79 void BtaAvCoState::Reset() {
80   active_peer_ = nullptr;
81   clearCodecConfig();
82 }
83 
Init(const std::vector<btav_a2dp_codec_config_t> & codec_priorities,std::vector<btav_a2dp_codec_info_t> * supported_codecs)84 void BtaAvCo::Init(
85     const std::vector<btav_a2dp_codec_config_t>& codec_priorities,
86     std::vector<btav_a2dp_codec_info_t>* supported_codecs) {
87   log::verbose("");
88 
89   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
90 
91   // Reset the control block
92   Reset();
93   peer_cache_->Init(codec_priorities, supported_codecs);
94 
95   // Gather the supported codecs from the first peer context;
96   // all contexes should be identical.
97   supported_codecs->clear();
98   for (auto* codec_config :
99        peer_cache_->peers_[0].GetCodecs()->orderedSourceCodecs()) {
100     auto& codec_info = supported_codecs->emplace_back();
101     codec_info.codec_type = codec_config->codecIndex();
102     codec_info.codec_id = codec_config->codecId();
103     codec_info.codec_name = codec_config->name();
104   }
105 }
106 
Reset()107 void BtaAvCo::Reset() {
108   bta_av_legacy_state_.Reset();
109   bta_av_source_state_.Reset();
110   bta_av_sink_state_.Reset();
111   content_protect_flag_ = 0;
112 
113   if (ContentProtectEnabled()) {
114     SetContentProtectFlag(AVDT_CP_SCMS_COPY_NEVER);
115   } else {
116     SetContentProtectFlag(AVDT_CP_SCMS_COPY_FREE);
117   }
118 
119   peer_cache_->Reset();
120 }
121 
IsSupportedCodec(btav_a2dp_codec_index_t codec_index)122 bool BtaAvCo::IsSupportedCodec(btav_a2dp_codec_index_t codec_index) {
123   // All peer state is initialized with the same local codec config,
124   // hence we check only the first peer.
125   A2dpCodecs* codecs = peer_cache_->peers_[0].GetCodecs();
126   if (codecs == nullptr) {
127     log::error("Peer codecs is set to null");
128     return false;
129   }
130   return codecs->isSupportedCodec(codec_index);
131 }
132 
GetActivePeerCurrentCodec()133 A2dpCodecConfig* BtaAvCo::GetActivePeerCurrentCodec() {
134   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
135 
136   BtaAvCoState* reference_state = nullptr;
137   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
138     reference_state = &bta_av_source_state_;
139   } else {
140     reference_state = &bta_av_legacy_state_;
141   }
142   BtaAvCoPeer* active_peer = reference_state->getActivePeer();
143   if (active_peer == nullptr || active_peer->GetCodecs() == nullptr) {
144     return nullptr;
145   }
146   return active_peer->GetCodecs()->getCurrentCodecConfig();
147 }
148 
GetPeerCurrentCodec(const RawAddress & peer_address)149 A2dpCodecConfig* BtaAvCo::GetPeerCurrentCodec(const RawAddress& peer_address) {
150   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
151 
152   BtaAvCoPeer* peer = peer_cache_->FindPeer(peer_address);
153   if (peer == nullptr || peer->GetCodecs() == nullptr) {
154     return nullptr;
155   }
156   return peer->GetCodecs()->getCurrentCodecConfig();
157 }
158 
ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint8_t num_seps,uint8_t num_sinks,uint8_t num_sources,uint16_t uuid_local)159 void BtaAvCo::ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle,
160                                      const RawAddress& peer_address,
161                                      uint8_t num_seps, uint8_t num_sinks,
162                                      uint8_t num_sources, uint16_t uuid_local) {
163   log::verbose(
164       "peer {} bta_av_handle:0x{:x} num_seps:{} num_sinks:{} num_sources:{}",
165       peer_address, bta_av_handle, num_seps, num_sinks, num_sources);
166 
167   // Find the peer
168   BtaAvCoPeer* p_peer =
169       peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
170   if (p_peer == nullptr) {
171     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
172                bta_av_handle, peer_address);
173     return;
174   }
175 
176   /* Sanity check : this should never happen */
177   if (p_peer->opened) {
178     log::error("peer {} already opened", peer_address);
179   }
180 
181   /* Copy the discovery results */
182   p_peer->addr = peer_address;
183   p_peer->num_sinks = num_sinks;
184   p_peer->num_sources = num_sources;
185   p_peer->num_seps = num_seps;
186   p_peer->num_rx_sinks = 0;
187   p_peer->num_rx_sources = 0;
188   p_peer->num_sup_sinks = 0;
189   p_peer->num_sup_sources = 0;
190   if (uuid_local == UUID_SERVCLASS_AUDIO_SINK) {
191     p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SOURCE;
192   } else if (uuid_local == UUID_SERVCLASS_AUDIO_SOURCE) {
193     p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SINK;
194   }
195 }
196 
197 static void bta_av_co_store_peer_codectype(const BtaAvCoPeer* p_peer);
198 static bool bta_av_co_should_select_hardware_codec(
199     const A2dpCodecConfig& software_config,
200     const ::bluetooth::audio::a2dp::provider::a2dp_configuration&
201         hardware_config);
202 
ProcessSourceGetConfig(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint8_t * p_codec_info,uint8_t * p_sep_info_idx,uint8_t seid,uint8_t * p_num_protect,uint8_t * p_protect_info)203 tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig(
204     tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
205     uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid,
206     uint8_t* p_num_protect, uint8_t* p_protect_info) {
207   log::verbose("peer {} bta_av_handle:0x{:x} codec:{} seid:{}", peer_address,
208                bta_av_handle, A2DP_CodecName(p_codec_info), seid);
209   log::verbose("num_protect:0x{:02x} protect_info:0x{:02x}{:02x}{:02x}",
210                *p_num_protect, p_protect_info[0], p_protect_info[1],
211                p_protect_info[2]);
212   log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info));
213 
214   // Find the peer
215   BtaAvCoPeer* p_peer =
216       peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
217   if (p_peer == nullptr) {
218     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
219                bta_av_handle, peer_address);
220     return A2DP_FAIL;
221   }
222   log::verbose("peer(o={}, n_sinks={}, n_rx_sinks={}, n_sup_sinks={})",
223                p_peer->opened, p_peer->num_sinks, p_peer->num_rx_sinks,
224                p_peer->num_sup_sinks);
225 
226   p_peer->num_rx_sinks++;
227 
228   // Bypass the validation for codecs that are offloaded:
229   // the stack does not need to know about the peer capabilities,
230   // since the validation and selection will be performed by the
231   // bluetooth audio HAL for offloaded codecs.
232   auto codec_index = A2DP_SourceCodecIndex(p_codec_info);
233   bool is_offloaded_codec =
234       ::bluetooth::audio::a2dp::provider::supports_codec(codec_index);
235 
236   // Check the peer's Sink codec
237   if (is_offloaded_codec || A2DP_IsPeerSinkCodecValid(p_codec_info)) {
238     // If there is room for a new one
239     if (p_peer->num_sup_sinks < BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks)) {
240       BtaAvCoSep* p_sink = &p_peer->sinks[p_peer->num_sup_sinks++];
241 
242       log::verbose("saved caps[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]", p_codec_info[1],
243                    p_codec_info[2], p_codec_info[3], p_codec_info[4],
244                    p_codec_info[5], p_codec_info[6]);
245 
246       memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
247       p_sink->sep_info_idx = *p_sep_info_idx;
248       p_sink->seid = seid;
249       p_sink->num_protect = *p_num_protect;
250       memcpy(p_sink->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
251     } else {
252       log::error("peer {} : no more room for Sink info", p_peer->addr);
253     }
254   }
255 
256   // Check if this is the last Sink get capabilities or all supported codec
257   // capabilities are retrieved.
258   if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
259       (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
260     return A2DP_FAIL;
261   }
262   log::verbose("last Sink codec reached for peer {} (local {})", p_peer->addr,
263                p_peer->acceptor ? "acceptor" : "initiator");
264 
265   bta_av_co_store_peer_codectype(p_peer);
266 
267   // Select the Source codec
268   const BtaAvCoSep* p_sink = nullptr;
269   if (p_peer->acceptor) {
270     UpdateAllSelectableSourceCodecs(p_peer);
271     if (p_peer->p_sink == nullptr) {
272       // Update the selected codec
273       p_peer->p_sink = peer_cache_->FindPeerSink(
274           p_peer, A2DP_SourceCodecIndex(p_peer->codec_config),
275           ContentProtectFlag());
276     }
277     p_sink = p_peer->p_sink;
278     if (p_sink == nullptr) {
279       log::error("cannot find the selected codec for peer {}", p_peer->addr);
280       return A2DP_FAIL;
281     }
282   } else {
283     if (btif_av_peer_prefers_mandatory_codec(p_peer->addr, A2dpType::kSource)) {
284       // Apply user preferred codec directly before first codec selected.
285       p_sink = peer_cache_->FindPeerSink(
286           p_peer, BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, ContentProtectFlag());
287       if (p_sink != nullptr) {
288         log::verbose("mandatory codec preferred for peer {}", p_peer->addr);
289         btav_a2dp_codec_config_t high_priority_mandatory{
290             .codec_type = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC,
291             .codec_priority = BTAV_A2DP_CODEC_PRIORITY_HIGHEST,
292             // Using default settings for those untouched fields
293         };
294         uint8_t result_codec_config[AVDT_CODEC_SIZE];
295         bool restart_input = false;
296         bool restart_output = false;
297         bool config_updated = false;
298         tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
299         GetPeerEncoderParameters(p_peer->addr, &peer_params);
300         p_peer->GetCodecs()->setCodecUserConfig(
301             high_priority_mandatory, &peer_params, p_sink->codec_caps,
302             result_codec_config, &restart_input, &restart_output,
303             &config_updated);
304       } else {
305         log::warn("mandatory codec not found for peer {}", p_peer->addr);
306       }
307     }
308     p_sink = SelectSourceCodec(p_peer);
309     if (p_sink == nullptr) {
310       log::error("cannot set up codec for peer {}", p_peer->addr);
311       return A2DP_FAIL;
312     }
313   }
314 
315   // By default, no content protection
316   *p_num_protect = 0;
317   if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
318     *p_num_protect = AVDT_CP_INFO_LEN;
319     memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN);
320   }
321 
322   // If acceptor -> reconfig otherwise reply for configuration
323   *p_sep_info_idx = p_sink->sep_info_idx;
324   log::verbose("peer {} acceptor:{} reconfig_needed:{}", p_peer->addr,
325                p_peer->acceptor, p_peer->reconfig_needed);
326   if (p_peer->acceptor) {
327     if (p_peer->reconfig_needed) {
328       log::verbose("call BTA_AvReconfig(0x{:x}) for peer {}", bta_av_handle,
329                    p_peer->addr);
330       BTA_AvReconfig(bta_av_handle, true, p_sink->sep_info_idx,
331                      p_peer->codec_config, *p_num_protect, bta_av_co_cp_scmst);
332     }
333   } else {
334     memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
335   }
336 
337   // report this peer selectable codecs after retrieved all its capabilities.
338   log::info("retrieved {} capabilities from peer {}", p_peer->num_rx_sinks,
339             p_peer->addr);
340   ReportSourceCodecState(p_peer);
341 
342   return A2DP_SUCCESS;
343 }
344 
ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint8_t * p_codec_info,uint8_t * p_sep_info_idx,uint8_t seid,uint8_t * p_num_protect,uint8_t * p_protect_info)345 tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
346                                            const RawAddress& peer_address,
347                                            uint8_t* p_codec_info,
348                                            uint8_t* p_sep_info_idx,
349                                            uint8_t seid, uint8_t* p_num_protect,
350                                            uint8_t* p_protect_info) {
351   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
352 
353   log::verbose("peer {} bta_av_handle:0x{:x} codec:{} seid:{}", peer_address,
354                bta_av_handle, A2DP_CodecName(p_codec_info), seid);
355   log::verbose("num_protect:0x{:02x} protect_info:0x{:02x}{:02x}{:02x}",
356                *p_num_protect, p_protect_info[0], p_protect_info[1],
357                p_protect_info[2]);
358   log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info));
359 
360   // Find the peer
361   BtaAvCoPeer* p_peer =
362       peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
363   if (p_peer == nullptr) {
364     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
365                bta_av_handle, peer_address);
366     return A2DP_FAIL;
367   }
368   log::verbose(
369       "peer {} found (o={}, n_sources={}, n_rx_sources={}, n_sup_sources={})",
370       p_peer->addr, p_peer->opened, p_peer->num_sources, p_peer->num_rx_sources,
371       p_peer->num_sup_sources);
372 
373   p_peer->num_rx_sources++;
374 
375   // Check the peer's Source codec
376   if (A2DP_IsPeerSourceCodecValid(p_codec_info)) {
377     // If there is room for a new one
378     if (p_peer->num_sup_sources < BTA_AV_CO_NUM_ELEMENTS(p_peer->sources)) {
379       BtaAvCoSep* p_source = &p_peer->sources[p_peer->num_sup_sources++];
380 
381       log::verbose("saved caps[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]", p_codec_info[1],
382                    p_codec_info[2], p_codec_info[3], p_codec_info[4],
383                    p_codec_info[5], p_codec_info[6]);
384 
385       memcpy(p_source->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
386       p_source->sep_info_idx = *p_sep_info_idx;
387       p_source->seid = seid;
388       p_source->num_protect = *p_num_protect;
389       memcpy(p_source->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
390     } else {
391       log::error("peer {} : no more room for Source info", p_peer->addr);
392     }
393   }
394 
395   // Check if this is the last Source get capabilities or all supported codec
396   // capabilities are retrieved.
397   if ((p_peer->num_rx_sources != p_peer->num_sources) &&
398       (p_peer->num_sup_sources != BTA_AV_CO_NUM_ELEMENTS(p_peer->sources))) {
399     return A2DP_FAIL;
400   }
401   log::verbose("last Source codec reached for peer {}", p_peer->addr);
402 
403   // Select the Sink codec
404   const BtaAvCoSep* p_source = nullptr;
405   if (p_peer->acceptor) {
406     UpdateAllSelectableSinkCodecs(p_peer);
407     if (p_peer->p_source == nullptr) {
408       // Update the selected codec
409       p_peer->p_source = peer_cache_->FindPeerSource(
410           p_peer, A2DP_SinkCodecIndex(p_peer->codec_config),
411           ContentProtectFlag());
412     }
413     p_source = p_peer->p_source;
414     if (p_source == nullptr) {
415       log::error("cannot find the selected codec for peer {}", p_peer->addr);
416       return A2DP_FAIL;
417     }
418   } else {
419     p_source = SelectSinkCodec(p_peer);
420     if (p_source == nullptr) {
421       log::error("cannot set up codec for the peer {}", p_peer->addr);
422       return A2DP_FAIL;
423     }
424   }
425 
426   // By default, no content protection
427   *p_num_protect = 0;
428   if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
429     *p_num_protect = AVDT_CP_INFO_LEN;
430     memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN);
431   }
432 
433   // If acceptor -> reconfig otherwise reply for configuration
434   *p_sep_info_idx = p_source->sep_info_idx;
435   log::verbose("peer {} acceptor:{} reconfig_needed:{}", p_peer->addr,
436                p_peer->acceptor, p_peer->reconfig_needed);
437   if (p_peer->acceptor) {
438     if (p_peer->reconfig_needed) {
439       log::verbose("call BTA_AvReconfig(0x{:x}) for peer {}", bta_av_handle,
440                    p_peer->addr);
441       BTA_AvReconfig(bta_av_handle, true, p_source->sep_info_idx,
442                      p_peer->codec_config, *p_num_protect, bta_av_co_cp_scmst);
443     }
444   } else {
445     memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
446   }
447 
448   return A2DP_SUCCESS;
449 }
450 
ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,const uint8_t * p_codec_info,uint8_t seid,uint8_t num_protect,const uint8_t * p_protect_info,uint8_t t_local_sep,uint8_t avdt_handle)451 void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,
452                                const RawAddress& peer_address,
453                                const uint8_t* p_codec_info, uint8_t seid,
454                                uint8_t num_protect,
455                                const uint8_t* p_protect_info,
456                                uint8_t t_local_sep, uint8_t avdt_handle) {
457   tA2DP_STATUS status = A2DP_SUCCESS;
458   uint8_t category = A2DP_SUCCESS;
459   bool reconfig_needed = false;
460 
461   log::verbose(
462       "bta_av_handle=0x{:x} peer_address={} seid={} num_protect={} "
463       "t_local_sep={} avdt_handle={}",
464       bta_av_handle, peer_address, seid, num_protect, t_local_sep, avdt_handle);
465   log::verbose("p_codec_info[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]", p_codec_info[1],
466                p_codec_info[2], p_codec_info[3], p_codec_info[4],
467                p_codec_info[5], p_codec_info[6]);
468   log::verbose("num_protect:0x{:02x} protect_info:0x{:02x}{:02x}{:02x}",
469                num_protect, p_protect_info[0], p_protect_info[1],
470                p_protect_info[2]);
471   log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info));
472 
473   // Find the peer
474   BtaAvCoPeer* p_peer =
475       peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
476   if (p_peer == nullptr) {
477     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
478                bta_av_handle, peer_address);
479     // Call call-in rejecting the configuration
480     bta_av_ci_setconfig(bta_av_handle, A2DP_BUSY, AVDT_ASC_CODEC, 0, nullptr,
481                         false, avdt_handle);
482     return;
483   }
484 
485   log::verbose(
486       "peer {} found (o={}, n_sinks={}, n_rx_sinks={}, n_sup_sinks={})",
487       p_peer->addr, p_peer->opened, p_peer->num_sinks, p_peer->num_rx_sinks,
488       p_peer->num_sup_sinks);
489 
490   // Sanity check: should not be opened at this point
491   if (p_peer->opened) {
492     log::error("peer {} already in use", p_peer->addr);
493   }
494 
495   if (num_protect != 0) {
496     if (ContentProtectEnabled()) {
497       if ((num_protect != 1) || !ContentProtectIsScmst(p_protect_info)) {
498         log::error("wrong CP configuration for peer {}", p_peer->addr);
499         status = A2DP_BAD_CP_TYPE;
500         category = AVDT_ASC_PROTECT;
501       }
502     } else {
503       // Do not support content protection for the time being
504       log::error("wrong CP configuration for peer {}", p_peer->addr);
505       status = A2DP_BAD_CP_TYPE;
506       category = AVDT_ASC_PROTECT;
507     }
508   }
509 
510   if (status == A2DP_SUCCESS) {
511     bool codec_config_supported = false;
512 
513     if (t_local_sep == AVDT_TSEP_SNK) {
514       log::verbose("peer {} is A2DP Source", p_peer->addr);
515       codec_config_supported = A2DP_IsSinkCodecSupported(p_codec_info);
516       if (codec_config_supported) {
517         // If Peer is Source, and our config subset matches with what is
518         // requested by peer, then just accept what peer wants.
519         SaveNewCodecConfig(p_peer, p_codec_info, num_protect, p_protect_info,
520                            t_local_sep);
521       }
522     }
523     if (t_local_sep == AVDT_TSEP_SRC) {
524       log::verbose("peer {} is A2DP SINK", p_peer->addr);
525       // Ignore the restart_output flag: accepting the remote device's
526       // codec selection should not trigger codec reconfiguration.
527       bool dummy_restart_output = false;
528       if ((p_peer->GetCodecs() == nullptr) ||
529           !SetCodecOtaConfig(p_peer, p_codec_info, num_protect, p_protect_info,
530                              &dummy_restart_output, t_local_sep)) {
531         log::error("cannot set source codec {} for peer {}",
532                    A2DP_CodecName(p_codec_info), p_peer->addr);
533       } else {
534         codec_config_supported = true;
535         // Check if reconfiguration is needed
536         if (((num_protect == 1) && !p_peer->ContentProtectActive())) {
537           reconfig_needed = true;
538         }
539       }
540     }
541 
542     // Check if codec configuration is supported
543     if (!codec_config_supported) {
544       category = AVDT_ASC_CODEC;
545       status = A2DP_WRONG_CODEC;
546     }
547   }
548 
549   if (status != A2DP_SUCCESS) {
550     log::verbose("peer {} reject s={} c={}", p_peer->addr, status, category);
551     // Call call-in rejecting the configuration
552     bta_av_ci_setconfig(bta_av_handle, status, category, 0, nullptr, false,
553                         avdt_handle);
554     return;
555   }
556 
557   // Mark that this is an acceptor peer
558   p_peer->acceptor = true;
559   p_peer->reconfig_needed = reconfig_needed;
560   log::verbose("peer {} accept reconf={}", p_peer->addr, reconfig_needed);
561   // Call call-in accepting the configuration
562   bta_av_ci_setconfig(bta_av_handle, A2DP_SUCCESS, A2DP_SUCCESS, 0, nullptr,
563                       reconfig_needed, avdt_handle);
564 }
565 
ProcessOpen(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t mtu)566 void BtaAvCo::ProcessOpen(tBTA_AV_HNDL bta_av_handle,
567                           const RawAddress& peer_address, uint16_t mtu) {
568   log::verbose("peer {} bta_av_handle: 0x{:x} mtu:{}", peer_address,
569                bta_av_handle, mtu);
570 
571   // Find the peer
572   BtaAvCoPeer* p_peer =
573       peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
574   if (p_peer == nullptr) {
575     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
576                bta_av_handle, peer_address);
577     return;
578   }
579   p_peer->opened = true;
580   p_peer->mtu = mtu;
581 
582   BtaAvCoState* reference_state = getStateFromPeer(p_peer);
583   if (reference_state == nullptr) {
584     log::warn("Invalid bta av state");
585     return;
586   }
587   BtaAvCoPeer* active_peer = reference_state->getActivePeer();
588   if (active_peer == nullptr) {
589     reference_state->setActivePeer(p_peer);
590   }
591 }
592 
ProcessClose(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)593 void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle,
594                            const RawAddress& peer_address) {
595   log::verbose("peer {} bta_av_handle: 0x{:x}", peer_address, bta_av_handle);
596   btif_av_reset_audio_delay();
597 
598   // Find the peer
599   BtaAvCoPeer* p_peer =
600       peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
601   if (p_peer == nullptr) {
602     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
603                bta_av_handle, peer_address);
604     return;
605   }
606   // Reset the active peer
607 
608   BtaAvCoState* reference_state = getStateFromPeer(p_peer);
609   if (reference_state == nullptr) {
610     log::warn("Invalid bta av state");
611     return;
612   }
613   BtaAvCoPeer* active_peer = reference_state->getActivePeer();
614   if (active_peer == p_peer) {
615     reference_state->setActivePeer(nullptr);
616   }
617 
618   // Mark the peer closed and clean the peer info
619   p_peer->Init(peer_cache_->codec_priorities_);
620 }
621 
ProcessStart(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,const uint8_t * p_codec_info,bool * p_no_rtp_header)622 void BtaAvCo::ProcessStart(tBTA_AV_HNDL bta_av_handle,
623                            const RawAddress& peer_address,
624                            const uint8_t* p_codec_info, bool* p_no_rtp_header) {
625   log::verbose("peer {} bta_av_handle: 0x{:x}", peer_address, bta_av_handle);
626 
627   // Find the peer
628   BtaAvCoPeer* p_peer =
629       peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
630   if (p_peer == nullptr) {
631     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
632                bta_av_handle, peer_address);
633     return;
634   }
635 
636   bool add_rtp_header =
637       A2DP_UsesRtpHeader(p_peer->ContentProtectActive(), p_codec_info);
638 
639   log::verbose("bta_av_handle: 0x{:x} add_rtp_header: {}", bta_av_handle,
640                add_rtp_header);
641   *p_no_rtp_header = !add_rtp_header;
642 }
643 
ProcessStop(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)644 void BtaAvCo::ProcessStop(tBTA_AV_HNDL bta_av_handle,
645                           const RawAddress& peer_address) {
646   log::verbose("peer {} bta_av_handle: 0x{:x}", peer_address, bta_av_handle);
647   // Nothing to do
648 }
649 
GetNextSourceDataPacket(const uint8_t * p_codec_info,uint32_t * p_timestamp)650 BT_HDR* BtaAvCo::GetNextSourceDataPacket(const uint8_t* p_codec_info,
651                                          uint32_t* p_timestamp) {
652   BT_HDR* p_buf;
653 
654   log::verbose("codec: {}", A2DP_CodecName(p_codec_info));
655 
656   p_buf = btif_a2dp_source_audio_readbuf();
657   if (p_buf == nullptr) return nullptr;
658 
659   if (p_buf->offset < 4) {
660     osi_free(p_buf);
661     log::error("No space for timestamp in packet, dropped");
662     return nullptr;
663   }
664   /*
665    * Retrieve the timestamp information from the media packet,
666    * and set up the packet header.
667    *
668    * In media packet, the following information is available:
669    * p_buf->layer_specific : number of audio frames in the packet
670    * p_buf->word[0] : timestamp
671    */
672   if (!A2DP_GetPacketTimestamp(p_codec_info, (const uint8_t*)(p_buf + 1),
673                                p_timestamp) ||
674       !A2DP_BuildCodecHeader(p_codec_info, p_buf, p_buf->layer_specific)) {
675     log::error("unsupported codec type ({})", A2DP_GetCodecType(p_codec_info));
676     osi_free(p_buf);
677     return nullptr;
678   }
679 
680   BtaAvCoState* reference_state = nullptr;
681   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
682     reference_state = &bta_av_source_state_;
683   } else {
684     reference_state = &bta_av_legacy_state_;
685   }
686   BtaAvCoPeer* active_peer = reference_state->getActivePeer();
687   // if offset is 0, the decremental operation may result in
688   // underflow and OOB access
689   if (ContentProtectEnabled() && (active_peer != nullptr) &&
690       active_peer->ContentProtectActive() && p_buf->offset > 0) {
691     p_buf->len++;
692     p_buf->offset--;
693     uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
694     *p = ContentProtectFlag();
695   }
696 
697   return p_buf;
698 }
699 
DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)700 void BtaAvCo::DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle,
701                                    const RawAddress& peer_address) {
702   log::error("peer {} dropped audio packet on handle 0x{:x}", peer_address,
703              bta_av_handle);
704 }
705 
ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t delay)706 void BtaAvCo::ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle,
707                                 const RawAddress& peer_address,
708                                 uint16_t delay) {
709   log::verbose("peer {} bta_av_handle: 0x{:x} delay:0x{:x}", peer_address,
710                bta_av_handle, delay);
711 
712   btif_av_set_audio_delay(peer_address, delay, A2dpType::kSource);
713 }
714 
UpdateMtu(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t mtu)715 void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle,
716                         const RawAddress& peer_address, uint16_t mtu) {
717   log::info("peer {} bta_av_handle: 0x{:x} mtu: {}", peer_address,
718             bta_av_handle, mtu);
719 
720   // Find the peer
721   BtaAvCoPeer* p_peer =
722       peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address);
723   if (p_peer == nullptr) {
724     log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}",
725                bta_av_handle, peer_address);
726     return;
727   }
728   p_peer->mtu = mtu;
729 }
730 
SetActivePeer(const RawAddress & peer_address,const uint8_t t_local_sep)731 bool BtaAvCo::SetActivePeer(const RawAddress& peer_address,
732                             const uint8_t t_local_sep) {
733   log::info("peer_address={}", peer_address);
734 
735   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
736 
737   BtaAvCoState* reference_state = getStateFromLocalProfile(t_local_sep);
738   if (reference_state == nullptr) {
739     log::warn(
740         "Invalid bta av state for peer_address : {} with local sep as :{}",
741         peer_address, t_local_sep);
742     return false;
743   }
744   if (peer_address.IsEmpty()) {
745     // Reset the active peer;
746     reference_state->setActivePeer(nullptr);
747     reference_state->clearCodecConfig();
748     return true;
749   }
750 
751   // Find the peer
752   BtaAvCoPeer* p_peer = peer_cache_->FindPeer(peer_address);
753   if (p_peer == nullptr) {
754     return false;
755   }
756 
757   reference_state->setActivePeer(p_peer);
758   reference_state->setCodecConfig(p_peer->codec_config);
759   log::info("codec = {}",
760             A2DP_CodecInfoString(reference_state->getCodecConfig()));
761   // report the selected codec configuration of this new active peer.
762   ReportSourceCodecState(p_peer);
763   return true;
764 }
765 
getStateFromLocalProfile(const uint8_t t_local_sep)766 BtaAvCoState* BtaAvCo::getStateFromLocalProfile(const uint8_t t_local_sep) {
767   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
768     if (t_local_sep == AVDT_TSEP_SRC) {
769       return &bta_av_source_state_;
770     } else if (t_local_sep == AVDT_TSEP_SNK) {
771       return &bta_av_sink_state_;
772     } else {
773       log::warn("Invalid bta av state for local sep type {}", t_local_sep);
774       return nullptr;
775     }
776   } else {
777     return &bta_av_legacy_state_;
778   }
779 }
780 
SaveCodec(const uint8_t * new_codec_config)781 void BtaAvCo::SaveCodec(const uint8_t* new_codec_config) {
782   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
783     bta_av_sink_state_.setCodecConfig(new_codec_config);
784   } else {
785     bta_av_legacy_state_.setCodecConfig(new_codec_config);
786   }
787 }
788 
GetPeerEncoderParameters(const RawAddress & peer_address,tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params)789 void BtaAvCo::GetPeerEncoderParameters(
790     const RawAddress& peer_address,
791     tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {
792   uint16_t min_mtu = 0xFFFF;
793   log::assert_that(p_peer_params != nullptr, "Peer address {}",
794                    ADDRESS_TO_LOGGABLE_STR(peer_address));
795 
796   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
797 
798   // Compute the MTU
799   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peer_cache_->peers_); i++) {
800     const BtaAvCoPeer* p_peer = &peer_cache_->peers_[i];
801     if (!p_peer->opened) continue;
802     if (p_peer->addr != peer_address) continue;
803     if (p_peer->mtu < min_mtu) min_mtu = p_peer->mtu;
804   }
805   p_peer_params->peer_mtu = min_mtu;
806   p_peer_params->is_peer_edr =
807       btif_av_is_peer_edr(peer_address, A2dpType::kSource);
808   p_peer_params->peer_supports_3mbps =
809       btif_av_peer_supports_3mbps(peer_address, A2dpType::kSource);
810   log::verbose(
811       "peer_address={} peer_mtu={} is_peer_edr={} peer_supports_3mbps={}",
812       peer_address, p_peer_params->peer_mtu, p_peer_params->is_peer_edr,
813       p_peer_params->peer_supports_3mbps);
814 }
815 
GetSourceEncoderInterface()816 const tA2DP_ENCODER_INTERFACE* BtaAvCo::GetSourceEncoderInterface() {
817   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
818   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
819     return A2DP_GetEncoderInterface(bta_av_source_state_.getCodecConfig());
820   }
821   return A2DP_GetEncoderInterface(bta_av_legacy_state_.getCodecConfig());
822 }
823 
SetCodecUserConfig(const RawAddress & peer_address,const btav_a2dp_codec_config_t & codec_user_config,bool * p_restart_output)824 bool BtaAvCo::SetCodecUserConfig(
825     const RawAddress& peer_address,
826     const btav_a2dp_codec_config_t& codec_user_config, bool* p_restart_output) {
827   uint8_t result_codec_config[AVDT_CODEC_SIZE];
828   const BtaAvCoSep* p_sink = nullptr;
829   bool restart_input = false;
830   bool restart_output = false;
831   bool config_updated = false;
832   bool success = true;
833 
834   log::verbose("peer_address={} codec_user_config={{}}", peer_address,
835                codec_user_config.ToString());
836 
837   *p_restart_output = false;
838 
839   BtaAvCoPeer* p_peer = peer_cache_->FindPeer(peer_address);
840   if (p_peer == nullptr) {
841     log::error("cannot find peer {} to configure", peer_address);
842     success = false;
843     goto done;
844   }
845 
846   // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
847   if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
848       (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
849     log::warn("peer {} : not all peer's capabilities have been retrieved",
850               p_peer->addr);
851     success = false;
852     goto done;
853   }
854 
855   // Find the peer SEP codec to use
856   if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) {
857     p_sink = peer_cache_->FindPeerSink(p_peer, codec_user_config.codec_type,
858                                        ContentProtectFlag());
859   } else {
860     // Use the current sink codec
861     p_sink = p_peer->p_sink;
862   }
863   if (p_sink == nullptr) {
864     log::error("peer {} : cannot find peer SEP to configure for codec type {}",
865                p_peer->addr, codec_user_config.codec_type);
866     success = false;
867     goto done;
868   }
869 
870   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
871   GetPeerEncoderParameters(p_peer->addr, &peer_params);
872   if (!p_peer->GetCodecs()->setCodecUserConfig(
873           codec_user_config, &peer_params, p_sink->codec_caps,
874           result_codec_config, &restart_input, &restart_output,
875           &config_updated)) {
876     success = false;
877     goto done;
878   }
879 
880   if (restart_output) {
881     uint8_t num_protect = 0;
882     if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
883       num_protect = AVDT_CP_INFO_LEN;
884     }
885 
886     p_sink = SelectSourceCodec(p_peer);
887     if (p_sink == nullptr) {
888       log::error("peer {} : cannot set up codec for the peer SINK",
889                  p_peer->addr);
890       success = false;
891       goto done;
892     }
893 
894     p_peer->acceptor = false;
895     log::verbose("call BTA_AvReconfig(0x{:x})", p_peer->BtaAvHandle());
896     BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx,
897                    p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
898     *p_restart_output = true;
899   }
900 
901 done:
902   // We send the upcall if there is no change or the user config failed for
903   // current active peer, so the caller would know it failed. If there is no
904   // error, the new selected codec configuration would be sent after we are
905   // ready to start a new session with the audio HAL.
906   // For none active peer, we unconditionally send the upcall, so the caller
907   // would always know the result.
908   // NOTE: Currently, the input is restarted by sending an upcall
909   // and informing the Media Framework about the change.
910 
911   // Find the peer that is currently open
912   BtaAvCoPeer* active_peer;
913   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
914     active_peer = bta_av_source_state_.getActivePeer();
915   } else {
916     active_peer = bta_av_legacy_state_.getActivePeer();
917   }
918   if (p_peer != nullptr &&
919       (!restart_output || !success || p_peer != active_peer)) {
920     return ReportSourceCodecState(p_peer);
921   }
922 
923   return success;
924 }
925 
SetCodecAudioConfig(const btav_a2dp_codec_config_t & codec_audio_config)926 bool BtaAvCo::SetCodecAudioConfig(
927     const btav_a2dp_codec_config_t& codec_audio_config) {
928   uint8_t result_codec_config[AVDT_CODEC_SIZE];
929   bool restart_output = false;
930   bool config_updated = false;
931 
932   log::verbose("codec_audio_config: {}", codec_audio_config.ToString());
933 
934   // Find the peer that is currently open
935   BtaAvCoPeer* p_peer;
936   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
937     p_peer = bta_av_source_state_.getActivePeer();
938   } else {
939     p_peer = bta_av_legacy_state_.getActivePeer();
940   }
941   if (p_peer == nullptr) {
942     log::error("no active peer to configure");
943     return false;
944   }
945 
946   // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
947   if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
948       (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
949     log::warn("peer {} : not all peer's capabilities have been retrieved",
950               p_peer->addr);
951     return false;
952   }
953 
954   // Use the current sink codec
955   const BtaAvCoSep* p_sink = p_peer->p_sink;
956   if (p_sink == nullptr) {
957     log::error("peer {} : cannot find peer SEP to configure", p_peer->addr);
958     return false;
959   }
960 
961   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
962   GetPeerEncoderParameters(p_peer->addr, &peer_params);
963   if (!p_peer->GetCodecs()->setCodecAudioConfig(
964           codec_audio_config, &peer_params, p_sink->codec_caps,
965           result_codec_config, &restart_output, &config_updated)) {
966     return false;
967   }
968 
969   if (restart_output) {
970     uint8_t num_protect = 0;
971     if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
972       num_protect = AVDT_CP_INFO_LEN;
973     }
974 
975     SaveNewCodecConfig(p_peer, result_codec_config, p_sink->num_protect,
976                        p_sink->protect_info, AVDT_TSEP_SRC);
977 
978     p_peer->acceptor = false;
979     log::verbose("call BTA_AvReconfig(0x{:x})", p_peer->BtaAvHandle());
980     BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx,
981                    p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
982   }
983 
984   if (config_updated) {
985     // NOTE: Currently, the input is restarted by sending an upcall
986     // and informing the Media Framework about the change of selected codec.
987     return ReportSourceCodecState(p_peer);
988   }
989 
990   return true;
991 }
992 
GetSourceEncoderEffectiveFrameSize()993 int BtaAvCo::GetSourceEncoderEffectiveFrameSize() {
994   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
995 
996   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
997     return A2DP_GetEecoderEffectiveFrameSize(
998         bta_av_source_state_.getCodecConfig());
999   }
1000   return A2DP_GetEecoderEffectiveFrameSize(
1001       bta_av_legacy_state_.getCodecConfig());
1002 }
1003 
ReportSourceCodecState(BtaAvCoPeer * p_peer)1004 bool BtaAvCo::ReportSourceCodecState(BtaAvCoPeer* p_peer) {
1005   btav_a2dp_codec_config_t codec_config = {
1006     .codec_type = BTAV_A2DP_CODEC_INDEX_SINK_MAX,
1007     .codec_priority = BTAV_A2DP_CODEC_PRIORITY_DISABLED,
1008     .sample_rate =    BTAV_A2DP_CODEC_SAMPLE_RATE_NONE,
1009     .bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE,
1010     .channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE,
1011     .codec_specific_1 = 0,
1012     .codec_specific_2 = 0,
1013     .codec_specific_3 = 0,
1014     .codec_specific_4 = 0,
1015   };
1016   std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities;
1017   std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities;
1018 
1019   log::verbose("peer_address={}", p_peer->addr);
1020   A2dpCodecs* codecs = p_peer->GetCodecs();
1021   if (codecs == nullptr) {
1022     log::error("Peer codecs is set to null");
1023     return false;
1024   }
1025   if (!codecs->getCodecConfigAndCapabilities(&codec_config,
1026                                              &codecs_local_capabilities,
1027                                              &codecs_selectable_capabilities)) {
1028     log::warn(
1029         "Peer {} : error reporting audio source codec state: cannot get codec "
1030         "config and capabilities",
1031         p_peer->addr);
1032     return false;
1033   }
1034   log::info("peer {} codec_config={{}}", p_peer->addr, codec_config.ToString());
1035   btif_av_report_source_codec_state(p_peer->addr, codec_config,
1036                                     codecs_local_capabilities,
1037                                     codecs_selectable_capabilities);
1038   return true;
1039 }
1040 
ReportSinkCodecState(BtaAvCoPeer * p_peer)1041 bool BtaAvCo::ReportSinkCodecState(BtaAvCoPeer* p_peer) {
1042   log::verbose("peer_address={}", p_peer->addr);
1043   // Nothing to do (for now)
1044   return true;
1045 }
1046 
DebugDump(int fd)1047 void BtaAvCo::DebugDump(int fd) {
1048   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
1049 
1050   //
1051   // Active peer codec-specific stats
1052   //
1053   if (bta_av_legacy_state_.getActivePeer() != nullptr) {
1054     A2dpCodecs* a2dp_codecs = bta_av_legacy_state_.getActivePeer()->GetCodecs();
1055     if (a2dp_codecs != nullptr) {
1056       a2dp_codecs->debug_codec_dump(fd);
1057     }
1058   }
1059   if (bta_av_source_state_.getActivePeer() != nullptr) {
1060     A2dpCodecs* a2dp_codecs = bta_av_source_state_.getActivePeer()->GetCodecs();
1061     if (a2dp_codecs != nullptr) {
1062       a2dp_codecs->debug_codec_dump(fd);
1063     }
1064   }
1065   if (bta_av_sink_state_.getActivePeer() != nullptr) {
1066     A2dpCodecs* a2dp_codecs = bta_av_sink_state_.getActivePeer()->GetCodecs();
1067     if (a2dp_codecs != nullptr) {
1068       a2dp_codecs->debug_codec_dump(fd);
1069     }
1070   }
1071 
1072   dprintf(fd, "\nA2DP Peers State:\n");
1073   dprintf(
1074       fd, "  Active peer: %s\n",
1075       (bta_av_legacy_state_.getActivePeer() != nullptr)
1076           ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_legacy_state_.getActivePeer()->addr)
1077           : "null");
1078   dprintf(
1079       fd, "  Source: active peer: %s\n",
1080       (bta_av_source_state_.getActivePeer() != nullptr)
1081           ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_source_state_.getActivePeer()->addr)
1082           : "null");
1083   dprintf(
1084       fd, "  Sink: active peer: %s\n",
1085       (bta_av_sink_state_.getActivePeer() != nullptr)
1086           ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_sink_state_.getActivePeer()->addr)
1087           : "null");
1088 
1089   for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peer_cache_->peers_); i++) {
1090     const BtaAvCoPeer& peer = peer_cache_->peers_[i];
1091     if (peer.addr.IsEmpty()) {
1092       continue;
1093     }
1094     dprintf(fd, "  Peer: %s\n", ADDRESS_TO_LOGGABLE_CSTR(peer.addr));
1095     dprintf(fd, "    Number of sinks: %u\n", peer.num_sinks);
1096     dprintf(fd, "    Number of sources: %u\n", peer.num_sources);
1097     dprintf(fd, "    Number of SEPs: %u\n", peer.num_seps);
1098     dprintf(fd, "    Number of received sinks: %u\n", peer.num_rx_sinks);
1099     dprintf(fd, "    Number of received sources: %u\n", peer.num_rx_sources);
1100     dprintf(fd, "    Number of supported sinks: %u\n", peer.num_sup_sinks);
1101     dprintf(fd, "    Number of supported sources: %u\n", peer.num_sup_sources);
1102     dprintf(fd, "    Acceptor: %s\n", (peer.acceptor) ? "true" : "false");
1103     dprintf(fd, "    Reconfig needed: %s\n",
1104             (peer.reconfig_needed) ? "true" : "false");
1105     dprintf(fd, "    Opened: %s\n", (peer.opened) ? "true" : "false");
1106     dprintf(fd, "    MTU: %u\n", peer.mtu);
1107     dprintf(fd, "    UUID to connect: 0x%x\n", peer.uuid_to_connect);
1108     dprintf(fd, "    BTA AV handle: %u\n", peer.BtaAvHandle());
1109   }
1110 }
1111 
1112 std::optional<::bluetooth::audio::a2dp::provider::a2dp_configuration>
GetProviderCodecConfiguration(BtaAvCoPeer * p_peer)1113 BtaAvCo::GetProviderCodecConfiguration(BtaAvCoPeer* p_peer) {
1114   // Gather peer codec capabilities.
1115   std::vector<::bluetooth::audio::a2dp::provider::a2dp_remote_capabilities>
1116       a2dp_remote_caps;
1117   for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
1118     const BtaAvCoSep* p_sink = &p_peer->sinks[index];
1119     auto& capabilities = a2dp_remote_caps.emplace_back();
1120     capabilities.seid = p_sink->seid;
1121     capabilities.capabilities = p_sink->codec_caps;
1122   }
1123 
1124   // Get the configuration of the preferred codec as codec hint.
1125   btav_a2dp_codec_config_t codec_config =
1126       p_peer->GetCodecs()->orderedSourceCodecs().front()->getCodecUserConfig();
1127 
1128   // Pass all gathered codec capabilities to the provider
1129   return ::bluetooth::audio::a2dp::provider::get_a2dp_configuration(
1130       p_peer->addr, a2dp_remote_caps, codec_config);
1131 }
1132 
SelectProviderCodecConfiguration(BtaAvCoPeer * p_peer,const::bluetooth::audio::a2dp::provider::a2dp_configuration & provider_codec_config)1133 BtaAvCoSep* BtaAvCo::SelectProviderCodecConfiguration(
1134     BtaAvCoPeer* p_peer,
1135     const ::bluetooth::audio::a2dp::provider::a2dp_configuration&
1136         provider_codec_config) {
1137   // Configure the selected offload codec for the active peer.
1138   // This function _must_ have the same external behaviour as
1139   // AttemptSourceCodecSelection, except the configuration
1140   // is provided by the HAL rather than derived locally.
1141 
1142   log::info("Configuration={}", provider_codec_config.toString());
1143 
1144   // Identify the selected sink.
1145   auto* p_sink = peer_cache_->FindPeerSink(
1146       p_peer, provider_codec_config.codec_parameters.codec_type,
1147       ContentProtectFlag());
1148   log::assert_that(p_sink != nullptr,
1149                    "Unable to find the selected codec config");
1150 
1151   // Identify the selected codec.
1152   auto* codec_config = reinterpret_cast<A2dpCodecConfigExt*>(
1153       p_peer->GetCodecs()->findSourceCodecConfig(
1154           provider_codec_config.codec_parameters.codec_type));
1155   log::assert_that(codec_config != nullptr,
1156                    "Unable to find the selected codec config");
1157 
1158   // Update the vendor codec parameters and codec configuration.
1159   codec_config->setCodecConfig(
1160       provider_codec_config.codec_parameters,
1161       provider_codec_config.codec_config,
1162       provider_codec_config.vendor_specific_parameters);
1163 
1164   // Select the codec config.
1165   p_peer->GetCodecs()->setCurrentCodecConfig(codec_config);
1166   p_peer->p_sink = p_sink;
1167   SaveNewCodecConfig(p_peer, provider_codec_config.codec_config,
1168                      p_sink->num_protect, p_sink->protect_info, AVDT_TSEP_SRC);
1169 
1170   return p_sink;
1171 }
1172 
SelectSourceCodec(BtaAvCoPeer * p_peer)1173 const BtaAvCoSep* BtaAvCo::SelectSourceCodec(BtaAvCoPeer* p_peer) {
1174   // Update all selectable codecs.
1175   // This is needed to update the selectable parameters for each codec.
1176   // NOTE: The selectable codec info is used only for informational purpose.
1177   UpdateAllSelectableSourceCodecs(p_peer);
1178 
1179   // Query the preferred codec configuration for offloaded codecs.
1180   auto provider_codec_config = GetProviderCodecConfiguration(p_peer);
1181 
1182   // Query the preferred codec configuration for software codecs.
1183   A2dpCodecConfig* software_codec_config = nullptr;
1184   for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) {
1185     if (::bluetooth::audio::a2dp::provider::supports_codec(
1186             iter->codecIndex())) {
1187       continue;
1188     }
1189 
1190     // Find the peer Sink for the codec
1191     uint8_t new_codec_config[AVDT_CODEC_SIZE];
1192     const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink(
1193         p_peer, iter->codecIndex(), ContentProtectFlag());
1194 
1195     if (p_sink == nullptr) {
1196       log::verbose("peer Sink for codec {} not found", iter->name());
1197       continue;
1198     }
1199 
1200     if (!p_peer->GetCodecs()->setCodecConfig(
1201             p_sink->codec_caps, true /* is_capability */, new_codec_config,
1202             false /* select_current_codec */)) {
1203       log::verbose("cannot set source codec {}", iter->name());
1204     } else {
1205       log::verbose("feasible to set source codec {}", iter->name());
1206       software_codec_config = iter;
1207       break;
1208     }
1209   }
1210 
1211   if (provider_codec_config.has_value() &&
1212       (software_codec_config == nullptr ||
1213        bta_av_co_should_select_hardware_codec(*software_codec_config,
1214                                               provider_codec_config.value()))) {
1215     // Select hardware offload codec configuration
1216     return SelectProviderCodecConfiguration(p_peer,
1217                                             provider_codec_config.value());
1218   }
1219 
1220   if (software_codec_config != nullptr) {
1221     // Select software codec configuration
1222     return AttemptSourceCodecSelection(*software_codec_config, p_peer);
1223   }
1224 
1225   return nullptr;
1226 }
1227 
SelectSinkCodec(BtaAvCoPeer * p_peer)1228 const BtaAvCoSep* BtaAvCo::SelectSinkCodec(BtaAvCoPeer* p_peer) {
1229   const BtaAvCoSep* p_source = nullptr;
1230 
1231   // Update all selectable codecs.
1232   // This is needed to update the selectable parameters for each codec.
1233   // NOTE: The selectable codec info is used only for informational purpose.
1234   UpdateAllSelectableSinkCodecs(p_peer);
1235 
1236   // Select the codec
1237   for (const auto& iter : p_peer->GetCodecs()->orderedSinkCodecs()) {
1238     log::verbose("trying codec {}", iter->name());
1239     p_source = AttemptSinkCodecSelection(*iter, p_peer);
1240     if (p_source != nullptr) {
1241       log::verbose("selected codec {}", iter->name());
1242       break;
1243     }
1244     log::verbose("cannot use codec {}", iter->name());
1245   }
1246 
1247   // NOTE: Unconditionally dispatch the event to make sure a callback with
1248   // the most recent codec info is generated.
1249   ReportSinkCodecState(p_peer);
1250 
1251   return p_source;
1252 }
1253 
AttemptSourceCodecSelection(const A2dpCodecConfig & codec_config,BtaAvCoPeer * p_peer)1254 const BtaAvCoSep* BtaAvCo::AttemptSourceCodecSelection(
1255     const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) {
1256   uint8_t new_codec_config[AVDT_CODEC_SIZE];
1257 
1258   log::verbose("");
1259 
1260   // Find the peer Sink for the codec
1261   BtaAvCoSep* p_sink = peer_cache_->FindPeerSink(
1262       p_peer, codec_config.codecIndex(), ContentProtectFlag());
1263   if (p_sink == nullptr) {
1264     log::verbose("peer Sink for codec {} not found", codec_config.name());
1265     return nullptr;
1266   }
1267   if (!p_peer->GetCodecs()->setCodecConfig(
1268           p_sink->codec_caps, true /* is_capability */, new_codec_config,
1269           true /* select_current_codec */)) {
1270     log::verbose("cannot set source codec {}", codec_config.name());
1271     return nullptr;
1272   }
1273   p_peer->p_sink = p_sink;
1274 
1275   SaveNewCodecConfig(p_peer, new_codec_config, p_sink->num_protect,
1276                      p_sink->protect_info, AVDT_TSEP_SRC);
1277 
1278   return p_sink;
1279 }
1280 
AttemptSinkCodecSelection(const A2dpCodecConfig & codec_config,BtaAvCoPeer * p_peer)1281 const BtaAvCoSep* BtaAvCo::AttemptSinkCodecSelection(
1282     const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) {
1283   uint8_t new_codec_config[AVDT_CODEC_SIZE];
1284 
1285   log::verbose("");
1286 
1287   // Find the peer Source for the codec
1288   BtaAvCoSep* p_source = peer_cache_->FindPeerSource(
1289       p_peer, codec_config.codecIndex(), ContentProtectFlag());
1290   if (p_source == nullptr) {
1291     log::verbose("peer Source for codec {} not found", codec_config.name());
1292     return nullptr;
1293   }
1294   if (!p_peer->GetCodecs()->setSinkCodecConfig(
1295           p_source->codec_caps, true /* is_capability */, new_codec_config,
1296           true /* select_current_codec */)) {
1297     log::verbose("cannot set sink codec {}", codec_config.name());
1298     return nullptr;
1299   }
1300   p_peer->p_source = p_source;
1301 
1302   SaveNewCodecConfig(p_peer, new_codec_config, p_source->num_protect,
1303                      p_source->protect_info, AVDT_TSEP_SNK);
1304 
1305   return p_source;
1306 }
1307 
UpdateAllSelectableSourceCodecs(BtaAvCoPeer * p_peer)1308 size_t BtaAvCo::UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer) {
1309   log::verbose("peer {}", p_peer->addr);
1310 
1311   size_t updated_codecs = 0;
1312   for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) {
1313     log::verbose("updating selectable codec {}", iter->name());
1314     if (UpdateSelectableSourceCodec(*iter, p_peer)) {
1315       updated_codecs++;
1316     }
1317   }
1318   return updated_codecs;
1319 }
1320 
UpdateSelectableSourceCodec(const A2dpCodecConfig & codec_config,BtaAvCoPeer * p_peer)1321 bool BtaAvCo::UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config,
1322                                           BtaAvCoPeer* p_peer) {
1323   log::verbose("peer {}", p_peer->addr);
1324 
1325   // Find the peer Sink for the codec
1326   const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink(
1327       p_peer, codec_config.codecIndex(), ContentProtectFlag());
1328   if (p_sink == nullptr) {
1329     // The peer Sink device does not support this codec
1330     return false;
1331   }
1332   if (!p_peer->GetCodecs()->setPeerSinkCodecCapabilities(p_sink->codec_caps)) {
1333     log::warn("cannot update peer {} codec capabilities for {}", p_peer->addr,
1334               A2DP_CodecName(p_sink->codec_caps));
1335     return false;
1336   }
1337   return true;
1338 }
1339 
UpdateAllSelectableSinkCodecs(BtaAvCoPeer * p_peer)1340 size_t BtaAvCo::UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer) {
1341   log::verbose("peer {}", p_peer->addr);
1342 
1343   size_t updated_codecs = 0;
1344   for (const auto& iter : p_peer->GetCodecs()->orderedSinkCodecs()) {
1345     log::verbose("updating selectable codec {}", iter->name());
1346     if (UpdateSelectableSinkCodec(*iter, p_peer)) {
1347       updated_codecs++;
1348     }
1349   }
1350   return updated_codecs;
1351 }
1352 
UpdateSelectableSinkCodec(const A2dpCodecConfig & codec_config,BtaAvCoPeer * p_peer)1353 bool BtaAvCo::UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config,
1354                                         BtaAvCoPeer* p_peer) {
1355   log::verbose("peer {}", p_peer->addr);
1356 
1357   // Find the peer Source for the codec
1358   const BtaAvCoSep* p_source = peer_cache_->FindPeerSource(
1359       p_peer, codec_config.codecIndex(), ContentProtectFlag());
1360   if (p_source == nullptr) {
1361     // The peer Source device does not support this codec
1362     return false;
1363   }
1364   if (!p_peer->GetCodecs()->setPeerSourceCodecCapabilities(
1365           p_source->codec_caps)) {
1366     log::warn("cannot update peer {} codec capabilities for {}", p_peer->addr,
1367               A2DP_CodecName(p_source->codec_caps));
1368     return false;
1369   }
1370   return true;
1371 }
1372 
SaveNewCodecConfig(BtaAvCoPeer * p_peer,const uint8_t * new_codec_config,uint8_t num_protect,const uint8_t * p_protect_info,const uint8_t t_local_sep)1373 void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer,
1374                                  const uint8_t* new_codec_config,
1375                                  uint8_t num_protect,
1376                                  const uint8_t* p_protect_info,
1377                                  const uint8_t t_local_sep) {
1378   log::verbose("peer {}", p_peer->addr);
1379   log::verbose("codec: {}", A2DP_CodecInfoString(new_codec_config));
1380 
1381   std::lock_guard<std::recursive_mutex> lock(peer_cache_->codec_lock_);
1382   BtaAvCoState* reference_state = getStateFromLocalProfile(t_local_sep);
1383   if (reference_state == nullptr) {
1384     log::warn(
1385         "Invalid bta av state for peer_address : {} with local sep as :{}",
1386         p_peer->addr, t_local_sep);
1387     return;
1388   }
1389   reference_state->setCodecConfig(new_codec_config);
1390   memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE);
1391 
1392   if (ContentProtectEnabled()) {
1393     // Check if this Sink supports SCMS
1394     bool cp_active = AudioProtectHasScmst(num_protect, p_protect_info);
1395     p_peer->SetContentProtectActive(cp_active);
1396   }
1397 }
1398 
getStateFromPeer(const BtaAvCoPeer * p_peer)1399 BtaAvCoState* BtaAvCo::getStateFromPeer(const BtaAvCoPeer* p_peer) {
1400   if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) {
1401     if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SINK) {
1402       return &bta_av_source_state_;
1403     } else if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SOURCE) {
1404       return &bta_av_sink_state_;
1405     } else {
1406       log::warn("Invalid bta av state for peer_address : {} with uuid as :{}",
1407                 p_peer->addr, p_peer->uuid_to_connect);
1408       return nullptr;
1409     }
1410   } else {
1411     return &bta_av_legacy_state_;
1412   }
1413 }
1414 
SetCodecOtaConfig(BtaAvCoPeer * p_peer,const uint8_t * p_ota_codec_config,uint8_t num_protect,const uint8_t * p_protect_info,bool * p_restart_output,const uint8_t t_local_sep)1415 bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,
1416                                 const uint8_t* p_ota_codec_config,
1417                                 uint8_t num_protect,
1418                                 const uint8_t* p_protect_info,
1419                                 bool* p_restart_output,
1420                                 const uint8_t t_local_sep) {
1421   uint8_t result_codec_config[AVDT_CODEC_SIZE];
1422   bool restart_input = false;
1423   bool restart_output = false;
1424   bool config_updated = false;
1425 
1426   log::info("peer_address={}, codec: {}", p_peer->addr,
1427             A2DP_CodecInfoString(p_ota_codec_config));
1428 
1429   *p_restart_output = false;
1430 
1431   // Find the peer SEP codec to use
1432   const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink(
1433       p_peer, A2DP_SourceCodecIndex(p_ota_codec_config), ContentProtectFlag());
1434   if ((p_peer->num_sup_sinks > 0) && (p_sink == nullptr)) {
1435     // There are no peer SEPs if we didn't do the discovery procedure yet.
1436     // We have all the information we need from the peer, so we can
1437     // proceed with the OTA codec configuration.
1438     log::error("peer {} : cannot find peer SEP to configure", p_peer->addr);
1439     return false;
1440   }
1441 
1442   tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1443   GetPeerEncoderParameters(p_peer->addr, &peer_params);
1444   if (!p_peer->GetCodecs()->setCodecOtaConfig(
1445           p_ota_codec_config, &peer_params, result_codec_config, &restart_input,
1446           &restart_output, &config_updated)) {
1447     log::error("peer {} : cannot set OTA config", p_peer->addr);
1448     return false;
1449   }
1450 
1451   if (restart_output) {
1452     log::verbose("restart output for codec: {}",
1453                  A2DP_CodecInfoString(result_codec_config));
1454 
1455     *p_restart_output = true;
1456     p_peer->p_sink = p_sink;
1457     SaveNewCodecConfig(p_peer, result_codec_config, num_protect, p_protect_info,
1458                        t_local_sep);
1459   }
1460 
1461   if (restart_input || config_updated) {
1462     // NOTE: Currently, the input is restarted by sending an upcall
1463     // and informing the Media Framework about the change of selected codec.
1464     ReportSourceCodecState(p_peer);
1465   }
1466 
1467   return true;
1468 }
1469 
bta_av_co_init(const std::vector<btav_a2dp_codec_config_t> & codec_priorities,std::vector<btav_a2dp_codec_info_t> * supported_codecs)1470 void bta_av_co_init(
1471     const std::vector<btav_a2dp_codec_config_t>& codec_priorities,
1472     std::vector<btav_a2dp_codec_info_t>* supported_codecs) {
1473   bta_av_co_cb.Init(codec_priorities, supported_codecs);
1474 }
1475 
bta_av_co_is_supported_codec(btav_a2dp_codec_index_t codec_index)1476 bool bta_av_co_is_supported_codec(btav_a2dp_codec_index_t codec_index) {
1477   return bta_av_co_cb.IsSupportedCodec(codec_index);
1478 }
1479 
bta_av_get_a2dp_current_codec(void)1480 A2dpCodecConfig* bta_av_get_a2dp_current_codec(void) {
1481   return bta_av_co_cb.GetActivePeerCurrentCodec();
1482 }
1483 
bta_av_get_a2dp_peer_current_codec(const RawAddress & peer_address)1484 A2dpCodecConfig* bta_av_get_a2dp_peer_current_codec(
1485     const RawAddress& peer_address) {
1486   return bta_av_co_cb.GetPeerCurrentCodec(peer_address);
1487 }
1488 
bta_av_co_audio_init(btav_a2dp_codec_index_t codec_index,AvdtpSepConfig * p_cfg)1489 bool bta_av_co_audio_init(btav_a2dp_codec_index_t codec_index,
1490                           AvdtpSepConfig* p_cfg) {
1491   return A2DP_InitCodecConfig(codec_index, p_cfg);
1492 }
1493 
bta_av_co_audio_disc_res(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint8_t num_seps,uint8_t num_sinks,uint8_t num_sources,uint16_t uuid_local)1494 void bta_av_co_audio_disc_res(tBTA_AV_HNDL bta_av_handle,
1495                               const RawAddress& peer_address, uint8_t num_seps,
1496                               uint8_t num_sinks, uint8_t num_sources,
1497                               uint16_t uuid_local) {
1498   bta_av_co_cb.ProcessDiscoveryResult(bta_av_handle, peer_address, num_seps,
1499                                       num_sinks, num_sources, uuid_local);
1500 }
1501 
bta_av_co_store_peer_codectype(const BtaAvCoPeer * p_peer)1502 static void bta_av_co_store_peer_codectype(const BtaAvCoPeer* p_peer) {
1503   int index, peer_codec_type = 0;
1504   const BtaAvCoSep* p_sink;
1505   log::verbose("");
1506   for (index = 0; index < p_peer->num_sup_sinks; index++) {
1507     p_sink = &p_peer->sinks[index];
1508     peer_codec_type |= A2DP_IotGetPeerSinkCodecType(p_sink->codec_caps);
1509   }
1510 
1511   DEVICE_IOT_CONFIG_ADDR_SET_HEX(p_peer->addr, IOT_CONF_KEY_A2DP_CODECTYPE,
1512                                  peer_codec_type, IOT_CONF_BYTE_NUM_1);
1513 }
1514 
bta_av_co_should_select_hardware_codec(const A2dpCodecConfig & software_config,const::bluetooth::audio::a2dp::provider::a2dp_configuration & hardware_config)1515 static bool bta_av_co_should_select_hardware_codec(
1516     const A2dpCodecConfig& software_config,
1517     const ::bluetooth::audio::a2dp::provider::a2dp_configuration&
1518         hardware_config) {
1519   btav_a2dp_codec_index_t software_codec_index = software_config.codecIndex();
1520   btav_a2dp_codec_index_t hardware_offload_index =
1521       hardware_config.codec_parameters.codec_type;
1522 
1523   // Prioritize any offload codec except SBC and AAC
1524   if (A2DP_GetCodecType(hardware_config.codec_config) ==
1525       A2DP_MEDIA_CT_NON_A2DP) {
1526     log::verbose("select hardware codec: {}",
1527                  A2DP_CodecIndexStr(hardware_offload_index));
1528     return true;
1529   }
1530   // Prioritize LDAC, AptX HD and AptX over AAC and SBC offload codecs
1531   if (software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC ||
1532       software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD ||
1533       software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
1534     log::verbose("select software codec: {}",
1535                  A2DP_CodecIndexStr(software_codec_index));
1536     return false;
1537   }
1538   // Prioritize AAC offload
1539   if (hardware_offload_index == BTAV_A2DP_CODEC_INDEX_SOURCE_AAC) {
1540     log::verbose("select hardware codec: {}",
1541                  A2DP_CodecIndexStr(hardware_offload_index));
1542     return true;
1543   }
1544   // Prioritize AAC software
1545   if (software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_AAC) {
1546     log::verbose("select software codec: {}",
1547                  A2DP_CodecIndexStr(software_codec_index));
1548     return false;
1549   }
1550   // Prioritize SBC offload
1551   if (hardware_offload_index == BTAV_A2DP_CODEC_INDEX_SOURCE_SBC) {
1552     log::verbose("select hardware codec: {}",
1553                  A2DP_CodecIndexStr(hardware_offload_index));
1554     return true;
1555   }
1556   // Prioritize SBC software
1557   if (software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_SBC) {
1558     log::verbose("select software codec: {}",
1559                  A2DP_CodecIndexStr(software_codec_index));
1560     return false;
1561   }
1562   log::error("select unknown software codec: {}",
1563              A2DP_CodecIndexStr(software_codec_index));
1564   return false;
1565 }
1566 
bta_av_co_audio_getconfig(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint8_t * p_codec_info,uint8_t * p_sep_info_idx,uint8_t seid,uint8_t * p_num_protect,uint8_t * p_protect_info)1567 tA2DP_STATUS bta_av_co_audio_getconfig(tBTA_AV_HNDL bta_av_handle,
1568                                        const RawAddress& peer_address,
1569                                        uint8_t* p_codec_info,
1570                                        uint8_t* p_sep_info_idx, uint8_t seid,
1571                                        uint8_t* p_num_protect,
1572                                        uint8_t* p_protect_info) {
1573   uint16_t peer_uuid = bta_av_co_cb.peer_cache_->FindPeerUuid(bta_av_handle);
1574 
1575   log::verbose("peer {} bta_av_handle=0x{:x} peer_uuid=0x{:x}", peer_address,
1576                bta_av_handle, peer_uuid);
1577 
1578   switch (peer_uuid) {
1579     case UUID_SERVCLASS_AUDIO_SOURCE:
1580       return bta_av_co_cb.ProcessSinkGetConfig(
1581           bta_av_handle, peer_address, p_codec_info, p_sep_info_idx, seid,
1582           p_num_protect, p_protect_info);
1583     case UUID_SERVCLASS_AUDIO_SINK:
1584       return bta_av_co_cb.ProcessSourceGetConfig(
1585           bta_av_handle, peer_address, p_codec_info, p_sep_info_idx, seid,
1586           p_num_protect, p_protect_info);
1587     default:
1588       break;
1589   }
1590   log::error("peer {} : Invalid peer UUID: 0x{:x} for bta_av_handle 0x{:x}",
1591              peer_address, peer_uuid, bta_av_handle);
1592   return A2DP_FAIL;
1593 }
1594 
bta_av_co_audio_setconfig(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,const uint8_t * p_codec_info,uint8_t seid,uint8_t num_protect,const uint8_t * p_protect_info,uint8_t t_local_sep,uint8_t avdt_handle)1595 void bta_av_co_audio_setconfig(tBTA_AV_HNDL bta_av_handle,
1596                                const RawAddress& peer_address,
1597                                const uint8_t* p_codec_info, uint8_t seid,
1598                                uint8_t num_protect,
1599                                const uint8_t* p_protect_info,
1600                                uint8_t t_local_sep, uint8_t avdt_handle) {
1601   bta_av_co_cb.ProcessSetConfig(bta_av_handle, peer_address, p_codec_info, seid,
1602                                 num_protect, p_protect_info, t_local_sep,
1603                                 avdt_handle);
1604 }
1605 
bta_av_co_audio_open(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t mtu)1606 void bta_av_co_audio_open(tBTA_AV_HNDL bta_av_handle,
1607                           const RawAddress& peer_address, uint16_t mtu) {
1608   bta_av_co_cb.ProcessOpen(bta_av_handle, peer_address, mtu);
1609 }
1610 
bta_av_co_audio_close(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)1611 void bta_av_co_audio_close(tBTA_AV_HNDL bta_av_handle,
1612                            const RawAddress& peer_address) {
1613   bta_av_co_cb.ProcessClose(bta_av_handle, peer_address);
1614 }
1615 
bta_av_co_audio_start(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,const uint8_t * p_codec_info,bool * p_no_rtp_header)1616 void bta_av_co_audio_start(tBTA_AV_HNDL bta_av_handle,
1617                            const RawAddress& peer_address,
1618                            const uint8_t* p_codec_info, bool* p_no_rtp_header) {
1619   bta_av_co_cb.ProcessStart(bta_av_handle, peer_address, p_codec_info,
1620                             p_no_rtp_header);
1621 }
1622 
bta_av_co_audio_stop(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)1623 void bta_av_co_audio_stop(tBTA_AV_HNDL bta_av_handle,
1624                           const RawAddress& peer_address) {
1625   bta_av_co_cb.ProcessStop(bta_av_handle, peer_address);
1626 }
1627 
bta_av_co_audio_source_data_path(const uint8_t * p_codec_info,uint32_t * p_timestamp)1628 BT_HDR* bta_av_co_audio_source_data_path(const uint8_t* p_codec_info,
1629                                          uint32_t* p_timestamp) {
1630   return bta_av_co_cb.GetNextSourceDataPacket(p_codec_info, p_timestamp);
1631 }
1632 
bta_av_co_audio_drop(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)1633 void bta_av_co_audio_drop(tBTA_AV_HNDL bta_av_handle,
1634                           const RawAddress& peer_address) {
1635   bta_av_co_cb.DataPacketWasDropped(bta_av_handle, peer_address);
1636 }
1637 
bta_av_co_audio_delay(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t delay)1638 void bta_av_co_audio_delay(tBTA_AV_HNDL bta_av_handle,
1639                            const RawAddress& peer_address, uint16_t delay) {
1640   bta_av_co_cb.ProcessAudioDelay(bta_av_handle, peer_address, delay);
1641 }
1642 
bta_av_co_audio_update_mtu(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t mtu)1643 void bta_av_co_audio_update_mtu(tBTA_AV_HNDL bta_av_handle,
1644                                 const RawAddress& peer_address, uint16_t mtu) {
1645   bta_av_co_cb.UpdateMtu(bta_av_handle, peer_address, mtu);
1646 }
1647 
bta_av_co_set_active_peer(const RawAddress & peer_address)1648 bool bta_av_co_set_active_peer(const RawAddress& peer_address) {
1649   return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_INVALID);
1650 }
1651 
bta_av_co_set_active_sink_peer(const RawAddress & peer_address)1652 bool bta_av_co_set_active_sink_peer(const RawAddress& peer_address) {
1653   return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_SNK);
1654 }
1655 
bta_av_co_set_active_source_peer(const RawAddress & peer_address)1656 bool bta_av_co_set_active_source_peer(const RawAddress& peer_address) {
1657   return bta_av_co_cb.SetActivePeer(peer_address, AVDT_TSEP_SRC);
1658 }
1659 
bta_av_co_save_codec(const uint8_t * new_codec_config)1660 void bta_av_co_save_codec(const uint8_t* new_codec_config) {
1661   return bta_av_co_cb.SaveCodec(new_codec_config);
1662 }
1663 
bta_av_co_get_peer_params(const RawAddress & peer_address,tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params)1664 void bta_av_co_get_peer_params(const RawAddress& peer_address,
1665                                tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {
1666   bta_av_co_cb.GetPeerEncoderParameters(peer_address, p_peer_params);
1667 }
1668 
bta_av_co_get_encoder_interface(void)1669 const tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface(void) {
1670   return bta_av_co_cb.GetSourceEncoderInterface();
1671 }
1672 
bta_av_co_set_codec_user_config(const RawAddress & peer_address,const btav_a2dp_codec_config_t & codec_user_config,bool * p_restart_output)1673 bool bta_av_co_set_codec_user_config(
1674     const RawAddress& peer_address,
1675     const btav_a2dp_codec_config_t& codec_user_config, bool* p_restart_output) {
1676   return bta_av_co_cb.SetCodecUserConfig(peer_address, codec_user_config,
1677                                          p_restart_output);
1678 }
1679 
bta_av_co_set_codec_audio_config(const btav_a2dp_codec_config_t & codec_audio_config)1680 bool bta_av_co_set_codec_audio_config(
1681     const btav_a2dp_codec_config_t& codec_audio_config) {
1682   return bta_av_co_cb.SetCodecAudioConfig(codec_audio_config);
1683 }
1684 
bta_av_co_get_encoder_effective_frame_size()1685 int bta_av_co_get_encoder_effective_frame_size() {
1686   return bta_av_co_cb.GetSourceEncoderEffectiveFrameSize();
1687 }
1688 
bta_av_co_get_scmst_info(const RawAddress & peer_address)1689 btav_a2dp_scmst_info_t bta_av_co_get_scmst_info(
1690     const RawAddress& peer_address) {
1691   BtaAvCoPeer* p_peer = bta_av_co_cb.peer_cache_->FindPeer(peer_address);
1692   log::assert_that(p_peer != nullptr, "assert failed: p_peer != nullptr");
1693   btav_a2dp_scmst_info_t scmst_info{};
1694   scmst_info.enable_status = BTAV_A2DP_SCMST_DISABLED;
1695 
1696   if (p_peer->ContentProtectActive()) {
1697     scmst_info.enable_status = BTAV_A2DP_SCMST_ENABLED;
1698     scmst_info.cp_header = bta_av_co_cb.ContentProtectFlag();
1699   }
1700 
1701   return scmst_info;
1702 }
1703 
btif_a2dp_codec_debug_dump(int fd)1704 void btif_a2dp_codec_debug_dump(int fd) { bta_av_co_cb.DebugDump(fd); }
1705