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