1 /******************************************************************************
3 * Copyright (C) 2009-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /*****************************************************************************
21 * Filename: audio_a2dp_hw.c
23 * Description: Implements hal for bluedroid a2dp audio device
25 *****************************************************************************/
27 #define LOG_TAG "bt_a2dp_hw"
34 #include <sys/errno.h>
35 #include <sys/socket.h>
41 #include <hardware/audio.h>
42 #include <hardware/hardware.h>
43 #include <system/audio.h>
45 #include "audio_a2dp_hw.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"
53 /*****************************************************************************
55 ******************************************************************************/
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 */
62 // set WRITE_POLL_MS to 0 for blocking sockets, nonzero for polled non-blocking sockets
63 #define WRITE_POLL_MS 20
65 #define CASE_RETURN_STR(const) case const: return #const;
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__)
73 #define ASSERTC(cond, msg, val) if (!(cond)) {ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
75 /*****************************************************************************
76 ** Local type definitions
77 ******************************************************************************/
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 */
88 struct a2dp_stream_in;
89 struct a2dp_stream_out;
91 struct a2dp_audio_device {
92 struct audio_hw_device device;
93 struct a2dp_stream_in *input;
94 struct a2dp_stream_out *output;
99 uint32_t channel_flags;
103 /* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
105 struct a2dp_stream_common {
106 pthread_mutex_t lock;
110 struct a2dp_config cfg;
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
121 struct a2dp_stream_in {
122 struct audio_stream_in stream;
123 struct a2dp_stream_common common;
126 /*****************************************************************************
128 ******************************************************************************/
130 /*****************************************************************************
132 ******************************************************************************/
134 static size_t out_get_buffer_size(const struct audio_stream *stream);
136 /*****************************************************************************
138 ******************************************************************************/
140 /*****************************************************************************
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);
147 /*****************************************************************************
148 ** Miscellaneous helper functions
149 ******************************************************************************/
151 static const char* dump_a2dp_ctrl_event(char event)
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)
161 return "UNKNOWN MSG ID";
165 /* logs timestamp with microsec precision
166 pprev is optional in case a dedicated diff is required */
167 static void ts_log(char *tag, int val, struct timespec *pprev_opt)
170 static struct timespec prev = {0,0};
171 unsigned long long now_us;
172 unsigned long long diff_us;
176 clock_gettime(CLOCK_MONOTONIC, &now);
178 now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
182 diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
184 DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
188 diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
190 DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
194 static int calc_audiotime(struct a2dp_config cfg, int bytes)
196 int chan_count = popcount(cfg.channel_flags);
198 ASSERTC(cfg.format == AUDIO_FORMAT_PCM_16_BIT,
199 "unsupported sample sz", cfg.format);
201 return (int)(((int64_t)bytes * (1000000 / (chan_count * 2))) / cfg.rate);
204 /*****************************************************************************
206 ** bluedroid stack adaptation
208 *****************************************************************************/
210 static int skt_connect(char *path, size_t buffer_sz)
216 INFO("connect to %s (sz %zu)", path, buffer_sz);
218 skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
220 if(osi_socket_local_client_connect(skt_fd, path,
221 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
223 ERROR("failed to connect (%s)", strerror(errno));
229 ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
231 ERROR("setsockopt failed (%s)", strerror(errno));
233 ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
235 ERROR("setsockopt failed (%s)", strerror(errno));
237 /* Socket send/receive timeout value */
239 tv.tv_sec = SOCK_SEND_TIMEOUT_MS / 1000;
240 tv.tv_usec = (SOCK_SEND_TIMEOUT_MS % 1000) * 1000;
242 ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
244 ERROR("setsockopt failed (%s)", strerror(errno));
246 tv.tv_sec = SOCK_RECV_TIMEOUT_MS / 1000;
247 tv.tv_usec = (SOCK_RECV_TIMEOUT_MS % 1000) * 1000;
249 ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
251 ERROR("setsockopt failed (%s)", strerror(errno));
253 INFO("connected to stack fd = %d", skt_fd);
258 static int skt_read(int fd, void *p, size_t len)
264 ts_log("skt_read recv", len, NULL);
266 OSI_NO_INTR(read = recv(fd, p, len, MSG_NOSIGNAL));
268 ERROR("read failed with errno=%d\n", errno);
273 static int skt_write(int fd, const void *p, size_t len)
278 ts_log("skt_write", len, NULL);
280 if (WRITE_POLL_MS == 0) {
281 // do not poll, use blocking send
282 OSI_NO_INTR(sent = send(fd, p, len, MSG_NOSIGNAL));
284 ERROR("write failed with error(%s)", strerror(errno));
289 // use non-blocking send, poll
290 int ms_timeout = SOCK_SEND_TIMEOUT_MS;
292 while (count < len) {
293 OSI_NO_INTR(sent = send(fd, p, len - count, MSG_NOSIGNAL | MSG_DONTWAIT));
295 if (errno != EAGAIN && errno != EWOULDBLOCK) {
296 ERROR("write failed with error(%s)", strerror(errno));
299 if (ms_timeout >= WRITE_POLL_MS) {
300 usleep(WRITE_POLL_MS * 1000);
301 ms_timeout -= WRITE_POLL_MS;
304 WARN("write timeout exceeded, sent %zu bytes", count);
308 p = (const uint8_t *)p + sent;
313 static int skt_disconnect(int fd)
317 if (fd != AUDIO_SKT_DISCONNECTED)
319 shutdown(fd, SHUT_RDWR);
327 /*****************************************************************************
329 ** AUDIO CONTROL PATH
331 *****************************************************************************/
333 static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length)
339 OSI_NO_INTR(ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
344 ERROR("ack failed: peer closed");
347 if (errno != EWOULDBLOCK && errno != EAGAIN) {
348 ERROR("ack failed: error(%s)", strerror(errno));
351 if (i == (CTRL_CHAN_RETRY_COUNT - 1)) {
352 ERROR("ack failed: max retry count");
355 INFO("ack failed (%s), retrying", strerror(errno));
358 skt_disconnect(common->ctrl_fd);
359 common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
364 static int a2dp_command(struct a2dp_stream_common *common, char cmd)
368 DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd));
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");
381 OSI_NO_INTR(sent = send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL));
384 ERROR("cmd failed (%s)", strerror(errno));
385 skt_disconnect(common->ctrl_fd);
386 common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
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));
396 DEBUG("A2DP COMMAND %s DONE STATUS %d", dump_a2dp_ctrl_event(cmd), ack);
398 if (ack == A2DP_CTRL_ACK_INCALL_FAILURE)
400 if (ack != A2DP_CTRL_ACK_SUCCESS) {
401 ERROR("A2DP COMMAND %s error %d", dump_a2dp_ctrl_event(cmd), ack);
408 static int check_a2dp_ready(struct a2dp_stream_common *common)
410 if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0)
412 ERROR("check a2dp ready failed");
418 static int a2dp_read_audio_config(struct a2dp_stream_common *common)
420 uint32_t sample_rate;
421 uint8_t channel_count;
423 if (a2dp_command(common, A2DP_CTRL_GET_AUDIO_CONFIG) < 0)
425 ERROR("check a2dp ready failed");
429 if (a2dp_ctrl_receive(common, &sample_rate, 4) < 0)
431 if (a2dp_ctrl_receive(common, &channel_count, 1) < 0)
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;
438 INFO("got config %d %d", common->cfg.format, common->cfg.rate);
443 static void a2dp_open_ctrl_path(struct a2dp_stream_common *common)
447 /* retry logic to catch any timing variations on control channel */
448 for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++)
450 /* connect control channel if not already connected */
451 if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0)
453 /* success, now check if stack is ready */
454 if (check_a2dp_ready(common) == 0)
457 ERROR("error : a2dp not ready, wait 250 ms and retry");
459 skt_disconnect(common->ctrl_fd);
460 common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
463 /* ctrl channel not ready, wait a bit */
468 /*****************************************************************************
472 *****************************************************************************/
474 static void a2dp_stream_common_init(struct a2dp_stream_common *common)
476 pthread_mutexattr_t lock_attr;
480 pthread_mutexattr_init(&lock_attr);
481 pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
482 pthread_mutex_init(&common->lock, &lock_attr);
484 common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
485 common->audio_fd = AUDIO_SKT_DISCONNECTED;
486 common->state = AUDIO_A2DP_STATE_STOPPED;
488 /* manages max capacity of socket pipe */
489 common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
492 static int start_audio_datapath(struct a2dp_stream_common *common)
494 INFO("state %d", common->state);
496 int oldstate = common->state;
497 common->state = AUDIO_A2DP_STATE_STARTING;
499 int a2dp_status = a2dp_command(common, A2DP_CTRL_CMD_START);
502 ERROR("Audiopath start failed (status %d)", a2dp_status);
505 else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE)
507 ERROR("Audiopath start failed - in call, move to suspended");
511 /* connect socket if not yet connected */
512 if (common->audio_fd == AUDIO_SKT_DISCONNECTED)
514 common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
515 if (common->audio_fd < 0)
517 ERROR("Audiopath start failed - error opening data socket");
521 common->state = AUDIO_A2DP_STATE_STARTED;
525 common->state = oldstate;
529 static int stop_audio_datapath(struct a2dp_stream_common *common)
531 int oldstate = common->state;
533 INFO("state %d", common->state);
535 /* prevent any stray output writes from autostarting the stream
536 while stopping audiopath */
537 common->state = AUDIO_A2DP_STATE_STOPPING;
539 if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0)
541 ERROR("audiopath stop failed");
542 common->state = oldstate;
546 common->state = AUDIO_A2DP_STATE_STOPPED;
548 /* disconnect audio path */
549 skt_disconnect(common->audio_fd);
550 common->audio_fd = AUDIO_SKT_DISCONNECTED;
555 static int suspend_audio_datapath(struct a2dp_stream_common *common, bool standby)
557 INFO("state %d", common->state);
559 if (common->state == AUDIO_A2DP_STATE_STOPPING)
562 if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0)
566 common->state = AUDIO_A2DP_STATE_STANDBY;
568 common->state = AUDIO_A2DP_STATE_SUSPENDED;
570 /* disconnect audio path */
571 skt_disconnect(common->audio_fd);
573 common->audio_fd = AUDIO_SKT_DISCONNECTED;
579 /*****************************************************************************
581 ** audio output callbacks
583 *****************************************************************************/
585 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
588 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
591 DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
593 pthread_mutex_lock(&out->common.lock);
594 if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED ||
595 out->common.state == AUDIO_A2DP_STATE_STOPPING) {
596 DEBUG("stream suspended or closing");
600 /* only allow autostarting if we are in stopped or standby */
601 if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) ||
602 (out->common.state == AUDIO_A2DP_STATE_STANDBY))
604 if (start_audio_datapath(&out->common) < 0)
609 else if (out->common.state != AUDIO_A2DP_STATE_STARTED)
611 ERROR("stream not in stopped or standby");
615 pthread_mutex_unlock(&out->common.lock);
616 sent = skt_write(out->common.audio_fd, buffer, bytes);
617 pthread_mutex_lock(&out->common.lock);
620 skt_disconnect(out->common.audio_fd);
621 out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
622 if ((out->common.state != AUDIO_A2DP_STATE_SUSPENDED) &&
623 (out->common.state != AUDIO_A2DP_STATE_STOPPING)) {
624 out->common.state = AUDIO_A2DP_STATE_STOPPED;
626 ERROR("write failed : stream suspended, avoid resetting state");
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);
637 // If send didn't work out, sleep to emulate write delay.
639 const int us_delay = calc_audiotime(out->common.cfg, bytes);
640 DEBUG("emulate a2dp write delay (%d us)", us_delay);
646 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
648 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
650 DEBUG("rate %" PRIu32,out->common.cfg.rate);
652 return out->common.cfg.rate;
655 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
657 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
659 DEBUG("out_set_sample_rate : %" PRIu32, rate);
661 if (rate != AUDIO_STREAM_DEFAULT_RATE)
663 ERROR("only rate %d supported", AUDIO_STREAM_DEFAULT_RATE);
667 out->common.cfg.rate = rate;
672 static size_t out_get_buffer_size(const struct audio_stream *stream)
674 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
675 // period_size is the AudioFlinger mixer buffer size.
676 const size_t period_size = out->common.buffer_sz / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS;
677 const size_t mixer_unit_size = 16 /* frames */ * 4 /* framesize */;
679 DEBUG("socket buffer size: %zu period size: %zu", out->common.buffer_sz, period_size);
680 if (period_size % mixer_unit_size != 0) {
681 ERROR("period size %zu not a multiple of %zu", period_size, mixer_unit_size);
687 static uint32_t out_get_channels(const struct audio_stream *stream)
689 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
691 DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_flags);
693 return out->common.cfg.channel_flags;
696 static audio_format_t out_get_format(const struct audio_stream *stream)
698 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
699 DEBUG("format 0x%x", out->common.cfg.format);
700 return out->common.cfg.format;
703 static int out_set_format(struct audio_stream *stream, audio_format_t format)
707 DEBUG("setting format not yet supported (0x%x)", format);
711 static int out_standby(struct audio_stream *stream)
713 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
718 pthread_mutex_lock(&out->common.lock);
719 // Do nothing in SUSPENDED state.
720 if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
721 retVal = suspend_audio_datapath(&out->common, true);
722 out->frames_rendered = 0; // rendered is reset, presented is not
723 pthread_mutex_unlock (&out->common.lock);
728 static int out_dump(const struct audio_stream *stream, int fd)
736 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
738 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
740 INFO("state %d", out->common.state);
742 hash_map_t *params = hash_map_utils_new_from_string_params(kvpairs);
748 pthread_mutex_lock(&out->common.lock);
751 hash_map_utils_dump_string_keys_string_values(params);
753 char *keyval = (char *)hash_map_get(params, "closing");
755 if (keyval && strcmp(keyval, "true") == 0)
757 DEBUG("stream closing, disallow any writes");
758 out->common.state = AUDIO_A2DP_STATE_STOPPING;
761 keyval = (char *)hash_map_get(params, "A2dpSuspended");
763 if (keyval && strcmp(keyval, "true") == 0)
765 if (out->common.state == AUDIO_A2DP_STATE_STARTED)
766 status = suspend_audio_datapath(&out->common, false);
770 /* Do not start the streaming automatically. If the phone was streaming
771 * prior to being suspended, the next out_write shall trigger the
772 * AVDTP start procedure */
773 if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
774 out->common.state = AUDIO_A2DP_STATE_STANDBY;
775 /* Irrespective of the state, return 0 */
778 pthread_mutex_unlock(&out->common.lock);
779 hash_map_free(params);
784 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
790 /* add populating param here */
795 static uint32_t out_get_latency(const struct audio_stream_out *stream)
799 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
803 latency_us = ((out->common.buffer_sz * 1000 ) /
804 audio_stream_out_frame_size(&out->stream) /
805 out->common.cfg.rate) * 1000;
808 return (latency_us / 1000) + 200;
811 static int out_set_volume(struct audio_stream_out *stream, float left,
820 /* volume controlled in audioflinger mixer (digital) */
825 static int out_get_presentation_position(const struct audio_stream_out *stream,
826 uint64_t *frames, struct timespec *timestamp)
828 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
831 if (stream == NULL || frames == NULL || timestamp == NULL)
834 int ret = -EWOULDBLOCK;
835 pthread_mutex_lock(&out->common.lock);
836 uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
837 if (out->frames_presented >= latency_frames) {
838 *frames = out->frames_presented - latency_frames;
839 clock_gettime(CLOCK_MONOTONIC, timestamp); // could also be associated with out_write().
842 pthread_mutex_unlock(&out->common.lock);
846 static int out_get_render_position(const struct audio_stream_out *stream,
847 uint32_t *dsp_frames)
849 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
852 if (stream == NULL || dsp_frames == NULL)
855 pthread_mutex_lock(&out->common.lock);
856 uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
857 if (out->frames_rendered >= latency_frames) {
858 *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
862 pthread_mutex_unlock(&out->common.lock);
866 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
875 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
888 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
890 struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
893 return in->common.cfg.rate;
896 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
898 struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
902 if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
908 static size_t in_get_buffer_size(const struct audio_stream *stream)
916 static uint32_t in_get_channels(const struct audio_stream *stream)
918 struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
921 return in->common.cfg.channel_flags;
924 static audio_format_t in_get_format(const struct audio_stream *stream)
929 return AUDIO_FORMAT_PCM_16_BIT;
932 static int in_set_format(struct audio_stream *stream, audio_format_t format)
938 if (format == AUDIO_FORMAT_PCM_16_BIT)
944 static int in_standby(struct audio_stream *stream)
952 static int in_dump(const struct audio_stream *stream, int fd)
961 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
970 static char * in_get_parameters(const struct audio_stream *stream,
980 static int in_set_gain(struct audio_stream_in *stream, float gain)
989 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
992 struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
996 DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
998 pthread_mutex_lock(&in->common.lock);
999 if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED ||
1000 in->common.state == AUDIO_A2DP_STATE_STOPPING)
1002 DEBUG("stream suspended");
1006 /* only allow autostarting if we are in stopped or standby */
1007 if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) ||
1008 (in->common.state == AUDIO_A2DP_STATE_STANDBY))
1010 if (start_audio_datapath(&in->common) < 0)
1015 else if (in->common.state != AUDIO_A2DP_STATE_STARTED)
1017 ERROR("stream not in stopped or standby");
1021 pthread_mutex_unlock(&in->common.lock);
1022 read = skt_read(in->common.audio_fd, buffer, bytes);
1023 pthread_mutex_lock(&in->common.lock);
1026 skt_disconnect(in->common.audio_fd);
1027 in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
1028 if ((in->common.state != AUDIO_A2DP_STATE_SUSPENDED) &&
1029 (in->common.state != AUDIO_A2DP_STATE_STOPPING)) {
1030 in->common.state = AUDIO_A2DP_STATE_STOPPED;
1032 ERROR("read failed : stream suspended, avoid resetting state");
1035 } else if (read == 0) {
1036 DEBUG("read time out - return zeros");
1037 memset(buffer, 0, bytes);
1040 pthread_mutex_unlock(&in->common.lock);
1042 DEBUG("read %d bytes out of %zu bytes", read, bytes);
1046 pthread_mutex_unlock(&in->common.lock);
1047 memset(buffer, 0, bytes);
1048 us_delay = calc_audiotime(in->common.cfg, bytes);
1049 DEBUG("emulate a2dp read delay (%d us)", us_delay);
1055 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
1063 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1072 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
1082 static int adev_open_output_stream(struct audio_hw_device *dev,
1083 audio_io_handle_t handle,
1084 audio_devices_t devices,
1085 audio_output_flags_t flags,
1086 struct audio_config *config,
1087 struct audio_stream_out **stream_out,
1088 const char *address)
1091 struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1092 struct a2dp_stream_out *out;
1099 INFO("opening output");
1101 out = (struct a2dp_stream_out *)calloc(1, sizeof(struct a2dp_stream_out));
1106 out->stream.common.get_sample_rate = out_get_sample_rate;
1107 out->stream.common.set_sample_rate = out_set_sample_rate;
1108 out->stream.common.get_buffer_size = out_get_buffer_size;
1109 out->stream.common.get_channels = out_get_channels;
1110 out->stream.common.get_format = out_get_format;
1111 out->stream.common.set_format = out_set_format;
1112 out->stream.common.standby = out_standby;
1113 out->stream.common.dump = out_dump;
1114 out->stream.common.set_parameters = out_set_parameters;
1115 out->stream.common.get_parameters = out_get_parameters;
1116 out->stream.common.add_audio_effect = out_add_audio_effect;
1117 out->stream.common.remove_audio_effect = out_remove_audio_effect;
1118 out->stream.get_latency = out_get_latency;
1119 out->stream.set_volume = out_set_volume;
1120 out->stream.write = out_write;
1121 out->stream.get_render_position = out_get_render_position;
1122 out->stream.get_presentation_position = out_get_presentation_position;
1125 /* initialize a2dp specifics */
1126 a2dp_stream_common_init(&out->common);
1128 out->common.cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG;
1129 out->common.cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
1130 out->common.cfg.rate = AUDIO_STREAM_DEFAULT_RATE;
1132 /* set output config values */
1135 config->format = out_get_format((const struct audio_stream *)&out->stream);
1136 config->sample_rate = out_get_sample_rate((const struct audio_stream *)&out->stream);
1137 config->channel_mask = out_get_channels((const struct audio_stream *)&out->stream);
1139 *stream_out = &out->stream;
1140 a2dp_dev->output = out;
1142 a2dp_open_ctrl_path(&out->common);
1143 if (out->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
1145 ERROR("ctrl socket failed to connect (%s)", strerror(errno));
1151 /* Delay to ensure Headset is in proper state when START is initiated
1152 from DUT immediately after the connection due to ongoing music playback. */
1159 a2dp_dev->output = NULL;
1164 static void adev_close_output_stream(struct audio_hw_device *dev,
1165 struct audio_stream_out *stream)
1167 struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1168 struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
1170 INFO("closing output (state %d)", out->common.state);
1172 pthread_mutex_lock(&out->common.lock);
1173 if ((out->common.state == AUDIO_A2DP_STATE_STARTED) ||
1174 (out->common.state == AUDIO_A2DP_STATE_STOPPING)) {
1175 stop_audio_datapath(&out->common);
1178 skt_disconnect(out->common.ctrl_fd);
1179 out->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
1181 a2dp_dev->output = NULL;
1182 pthread_mutex_unlock(&out->common.lock);
1187 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
1189 struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1190 struct a2dp_stream_out *out = a2dp_dev->output;
1196 INFO("state %d", out->common.state);
1198 retval = out->stream.common.set_parameters((struct audio_stream *)out, kvpairs);
1203 static char * adev_get_parameters(const struct audio_hw_device *dev,
1210 hash_map_t *params = hash_map_utils_new_from_string_params(keys);
1211 hash_map_utils_dump_string_keys_string_values(params);
1212 hash_map_free(params);
1217 static int adev_init_check(const struct audio_hw_device *dev)
1225 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
1235 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
1245 static int adev_set_mode(struct audio_hw_device *dev, int mode)
1255 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
1265 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
1275 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
1276 const struct audio_config *config)
1286 static int adev_open_input_stream(struct audio_hw_device *dev,
1287 audio_io_handle_t handle,
1288 audio_devices_t devices,
1289 struct audio_config *config,
1290 struct audio_stream_in **stream_in,
1291 audio_input_flags_t flags,
1292 const char *address,
1293 audio_source_t source)
1295 struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1296 struct a2dp_stream_in *in;
1307 in = (struct a2dp_stream_in *)calloc(1, sizeof(struct a2dp_stream_in));
1312 in->stream.common.get_sample_rate = in_get_sample_rate;
1313 in->stream.common.set_sample_rate = in_set_sample_rate;
1314 in->stream.common.get_buffer_size = in_get_buffer_size;
1315 in->stream.common.get_channels = in_get_channels;
1316 in->stream.common.get_format = in_get_format;
1317 in->stream.common.set_format = in_set_format;
1318 in->stream.common.standby = in_standby;
1319 in->stream.common.dump = in_dump;
1320 in->stream.common.set_parameters = in_set_parameters;
1321 in->stream.common.get_parameters = in_get_parameters;
1322 in->stream.common.add_audio_effect = in_add_audio_effect;
1323 in->stream.common.remove_audio_effect = in_remove_audio_effect;
1324 in->stream.set_gain = in_set_gain;
1325 in->stream.read = in_read;
1326 in->stream.get_input_frames_lost = in_get_input_frames_lost;
1328 /* initialize a2dp specifics */
1329 a2dp_stream_common_init(&in->common);
1331 *stream_in = &in->stream;
1332 a2dp_dev->input = in;
1334 a2dp_open_ctrl_path(&in->common);
1335 if (in->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
1337 ERROR("ctrl socket failed to connect (%s)", strerror(errno));
1342 if (a2dp_read_audio_config(&in->common) < 0) {
1343 ERROR("a2dp_read_audio_config failed (%s)", strerror(errno));
1354 a2dp_dev->input = NULL;
1359 static void adev_close_input_stream(struct audio_hw_device *dev,
1360 struct audio_stream_in *stream)
1362 struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
1363 struct a2dp_stream_in* in = (struct a2dp_stream_in *)stream;
1364 a2dp_state_t state = in->common.state;
1366 INFO("closing input (state %d)", state);
1368 if ((state == AUDIO_A2DP_STATE_STARTED) || (state == AUDIO_A2DP_STATE_STOPPING))
1369 stop_audio_datapath(&in->common);
1371 skt_disconnect(in->common.ctrl_fd);
1372 in->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
1374 a2dp_dev->input = NULL;
1379 static int adev_dump(const audio_hw_device_t *device, int fd)
1389 static int adev_close(hw_device_t *device)
1397 static int adev_open(const hw_module_t* module, const char* name,
1398 hw_device_t** device)
1400 struct a2dp_audio_device *adev;
1402 INFO(" adev_open in A2dp_hw module");
1405 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
1407 ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
1411 adev = calloc(1, sizeof(struct a2dp_audio_device));
1416 adev->device.common.tag = HARDWARE_DEVICE_TAG;
1417 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
1418 adev->device.common.module = (struct hw_module_t *) module;
1419 adev->device.common.close = adev_close;
1421 adev->device.init_check = adev_init_check;
1422 adev->device.set_voice_volume = adev_set_voice_volume;
1423 adev->device.set_master_volume = adev_set_master_volume;
1424 adev->device.set_mode = adev_set_mode;
1425 adev->device.set_mic_mute = adev_set_mic_mute;
1426 adev->device.get_mic_mute = adev_get_mic_mute;
1427 adev->device.set_parameters = adev_set_parameters;
1428 adev->device.get_parameters = adev_get_parameters;
1429 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
1430 adev->device.open_output_stream = adev_open_output_stream;
1431 adev->device.close_output_stream = adev_close_output_stream;
1432 adev->device.open_input_stream = adev_open_input_stream;
1433 adev->device.close_input_stream = adev_close_input_stream;
1434 adev->device.dump = adev_dump;
1436 adev->output = NULL;
1439 *device = &adev->device.common;
1444 static struct hw_module_methods_t hal_module_methods = {
1448 __attribute__ ((visibility ("default")))
1449 struct audio_module HAL_MODULE_INFO_SYM = {
1451 .tag = HARDWARE_MODULE_TAG,
1454 .id = AUDIO_HARDWARE_MODULE_ID,
1455 .name = "A2DP Audio HW HAL",
1456 .author = "The Android Open Source Project",
1457 .methods = &hal_module_methods,