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