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 #include <mutex>
27
28 #include <base/bind.h>
29 #include <base/logging.h>
30 #include <string.h>
31
32 #include "bt_target.h"
33
34 #include "a2dp_api.h"
35 #include "a2dp_sbc.h"
36 #include "bta_av_api.h"
37 #include "bta_av_ci.h"
38 #include "bta_av_co.h"
39 #include "bta_sys.h"
40
41 #include "btif_av.h"
42 #include "btif_av_co.h"
43 #include "btif_util.h"
44 #include "osi/include/osi.h"
45 #include "osi/include/properties.h"
46
47 // Macro to retrieve the number of elements in a statically allocated array
48 #define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a) / sizeof((__a)[0]))
49
50 // Macro to convert BTA AV audio handle to index and vice versa
51 #define BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle) \
52 (((bta_av_handle) & (~BTA_AV_CHNL_MSK)) - 1)
53 #define BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(index) \
54 (((index) + 1) | BTA_AV_CHNL_AUDIO)
55
56 class BtaAvCoSep {
57 public:
BtaAvCoSep()58 BtaAvCoSep()
59 : sep_info_idx(0), seid(0), codec_caps{}, num_protect(0), protect_info{} {
60 Reset();
61 }
62
63 /**
64 * Reset the state.
65 */
Reset()66 void Reset() {
67 sep_info_idx = 0;
68 seid = 0;
69 memset(codec_caps, 0, sizeof(codec_caps));
70 num_protect = 0;
71 memset(protect_info, 0, sizeof(protect_info));
72 }
73
74 uint8_t sep_info_idx; // Local SEP index (in BTA tables)
75 uint8_t seid; // Peer SEP index (in peer tables)
76 uint8_t codec_caps[AVDT_CODEC_SIZE]; // Peer SEP codec capabilities
77 uint8_t num_protect; // Peer SEP number of CP elements
78 uint8_t protect_info[AVDT_CP_INFO_LEN]; // Peer SEP content protection info
79 };
80
81 class BtaAvCoPeer {
82 public:
BtaAvCoPeer()83 BtaAvCoPeer()
84 : addr(RawAddress::kEmpty),
85 num_sinks(0),
86 num_sources(0),
87 num_seps(0),
88 num_rx_sinks(0),
89 num_rx_sources(0),
90 num_sup_sinks(0),
91 num_sup_sources(0),
92 p_sink(nullptr),
93 p_source(nullptr),
94 codec_config{},
95 acceptor(false),
96 reconfig_needed(false),
97 opened(false),
98 mtu(0),
99 uuid_to_connect(0),
100 bta_av_handle_(0),
101 codecs_(nullptr),
102 content_protect_active_(false) {
103 Reset(0);
104 }
105
106 /**
107 * Initialize the state.
108 *
109 * @param codec_priorities the codec priorities to use for the initialization
110 */
111 void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities);
112
113 /**
114 * Reset the state.
115 *
116 * @param bta_av_handle the BTA AV handle to use
117 */
118 void Reset(tBTA_AV_HNDL bta_av_handle);
119
120 /**
121 * Get the BTA AV handle.
122 *
123 * @return the BTA AV handle
124 */
BtaAvHandle() const125 tBTA_AV_HNDL BtaAvHandle() const { return bta_av_handle_; }
126
127 /**
128 * Get the A2DP codecs.
129 *
130 * @return the A2DP codecs
131 */
GetCodecs()132 A2dpCodecs* GetCodecs() { return codecs_; }
133
ContentProtectActive() const134 bool ContentProtectActive() const { return content_protect_active_; }
SetContentProtectActive(bool cp_active)135 void SetContentProtectActive(bool cp_active) {
136 content_protect_active_ = cp_active;
137 }
138
139 RawAddress addr; // Peer address
140 BtaAvCoSep sinks[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sinks
141 BtaAvCoSep sources[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sources
142 uint8_t num_sinks; // Total number of sinks at peer
143 uint8_t num_sources; // Total number of sources at peer
144 uint8_t num_seps; // Total number of SEPs at peer
145 uint8_t num_rx_sinks; // Number of received sinks
146 uint8_t num_rx_sources; // Number of received sources
147 uint8_t num_sup_sinks; // Number of supported sinks
148 uint8_t num_sup_sources; // Number of supported sources
149 const BtaAvCoSep* p_sink; // Currently selected sink
150 const BtaAvCoSep* p_source; // Currently selected source
151 uint8_t codec_config[AVDT_CODEC_SIZE]; // Current codec configuration
152 bool acceptor; // True if acceptor
153 bool reconfig_needed; // True if reconfiguration is needed
154 bool opened; // True if opened
155 uint16_t mtu; // Maximum Transmit Unit size
156 uint16_t uuid_to_connect; // UUID of peer device
157
158 private:
159 tBTA_AV_HNDL bta_av_handle_; // BTA AV handle to use
160 A2dpCodecs* codecs_; // Locally supported codecs
161 bool content_protect_active_; // True if Content Protect is active
162 };
163
164 class BtaAvCo {
165 public:
BtaAvCo(bool content_protect_enabled)166 BtaAvCo(bool content_protect_enabled)
167 : active_peer_(nullptr),
168 codec_config_{},
169 content_protect_enabled_(content_protect_enabled),
170 content_protect_flag_(0) {
171 Reset();
172 }
173
174 /**
175 * Initialize the state.
176 *
177 * @param codec_priorities the codec priorities to use for the initialization
178 */
179 void Init(const std::vector<btav_a2dp_codec_config_t>& codec_priorities);
180
181 /**
182 * Checks whether a codec is supported.
183 *
184 * @param codec_index the index of the codec to check
185 * @return true if the codec is supported, otherwise false
186 */
187 bool IsSupportedCodec(btav_a2dp_codec_index_t codec_index);
188
189 /**
190 * Get the current codec configuration for the active peer.
191 *
192 * @return the current codec configuration if found, otherwise nullptr
193 */
194 A2dpCodecConfig* GetActivePeerCurrentCodec();
195
196 /**
197 * Get the current codec configuration for a peer.
198 *
199 * @param peer_address the peer address
200 * @return the current codec configuration if found, otherwise nullptr
201 */
202 A2dpCodecConfig* GetPeerCurrentCodec(const RawAddress& peer_address);
203
204 /**
205 * Find the peer UUID for a given BTA AV handle.
206 *
207 * @param bta_av_handle the BTA AV handle to use
208 * @return the peer UUID if found, otherwise 0
209 */
210 uint16_t FindPeerUuid(tBTA_AV_HNDL bta_av_handle);
211
212 /**
213 * Process the AVDTP discovery result: number of Stream End Points (SEP)
214 * found during the AVDTP stream discovery process.
215 *
216 * @param bta_av_handle the BTA AV handle to identify the peer
217 * @param peer_address the peer address
218 * @param num_seps the number of discovered SEPs
219 * @param num_sinks number of discovered Sink SEPs
220 * @param num_sources number of discovered Source SEPs
221 * @param uuid_local local UUID
222 */
223 void ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle,
224 const RawAddress& peer_address, uint8_t num_seps,
225 uint8_t num_sinks, uint8_t num_sources,
226 uint16_t uuid_local);
227
228 /**
229 * Process retrieved codec configuration and content protection from
230 * Peer Sink SEP.
231 *
232 * @param bta_av_handle the BTA AV handle to identify the peer
233 * @param peer_address the peer address
234 * @param p_codec_info the peer sink capability filled-in by the caller.
235 * On success, it will contain the current codec configuration for the peer.
236 * @param p_sep_info_idx the peer SEP index for the corresponding peer
237 * sink capability filled-in by the caller. On success, it will contain
238 * the SEP index for the current codec configuration for the peer.
239 * @param seid the peer SEP index in peer tables
240 * @param p_num_protect the peer SEP number of content protection elements
241 * filled-in by the caller. On success, it will contain the SEP number of
242 * content protection elements for the current codec configuration for the
243 * peer.
244 * @param p_protect_info the peer SEP content protection info filled-in by
245 * the caller. On success, it will contain the SEP content protection info
246 * for the current codec configuration for the peer.
247 * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL
248 */
249 tA2DP_STATUS ProcessSourceGetConfig(tBTA_AV_HNDL bta_av_handle,
250 const RawAddress& peer_address,
251 uint8_t* p_codec_info,
252 uint8_t* p_sep_info_idx, uint8_t seid,
253 uint8_t* p_num_protect,
254 uint8_t* p_protect_info);
255
256 /**
257 * Process retrieved codec configuration and content protection from
258 * Peer Source SEP.
259 *
260 * @param bta_av_handle the BTA AV handle to identify the peer
261 * @param peer_address the peer address
262 * @param p_codec_info the peer source capability filled-in by the caller.
263 * On success, it will contain the current codec configuration for the peer.
264 * @param p_sep_info_idx the peer SEP index for the corresponding peer
265 * source capability filled-in by the caller. On success, it will contain
266 * the SEP index for the current codec configuration for the peer.
267 * @param seid the peer SEP index in peer tables
268 * @param p_num_protect the peer SEP number of content protection elements
269 * filled-in by the caller. On success, it will contain the SEP number of
270 * content protection elements for the current codec configuration for the
271 * peer.
272 * @param p_protect_info the peer SEP content protection info filled-in by
273 * the caller. On success, it will contain the SEP content protection info
274 * for the current codec configuration for the peer.
275 * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL
276 */
277 tA2DP_STATUS ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
278 const RawAddress& peer_address,
279 uint8_t* p_codec_info,
280 uint8_t* p_sep_info_idx, uint8_t seid,
281 uint8_t* p_num_protect,
282 uint8_t* p_protect_info);
283
284 /**
285 * Process AVDTP Set Config to set the codec and content protection
286 * configuration of the audio stream.
287 *
288 * @param bta_av_handle the BTA AV handle to identify the peer
289 * @param peer_address the peer address
290 * @param p_codec_info the codec configuration to set
291 * @param seid stream endpoint ID of stream initiating the operation
292 * @param peer_address the peer address
293 * @param num_protect the peer SEP number of content protection elements
294 * @param p_protect_info the peer SEP conntent protection info
295 * @param t_local_sep the local SEP: AVDT_TSEP_SRC or AVDT_TSEP_SNK
296 * @param avdt_handle the AVDTP handle
297 */
298 void ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,
299 const RawAddress& peer_address,
300 const uint8_t* p_codec_info, uint8_t seid,
301 uint8_t num_protect, const uint8_t* p_protect_info,
302 uint8_t t_local_sep, uint8_t avdt_handle);
303
304 /**
305 * Process AVDTP Open when the stream connection is opened.
306 *
307 * @param bta_av_handle the BTA AV handle to identify the peer
308 * @param peer_address the peer address
309 * @param mtu the MTU of the connection
310 */
311 void ProcessOpen(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
312 uint16_t mtu);
313
314 /**
315 * Process AVDTP Close when the stream connection is closed.
316 *
317 * @param bta_av_handle the BTA AV handle to identify the peer
318 * @param peer_address the peer address
319 */
320 void ProcessClose(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address);
321
322 /**
323 * Process AVDTP Start when the audio data streaming is started.
324 *
325 * @param bta_av_handle the BTA AV handle to identify the peer
326 * @param peer_address the peer address
327 * @param p_codec_info the codec configuration
328 * @param p_no_rtp_header on return, set to true if the audio data packets
329 * should not contain RTP header
330 */
331 void ProcessStart(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
332 const uint8_t* p_codec_info, bool* p_no_rtp_header);
333
334 /**
335 * Process AVDTP Stop when the audio data streaming is stopped.
336 *
337 * @param bta_av_handle the BTA AV handle to identify the peer
338 * @param peer_address the peer address
339 */
340 void ProcessStop(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address);
341
342 /**
343 * Get the next encoded audio data packet to send.
344 *
345 * @param p_codec_info the codec configuration
346 * @param p_timestamp on return, set to the timestamp of the data packet
347 * @return the next encoded data packet or nullptr if no encoded data to send
348 */
349 BT_HDR* GetNextSourceDataPacket(const uint8_t* p_codec_info,
350 uint32_t* p_timestamp);
351
352 /**
353 * An audio packet has been dropped.
354 * This signal can be used by the encoder to reduce the encoder bit rate
355 * setting.
356 *
357 * @param bta_av_handle the BTA AV handle to identify the peer
358 * @param peer_address the peer address
359 */
360 void DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle,
361 const RawAddress& peer_address);
362
363 /**
364 * Process AVDTP Audio Delay when the initial delay report is received by
365 * the Source.
366 *
367 * @param bta_av_handle the BTA AV handle to identify the peer
368 * @param peer_address the peer address
369 * @param delay the reported delay in 1/10th of a millisecond
370 */
371 void ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle,
372 const RawAddress& peer_address, uint16_t delay);
373
374 /**
375 * Update the MTU of the audio data connection.
376 *
377 * @param bta_av_handle the BTA AV handle to identify the peer
378 * @param peer_address the peer address
379 * @param mtu the new MTU of the audio data connection
380 */
381 void UpdateMtu(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
382 uint16_t mtu);
383
384 /**
385 * Set the active peer.
386 *
387 * @param peer_address the peer address
388 * @return true on success, otherwise false
389 */
390 bool SetActivePeer(const RawAddress& peer_address);
391
392 /**
393 * Get the encoder parameters for a peer.
394 *
395 * @param peer_address the peer address
396 * @param p_peer_params on return, set to the peer's encoder parameters
397 */
398 void GetPeerEncoderParameters(const RawAddress& peer_address,
399 tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params);
400
401 /**
402 * Get the Source encoder interface for the current codec.
403 *
404 * @return the Source encoder interface for the current codec
405 */
406 const tA2DP_ENCODER_INTERFACE* GetSourceEncoderInterface();
407
408 /**
409 * Get the Sink decoder interface for the current codec.
410 *
411 * @return the Sink decoder interface for the current codec
412 */
413 const tA2DP_DECODER_INTERFACE* GetSinkDecoderInterface();
414
415 /**
416 * Set the codec user configuration.
417 *
418 * @param peer_address the peer address
419 * @param codec_user_config the codec user configuration to set
420 * @param p_restart_output if there is a change in the encoder configuration
421 * that requires restarting of the A2DP connection, flag |p_restart_output|
422 * will be set to true.
423 * @return true on success, otherwise false
424 */
425 bool SetCodecUserConfig(const RawAddress& peer_address,
426 const btav_a2dp_codec_config_t& codec_user_config,
427 bool* p_restart_output);
428
429 /**
430 * Set the codec audio configuration.
431 *
432 * @param codec_audio_config the codec audio configuration to set
433 * @return true on success, otherwise false
434 */
435 bool SetCodecAudioConfig(const btav_a2dp_codec_config_t& codec_audio_config);
436
437 /**
438 * Report the source codec state for a peer
439 *
440 * @param p_peer the peer to report
441 * @return true on success, otherwise false
442 */
443 bool ReportSourceCodecState(BtaAvCoPeer* p_peer);
444
445 /**
446 * Report the sink codec state for a peer
447 *
448 * @param p_peer the peer to report
449 * @return true on success, otherwise false
450 */
451 bool ReportSinkCodecState(BtaAvCoPeer* p_peer);
452
453 /**
454 * Get the content protection flag.
455 *
456 * @return the content protection flag. It should be one of the following:
457 * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE
458 */
ContentProtectFlag() const459 uint8_t ContentProtectFlag() const { return content_protect_flag_; }
460
461 /**
462 * Set the content protection flag.
463 *
464 * @param cp_flag the content protection flag. It should be one of the
465 * following:
466 * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE
467 * NOTE: If Content Protection is not enabled on the system, then
468 * the only acceptable vailue is AVDT_CP_SCMS_COPY_FREE.
469 */
SetContentProtectFlag(uint8_t cp_flag)470 void SetContentProtectFlag(uint8_t cp_flag) {
471 if (!ContentProtectEnabled() && (cp_flag != AVDT_CP_SCMS_COPY_FREE)) {
472 return;
473 }
474 content_protect_flag_ = cp_flag;
475 }
476
477 /**
478 * Dump debug-related information.
479 *
480 * @param fd the file descritor to use for writing the ASCII formatted
481 * information
482 */
483 void DebugDump(int fd);
484
485 /**
486 * Find the peer entry for a given peer address.
487 *
488 * @param peer_address the peer address to use
489 * @return the peer entry if found, otherwise nullptr
490 */
491 BtaAvCoPeer* FindPeer(const RawAddress& peer_address);
492
493 /**
494 * Find the peer Sink SEP entry for a given codec index.
495 *
496 * @param p_peer the peer to use
497 * @param codec_index the codec index to use
498 * @return the peer Sink SEP for the codec index if found, otherwise nullptr
499 */
500 BtaAvCoSep* FindPeerSink(BtaAvCoPeer* p_peer,
501 btav_a2dp_codec_index_t codec_index);
502
503 /**
504 * Find the peer Source SEP entry for a given codec index.
505 *
506 * @param p_peer the peer to use
507 * @param codec_config the codec index to use
508 * @return the peer Source SEP for the codec index if found, otherwise nullptr
509 */
510 BtaAvCoSep* FindPeerSource(BtaAvCoPeer* p_peer,
511 btav_a2dp_codec_index_t codec_index);
512
513 private:
514 /**
515 * Reset the state.
516 */
517 void Reset();
518
519 /**
520 * Find the peer entry for a given BTA AV handle.
521 *
522 * @param bta_av_handle the BTA AV handle to use
523 * @return the peer entry if found, otherwise nullptr
524 */
525 BtaAvCoPeer* FindPeer(tBTA_AV_HNDL bta_av_handle);
526
527 /**
528 * Find the peer entry for a given BTA AV handle and update it with the
529 * peer address.
530 *
531 * @param bta_av_handle the BTA AV handle to use
532 * @param peer_address the peer address
533 * @return the peer entry if found, otherwise nullptr
534 */
535 BtaAvCoPeer* FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle,
536 const RawAddress& peer_address);
537
538 /**
539 * Select the Source codec configuration based on peer codec support.
540 *
541 * Furthermore, the local state for the remaining non-selected codecs is
542 * updated to reflect whether the codec is selectable.
543 *
544 * @param p_peer the peer to use
545 * @return a pointer to the corresponding SEP Sink entry on success,
546 * otherwise nullptr
547 */
548 const BtaAvCoSep* SelectSourceCodec(BtaAvCoPeer* p_peer);
549
550 /**
551 * Select the Sink codec configuration based on peer codec support.
552 *
553 * Furthermore, the local state for the remaining non-selected codecs is
554 * updated to reflect whether the codec is selectable.
555 *
556 * @param p_peer the peer to use
557 * @return a pointer to the corresponding SEP Source entry on success,
558 * otherwise nullptr
559 */
560 const BtaAvCoSep* SelectSinkCodec(BtaAvCoPeer* p_peer);
561
562 /**
563 * Save new codec configuration.
564 *
565 * @param p_peer the peer to use
566 * @param new_codec_config the new codec configuration to use
567 * @param num_protect the number of content protection elements
568 * @param p_protect_info the content protection info to use
569 */
570 void SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config,
571 uint8_t num_protect, const uint8_t* p_protect_info);
572
573 /**
574 * Set the Over-The-Air preferred codec configuration.
575 *
576 * The OTA prefered codec configuration is ignored if the current
577 * codec configuration contains explicit user configuration, or if the
578 * codec configuration for the same codec contains explicit user
579 * configuration.
580 *
581 * @param p_peer is the peer device that sent the OTA codec configuration
582 * @param p_ota_codec_config contains the received OTA A2DP codec
583 * configuration from the remote peer. Note: this is not the peer codec
584 * capability, but the codec configuration that the peer would like to use.
585 * @param num_protect is the number of content protection methods to use
586 * @param p_protect_info contains the content protection information to use.
587 * @param p_restart_output if there is a change in the encoder configuration
588 * that requires restarting of the A2DP connection, flag |p_restart_output|
589 * is set to true.
590 * @return true on success, otherwise false
591 */
592 bool SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config,
593 uint8_t num_protect, const uint8_t* p_protect_info,
594 bool* p_restart_output);
595
596 /**
597 * Update all selectable Source codecs with the corresponding codec
598 * information from a Sink peer.
599 *
600 * @param p_peer the peer Sink SEP to use
601 * @return the number of codecs that have been updated
602 */
603 size_t UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer);
604
605 /**
606 * Update a selectable Source codec with the corresponding codec information
607 * from a Sink peer.
608 *
609 * @param codec_config the codec config info to identify the codec to update
610 * @param p_peer the peer Sink SEP to use
611 * @return true if the codec is updated, otherwise false
612 */
613 bool UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config,
614 BtaAvCoPeer* p_peer);
615
616 /**
617 * Update all selectable Sink codecs with the corresponding codec
618 * information from a Source peer.
619 *
620 * @param p_peer the peer Source SEP to use
621 * @return the number of codecs that have been updated
622 */
623 size_t UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer);
624
625 /**
626 * Update a selectable Sink codec with the corresponding codec information
627 * from a Source peer.
628 *
629 * @param codec_config the codec config info to identify the codec to update
630 * @param p_peer the peer Source SEP to use
631 * @return true if the codec is updated, otherwise false
632 */
633 bool UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config,
634 BtaAvCoPeer* p_peer);
635
636 /**
637 * Attempt to select Source codec configuration for a Sink peer.
638 *
639 * @param codec_config the codec configuration to use
640 * @param p_peer the Sink peer to use
641 * @return a pointer to the corresponding SEP Sink entry on success,
642 * otnerwise nullptr
643 */
644 const BtaAvCoSep* AttemptSourceCodecSelection(
645 const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer);
646
647 /**
648 * Attempt to select Sink codec configuration for a Source peer.
649 *
650 * @param codec_config the codec configuration to use
651 * @param p_peer the Source peer to use
652 * @return a pointer to the corresponding SEP Source entry on success,
653 * otnerwise nullptr
654 */
655 const BtaAvCoSep* AttemptSinkCodecSelection(
656 const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer);
657
658 /**
659 * Check if a peer SEP has content protection enabled.
660 *
661 * @param p_sep the peer SEP to check
662 * @return true if the peer SEP has content protection enabled,
663 * otherwise false
664 */
665 bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep);
666
667 /**
668 * Check if a content protection service is SCMS-T.
669 *
670 * @param p_orotect_info the content protection info to check
671 * @return true if the Contention Protection in @param p_protect_info
672 * is SCMS-T, otherwise false
673 */
674 static bool ContentProtectIsScmst(const uint8_t* p_protect_info);
675
676 /**
677 * Check if audio protect info contains SCMS-T Content Protection.
678 *
679 * @param num_protect number of protect schemes
680 * @param p_protect_info the protect info to check
681 * @return true if @param p_protect_info contains SCMS-T, otherwise false
682 */
683 static bool AudioProtectHasScmst(uint8_t num_protect,
684 const uint8_t* p_protect_info);
685
ContentProtectEnabled() const686 bool ContentProtectEnabled() const { return content_protect_enabled_; }
687
688 std::recursive_mutex codec_lock_; // Protect access to the codec state
689 std::vector<btav_a2dp_codec_config_t> codec_priorities_; // Configured
690 BtaAvCoPeer peers_[BTA_AV_NUM_STRS]; // Connected peer information
691 BtaAvCoPeer* active_peer_; // The current active peer
692 uint8_t codec_config_[AVDT_CODEC_SIZE]; // Current codec configuration
693 const bool content_protect_enabled_; // True if Content Protect is enabled
694 uint8_t content_protect_flag_; // Content Protect flag
695 };
696
697 // SCMS-T protect info
698 const uint8_t bta_av_co_cp_scmst[AVDT_CP_INFO_LEN] = {0x02, 0x02, 0x00};
699
700 // Control block instance
701 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
702 static const bool kContentProtectEnabled = true;
703 #else
704 static const bool kContentProtectEnabled = false;
705 #endif
706 static BtaAvCo bta_av_co_cb(kContentProtectEnabled);
707
Init(const std::vector<btav_a2dp_codec_config_t> & codec_priorities)708 void BtaAvCoPeer::Init(
709 const std::vector<btav_a2dp_codec_config_t>& codec_priorities) {
710 Reset(bta_av_handle_);
711 // Reset the current config
712 codecs_ = new A2dpCodecs(codec_priorities);
713 codecs_->init();
714 A2DP_InitDefaultCodec(codec_config);
715 }
716
Reset(tBTA_AV_HNDL bta_av_handle)717 void BtaAvCoPeer::Reset(tBTA_AV_HNDL bta_av_handle) {
718 addr = RawAddress::kEmpty;
719 for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(sinks); i++) {
720 BtaAvCoSep& sink = sinks[i];
721 sink.Reset();
722 }
723 for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(sources); i++) {
724 BtaAvCoSep& source = sources[i];
725 source.Reset();
726 }
727 num_sinks = 0;
728 num_sources = 0;
729 num_seps = 0;
730 num_rx_sinks = 0;
731 num_rx_sources = 0;
732 num_sup_sinks = 0;
733 num_sup_sources = 0;
734 p_sink = nullptr;
735 p_source = nullptr;
736 memset(codec_config, 0, sizeof(codec_config));
737 acceptor = false;
738 reconfig_needed = false;
739 opened = false;
740 mtu = 0;
741 uuid_to_connect = 0;
742
743 bta_av_handle_ = bta_av_handle;
744 delete codecs_;
745 codecs_ = nullptr;
746 content_protect_active_ = false;
747 }
748
Init(const std::vector<btav_a2dp_codec_config_t> & codec_priorities)749 void BtaAvCo::Init(
750 const std::vector<btav_a2dp_codec_config_t>& codec_priorities) {
751 APPL_TRACE_DEBUG("%s", __func__);
752
753 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
754
755 // Reset the control block
756 Reset();
757 codec_priorities_ = codec_priorities;
758
759 for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
760 BtaAvCoPeer* p_peer = &peers_[i];
761 p_peer->Init(codec_priorities);
762 }
763 }
764
Reset()765 void BtaAvCo::Reset() {
766 codec_priorities_.clear();
767 active_peer_ = nullptr;
768 content_protect_flag_ = 0;
769 memset(codec_config_, 0, sizeof(codec_config_));
770
771 if (ContentProtectEnabled()) {
772 SetContentProtectFlag(AVDT_CP_SCMS_COPY_NEVER);
773 } else {
774 SetContentProtectFlag(AVDT_CP_SCMS_COPY_FREE);
775 }
776
777 // Reset the peers and initialize the handles
778 for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
779 BtaAvCoPeer* p_peer = &peers_[i];
780 p_peer->Reset(BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(i));
781 }
782 }
783
IsSupportedCodec(btav_a2dp_codec_index_t codec_index)784 bool BtaAvCo::IsSupportedCodec(btav_a2dp_codec_index_t codec_index) {
785 // All peer state is initialized with the same local codec config,
786 // hence we check only the first peer.
787 A2dpCodecs* codecs = peers_[0].GetCodecs();
788 CHECK(codecs != nullptr);
789 return codecs->isSupportedCodec(codec_index);
790 }
791
GetActivePeerCurrentCodec()792 A2dpCodecConfig* BtaAvCo::GetActivePeerCurrentCodec() {
793 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
794
795 if (active_peer_ == nullptr || active_peer_->GetCodecs() == nullptr) {
796 return nullptr;
797 }
798 return active_peer_->GetCodecs()->getCurrentCodecConfig();
799 }
800
GetPeerCurrentCodec(const RawAddress & peer_address)801 A2dpCodecConfig* BtaAvCo::GetPeerCurrentCodec(const RawAddress& peer_address) {
802 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
803
804 BtaAvCoPeer* peer = FindPeer(peer_address);
805 if (peer == nullptr || peer->GetCodecs() == nullptr) {
806 return nullptr;
807 }
808 return peer->GetCodecs()->getCurrentCodecConfig();
809 }
810
FindPeer(const RawAddress & peer_address)811 BtaAvCoPeer* BtaAvCo::FindPeer(const RawAddress& peer_address) {
812 for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
813 BtaAvCoPeer* p_peer = &peers_[i];
814 if (p_peer->addr == peer_address) {
815 return p_peer;
816 }
817 }
818 return nullptr;
819 }
820
FindPeer(tBTA_AV_HNDL bta_av_handle)821 BtaAvCoPeer* BtaAvCo::FindPeer(tBTA_AV_HNDL bta_av_handle) {
822 uint8_t index;
823
824 index = BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle);
825
826 APPL_TRACE_DEBUG("%s: bta_av_handle = 0x%x index = %d", __func__,
827 bta_av_handle, index);
828
829 // Sanity check
830 if (index >= BTA_AV_CO_NUM_ELEMENTS(peers_)) {
831 APPL_TRACE_ERROR(
832 "%s: peer index %d for BTA AV handle 0x%x is out of bounds", __func__,
833 index, bta_av_handle);
834 return nullptr;
835 }
836
837 return &peers_[index];
838 }
839
FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)840 BtaAvCoPeer* BtaAvCo::FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle,
841 const RawAddress& peer_address) {
842 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle = 0x%x", __func__,
843 peer_address.ToString().c_str(), bta_av_handle);
844
845 BtaAvCoPeer* p_peer = FindPeer(bta_av_handle);
846 if (p_peer == nullptr) {
847 APPL_TRACE_ERROR("%s: peer entry for BTA AV handle 0x%x peer %s not found",
848 __func__, bta_av_handle, peer_address.ToString().c_str());
849 return nullptr;
850 }
851
852 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle = 0x%x previous address %s",
853 __func__, peer_address.ToString().c_str(), bta_av_handle,
854 p_peer->addr.ToString().c_str());
855 p_peer->addr = peer_address;
856 return p_peer;
857 }
858
FindPeerUuid(tBTA_AV_HNDL bta_av_handle)859 uint16_t BtaAvCo::FindPeerUuid(tBTA_AV_HNDL bta_av_handle) {
860 BtaAvCoPeer* p_peer = FindPeer(bta_av_handle);
861 if (p_peer == nullptr) {
862 return 0;
863 }
864 return p_peer->uuid_to_connect;
865 }
866
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)867 void BtaAvCo::ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle,
868 const RawAddress& peer_address,
869 uint8_t num_seps, uint8_t num_sinks,
870 uint8_t num_sources, uint16_t uuid_local) {
871 APPL_TRACE_DEBUG(
872 "%s: peer %s bta_av_handle:0x%x num_seps:%d num_sinks:%d num_sources:%d",
873 __func__, peer_address.ToString().c_str(), bta_av_handle, num_seps,
874 num_sinks, num_sources);
875
876 // Find the peer
877 BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
878 if (p_peer == nullptr) {
879 APPL_TRACE_ERROR(
880 "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
881 __func__, bta_av_handle, peer_address.ToString().c_str());
882 return;
883 }
884
885 /* Sanity check : this should never happen */
886 if (p_peer->opened) {
887 APPL_TRACE_ERROR("%s: peer %s already opened", __func__,
888 peer_address.ToString().c_str());
889 }
890
891 /* Copy the discovery results */
892 p_peer->addr = peer_address;
893 p_peer->num_sinks = num_sinks;
894 p_peer->num_sources = num_sources;
895 p_peer->num_seps = num_seps;
896 p_peer->num_rx_sinks = 0;
897 p_peer->num_rx_sources = 0;
898 p_peer->num_sup_sinks = 0;
899 p_peer->num_sup_sources = 0;
900 if (uuid_local == UUID_SERVCLASS_AUDIO_SINK) {
901 p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SOURCE;
902 } else if (uuid_local == UUID_SERVCLASS_AUDIO_SOURCE) {
903 p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SINK;
904 }
905 }
906
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)907 tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig(
908 tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address,
909 uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid,
910 uint8_t* p_num_protect, uint8_t* p_protect_info) {
911 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle:0x%x codec:%s seid:%d", __func__,
912 peer_address.ToString().c_str(), bta_av_handle,
913 A2DP_CodecName(p_codec_info), seid);
914 APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
915 __func__, *p_num_protect, p_protect_info[0],
916 p_protect_info[1], p_protect_info[2]);
917 APPL_TRACE_DEBUG("%s: codec: %s", __func__,
918 A2DP_CodecInfoString(p_codec_info).c_str());
919
920 // Find the peer
921 BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
922 if (p_peer == nullptr) {
923 APPL_TRACE_ERROR(
924 "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
925 __func__, bta_av_handle, peer_address.ToString().c_str());
926 return A2DP_FAIL;
927 }
928 APPL_TRACE_DEBUG("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)",
929 __func__, p_peer->opened, p_peer->num_sinks,
930 p_peer->num_rx_sinks, p_peer->num_sup_sinks);
931
932 p_peer->num_rx_sinks++;
933
934 // Check the peer's Sink codec
935 if (A2DP_IsPeerSinkCodecValid(p_codec_info)) {
936 // If there is room for a new one
937 if (p_peer->num_sup_sinks < BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks)) {
938 BtaAvCoSep* p_sink = &p_peer->sinks[p_peer->num_sup_sinks++];
939
940 APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__,
941 p_codec_info[1], p_codec_info[2], p_codec_info[3],
942 p_codec_info[4], p_codec_info[5], p_codec_info[6]);
943
944 memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
945 p_sink->sep_info_idx = *p_sep_info_idx;
946 p_sink->seid = seid;
947 p_sink->num_protect = *p_num_protect;
948 memcpy(p_sink->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
949 } else {
950 APPL_TRACE_ERROR("%s: peer %s : no more room for Sink info", __func__,
951 p_peer->addr.ToString().c_str());
952 }
953 }
954
955 // Check if this is the last Sink get capabilities or all supported codec
956 // capabilities are retrieved.
957 if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
958 (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
959 return A2DP_FAIL;
960 }
961 APPL_TRACE_DEBUG("%s: last Sink codec reached for peer %s (local %s)",
962 __func__, p_peer->addr.ToString().c_str(),
963 p_peer->acceptor ? "acceptor" : "initiator");
964
965 // Select the Source codec
966 const BtaAvCoSep* p_sink = nullptr;
967 if (p_peer->acceptor) {
968 UpdateAllSelectableSourceCodecs(p_peer);
969 if (p_peer->p_sink == nullptr) {
970 // Update the selected codec
971 p_peer->p_sink =
972 FindPeerSink(p_peer, A2DP_SourceCodecIndex(p_peer->codec_config));
973 }
974 p_sink = p_peer->p_sink;
975 if (p_sink == nullptr) {
976 APPL_TRACE_ERROR("%s: cannot find the selected codec for peer %s",
977 __func__, p_peer->addr.ToString().c_str());
978 return A2DP_FAIL;
979 }
980 } else {
981 if (btif_av_peer_prefers_mandatory_codec(p_peer->addr)) {
982 // Apply user preferred codec directly before first codec selected.
983 p_sink = FindPeerSink(p_peer, BTAV_A2DP_CODEC_INDEX_SOURCE_SBC);
984 if (p_sink != nullptr) {
985 APPL_TRACE_API("%s: mandatory codec preferred for peer %s", __func__,
986 p_peer->addr.ToString().c_str());
987 btav_a2dp_codec_config_t high_priority_mandatory{
988 .codec_type = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC,
989 .codec_priority = BTAV_A2DP_CODEC_PRIORITY_HIGHEST,
990 // Using default settings for those untouched fields
991 };
992 uint8_t result_codec_config[AVDT_CODEC_SIZE];
993 bool restart_input = false;
994 bool restart_output = false;
995 bool config_updated = false;
996 tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
997 GetPeerEncoderParameters(p_peer->addr, &peer_params);
998 p_peer->GetCodecs()->setCodecUserConfig(
999 high_priority_mandatory, &peer_params, p_sink->codec_caps,
1000 result_codec_config, &restart_input, &restart_output,
1001 &config_updated);
1002 } else {
1003 APPL_TRACE_WARNING("%s: mandatory codec not found for peer %s",
1004 __func__, p_peer->addr.ToString().c_str());
1005 }
1006 }
1007 p_sink = SelectSourceCodec(p_peer);
1008 if (p_sink == nullptr) {
1009 APPL_TRACE_ERROR("%s: cannot set up codec for peer %s", __func__,
1010 p_peer->addr.ToString().c_str());
1011 return A2DP_FAIL;
1012 }
1013 }
1014
1015 // By default, no content protection
1016 *p_num_protect = 0;
1017 if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
1018 *p_num_protect = AVDT_CP_INFO_LEN;
1019 memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN);
1020 }
1021
1022 // If acceptor -> reconfig otherwise reply for configuration
1023 *p_sep_info_idx = p_sink->sep_info_idx;
1024 APPL_TRACE_EVENT("%s: peer %s acceptor:%s reconfig_needed:%s", __func__,
1025 p_peer->addr.ToString().c_str(),
1026 (p_peer->acceptor) ? "true" : "false",
1027 (p_peer->reconfig_needed) ? "true" : "false");
1028 if (p_peer->acceptor) {
1029 if (p_peer->reconfig_needed) {
1030 APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(0x%x) for peer %s", __func__,
1031 bta_av_handle, p_peer->addr.ToString().c_str());
1032 BTA_AvReconfig(bta_av_handle, true, p_sink->sep_info_idx,
1033 p_peer->codec_config, *p_num_protect, bta_av_co_cp_scmst);
1034 }
1035 } else {
1036 memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
1037 }
1038
1039 // report this peer selectable codecs after retrieved all its capabilities.
1040 LOG(INFO) << __func__ << ": retrieved " << +p_peer->num_rx_sinks
1041 << " capabilities from peer " << p_peer->addr;
1042 ReportSourceCodecState(p_peer);
1043
1044 return A2DP_SUCCESS;
1045 }
1046
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)1047 tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle,
1048 const RawAddress& peer_address,
1049 uint8_t* p_codec_info,
1050 uint8_t* p_sep_info_idx,
1051 uint8_t seid, uint8_t* p_num_protect,
1052 uint8_t* p_protect_info) {
1053 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
1054
1055 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle:0x%x codec:%s seid:%d", __func__,
1056 peer_address.ToString().c_str(), bta_av_handle,
1057 A2DP_CodecName(p_codec_info), seid);
1058 APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
1059 __func__, *p_num_protect, p_protect_info[0],
1060 p_protect_info[1], p_protect_info[2]);
1061 APPL_TRACE_DEBUG("%s: codec: %s", __func__,
1062 A2DP_CodecInfoString(p_codec_info).c_str());
1063
1064 // Find the peer
1065 BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
1066 if (p_peer == nullptr) {
1067 APPL_TRACE_ERROR(
1068 "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
1069 __func__, bta_av_handle, peer_address.ToString().c_str());
1070 return A2DP_FAIL;
1071 }
1072 APPL_TRACE_DEBUG(
1073 "%s: peer %s found (o=%d, n_sources=%d, n_rx_sources=%d, "
1074 "n_sup_sources=%d)",
1075 __func__, p_peer->addr.ToString().c_str(), p_peer->opened,
1076 p_peer->num_sources, p_peer->num_rx_sources, p_peer->num_sup_sources);
1077
1078 p_peer->num_rx_sources++;
1079
1080 // Check the peer's Source codec
1081 if (A2DP_IsPeerSourceCodecValid(p_codec_info)) {
1082 // If there is room for a new one
1083 if (p_peer->num_sup_sources < BTA_AV_CO_NUM_ELEMENTS(p_peer->sources)) {
1084 BtaAvCoSep* p_source = &p_peer->sources[p_peer->num_sup_sources++];
1085
1086 APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__,
1087 p_codec_info[1], p_codec_info[2], p_codec_info[3],
1088 p_codec_info[4], p_codec_info[5], p_codec_info[6]);
1089
1090 memcpy(p_source->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
1091 p_source->sep_info_idx = *p_sep_info_idx;
1092 p_source->seid = seid;
1093 p_source->num_protect = *p_num_protect;
1094 memcpy(p_source->protect_info, p_protect_info, AVDT_CP_INFO_LEN);
1095 } else {
1096 APPL_TRACE_ERROR("%s: peer %s : no more room for Source info", __func__,
1097 p_peer->addr.ToString().c_str());
1098 }
1099 }
1100
1101 // Check if this is the last Source get capabilities or all supported codec
1102 // capabilities are retrieved.
1103 if ((p_peer->num_rx_sources != p_peer->num_sources) &&
1104 (p_peer->num_sup_sources != BTA_AV_CO_NUM_ELEMENTS(p_peer->sources))) {
1105 return A2DP_FAIL;
1106 }
1107 APPL_TRACE_DEBUG("%s: last Source codec reached for peer %s", __func__,
1108 p_peer->addr.ToString().c_str());
1109
1110 // Select the Sink codec
1111 const BtaAvCoSep* p_source = nullptr;
1112 if (p_peer->acceptor) {
1113 UpdateAllSelectableSinkCodecs(p_peer);
1114 if (p_peer->p_source == nullptr) {
1115 // Update the selected codec
1116 p_peer->p_source =
1117 FindPeerSource(p_peer, A2DP_SinkCodecIndex(p_peer->codec_config));
1118 }
1119 p_source = p_peer->p_source;
1120 if (p_source == nullptr) {
1121 APPL_TRACE_ERROR("%s: cannot find the selected codec for peer %s",
1122 __func__, p_peer->addr.ToString().c_str());
1123 return A2DP_FAIL;
1124 }
1125 } else {
1126 p_source = SelectSinkCodec(p_peer);
1127 if (p_source == nullptr) {
1128 APPL_TRACE_ERROR("%s: cannot set up codec for the peer %s", __func__,
1129 p_peer->addr.ToString().c_str());
1130 return A2DP_FAIL;
1131 }
1132 }
1133
1134 // By default, no content protection
1135 *p_num_protect = 0;
1136 if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
1137 *p_num_protect = AVDT_CP_INFO_LEN;
1138 memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN);
1139 }
1140
1141 // If acceptor -> reconfig otherwise reply for configuration
1142 *p_sep_info_idx = p_source->sep_info_idx;
1143 APPL_TRACE_EVENT("%s: peer %s acceptor:%s reconfig_needed:%s", __func__,
1144 p_peer->addr.ToString().c_str(),
1145 (p_peer->acceptor) ? "true" : "false",
1146 (p_peer->reconfig_needed) ? "true" : "false");
1147 if (p_peer->acceptor) {
1148 if (p_peer->reconfig_needed) {
1149 APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(0x%x) for peer %s", __func__,
1150 bta_av_handle, p_peer->addr.ToString().c_str());
1151 BTA_AvReconfig(bta_av_handle, true, p_source->sep_info_idx,
1152 p_peer->codec_config, *p_num_protect, bta_av_co_cp_scmst);
1153 }
1154 } else {
1155 memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
1156 }
1157
1158 return A2DP_SUCCESS;
1159 }
1160
ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,UNUSED_ATTR const RawAddress & peer_address,const uint8_t * p_codec_info,UNUSED_ATTR uint8_t seid,uint8_t num_protect,const uint8_t * p_protect_info,uint8_t t_local_sep,uint8_t avdt_handle)1161 void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle,
1162 UNUSED_ATTR const RawAddress& peer_address,
1163 const uint8_t* p_codec_info,
1164 UNUSED_ATTR uint8_t seid, uint8_t num_protect,
1165 const uint8_t* p_protect_info,
1166 uint8_t t_local_sep, uint8_t avdt_handle) {
1167 tA2DP_STATUS status = A2DP_SUCCESS;
1168 uint8_t category = A2DP_SUCCESS;
1169 bool reconfig_needed = false;
1170
1171 APPL_TRACE_DEBUG(
1172 "%s: bta_av_handle=0x%x peer_address=%s seid=%d "
1173 "num_protect=%d t_local_sep=%d avdt_handle=%d",
1174 __func__, bta_av_handle, peer_address.ToString().c_str(), seid,
1175 num_protect, t_local_sep, avdt_handle);
1176 APPL_TRACE_DEBUG("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__,
1177 p_codec_info[1], p_codec_info[2], p_codec_info[3],
1178 p_codec_info[4], p_codec_info[5], p_codec_info[6]);
1179 APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x",
1180 __func__, num_protect, p_protect_info[0], p_protect_info[1],
1181 p_protect_info[2]);
1182 APPL_TRACE_DEBUG("%s: codec: %s", __func__,
1183 A2DP_CodecInfoString(p_codec_info).c_str());
1184
1185 // Find the peer
1186 BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
1187 if (p_peer == nullptr) {
1188 APPL_TRACE_ERROR(
1189 "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
1190 __func__, bta_av_handle, peer_address.ToString().c_str());
1191 // Call call-in rejecting the configuration
1192 bta_av_ci_setconfig(bta_av_handle, A2DP_BUSY, AVDT_ASC_CODEC, 0, nullptr,
1193 false, avdt_handle);
1194 return;
1195 }
1196
1197 APPL_TRACE_DEBUG(
1198 "%s: peer %s found (o=%d, n_sinks=%d, n_rx_sinks=%d, "
1199 "n_sup_sinks=%d)",
1200 __func__, p_peer->addr.ToString().c_str(), p_peer->opened,
1201 p_peer->num_sinks, p_peer->num_rx_sinks, p_peer->num_sup_sinks);
1202
1203 // Sanity check: should not be opened at this point
1204 if (p_peer->opened) {
1205 APPL_TRACE_ERROR("%s: peer %s already in use", __func__,
1206 p_peer->addr.ToString().c_str());
1207 }
1208
1209 if (num_protect != 0) {
1210 if (ContentProtectEnabled()) {
1211 if ((num_protect != 1) ||
1212 !BtaAvCo::ContentProtectIsScmst(p_protect_info)) {
1213 APPL_TRACE_ERROR("%s: wrong CP configuration for peer %s", __func__,
1214 p_peer->addr.ToString().c_str());
1215 status = A2DP_BAD_CP_TYPE;
1216 category = AVDT_ASC_PROTECT;
1217 }
1218 } else {
1219 // Do not support content protection for the time being
1220 APPL_TRACE_ERROR("%s: wrong CP configuration for peer %s", __func__,
1221 p_peer->addr.ToString().c_str());
1222 status = A2DP_BAD_CP_TYPE;
1223 category = AVDT_ASC_PROTECT;
1224 }
1225 }
1226
1227 if (status == A2DP_SUCCESS) {
1228 bool codec_config_supported = false;
1229
1230 if (t_local_sep == AVDT_TSEP_SNK) {
1231 APPL_TRACE_DEBUG("%s: peer %s is A2DP Source", __func__,
1232 p_peer->addr.ToString().c_str());
1233 codec_config_supported = A2DP_IsSinkCodecSupported(p_codec_info);
1234 if (codec_config_supported) {
1235 // If Peer is Source, and our config subset matches with what is
1236 // requested by peer, then just accept what peer wants.
1237 SaveNewCodecConfig(p_peer, p_codec_info, num_protect, p_protect_info);
1238 }
1239 }
1240 if (t_local_sep == AVDT_TSEP_SRC) {
1241 APPL_TRACE_DEBUG("%s: peer %s is A2DP SINK", __func__,
1242 p_peer->addr.ToString().c_str());
1243 // Ignore the restart_output flag: accepting the remote device's
1244 // codec selection should not trigger codec reconfiguration.
1245 bool dummy_restart_output = false;
1246 if ((p_peer->GetCodecs() == nullptr) ||
1247 !SetCodecOtaConfig(p_peer, p_codec_info, num_protect, p_protect_info,
1248 &dummy_restart_output)) {
1249 APPL_TRACE_ERROR("%s: cannot set source codec %s for peer %s", __func__,
1250 A2DP_CodecName(p_codec_info),
1251 p_peer->addr.ToString().c_str());
1252 } else {
1253 codec_config_supported = true;
1254 // Check if reconfiguration is needed
1255 if (((num_protect == 1) && !p_peer->ContentProtectActive())) {
1256 reconfig_needed = true;
1257 }
1258 }
1259 }
1260
1261 // Check if codec configuration is supported
1262 if (!codec_config_supported) {
1263 category = AVDT_ASC_CODEC;
1264 status = A2DP_WRONG_CODEC;
1265 }
1266 }
1267
1268 if (status != A2DP_SUCCESS) {
1269 APPL_TRACE_DEBUG("%s: peer %s reject s=%d c=%d", __func__,
1270 p_peer->addr.ToString().c_str(), status, category);
1271 // Call call-in rejecting the configuration
1272 bta_av_ci_setconfig(bta_av_handle, status, category, 0, nullptr, false,
1273 avdt_handle);
1274 return;
1275 }
1276
1277 // Mark that this is an acceptor peer
1278 p_peer->acceptor = true;
1279 p_peer->reconfig_needed = reconfig_needed;
1280 APPL_TRACE_DEBUG("%s: peer %s accept reconf=%d", __func__,
1281 p_peer->addr.ToString().c_str(), reconfig_needed);
1282 // Call call-in accepting the configuration
1283 bta_av_ci_setconfig(bta_av_handle, A2DP_SUCCESS, A2DP_SUCCESS, 0, nullptr,
1284 reconfig_needed, avdt_handle);
1285 }
1286
ProcessOpen(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t mtu)1287 void BtaAvCo::ProcessOpen(tBTA_AV_HNDL bta_av_handle,
1288 const RawAddress& peer_address, uint16_t mtu) {
1289 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x mtu:%d", __func__,
1290 peer_address.ToString().c_str(), bta_av_handle, mtu);
1291
1292 // Find the peer
1293 BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
1294 if (p_peer == nullptr) {
1295 APPL_TRACE_ERROR(
1296 "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
1297 __func__, bta_av_handle, peer_address.ToString().c_str());
1298 return;
1299 }
1300 p_peer->opened = true;
1301 p_peer->mtu = mtu;
1302
1303 // The first connected peer becomes the active peer
1304 if (active_peer_ == nullptr) {
1305 active_peer_ = p_peer;
1306 }
1307 }
1308
ProcessClose(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)1309 void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle,
1310 const RawAddress& peer_address) {
1311 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x", __func__,
1312 peer_address.ToString().c_str(), bta_av_handle);
1313 btif_av_reset_audio_delay();
1314
1315 // Find the peer
1316 BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
1317 if (p_peer == nullptr) {
1318 APPL_TRACE_ERROR(
1319 "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
1320 __func__, bta_av_handle, peer_address.ToString().c_str());
1321 return;
1322 }
1323 // Reset the active peer
1324 if (active_peer_ == p_peer) {
1325 active_peer_ = nullptr;
1326 }
1327 // Mark the peer closed and clean the peer info
1328 p_peer->Init(codec_priorities_);
1329 }
1330
ProcessStart(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,const uint8_t * p_codec_info,bool * p_no_rtp_header)1331 void BtaAvCo::ProcessStart(tBTA_AV_HNDL bta_av_handle,
1332 const RawAddress& peer_address,
1333 const uint8_t* p_codec_info, bool* p_no_rtp_header) {
1334 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x", __func__,
1335 peer_address.ToString().c_str(), bta_av_handle);
1336
1337 // Find the peer
1338 BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
1339 if (p_peer == nullptr) {
1340 APPL_TRACE_ERROR(
1341 "%s: could not find peer entry for bta_av_handle 0x%x peer %s",
1342 __func__, bta_av_handle, peer_address.ToString().c_str());
1343 return;
1344 }
1345
1346 bool add_rtp_header =
1347 A2DP_UsesRtpHeader(p_peer->ContentProtectActive(), p_codec_info);
1348
1349 APPL_TRACE_DEBUG("%s: bta_av_handle: 0x%x add_rtp_header: %s", __func__,
1350 bta_av_handle, add_rtp_header ? "true" : "false");
1351 *p_no_rtp_header = !add_rtp_header;
1352 }
1353
ProcessStop(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)1354 void BtaAvCo::ProcessStop(tBTA_AV_HNDL bta_av_handle,
1355 const RawAddress& peer_address) {
1356 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x", __func__,
1357 peer_address.ToString().c_str(), bta_av_handle);
1358 // Nothing to do
1359 }
1360
GetNextSourceDataPacket(const uint8_t * p_codec_info,uint32_t * p_timestamp)1361 BT_HDR* BtaAvCo::GetNextSourceDataPacket(const uint8_t* p_codec_info,
1362 uint32_t* p_timestamp) {
1363 BT_HDR* p_buf;
1364
1365 APPL_TRACE_DEBUG("%s: codec: %s", __func__, A2DP_CodecName(p_codec_info));
1366
1367 p_buf = btif_a2dp_source_audio_readbuf();
1368 if (p_buf == nullptr) return nullptr;
1369
1370 /*
1371 * Retrieve the timestamp information from the media packet,
1372 * and set up the packet header.
1373 *
1374 * In media packet, the following information is available:
1375 * p_buf->layer_specific : number of audio frames in the packet
1376 * p_buf->word[0] : timestamp
1377 */
1378 if (!A2DP_GetPacketTimestamp(p_codec_info, (const uint8_t*)(p_buf + 1),
1379 p_timestamp) ||
1380 !A2DP_BuildCodecHeader(p_codec_info, p_buf, p_buf->layer_specific)) {
1381 APPL_TRACE_ERROR("%s: unsupported codec type (%d)", __func__,
1382 A2DP_GetCodecType(p_codec_info));
1383 }
1384
1385 if (ContentProtectEnabled() && (active_peer_ != nullptr) &&
1386 active_peer_->ContentProtectActive()) {
1387 p_buf->len++;
1388 p_buf->offset--;
1389 uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1390 *p = ContentProtectFlag();
1391 }
1392
1393 return p_buf;
1394 }
1395
DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)1396 void BtaAvCo::DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle,
1397 const RawAddress& peer_address) {
1398 APPL_TRACE_ERROR("%s: peer %s dropped audio packet on handle 0x%x", __func__,
1399 peer_address.ToString().c_str(), bta_av_handle);
1400 }
1401
ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t delay)1402 void BtaAvCo::ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle,
1403 const RawAddress& peer_address,
1404 uint16_t delay) {
1405 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle: 0x%x delay:0x%x", __func__,
1406 peer_address.ToString().c_str(), bta_av_handle, delay);
1407
1408 btif_av_set_audio_delay(peer_address, delay);
1409 }
1410
UpdateMtu(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t mtu)1411 void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle,
1412 const RawAddress& peer_address, uint16_t mtu) {
1413 LOG(INFO) << __func__ << ": peer " << peer_address
1414 << " bta_av_handle: " << loghex(bta_av_handle) << " mtu: " << mtu;
1415
1416 // Find the peer
1417 BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address);
1418 if (p_peer == nullptr) {
1419 LOG(ERROR) << __func__ << ": could not find peer entry for bta_av_handle "
1420 << loghex(bta_av_handle) << " peer " << peer_address;
1421 return;
1422 }
1423 p_peer->mtu = mtu;
1424 }
1425
SetActivePeer(const RawAddress & peer_address)1426 bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) {
1427 VLOG(1) << __func__ << ": peer_address=" << peer_address;
1428
1429 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
1430
1431 if (peer_address.IsEmpty()) {
1432 // Reset the active peer;
1433 active_peer_ = nullptr;
1434 memset(codec_config_, 0, sizeof(codec_config_));
1435 return true;
1436 }
1437
1438 // Find the peer
1439 BtaAvCoPeer* p_peer = FindPeer(peer_address);
1440 if (p_peer == nullptr) {
1441 return false;
1442 }
1443
1444 active_peer_ = p_peer;
1445 memcpy(codec_config_, active_peer_->codec_config, AVDT_CODEC_SIZE);
1446 LOG(INFO) << __func__ << ": codec = " << A2DP_CodecInfoString(codec_config_);
1447 // report the selected codec configuration of this new active peer.
1448 ReportSourceCodecState(active_peer_);
1449 return true;
1450 }
1451
GetPeerEncoderParameters(const RawAddress & peer_address,tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params)1452 void BtaAvCo::GetPeerEncoderParameters(
1453 const RawAddress& peer_address,
1454 tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {
1455 uint16_t min_mtu = 0xFFFF;
1456 CHECK(p_peer_params != nullptr) << "Peer address " << peer_address;
1457
1458 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
1459
1460 // Compute the MTU
1461 for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
1462 const BtaAvCoPeer* p_peer = &peers_[i];
1463 if (!p_peer->opened) continue;
1464 if (p_peer->addr != peer_address) continue;
1465 if (p_peer->mtu < min_mtu) min_mtu = p_peer->mtu;
1466 }
1467 p_peer_params->peer_mtu = min_mtu;
1468 p_peer_params->is_peer_edr = btif_av_is_peer_edr(peer_address);
1469 p_peer_params->peer_supports_3mbps =
1470 btif_av_peer_supports_3mbps(peer_address);
1471 APPL_TRACE_DEBUG(
1472 "%s: peer_address=%s peer_mtu=%d is_peer_edr=%s peer_supports_3mbps=%s",
1473 __func__, peer_address.ToString().c_str(), p_peer_params->peer_mtu,
1474 logbool(p_peer_params->is_peer_edr).c_str(),
1475 logbool(p_peer_params->peer_supports_3mbps).c_str());
1476 }
1477
GetSourceEncoderInterface()1478 const tA2DP_ENCODER_INTERFACE* BtaAvCo::GetSourceEncoderInterface() {
1479 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
1480
1481 return A2DP_GetEncoderInterface(codec_config_);
1482 }
1483
GetSinkDecoderInterface()1484 const tA2DP_DECODER_INTERFACE* BtaAvCo::GetSinkDecoderInterface() {
1485 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
1486
1487 return A2DP_GetDecoderInterface(codec_config_);
1488 }
1489
SetCodecUserConfig(const RawAddress & peer_address,const btav_a2dp_codec_config_t & codec_user_config,bool * p_restart_output)1490 bool BtaAvCo::SetCodecUserConfig(
1491 const RawAddress& peer_address,
1492 const btav_a2dp_codec_config_t& codec_user_config, bool* p_restart_output) {
1493 uint8_t result_codec_config[AVDT_CODEC_SIZE];
1494 const BtaAvCoSep* p_sink = nullptr;
1495 bool restart_input = false;
1496 bool restart_output = false;
1497 bool config_updated = false;
1498 bool success = true;
1499
1500 VLOG(1) << __func__ << ": peer_address=" << peer_address
1501 << " codec_user_config={" << codec_user_config.ToString() << "}";
1502
1503 *p_restart_output = false;
1504
1505 BtaAvCoPeer* p_peer = FindPeer(peer_address);
1506 if (p_peer == nullptr) {
1507 LOG(ERROR) << __func__ << ": cannot find peer " << peer_address
1508 << " to configure";
1509 success = false;
1510 goto done;
1511 }
1512
1513 // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
1514 if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
1515 (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
1516 LOG(WARNING) << __func__ << ": peer " << p_peer->addr
1517 << " : not all peer's capabilities have been retrieved";
1518 success = false;
1519 goto done;
1520 }
1521
1522 // Find the peer SEP codec to use
1523 if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) {
1524 p_sink = FindPeerSink(p_peer, codec_user_config.codec_type);
1525 } else {
1526 // Use the current sink codec
1527 p_sink = p_peer->p_sink;
1528 }
1529 if (p_sink == nullptr) {
1530 LOG(ERROR) << __func__ << ": peer " << p_peer->addr
1531 << " : cannot find peer SEP to configure for codec type "
1532 << codec_user_config.codec_type;
1533 success = false;
1534 goto done;
1535 }
1536
1537 tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1538 GetPeerEncoderParameters(p_peer->addr, &peer_params);
1539 if (!p_peer->GetCodecs()->setCodecUserConfig(
1540 codec_user_config, &peer_params, p_sink->codec_caps,
1541 result_codec_config, &restart_input, &restart_output,
1542 &config_updated)) {
1543 success = false;
1544 goto done;
1545 }
1546
1547 if (restart_output) {
1548 uint8_t num_protect = 0;
1549 if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
1550 num_protect = AVDT_CP_INFO_LEN;
1551 }
1552
1553 p_sink = SelectSourceCodec(p_peer);
1554 if (p_sink == nullptr) {
1555 LOG(ERROR) << __func__ << ": peer " << p_peer->addr
1556 << " : cannot set up codec for the peer SINK";
1557 success = false;
1558 goto done;
1559 }
1560
1561 p_peer->acceptor = false;
1562 VLOG(1) << __func__ << ": call BTA_AvReconfig("
1563 << loghex(p_peer->BtaAvHandle()) << ")";
1564 BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx,
1565 p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
1566 *p_restart_output = true;
1567 }
1568
1569 done:
1570 // We send the upcall if there is no change or the user config failed for
1571 // current active peer, so the caller would know it failed. If there is no
1572 // error, the new selected codec configuration would be sent after we are
1573 // ready to start a new session with the audio HAL.
1574 // For none active peer, we unconditionally send the upcall, so the caller
1575 // would always know the result.
1576 // NOTE: Currently, the input is restarted by sending an upcall
1577 // and informing the Media Framework about the change.
1578 if (p_peer != nullptr &&
1579 (!restart_output || !success || p_peer != active_peer_)) {
1580 return ReportSourceCodecState(p_peer);
1581 }
1582
1583 return success;
1584 }
1585
SetCodecAudioConfig(const btav_a2dp_codec_config_t & codec_audio_config)1586 bool BtaAvCo::SetCodecAudioConfig(
1587 const btav_a2dp_codec_config_t& codec_audio_config) {
1588 uint8_t result_codec_config[AVDT_CODEC_SIZE];
1589 bool restart_output = false;
1590 bool config_updated = false;
1591
1592 VLOG(1) << __func__
1593 << ": codec_audio_config: " << codec_audio_config.ToString();
1594
1595 // Find the peer that is currently open
1596 BtaAvCoPeer* p_peer = active_peer_;
1597 if (p_peer == nullptr) {
1598 LOG(ERROR) << __func__ << ": no active peer to configure";
1599 return false;
1600 }
1601
1602 // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
1603 if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
1604 (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
1605 LOG(WARNING) << __func__ << ": peer " << p_peer->addr
1606 << " : not all peer's capabilities have been retrieved";
1607 return false;
1608 }
1609
1610 // Use the current sink codec
1611 const BtaAvCoSep* p_sink = p_peer->p_sink;
1612 if (p_sink == nullptr) {
1613 LOG(ERROR) << __func__ << ": peer " << p_peer->addr
1614 << " : cannot find peer SEP to configure";
1615 return false;
1616 }
1617
1618 tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
1619 GetPeerEncoderParameters(p_peer->addr, &peer_params);
1620 if (!p_peer->GetCodecs()->setCodecAudioConfig(
1621 codec_audio_config, &peer_params, p_sink->codec_caps,
1622 result_codec_config, &restart_output, &config_updated)) {
1623 return false;
1624 }
1625
1626 if (restart_output) {
1627 uint8_t num_protect = 0;
1628 if (ContentProtectEnabled() && p_peer->ContentProtectActive()) {
1629 num_protect = AVDT_CP_INFO_LEN;
1630 }
1631
1632 SaveNewCodecConfig(p_peer, result_codec_config, p_sink->num_protect,
1633 p_sink->protect_info);
1634
1635 p_peer->acceptor = false;
1636 VLOG(1) << __func__ << ": call BTA_AvReconfig("
1637 << loghex(p_peer->BtaAvHandle()) << ")";
1638 BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx,
1639 p_peer->codec_config, num_protect, bta_av_co_cp_scmst);
1640 }
1641
1642 if (config_updated) {
1643 // NOTE: Currently, the input is restarted by sending an upcall
1644 // and informing the Media Framework about the change of selected codec.
1645 return ReportSourceCodecState(p_peer);
1646 }
1647
1648 return true;
1649 }
1650
ReportSourceCodecState(BtaAvCoPeer * p_peer)1651 bool BtaAvCo::ReportSourceCodecState(BtaAvCoPeer* p_peer) {
1652 btav_a2dp_codec_config_t codec_config;
1653 std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities;
1654 std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities;
1655
1656 VLOG(1) << __func__ << ": peer_address=" << p_peer->addr;
1657 A2dpCodecs* codecs = p_peer->GetCodecs();
1658 CHECK(codecs != nullptr);
1659 if (!codecs->getCodecConfigAndCapabilities(&codec_config,
1660 &codecs_local_capabilities,
1661 &codecs_selectable_capabilities)) {
1662 LOG(WARNING) << __func__ << ": Peer " << p_peer->addr
1663 << " : error reporting audio source codec state: cannot get "
1664 "codec config and capabilities";
1665 return false;
1666 }
1667 LOG(INFO) << __func__ << ": peer " << p_peer->addr << " codec_config={"
1668 << codec_config.ToString() << "}";
1669 btif_av_report_source_codec_state(p_peer->addr, codec_config,
1670 codecs_local_capabilities,
1671 codecs_selectable_capabilities);
1672 return true;
1673 }
1674
ReportSinkCodecState(BtaAvCoPeer * p_peer)1675 bool BtaAvCo::ReportSinkCodecState(BtaAvCoPeer* p_peer) {
1676 APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
1677 p_peer->addr.ToString().c_str());
1678 // Nothing to do (for now)
1679 return true;
1680 }
1681
DebugDump(int fd)1682 void BtaAvCo::DebugDump(int fd) {
1683 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
1684
1685 //
1686 // Active peer codec-specific stats
1687 //
1688 if (active_peer_ != nullptr) {
1689 A2dpCodecs* a2dp_codecs = active_peer_->GetCodecs();
1690 if (a2dp_codecs != nullptr) {
1691 a2dp_codecs->debug_codec_dump(fd);
1692 }
1693 }
1694
1695 if (appl_trace_level < BT_TRACE_LEVEL_DEBUG) return;
1696
1697 dprintf(fd, "\nA2DP Peers State:\n");
1698 dprintf(fd, " Active peer: %s\n",
1699 (active_peer_ != nullptr) ? active_peer_->addr.ToString().c_str()
1700 : "null");
1701
1702 for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) {
1703 const BtaAvCoPeer& peer = peers_[i];
1704 if (peer.addr.IsEmpty()) {
1705 continue;
1706 }
1707 dprintf(fd, " Peer: %s\n", peer.addr.ToString().c_str());
1708 dprintf(fd, " Number of sinks: %u\n", peer.num_sinks);
1709 dprintf(fd, " Number of sources: %u\n", peer.num_sources);
1710 dprintf(fd, " Number of SEPs: %u\n", peer.num_seps);
1711 dprintf(fd, " Number of received sinks: %u\n", peer.num_rx_sinks);
1712 dprintf(fd, " Number of received sources: %u\n", peer.num_rx_sources);
1713 dprintf(fd, " Number of supported sinks: %u\n", peer.num_sup_sinks);
1714 dprintf(fd, " Number of supported sources: %u\n", peer.num_sup_sources);
1715 dprintf(fd, " Acceptor: %s\n", (peer.acceptor) ? "true" : "false");
1716 dprintf(fd, " Reconfig needed: %s\n",
1717 (peer.reconfig_needed) ? "true" : "false");
1718 dprintf(fd, " Opened: %s\n", (peer.opened) ? "true" : "false");
1719 dprintf(fd, " MTU: %u\n", peer.mtu);
1720 dprintf(fd, " UUID to connect: 0x%x\n", peer.uuid_to_connect);
1721 dprintf(fd, " BTA AV handle: %u\n", peer.BtaAvHandle());
1722 }
1723 }
1724
ContentProtectIsScmst(const uint8_t * p_protect_info)1725 bool BtaAvCo::ContentProtectIsScmst(const uint8_t* p_protect_info) {
1726 APPL_TRACE_DEBUG("%s", __func__);
1727
1728 if (*p_protect_info >= AVDT_CP_LOSC) {
1729 uint16_t cp_id;
1730 p_protect_info++;
1731 STREAM_TO_UINT16(cp_id, p_protect_info);
1732 if (cp_id == AVDT_CP_SCMS_T_ID) {
1733 APPL_TRACE_DEBUG("%s: SCMS-T found", __func__);
1734 return true;
1735 }
1736 }
1737 return false;
1738 }
1739
AudioProtectHasScmst(uint8_t num_protect,const uint8_t * p_protect_info)1740 bool BtaAvCo::AudioProtectHasScmst(uint8_t num_protect,
1741 const uint8_t* p_protect_info) {
1742 APPL_TRACE_DEBUG("%s", __func__);
1743 while (num_protect--) {
1744 if (BtaAvCo::ContentProtectIsScmst(p_protect_info)) return true;
1745 // Move to the next Content Protect schema
1746 p_protect_info += *p_protect_info + 1;
1747 }
1748 APPL_TRACE_DEBUG("%s: SCMS-T not found", __func__);
1749 return false;
1750 }
1751
AudioSepHasContentProtection(const BtaAvCoSep * p_sep)1752 bool BtaAvCo::AudioSepHasContentProtection(const BtaAvCoSep* p_sep) {
1753 APPL_TRACE_DEBUG("%s", __func__);
1754
1755 // Check if content protection is enabled for this stream
1756 if (ContentProtectFlag() != AVDT_CP_SCMS_COPY_FREE) {
1757 return BtaAvCo::AudioProtectHasScmst(p_sep->num_protect,
1758 p_sep->protect_info);
1759 }
1760
1761 APPL_TRACE_DEBUG("%s: not required", __func__);
1762 return true;
1763 }
1764
SelectSourceCodec(BtaAvCoPeer * p_peer)1765 const BtaAvCoSep* BtaAvCo::SelectSourceCodec(BtaAvCoPeer* p_peer) {
1766 const BtaAvCoSep* p_sink = nullptr;
1767
1768 // Update all selectable codecs.
1769 // This is needed to update the selectable parameters for each codec.
1770 // NOTE: The selectable codec info is used only for informational purpose.
1771 UpdateAllSelectableSourceCodecs(p_peer);
1772
1773 // Select the codec
1774 for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) {
1775 VLOG(1) << __func__ << ": trying codec " << iter->name();
1776 p_sink = AttemptSourceCodecSelection(*iter, p_peer);
1777 if (p_sink != nullptr) {
1778 VLOG(1) << __func__ << ": selected codec " << iter->name();
1779 break;
1780 }
1781 VLOG(1) << __func__ << ": cannot use codec " << iter->name();
1782 }
1783 return p_sink;
1784 }
1785
SelectSinkCodec(BtaAvCoPeer * p_peer)1786 const BtaAvCoSep* BtaAvCo::SelectSinkCodec(BtaAvCoPeer* p_peer) {
1787 const BtaAvCoSep* p_source = nullptr;
1788
1789 // Update all selectable codecs.
1790 // This is needed to update the selectable parameters for each codec.
1791 // NOTE: The selectable codec info is used only for informational purpose.
1792 UpdateAllSelectableSinkCodecs(p_peer);
1793
1794 // Select the codec
1795 for (const auto& iter : p_peer->GetCodecs()->orderedSinkCodecs()) {
1796 APPL_TRACE_DEBUG("%s: trying codec %s", __func__, iter->name().c_str());
1797 p_source = AttemptSinkCodecSelection(*iter, p_peer);
1798 if (p_source != nullptr) {
1799 APPL_TRACE_DEBUG("%s: selected codec %s", __func__, iter->name().c_str());
1800 break;
1801 }
1802 APPL_TRACE_DEBUG("%s: cannot use codec %s", __func__, iter->name().c_str());
1803 }
1804
1805 // NOTE: Unconditionally dispatch the event to make sure a callback with
1806 // the most recent codec info is generated.
1807 ReportSinkCodecState(p_peer);
1808
1809 return p_source;
1810 }
1811
FindPeerSink(BtaAvCoPeer * p_peer,btav_a2dp_codec_index_t codec_index)1812 BtaAvCoSep* BtaAvCo::FindPeerSink(BtaAvCoPeer* p_peer,
1813 btav_a2dp_codec_index_t codec_index) {
1814 if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
1815 APPL_TRACE_WARNING("%s: invalid codec index for peer %s", __func__,
1816 p_peer->addr.ToString().c_str());
1817 return nullptr;
1818 }
1819
1820 // Find the peer Sink for the codec
1821 for (size_t index = 0; index < p_peer->num_sup_sinks; index++) {
1822 BtaAvCoSep* p_sink = &p_peer->sinks[index];
1823 btav_a2dp_codec_index_t peer_codec_index =
1824 A2DP_SourceCodecIndex(p_sink->codec_caps);
1825 if (peer_codec_index != codec_index) {
1826 continue;
1827 }
1828 if (!AudioSepHasContentProtection(p_sink)) {
1829 APPL_TRACE_DEBUG(
1830 "%s: peer Sink for codec %s does not support "
1831 "Content Protection",
1832 __func__, A2DP_CodecIndexStr(codec_index));
1833 continue;
1834 }
1835 return p_sink;
1836 }
1837 return nullptr;
1838 }
1839
FindPeerSource(BtaAvCoPeer * p_peer,btav_a2dp_codec_index_t codec_index)1840 BtaAvCoSep* BtaAvCo::FindPeerSource(BtaAvCoPeer* p_peer,
1841 btav_a2dp_codec_index_t codec_index) {
1842 if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
1843 APPL_TRACE_WARNING("%s: invalid codec index for peer %s", __func__,
1844 p_peer->addr.ToString().c_str());
1845 return nullptr;
1846 }
1847
1848 // Find the peer Source for the codec
1849 for (size_t index = 0; index < p_peer->num_sup_sources; index++) {
1850 BtaAvCoSep* p_source = &p_peer->sources[index];
1851 btav_a2dp_codec_index_t peer_codec_index =
1852 A2DP_SinkCodecIndex(p_source->codec_caps);
1853 if (peer_codec_index != codec_index) {
1854 continue;
1855 }
1856 if (!AudioSepHasContentProtection(p_source)) {
1857 APPL_TRACE_DEBUG(
1858 "%s: peer Source for codec %s does not support "
1859 "Content Protection",
1860 __func__, A2DP_CodecIndexStr(codec_index));
1861 continue;
1862 }
1863 return p_source;
1864 }
1865 return nullptr;
1866 }
1867
AttemptSourceCodecSelection(const A2dpCodecConfig & codec_config,BtaAvCoPeer * p_peer)1868 const BtaAvCoSep* BtaAvCo::AttemptSourceCodecSelection(
1869 const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) {
1870 uint8_t new_codec_config[AVDT_CODEC_SIZE];
1871
1872 APPL_TRACE_DEBUG("%s", __func__);
1873
1874 // Find the peer Sink for the codec
1875 BtaAvCoSep* p_sink = FindPeerSink(p_peer, codec_config.codecIndex());
1876 if (p_sink == nullptr) {
1877 APPL_TRACE_DEBUG("%s: peer Sink for codec %s not found", __func__,
1878 codec_config.name().c_str());
1879 return nullptr;
1880 }
1881 if (!p_peer->GetCodecs()->setCodecConfig(
1882 p_sink->codec_caps, true /* is_capability */, new_codec_config,
1883 true /* select_current_codec */)) {
1884 APPL_TRACE_DEBUG("%s: cannot set source codec %s", __func__,
1885 codec_config.name().c_str());
1886 return nullptr;
1887 }
1888 p_peer->p_sink = p_sink;
1889
1890 SaveNewCodecConfig(p_peer, new_codec_config, p_sink->num_protect,
1891 p_sink->protect_info);
1892
1893 return p_sink;
1894 }
1895
AttemptSinkCodecSelection(const A2dpCodecConfig & codec_config,BtaAvCoPeer * p_peer)1896 const BtaAvCoSep* BtaAvCo::AttemptSinkCodecSelection(
1897 const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) {
1898 uint8_t new_codec_config[AVDT_CODEC_SIZE];
1899
1900 APPL_TRACE_DEBUG("%s", __func__);
1901
1902 // Find the peer Source for the codec
1903 BtaAvCoSep* p_source = FindPeerSource(p_peer, codec_config.codecIndex());
1904 if (p_source == nullptr) {
1905 APPL_TRACE_DEBUG("%s: peer Source for codec %s not found", __func__,
1906 codec_config.name().c_str());
1907 return nullptr;
1908 }
1909 if (!p_peer->GetCodecs()->setSinkCodecConfig(
1910 p_source->codec_caps, true /* is_capability */, new_codec_config,
1911 true /* select_current_codec */)) {
1912 APPL_TRACE_DEBUG("%s: cannot set sink codec %s", __func__,
1913 codec_config.name().c_str());
1914 return nullptr;
1915 }
1916 p_peer->p_source = p_source;
1917
1918 SaveNewCodecConfig(p_peer, new_codec_config, p_source->num_protect,
1919 p_source->protect_info);
1920
1921 return p_source;
1922 }
1923
UpdateAllSelectableSourceCodecs(BtaAvCoPeer * p_peer)1924 size_t BtaAvCo::UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer) {
1925 APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
1926
1927 size_t updated_codecs = 0;
1928 for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) {
1929 APPL_TRACE_DEBUG("%s: updating selectable codec %s", __func__,
1930 iter->name().c_str());
1931 if (UpdateSelectableSourceCodec(*iter, p_peer)) {
1932 updated_codecs++;
1933 }
1934 }
1935 return updated_codecs;
1936 }
1937
UpdateSelectableSourceCodec(const A2dpCodecConfig & codec_config,BtaAvCoPeer * p_peer)1938 bool BtaAvCo::UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config,
1939 BtaAvCoPeer* p_peer) {
1940 APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
1941
1942 // Find the peer Sink for the codec
1943 const BtaAvCoSep* p_sink = FindPeerSink(p_peer, codec_config.codecIndex());
1944 if (p_sink == nullptr) {
1945 // The peer Sink device does not support this codec
1946 return false;
1947 }
1948 if (!p_peer->GetCodecs()->setPeerSinkCodecCapabilities(p_sink->codec_caps)) {
1949 APPL_TRACE_WARNING("%s: cannot update peer %s codec capabilities for %s",
1950 __func__, p_peer->addr.ToString().c_str(),
1951 A2DP_CodecName(p_sink->codec_caps));
1952 return false;
1953 }
1954 return true;
1955 }
1956
UpdateAllSelectableSinkCodecs(BtaAvCoPeer * p_peer)1957 size_t BtaAvCo::UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer) {
1958 APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
1959
1960 size_t updated_codecs = 0;
1961 for (const auto& iter : p_peer->GetCodecs()->orderedSinkCodecs()) {
1962 APPL_TRACE_DEBUG("%s: updating selectable codec %s", __func__,
1963 iter->name().c_str());
1964 if (UpdateSelectableSinkCodec(*iter, p_peer)) {
1965 updated_codecs++;
1966 }
1967 }
1968 return updated_codecs;
1969 }
1970
UpdateSelectableSinkCodec(const A2dpCodecConfig & codec_config,BtaAvCoPeer * p_peer)1971 bool BtaAvCo::UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config,
1972 BtaAvCoPeer* p_peer) {
1973 APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
1974
1975 // Find the peer Source for the codec
1976 const BtaAvCoSep* p_source =
1977 FindPeerSource(p_peer, codec_config.codecIndex());
1978 if (p_source == nullptr) {
1979 // The peer Source device does not support this codec
1980 return false;
1981 }
1982 if (!p_peer->GetCodecs()->setPeerSourceCodecCapabilities(
1983 p_source->codec_caps)) {
1984 APPL_TRACE_WARNING("%s: cannot update peer %s codec capabilities for %s",
1985 __func__, p_peer->addr.ToString().c_str(),
1986 A2DP_CodecName(p_source->codec_caps));
1987 return false;
1988 }
1989 return true;
1990 }
1991
SaveNewCodecConfig(BtaAvCoPeer * p_peer,const uint8_t * new_codec_config,uint8_t num_protect,const uint8_t * p_protect_info)1992 void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer,
1993 const uint8_t* new_codec_config,
1994 uint8_t num_protect,
1995 const uint8_t* p_protect_info) {
1996 APPL_TRACE_DEBUG("%s: peer %s", __func__, p_peer->addr.ToString().c_str());
1997 APPL_TRACE_DEBUG("%s: codec: %s", __func__,
1998 A2DP_CodecInfoString(new_codec_config).c_str());
1999
2000 std::lock_guard<std::recursive_mutex> lock(codec_lock_);
2001
2002 memcpy(codec_config_, new_codec_config, sizeof(codec_config_));
2003 memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE);
2004
2005 if (ContentProtectEnabled()) {
2006 // Check if this Sink supports SCMS
2007 bool cp_active = BtaAvCo::AudioProtectHasScmst(num_protect, p_protect_info);
2008 p_peer->SetContentProtectActive(cp_active);
2009 }
2010 }
2011
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)2012 bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer,
2013 const uint8_t* p_ota_codec_config,
2014 uint8_t num_protect,
2015 const uint8_t* p_protect_info,
2016 bool* p_restart_output) {
2017 uint8_t result_codec_config[AVDT_CODEC_SIZE];
2018 bool restart_input = false;
2019 bool restart_output = false;
2020 bool config_updated = false;
2021
2022 LOG(INFO) << __func__ << ": peer_address=" << p_peer->addr
2023 << ", codec: " << A2DP_CodecInfoString(p_ota_codec_config);
2024
2025 *p_restart_output = false;
2026
2027 // Find the peer SEP codec to use
2028 const BtaAvCoSep* p_sink =
2029 FindPeerSink(p_peer, A2DP_SourceCodecIndex(p_ota_codec_config));
2030 if ((p_peer->num_sup_sinks > 0) && (p_sink == nullptr)) {
2031 // There are no peer SEPs if we didn't do the discovery procedure yet.
2032 // We have all the information we need from the peer, so we can
2033 // proceed with the OTA codec configuration.
2034 LOG(ERROR) << __func__ << ": peer " << p_peer->addr
2035 << " : cannot find peer SEP to configure";
2036 return false;
2037 }
2038
2039 tA2DP_ENCODER_INIT_PEER_PARAMS peer_params;
2040 GetPeerEncoderParameters(p_peer->addr, &peer_params);
2041 if (!p_peer->GetCodecs()->setCodecOtaConfig(
2042 p_ota_codec_config, &peer_params, result_codec_config, &restart_input,
2043 &restart_output, &config_updated)) {
2044 LOG(ERROR) << __func__ << ": peer " << p_peer->addr
2045 << " : cannot set OTA config";
2046 return false;
2047 }
2048
2049 if (restart_output) {
2050 VLOG(1) << __func__ << ": restart output for codec: "
2051 << A2DP_CodecInfoString(result_codec_config);
2052
2053 *p_restart_output = true;
2054 p_peer->p_sink = p_sink;
2055 SaveNewCodecConfig(p_peer, result_codec_config, num_protect,
2056 p_protect_info);
2057 }
2058
2059 if (restart_input || config_updated) {
2060 // NOTE: Currently, the input is restarted by sending an upcall
2061 // and informing the Media Framework about the change of selected codec.
2062 ReportSourceCodecState(p_peer);
2063 }
2064
2065 return true;
2066 }
2067
bta_av_co_init(const std::vector<btav_a2dp_codec_config_t> & codec_priorities)2068 void bta_av_co_init(
2069 const std::vector<btav_a2dp_codec_config_t>& codec_priorities) {
2070 bta_av_co_cb.Init(codec_priorities);
2071 }
2072
bta_av_co_is_supported_codec(btav_a2dp_codec_index_t codec_index)2073 bool bta_av_co_is_supported_codec(btav_a2dp_codec_index_t codec_index) {
2074 return bta_av_co_cb.IsSupportedCodec(codec_index);
2075 }
2076
bta_av_get_a2dp_current_codec(void)2077 A2dpCodecConfig* bta_av_get_a2dp_current_codec(void) {
2078 return bta_av_co_cb.GetActivePeerCurrentCodec();
2079 }
2080
bta_av_get_a2dp_peer_current_codec(const RawAddress & peer_address)2081 A2dpCodecConfig* bta_av_get_a2dp_peer_current_codec(
2082 const RawAddress& peer_address) {
2083 return bta_av_co_cb.GetPeerCurrentCodec(peer_address);
2084 }
2085
bta_av_co_audio_init(btav_a2dp_codec_index_t codec_index,AvdtpSepConfig * p_cfg)2086 bool bta_av_co_audio_init(btav_a2dp_codec_index_t codec_index,
2087 AvdtpSepConfig* p_cfg) {
2088 return A2DP_InitCodecConfig(codec_index, p_cfg);
2089 }
2090
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)2091 void bta_av_co_audio_disc_res(tBTA_AV_HNDL bta_av_handle,
2092 const RawAddress& peer_address, uint8_t num_seps,
2093 uint8_t num_sinks, uint8_t num_sources,
2094 uint16_t uuid_local) {
2095 bta_av_co_cb.ProcessDiscoveryResult(bta_av_handle, peer_address, num_seps,
2096 num_sinks, num_sources, uuid_local);
2097 }
2098
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)2099 tA2DP_STATUS bta_av_co_audio_getconfig(tBTA_AV_HNDL bta_av_handle,
2100 const RawAddress& peer_address,
2101 uint8_t* p_codec_info,
2102 uint8_t* p_sep_info_idx, uint8_t seid,
2103 uint8_t* p_num_protect,
2104 uint8_t* p_protect_info) {
2105 uint16_t peer_uuid = bta_av_co_cb.FindPeerUuid(bta_av_handle);
2106
2107 APPL_TRACE_DEBUG("%s: peer %s bta_av_handle=0x%x peer_uuid=0x%x", __func__,
2108 peer_address.ToString().c_str(), bta_av_handle, peer_uuid);
2109
2110 switch (peer_uuid) {
2111 case UUID_SERVCLASS_AUDIO_SOURCE:
2112 return bta_av_co_cb.ProcessSinkGetConfig(
2113 bta_av_handle, peer_address, p_codec_info, p_sep_info_idx, seid,
2114 p_num_protect, p_protect_info);
2115 case UUID_SERVCLASS_AUDIO_SINK:
2116 return bta_av_co_cb.ProcessSourceGetConfig(
2117 bta_av_handle, peer_address, p_codec_info, p_sep_info_idx, seid,
2118 p_num_protect, p_protect_info);
2119 default:
2120 break;
2121 }
2122 APPL_TRACE_ERROR(
2123 "%s: peer %s : Invalid peer UUID: 0x%x for bta_av_handle 0x%x",
2124 peer_address.ToString().c_str(), peer_uuid, bta_av_handle);
2125 return A2DP_FAIL;
2126 }
2127
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)2128 void bta_av_co_audio_setconfig(tBTA_AV_HNDL bta_av_handle,
2129 const RawAddress& peer_address,
2130 const uint8_t* p_codec_info, uint8_t seid,
2131 uint8_t num_protect,
2132 const uint8_t* p_protect_info,
2133 uint8_t t_local_sep, uint8_t avdt_handle) {
2134 bta_av_co_cb.ProcessSetConfig(bta_av_handle, peer_address, p_codec_info, seid,
2135 num_protect, p_protect_info, t_local_sep,
2136 avdt_handle);
2137 }
2138
bta_av_co_audio_open(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t mtu)2139 void bta_av_co_audio_open(tBTA_AV_HNDL bta_av_handle,
2140 const RawAddress& peer_address, uint16_t mtu) {
2141 bta_av_co_cb.ProcessOpen(bta_av_handle, peer_address, mtu);
2142 }
2143
bta_av_co_audio_close(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)2144 void bta_av_co_audio_close(tBTA_AV_HNDL bta_av_handle,
2145 const RawAddress& peer_address) {
2146 bta_av_co_cb.ProcessClose(bta_av_handle, peer_address);
2147 }
2148
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)2149 void bta_av_co_audio_start(tBTA_AV_HNDL bta_av_handle,
2150 const RawAddress& peer_address,
2151 const uint8_t* p_codec_info, bool* p_no_rtp_header) {
2152 bta_av_co_cb.ProcessStart(bta_av_handle, peer_address, p_codec_info,
2153 p_no_rtp_header);
2154 }
2155
bta_av_co_audio_stop(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)2156 void bta_av_co_audio_stop(tBTA_AV_HNDL bta_av_handle,
2157 const RawAddress& peer_address) {
2158 bta_av_co_cb.ProcessStop(bta_av_handle, peer_address);
2159 }
2160
bta_av_co_audio_source_data_path(const uint8_t * p_codec_info,uint32_t * p_timestamp)2161 BT_HDR* bta_av_co_audio_source_data_path(const uint8_t* p_codec_info,
2162 uint32_t* p_timestamp) {
2163 return bta_av_co_cb.GetNextSourceDataPacket(p_codec_info, p_timestamp);
2164 }
2165
bta_av_co_audio_drop(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address)2166 void bta_av_co_audio_drop(tBTA_AV_HNDL bta_av_handle,
2167 const RawAddress& peer_address) {
2168 bta_av_co_cb.DataPacketWasDropped(bta_av_handle, peer_address);
2169 }
2170
bta_av_co_audio_delay(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t delay)2171 void bta_av_co_audio_delay(tBTA_AV_HNDL bta_av_handle,
2172 const RawAddress& peer_address, uint16_t delay) {
2173 bta_av_co_cb.ProcessAudioDelay(bta_av_handle, peer_address, delay);
2174 }
2175
bta_av_co_audio_update_mtu(tBTA_AV_HNDL bta_av_handle,const RawAddress & peer_address,uint16_t mtu)2176 void bta_av_co_audio_update_mtu(tBTA_AV_HNDL bta_av_handle,
2177 const RawAddress& peer_address, uint16_t mtu) {
2178 bta_av_co_cb.UpdateMtu(bta_av_handle, peer_address, mtu);
2179 }
2180
bta_av_co_set_active_peer(const RawAddress & peer_address)2181 bool bta_av_co_set_active_peer(const RawAddress& peer_address) {
2182 return bta_av_co_cb.SetActivePeer(peer_address);
2183 }
2184
bta_av_co_get_peer_params(const RawAddress & peer_address,tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params)2185 void bta_av_co_get_peer_params(const RawAddress& peer_address,
2186 tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {
2187 bta_av_co_cb.GetPeerEncoderParameters(peer_address, p_peer_params);
2188 }
2189
bta_av_co_get_encoder_interface(void)2190 const tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface(void) {
2191 return bta_av_co_cb.GetSourceEncoderInterface();
2192 }
2193
bta_av_co_get_decoder_interface(void)2194 const tA2DP_DECODER_INTERFACE* bta_av_co_get_decoder_interface(void) {
2195 return bta_av_co_cb.GetSinkDecoderInterface();
2196 }
2197
bta_av_co_set_codec_user_config(const RawAddress & peer_address,const btav_a2dp_codec_config_t & codec_user_config,bool * p_restart_output)2198 bool bta_av_co_set_codec_user_config(
2199 const RawAddress& peer_address,
2200 const btav_a2dp_codec_config_t& codec_user_config, bool* p_restart_output) {
2201 return bta_av_co_cb.SetCodecUserConfig(peer_address, codec_user_config,
2202 p_restart_output);
2203 }
2204
bta_av_co_set_codec_audio_config(const btav_a2dp_codec_config_t & codec_audio_config)2205 bool bta_av_co_set_codec_audio_config(
2206 const btav_a2dp_codec_config_t& codec_audio_config) {
2207 return bta_av_co_cb.SetCodecAudioConfig(codec_audio_config);
2208 }
2209
bta_av_co_content_protect_is_active(const RawAddress & peer_address)2210 bool bta_av_co_content_protect_is_active(const RawAddress& peer_address) {
2211 BtaAvCoPeer* p_peer = bta_av_co_cb.FindPeer(peer_address);
2212 CHECK(p_peer != nullptr);
2213 return p_peer->ContentProtectActive();
2214 }
2215
btif_a2dp_codec_debug_dump(int fd)2216 void btif_a2dp_codec_debug_dump(int fd) { bta_av_co_cb.DebugDump(fd); }
2217