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