2014-11-05 08:41:16

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCH 1/7] android/hal-sco: Add support for new Android API

From: Andrei Emeltchenko <[email protected]>

Add new parameters to sco_open_input_stream() and
sco_open_output_stream() for the new API.
---
android/hal-sco.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 59 insertions(+), 4 deletions(-)

diff --git a/android/hal-sco.c b/android/hal-sco.c
index 91a3baf..d9c9a68 100644
--- a/android/hal-sco.c
+++ b/android/hal-sco.c
@@ -612,12 +612,13 @@ static int out_remove_audio_effect(const struct audio_stream *stream,
return -ENOSYS;
}

-static int sco_open_output_stream(struct audio_hw_device *dev,
+static int sco_open_output_stream_real(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)
+ struct audio_stream_out **stream_out,
+ const char *address)
{
struct sco_dev *adev = (struct sco_dev *) dev;
struct sco_stream_out *out;
@@ -741,6 +742,31 @@ failed:
return ret;
}

+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+static int sco_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)
+{
+ return sco_open_output_stream_real(dev, handle, devices, flags,
+ config, stream_out, address);
+}
+#else
+static int sco_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)
+{
+ return sco_open_output_stream_real(dev, handle, devices, flags,
+ config, stream_out, NULL);
+}
+#endif
+
static void sco_close_output_stream(struct audio_hw_device *dev,
struct audio_stream_out *stream_out)
{
@@ -1060,11 +1086,14 @@ static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
return -ENOSYS;
}

-static int sco_open_input_stream(struct audio_hw_device *dev,
+static int sco_open_input_stream_real(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
- struct audio_stream_in **stream_in)
+ struct audio_stream_in **stream_in,
+ audio_input_flags_t flags,
+ const char *address,
+ audio_source_t source)
{
struct sco_dev *sco_dev = (struct sco_dev *) dev;
struct sco_stream_in *in;
@@ -1165,6 +1194,32 @@ failed2:
return ret;
}

+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+static int sco_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)
+{
+ return sco_open_input_stream_real(dev, handle, devices, config,
+ stream_in, flags, address,
+ source);
+}
+#else
+static int sco_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)
+{
+ return sco_open_input_stream_real(dev, handle, devices, config,
+ stream_in, 0, NULL, 0);
+}
+#endif
+
static void sco_close_input_stream(struct audio_hw_device *dev,
struct audio_stream_in *stream_in)
{
--
1.9.1



2014-11-05 11:26:41

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH 1/7] android/hal-sco: Add support for new Android API

Hi Andrei,

On Wednesday 05 of November 2014 10:41:16 Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <[email protected]>
>
> Add new parameters to sco_open_input_stream() and
> sco_open_output_stream() for the new API.
> ---
> android/hal-sco.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 59 insertions(+), 4 deletions(-)
>
> diff --git a/android/hal-sco.c b/android/hal-sco.c
> index 91a3baf..d9c9a68 100644
> --- a/android/hal-sco.c
> +++ b/android/hal-sco.c
> @@ -612,12 +612,13 @@ static int out_remove_audio_effect(const struct audio_stream *stream,
> return -ENOSYS;
> }
>
> -static int sco_open_output_stream(struct audio_hw_device *dev,
> +static int sco_open_output_stream_real(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)
> + struct audio_stream_out **stream_out,
> + const char *address)
> {
> struct sco_dev *adev = (struct sco_dev *) dev;
> struct sco_stream_out *out;
> @@ -741,6 +742,31 @@ failed:
> return ret;
> }
>
> +#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
> +static int sco_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)
> +{
> + return sco_open_output_stream_real(dev, handle, devices, flags,
> + config, stream_out, address);
> +}
> +#else
> +static int sco_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)
> +{
> + return sco_open_output_stream_real(dev, handle, devices, flags,
> + config, stream_out, NULL);
> +}
> +#endif
> +
> static void sco_close_output_stream(struct audio_hw_device *dev,
> struct audio_stream_out *stream_out)
> {
> @@ -1060,11 +1086,14 @@ static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
> return -ENOSYS;
> }
>
> -static int sco_open_input_stream(struct audio_hw_device *dev,
> +static int sco_open_input_stream_real(struct audio_hw_device *dev,
> audio_io_handle_t handle,
> audio_devices_t devices,
> struct audio_config *config,
> - struct audio_stream_in **stream_in)
> + struct audio_stream_in **stream_in,
> + audio_input_flags_t flags,
> + const char *address,
> + audio_source_t source)
> {
> struct sco_dev *sco_dev = (struct sco_dev *) dev;
> struct sco_stream_in *in;
> @@ -1165,6 +1194,32 @@ failed2:
> return ret;
> }
>
> +#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
> +static int sco_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)
> +{
> + return sco_open_input_stream_real(dev, handle, devices, config,
> + stream_in, flags, address,
> + source);
> +}
> +#else
> +static int sco_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)
> +{
> + return sco_open_input_stream_real(dev, handle, devices, config,
> + stream_in, 0, NULL, 0);
> +}
> +#endif
> +
> static void sco_close_input_stream(struct audio_hw_device *dev,
> struct audio_stream_in *stream_in)
> {

All patches in this set have been applied, thanks.

--
Best regards,
Szymon Janc

2014-11-05 08:41:17

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCH 2/7] android/hal-sco: Remove deprecated API usage

