15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2009-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 * Filename: audio_a2dp_hw.c 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Description: Implements hal for bluedroid a2dp audio device 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *****************************************************************************/ 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <errno.h> 2840421cbeef5836f5ca9a7c323121f5396db467c3Mark Salyzyn#include <inttypes.h> 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <pthread.h> 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdint.h> 315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/time.h> 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/socket.h> 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/un.h> 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/poll.h> 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/errno.h> 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/stat.h> 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <unistd.h> 385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <fcntl.h> 395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <cutils/str_parms.h> 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <cutils/sockets.h> 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <system/audio.h> 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/audio.h> 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/hardware.h> 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "audio_a2dp_hw.h" 475cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h" 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 49f8027005333c88a2f097cfd70d15c3d54c7764aeChris Manton#define LOG_TAG "bt_a2dp_hw" 5044802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h" 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Constants & Macros 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CTRL_CHAN_RETRY_COUNT 3 575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define USEC_PER_SEC 1000000L 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CASE_RETURN_STR(const) case const: return #const; 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6144802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#define FNLOG() LOG_VERBOSE("%s", __FUNCTION__); 6244802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#define DEBUG(fmt, ...) LOG_VERBOSE("%s: " fmt,__FUNCTION__, ## __VA_ARGS__) 6344802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#define INFO(fmt, ...) LOG_INFO("%s: " fmt,__FUNCTION__, ## __VA_ARGS__) 6444802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#define ERROR(fmt, ...) LOG_ERROR("%s: " fmt,__FUNCTION__, ## __VA_ARGS__) 655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define ASSERTC(cond, msg, val) if (!(cond)) {ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);} 675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Local type definitions 705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef enum { 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project AUDIO_A2DP_STATE_STARTING, 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project AUDIO_A2DP_STATE_STARTED, 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project AUDIO_A2DP_STATE_STOPPING, 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project AUDIO_A2DP_STATE_STOPPED, 775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project AUDIO_A2DP_STATE_SUSPENDED, /* need explicit set param call to resume (suspend=false) */ 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project AUDIO_A2DP_STATE_STANDBY /* allows write to autoresume */ 795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} a2dp_state_t; 805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 813e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstruct a2dp_stream_in; 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct a2dp_stream_out; 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct a2dp_audio_device { 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct audio_hw_device device; 863e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_stream_in *input; 875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *output; 885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct a2dp_config { 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t rate; 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t channel_flags; 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int format; 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* move ctrl_fd outside output stream and keep open until HAL unloaded ? */ 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 983e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstruct a2dp_stream_common { 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_mutex_t lock; 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ctrl_fd; 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int audio_fd; 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project size_t buffer_sz; 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_config cfg; 1043e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_state_t state; 1053e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood}; 1063e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 1073e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstruct a2dp_stream_out { 1083e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct audio_stream_out stream; 1093e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_stream_common common; 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct a2dp_stream_in { 1133e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct audio_stream_in stream; 1143e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_stream_common common; 1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Static variables 1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Static functions 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic size_t out_get_buffer_size(const struct audio_stream *stream); 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Externs 1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Functions 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Miscellaneous helper functions 1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const char* dump_a2dp_ctrl_event(char event) 1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project switch(event) 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project CASE_RETURN_STR(A2DP_CTRL_CMD_NONE) 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY) 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project CASE_RETURN_STR(A2DP_CTRL_CMD_START) 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project CASE_RETURN_STR(A2DP_CTRL_CMD_STOP) 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND) 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project default: 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return "UNKNOWN MSG ID"; 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* logs timestamp with microsec precision 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pprev is optional in case a dedicated diff is required */ 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void ts_log(char *tag, int val, struct timespec *pprev_opt) 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct timespec now; 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project static struct timespec prev = {0,0}; 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project unsigned long long now_us; 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project unsigned long long diff_us; 1615cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(tag); 1625cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(val); 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project clock_gettime(CLOCK_MONOTONIC, &now); 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000; 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (pprev_opt) 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000; 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *pprev_opt = now; 1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val); 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000; 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project prev = now; 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val); 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int calc_audiotime(struct a2dp_config cfg, int bytes) 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int chan_count = popcount(cfg.channel_flags); 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ASSERTC(cfg.format == AUDIO_FORMAT_PCM_16_BIT, 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "unsupported sample sz", cfg.format); 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return bytes*(1000000/(chan_count*2))/cfg.rate; 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** bluedroid stack adaptation 1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/ 1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1983e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic int skt_connect(char *path, size_t buffer_sz) 1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ret; 2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int skt_fd; 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct sockaddr_un remote; 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int len; 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2053e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("connect to %s (sz %zu)", path, buffer_sz); 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0); 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(socket_local_client_connect(skt_fd, path, 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("failed to connect (%s)", strerror(errno)); 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close(skt_fd); 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2173e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood len = buffer_sz; 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len)); 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* only issue warning if failed */ 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ret < 0) 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("setsockopt failed (%s)", strerror(errno)); 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 224b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len)); 225b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood 226b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood /* only issue warning if failed */ 227b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood if (ret < 0) 228b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood ERROR("setsockopt failed (%s)", strerror(errno)); 229b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project INFO("connected to stack fd = %d", skt_fd); 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return skt_fd; 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 235b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwoodstatic int skt_read(int fd, void *p, size_t len) 2363e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood{ 2373e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood int read; 2383e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct pollfd pfd; 2393e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct timespec ts; 2403e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 2413e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood FNLOG(); 2423e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 2433e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ts_log("skt_read recv", len, NULL); 2443e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 2453e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if ((read = recv(fd, p, len, MSG_NOSIGNAL)) == -1) 2463e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 2473e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("write failed with errno=%d\n", errno); 2483e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 2493e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 2503e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 2513e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return read; 2523e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood} 2533e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int skt_write(int fd, const void *p, size_t len) 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int sent; 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct pollfd pfd; 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pfd.fd = fd; 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pfd.events = POLLOUT; 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* poll for 500 ms */ 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* send time out */ 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (poll(&pfd, 1, 500) == 0) 2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts_log("skt_write", len, NULL); 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((sent = send(fd, p, len, MSG_NOSIGNAL)) == -1) 2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("write failed with errno=%d\n", errno); 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return sent; 2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int skt_disconnect(int fd) 2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project INFO("fd %d", fd); 2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (fd != AUDIO_SKT_DISCONNECTED) 2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project shutdown(fd, SHUT_RDWR); 2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close(fd); 2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** AUDIO CONTROL PATH 2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/ 3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3013e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length) 3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3033e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood int ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL); 3043e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (ret < 0) 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("ack failed (%s)", strerror(errno)); 3071b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav if (errno == EINTR) 3081b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav { 3091b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav /* retry again */ 3103e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL); 3113e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (ret < 0) 3121b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav { 3131b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav ERROR("ack failed (%s)", strerror(errno)); 3143e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(common->ctrl_fd); 3153e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->ctrl_fd = AUDIO_SKT_DISCONNECTED; 3161b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav return -1; 3171b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav } 3181b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav } 3191b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav else 3201b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav { 3213e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(common->ctrl_fd); 3223e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->ctrl_fd = AUDIO_SKT_DISCONNECTED; 3231b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav return -1; 3241b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav 3251b1708919d25b5b58384a590f8258f099c97a81fNitin Srivastav } 3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3273e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return ret; 3283e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood} 3293e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3303e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic int a2dp_command(struct a2dp_stream_common *common, char cmd) 3313e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood{ 3323e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood char ack; 3333e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3343e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd)); 3353e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3363e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* send command */ 3373e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1) 3383e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 3393e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("cmd failed (%s)", strerror(errno)); 3403e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(common->ctrl_fd); 3413e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->ctrl_fd = AUDIO_SKT_DISCONNECTED; 3423e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 3433e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 3443e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3453e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* wait for ack byte */ 3463e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (a2dp_ctrl_receive(common, &ack, 1) < 0) 3473e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("A2DP COMMAND %s DONE STATUS %d", dump_a2dp_ctrl_event(cmd), ack); 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3519c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta if (ack == A2DP_CTRL_ACK_INCALL_FAILURE) 3529c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta return ack; 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (ack != A2DP_CTRL_ACK_SUCCESS) 3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3593e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic int check_a2dp_ready(struct a2dp_stream_common *common) 3603e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood{ 3613e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0) 3623e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 3633e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("check a2dp ready failed"); 3643e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 3653e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 3663e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return 0; 3673e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood} 3683e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3693e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic int a2dp_read_audio_config(struct a2dp_stream_common *common) 3703e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood{ 3713e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood char cmd = A2DP_CTRL_GET_AUDIO_CONFIG; 3723e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood uint32_t sample_rate; 3733e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood uint8_t channel_count; 3743e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3753e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (a2dp_command(common, A2DP_CTRL_GET_AUDIO_CONFIG) < 0) 3763e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 3773e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("check a2dp ready failed"); 3783e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 3793e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 3803e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3813e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (a2dp_ctrl_receive(common, &sample_rate, 4) < 0) 3823e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 3833e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (a2dp_ctrl_receive(common, &channel_count, 1) < 0) 3843e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 3853e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3863e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->cfg.channel_flags = (channel_count == 1 ? AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO); 3873e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT; 3883e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->cfg.rate = sample_rate; 3893e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3903e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("got config %d %d", common->cfg.format, common->cfg.rate); 3913e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3923e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return 0; 3933e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood} 3943e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3953e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic void a2dp_open_ctrl_path(struct a2dp_stream_common *common) 3963e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood{ 3973e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood int i; 3983e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 3993e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* retry logic to catch any timing variations on control channel */ 4003e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++) 4013e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 4023e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* connect control channel if not already connected */ 4033e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0) 4043e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 4053e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* success, now check if stack is ready */ 4063e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (check_a2dp_ready(common) == 0) 4073e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood break; 4083e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 4093e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("error : a2dp not ready, wait 250 ms and retry"); 4103e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood usleep(250000); 4113e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(common->ctrl_fd); 4123e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->ctrl_fd = AUDIO_SKT_DISCONNECTED; 4133e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 4143e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 4153e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* ctrl channel not ready, wait a bit */ 4163e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood usleep(250000); 4173e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 4183e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood} 4193e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** AUDIO DATA PATH 4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/ 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4263e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic void a2dp_stream_common_init(struct a2dp_stream_common *common) 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_mutexattr_t lock_attr; 4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_mutexattr_init(&lock_attr); 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE); 4343e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood pthread_mutex_init(&common->lock, &lock_attr); 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4363e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->ctrl_fd = AUDIO_SKT_DISCONNECTED; 4373e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->audio_fd = AUDIO_SKT_DISCONNECTED; 4383e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = AUDIO_A2DP_STATE_STOPPED; 4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* manages max capacity of socket pipe */ 4413e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ; 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4443e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic int start_audio_datapath(struct a2dp_stream_common *common) 4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4463e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("state %d", common->state); 4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4483e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) { 4499c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta INFO("%s AUDIO_SKT_DISCONNECTED", __func__); 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 4513e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4539c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta int oldstate = common->state; 4543e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = AUDIO_A2DP_STATE_STARTING; 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4569c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta int a2dp_status = a2dp_command(common, A2DP_CTRL_CMD_START); 4579c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta if (a2dp_status < 0) 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4599c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta ERROR("%s Audiopath start failed (status %d)", __func__, a2dp_status); 4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4613e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = oldstate; 4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4649c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE) 4659c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta { 4669c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta ERROR("%s Audiopath start failed - in call, move to suspended", __func__); 4679c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta common->state = oldstate; 4689c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta return -1; 4699c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta } 4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* connect socket if not yet connected */ 4723e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (common->audio_fd == AUDIO_SKT_DISCONNECTED) 4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4743e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz); 4753e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (common->audio_fd < 0) 4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4773e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = oldstate; 4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4813e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = AUDIO_A2DP_STATE_STARTED; 4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4873e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic int stop_audio_datapath(struct a2dp_stream_common *common) 4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4893e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood int oldstate = common->state; 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4913e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("state %d", common->state); 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4933e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* prevent any stray output writes from autostarting the stream 4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while stopping audiopath */ 4983e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = AUDIO_A2DP_STATE_STOPPING; 4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5003e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0) 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("audiopath stop failed"); 5033e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = oldstate; 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5073e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = AUDIO_A2DP_STATE_STOPPED; 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* disconnect audio path */ 5103e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(common->audio_fd); 5113e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->audio_fd = AUDIO_SKT_DISCONNECTED; 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5163e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwoodstatic int suspend_audio_datapath(struct a2dp_stream_common *common, bool standby) 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5183e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("state %d", common->state); 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5203e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5233e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (common->state == AUDIO_A2DP_STATE_STOPPING) 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5263e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0) 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (standby) 5303e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = AUDIO_A2DP_STATE_STANDBY; 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5323e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->state = AUDIO_A2DP_STATE_SUSPENDED; 5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* disconnect audio path */ 5353e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(common->audio_fd); 5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5373e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood common->audio_fd = AUDIO_SKT_DISCONNECTED; 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** audio output callbacks 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/ 5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic ssize_t out_write(struct audio_stream_out *stream, const void* buffer, 5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project size_t bytes) 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int sent; 5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5553e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd); 5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 55796162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta pthread_mutex_lock(&out->common.lock); 55896162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta 5593e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED) 5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("stream suspended"); 56296162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta pthread_mutex_unlock(&out->common.lock); 5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* only allow autostarting if we are in stopped or standby */ 5673e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) || 5683e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood (out->common.state == AUDIO_A2DP_STATE_STANDBY)) 5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5703e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (start_audio_datapath(&out->common) < 0) 5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* emulate time this write represents to avoid very fast write 5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project failures during transition periods or remote suspend */ 5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5753e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood int us_delay = calc_audiotime(out->common.cfg, bytes); 5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("emulate a2dp write delay (%d us)", us_delay); 5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project usleep(us_delay); 5803e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood pthread_mutex_unlock(&out->common.lock); 5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5843e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood else if (out->common.state != AUDIO_A2DP_STATE_STARTED) 5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("stream not in stopped or standby"); 58796162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta pthread_mutex_unlock(&out->common.lock); 5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 59196162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta pthread_mutex_unlock(&out->common.lock); 5923e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood sent = skt_write(out->common.audio_fd, buffer, bytes); 5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 59415d6b3144d92167d1f4f88cc87a50c2571a2c166Eric Laurent if (sent == -1) 59515d6b3144d92167d1f4f88cc87a50c2571a2c166Eric Laurent { 5963e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(out->common.audio_fd); 5973e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood out->common.audio_fd = AUDIO_SKT_DISCONNECTED; 59896162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED) 59996162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta out->common.state = AUDIO_A2DP_STATE_STOPPED; 60096162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta else 60196162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta ERROR("write failed : stream suspended, avoid resetting state"); 6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 60440421cbeef5836f5ca9a7c323121f5396db467c3Mark Salyzyn DEBUG("wrote %d bytes out of %zu bytes", sent, bytes); 6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return sent; 6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint32_t out_get_sample_rate(const struct audio_stream *stream) 6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6133e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("rate %" PRIu32,out->common.cfg.rate); 6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6153e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return out->common.cfg.rate; 6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) 6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 62240421cbeef5836f5ca9a7c323121f5396db467c3Mark Salyzyn DEBUG("out_set_sample_rate : %" PRIu32, rate); 6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (rate != AUDIO_STREAM_DEFAULT_RATE) 6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("only rate %d supported", AUDIO_STREAM_DEFAULT_RATE); 6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6303e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood out->common.cfg.rate = rate; 6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic size_t out_get_buffer_size(const struct audio_stream *stream) 6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6393e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("buffer_size : %zu", out->common.buffer_sz); 6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6413e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return out->common.buffer_sz; 6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint32_t out_get_channels(const struct audio_stream *stream) 6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6483e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_flags); 6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6503e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return out->common.cfg.channel_flags; 6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic audio_format_t out_get_format(const struct audio_stream *stream) 6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6563e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("format 0x%x", out->common.cfg.format); 6573e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return out->common.cfg.format; 6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_set_format(struct audio_stream *stream, audio_format_t format) 6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6625cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(format); 6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("setting format not yet supported (0x%x)", format); 6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOSYS; 6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_standby(struct audio_stream *stream) 6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int retVal = 0; 6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6753e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood pthread_mutex_lock(&out->common.lock); 6769c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta // Do nothing in SUSPENDED state. 6779c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED) 6789c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta retVal = suspend_audio_datapath(&out->common, true); 6799c5d0727dd4cd09e44c032506c28ab4120ad3b88Anubhav Gupta pthread_mutex_unlock (&out->common.lock); 6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return retVal; 6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_dump(const struct audio_stream *stream, int fd) 6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6865cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(fd); 6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_set_parameters(struct audio_stream *stream, const char *kvpairs) 6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct str_parms *parms; 6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project char keyval[16]; 6973efd2322e130b521dd403a03676109ca325d7d3cEric Laurent int retval; 6983efd2322e130b521dd403a03676109ca325d7d3cEric Laurent int status = 0; 6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7003e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("state %d", out->common.state); 7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project parms = str_parms_create_str(kvpairs); 7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* dump params */ 7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project str_parms_dump(parms); 7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project retval = str_parms_get_str(parms, "closing", keyval, sizeof(keyval)); 7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (retval >= 0) 7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (strcmp(keyval, "true") == 0) 7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("stream closing, disallow any writes"); 71496162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta pthread_mutex_lock(&out->common.lock); 7153e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood out->common.state = AUDIO_A2DP_STATE_STOPPING; 71696162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta pthread_mutex_unlock(&out->common.lock); 7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project retval = str_parms_get_str(parms, "A2dpSuspended", keyval, sizeof(keyval)); 7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (retval >= 0) 7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 72496162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta pthread_mutex_lock(&out->common.lock); 7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (strcmp(keyval, "true") == 0) 7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7273e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (out->common.state == AUDIO_A2DP_STATE_STARTED) 7283e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood status = suspend_audio_datapath(&out->common, false); 7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Do not start the streaming automatically. If the phone was streaming 7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * prior to being suspended, the next out_write shall trigger the 7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * AVDTP start procedure */ 7353e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED) 7363e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood out->common.state = AUDIO_A2DP_STATE_STANDBY; 7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Irrespective of the state, return 0 */ 7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 73996162b608ce2ad6d86214d7efd2bcc120d1f079cAnubhav Gupta pthread_mutex_unlock(&out->common.lock); 7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project str_parms_destroy(parms); 7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7443efd2322e130b521dd403a03676109ca325d7d3cEric Laurent return status; 7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic char * out_get_parameters(const struct audio_stream *stream, const char *keys) 7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 7495cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(keys); 7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* add populating param here */ 7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return strdup(""); 7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint32_t out_get_latency(const struct audio_stream_out *stream) 7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int latency_us; 7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7673e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood latency_us = ((out->common.buffer_sz * 1000 ) / 768171c23f2c009c8dceb5ca69729dff7913e23d3e6Eric Laurent audio_stream_out_frame_size(&out->stream) / 7693e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood out->common.cfg.rate) * 1000; 7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (latency_us / 1000) + 200; 7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_set_volume(struct audio_stream_out *stream, float left, 7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project float right) 7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 7785cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 7795cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(left); 7805cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(right); 7815cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* volume controlled in audioflinger mixer (digital) */ 7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOSYS; 7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_get_render_position(const struct audio_stream_out *stream, 7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t *dsp_frames) 7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 79415d6b3144d92167d1f4f88cc87a50c2571a2c166Eric Laurent UNUSED(stream); 79515d6b3144d92167d1f4f88cc87a50c2571a2c166Eric Laurent UNUSED(dsp_frames); 7965cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 79815d6b3144d92167d1f4f88cc87a50c2571a2c166Eric Laurent return -EINVAL; 7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8035cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 8045cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(effect); 8055cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8125cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 8135cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(effect); 8145cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* 8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * AUDIO INPUT STREAM 8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint32_t in_get_sample_rate(const struct audio_stream *stream) 8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8253e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; 8265cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8283e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return in->common.cfg.rate; 8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) 8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8333e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; 8345cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8363e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 8373e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate) 8383e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return 0; 8393e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood else 8403e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic size_t in_get_buffer_size(const struct audio_stream *stream) 8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8455cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 8465cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 320; 8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint32_t in_get_channels(const struct audio_stream *stream) 8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8533e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; 8545cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8563e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return in->common.cfg.channel_flags; 8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic audio_format_t in_get_format(const struct audio_stream *stream) 8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8615cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 8625cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return AUDIO_FORMAT_PCM_16_BIT; 8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int in_set_format(struct audio_stream *stream, audio_format_t format) 8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8695cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 8705cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(format); 8715cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8733e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (format == AUDIO_FORMAT_PCM_16_BIT) 8743e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return 0; 8753e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood else 8763e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int in_standby(struct audio_stream *stream) 8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8815cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 8825cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int in_dump(const struct audio_stream *stream, int fd) 8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8895cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 8905cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(fd); 8915cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int in_set_parameters(struct audio_stream *stream, const char *kvpairs) 8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 8985cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 8995cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(kvpairs); 9005cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic char * in_get_parameters(const struct audio_stream *stream, 9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project const char *keys) 9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 9085cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 9095cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(keys); 9105cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return strdup(""); 9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int in_set_gain(struct audio_stream_in *stream, float gain) 9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 9175cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 9185cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(gain); 9195cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic ssize_t in_read(struct audio_stream_in *stream, void* buffer, 9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project size_t bytes) 9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 9273e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; 9283e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood int read; 9295cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 9303e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("read %zu bytes, state: %d", bytes, in->common.state); 9313e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 9323e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED) 9333e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 9343e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("stream suspended"); 9353e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 9363e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 9373e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 9383e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* only allow autostarting if we are in stopped or standby */ 9393e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) || 9403e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood (in->common.state == AUDIO_A2DP_STATE_STANDBY)) 9413e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 9423e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood pthread_mutex_lock(&in->common.lock); 9433e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 9443e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (start_audio_datapath(&in->common) < 0) 9453e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 9463e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* emulate time this write represents to avoid very fast write 9473e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood failures during transition periods or remote suspend */ 9483e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 949b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood int us_delay = calc_audiotime(in->common.cfg, bytes); 950b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood 9513e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("emulate a2dp read delay (%d us)", us_delay); 9523e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 9533e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood usleep(us_delay); 9543e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood pthread_mutex_unlock(&in->common.lock); 9553e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 9563e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 9573e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 9583e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood pthread_mutex_unlock(&in->common.lock); 9593e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 9603e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood else if (in->common.state != AUDIO_A2DP_STATE_STARTED) 9613e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 9623e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("stream not in stopped or standby"); 9633e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return -1; 9643e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 9653e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 966b1c8fccbca8573555d6db07a2e44685f335800aaMike Lockwood read = skt_read(in->common.audio_fd, buffer, bytes); 9673e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 9683e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (read == -1) 9693e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 9703e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(in->common.audio_fd); 9713e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood in->common.audio_fd = AUDIO_SKT_DISCONNECTED; 9723e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood in->common.state = AUDIO_A2DP_STATE_STOPPED; 9733e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } else if (read == 0) { 9743e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("read time out - return zeros"); 9753e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood memset(buffer, 0, bytes); 9763e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood read = bytes; 9773e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 9783e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 9793e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("read %d bytes out of %zu bytes", read, bytes); 9803e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood return read; 9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) 9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 9855cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 9865cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 9935cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 9945cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(effect); 9955cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 10025cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(stream); 10035cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(effect); 10045cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_open_output_stream(struct audio_hw_device *dev, 10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project audio_io_handle_t handle, 10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project audio_devices_t devices, 10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project audio_output_flags_t flags, 10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct audio_config *config, 101570311ac9119c65e48c26ce899181e683a3220562Eric Laurent struct audio_stream_out **stream_out, 10168c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge const char *address) 10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; 10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out; 10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ret = 0; 10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 10238c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge UNUSED(address); 10245cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(handle); 10255cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(devices); 10265cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(flags); 10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project INFO("opening output"); 10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out = (struct a2dp_stream_out *)calloc(1, sizeof(struct a2dp_stream_out)); 10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!out) 10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOMEM; 10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.get_sample_rate = out_get_sample_rate; 10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.set_sample_rate = out_set_sample_rate; 10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.get_buffer_size = out_get_buffer_size; 10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.get_channels = out_get_channels; 10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.get_format = out_get_format; 10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.set_format = out_set_format; 10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.standby = out_standby; 10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.dump = out_dump; 10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.set_parameters = out_set_parameters; 10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.get_parameters = out_get_parameters; 10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.add_audio_effect = out_add_audio_effect; 10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.common.remove_audio_effect = out_remove_audio_effect; 10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.get_latency = out_get_latency; 10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.set_volume = out_set_volume; 10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.write = out_write; 10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project out->stream.get_render_position = out_get_render_position; 10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* initialize a2dp specifics */ 10533e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_stream_common_init(&out->common); 10543e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 10553e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood out->common.cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG; 10563e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood out->common.cfg.format = AUDIO_STREAM_DEFAULT_FORMAT; 10573e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood out->common.cfg.rate = AUDIO_STREAM_DEFAULT_RATE; 10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* set output config values */ 10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (config) 10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project config->format = out_get_format((const struct audio_stream *)&out->stream); 10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project config->sample_rate = out_get_sample_rate((const struct audio_stream *)&out->stream); 10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project config->channel_mask = out_get_channels((const struct audio_stream *)&out->stream); 10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *stream_out = &out->stream; 10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project a2dp_dev->output = out; 10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10693e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_open_ctrl_path(&out->common); 10703e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (out->common.ctrl_fd == AUDIO_SKT_DISCONNECTED) 10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("ctrl socket failed to connect (%s)", strerror(errno)); 10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ret = -1; 10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project goto err_open; 10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("success"); 10788795a9a1789c4b32b7a2b99c7c09b4fb4ba3775dAnubhav Gupta /* Delay to ensure Headset is in proper state when START is initiated 10798795a9a1789c4b32b7a2b99c7c09b4fb4ba3775dAnubhav Gupta from DUT immediately after the connection due to ongoing music playback. */ 10808795a9a1789c4b32b7a2b99c7c09b4fb4ba3775dAnubhav Gupta usleep(250000); 10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 10825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecterr_open: 10845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project free(out); 10855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *stream_out = NULL; 1086e67bf20a9d9df7f8835881711439c4319fbf2d24Nitin Srivastava a2dp_dev->output = NULL; 10875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("failed"); 10885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return ret; 10895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 10905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void adev_close_output_stream(struct audio_hw_device *dev, 10925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct audio_stream_out *stream) 10935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 10945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; 10955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; 10965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10973e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("closing output (state %d)", out->common.state); 10985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1099764babe943fc2e559923c7bf8514664187808dddNitin Srivastava pthread_mutex_lock(&out->common.lock); 11003e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if ((out->common.state == AUDIO_A2DP_STATE_STARTED) || (out->common.state == AUDIO_A2DP_STATE_STOPPING)) 11013e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood stop_audio_datapath(&out->common); 11025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11033e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(out->common.ctrl_fd); 11045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project free(stream); 11055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project a2dp_dev->output = NULL; 1106764babe943fc2e559923c7bf8514664187808dddNitin Srivastava pthread_mutex_unlock(&out->common.lock); 11075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project DEBUG("done"); 11095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 11125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; 11145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_out *out = a2dp_dev->output; 11155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int retval = 0; 11165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (out == NULL) 11185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return retval; 111971ac7a776357e676c31908900d807e9f4dc26236Eric Laurent 11203e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("state %d", out->common.state); 11215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project retval = out->stream.common.set_parameters((struct audio_stream *)out, kvpairs); 11235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return retval; 11255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic char * adev_get_parameters(const struct audio_hw_device *dev, 11285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project const char *keys) 11295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct str_parms *parms; 11315cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(dev); 11325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 11345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project parms = str_parms_create_str(keys); 11365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project str_parms_dump(parms); 11385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project str_parms_destroy(parms); 11405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return strdup(""); 11425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_init_check(const struct audio_hw_device *dev) 11455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device*)dev; 11475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 11495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 11515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 11545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11555cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(dev); 11565cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(volume); 11575cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 11585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 11595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOSYS; 11615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_set_master_volume(struct audio_hw_device *dev, float volume) 11645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11655cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(dev); 11665cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(volume); 11675cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 11685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 11695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOSYS; 11715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_set_mode(struct audio_hw_device *dev, int mode) 11745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11755cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(dev); 11765cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(mode); 11775cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 11785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 11795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 11815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 11845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11855cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(dev); 11865cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(state); 11875cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 11885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 11895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOSYS; 11915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 11925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 11935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 11945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 11955cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(dev); 11965cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(state); 11975cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 11985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 11995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOSYS; 12015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 12025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 12045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project const struct audio_config *config) 12055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 12065cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(dev); 12075cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(config); 12085cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 12095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 12105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 320; 12125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 12135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_open_input_stream(struct audio_hw_device *dev, 12155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project audio_io_handle_t handle, 12165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project audio_devices_t devices, 12175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct audio_config *config, 121885f2cd2474077511105c1251a0a5a957c7f78669Glenn Kasten struct audio_stream_in **stream_in, 12198c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge audio_input_flags_t flags, 12208c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge const char *address, 12218c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge audio_source_t source) 12225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 12233e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; 12245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_stream_in *in; 12255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ret; 12268c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge UNUSED(address); 12275cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(config); 12288c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge UNUSED(devices); 12298c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge UNUSED(flags); 12308c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge UNUSED(handle); 12318c0d3947e3b65a4cc35c12729e43d8b1577306cdIan Coolidge UNUSED(source); 12325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 12345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in = (struct a2dp_stream_in *)calloc(1, sizeof(struct a2dp_stream_in)); 12365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!in) 12385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOMEM; 12395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.get_sample_rate = in_get_sample_rate; 12415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.set_sample_rate = in_set_sample_rate; 12425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.get_buffer_size = in_get_buffer_size; 12435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.get_channels = in_get_channels; 12445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.get_format = in_get_format; 12455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.set_format = in_set_format; 12465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.standby = in_standby; 12475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.dump = in_dump; 12485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.set_parameters = in_set_parameters; 12495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.get_parameters = in_get_parameters; 12505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.add_audio_effect = in_add_audio_effect; 12515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.common.remove_audio_effect = in_remove_audio_effect; 12525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.set_gain = in_set_gain; 12535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.read = in_read; 12545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project in->stream.get_input_frames_lost = in_get_input_frames_lost; 12555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12563e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood /* initialize a2dp specifics */ 12573e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_stream_common_init(&in->common); 12583e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 12595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *stream_in = &in->stream; 12603e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_dev->input = in; 12613e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 12623e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_open_ctrl_path(&in->common); 12633e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (in->common.ctrl_fd == AUDIO_SKT_DISCONNECTED) 12643e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood { 12653e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("ctrl socket failed to connect (%s)", strerror(errno)); 12663e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ret = -1; 12673e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood goto err_open; 12683e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 12693e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 12703e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if (a2dp_read_audio_config(&in->common) < 0) { 12713e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("a2dp_read_audio_config failed (%s)", strerror(errno)); 12723e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ret = -1; 12733e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood goto err_open; 12743e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood } 12753e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 12763e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("success"); 12775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 12785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecterr_open: 12805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project free(in); 12815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *stream_in = NULL; 12823e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_dev->input = NULL; 12833e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood ERROR("failed"); 12845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return ret; 12855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 12865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void adev_close_input_stream(struct audio_hw_device *dev, 12883e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct audio_stream_in *stream) 12895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 12903e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; 12913e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood struct a2dp_stream_in* in = (struct a2dp_stream_in *)stream; 12923e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_state_t state = in->common.state; 12935cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 12943e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood INFO("closing input (state %d)", state); 12953e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 12963e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood if ((state == AUDIO_A2DP_STATE_STARTED) || (state == AUDIO_A2DP_STATE_STOPPING)) 12973e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood stop_audio_datapath(&in->common); 12985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 12993e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood skt_disconnect(in->common.ctrl_fd); 13003e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood free(stream); 13013e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood a2dp_dev->input = NULL; 13023e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood 13033e8a242fcbeebea2857fa964ca48624d8433333eMike Lockwood DEBUG("done"); 13045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 13055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_dump(const audio_hw_device_t *device, int fd) 13075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 13085cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(device); 13095cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen UNUSED(fd); 13105cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen 13115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 13125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 13145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 13155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_close(hw_device_t *device) 13175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 13185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 13195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project free(device); 13215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 13225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 13235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int adev_open(const hw_module_t* module, const char* name, 13255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project hw_device_t** device) 13265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 13275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct a2dp_audio_device *adev; 13285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ret; 13295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project INFO(" adev_open in A2dp_hw module"); 13315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project FNLOG(); 13325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) 13345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 13355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE); 13365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -EINVAL; 13375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 13385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev = calloc(1, sizeof(struct a2dp_audio_device)); 13405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (!adev) 13425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -ENOMEM; 13435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.common.tag = HARDWARE_DEVICE_TAG; 13459a445034f27ed64b46ae7f2914e6c1804a98716dEric Laurent adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; 13465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.common.module = (struct hw_module_t *) module; 13475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.common.close = adev_close; 13485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.init_check = adev_init_check; 13505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.set_voice_volume = adev_set_voice_volume; 13515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.set_master_volume = adev_set_master_volume; 13525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.set_mode = adev_set_mode; 13535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.set_mic_mute = adev_set_mic_mute; 13545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.get_mic_mute = adev_get_mic_mute; 13555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.set_parameters = adev_set_parameters; 13565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.get_parameters = adev_get_parameters; 13575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.get_input_buffer_size = adev_get_input_buffer_size; 13585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.open_output_stream = adev_open_output_stream; 13595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.close_output_stream = adev_close_output_stream; 13605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.open_input_stream = adev_open_input_stream; 13615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.close_input_stream = adev_close_input_stream; 13625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->device.dump = adev_dump; 13635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project adev->output = NULL; 13655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *device = &adev->device.common; 13685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 13705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 13715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic struct hw_module_methods_t hal_module_methods = { 13735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .open = adev_open, 13745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 13755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 13765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstruct audio_module HAL_MODULE_INFO_SYM = { 13775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .common = { 13785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .tag = HARDWARE_MODULE_TAG, 13795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .version_major = 1, 13805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .version_minor = 0, 13815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .id = AUDIO_HARDWARE_MODULE_ID, 13825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .name = "A2DP Audio HW HAL", 13835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .author = "The Android Open Source Project", 13845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project .methods = &hal_module_methods, 13855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project }, 13865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 1387