Home | History | Annotate | Download | only in audio_a2dp_hw
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2009-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /*****************************************************************************
     20  *
     21  *  Filename:      audio_a2dp_hw.c
     22  *
     23  *  Description:   Implements hal for bluedroid a2dp audio device
     24  *
     25  *****************************************************************************/
     26 
     27 #include <errno.h>
     28 #include <pthread.h>
     29 #include <stdint.h>
     30 #include <sys/time.h>
     31 #include <sys/socket.h>
     32 #include <sys/un.h>
     33 #include <sys/poll.h>
     34 #include <sys/errno.h>
     35 #include <sys/stat.h>
     36 #include <unistd.h>
     37 #include <fcntl.h>
     38 #include <cutils/str_parms.h>
     39 #include <cutils/sockets.h>
     40 
     41 #include <system/audio.h>
     42 #include <hardware/audio.h>
     43 
     44 #include <hardware/hardware.h>
     45 #include "audio_a2dp_hw.h"
     46 
     47 #define LOG_TAG "audio_a2dp_hw"
     48 /* #define LOG_NDEBUG 0 */
     49 #include <cutils/log.h>
     50 
     51 /*****************************************************************************
     52 **  Constants & Macros
     53 ******************************************************************************/
     54 
     55 #define CTRL_CHAN_RETRY_COUNT 3
     56 #define USEC_PER_SEC 1000000L
     57 
     58 #define CASE_RETURN_STR(const) case const: return #const;
     59 
     60 #define FNLOG()             ALOGV("%s", __FUNCTION__);
     61 #define DEBUG(fmt, ...)     ALOGV("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
     62 #define INFO(fmt, ...)      ALOGI("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
     63 #define ERROR(fmt, ...)     ALOGE("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
     64 
     65 #define ASSERTC(cond, msg, val) if (!(cond)) {ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
     66 
     67 /*****************************************************************************
     68 **  Local type definitions
     69 ******************************************************************************/
     70 
     71 typedef enum {
     72     AUDIO_A2DP_STATE_STARTING,
     73     AUDIO_A2DP_STATE_STARTED,
     74     AUDIO_A2DP_STATE_STOPPING,
     75     AUDIO_A2DP_STATE_STOPPED,
     76     AUDIO_A2DP_STATE_SUSPENDED, /* need explicit set param call to resume (suspend=false) */
     77     AUDIO_A2DP_STATE_STANDBY    /* allows write to autoresume */
     78 } a2dp_state_t;
     79 
     80 struct a2dp_stream_out;
     81 
     82 struct a2dp_audio_device {
     83     struct audio_hw_device device;
     84     struct a2dp_stream_out *output;
     85 };
     86 
     87 struct a2dp_config {
     88     uint32_t                rate;
     89     uint32_t                channel_flags;
     90     int                     format;
     91 };
     92 
     93 /* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
     94 
     95 struct a2dp_stream_out {
     96     struct audio_stream_out stream;
     97     pthread_mutex_t         lock;
     98     int                     ctrl_fd;
     99     int                     audio_fd;
    100     size_t                  buffer_sz;
    101     a2dp_state_t            state;
    102     struct a2dp_config      cfg;
    103 };
    104 
    105 struct a2dp_stream_in {
    106     struct audio_stream_in stream;
    107 };
    108 
    109 /*****************************************************************************
    110 **  Static variables
    111 ******************************************************************************/
    112 
    113 /*****************************************************************************
    114 **  Static functions
    115 ******************************************************************************/
    116 
    117 static size_t out_get_buffer_size(const struct audio_stream *stream);
    118 
    119 /*****************************************************************************
    120 **  Externs
    121 ******************************************************************************/
    122 
    123 /*****************************************************************************
    124 **  Functions
    125 ******************************************************************************/
    126 
    127 /*****************************************************************************
    128 **   Miscellaneous helper functions
    129 ******************************************************************************/
    130 
    131 static const char* dump_a2dp_ctrl_event(char event)
    132 {
    133     switch(event)
    134     {
    135         CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
    136         CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
    137         CASE_RETURN_STR(A2DP_CTRL_CMD_START)
    138         CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
    139         CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
    140         default:
    141             return "UNKNOWN MSG ID";
    142     }
    143 }
    144 
    145 /* logs timestamp with microsec precision
    146    pprev is optional in case a dedicated diff is required */
    147 static void ts_log(char *tag, int val, struct timespec *pprev_opt)
    148 {
    149     struct timespec now;
    150     static struct timespec prev = {0,0};
    151     unsigned long long now_us;
    152     unsigned long long diff_us;
    153 
    154     clock_gettime(CLOCK_MONOTONIC, &now);
    155 
    156     now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
    157 
    158     if (pprev_opt)
    159     {
    160         diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
    161         *pprev_opt = now;
    162         DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
    163     }
    164     else
    165     {
    166         diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
    167         prev = now;
    168         DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
    169     }
    170 }
    171 
    172 static int calc_audiotime(struct a2dp_config cfg, int bytes)
    173 {
    174     int chan_count = popcount(cfg.channel_flags);
    175 
    176     ASSERTC(cfg.format == AUDIO_FORMAT_PCM_16_BIT,
    177             "unsupported sample sz", cfg.format);
    178 
    179     return bytes*(1000000/(chan_count*2))/cfg.rate;
    180 }
    181 
    182 /*****************************************************************************
    183 **
    184 **   bluedroid stack adaptation
    185 **
    186 *****************************************************************************/
    187 
    188 static int skt_connect(struct a2dp_stream_out *out, char *path)
    189 {
    190     int ret;
    191     int skt_fd;
    192     struct sockaddr_un remote;
    193     int len;
    194 
    195     INFO("connect to %s (sz %d)", path, out->buffer_sz);
    196 
    197     skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
    198 
    199     if(socket_local_client_connect(skt_fd, path,
    200             ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
    201     {
    202         ERROR("failed to connect (%s)", strerror(errno));
    203         close(skt_fd);
    204         return -1;
    205     }
    206 
    207     len = out->buffer_sz;
    208     ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
    209 
    210     /* only issue warning if failed */
    211     if (ret < 0)
    212         ERROR("setsockopt failed (%s)", strerror(errno));
    213 
    214     INFO("connected to stack fd = %d", skt_fd);
    215 
    216     return skt_fd;
    217 }
    218 
    219 static int skt_write(int fd, const void *p, size_t len)
    220 {
    221     int sent;
    222     struct pollfd pfd;
    223 
    224     FNLOG();
    225 
    226     pfd.fd = fd;
    227     pfd.events = POLLOUT;
    228 
    229     /* poll for 500 ms */
    230 
    231     /* send time out */
    232     if (poll(&pfd, 1, 500) == 0)
    233         return 0;
    234 
    235     ts_log("skt_write", len, NULL);
    236 
    237     if ((sent = send(fd, p, len, MSG_NOSIGNAL)) == -1)
    238     {
    239         ERROR("write failed with errno=%d\n", errno);
    240         return -1;
    241     }
    242 
    243     return sent;
    244 }
    245 
    246 static int skt_disconnect(int fd)
    247 {
    248     INFO("fd %d", fd);
    249 
    250     if (fd != AUDIO_SKT_DISCONNECTED)
    251     {
    252         shutdown(fd, SHUT_RDWR);
    253         close(fd);
    254     }
    255     return 0;
    256 }
    257 
    258 
    259 
    260 /*****************************************************************************
    261 **
    262 **  AUDIO CONTROL PATH
    263 **
    264 *****************************************************************************/
    265 
    266 static int a2dp_command(struct a2dp_stream_out *out, char cmd)
    267 {
    268     char ack;
    269 
    270     DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd));
    271 
    272     /* send command */
    273     if (send(out->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1)
    274     {
    275         ERROR("cmd failed (%s)", strerror(errno));
    276         skt_disconnect(out->ctrl_fd);
    277         out->ctrl_fd = AUDIO_SKT_DISCONNECTED;
    278         return -1;
    279     }
    280 
    281     /* wait for ack byte */
    282     if (recv(out->ctrl_fd, &ack, 1, MSG_NOSIGNAL) < 0)
    283     {
    284         ERROR("ack failed (%s)", strerror(errno));
    285         skt_disconnect(out->ctrl_fd);
    286         out->ctrl_fd = AUDIO_SKT_DISCONNECTED;
    287         return -1;
    288     }
    289 
    290     DEBUG("A2DP COMMAND %s DONE STATUS %d", dump_a2dp_ctrl_event(cmd), ack);
    291 
    292     if (ack != A2DP_CTRL_ACK_SUCCESS)
    293         return -1;
    294 
    295     return 0;
    296 }
    297 
    298 /*****************************************************************************
    299 **
    300 ** AUDIO DATA PATH
    301 **
    302 *****************************************************************************/
    303 
    304 static void a2dp_stream_out_init(struct a2dp_stream_out *out)
    305 {
    306     pthread_mutexattr_t lock_attr;
    307 
    308     FNLOG();
    309 
    310     pthread_mutexattr_init(&lock_attr);
    311     pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
    312     pthread_mutex_init(&out->lock, &lock_attr);
    313 
    314     out->ctrl_fd = AUDIO_SKT_DISCONNECTED;
    315     out->audio_fd = AUDIO_SKT_DISCONNECTED;
    316     out->state = AUDIO_A2DP_STATE_STOPPED;
    317 
    318     out->cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG;
    319     out->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
    320     out->cfg.rate = AUDIO_STREAM_DEFAULT_RATE;
    321 
    322     /* manages max capacity of socket pipe */
    323     out->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
    324 }
    325 
    326 static int start_audio_datapath(struct a2dp_stream_out *out)
    327 {
    328     int oldstate = out->state;
    329 
    330     INFO("state %d", out->state);
    331 
    332     if (out->ctrl_fd == AUDIO_SKT_DISCONNECTED)
    333         return -1;
    334 
    335     out->state = AUDIO_A2DP_STATE_STARTING;
    336 
    337     if (a2dp_command(out, A2DP_CTRL_CMD_START) < 0)
    338     {
    339         ERROR("audiopath start failed");
    340 
    341         out->state = oldstate;
    342         return -1;
    343     }
    344 
    345     /* connect socket if not yet connected */
    346     if (out->audio_fd == AUDIO_SKT_DISCONNECTED)
    347     {
    348         out->audio_fd = skt_connect(out, A2DP_DATA_PATH);
    349 
    350         if (out->audio_fd < 0)
    351         {
    352             out->state = oldstate;
    353             return -1;
    354         }
    355 
    356         out->state = AUDIO_A2DP_STATE_STARTED;
    357     }
    358 
    359     return 0;
    360 }
    361 
    362 
    363 static int stop_audio_datapath(struct a2dp_stream_out *out)
    364 {
    365     int oldstate = out->state;
    366 
    367     INFO("state %d", out->state);
    368 
    369     if (out->ctrl_fd == AUDIO_SKT_DISCONNECTED)
    370          return -1;
    371 
    372     /* prevent any stray output writes from autostarting the stream
    373        while stopping audiopath */
    374     out->state = AUDIO_A2DP_STATE_STOPPING;
    375 
    376     if (a2dp_command(out, A2DP_CTRL_CMD_STOP) < 0)
    377     {
    378         ERROR("audiopath stop failed");
    379         out->state = oldstate;
    380         return -1;
    381     }
    382 
    383     out->state = AUDIO_A2DP_STATE_STOPPED;
    384 
    385     /* disconnect audio path */
    386     skt_disconnect(out->audio_fd);
    387     out->audio_fd = AUDIO_SKT_DISCONNECTED;
    388 
    389     return 0;
    390 }
    391 
    392 static int suspend_audio_datapath(struct a2dp_stream_out *out, bool standby)
    393 {
    394     INFO("state %d", out->state);
    395 
    396     if (out->ctrl_fd == AUDIO_SKT_DISCONNECTED)
    397          return -1;
    398 
    399     if (out->state == AUDIO_A2DP_STATE_STOPPING)
    400         return -1;
    401 
    402     if (a2dp_command(out, A2DP_CTRL_CMD_SUSPEND) < 0)
    403         return -1;
    404 
    405     if (standby)
    406         out->state = AUDIO_A2DP_STATE_STANDBY;
    407     else
    408         out->state = AUDIO_A2DP_STATE_SUSPENDED;
    409 
    410     /* disconnect audio path */
    411     skt_disconnect(out->audio_fd);
    412 
    413     out->audio_fd = AUDIO_SKT_DISCONNECTED;
    414 
    415     return 0;
    416 }
    417 
    418 static int check_a2dp_ready(struct a2dp_stream_out *out)
    419 {
    420     INFO("state %d", out->state);
    421 
    422     if (a2dp_command(out, A2DP_CTRL_CMD_CHECK_READY) < 0)
    423     {
    424         ERROR("check a2dp ready failed");
    425         return -1;
    426     }
    427     return 0;
    428 }
    429 
    430 
    431 /*****************************************************************************
    432 **
    433 **  audio output callbacks
    434 **
    435 *****************************************************************************/
    436 
    437 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
    438                          size_t bytes)
    439 {
    440     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    441     int sent;
    442 
    443     DEBUG("write %d bytes (fd %d)", bytes, out->audio_fd);
    444 
    445     if (out->state == AUDIO_A2DP_STATE_SUSPENDED)
    446     {
    447         DEBUG("stream suspended");
    448         return -1;
    449     }
    450 
    451     /* only allow autostarting if we are in stopped or standby */
    452     if ((out->state == AUDIO_A2DP_STATE_STOPPED) ||
    453         (out->state == AUDIO_A2DP_STATE_STANDBY))
    454     {
    455         pthread_mutex_lock(&out->lock);
    456 
    457         if (start_audio_datapath(out) < 0)
    458         {
    459             /* emulate time this write represents to avoid very fast write
    460                failures during transition periods or remote suspend */
    461 
    462             int us_delay = calc_audiotime(out->cfg, bytes);
    463 
    464             DEBUG("emulate a2dp write delay (%d us)", us_delay);
    465 
    466             usleep(us_delay);
    467             pthread_mutex_unlock(&out->lock);
    468             return -1;
    469         }
    470 
    471         pthread_mutex_unlock(&out->lock);
    472     }
    473     else if (out->state != AUDIO_A2DP_STATE_STARTED)
    474     {
    475         ERROR("stream not in stopped or standby");
    476         return -1;
    477     }
    478 
    479     sent = skt_write(out->audio_fd, buffer,  bytes);
    480 
    481     if (sent == -1)
    482     {
    483         skt_disconnect(out->audio_fd);
    484         out->audio_fd = AUDIO_SKT_DISCONNECTED;
    485         out->state = AUDIO_A2DP_STATE_STOPPED;
    486     }
    487 
    488     DEBUG("wrote %d bytes out of %d bytes", sent, bytes);
    489     return sent;
    490 }
    491 
    492 
    493 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
    494 {
    495     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    496 
    497     DEBUG("rate %d", out->cfg.rate);
    498 
    499     return out->cfg.rate;
    500 }
    501 
    502 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
    503 {
    504     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    505 
    506     DEBUG("out_set_sample_rate : %d", rate);
    507 
    508     if (rate != AUDIO_STREAM_DEFAULT_RATE)
    509     {
    510         ERROR("only rate %d supported", AUDIO_STREAM_DEFAULT_RATE);
    511         return -1;
    512     }
    513 
    514     out->cfg.rate = rate;
    515 
    516     return 0;
    517 }
    518 
    519 static size_t out_get_buffer_size(const struct audio_stream *stream)
    520 {
    521     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    522 
    523     DEBUG("buffer_size : %d", out->buffer_sz);
    524 
    525     return out->buffer_sz;
    526 }
    527 
    528 static uint32_t out_get_channels(const struct audio_stream *stream)
    529 {
    530     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    531 
    532     DEBUG("channels 0x%x", out->cfg.channel_flags);
    533 
    534     return out->cfg.channel_flags;
    535 }
    536 
    537 static audio_format_t out_get_format(const struct audio_stream *stream)
    538 {
    539     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    540     DEBUG("format 0x%x", out->cfg.format);
    541     return out->cfg.format;
    542 }
    543 
    544 static int out_set_format(struct audio_stream *stream, audio_format_t format)
    545 {
    546     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    547     DEBUG("setting format not yet supported (0x%x)", format);
    548     return -ENOSYS;
    549 }
    550 
    551 static int out_standby(struct audio_stream *stream)
    552 {
    553     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    554     int retval = 0;
    555 
    556     int retVal = 0;
    557 
    558     FNLOG();
    559 
    560     pthread_mutex_lock(&out->lock);
    561 
    562     if (out->state == AUDIO_A2DP_STATE_STARTED)
    563         retVal =  suspend_audio_datapath(out, true);
    564     else
    565         retVal = 0;
    566     pthread_mutex_unlock (&out->lock);
    567 
    568     return retVal;
    569 }
    570 
    571 static int out_dump(const struct audio_stream *stream, int fd)
    572 {
    573     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    574     FNLOG();
    575     return 0;
    576 }
    577 
    578 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
    579 {
    580     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    581     struct str_parms *parms;
    582     char keyval[16];
    583     int retval = 0;
    584 
    585     INFO("state %d", out->state);
    586 
    587     pthread_mutex_lock(&out->lock);
    588 
    589     parms = str_parms_create_str(kvpairs);
    590 
    591     /* dump params */
    592     str_parms_dump(parms);
    593 
    594     retval = str_parms_get_str(parms, "closing", keyval, sizeof(keyval));
    595 
    596     if (retval >= 0)
    597     {
    598         if (strcmp(keyval, "true") == 0)
    599         {
    600             DEBUG("stream closing, disallow any writes");
    601             out->state = AUDIO_A2DP_STATE_STOPPING;
    602         }
    603     }
    604 
    605     retval = str_parms_get_str(parms, "A2dpSuspended", keyval, sizeof(keyval));
    606 
    607     if (retval >= 0)
    608     {
    609         if (strcmp(keyval, "true") == 0)
    610         {
    611             if (out->state == AUDIO_A2DP_STATE_STARTED)
    612                 retval = suspend_audio_datapath(out, false);
    613         }
    614         else
    615         {
    616             /* Do not start the streaming automatically. If the phone was streaming
    617              * prior to being suspended, the next out_write shall trigger the
    618              * AVDTP start procedure */
    619             if (out->state == AUDIO_A2DP_STATE_SUSPENDED)
    620                 out->state = AUDIO_A2DP_STATE_STANDBY;
    621             /* Irrespective of the state, return 0 */
    622             retval = 0;
    623         }
    624     }
    625 
    626     pthread_mutex_unlock(&out->lock);
    627     str_parms_destroy(parms);
    628 
    629     return retval;
    630 }
    631 
    632 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
    633 {
    634     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    635 
    636     FNLOG();
    637 
    638     /* add populating param here */
    639 
    640     return strdup("");
    641 }
    642 
    643 static uint32_t out_get_latency(const struct audio_stream_out *stream)
    644 {
    645     int latency_us;
    646 
    647     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    648 
    649     FNLOG();
    650 
    651     latency_us = ((out->buffer_sz * 1000 ) /
    652                     audio_stream_frame_size(&out->stream.common) /
    653                     out->cfg.rate) * 1000;
    654 
    655 
    656     return (latency_us / 1000) + 200;
    657 }
    658 
    659 static int out_set_volume(struct audio_stream_out *stream, float left,
    660                           float right)
    661 {
    662     FNLOG();
    663 
    664     /* volume controlled in audioflinger mixer (digital) */
    665 
    666     return -ENOSYS;
    667 }
    668 
    669 
    670 
    671 static int out_get_render_position(const struct audio_stream_out *stream,
    672                                    uint32_t *dsp_frames)
    673 {
    674     FNLOG();
    675     return -EINVAL;
    676 }
    677 
    678 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    679 {
    680     FNLOG();
    681     return 0;
    682 }
    683 
    684 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    685 {
    686     FNLOG();
    687     return 0;
    688 }
    689 
    690 /*
    691  * AUDIO INPUT STREAM
    692  */
    693 
    694 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
    695 {
    696     FNLOG();
    697     return 8000;
    698 }
    699 
    700 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
    701 {
    702     FNLOG();
    703     return 0;
    704 }
    705 
    706 static size_t in_get_buffer_size(const struct audio_stream *stream)
    707 {
    708     FNLOG();
    709     return 320;
    710 }
    711 
    712 static uint32_t in_get_channels(const struct audio_stream *stream)
    713 {
    714     FNLOG();
    715     return AUDIO_CHANNEL_IN_MONO;
    716 }
    717 
    718 static audio_format_t in_get_format(const struct audio_stream *stream)
    719 {
    720     FNLOG();
    721     return AUDIO_FORMAT_PCM_16_BIT;
    722 }
    723 
    724 static int in_set_format(struct audio_stream *stream, audio_format_t format)
    725 {
    726     FNLOG();
    727     return 0;
    728 }
    729 
    730 static int in_standby(struct audio_stream *stream)
    731 {
    732     FNLOG();
    733     return 0;
    734 }
    735 
    736 static int in_dump(const struct audio_stream *stream, int fd)
    737 {
    738     FNLOG();
    739     return 0;
    740 }
    741 
    742 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
    743 {
    744     FNLOG();
    745     return 0;
    746 }
    747 
    748 static char * in_get_parameters(const struct audio_stream *stream,
    749                                 const char *keys)
    750 {
    751     FNLOG();
    752     return strdup("");
    753 }
    754 
    755 static int in_set_gain(struct audio_stream_in *stream, float gain)
    756 {
    757     FNLOG();
    758     return 0;
    759 }
    760 
    761 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
    762                        size_t bytes)
    763 {
    764     FNLOG();
    765     return bytes;
    766 }
    767 
    768 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
    769 {
    770     FNLOG();
    771     return 0;
    772 }
    773 
    774 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    775 {
    776     FNLOG();
    777     return 0;
    778 }
    779 
    780 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    781 {
    782     FNLOG();
    783 
    784     return 0;
    785 }
    786 
    787 static int adev_open_output_stream(struct audio_hw_device *dev,
    788                                    audio_io_handle_t handle,
    789                                    audio_devices_t devices,
    790                                    audio_output_flags_t flags,
    791                                    struct audio_config *config,
    792                                    struct audio_stream_out **stream_out)
    793 
    794 {
    795     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
    796     struct a2dp_stream_out *out;
    797     int ret = 0;
    798     int i;
    799 
    800     INFO("opening output");
    801 
    802     out = (struct a2dp_stream_out *)calloc(1, sizeof(struct a2dp_stream_out));
    803 
    804     if (!out)
    805         return -ENOMEM;
    806 
    807     out->stream.common.get_sample_rate = out_get_sample_rate;
    808     out->stream.common.set_sample_rate = out_set_sample_rate;
    809     out->stream.common.get_buffer_size = out_get_buffer_size;
    810     out->stream.common.get_channels = out_get_channels;
    811     out->stream.common.get_format = out_get_format;
    812     out->stream.common.set_format = out_set_format;
    813     out->stream.common.standby = out_standby;
    814     out->stream.common.dump = out_dump;
    815     out->stream.common.set_parameters = out_set_parameters;
    816     out->stream.common.get_parameters = out_get_parameters;
    817     out->stream.common.add_audio_effect = out_add_audio_effect;
    818     out->stream.common.remove_audio_effect = out_remove_audio_effect;
    819     out->stream.get_latency = out_get_latency;
    820     out->stream.set_volume = out_set_volume;
    821     out->stream.write = out_write;
    822     out->stream.get_render_position = out_get_render_position;
    823 
    824     /* initialize a2dp specifics */
    825     a2dp_stream_out_init(out);
    826 
    827    /* set output config values */
    828    if (config)
    829    {
    830       config->format = out_get_format((const struct audio_stream *)&out->stream);
    831       config->sample_rate = out_get_sample_rate((const struct audio_stream *)&out->stream);
    832       config->channel_mask = out_get_channels((const struct audio_stream *)&out->stream);
    833    }
    834     *stream_out = &out->stream;
    835     a2dp_dev->output = out;
    836 
    837     /* retry logic to catch any timing variations on control channel */
    838     for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++)
    839     {
    840         /* connect control channel if not already connected */
    841         if ((out->ctrl_fd = skt_connect(out, A2DP_CTRL_PATH)) > 0)
    842         {
    843             /* success, now check if stack is ready */
    844             if (check_a2dp_ready(out) == 0)
    845                 break;
    846 
    847             ERROR("error : a2dp not ready, wait 250 ms and retry");
    848             usleep(250000);
    849             skt_disconnect(out->ctrl_fd);
    850         }
    851 
    852         /* ctrl channel not ready, wait a bit */
    853         usleep(250000);
    854     }
    855 
    856     if (out->ctrl_fd == AUDIO_SKT_DISCONNECTED)
    857     {
    858         ERROR("ctrl socket failed to connect (%s)", strerror(errno));
    859         ret = -1;
    860         goto err_open;
    861     }
    862 
    863     DEBUG("success");
    864     return 0;
    865 
    866 err_open:
    867     free(out);
    868     *stream_out = NULL;
    869     ERROR("failed");
    870     return ret;
    871 }
    872 
    873 static void adev_close_output_stream(struct audio_hw_device *dev,
    874                                      struct audio_stream_out *stream)
    875 {
    876     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
    877     struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
    878 
    879     INFO("closing output (state %d)", out->state);
    880 
    881     if ((out->state == AUDIO_A2DP_STATE_STARTED) || (out->state == AUDIO_A2DP_STATE_STOPPING))
    882         stop_audio_datapath(out);
    883 
    884     skt_disconnect(out->ctrl_fd);
    885     free(stream);
    886     a2dp_dev->output = NULL;
    887 
    888     DEBUG("done");
    889 }
    890 
    891 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
    892 {
    893     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
    894     struct a2dp_stream_out *out = a2dp_dev->output;
    895     int retval = 0;
    896 
    897     if (out == NULL)
    898         return retval;
    899 
    900     INFO("state %d", out->state);
    901 
    902     retval = out->stream.common.set_parameters((struct audio_stream *)out, kvpairs);
    903 
    904     return retval;
    905 }
    906 
    907 static char * adev_get_parameters(const struct audio_hw_device *dev,
    908                                   const char *keys)
    909 {
    910     struct str_parms *parms;
    911 
    912     FNLOG();
    913 
    914     parms = str_parms_create_str(keys);
    915 
    916     str_parms_dump(parms);
    917 
    918     str_parms_destroy(parms);
    919 
    920     return strdup("");
    921 }
    922 
    923 static int adev_init_check(const struct audio_hw_device *dev)
    924 {
    925     struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device*)dev;
    926 
    927     FNLOG();
    928 
    929     return 0;
    930 }
    931 
    932 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
    933 {
    934     FNLOG();
    935 
    936     return -ENOSYS;
    937 }
    938 
    939 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
    940 {
    941     FNLOG();
    942 
    943     return -ENOSYS;
    944 }
    945 
    946 static int adev_set_mode(struct audio_hw_device *dev, int mode)
    947 {
    948     FNLOG();
    949 
    950     return 0;
    951 }
    952 
    953 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
    954 {
    955     FNLOG();
    956 
    957     return -ENOSYS;
    958 }
    959 
    960 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
    961 {
    962     FNLOG();
    963 
    964     return -ENOSYS;
    965 }
    966 
    967 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
    968                                          const struct audio_config *config)
    969 {
    970     FNLOG();
    971 
    972     return 320;
    973 }
    974 
    975 static int adev_open_input_stream(struct audio_hw_device *dev,
    976                                   audio_io_handle_t handle,
    977                                   audio_devices_t devices,
    978                                   struct audio_config *config,
    979                                   struct audio_stream_in **stream_in)
    980 {
    981     struct a2dp_audio_device *ladev = (struct a2dp_audio_device *)dev;
    982     struct a2dp_stream_in *in;
    983     int ret;
    984 
    985     FNLOG();
    986 
    987     in = (struct a2dp_stream_in *)calloc(1, sizeof(struct a2dp_stream_in));
    988 
    989     if (!in)
    990         return -ENOMEM;
    991 
    992     in->stream.common.get_sample_rate = in_get_sample_rate;
    993     in->stream.common.set_sample_rate = in_set_sample_rate;
    994     in->stream.common.get_buffer_size = in_get_buffer_size;
    995     in->stream.common.get_channels = in_get_channels;
    996     in->stream.common.get_format = in_get_format;
    997     in->stream.common.set_format = in_set_format;
    998     in->stream.common.standby = in_standby;
    999     in->stream.common.dump = in_dump;
   1000     in->stream.common.set_parameters = in_set_parameters;
   1001     in->stream.common.get_parameters = in_get_parameters;
   1002     in->stream.common.add_audio_effect = in_add_audio_effect;
   1003     in->stream.common.remove_audio_effect = in_remove_audio_effect;
   1004     in->stream.set_gain = in_set_gain;
   1005     in->stream.read = in_read;
   1006     in->stream.get_input_frames_lost = in_get_input_frames_lost;
   1007 
   1008     *stream_in = &in->stream;
   1009     return 0;
   1010 
   1011 err_open:
   1012     free(in);
   1013     *stream_in = NULL;
   1014     return ret;
   1015 }
   1016 
   1017 static void adev_close_input_stream(struct audio_hw_device *dev,
   1018                                    struct audio_stream_in *in)
   1019 {
   1020     FNLOG();
   1021 
   1022     return;
   1023 }
   1024 
   1025 static int adev_dump(const audio_hw_device_t *device, int fd)
   1026 {
   1027     FNLOG();
   1028 
   1029     return 0;
   1030 }
   1031 
   1032 static int adev_close(hw_device_t *device)
   1033 {
   1034     FNLOG();
   1035 
   1036     free(device);
   1037     return 0;
   1038 }
   1039 
   1040 static int adev_open(const hw_module_t* module, const char* name,
   1041                      hw_device_t** device)
   1042 {
   1043     struct a2dp_audio_device *adev;
   1044     int ret;
   1045 
   1046     INFO(" adev_open in A2dp_hw module");
   1047     FNLOG();
   1048 
   1049     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
   1050     {
   1051         ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
   1052         return -EINVAL;
   1053     }
   1054 
   1055     adev = calloc(1, sizeof(struct a2dp_audio_device));
   1056 
   1057     if (!adev)
   1058         return -ENOMEM;
   1059 
   1060     adev->device.common.tag = HARDWARE_DEVICE_TAG;
   1061     adev->device.common.version = AUDIO_DEVICE_API_VERSION_CURRENT;
   1062     adev->device.common.module = (struct hw_module_t *) module;
   1063     adev->device.common.close = adev_close;
   1064 
   1065     adev->device.init_check = adev_init_check;
   1066     adev->device.set_voice_volume = adev_set_voice_volume;
   1067     adev->device.set_master_volume = adev_set_master_volume;
   1068     adev->device.set_mode = adev_set_mode;
   1069     adev->device.set_mic_mute = adev_set_mic_mute;
   1070     adev->device.get_mic_mute = adev_get_mic_mute;
   1071     adev->device.set_parameters = adev_set_parameters;
   1072     adev->device.get_parameters = adev_get_parameters;
   1073     adev->device.get_input_buffer_size = adev_get_input_buffer_size;
   1074     adev->device.open_output_stream = adev_open_output_stream;
   1075     adev->device.close_output_stream = adev_close_output_stream;
   1076     adev->device.open_input_stream = adev_open_input_stream;
   1077     adev->device.close_input_stream = adev_close_input_stream;
   1078     adev->device.dump = adev_dump;
   1079 
   1080     adev->output = NULL;
   1081 
   1082 
   1083     *device = &adev->device.common;
   1084 
   1085     return 0;
   1086 }
   1087 
   1088 static struct hw_module_methods_t hal_module_methods = {
   1089     .open = adev_open,
   1090 };
   1091 
   1092 struct audio_module HAL_MODULE_INFO_SYM = {
   1093     .common = {
   1094         .tag = HARDWARE_MODULE_TAG,
   1095         .version_major = 1,
   1096         .version_minor = 0,
   1097         .id = AUDIO_HARDWARE_MODULE_ID,
   1098         .name = "A2DP Audio HW HAL",
   1099         .author = "The Android Open Source Project",
   1100         .methods = &hal_module_methods,
   1101     },
   1102 };
   1103 
   1104