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