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
dump_a2dp_ctrl_event(char event)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 */
ts_log(char * tag,int val,struct timespec * pprev_opt)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
calc_audiotime(struct a2dp_config cfg,int bytes)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
skt_connect(struct a2dp_stream_out * out,char * path)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
skt_write(int fd,const void * p,size_t len)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
skt_disconnect(int fd)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
a2dp_command(struct a2dp_stream_out * out,char cmd)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
a2dp_stream_out_init(struct a2dp_stream_out * out)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
start_audio_datapath(struct a2dp_stream_out * out)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
stop_audio_datapath(struct a2dp_stream_out * out)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
suspend_audio_datapath(struct a2dp_stream_out * out,bool standby)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
check_a2dp_ready(struct a2dp_stream_out * out)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
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)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
out_get_sample_rate(const struct audio_stream * stream)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
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)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
out_get_buffer_size(const struct audio_stream * stream)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
out_get_channels(const struct audio_stream * stream)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
out_get_format(const struct audio_stream * stream)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
out_set_format(struct audio_stream * stream,audio_format_t format)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
out_standby(struct audio_stream * stream)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
out_dump(const struct audio_stream * stream,int fd)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
out_set_parameters(struct audio_stream * stream,const char * kvpairs)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
out_get_parameters(const struct audio_stream * stream,const char * keys)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
out_get_latency(const struct audio_stream_out * stream)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
out_set_volume(struct audio_stream_out * stream,float left,float right)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
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)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
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)678 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
679 {
680 FNLOG();
681 return 0;
682 }
683
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)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
in_get_sample_rate(const struct audio_stream * stream)694 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
695 {
696 FNLOG();
697 return 8000;
698 }
699
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)700 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
701 {
702 FNLOG();
703 return 0;
704 }
705
in_get_buffer_size(const struct audio_stream * stream)706 static size_t in_get_buffer_size(const struct audio_stream *stream)
707 {
708 FNLOG();
709 return 320;
710 }
711
in_get_channels(const struct audio_stream * stream)712 static uint32_t in_get_channels(const struct audio_stream *stream)
713 {
714 FNLOG();
715 return AUDIO_CHANNEL_IN_MONO;
716 }
717
in_get_format(const struct audio_stream * stream)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
in_set_format(struct audio_stream * stream,audio_format_t format)724 static int in_set_format(struct audio_stream *stream, audio_format_t format)
725 {
726 FNLOG();
727 return 0;
728 }
729
in_standby(struct audio_stream * stream)730 static int in_standby(struct audio_stream *stream)
731 {
732 FNLOG();
733 return 0;
734 }
735
in_dump(const struct audio_stream * stream,int fd)736 static int in_dump(const struct audio_stream *stream, int fd)
737 {
738 FNLOG();
739 return 0;
740 }
741
in_set_parameters(struct audio_stream * stream,const char * kvpairs)742 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
743 {
744 FNLOG();
745 return 0;
746 }
747
in_get_parameters(const struct audio_stream * stream,const char * keys)748 static char * in_get_parameters(const struct audio_stream *stream,
749 const char *keys)
750 {
751 FNLOG();
752 return strdup("");
753 }
754
in_set_gain(struct audio_stream_in * stream,float gain)755 static int in_set_gain(struct audio_stream_in *stream, float gain)
756 {
757 FNLOG();
758 return 0;
759 }
760
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)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
in_get_input_frames_lost(struct audio_stream_in * stream)768 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
769 {
770 FNLOG();
771 return 0;
772 }
773
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)774 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
775 {
776 FNLOG();
777 return 0;
778 }
779
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)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
adev_open_output_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,struct audio_stream_out ** stream_out)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
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)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
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)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
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)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
adev_init_check(const struct audio_hw_device * dev)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
adev_set_voice_volume(struct audio_hw_device * dev,float volume)932 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
933 {
934 FNLOG();
935
936 return -ENOSYS;
937 }
938
adev_set_master_volume(struct audio_hw_device * dev,float volume)939 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
940 {
941 FNLOG();
942
943 return -ENOSYS;
944 }
945
adev_set_mode(struct audio_hw_device * dev,int mode)946 static int adev_set_mode(struct audio_hw_device *dev, int mode)
947 {
948 FNLOG();
949
950 return 0;
951 }
952
adev_set_mic_mute(struct audio_hw_device * dev,bool state)953 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
954 {
955 FNLOG();
956
957 return -ENOSYS;
958 }
959
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)960 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
961 {
962 FNLOG();
963
964 return -ENOSYS;
965 }
966
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)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
adev_open_input_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,struct audio_stream_in ** stream_in)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
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * in)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
adev_dump(const audio_hw_device_t * device,int fd)1025 static int adev_dump(const audio_hw_device_t *device, int fd)
1026 {
1027 FNLOG();
1028
1029 return 0;
1030 }
1031
adev_close(hw_device_t * device)1032 static int adev_close(hw_device_t *device)
1033 {
1034 FNLOG();
1035
1036 free(device);
1037 return 0;
1038 }
1039
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)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