From: Andrei Emeltchenko <[email protected]>

Instead of deprecated functions use new ones. Fixes deprecation warnings
during build.
---
android/hal-sco.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/android/hal-sco.c b/android/hal-sco.c
index d9c9a68..ca3022e 100644
--- a/android/hal-sco.c
+++ b/android/hal-sco.c
@@ -438,7 +438,11 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
struct sco_stream_out *out = (struct sco_stream_out *) stream;
+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+ size_t frame_num = bytes / audio_stream_out_frame_size(stream);
+#else
size_t frame_num = bytes / audio_stream_frame_size(&out->stream.common);
+#endif
size_t output_frame_num = frame_num;
void *send_buf = out->downmix_buf;
size_t total;
@@ -507,8 +511,13 @@ static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
static size_t out_get_buffer_size(const struct audio_stream *stream)
{
struct sco_stream_out *out = (struct sco_stream_out *) stream;
+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+ size_t size = audio_stream_out_frame_size(&out->stream) *
+ out->cfg.frame_num;
+#else
size_t size = audio_stream_frame_size(&out->stream.common) *
out->cfg.frame_num;
+#endif

/* buffer size without resampling */
if (out->cfg.rate == AUDIO_STREAM_SCO_RATE)
@@ -880,8 +889,13 @@ static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
static size_t in_get_buffer_size(const struct audio_stream *stream)
{
struct sco_stream_in *in = (struct sco_stream_in *) stream;
+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+ size_t size = audio_stream_in_frame_size(&in->stream) *
+ in->cfg.frame_num;
+#else
size_t size = audio_stream_frame_size(&in->stream.common) *
in->cfg.frame_num;
+#endif

/* buffer size without resampling */
if (in->cfg.rate == AUDIO_STREAM_SCO_RATE)
@@ -1024,7 +1038,11 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
size_t bytes)
{
struct sco_stream_in *in = (struct sco_stream_in *) stream;
+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+ size_t frame_size = audio_stream_in_frame_size(&in->stream);
+#else
size_t frame_size = audio_stream_frame_size(&stream->common);
+#endif
size_t frame_num = bytes / frame_size;
size_t input_frame_num = frame_num;
void *read_buf = buffer;
--
1.9.1


2014-11-05 08:41:20

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCH 5/7] android/hal-sco: Save bd_addr for input stream of Audio SCO HAL

From: Andrei Emeltchenko <[email protected]>

Make use of address field which makes possible to query right SCO fd
from handsfree multi-client code.
---
android/hal-sco.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/android/hal-sco.c b/android/hal-sco.c
index e84dae0..442e2d0 100644
--- a/android/hal-sco.c
+++ b/android/hal-sco.c
@@ -103,6 +103,8 @@ struct sco_stream_in {
struct resampler_itfe *resampler;
int16_t *resample_buf;
uint32_t resample_frame_num;
+
+ bt_bdaddr_t bd_addr;
};

struct sco_dev {
@@ -1158,6 +1160,14 @@ static int sco_open_input_stream_real(struct audio_hw_device *dev,
in->stream.read = in_read;
in->stream.get_input_frames_lost = in_get_input_frames_lost;

+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+ if (address) {
+ DBG("address %s", address);
+
+ str2bt_bdaddr_t(address, &in->bd_addr);
+ }
+#endif
+
if (config) {
DBG("config: rate %u chan mask %x format %d offload %p",
config->sample_rate, config->channel_mask,
--
1.9.1


2014-11-05 08:41:22

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCH 7/7] android/hal-sco: Use bdaddr parameter in Get SCO fd command

From: Andrei Emeltchenko <[email protected]>

---
android/hal-sco.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/android/hal-sco.c b/android/hal-sco.c
index 442e2d0..6c4e975 100644
--- a/android/hal-sco.c
+++ b/android/hal-sco.c
@@ -281,20 +281,23 @@ failed:
return SCO_STATUS_FAILED;
}

-static int ipc_get_sco_fd(void)
+static int ipc_get_sco_fd(bt_bdaddr_t *bd_addr)
{
int ret = SCO_STATUS_SUCCESS;

pthread_mutex_lock(&sco_mutex);

if (sco_fd < 0) {
+ struct sco_cmd_get_fd cmd;
struct sco_rsp_get_fd rsp;
size_t rsp_len = sizeof(rsp);

DBG("Getting SCO fd");

- ret = sco_ipc_cmd(SCO_SERVICE_ID, SCO_OP_GET_FD, 0, NULL,
- &rsp_len, &rsp, &sco_fd);
+ memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
+
+ ret = sco_ipc_cmd(SCO_SERVICE_ID, SCO_OP_GET_FD, sizeof(cmd),
+ &cmd, &rsp_len, &rsp, &sco_fd);

/* Sometimes mtu returned is wrong */
sco_mtu = /* rsp.mtu */ 48;
@@ -453,7 +456,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,

DBG("write to fd %d bytes %zu", sco_fd, bytes);

- if (ipc_get_sco_fd() != SCO_STATUS_SUCCESS)
+ if (ipc_get_sco_fd(&out->bd_addr) != SCO_STATUS_SUCCESS)
return -1;

if (!out->downmix_buf) {
@@ -645,9 +648,6 @@ static int sco_open_output_stream_real(struct audio_hw_device *dev,
return -EIO;
}

- if (ipc_get_sco_fd() != SCO_STATUS_SUCCESS)
- DBG("SCO is not connected yet; get fd on write()");
-
out = calloc(1, sizeof(struct sco_stream_out));
if (!out)
return -ENOMEM;
@@ -679,6 +679,9 @@ static int sco_open_output_stream_real(struct audio_hw_device *dev,
}
#endif

+ if (ipc_get_sco_fd(&out->bd_addr) != SCO_STATUS_SUCCESS)
+ DBG("SCO is not connected yet; get fd on write()");
+
if (config) {
DBG("config: rate %u chan mask %x format %d offload %p",
config->sample_rate, config->channel_mask,
@@ -1063,7 +1066,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,

DBG("Read from fd %d bytes %zu", sco_fd, bytes);

- if (ipc_get_sco_fd() != SCO_STATUS_SUCCESS)
+ if (ipc_get_sco_fd(&in->bd_addr) != SCO_STATUS_SUCCESS)
return -1;

if (!in->resampler && in->cfg.rate != AUDIO_STREAM_SCO_RATE) {
--
1.9.1


2014-11-05 08:41:21

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCH 6/7] android/hal-sco: Add remote address parameter in Get SCO fd command

From: Andrei Emeltchenko <[email protected]>

---
android/sco-ipc-api.txt | 2 +-
android/sco-msg.h | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/android/sco-ipc-api.txt b/android/sco-ipc-api.txt
index 17372fe..27d5ef2 100644
--- a/android/sco-ipc-api.txt
+++ b/android/sco-ipc-api.txt
@@ -32,6 +32,6 @@ SCO Audio Service (ID 0)

Opcode 0x01 - Get SCO fd command

- Command parameters: <none>
+ Command parameters: Remote address (6 octets)
Response parameters: MTU (2 octets)
File descriptor (inline)
diff --git a/android/sco-msg.h b/android/sco-msg.h
index 74f25b8..d1b13d7 100644
--- a/android/sco-msg.h
+++ b/android/sco-msg.h
@@ -31,6 +31,10 @@ static const char BLUEZ_SCO_SK_PATH[] = "\0bluez_sco_socket";
#define SCO_OP_STATUS IPC_OP_STATUS

#define SCO_OP_GET_FD 0x01
+struct sco_cmd_get_fd {
+ uint8_t bdaddr[6];
+} __attribute__((packed));
+
struct sco_rsp_get_fd {
uint16_t mtu;
} __attribute__((packed));
--
1.9.1


2014-11-05 08:41:19

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCH 4/7] android/hal-sco: Save bd_addr for output stream of Audio SCO HAL

From: Andrei Emeltchenko <[email protected]>

Make use of address field which makes possible to query right SCO fd
from handsfree multi-client code.
---
android/Android.mk | 3 ++-
android/hal-sco.c | 10 ++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/android/Android.mk b/android/Android.mk
index aefe41c..bfdf03f 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -382,7 +382,8 @@ include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

-LOCAL_SRC_FILES := bluez/android/hal-sco.c
+LOCAL_SRC_FILES := bluez/android/hal-sco.c \
+ bluez/android/hal-utils.c

LOCAL_C_INCLUDES = \
$(call include-path-for, system-core) \
diff --git a/android/hal-sco.c b/android/hal-sco.c
index c5b86b0..e84dae0 100644
--- a/android/hal-sco.c
+++ b/android/hal-sco.c
@@ -79,6 +79,8 @@ struct sco_stream_out {
struct resampler_itfe *resampler;
int16_t *resample_buf;
uint32_t resample_frame_num;
+
+ bt_bdaddr_t bd_addr;
};

static void sco_close_socket(void)
@@ -667,6 +669,14 @@ static int sco_open_output_stream_real(struct audio_hw_device *dev,
out->stream.write = out_write;
out->stream.get_render_position = out_get_render_position;

+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+ if (address) {
+ DBG("address %s", address);
+
+ str2bt_bdaddr_t(address, &out->bd_addr);
+ }
+#endif
+
if (config) {
DBG("config: rate %u chan mask %x format %d offload %p",
config->sample_rate, config->channel_mask,
--
1.9.1


2014-11-05 08:41:18

by Andrei Emeltchenko

[permalink] [raw]
Subject: [PATCH 3/7] android/hal-sco: Implement dummy SCO HAL functions

From: Andrei Emeltchenko <[email protected]>

Prevent from crash and print debug statements.
---
android/hal-sco.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)

diff --git a/android/hal-sco.c b/android/hal-sco.c
index ca3022e..c5b86b0 100644
--- a/android/hal-sco.c
+++ b/android/hal-sco.c
@@ -1271,6 +1271,51 @@ static int sco_dump(const audio_hw_device_t *device, int fd)
return 0;
}

+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+static int set_master_mute(struct audio_hw_device *dev, bool mute)
+{
+ DBG("");
+ return -ENOSYS;
+}
+
+static int get_master_mute(struct audio_hw_device *dev, bool *mute)
+{
+ DBG("");
+ return -ENOSYS;
+}
+
+static int create_audio_patch(struct audio_hw_device *dev,
+ unsigned int num_sources,
+ const struct audio_port_config *sources,
+ unsigned int num_sinks,
+ const struct audio_port_config *sinks,
+ audio_patch_handle_t *handle)
+{
+ DBG("");
+ return -ENOSYS;
+}
+
+static int release_audio_patch(struct audio_hw_device *dev,
+ audio_patch_handle_t handle)
+{
+ DBG("");
+ return -ENOSYS;
+}
+
+static int get_audio_port(struct audio_hw_device *dev, struct audio_port *port)
+{
+ DBG("");
+ return -ENOSYS;
+}
+
+static int set_audio_port_config(struct audio_hw_device *dev,
+ const struct audio_port_config *config)
+{
+ DBG("");
+ return -ENOSYS;
+}
+#endif
+
static int sco_close(hw_device_t *device)
{
DBG("");
@@ -1424,6 +1469,14 @@ static int sco_open(const hw_module_t *module, const char *name,
dev->dev.open_input_stream = sco_open_input_stream;
dev->dev.close_input_stream = sco_close_input_stream;
dev->dev.dump = sco_dump;
+#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
+ dev->dev.set_master_mute = set_master_mute;
+ dev->dev.get_master_mute = get_master_mute;
+ dev->dev.create_audio_patch = create_audio_patch;
+ dev->dev.release_audio_patch = release_audio_patch;
+ dev->dev.get_audio_port = get_audio_port;
+ dev->dev.set_audio_port_config = set_audio_port_config;
+#endif

*device = &dev->dev.common;

--
1.9.1