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