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