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