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