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