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