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