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 <inttypes.h>
29#include <pthread.h>
30#include <stdint.h>
31#include <sys/time.h>
32#include <sys/socket.h>
33#include <sys/un.h>
34#include <sys/poll.h>
35#include <sys/errno.h>
36#include <sys/stat.h>
37#include <unistd.h>
38#include <fcntl.h>
39#include <cutils/str_parms.h>
40#include <cutils/sockets.h>
41
42#include <system/audio.h>
43#include <hardware/audio.h>
44
45#include <hardware/hardware.h>
46#include "audio_a2dp_hw.h"
47#include "bt_utils.h"
48
49#define LOG_TAG "bt_a2dp_hw"
50#include "osi/include/log.h"
51
52/*****************************************************************************
53**  Constants & Macros
54******************************************************************************/
55
56#define CTRL_CHAN_RETRY_COUNT 3
57#define USEC_PER_SEC 1000000L
58
59#define CASE_RETURN_STR(const) case const: return #const;
60
61#define FNLOG()             LOG_VERBOSE("%s", __FUNCTION__);
62#define DEBUG(fmt, ...)     LOG_VERBOSE("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
63#define INFO(fmt, ...)      LOG_INFO("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
64#define ERROR(fmt, ...)     LOG_ERROR("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
65
66#define ASSERTC(cond, msg, val) if (!(cond)) {ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
67
68/*****************************************************************************
69**  Local type definitions
70******************************************************************************/
71
72typedef enum {
73    AUDIO_A2DP_STATE_STARTING,
74    AUDIO_A2DP_STATE_STARTED,
75    AUDIO_A2DP_STATE_STOPPING,
76    AUDIO_A2DP_STATE_STOPPED,
77    AUDIO_A2DP_STATE_SUSPENDED, /* need explicit set param call to resume (suspend=false) */
78    AUDIO_A2DP_STATE_STANDBY    /* allows write to autoresume */
79} a2dp_state_t;
80
81struct a2dp_stream_in;
82struct a2dp_stream_out;
83
84struct a2dp_audio_device {
85    struct audio_hw_device device;
86    struct a2dp_stream_in  *input;
87    struct a2dp_stream_out *output;
88};
89
90struct a2dp_config {
91    uint32_t                rate;
92    uint32_t                channel_flags;
93    int                     format;
94};
95
96/* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
97
98struct a2dp_stream_common {
99    pthread_mutex_t         lock;
100    int                     ctrl_fd;
101    int                     audio_fd;
102    size_t                  buffer_sz;
103    struct a2dp_config      cfg;
104    a2dp_state_t            state;
105};
106
107struct a2dp_stream_out {
108    struct audio_stream_out stream;
109    struct a2dp_stream_common common;
110    uint64_t frames_presented; // frames written, never reset
111    uint64_t frames_rendered;  // frames written, reset on standby
112};
113
114struct a2dp_stream_in {
115    struct audio_stream_in  stream;
116    struct a2dp_stream_common common;
117};
118
119/*****************************************************************************
120**  Static variables
121******************************************************************************/
122
123/*****************************************************************************
124**  Static functions
125******************************************************************************/
126
127static size_t out_get_buffer_size(const struct audio_stream *stream);
128
129/*****************************************************************************
130**  Externs
131******************************************************************************/
132
133/*****************************************************************************
134**  Functions
135******************************************************************************/
136
137/*****************************************************************************
138**   Miscellaneous helper functions
139******************************************************************************/
140
141static const char* dump_a2dp_ctrl_event(char event)
142{
143    switch(event)
144    {
145        CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
146        CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
147        CASE_RETURN_STR(A2DP_CTRL_CMD_START)
148        CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
149        CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
150        default:
151            return "UNKNOWN MSG ID";
152    }
153}
154
155/* logs timestamp with microsec precision
156   pprev is optional in case a dedicated diff is required */
157static void ts_log(char *tag, int val, struct timespec *pprev_opt)
158{
159    struct timespec now;
160    static struct timespec prev = {0,0};
161    unsigned long long now_us;
162    unsigned long long diff_us;
163    UNUSED(tag);
164    UNUSED(val);
165
166    clock_gettime(CLOCK_MONOTONIC, &now);
167
168    now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
169
170    if (pprev_opt)
171    {
172        diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
173        *pprev_opt = now;
174        DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
175    }
176    else
177    {
178        diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
179        prev = now;
180        DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
181    }
182}
183
184static int calc_audiotime(struct a2dp_config cfg, int bytes)
185{
186    int chan_count = popcount(cfg.channel_flags);
187
188    ASSERTC(cfg.format == AUDIO_FORMAT_PCM_16_BIT,
189            "unsupported sample sz", cfg.format);
190
191    return bytes*(1000000/(chan_count*2))/cfg.rate;
192}
193
194/*****************************************************************************
195**
196**   bluedroid stack adaptation
197**
198*****************************************************************************/
199
200static int skt_connect(char *path, size_t buffer_sz)
201{
202    int ret;
203    int skt_fd;
204    struct sockaddr_un remote;
205    int len;
206
207    INFO("connect to %s (sz %zu)", path, buffer_sz);
208
209    skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
210
211    if(socket_local_client_connect(skt_fd, path,
212            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
213    {
214        ERROR("failed to connect (%s)", strerror(errno));
215        close(skt_fd);
216        return -1;
217    }
218
219    len = buffer_sz;
220    ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
221
222    /* only issue warning if failed */
223    if (ret < 0)
224        ERROR("setsockopt failed (%s)", strerror(errno));
225
226    ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
227
228    /* only issue warning if failed */
229    if (ret < 0)
230        ERROR("setsockopt failed (%s)", strerror(errno));
231
232    INFO("connected to stack fd = %d", skt_fd);
233
234    return skt_fd;
235}
236
237static int skt_read(int fd, void *p, size_t len)
238{
239    int read;
240    struct pollfd pfd;
241    struct timespec ts;
242
243    FNLOG();
244
245    ts_log("skt_read recv", len, NULL);
246
247    if ((read = recv(fd, p, len, MSG_NOSIGNAL)) == -1)
248    {
249        ERROR("write failed with errno=%d\n", errno);
250        return -1;
251    }
252
253    return read;
254}
255
256static int skt_write(int fd, const void *p, size_t len)
257{
258    int sent;
259    struct pollfd pfd;
260
261    FNLOG();
262
263    pfd.fd = fd;
264    pfd.events = POLLOUT;
265
266    /* poll for 500 ms */
267
268    /* send time out */
269    if (poll(&pfd, 1, 500) == 0)
270        return 0;
271
272    ts_log("skt_write", len, NULL);
273
274    if ((sent = send(fd, p, len, MSG_NOSIGNAL)) == -1)
275    {
276        ERROR("write failed with errno=%d\n", errno);
277        return -1;
278    }
279
280    return sent;
281}
282
283static int skt_disconnect(int fd)
284{
285    INFO("fd %d", fd);
286
287    if (fd != AUDIO_SKT_DISCONNECTED)
288    {
289        shutdown(fd, SHUT_RDWR);
290        close(fd);
291    }
292    return 0;
293}
294
295
296
297/*****************************************************************************
298**
299**  AUDIO CONTROL PATH
300**
301*****************************************************************************/
302
303static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length)
304{
305    int ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
306    if (ret < 0)
307    {
308        ERROR("ack failed (%s)", strerror(errno));
309        if (errno == EINTR)
310        {
311            /* retry again */
312            ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
313            if (ret < 0)
314            {
315               ERROR("ack failed (%s)", strerror(errno));
316               skt_disconnect(common->ctrl_fd);
317               common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
318               return -1;
319            }
320        }
321        else
322        {
323               skt_disconnect(common->ctrl_fd);
324               common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
325               return -1;
326
327        }
328    }
329    return ret;
330}
331
332static int a2dp_command(struct a2dp_stream_common *common, char cmd)
333{
334    char ack;
335
336    DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd));
337
338    /* send command */
339    if (send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1)
340    {
341        ERROR("cmd failed (%s)", strerror(errno));
342        skt_disconnect(common->ctrl_fd);
343        common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
344        return -1;
345    }
346
347    /* wait for ack byte */
348    if (a2dp_ctrl_receive(common, &ack, 1) < 0)
349        return -1;
350
351    DEBUG("A2DP COMMAND %s DONE STATUS %d", dump_a2dp_ctrl_event(cmd), ack);
352
353    if (ack == A2DP_CTRL_ACK_INCALL_FAILURE)
354        return ack;
355    if (ack != A2DP_CTRL_ACK_SUCCESS)
356        return -1;
357
358    return 0;
359}
360
361static int check_a2dp_ready(struct a2dp_stream_common *common)
362{
363    if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0)
364    {
365        ERROR("check a2dp ready failed");
366        return -1;
367    }
368    return 0;
369}
370
371static int a2dp_read_audio_config(struct a2dp_stream_common *common)
372{
373    char cmd = A2DP_CTRL_GET_AUDIO_CONFIG;
374    uint32_t sample_rate;
375    uint8_t channel_count;
376
377    if (a2dp_command(common, A2DP_CTRL_GET_AUDIO_CONFIG) < 0)
378    {
379        ERROR("check a2dp ready failed");
380        return -1;
381    }
382
383    if (a2dp_ctrl_receive(common, &sample_rate, 4) < 0)
384        return -1;
385    if (a2dp_ctrl_receive(common, &channel_count, 1) < 0)
386        return -1;
387
388    common->cfg.channel_flags = (channel_count == 1 ? AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO);
389    common->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
390    common->cfg.rate = sample_rate;
391
392    INFO("got config %d %d", common->cfg.format, common->cfg.rate);
393
394    return 0;
395}
396
397static void a2dp_open_ctrl_path(struct a2dp_stream_common *common)
398{
399    int i;
400
401    /* retry logic to catch any timing variations on control channel */
402    for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++)
403    {
404        /* connect control channel if not already connected */
405        if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0)
406        {
407            /* success, now check if stack is ready */
408            if (check_a2dp_ready(common) == 0)
409                break;
410
411            ERROR("error : a2dp not ready, wait 250 ms and retry");
412            usleep(250000);
413            skt_disconnect(common->ctrl_fd);
414            common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
415        }
416
417        /* ctrl channel not ready, wait a bit */
418        usleep(250000);
419    }
420}
421
422/*****************************************************************************
423**
424** AUDIO DATA PATH
425**
426*****************************************************************************/
427
428static void a2dp_stream_common_init(struct a2dp_stream_common *common)
429{
430    pthread_mutexattr_t lock_attr;
431
432    FNLOG();
433
434    pthread_mutexattr_init(&lock_attr);
435    pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
436    pthread_mutex_init(&common->lock, &lock_attr);
437
438    common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
439    common->audio_fd = AUDIO_SKT_DISCONNECTED;
440    common->state = AUDIO_A2DP_STATE_STOPPED;
441
442    /* manages max capacity of socket pipe */
443    common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
444}
445
446static int start_audio_datapath(struct a2dp_stream_common *common)
447{
448    INFO("state %d", common->state);
449
450    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
451        INFO("%s AUDIO_SKT_DISCONNECTED", __func__);
452        return -1;
453    }
454
455    int oldstate = common->state;
456    common->state = AUDIO_A2DP_STATE_STARTING;
457
458    int a2dp_status = a2dp_command(common, A2DP_CTRL_CMD_START);
459    if (a2dp_status < 0)
460    {
461        ERROR("%s Audiopath start failed (status %d)", __func__, a2dp_status);
462
463        common->state = oldstate;
464        return -1;
465    }
466    else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE)
467    {
468        ERROR("%s Audiopath start failed - in call, move to suspended", __func__);
469        common->state = oldstate;
470        return -1;
471    }
472
473    /* connect socket if not yet connected */
474    if (common->audio_fd == AUDIO_SKT_DISCONNECTED)
475    {
476        common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
477        if (common->audio_fd < 0)
478        {
479            common->state = oldstate;
480            return -1;
481        }
482
483        common->state = AUDIO_A2DP_STATE_STARTED;
484    }
485
486    return 0;
487}
488
489static int stop_audio_datapath(struct a2dp_stream_common *common)
490{
491    int oldstate = common->state;
492
493    INFO("state %d", common->state);
494
495    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
496         return -1;
497
498    /* prevent any stray output writes from autostarting the stream
499       while stopping audiopath */
500    common->state = AUDIO_A2DP_STATE_STOPPING;
501
502    if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0)
503    {
504        ERROR("audiopath stop failed");
505        common->state = oldstate;
506        return -1;
507    }
508
509    common->state = AUDIO_A2DP_STATE_STOPPED;
510
511    /* disconnect audio path */
512    skt_disconnect(common->audio_fd);
513    common->audio_fd = AUDIO_SKT_DISCONNECTED;
514
515    return 0;
516}
517
518static int suspend_audio_datapath(struct a2dp_stream_common *common, bool standby)
519{
520    INFO("state %d", common->state);
521
522    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
523         return -1;
524
525    if (common->state == AUDIO_A2DP_STATE_STOPPING)
526        return -1;
527
528    if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0)
529        return -1;
530
531    if (standby)
532        common->state = AUDIO_A2DP_STATE_STANDBY;
533    else
534        common->state = AUDIO_A2DP_STATE_SUSPENDED;
535
536    /* disconnect audio path */
537    skt_disconnect(common->audio_fd);
538
539    common->audio_fd = AUDIO_SKT_DISCONNECTED;
540
541    return 0;
542}
543
544
545/*****************************************************************************
546**
547**  audio output callbacks
548**
549*****************************************************************************/
550
551static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
552                         size_t bytes)
553{
554    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
555    int sent;
556
557    DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
558
559    pthread_mutex_lock(&out->common.lock);
560
561    if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
562    {
563        DEBUG("stream suspended");
564        pthread_mutex_unlock(&out->common.lock);
565        return -1;
566    }
567
568    /* only allow autostarting if we are in stopped or standby */
569    if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) ||
570        (out->common.state == AUDIO_A2DP_STATE_STANDBY))
571    {
572        if (start_audio_datapath(&out->common) < 0)
573        {
574            /* emulate time this write represents to avoid very fast write
575               failures during transition periods or remote suspend */
576
577            int us_delay = calc_audiotime(out->common.cfg, bytes);
578
579            DEBUG("emulate a2dp write delay (%d us)", us_delay);
580
581            usleep(us_delay);
582            pthread_mutex_unlock(&out->common.lock);
583            return -1;
584        }
585    }
586    else if (out->common.state != AUDIO_A2DP_STATE_STARTED)
587    {
588        ERROR("stream not in stopped or standby");
589        pthread_mutex_unlock(&out->common.lock);
590        return -1;
591    }
592
593    pthread_mutex_unlock(&out->common.lock);
594    sent = skt_write(out->common.audio_fd, buffer,  bytes);
595
596    if (sent == -1) {
597        skt_disconnect(out->common.audio_fd);
598        out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
599        if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
600            out->common.state = AUDIO_A2DP_STATE_STOPPED;
601        else
602            ERROR("write failed : stream suspended, avoid resetting state");
603    } else {
604        const size_t frames = bytes / audio_stream_out_frame_size(stream);
605        out->frames_rendered += frames;
606        out->frames_presented += frames;
607    }
608
609    DEBUG("wrote %d bytes out of %zu bytes", sent, bytes);
610    return sent;
611}
612
613
614static uint32_t out_get_sample_rate(const struct audio_stream *stream)
615{
616    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
617
618    DEBUG("rate %" PRIu32,out->common.cfg.rate);
619
620    return out->common.cfg.rate;
621}
622
623static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
624{
625    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
626
627    DEBUG("out_set_sample_rate : %" PRIu32, rate);
628
629    if (rate != AUDIO_STREAM_DEFAULT_RATE)
630    {
631        ERROR("only rate %d supported", AUDIO_STREAM_DEFAULT_RATE);
632        return -1;
633    }
634
635    out->common.cfg.rate = rate;
636
637    return 0;
638}
639
640static size_t out_get_buffer_size(const struct audio_stream *stream)
641{
642    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
643
644    DEBUG("buffer_size : %zu", out->common.buffer_sz);
645
646    return out->common.buffer_sz;
647}
648
649static uint32_t out_get_channels(const struct audio_stream *stream)
650{
651    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
652
653    DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_flags);
654
655    return out->common.cfg.channel_flags;
656}
657
658static audio_format_t out_get_format(const struct audio_stream *stream)
659{
660    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
661    DEBUG("format 0x%x", out->common.cfg.format);
662    return out->common.cfg.format;
663}
664
665static int out_set_format(struct audio_stream *stream, audio_format_t format)
666{
667    UNUSED(format);
668    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
669    DEBUG("setting format not yet supported (0x%x)", format);
670    return -ENOSYS;
671}
672
673static int out_standby(struct audio_stream *stream)
674{
675    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
676    int retVal = 0;
677
678    FNLOG();
679
680    pthread_mutex_lock(&out->common.lock);
681    // Do nothing in SUSPENDED state.
682    if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
683        retVal = suspend_audio_datapath(&out->common, true);
684    out->frames_rendered = 0; // rendered is reset, presented is not
685    pthread_mutex_unlock (&out->common.lock);
686
687    return retVal;
688}
689
690static int out_dump(const struct audio_stream *stream, int fd)
691{
692    UNUSED(fd);
693    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
694    FNLOG();
695    return 0;
696}
697
698static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
699{
700    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
701    struct str_parms *parms;
702    char keyval[16];
703    int retval;
704    int status = 0;
705
706    INFO("state %d", out->common.state);
707
708    parms = str_parms_create_str(kvpairs);
709
710    /* dump params */
711    str_parms_dump(parms);
712
713    retval = str_parms_get_str(parms, "closing", keyval, sizeof(keyval));
714
715    if (retval >= 0)
716    {
717        if (strcmp(keyval, "true") == 0)
718        {
719            DEBUG("stream closing, disallow any writes");
720            pthread_mutex_lock(&out->common.lock);
721            out->common.state = AUDIO_A2DP_STATE_STOPPING;
722            pthread_mutex_unlock(&out->common.lock);
723        }
724    }
725
726    retval = str_parms_get_str(parms, "A2dpSuspended", keyval, sizeof(keyval));
727
728    if (retval >= 0)
729    {
730        pthread_mutex_lock(&out->common.lock);
731        if (strcmp(keyval, "true") == 0)
732        {
733            if (out->common.state == AUDIO_A2DP_STATE_STARTED)
734                status = suspend_audio_datapath(&out->common, false);
735        }
736        else
737        {
738            /* Do not start the streaming automatically. If the phone was streaming
739             * prior to being suspended, the next out_write shall trigger the
740             * AVDTP start procedure */
741            if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
742                out->common.state = AUDIO_A2DP_STATE_STANDBY;
743            /* Irrespective of the state, return 0 */
744        }
745        pthread_mutex_unlock(&out->common.lock);
746    }
747
748    str_parms_destroy(parms);
749
750    return status;
751}
752
753static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
754{
755    UNUSED(keys);
756    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
757
758    FNLOG();
759
760    /* add populating param here */
761
762    return strdup("");
763}
764
765static uint32_t out_get_latency(const struct audio_stream_out *stream)
766{
767    int latency_us;
768
769    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
770
771    FNLOG();
772
773    latency_us = ((out->common.buffer_sz * 1000 ) /
774                    audio_stream_out_frame_size(&out->stream) /
775                    out->common.cfg.rate) * 1000;
776
777
778    return (latency_us / 1000) + 200;
779}
780
781static int out_set_volume(struct audio_stream_out *stream, float left,
782                          float right)
783{
784    UNUSED(stream);
785    UNUSED(left);
786    UNUSED(right);
787
788    FNLOG();
789
790    /* volume controlled in audioflinger mixer (digital) */
791
792    return -ENOSYS;
793}
794
795static int out_get_presentation_position(const struct audio_stream_out *stream,
796                                         uint64_t *frames, struct timespec *timestamp)
797{
798    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
799
800    FNLOG();
801    if (stream == NULL || frames == NULL || timestamp == NULL)
802        return -EINVAL;
803
804    int ret = -EWOULDBLOCK;
805    pthread_mutex_lock(&out->common.lock);
806    uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
807    if (out->frames_presented >= latency_frames) {
808        *frames = out->frames_presented - latency_frames;
809        clock_gettime(CLOCK_MONOTONIC, timestamp); // could also be associated with out_write().
810        ret = 0;
811    }
812    pthread_mutex_unlock(&out->common.lock);
813    return ret;
814}
815
816static int out_get_render_position(const struct audio_stream_out *stream,
817                                   uint32_t *dsp_frames)
818{
819    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
820
821    FNLOG();
822    if (stream == NULL || dsp_frames == NULL)
823        return -EINVAL;
824
825    pthread_mutex_lock(&out->common.lock);
826    uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
827    if (out->frames_rendered >= latency_frames) {
828        *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
829    } else {
830        *dsp_frames = 0;
831    }
832    pthread_mutex_unlock(&out->common.lock);
833    return 0;
834}
835
836static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
837{
838    UNUSED(stream);
839    UNUSED(effect);
840
841    FNLOG();
842    return 0;
843}
844
845static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
846{
847    UNUSED(stream);
848    UNUSED(effect);
849
850    FNLOG();
851    return 0;
852}
853
854/*
855 * AUDIO INPUT STREAM
856 */
857
858static uint32_t in_get_sample_rate(const struct audio_stream *stream)
859{
860    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
861
862    FNLOG();
863    return in->common.cfg.rate;
864}
865
866static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
867{
868    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
869
870    FNLOG();
871
872    if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
873        return 0;
874    else
875        return -1;
876}
877
878static size_t in_get_buffer_size(const struct audio_stream *stream)
879{
880    UNUSED(stream);
881
882    FNLOG();
883    return 320;
884}
885
886static uint32_t in_get_channels(const struct audio_stream *stream)
887{
888    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
889
890    FNLOG();
891    return in->common.cfg.channel_flags;
892}
893
894static audio_format_t in_get_format(const struct audio_stream *stream)
895{
896    UNUSED(stream);
897
898    FNLOG();
899    return AUDIO_FORMAT_PCM_16_BIT;
900}
901
902static int in_set_format(struct audio_stream *stream, audio_format_t format)
903{
904    UNUSED(stream);
905    UNUSED(format);
906
907    FNLOG();
908    if (format == AUDIO_FORMAT_PCM_16_BIT)
909        return 0;
910    else
911        return -1;
912}
913
914static int in_standby(struct audio_stream *stream)
915{
916    UNUSED(stream);
917
918    FNLOG();
919    return 0;
920}
921
922static int in_dump(const struct audio_stream *stream, int fd)
923{
924    UNUSED(stream);
925    UNUSED(fd);
926
927    FNLOG();
928    return 0;
929}
930
931static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
932{
933    UNUSED(stream);
934    UNUSED(kvpairs);
935
936    FNLOG();
937    return 0;
938}
939
940static char * in_get_parameters(const struct audio_stream *stream,
941                                const char *keys)
942{
943    UNUSED(stream);
944    UNUSED(keys);
945
946    FNLOG();
947    return strdup("");
948}
949
950static int in_set_gain(struct audio_stream_in *stream, float gain)
951{
952    UNUSED(stream);
953    UNUSED(gain);
954
955    FNLOG();
956    return 0;
957}
958
959static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
960                       size_t bytes)
961{
962    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
963    int read;
964
965    DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
966
967    if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED)
968    {
969        DEBUG("stream suspended");
970        return -1;
971    }
972
973    /* only allow autostarting if we are in stopped or standby */
974    if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) ||
975        (in->common.state == AUDIO_A2DP_STATE_STANDBY))
976    {
977        pthread_mutex_lock(&in->common.lock);
978
979        if (start_audio_datapath(&in->common) < 0)
980        {
981            /* emulate time this write represents to avoid very fast write
982               failures during transition periods or remote suspend */
983
984            int us_delay = calc_audiotime(in->common.cfg, bytes);
985
986            DEBUG("emulate a2dp read delay (%d us)", us_delay);
987
988            usleep(us_delay);
989            pthread_mutex_unlock(&in->common.lock);
990            return -1;
991        }
992
993        pthread_mutex_unlock(&in->common.lock);
994    }
995    else if (in->common.state != AUDIO_A2DP_STATE_STARTED)
996    {
997        ERROR("stream not in stopped or standby");
998        return -1;
999    }
1000
1001    read = skt_read(in->common.audio_fd, buffer, bytes);
1002
1003    if (read == -1)
1004    {
1005        skt_disconnect(in->common.audio_fd);
1006        in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
1007        in->common.state = AUDIO_A2DP_STATE_STOPPED;
1008    } else if (read == 0) {
1009        DEBUG("read time out - return zeros");
1010        memset(buffer, 0, bytes);
1011        read = bytes;
1012    }
1013
1014    DEBUG("read %d bytes out of %zu bytes", read, bytes);
1015    return read;
1016}
1017
1018static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
1019{
1020    UNUSED(stream);
1021
1022    FNLOG();
1023    return 0;
1024}
1025
1026static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1027{
1028    UNUSED(stream);
1029    UNUSED(effect);
1030
1031    FNLOG();
1032    return 0;
1033}
1034
1035static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1036{
1037    UNUSED(stream);
1038    UNUSED(effect);
1039
1040    FNLOG();
1041
1042    return 0;
1043}
1044
1045static int adev_open_output_stream(struct audio_hw_device *dev,
1046                                   audio_io_handle_t handle,
1047                                   audio_devices_t devices,
1048                                   audio_output_flags_t flags,
1049                                   struct audio_config *config,
1050                                   struct audio_stream_out **stream_out,
1051                                   const char *address)
1052
1053{
1054    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1055    struct a2dp_stream_out *out;
1056    int ret = 0;
1057    int i;
1058    UNUSED(address);
1059    UNUSED(handle);
1060    UNUSED(devices);
1061    UNUSED(flags);
1062
1063    INFO("opening output");
1064
1065    out = (struct a2dp_stream_out *)calloc(1, sizeof(struct a2dp_stream_out));
1066
1067    if (!out)
1068        return -ENOMEM;
1069
1070    out->stream.common.get_sample_rate = out_get_sample_rate;
1071    out->stream.common.set_sample_rate = out_set_sample_rate;
1072    out->stream.common.get_buffer_size = out_get_buffer_size;
1073    out->stream.common.get_channels = out_get_channels;
1074    out->stream.common.get_format = out_get_format;
1075    out->stream.common.set_format = out_set_format;
1076    out->stream.common.standby = out_standby;
1077    out->stream.common.dump = out_dump;
1078    out->stream.common.set_parameters = out_set_parameters;
1079    out->stream.common.get_parameters = out_get_parameters;
1080    out->stream.common.add_audio_effect = out_add_audio_effect;
1081    out->stream.common.remove_audio_effect = out_remove_audio_effect;
1082    out->stream.get_latency = out_get_latency;
1083    out->stream.set_volume = out_set_volume;
1084    out->stream.write = out_write;
1085    out->stream.get_render_position = out_get_render_position;
1086    out->stream.get_presentation_position = out_get_presentation_position;
1087
1088
1089    /* initialize a2dp specifics */
1090    a2dp_stream_common_init(&out->common);
1091
1092    out->common.cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG;
1093    out->common.cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
1094    out->common.cfg.rate = AUDIO_STREAM_DEFAULT_RATE;
1095
1096   /* set output config values */
1097   if (config)
1098   {
1099      config->format = out_get_format((const struct audio_stream *)&out->stream);
1100      config->sample_rate = out_get_sample_rate((const struct audio_stream *)&out->stream);
1101      config->channel_mask = out_get_channels((const struct audio_stream *)&out->stream);
1102   }
1103    *stream_out = &out->stream;
1104    a2dp_dev->output = out;
1105
1106    a2dp_open_ctrl_path(&out->common);
1107    if (out->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
1108    {
1109        ERROR("ctrl socket failed to connect (%s)", strerror(errno));
1110        ret = -1;
1111        goto err_open;
1112    }
1113
1114    DEBUG("success");
1115    /* Delay to ensure Headset is in proper state when START is initiated
1116       from DUT immediately after the connection due to ongoing music playback. */
1117    usleep(250000);
1118    return 0;
1119
1120err_open:
1121    free(out);
1122    *stream_out = NULL;
1123    a2dp_dev->output = NULL;
1124    ERROR("failed");
1125    return ret;
1126}
1127
1128static void adev_close_output_stream(struct audio_hw_device *dev,
1129                                     struct audio_stream_out *stream)
1130{
1131    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1132    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
1133
1134    INFO("closing output (state %d)", out->common.state);
1135
1136    pthread_mutex_lock(&out->common.lock);
1137    if ((out->common.state == AUDIO_A2DP_STATE_STARTED) || (out->common.state == AUDIO_A2DP_STATE_STOPPING))
1138        stop_audio_datapath(&out->common);
1139
1140    skt_disconnect(out->common.ctrl_fd);
1141    free(stream);
1142    a2dp_dev->output = NULL;
1143    pthread_mutex_unlock(&out->common.lock);
1144
1145    DEBUG("done");
1146}
1147
1148static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1149{
1150    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1151    struct a2dp_stream_out *out = a2dp_dev->output;
1152    int retval = 0;
1153
1154    if (out == NULL)
1155        return retval;
1156
1157    INFO("state %d", out->common.state);
1158
1159    retval = out->stream.common.set_parameters((struct audio_stream *)out, kvpairs);
1160
1161    return retval;
1162}
1163
1164static char * adev_get_parameters(const struct audio_hw_device *dev,
1165                                  const char *keys)
1166{
1167    struct str_parms *parms;
1168    UNUSED(dev);
1169
1170    FNLOG();
1171
1172    parms = str_parms_create_str(keys);
1173
1174    str_parms_dump(parms);
1175
1176    str_parms_destroy(parms);
1177
1178    return strdup("");
1179}
1180
1181static int adev_init_check(const struct audio_hw_device *dev)
1182{
1183    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device*)dev;
1184
1185    FNLOG();
1186
1187    return 0;
1188}
1189
1190static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1191{
1192    UNUSED(dev);
1193    UNUSED(volume);
1194
1195    FNLOG();
1196
1197    return -ENOSYS;
1198}
1199
1200static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1201{
1202    UNUSED(dev);
1203    UNUSED(volume);
1204
1205    FNLOG();
1206
1207    return -ENOSYS;
1208}
1209
1210static int adev_set_mode(struct audio_hw_device *dev, int mode)
1211{
1212    UNUSED(dev);
1213    UNUSED(mode);
1214
1215    FNLOG();
1216
1217    return 0;
1218}
1219
1220static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1221{
1222    UNUSED(dev);
1223    UNUSED(state);
1224
1225    FNLOG();
1226
1227    return -ENOSYS;
1228}
1229
1230static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1231{
1232    UNUSED(dev);
1233    UNUSED(state);
1234
1235    FNLOG();
1236
1237    return -ENOSYS;
1238}
1239
1240static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
1241                                         const struct audio_config *config)
1242{
1243    UNUSED(dev);
1244    UNUSED(config);
1245
1246    FNLOG();
1247
1248    return 320;
1249}
1250
1251static int adev_open_input_stream(struct audio_hw_device *dev,
1252                                  audio_io_handle_t handle,
1253                                  audio_devices_t devices,
1254                                  struct audio_config *config,
1255                                  struct audio_stream_in **stream_in,
1256                                  audio_input_flags_t flags,
1257                                  const char *address,
1258                                  audio_source_t source)
1259{
1260    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1261    struct a2dp_stream_in *in;
1262    int ret;
1263    UNUSED(address);
1264    UNUSED(config);
1265    UNUSED(devices);
1266    UNUSED(flags);
1267    UNUSED(handle);
1268    UNUSED(source);
1269
1270    FNLOG();
1271
1272    in = (struct a2dp_stream_in *)calloc(1, sizeof(struct a2dp_stream_in));
1273
1274    if (!in)
1275        return -ENOMEM;
1276
1277    in->stream.common.get_sample_rate = in_get_sample_rate;
1278    in->stream.common.set_sample_rate = in_set_sample_rate;
1279    in->stream.common.get_buffer_size = in_get_buffer_size;
1280    in->stream.common.get_channels = in_get_channels;
1281    in->stream.common.get_format = in_get_format;
1282    in->stream.common.set_format = in_set_format;
1283    in->stream.common.standby = in_standby;
1284    in->stream.common.dump = in_dump;
1285    in->stream.common.set_parameters = in_set_parameters;
1286    in->stream.common.get_parameters = in_get_parameters;
1287    in->stream.common.add_audio_effect = in_add_audio_effect;
1288    in->stream.common.remove_audio_effect = in_remove_audio_effect;
1289    in->stream.set_gain = in_set_gain;
1290    in->stream.read = in_read;
1291    in->stream.get_input_frames_lost = in_get_input_frames_lost;
1292
1293    /* initialize a2dp specifics */
1294    a2dp_stream_common_init(&in->common);
1295
1296    *stream_in = &in->stream;
1297    a2dp_dev->input = in;
1298
1299    a2dp_open_ctrl_path(&in->common);
1300    if (in->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
1301    {
1302        ERROR("ctrl socket failed to connect (%s)", strerror(errno));
1303        ret = -1;
1304        goto err_open;
1305    }
1306
1307    if (a2dp_read_audio_config(&in->common) < 0) {
1308        ERROR("a2dp_read_audio_config failed (%s)", strerror(errno));
1309        ret = -1;
1310        goto err_open;
1311    }
1312
1313    DEBUG("success");
1314    return 0;
1315
1316err_open:
1317    free(in);
1318    *stream_in = NULL;
1319    a2dp_dev->input = NULL;
1320    ERROR("failed");
1321    return ret;
1322}
1323
1324static void adev_close_input_stream(struct audio_hw_device *dev,
1325                                   struct audio_stream_in *stream)
1326{
1327    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1328    struct a2dp_stream_in* in = (struct a2dp_stream_in *)stream;
1329    a2dp_state_t state = in->common.state;
1330
1331    INFO("closing input (state %d)", state);
1332
1333    if ((state == AUDIO_A2DP_STATE_STARTED) || (state == AUDIO_A2DP_STATE_STOPPING))
1334        stop_audio_datapath(&in->common);
1335
1336    skt_disconnect(in->common.ctrl_fd);
1337    free(stream);
1338    a2dp_dev->input = NULL;
1339
1340    DEBUG("done");
1341}
1342
1343static int adev_dump(const audio_hw_device_t *device, int fd)
1344{
1345    UNUSED(device);
1346    UNUSED(fd);
1347
1348    FNLOG();
1349
1350    return 0;
1351}
1352
1353static int adev_close(hw_device_t *device)
1354{
1355    FNLOG();
1356
1357    free(device);
1358    return 0;
1359}
1360
1361static int adev_open(const hw_module_t* module, const char* name,
1362                     hw_device_t** device)
1363{
1364    struct a2dp_audio_device *adev;
1365    int ret;
1366
1367    INFO(" adev_open in A2dp_hw module");
1368    FNLOG();
1369
1370    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1371    {
1372        ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
1373        return -EINVAL;
1374    }
1375
1376    adev = calloc(1, sizeof(struct a2dp_audio_device));
1377
1378    if (!adev)
1379        return -ENOMEM;
1380
1381    adev->device.common.tag = HARDWARE_DEVICE_TAG;
1382    adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1383    adev->device.common.module = (struct hw_module_t *) module;
1384    adev->device.common.close = adev_close;
1385
1386    adev->device.init_check = adev_init_check;
1387    adev->device.set_voice_volume = adev_set_voice_volume;
1388    adev->device.set_master_volume = adev_set_master_volume;
1389    adev->device.set_mode = adev_set_mode;
1390    adev->device.set_mic_mute = adev_set_mic_mute;
1391    adev->device.get_mic_mute = adev_get_mic_mute;
1392    adev->device.set_parameters = adev_set_parameters;
1393    adev->device.get_parameters = adev_get_parameters;
1394    adev->device.get_input_buffer_size = adev_get_input_buffer_size;
1395    adev->device.open_output_stream = adev_open_output_stream;
1396    adev->device.close_output_stream = adev_close_output_stream;
1397    adev->device.open_input_stream = adev_open_input_stream;
1398    adev->device.close_input_stream = adev_close_input_stream;
1399    adev->device.dump = adev_dump;
1400
1401    adev->output = NULL;
1402
1403
1404    *device = &adev->device.common;
1405
1406    return 0;
1407}
1408
1409static struct hw_module_methods_t hal_module_methods = {
1410    .open = adev_open,
1411};
1412
1413struct audio_module HAL_MODULE_INFO_SYM = {
1414    .common = {
1415        .tag = HARDWARE_MODULE_TAG,
1416        .version_major = 1,
1417        .version_minor = 0,
1418        .id = AUDIO_HARDWARE_MODULE_ID,
1419        .name = "A2DP Audio HW HAL",
1420        .author = "The Android Open Source Project",
1421        .methods = &hal_module_methods,
1422    },
1423};
1424