15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2004-2012 Broadcom Corporation 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * This is the advanced audio/video call-out function implementation for 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * BTIF. 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 266bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson#include "bta_av_co.h" 27f2af1c42ccb2f642b241c2261b42d0be61d45438Jack He#include <base/logging.h> 28b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov#include <string.h> 29f66f4e95f2b4bc8d36033f2d65b387e32601fcd8Pavlin Radoslavov#include "a2dp_api.h" 305ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov#include "a2dp_sbc.h" 31a62c5a302e54568a3d2c164a7dbef52f279512f2Pavlin Radoslavov#include "bt_target.h" 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_av_api.h" 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_av_ci.h" 346bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson#include "bta_sys.h" 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 365ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov#include "btif_av.h" 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_av_co.h" 385cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "btif_util.h" 391eb1ea0cf2da992a3193506806e571dcbe3ec947Pavlin Radoslavov#include "osi/include/mutex.h" 40c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov#include "osi/include/osi.h" 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Constants 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *****************************************************************************/ 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Macro to retrieve the number of elements in a statically allocated array */ 476bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson#define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a) / sizeof((__a)[0])) 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Macro to convert audio handle to index and vice versa */ 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl) (((hndl) & (~BTA_AV_CHNL_MSK)) - 1) 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define BTA_AV_CO_AUDIO_INDX_TO_HNDL(indx) (((indx) + 1) | BTA_AV_CHNL_AUDIO) 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* SCMS-T protect info */ 54feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavovconst uint8_t bta_av_co_cp_scmst[AVDT_CP_INFO_LEN] = {0x02, 0x02, 0x00}; 555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 576bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson * Local data 586bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson ****************************************************************************/ 596bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsontypedef struct { 609008888d24407541aa383aa4bd363a40abbf954bMyles Watson uint8_t sep_info_idx; /* local SEP index (in BTA tables) */ 619008888d24407541aa383aa4bd363a40abbf954bMyles Watson uint8_t seid; /* peer SEP index (in peer tables) */ 629008888d24407541aa383aa4bd363a40abbf954bMyles Watson uint8_t codec_caps[AVDT_CODEC_SIZE]; /* peer SEP codec capabilities */ 639008888d24407541aa383aa4bd363a40abbf954bMyles Watson uint8_t num_protect; /* peer SEP number of CP elements */ 64feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov uint8_t protect_info[AVDT_CP_INFO_LEN]; /* peer SEP content protection info */ 655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} tBTA_AV_CO_SINK; 665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 676bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsontypedef struct { 689e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski RawAddress addr; /* address of audio/video peer */ 696bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_SINK 705ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov sinks[BTAV_A2DP_CODEC_INDEX_MAX]; /* array of supported sinks */ 715ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tBTA_AV_CO_SINK srcs[BTAV_A2DP_CODEC_INDEX_MAX]; /* array of supported srcs */ 726bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t num_sinks; /* total number of sinks at peer */ 736bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t num_srcs; /* total number of srcs at peer */ 746bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t num_seps; /* total number of seids at peer */ 756bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t num_rx_sinks; /* number of received sinks */ 766bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t num_rx_srcs; /* number of received srcs */ 776bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t num_sup_sinks; /* number of supported sinks in the sinks array */ 786bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t num_sup_srcs; /* number of supported srcs in the srcs array */ 799008888d24407541aa383aa4bd363a40abbf954bMyles Watson const tBTA_AV_CO_SINK* p_sink; /* currently selected sink */ 809008888d24407541aa383aa4bd363a40abbf954bMyles Watson const tBTA_AV_CO_SINK* p_src; /* currently selected src */ 8182fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov uint8_t codec_config[AVDT_CODEC_SIZE]; /* current codec configuration */ 829008888d24407541aa383aa4bd363a40abbf954bMyles Watson bool cp_active; /* current CP configuration */ 839008888d24407541aa383aa4bd363a40abbf954bMyles Watson bool acp; /* acceptor */ 849008888d24407541aa383aa4bd363a40abbf954bMyles Watson bool reconfig_needed; /* reconfiguration is needed */ 859008888d24407541aa383aa4bd363a40abbf954bMyles Watson bool opened; /* opened */ 869008888d24407541aa383aa4bd363a40abbf954bMyles Watson uint16_t mtu; /* maximum transmit unit size */ 879008888d24407541aa383aa4bd363a40abbf954bMyles Watson uint16_t uuid_to_connect; /* uuid of peer device */ 885ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tBTA_AV_HNDL handle; /* handle to use */ 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} tBTA_AV_CO_PEER; 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 916bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsontypedef struct { 926bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson bool active; 936bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t flag; 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} tBTA_AV_CO_CP; 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 965ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovclass BtaAvCoCb { 975ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov public: 985ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov BtaAvCoCb() : codecs(nullptr) { reset(); } 995ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 1006bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Connected peer information */ 1016bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_PEER peers[BTA_AV_NUM_STRS]; 1026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Current codec configuration - access to this variable must be protected */ 10382fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov uint8_t codec_config[AVDT_CODEC_SIZE]; 1045ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2dpCodecs* codecs; /* Locally supported codecs */ 1056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_CP cp; 1065ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 1075ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov void reset() { 1085ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov delete codecs; 1095ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov codecs = nullptr; 1105ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // TODO: Ugly leftover reset from the original C code. Should go away once 1115ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // the rest of the code in this file migrates to C++. 1125ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov memset(peers, 0, sizeof(peers)); 1135ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov memset(codec_config, 0, sizeof(codec_config)); 1145ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov memset(&cp, 0, sizeof(cp)); 1155ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 1165ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // Initialize the handles 1175ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers); i++) { 1185ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tBTA_AV_CO_PEER* p_peer = &peers[i]; 1195ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer->handle = BTA_AV_CO_AUDIO_INDX_TO_HNDL(i); 1205ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 1215ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 1225ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov}; 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Control block instance */ 1255ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovstatic BtaAvCoCb bta_av_co_cb; 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 127cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic bool bta_av_co_cp_is_scmst(const uint8_t* p_protect_info); 128cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic bool bta_av_co_audio_protect_has_scmst(uint8_t num_protect, 129cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov const uint8_t* p_protect_info); 130c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovstatic const tBTA_AV_CO_SINK* bta_av_co_find_peer_src_supports_codec( 1316bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson const tBTA_AV_CO_PEER* p_peer); 132cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic tBTA_AV_CO_SINK* bta_av_co_audio_set_codec(tBTA_AV_CO_PEER* p_peer); 133cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic tBTA_AV_CO_SINK* bta_av_co_audio_codec_selected( 1345ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2dpCodecConfig& codec_config, tBTA_AV_CO_PEER* p_peer); 135494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavovstatic bool bta_av_co_audio_update_selectable_codec( 136494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov A2dpCodecConfig& codec_config, const tBTA_AV_CO_PEER* p_peer); 137cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic void bta_av_co_save_new_codec_config(tBTA_AV_CO_PEER* p_peer, 138cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov const uint8_t* new_codec_config, 139cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov uint8_t num_protect, 140cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov const uint8_t* p_protect_info); 1415ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovstatic bool bta_av_co_set_codec_ota_config(tBTA_AV_CO_PEER* p_peer, 1425ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const uint8_t* p_ota_codec_config, 1435ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov uint8_t num_protect, 1445ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const uint8_t* p_protect_info, 1455ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool* p_restart_output); 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_cp_get_flag 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description Get content protection flag 152feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov ** AVDT_CP_SCMS_COPY_NEVER 153feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov ** AVDT_CP_SCMS_COPY_ONCE 154feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov ** AVDT_CP_SCMS_COPY_FREE 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns The current flag value 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 158ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1596bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic uint8_t bta_av_co_cp_get_flag(void) { return bta_av_co_cb.cp.flag; } 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_cp_set_flag 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description Set content protection flag 166feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov ** AVDT_CP_SCMS_COPY_NEVER 167feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov ** AVDT_CP_SCMS_COPY_ONCE 168feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov ** AVDT_CP_SCMS_COPY_FREE 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 170b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen ** Returns true if setting the SCMS flag is supported else false 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 172ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1736bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic bool bta_av_co_cp_set_flag(uint8_t cp_flag) { 1746bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: cp_flag = %d", __func__, cp_flag); 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 176b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen#if (BTA_AV_CO_CP_SCMS_T == TRUE) 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else 178feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov if (cp_flag != AVDT_CP_SCMS_COPY_FREE) { 1796bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return false; 1806bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 1826bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson bta_av_co_cb.cp.flag = cp_flag; 1836bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return true; 1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_get_peer 1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description find the peer entry for a given handle 1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns the control block 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 194ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 1956bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic tBTA_AV_CO_PEER* bta_av_co_get_peer(tBTA_AV_HNDL hndl) { 1966bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t index; 1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1986bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson index = BTA_AV_CO_AUDIO_HNDL_TO_INDX(hndl); 1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2006bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: handle = %d index = %d", __func__, hndl, index); 20179506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 2026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Sanity check */ 2036bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (index >= BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers)) { 2046bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: peer index out of bounds: %d", __func__, index); 2056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return NULL; 2066bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2086bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return &bta_av_co_cb.peers[index]; 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_init 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description This callout function is executed by AV when it is 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** started by calling BTA_AvRegister(). This function can be 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** used by the phone to initialize audio paths or for other 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** initialization purposes. 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns Stream codec and content protection capabilities info. 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 223ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 2245ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovbool bta_av_co_audio_init(btav_a2dp_codec_index_t codec_index, 2256bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tAVDT_CFG* p_cfg) { 2265ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return A2DP_InitCodecConfig(codec_index, p_cfg); 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_disc_res 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description This callout function is executed by AV to report the 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** number of stream end points (SEP) were found during the 2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** AVDT stream discovery process. 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns void. 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 240ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 241c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovvoid bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl, uint8_t num_seps, 242903c16685e62e7721d44460b9171e020f38609f5Jakub Pawlowski uint8_t num_sink, uint8_t num_src, 2439e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski const RawAddress& addr, uint16_t uuid_local) { 2446bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_PEER* p_peer; 2456bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 2466bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: h:x%x num_seps:%d num_sink:%d num_src:%d", __func__, 2476bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson hndl, num_seps, num_sink, num_src); 2486bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 2496bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Find the peer info */ 2506bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer = bta_av_co_get_peer(hndl); 2516bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer == NULL) { 2526bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: could not find peer entry", __func__); 2536bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return; 2546bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 2556bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 2566bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Sanity check : this should never happen */ 2576bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer->opened) { 2586bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: peer already opened", __func__); 2596bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 2606bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 2616bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Copy the discovery results */ 262903c16685e62e7721d44460b9171e020f38609f5Jakub Pawlowski p_peer->addr = addr; 2636bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_sinks = num_sink; 2646bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_srcs = num_src; 2656bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_seps = num_seps; 2666bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_rx_sinks = 0; 2676bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_rx_srcs = 0; 2686bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_sup_sinks = 0; 2696bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (uuid_local == UUID_SERVCLASS_AUDIO_SINK) 2706bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SOURCE; 2716bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson else if (uuid_local == UUID_SERVCLASS_AUDIO_SOURCE) 2726bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->uuid_to_connect = UUID_SERVCLASS_AUDIO_SINK; 2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 277cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** Function bta_av_audio_sink_getconfig 278cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** 279cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** Description This callout function is executed by AV to retrieve the 280cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** desired codec and content protection configuration for the 281cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** A2DP Sink audio stream in Initiator. 282cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** 283cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** 284cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** Returns Pass or Fail for current getconfig. 285cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** 286ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 2876bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic tA2DP_STATUS bta_av_audio_sink_getconfig( 2886bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_HNDL hndl, uint8_t* p_codec_info, uint8_t* p_sep_info_idx, 2896bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t seid, uint8_t* p_num_protect, uint8_t* p_protect_info) { 2906bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tA2DP_STATUS result = A2DP_FAIL; 2916bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_PEER* p_peer; 2926bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 2936bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: handle:0x%x codec:%s seid:%d", __func__, hndl, 2946bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson A2DP_CodecName(p_codec_info), seid); 2956bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x", 2966bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson __func__, *p_num_protect, p_protect_info[0], 2976bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_protect_info[1], p_protect_info[2]); 2986bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 2996bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Retrieve the peer info */ 3006bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer = bta_av_co_get_peer(hndl); 3016bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer == NULL) { 3026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: could not find peer entry", __func__); 3036bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return A2DP_FAIL; 3046bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 3056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 3066bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: peer(o=%d,n_sinks=%d,n_rx_sinks=%d,n_sup_sinks=%d)", 3076bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson __func__, p_peer->opened, p_peer->num_srcs, 3086bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_rx_srcs, p_peer->num_sup_srcs); 3096bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 3106bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_rx_srcs++; 3116bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 3126bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Check the peer's SOURCE codec */ 3136bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (A2DP_IsPeerSourceCodecValid(p_codec_info)) { 3146bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* If there is room for a new one */ 3156bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer->num_sup_srcs < BTA_AV_CO_NUM_ELEMENTS(p_peer->srcs)) { 3166bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_SINK* p_src = &p_peer->srcs[p_peer->num_sup_srcs++]; 3176bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 3186bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__, 3196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_codec_info[1], p_codec_info[2], p_codec_info[3], 3206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_codec_info[4], p_codec_info[5], p_codec_info[6]); 3216bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 3226bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson memcpy(p_src->codec_caps, p_codec_info, AVDT_CODEC_SIZE); 3236bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_src->sep_info_idx = *p_sep_info_idx; 3246bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_src->seid = seid; 3256bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_src->num_protect = *p_num_protect; 326feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov memcpy(p_src->protect_info, p_protect_info, AVDT_CP_INFO_LEN); 3276bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } else { 3286bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: no more room for SRC info", __func__); 329cc35559160745c60b42ae182002a59337d844d09Hemant Gupta } 3306bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 331cc35559160745c60b42ae182002a59337d844d09Hemant Gupta 3326bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* If last SINK get capabilities or all supported codec caps retrieved */ 3336bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if ((p_peer->num_rx_srcs == p_peer->num_srcs) || 3346bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson (p_peer->num_sup_srcs == BTA_AV_CO_NUM_ELEMENTS(p_peer->srcs))) { 3356bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: last SRC reached", __func__); 3366bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 33782fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov /* Protect access to bta_av_co_cb.codec_config */ 3386bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson mutex_global_lock(); 3396bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 3406bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Find a src that matches the codec config */ 3416bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson const tBTA_AV_CO_SINK* p_src = 3426bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson bta_av_co_find_peer_src_supports_codec(p_peer); 3436bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_src != NULL) { 3445ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov uint8_t pref_config[AVDT_CODEC_SIZE]; 3456bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: codec supported", __func__); 3466bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 3476bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Build the codec configuration for this sink */ 3485ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov /* Save the new configuration */ 3495ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer->p_src = p_src; 3505ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov /* get preferred config from src_caps */ 3515ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (A2DP_BuildSrc2SinkConfig(p_src->codec_caps, pref_config) != 3525ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2DP_SUCCESS) { 3535ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov mutex_global_unlock(); 3545ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return A2DP_FAIL; 3555ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 3565ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov memcpy(p_peer->codec_config, pref_config, AVDT_CODEC_SIZE); 357cc35559160745c60b42ae182002a59337d844d09Hemant Gupta 3585ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_DEBUG("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__, 3595ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer->codec_config[1], p_peer->codec_config[2], 3605ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer->codec_config[3], p_peer->codec_config[4], 3615ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer->codec_config[5], p_peer->codec_config[6]); 3625ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov /* By default, no content protection */ 3635ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov *p_num_protect = 0; 364cc35559160745c60b42ae182002a59337d844d09Hemant Gupta 365b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen#if (BTA_AV_CO_CP_SCMS_T == TRUE) 3665ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer->cp_active = false; 3675ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_cb.cp.active = false; 368cc35559160745c60b42ae182002a59337d844d09Hemant Gupta#endif 369cc35559160745c60b42ae182002a59337d844d09Hemant Gupta 3705ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov *p_sep_info_idx = p_src->sep_info_idx; 3715ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE); 3725ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov result = A2DP_SUCCESS; 373cc35559160745c60b42ae182002a59337d844d09Hemant Gupta } 37482fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov /* Protect access to bta_av_co_cb.codec_config */ 3756bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson mutex_global_unlock(); 3766bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 3776bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return result; 378cc35559160745c60b42ae182002a59337d844d09Hemant Gupta} 379cc35559160745c60b42ae182002a59337d844d09Hemant Gupta/******************************************************************************* 380cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_getconfig 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description This callout function is executed by AV to retrieve the 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** desired codec and content protection configuration for the 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** audio stream. 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns Stream codec and content protection configuration info. 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 390ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 3916bd442f543972b072ef2cbbcf2f7c91202de1045Myles WatsontA2DP_STATUS bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, uint8_t* p_codec_info, 3926bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t* p_sep_info_idx, uint8_t seid, 3936bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t* p_num_protect, 3946bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t* p_protect_info) { 3956bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_PEER* p_peer; 3966bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 3976bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 398c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov A2DP_DumpCodecInfo(p_codec_info); 3996bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 4006bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Retrieve the peer info */ 4016bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer = bta_av_co_get_peer(hndl); 4026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer == NULL) { 4036bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: could not find peer entry", __func__); 4046bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return A2DP_FAIL; 4056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 4066bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 4076bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer->uuid_to_connect == UUID_SERVCLASS_AUDIO_SOURCE) { 408cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov return bta_av_audio_sink_getconfig(hndl, p_codec_info, p_sep_info_idx, seid, 409cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov p_num_protect, p_protect_info); 4106bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 4116bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: handle:0x%x codec:%s seid:%d", __func__, hndl, 4126bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson A2DP_CodecName(p_codec_info), seid); 4136bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x", 4146bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson __func__, *p_num_protect, p_protect_info[0], 4156bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_protect_info[1], p_protect_info[2]); 4166bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)", 4176bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson __func__, p_peer->opened, p_peer->num_sinks, 4186bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_rx_sinks, p_peer->num_sup_sinks); 4196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 4206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_rx_sinks++; 4216bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 4226bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Check the peer's SINK codec */ 4236bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (A2DP_IsPeerSinkCodecValid(p_codec_info)) { 4246bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* If there is room for a new one */ 4256bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer->num_sup_sinks < BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks)) { 4266bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_SINK* p_sink = &p_peer->sinks[p_peer->num_sup_sinks++]; 4276bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 4286bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__, 4296bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_codec_info[1], p_codec_info[2], p_codec_info[3], 4306bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_codec_info[4], p_codec_info[5], p_codec_info[6]); 4316bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 4326bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE); 4336bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_sink->sep_info_idx = *p_sep_info_idx; 4346bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_sink->seid = seid; 4356bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_sink->num_protect = *p_num_protect; 436feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov memcpy(p_sink->protect_info, p_protect_info, AVDT_CP_INFO_LEN); 4376bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } else { 4386bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: no more room for SINK info", __func__); 4396bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 4406bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 442cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // Check if this is the last SINK get capabilities or all supported codec 443cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // capabilities are retrieved. 444cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if ((p_peer->num_rx_sinks != p_peer->num_sinks) && 445cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) { 446cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov return A2DP_FAIL; 447cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 448cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov APPL_TRACE_DEBUG("%s: last sink reached", __func__); 4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 450cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov const tBTA_AV_CO_SINK* p_sink = bta_av_co_audio_set_codec(p_peer); 451cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (p_sink == NULL) { 4522073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov APPL_TRACE_ERROR("%s: cannot set up codec for the peer SINK", __func__); 453cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov return A2DP_FAIL; 454cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 456cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // By default, no content protection 457cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov *p_num_protect = 0; 458b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen#if (BTA_AV_CO_CP_SCMS_T == TRUE) 459cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (p_peer->cp_active) { 460cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov *p_num_protect = AVDT_CP_INFO_LEN; 461cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov memcpy(p_protect_info, bta_av_co_cp_scmst, AVDT_CP_INFO_LEN); 462cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 465cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // If acceptor -> reconfig otherwise reply for configuration. 466cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (p_peer->acp) { 467cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // Stop fetching caps once we retrieved a supported codec. 468cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov APPL_TRACE_EVENT("%s: no need to fetch more SEPs", __func__); 469cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov *p_sep_info_idx = p_peer->num_seps; 470cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (p_peer->reconfig_needed) { 471cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__, hndl); 472cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov BTA_AvReconfig(hndl, true, p_sink->sep_info_idx, p_peer->codec_config, 473cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov *p_num_protect, bta_av_co_cp_scmst); 4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 475cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } else { 476cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov *p_sep_info_idx = p_sink->sep_info_idx; 477cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE); 4786bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 479cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov 480cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov return A2DP_SUCCESS; 4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_setconfig 4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 4876bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson ** Description This callout function is executed by AV to set the codec 488f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** and content protection configuration of the audio stream. 4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns void 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 493ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 4946bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonvoid bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, const uint8_t* p_codec_info, 495b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavov UNUSED_ATTR uint8_t seid, 4969e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski UNUSED_ATTR const RawAddress& addr, 497903c16685e62e7721d44460b9171e020f38609f5Jakub Pawlowski uint8_t num_protect, 498cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov const uint8_t* p_protect_info, 499cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov uint8_t t_local_sep, uint8_t avdt_handle) { 5006bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_PEER* p_peer; 5016bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tA2DP_STATUS status = A2DP_SUCCESS; 5026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t category = A2DP_SUCCESS; 50382fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov bool reconfig_needed = false; 5046bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 5056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__, 5066bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_codec_info[1], p_codec_info[2], p_codec_info[3], 5076bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_codec_info[4], p_codec_info[5], p_codec_info[6]); 5086bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("num_protect:0x%02x protect_info:0x%02x%02x%02x", 5096bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson num_protect, p_protect_info[0], p_protect_info[1], 5106bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_protect_info[2]); 511c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov A2DP_DumpCodecInfo(p_codec_info); 5126bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 5136bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Retrieve the peer info */ 5146bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer = bta_av_co_get_peer(hndl); 5156bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer == NULL) { 5166bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: could not find peer entry", __func__); 5176bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Call call-in rejecting the configuration */ 5186bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson bta_av_ci_setconfig(hndl, A2DP_BUSY, AVDT_ASC_CODEC, 0, NULL, false, 5196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson avdt_handle); 5206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return; 5216bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 522c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 5236bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)", 5246bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson __func__, p_peer->opened, p_peer->num_sinks, 5256bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_rx_sinks, p_peer->num_sup_sinks); 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5276bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Sanity check: should not be opened at this point */ 5286bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer->opened) { 5296bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: peer already in use", __func__); 5306bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5326bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (num_protect != 0) { 533b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen#if (BTA_AV_CO_CP_SCMS_T == TRUE) 5346bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* If CP is supported */ 5356bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if ((num_protect != 1) || 5366bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson (bta_av_co_cp_is_scmst(p_protect_info) == false)) { 5376bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: wrong CP configuration", __func__); 5386bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson status = A2DP_BAD_CP_TYPE; 5396bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson category = AVDT_ASC_PROTECT; 5406bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else 5426bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Do not support content protection for the time being */ 5436bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: wrong CP configuration", __func__); 5446bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson status = A2DP_BAD_CP_TYPE; 5456bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson category = AVDT_ASC_PROTECT; 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 5476bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 548c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 5496bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (status == A2DP_SUCCESS) { 55082fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov bool codec_config_supported = false; 551cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov 5526bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (t_local_sep == AVDT_TSEP_SNK) { 5536bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: peer is A2DP SRC", __func__); 55482fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov codec_config_supported = A2DP_IsSinkCodecSupported(p_codec_info); 555cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (codec_config_supported) { 556cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // If Peer is SRC, and our config subset matches with what is 557cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // requested by peer, then just accept what peer wants. 5585ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_save_new_codec_config(p_peer, p_codec_info, num_protect, 5595ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_protect_info); 560cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5626bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (t_local_sep == AVDT_TSEP_SRC) { 5636bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: peer is A2DP SINK", __func__); 5645ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool restart_output = false; 5655ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if ((bta_av_co_cb.codecs == nullptr) || 5665ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov !bta_av_co_set_codec_ota_config(p_peer, p_codec_info, num_protect, 5675ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_protect_info, &restart_output)) { 5685ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_DEBUG("%s: cannot set source codec %s", __func__, 569cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov A2DP_CodecName(p_codec_info)); 570cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } else { 571cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov codec_config_supported = true; 572cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // Check if reconfiguration is needed 5735ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (restart_output || 574cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov ((num_protect == 1) && (!bta_av_co_cb.cp.active))) { 575cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov reconfig_needed = true; 576cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 577cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5806bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Check if codec configuration is supported */ 581cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (!codec_config_supported) { 5826bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson category = AVDT_ASC_CODEC; 5836bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson status = A2DP_WRONG_CODEC; 5846bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 5856bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 5866bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 5876bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (status != A2DP_SUCCESS) { 5886bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: reject s=%d c=%d", __func__, status, category); 5896bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Call call-in rejecting the configuration */ 5906bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson bta_av_ci_setconfig(hndl, status, category, 0, NULL, false, avdt_handle); 5916bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return; 5926bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 5936bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 5946bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Mark that this is an acceptor peer */ 5956bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->acp = true; 59682fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov p_peer->reconfig_needed = reconfig_needed; 59782fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov APPL_TRACE_DEBUG("%s: accept reconf=%d", __func__, reconfig_needed); 5986bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Call call-in accepting the configuration */ 59982fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov bta_av_ci_setconfig(hndl, A2DP_SUCCESS, A2DP_SUCCESS, 0, NULL, 60082fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov reconfig_needed, avdt_handle); 6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_open 6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6076bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson ** Description This function is called by AV when the audio stream 608f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** connection is opened. 6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns void 6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 613ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 614cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovvoid bta_av_co_audio_open(tBTA_AV_HNDL hndl, uint16_t mtu) { 6156bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_PEER* p_peer; 6166bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 617cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov APPL_TRACE_DEBUG("%s: handle: %d mtu:%d", __func__, hndl, mtu); 6186bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 6196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Retrieve the peer info */ 6206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer = bta_av_co_get_peer(hndl); 6216bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer == NULL) { 6226bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: could not find peer entry", __func__); 6236bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } else { 6246bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->opened = true; 6256bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->mtu = mtu; 6266bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_close 6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6336bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson ** Description This function is called by AV when the audio stream 634f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** connection is closed. 6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns void 6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 639ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 640cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovvoid bta_av_co_audio_close(tBTA_AV_HNDL hndl) { 6416bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson tBTA_AV_CO_PEER* p_peer; 6426bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 6436bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 6446bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 6456bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Retrieve the peer info */ 6466bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer = bta_av_co_get_peer(hndl); 6476bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer) { 6486bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Mark the peer closed and clean the peer info */ 6496bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson memset(p_peer, 0, sizeof(*p_peer)); 6506bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } else { 6516bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: could not find peer entry", __func__); 6526bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_start 6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description This function is called by AV when the audio streaming data 6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** transfer is started. 6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns void 6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 665ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 666b3e5af36e9e396eafab3001728ecbc1d8d36a339Pavlin Radoslavovvoid bta_av_co_audio_start(UNUSED_ATTR tBTA_AV_HNDL hndl, 6676bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson UNUSED_ATTR uint8_t* p_codec_info, 6686bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson UNUSED_ATTR bool* p_no_rtp_hdr) { 6696bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_stop 6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description This function is called by AV when the audio streaming data 6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** transfer is stopped. 6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns void 6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 682ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 6836bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonvoid bta_av_co_audio_stop(UNUSED_ATTR tBTA_AV_HNDL hndl) { 6846bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_src_data_path 6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description This function is called to manage data transfer from 6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** the audio codec to AVDTP. 6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 6946bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson ** Returns Pointer to the GKI buffer to send, NULL if no buffer to 695f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** send 6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 697ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 6986bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonvoid* bta_av_co_audio_src_data_path(const uint8_t* p_codec_info, 6996bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint32_t* p_timestamp) { 7006bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson BT_HDR* p_buf; 7016bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 7026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: codec: %s", __func__, A2DP_CodecName(p_codec_info)); 7036bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 7046bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_buf = btif_a2dp_source_audio_readbuf(); 7056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_buf == NULL) return NULL; 7066bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 7076bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* 7086bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson * Retrieve the timestamp information from the media packet, 7096bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson * and set up the packet header. 7106bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson * 7116bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson * In media packet, the following information is available: 7126bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson * p_buf->layer_specific : number of audio frames in the packet 7136bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson * p_buf->word[0] : timestamp 7146bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson */ 7156bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (!A2DP_GetPacketTimestamp(p_codec_info, (const uint8_t*)(p_buf + 1), 7166bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_timestamp) || 7176bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson !A2DP_BuildCodecHeader(p_codec_info, p_buf, p_buf->layer_specific)) { 7186bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: unsupported codec type (%d)", __func__, 7196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson A2DP_GetCodecType(p_codec_info)); 7206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 722b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen#if (BTA_AV_CO_CP_SCMS_T == TRUE) 7236bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (bta_av_co_cb.cp.active) { 7246bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_buf->len++; 7256bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_buf->offset--; 7266bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset; 7276bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson *p = bta_av_co_cp_get_flag(); 7286bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 729c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov#endif 730c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 7316bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return p_buf; 7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_drop 7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description An Audio packet is dropped. . 7396bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson ** It's very likely that the connected headset with this 740f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** handle is moved far away. The implementation may want to 741f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** reduce the encoder bit rate setting to reduce the packet 742f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** size. 7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns void 7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 746ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 7476bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonvoid bta_av_co_audio_drop(tBTA_AV_HNDL hndl) { 7486bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: dropped audio packet on handle 0x%x", __func__, hndl); 7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_delay 7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7556bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson ** Description This function is called by AV when the audio stream 756f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** connection needs to send the initial delay report to the 757f45481678af0694902b5200ba69ced4cb61d73f0Myles Watson ** connected SRC. 7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Returns void 7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 762ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 7636bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonvoid bta_av_co_audio_delay(tBTA_AV_HNDL hndl, uint16_t delay) { 7646bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_ERROR("%s: handle: x%x, delay:0x%x", __func__, hndl, delay); 7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 76731d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavovvoid bta_av_co_audio_update_mtu(tBTA_AV_HNDL hndl, uint16_t mtu) { 76831d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov tBTA_AV_CO_PEER* p_peer; 76931d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov 77031d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov APPL_TRACE_DEBUG("%s: handle: %d mtu: %d", __func__, hndl, mtu); 77131d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov 77231d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov /* Retrieve the peer info */ 77331d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov p_peer = bta_av_co_get_peer(hndl); 77431d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov if (p_peer == NULL) { 77531d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov APPL_TRACE_ERROR("%s: could not find peer entry", __func__); 77631d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov return; 77731d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov } 77831d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov p_peer->mtu = mtu; 77931d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov} 78031d373be957f094092b9dc94f0b41de23f69fd2aPavlin Radoslavov 7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_cp_is_scmst 7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description Check if a content protection service is SCMS-T 7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 787b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen ** Returns true if this CP is SCMS-T, false otherwise 7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 789ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 790cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic bool bta_av_co_cp_is_scmst(const uint8_t* p_protect_info) { 7916bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 79279506e8fcd91d066db1c8aa71008a7b53b0e9172Pavlin Radoslavov 793cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (*p_protect_info >= AVDT_CP_LOSC) { 7946bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint16_t cp_id; 7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 796cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov p_protect_info++; 797cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov STREAM_TO_UINT16(cp_id, p_protect_info); 798feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov if (cp_id == AVDT_CP_SCMS_T_ID) { 7996bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: SCMS-T found", __func__); 8006bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return true; 8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8046bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return false; 8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 807cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov// Check if audio protect info contains SCMS-T Copy Protection 808cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov// Returns true if |p_protect_info| contains SCMS-T, otherwise false. 809cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic bool bta_av_co_audio_protect_has_scmst(uint8_t num_protect, 810cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov const uint8_t* p_protect_info) { 8116bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 8126bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 813cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov while (num_protect--) { 814cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (bta_av_co_cp_is_scmst(p_protect_info)) return true; 8156bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Move to the next SC */ 816cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov p_protect_info += *p_protect_info + 1; 8176bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 8186bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: SCMS-T not found", __func__); 8196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return false; 8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Function bta_av_co_audio_sink_supports_cp 8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Description Check if a sink supports the current content protection 8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 828b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen ** Returns true if the sink supports this CP, false otherwise 8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 830ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 8316bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic bool bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK* p_sink) { 8326bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8346bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Check if content protection is enabled for this stream */ 835cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (bta_av_co_cp_get_flag() != AVDT_CP_SCMS_COPY_FREE) { 836cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov return bta_av_co_audio_protect_has_scmst(p_sink->num_protect, 837cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov p_sink->protect_info); 838cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 839c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 8406bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: not required", __func__); 8416bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return true; 8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** 846c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov ** Function bta_av_co_find_peer_src_supports_codec 847cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** 848c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov ** Description Find a peer acting as src that supports codec config 849cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** 850c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov ** Returns The peer source that supports the codec, otherwise NULL. 851cc35559160745c60b42ae182002a59337d844d09Hemant Gupta ** 852ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 853c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavovstatic const tBTA_AV_CO_SINK* bta_av_co_find_peer_src_supports_codec( 8546bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson const tBTA_AV_CO_PEER* p_peer) { 8556bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s: peer num_sup_srcs = %d", __func__, 8566bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson p_peer->num_sup_srcs); 8576bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 8586bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson for (size_t index = 0; index < p_peer->num_sup_srcs; index++) { 8596bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson const uint8_t* p_codec_caps = p_peer->srcs[index].codec_caps; 86082fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov if (A2DP_CodecTypeEquals(bta_av_co_cb.codec_config, p_codec_caps) && 8616bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson A2DP_IsPeerSourceCodecSupported(p_codec_caps)) { 8626bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return &p_peer->srcs[index]; 8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8646bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 8656bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson return NULL; 8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 868cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov// 869cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov// Select the current codec configuration based on peer codec support. 870494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov// Furthermore, the local state for the remaining non-selected codecs is 871494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov// updated to reflect whether the codec is selectable. 872494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov// Return a pointer to the corresponding |tBTA_AV_CO_SINK| sink entry 873494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov// on success, otherwise NULL. 874cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov// 875cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic tBTA_AV_CO_SINK* bta_av_co_audio_set_codec(tBTA_AV_CO_PEER* p_peer) { 876494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov tBTA_AV_CO_SINK* p_sink = NULL; 877494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov 878494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // Update all selectable codecs. 879494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // This is needed to update the selectable parameters for each codec. 880494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // NOTE: The selectable codec info is used only for informational purpose. 881494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov for (const auto& iter : bta_av_co_cb.codecs->orderedSourceCodecs()) { 882494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov APPL_TRACE_DEBUG("%s: updating selectable codec %s", __func__, 883494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov iter->name().c_str()); 884494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov bta_av_co_audio_update_selectable_codec(*iter, p_peer); 885494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov } 886494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov 887494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // Select the codec 8885ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov for (const auto& iter : bta_av_co_cb.codecs->orderedSourceCodecs()) { 8895ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_DEBUG("%s: trying codec %s", __func__, iter->name().c_str()); 890494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov p_sink = bta_av_co_audio_codec_selected(*iter, p_peer); 891cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (p_sink != NULL) { 8925ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_DEBUG("%s: selected codec %s", __func__, iter->name().c_str()); 893494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov break; 89482fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov } 8955ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_DEBUG("%s: cannot use codec %s", __func__, iter->name().c_str()); 89682fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov } 89782fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov 898494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // NOTE: Unconditionally dispatch the event to make sure a callback with 899494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // the most recent codec info is generated. 900494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0); 901494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov 902494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov return p_sink; 903cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov} 904c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 9055ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// Select an open device for the preferred codec specified by |codec_config|. 906cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov// Return the corresponding peer that supports the codec, otherwise NULL. 907cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic tBTA_AV_CO_SINK* bta_av_co_audio_codec_selected( 9085ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2dpCodecConfig& codec_config, tBTA_AV_CO_PEER* p_peer) { 909cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov uint8_t new_codec_config[AVDT_CODEC_SIZE]; 910c66edf3144f19eb7bc174f39a17c16f8ad49b64bPavlin Radoslavov 911cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov APPL_TRACE_DEBUG("%s", __func__); 9126bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 913cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // Find the peer sink for the codec 914cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov tBTA_AV_CO_SINK* p_sink = NULL; 915cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov for (size_t index = 0; index < p_peer->num_sup_sinks; index++) { 9165ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov btav_a2dp_codec_index_t peer_codec_index = 9175ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps); 9185ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (peer_codec_index != codec_config.codecIndex()) { 91982fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov continue; 9206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 921cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) { 922cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov APPL_TRACE_DEBUG( 923cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov "%s: peer sink for codec %s does not support " 924cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov "Copy Protection", 9255ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov __func__, codec_config.name().c_str()); 92682fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov continue; 9276bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 928cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov p_sink = &p_peer->sinks[index]; 929cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov break; 930cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 931cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov if (p_sink == NULL) { 932cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov APPL_TRACE_DEBUG("%s: peer sink for codec %s not found", __func__, 9335ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov codec_config.name().c_str()); 934cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov return NULL; 935cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 936494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov if (!bta_av_co_cb.codecs->setCodecConfig( 937494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov p_sink->codec_caps, true /* is_capability */, new_codec_config, 938494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov true /* select_current_codec */)) { 9395ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_DEBUG("%s: cannot set source codec %s", __func__, 9405ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov codec_config.name().c_str()); 941cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov return NULL; 942cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov } 943cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov p_peer->p_sink = p_sink; 9446bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 945cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov bta_av_co_save_new_codec_config(p_peer, new_codec_config, p_sink->num_protect, 946cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov p_sink->protect_info); 947494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // NOTE: Event BTIF_AV_SOURCE_CONFIG_UPDATED_EVT is dispatched by the caller 948d43a901c579ef08a1b5d7cfe18f759aad0a14f1aPavlin Radoslavov 949cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov return p_sink; 950cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov} 951cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov 952494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov// Update a selectable codec |codec_config| with the corresponding codec 953494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov// information from a peer device |p_peer|. 954494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov// Returns true if the codec is updated, otherwise false. 955494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavovstatic bool bta_av_co_audio_update_selectable_codec( 956494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov A2dpCodecConfig& codec_config, const tBTA_AV_CO_PEER* p_peer) { 957494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov uint8_t new_codec_config[AVDT_CODEC_SIZE]; 958494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov 959494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov APPL_TRACE_DEBUG("%s", __func__); 960494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov 961494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // Find the peer sink for the codec 962494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov const tBTA_AV_CO_SINK* p_sink = NULL; 963494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov for (size_t index = 0; index < p_peer->num_sup_sinks; index++) { 964494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov btav_a2dp_codec_index_t peer_codec_index = 965494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps); 966494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov if (peer_codec_index != codec_config.codecIndex()) { 967494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov continue; 968494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov } 969494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) { 970494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov APPL_TRACE_DEBUG( 971494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov "%s: peer sink for codec %s does not support " 972494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov "Copy Protection", 973494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov __func__, codec_config.name().c_str()); 974494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov continue; 975494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov } 976494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov p_sink = &p_peer->sinks[index]; 977494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov break; 978494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov } 979494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov if (p_sink == NULL) { 980494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // The peer sink device does not support this codec 981494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov return false; 982494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov } 983494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov if (!bta_av_co_cb.codecs->setCodecConfig( 984494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov p_sink->codec_caps, true /* is_capability */, new_codec_config, 985494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov false /* select_current_codec */)) { 986494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov APPL_TRACE_DEBUG("%s: cannot update source codec %s", __func__, 987494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov codec_config.name().c_str()); 988494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov return false; 989494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov } 990494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov return true; 991494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov} 992494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov 993cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavovstatic void bta_av_co_save_new_codec_config(tBTA_AV_CO_PEER* p_peer, 994cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov const uint8_t* new_codec_config, 995cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov uint8_t num_protect, 996cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov const uint8_t* p_protect_info) { 997c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov APPL_TRACE_DEBUG("%s", __func__); 998c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov A2DP_DumpCodecInfo(new_codec_config); 999c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov 1000cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // Protect access to bta_av_co_cb.codec_config 1001cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov mutex_global_lock(); 100282fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov 1003cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov memcpy(bta_av_co_cb.codec_config, new_codec_config, 1004cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov sizeof(bta_av_co_cb.codec_config)); 1005cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE); 100682fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov 1007b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen#if (BTA_AV_CO_CP_SCMS_T == TRUE) 1008cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov /* Check if this sink supports SCMS */ 1009cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov bool cp_active = 1010cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov bta_av_co_audio_protect_has_scmst(num_protect, p_protect_info); 1011cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov bta_av_co_cb.cp.active = cp_active; 1012cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov p_peer->cp_active = cp_active; 10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1015cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov // Protect access to bta_av_co_cb.codec_config 1016cd02ce9c60da962a7981320b26aada8744718941Pavlin Radoslavov mutex_global_unlock(); 10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10195ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovvoid bta_av_co_get_peer_params(tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) { 10206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson uint16_t min_mtu = 0xFFFF; 10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10226bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 10235ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov CHECK(p_peer_params != nullptr); 1024b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 102582fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov /* Protect access to bta_av_co_cb.codec_config */ 10266bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson mutex_global_lock(); 1027b18f03ecb0ac258985025b5b19273a187a66e87ePavlin Radoslavov 10286bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Compute the MTU */ 10296bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) { 10306bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson const tBTA_AV_CO_PEER* p_peer = &bta_av_co_cb.peers[i]; 10316bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (!p_peer->opened) continue; 10326bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (p_peer->mtu < min_mtu) min_mtu = p_peer->mtu; 10336bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } 10345ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer_params->peer_mtu = min_mtu; 10355ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer_params->is_peer_edr = btif_av_is_peer_edr(); 10365ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer_params->peer_supports_3mbps = btif_av_peer_supports_3mbps(); 10376bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 103882fcd30ee39420e8702e3d2499d638d9a946beabPavlin Radoslavov /* Protect access to bta_av_co_cb.codec_config */ 10396bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson mutex_global_unlock(); 10404ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov} 10414ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov 10425ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovconst tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface(void) { 10434ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov /* Protect access to bta_av_co_cb.codec_config */ 10444ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov mutex_global_lock(); 10454ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov 10465ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const tA2DP_ENCODER_INTERFACE* encoder_interface = 10475ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2DP_GetEncoderInterface(bta_av_co_cb.codec_config); 10485ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 10495ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov /* Protect access to bta_av_co_cb.codec_config */ 10505ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov mutex_global_unlock(); 10515ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 10525ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return encoder_interface; 10535ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov} 10545ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 10555ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovbool bta_av_co_set_codec_user_config( 10565ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const btav_a2dp_codec_config_t& codec_user_config) { 10575ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov uint8_t result_codec_config[AVDT_CODEC_SIZE]; 1058494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov const tBTA_AV_CO_SINK* p_sink = nullptr; 10595ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool restart_input = false; 10605ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool restart_output = false; 10615ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool config_updated = false; 1062494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov bool success = true; 10635ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 10645ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // Find the peer that is currently open 10655ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tBTA_AV_CO_PEER* p_peer = nullptr; 10665ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) { 10675ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tBTA_AV_CO_PEER* p_peer_tmp = &bta_av_co_cb.peers[i]; 10685ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (p_peer_tmp->opened) { 10695ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer = p_peer_tmp; 10705ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov break; 10715ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 10724ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov } 10735ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (p_peer == nullptr) { 10745ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_ERROR("%s: no open peer to configure", __func__); 1075494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov success = false; 1076494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov goto done; 10774ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov } 10785ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 10795ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // Find the peer SEP codec to use 10805ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) { 10815ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov for (size_t index = 0; index < p_peer->num_sup_sinks; index++) { 10825ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov btav_a2dp_codec_index_t peer_codec_index = 10835ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps); 10845ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (peer_codec_index != codec_user_config.codec_type) continue; 10855ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) continue; 10865ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_sink = &p_peer->sinks[index]; 10875ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov break; 10885ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 10894ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov } else { 10905ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // Use the current sink codec 10915ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_sink = p_peer->p_sink; 10925ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 10935ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (p_sink == nullptr) { 10942073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov APPL_TRACE_ERROR("%s: cannot find peer SEP to configure for codec type %d", 10952073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov __func__, codec_user_config.codec_type); 1096494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov success = false; 1097494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov goto done; 10984ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov } 10994ebaa86a3ab1ea390d238e1f6dee62cd837c60edPavlin Radoslavov 11005ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; 11015ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_get_peer_params(&peer_params); 11025ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (!bta_av_co_cb.codecs->setCodecUserConfig( 11035ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov codec_user_config, &peer_params, p_sink->codec_caps, 11045ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov result_codec_config, &restart_input, &restart_output, 11055ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov &config_updated)) { 1106494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov success = false; 1107494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov goto done; 11085ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 11095ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 11105ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (restart_output) { 11115ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov uint8_t num_protect = 0; 11125ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov#if (BTA_AV_CO_CP_SCMS_T == TRUE) 11135ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (p_peer->cp_active) num_protect = AVDT_CP_INFO_LEN; 11145ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov#endif 11155ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 11162073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov p_sink = bta_av_co_audio_set_codec(p_peer); 11172073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov if (p_sink == NULL) { 11182073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov APPL_TRACE_ERROR("%s: cannot set up codec for the peer SINK", __func__); 11192073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov success = false; 11202073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov goto done; 11212073c3eb61f69864e645c50005f11c4e8b5e2588Pavlin Radoslavov } 1122c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities 1123c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov if ((p_peer->num_rx_sinks != p_peer->num_sinks) && 1124c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) { 1125c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov APPL_TRACE_WARNING("%s: not all peer's capabilities have been retrieved", 1126c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov __func__); 1127c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov success = false; 1128c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov goto done; 1129c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov } 1130c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov 11315ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__, p_peer->handle); 11325ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov BTA_AvReconfig(p_peer->handle, true, p_sink->sep_info_idx, 11335ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer->codec_config, num_protect, bta_av_co_cp_scmst); 11345ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 11355ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 1136494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavovdone: 1137494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // NOTE: We uncoditionally send the upcall even if there is no change 1138494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // or the user config failed. Thus, the caller would always know whether the 1139494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // request succeeded or failed. 1140494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // NOTE: Currently, the input is restarted by sending an upcall 1141494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // and informing the Media Framework about the change. 1142494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0); 11435ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 1144494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov return success; 11451394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov} 11461394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov 11475ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// Sets the Over-The-Air preferred codec configuration. 11485ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// The OTA prefered codec configuration is ignored if the current 11495ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// codec configuration contains explicit user configuration, or if the 11505ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// codec configuration for the same codec contains explicit user 11515ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// configuration. 11525ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// |p_peer| is the peer device that sent the OTA codec configuration. 11535ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// |p_ota_codec_config| contains the received OTA A2DP codec configuration 11545ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// from the remote peer. Note: this is not the peer codec capability, 11555ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// but the codec configuration that the peer would like to use. 11565ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// |num_protect| is the number of content protection methods to use. 11575ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// |p_protect_info| contains the content protection information to use. 11585ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// If there is a change in the encoder configuration tht requires restarting 11595ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// of the A2DP connection, flag |p_restart_output| is set to true. 11605ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov// Returns true on success, otherwise false. 11615ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovstatic bool bta_av_co_set_codec_ota_config(tBTA_AV_CO_PEER* p_peer, 11625ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const uint8_t* p_ota_codec_config, 11635ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov uint8_t num_protect, 11645ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const uint8_t* p_protect_info, 11655ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool* p_restart_output) { 11665ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov uint8_t result_codec_config[AVDT_CODEC_SIZE]; 11675ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool restart_input = false; 11685ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool restart_output = false; 11695ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool config_updated = false; 11705ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 1171c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov APPL_TRACE_DEBUG("%s", __func__); 1172c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov A2DP_DumpCodecInfo(p_ota_codec_config); 1173c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov 11745ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov *p_restart_output = false; 11755ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 11765ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // Find the peer SEP codec to use 11775ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov btav_a2dp_codec_index_t ota_codec_index = 11785ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2DP_SourceCodecIndex(p_ota_codec_config); 11795ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (ota_codec_index == BTAV_A2DP_CODEC_INDEX_MAX) { 11805ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_WARNING("%s: invalid peer codec config", __func__); 11815ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return false; 11825ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 11835ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const tBTA_AV_CO_SINK* p_sink = nullptr; 11845ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov for (size_t index = 0; index < p_peer->num_sup_sinks; index++) { 11855ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov btav_a2dp_codec_index_t peer_codec_index = 11865ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2DP_SourceCodecIndex(p_peer->sinks[index].codec_caps); 11875ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (peer_codec_index != ota_codec_index) continue; 11885ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (!bta_av_co_audio_sink_supports_cp(&p_peer->sinks[index])) continue; 11895ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_sink = &p_peer->sinks[index]; 11905ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov break; 11915ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 11925ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if ((p_peer->num_sup_sinks > 0) && (p_sink == nullptr)) { 11935ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // There are no peer SEPs if we didn't do the discovery procedure yet. 11945ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // We have all the information we need from the peer, so we can 11955ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // proceed with the OTA codec configuration. 11965ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_ERROR("%s: cannot find peer SEP to configure", __func__); 11975ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return false; 11985ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 11991394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov 12005ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; 12015ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_get_peer_params(&peer_params); 12025ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (!bta_av_co_cb.codecs->setCodecOtaConfig( 12035ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_ota_codec_config, &peer_params, result_codec_config, &restart_input, 12045ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov &restart_output, &config_updated)) { 12055ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_ERROR("%s: cannot set OTA config", __func__); 12065ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return false; 12075ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12081394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov 12095ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (restart_output) { 1210c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov APPL_TRACE_DEBUG("%s: restart output", __func__); 1211c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov A2DP_DumpCodecInfo(result_codec_config); 1212c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov 12135ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov *p_restart_output = true; 12145ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer->p_sink = p_sink; 12155ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_save_new_codec_config(p_peer, result_codec_config, num_protect, 12165ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_protect_info); 12175ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12185ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12195ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (restart_input || config_updated) { 12205ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // NOTE: Currently, the input is restarted by sending an upcall 12215ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // and informing the Media Framework about the change. 12225ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0); 12235ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12245ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12255ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return true; 12265ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov} 12275ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12285ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavovbool bta_av_co_set_codec_audio_config( 12295ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const btav_a2dp_codec_config_t& codec_audio_config) { 12305ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov uint8_t result_codec_config[AVDT_CODEC_SIZE]; 12315ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool restart_output = false; 12325ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bool config_updated = false; 12335ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12345ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // Find the peer that is currently open 12355ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tBTA_AV_CO_PEER* p_peer = nullptr; 12365ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); i++) { 12375ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tBTA_AV_CO_PEER* p_peer_tmp = &bta_av_co_cb.peers[i]; 12385ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (p_peer_tmp->opened) { 12395ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_peer = p_peer_tmp; 12405ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov break; 12415ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12425ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12435ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (p_peer == nullptr) { 12445ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_ERROR("%s: no open peer to configure", __func__); 12455ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return false; 12465ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12475ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12485ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // Use the current sink codec 12495ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov const tBTA_AV_CO_SINK* p_sink = p_peer->p_sink; 12505ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (p_sink == nullptr) { 12515ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov APPL_TRACE_ERROR("%s: cannot find peer SEP to configure", __func__); 12525ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return false; 12535ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12545ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12555ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; 12565ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_get_peer_params(&peer_params); 12575ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (!bta_av_co_cb.codecs->setCodecAudioConfig( 12585ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov codec_audio_config, &peer_params, p_sink->codec_caps, 12595ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov result_codec_config, &restart_output, &config_updated)) { 12605ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return false; 12615ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12625ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12635ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (restart_output) { 12645ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov uint8_t num_protect = 0; 12655ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov#if (BTA_AV_CO_CP_SCMS_T == TRUE) 12665ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (p_peer->cp_active) num_protect = AVDT_CP_INFO_LEN; 12675ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov#endif 12685ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12695ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_save_new_codec_config(p_peer, result_codec_config, 12705ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov p_sink->num_protect, p_sink->protect_info); 12715ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 1272c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities 1273c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov if ((p_peer->num_rx_sinks != p_peer->num_sinks) && 1274c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) { 1275c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov APPL_TRACE_WARNING("%s: not all peer's capabilities have been retrieved", 1276c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov __func__); 1277c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov } else { 1278c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov APPL_TRACE_DEBUG("%s: call BTA_AvReconfig(x%x)", __func__, 1279c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov p_peer->handle); 1280c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov BTA_AvReconfig(p_peer->handle, true, p_sink->sep_info_idx, 1281c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov p_peer->codec_config, num_protect, bta_av_co_cp_scmst); 1282c64dc1d28496b5e917d0f82317d40d3c60e6495dPavlin Radoslavov } 12835ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12845ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12855ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (config_updated) { 12865ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // NOTE: Currently, the input is restarted by sending an upcall 12875ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov // and informing the Media Framework about the change. 12885ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0); 12895ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 12905ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12915ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return true; 12925ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov} 12935ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12945ce0116fbf5b530d5b93f11312096eade1021c1ePavlin RadoslavovA2dpCodecs* bta_av_get_a2dp_codecs(void) { return bta_av_co_cb.codecs; } 12955ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12965ce0116fbf5b530d5b93f11312096eade1021c1ePavlin RadoslavovA2dpCodecConfig* bta_av_get_a2dp_current_codec(void) { 12975ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2dpCodecConfig* current_codec; 12985ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov 12995ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov mutex_global_lock(); 13005ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov if (bta_av_co_cb.codecs == nullptr) { 13015ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov mutex_global_unlock(); 13025ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return nullptr; 13035ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov } 13045ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov current_codec = bta_av_co_cb.codecs->getCurrentCodecConfig(); 13056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson mutex_global_unlock(); 13061394c197027c0907932a814a786cc033870eb1c9Pavlin Radoslavov 13075ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov return current_codec; 13085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 13095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1310a6ba5aca4e8c1a200b8cc29fb60d390a7196416aPavlin Radoslavovvoid bta_av_co_init( 1311a6ba5aca4e8c1a200b8cc29fb60d390a7196416aPavlin Radoslavov const std::vector<btav_a2dp_codec_config_t>& codec_priorities) { 13126bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson APPL_TRACE_DEBUG("%s", __func__); 13135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13146bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Reset the control block */ 13155ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_cb.reset(); 13165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1317b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen#if (BTA_AV_CO_CP_SCMS_T == TRUE) 1318feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov bta_av_co_cp_set_flag(AVDT_CP_SCMS_COPY_NEVER); 13195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else 1320feee26c3dae12b53773b31f57cf2533a3d993979Pavlin Radoslavov bta_av_co_cp_set_flag(AVDT_CP_SCMS_COPY_FREE); 13215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 13225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13236bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson /* Reset the current config */ 13245ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov /* Protect access to bta_av_co_cb.codec_config */ 13255ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov mutex_global_lock(); 1326a6ba5aca4e8c1a200b8cc29fb60d390a7196416aPavlin Radoslavov bta_av_co_cb.codecs = new A2dpCodecs(codec_priorities); 13275ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov bta_av_co_cb.codecs->init(); 13285ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov A2DP_InitDefaultCodec(bta_av_co_cb.codec_config); 13295ce0116fbf5b530d5b93f11312096eade1021c1ePavlin Radoslavov mutex_global_unlock(); 1330494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov 1331494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // NOTE: Unconditionally dispatch the event to make sure a callback with 1332494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov // the most recent codec info is generated. 1333494e53e904e8aecc28178fda5856071776b2caf0Pavlin Radoslavov btif_dispatch_sm_event(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT, NULL, 0); 13345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1335