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