Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] android/pan: Fix wrong freeing dev
From: Andrei Emeltchenko @ 2014-01-22 10:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

It does make sense free() dev after it is used. g_free() is not needed
here since it will be already executed in bt_pan_notify_conn_state().
---
 android/pan.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/android/pan.c b/android/pan.c
index bfba128..4e04da0 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -463,7 +463,6 @@ static void nap_confirm_cb(GIOChannel *chan, gpointer data)
 	return;
 
 failed:
-	g_free(dev);
 	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v3 10/10] android/hal-audio: Return proper latency for stream
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

This patch implements get_latency() for output stream properly by
returning some meaningful value, i.e. calculated duration of single
media packet increased by fixed A2DP playback latency. This is the
same as PulseAudio does.
---
 android/hal-audio.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index ddc6348..9fe46d6 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -35,6 +35,8 @@
 #include "../profiles/audio/a2dp-codecs.h"
 #include <sbc/sbc.h>
 
+#define FIXED_A2DP_PLAYBACK_LATENCY_MS 25
+
 static const uint8_t a2dp_src_uuid[] = {
 		0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00,
 		0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb };
@@ -125,6 +127,7 @@ struct sbc_data {
 	uint8_t *out_buf;
 
 	unsigned frame_duration;
+	unsigned frames_per_packet;
 
 	struct timespec start;
 	unsigned frames_sent;
@@ -151,6 +154,7 @@ static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
 static size_t sbc_get_buffer_size(void *codec_data);
+static size_t sbc_get_mediapacket_duration(void *codec_data);
 static void sbc_resume(void *codec_data);
 static ssize_t sbc_write_data(void *codec_data, const void *buffer,
 					size_t bytes, int fd);
@@ -166,6 +170,7 @@ struct audio_codec {
 	int (*get_config) (void *codec_data,
 					struct audio_input_config *config);
 	size_t (*get_buffer_size) (void *codec_data);
+	size_t (*get_mediapacket_duration) (void *codec_data);
 	void (*resume) (void *codec_data);
 	ssize_t (*write_data) (void *codec_data, const void *buffer,
 				size_t bytes, int fd);
@@ -181,6 +186,7 @@ static const struct audio_codec audio_codecs[] = {
 		.cleanup = sbc_cleanup,
 		.get_config = sbc_get_config,
 		.get_buffer_size = sbc_get_buffer_size,
+		.get_mediapacket_duration = sbc_get_mediapacket_duration,
 		.resume = sbc_resume,
 		.write_data = sbc_write_data,
 	}
@@ -330,6 +336,7 @@ static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
 	sbc_data->out_buf = calloc(1, sbc_data->out_buf_size);
 
 	sbc_data->frame_duration = sbc_get_frame_duration(&sbc_data->enc);
+	sbc_data->frames_per_packet = num_frames;
 
 	*codec_data = sbc_data;
 
@@ -387,6 +394,15 @@ static size_t sbc_get_buffer_size(void *codec_data)
 	return sbc_data->in_buf_size;
 }
 
+static size_t sbc_get_mediapacket_duration(void *codec_data)
+{
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+
+	DBG("");
+
+	return sbc_data->frame_duration * sbc_data->frames_per_packet;
+}
+
 static void sbc_resume(void *codec_data)
 {
 	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
@@ -948,8 +964,15 @@ static char *out_get_parameters(const struct audio_stream *stream,
 
 static uint32_t out_get_latency(const struct audio_stream_out *stream)
 {
+	struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+	struct audio_endpoint *ep = out->ep;
+	size_t pkt_duration;
+
 	DBG("");
-	return 0;
+
+	pkt_duration = ep->codec->get_mediapacket_duration(ep->codec_data);
+
+	return FIXED_A2DP_PLAYBACK_LATENCY_MS + pkt_duration / 1000;
 }
 
 static int out_set_volume(struct audio_stream_out *stream, float left,
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 09/10] android/hal-audio: Add proper SBC encoding
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

Input and output stream is configured in a way that each input buffer
can be encoded to exactly one output buffer.

Reading from AudioFlinger is synchronized based on amounts of frames
which were expected to be sent since stream was resumed, i.e. as long
as we sent enough data we can wait for period of single media packet
before we need another buffer from input. Without synchronization
we'd receive next input buffer as soon as we process current one.
---
 android/hal-audio.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 99 insertions(+), 3 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 81a452a..ddc6348 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -24,6 +24,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <unistd.h>
+#include <arpa/inet.h>
 
 #include <hardware/audio.h>
 #include <hardware/hardware.h>
@@ -127,8 +128,22 @@ struct sbc_data {
 
 	struct timespec start;
 	unsigned frames_sent;
+
+	uint16_t seq;
 };
 
+static inline void timespec_diff(struct timespec *a, struct timespec *b,
+					struct timespec *res)
+{
+	res->tv_sec = a->tv_sec - b->tv_sec;
+	res->tv_nsec = a->tv_nsec - b->tv_nsec;
+
+	if (res->tv_nsec < 0) {
+		res->tv_sec--;
+		res->tv_nsec += 1000000000; /* 1sec */
+	}
+}
+
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
 static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
 				void **codec_data);
@@ -137,6 +152,8 @@ static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
 static size_t sbc_get_buffer_size(void *codec_data);
 static void sbc_resume(void *codec_data);
+static ssize_t sbc_write_data(void *codec_data, const void *buffer,
+					size_t bytes, int fd);
 
 struct audio_codec {
 	uint8_t type;
@@ -151,7 +168,7 @@ struct audio_codec {
 	size_t (*get_buffer_size) (void *codec_data);
 	void (*resume) (void *codec_data);
 	ssize_t (*write_data) (void *codec_data, const void *buffer,
-				size_t bytes);
+				size_t bytes, int fd);
 };
 
 static const struct audio_codec audio_codecs[] = {
@@ -165,6 +182,7 @@ static const struct audio_codec audio_codecs[] = {
 		.get_config = sbc_get_config,
 		.get_buffer_size = sbc_get_buffer_size,
 		.resume = sbc_resume,
+		.write_data = sbc_write_data,
 	}
 };
 
@@ -380,6 +398,80 @@ static void sbc_resume(void *codec_data)
 	sbc_data->frames_sent = 0;
 }
 
+static ssize_t sbc_write_data(void *codec_data, const void *buffer,
+				size_t bytes, int fd)
+{
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+	size_t consumed = 0;
+	size_t encoded = 0;
+	struct media_packet *mp = (struct media_packet *) sbc_data->out_buf;
+	size_t free_space = sbc_data->out_buf_size - sizeof(*mp);
+	struct timespec cur;
+	struct timespec diff;
+	unsigned expected_frames;
+	int ret;
+
+	mp->hdr.v = 2;
+	mp->hdr.pt = 1;
+	mp->hdr.sequence_number = htons(sbc_data->seq++);
+	mp->hdr.ssrc = htonl(1);
+	mp->payload.frame_count = 0;
+
+	while (bytes - consumed >= sbc_data->in_frame_len) {
+		ssize_t written = 0;
+
+		ret = sbc_encode(&sbc_data->enc, buffer + consumed,
+					sbc_data->in_frame_len,
+					mp->data + encoded, free_space,
+					&written);
+
+		if (ret < 0) {
+			DBG("failed to encode block");
+			break;
+		}
+
+		mp->payload.frame_count++;
+
+		consumed += ret;
+		encoded += written;
+		free_space -= written;
+	}
+
+	ret = write(fd, mp, sizeof(*mp) + encoded);
+	if (ret < 0) {
+		int err = errno;
+		DBG("error writing data: %d (%s)", err, strerror(err));
+	}
+
+	if (consumed != bytes || free_space != 0) {
+		/* we should encode all input data and fill output buffer
+		 * if we did not, something went wrong but we can't really
+		 * handle this so this is just sanity check
+		 */
+		DBG("some data were not encoded");
+	}
+
+	sbc_data->frames_sent += mp->payload.frame_count;
+
+	clock_gettime(CLOCK_MONOTONIC, &cur);
+	timespec_diff(&cur, &sbc_data->start, &diff);
+	expected_frames = (diff.tv_sec * 1000000 + diff.tv_nsec / 1000) /
+				sbc_data->frame_duration;
+
+	/* AudioFlinger does not seem to provide any *working* API to provide
+	 * data in some interval and will just send another buffer as soon as
+	 * we process current one. To prevent overflowing L2CAP socket, we need
+	 * to introduce some artificial delay here base on how many audio frames
+	 * were sent so far, i.e. if we're not lagging behind audio stream, we
+	 * can sleep for duration of single media packet.
+	 */
+	if (sbc_data->frames_sent >= expected_frames)
+		usleep(sbc_data->frame_duration * mp->payload.frame_count);
+
+	/* we always assume that all data was processed and sent */
+	return bytes;
+}
+
 static void audio_ipc_cleanup(void)
 {
 	if (audio_sk >= 0) {
@@ -712,9 +804,13 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
 		return -1;
 	}
 
-	/* TODO: encode data using codec */
+	if (out->ep->fd < 0) {
+		DBG("no transport");
+		return -1;
+	}
 
-	return bytes;
+	return out->ep->codec->write_data(out->ep->codec_data, buffer,
+						bytes, out->ep->fd);
 }
 
 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 08/10] android/hal-audio: Read fd from Output Stream response
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 android/hal-audio.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 6e4adf3..81a452a 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -577,7 +577,7 @@ static int ipc_close_cmd(uint8_t endpoint_id)
 	return result;
 }
 
-static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu,
+static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu, int *fd,
 					struct audio_preset **caps)
 {
 	char buf[BLUEZ_AUDIO_MTU];
@@ -595,7 +595,7 @@ static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu,
 	cmd.id = endpoint_id;
 
 	result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
-				sizeof(cmd), &cmd, &rsp_len, rsp, NULL);
+				sizeof(cmd), &cmd, &rsp_len, rsp, fd);
 
 	if (result == AUDIO_STATUS_SUCCESS) {
 		size_t buf_len = sizeof(struct audio_preset) +
@@ -992,6 +992,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 	struct audio_preset *preset;
 	const struct audio_codec *codec;
 	uint16_t mtu;
+	int fd;
 
 	out = calloc(1, sizeof(struct a2dp_stream_out));
 	if (!out)
@@ -1019,13 +1020,15 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 	/* TODO: for now we always use endpoint 0 */
 	out->ep = &audio_endpoints[0];
 
-	if (ipc_open_stream_cmd(out->ep->id, &mtu, &preset) !=
+	if (ipc_open_stream_cmd(out->ep->id, &mtu, &fd, &preset) !=
 			AUDIO_STATUS_SUCCESS)
 		goto fail;
 
-	if (!preset)
+	if (!preset || fd < 0)
 		goto fail;
 
+	out->ep->fd = fd;
+
 	codec = out->ep->codec;
 
 	codec->init(preset, mtu, &out->ep->codec_data);
@@ -1059,6 +1062,11 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
 
 	ipc_close_stream_cmd(ep->id);
 
+	if (ep->fd >= 0) {
+		close(ep->fd);
+		ep->fd = -1;
+	}
+
 	ep->codec->cleanup(ep->codec_data);
 	ep->codec_data = NULL;
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 07/10] android/hal-audio: Return proper buffer size to AudioFlinger
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 android/hal-audio.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index f147cd9..6e4adf3 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -135,6 +135,7 @@ static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
 static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
+static size_t sbc_get_buffer_size(void *codec_data);
 static void sbc_resume(void *codec_data);
 
 struct audio_codec {
@@ -147,6 +148,7 @@ struct audio_codec {
 	int (*cleanup) (void *codec_data);
 	int (*get_config) (void *codec_data,
 					struct audio_input_config *config);
+	size_t (*get_buffer_size) (void *codec_data);
 	void (*resume) (void *codec_data);
 	ssize_t (*write_data) (void *codec_data, const void *buffer,
 				size_t bytes);
@@ -161,6 +163,7 @@ static const struct audio_codec audio_codecs[] = {
 		.init = sbc_codec_init,
 		.cleanup = sbc_cleanup,
 		.get_config = sbc_get_config,
+		.get_buffer_size = sbc_get_buffer_size,
 		.resume = sbc_resume,
 	}
 };
@@ -357,6 +360,15 @@ static int sbc_get_config(void *codec_data,
 	return AUDIO_STATUS_SUCCESS;
 }
 
+static size_t sbc_get_buffer_size(void *codec_data)
+{
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+
+	DBG("");
+
+	return sbc_data->in_buf_size;
+}
+
 static void sbc_resume(void *codec_data)
 {
 	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
@@ -730,8 +742,11 @@ 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 a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+
 	DBG("");
-	return 20 * 512;
+
+	return out->ep->codec->get_buffer_size(out->ep->codec_data);
 }
 
 static uint32_t out_get_channels(const struct audio_stream *stream)
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 06/10] android/hal-audio: Add resume to codec callbacks
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

Once stream is resumed it may be required to reset some state of codec,
i.e. in case of SBC we need to reset monotonic clock and frames count
which are used for synchronization.
---
 android/hal-audio.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 57385aa..f147cd9 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -124,6 +124,9 @@ struct sbc_data {
 	uint8_t *out_buf;
 
 	unsigned frame_duration;
+
+	struct timespec start;
+	unsigned frames_sent;
 };
 
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
@@ -132,6 +135,7 @@ static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
 static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
+static void sbc_resume(void *codec_data);
 
 struct audio_codec {
 	uint8_t type;
@@ -143,6 +147,7 @@ struct audio_codec {
 	int (*cleanup) (void *codec_data);
 	int (*get_config) (void *codec_data,
 					struct audio_input_config *config);
+	void (*resume) (void *codec_data);
 	ssize_t (*write_data) (void *codec_data, const void *buffer,
 				size_t bytes);
 };
@@ -156,6 +161,7 @@ static const struct audio_codec audio_codecs[] = {
 		.init = sbc_codec_init,
 		.cleanup = sbc_cleanup,
 		.get_config = sbc_get_config,
+		.resume = sbc_resume,
 	}
 };
 
@@ -351,6 +357,17 @@ static int sbc_get_config(void *codec_data,
 	return AUDIO_STATUS_SUCCESS;
 }
 
+static void sbc_resume(void *codec_data)
+{
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+
+	DBG("");
+
+	clock_gettime(CLOCK_MONOTONIC, &sbc_data->start);
+
+	sbc_data->frames_sent = 0;
+}
+
 static void audio_ipc_cleanup(void)
 {
 	if (audio_sk >= 0) {
@@ -673,6 +690,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
 		if (ipc_resume_stream_cmd(out->ep->id) != AUDIO_STATUS_SUCCESS)
 			return -1;
 
+		out->ep->codec->resume(out->ep->codec_data);
+
 		out->audio_state = AUDIO_A2DP_STATE_STARTED;
 	}
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 05/10] android/hal-audio: Calculate SBC stream parameters
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

This patch adds necessary calculations for SBC stream parameters.

Both input and output buffers are expected to have exact amount of
data to fill single media packet (based on transport channel MTU).

Frame duration will be used to synchronize input and output streams.
---
 android/hal-audio.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 97 insertions(+), 6 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 8d604db..57385aa 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -46,6 +46,66 @@ static pthread_t ipc_th = 0;
 static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+struct rtp_header {
+	unsigned cc:4;
+	unsigned x:1;
+	unsigned p:1;
+	unsigned v:2;
+
+	unsigned pt:7;
+	unsigned m:1;
+
+	uint16_t sequence_number;
+	uint32_t timestamp;
+	uint32_t ssrc;
+	uint32_t csrc[0];
+} __attribute__ ((packed));
+
+struct rtp_payload {
+	unsigned frame_count:4;
+	unsigned rfa0:1;
+	unsigned is_last_fragment:1;
+	unsigned is_first_fragment:1;
+	unsigned is_fragmented:1;
+} __attribute__ ((packed));
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+struct rtp_header {
+	unsigned v:2;
+	unsigned p:1;
+	unsigned x:1;
+	unsigned cc:4;
+
+	unsigned m:1;
+	unsigned pt:7;
+
+	uint16_t sequence_number;
+	uint32_t timestamp;
+	uint32_t ssrc;
+	uint32_t csrc[0];
+} __attribute__ ((packed));
+
+struct rtp_payload {
+	unsigned is_fragmented:1;
+	unsigned is_first_fragment:1;
+	unsigned is_last_fragment:1;
+	unsigned rfa0:1;
+	unsigned frame_count:4;
+} __attribute__ ((packed));
+
+#else
+#error "Unknown byte order"
+#endif
+
+struct media_packet {
+	struct rtp_header hdr;
+	struct rtp_payload payload;
+	uint8_t data[0];
+};
+
 struct audio_input_config {
 	uint32_t rate;
 	uint32_t channels;
@@ -56,10 +116,19 @@ struct sbc_data {
 	a2dp_sbc_t sbc;
 
 	sbc_t enc;
+
+	size_t in_frame_len;
+	size_t in_buf_size;
+
+	size_t out_buf_size;
+	uint8_t *out_buf;
+
+	unsigned frame_duration;
 };
 
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
-static int sbc_codec_init(struct audio_preset *preset, void **codec_data);
+static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
+				void **codec_data);
 static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
@@ -69,7 +138,8 @@ struct audio_codec {
 
 	int (*get_presets) (struct audio_preset *preset, size_t *len);
 
-	int (*init) (struct audio_preset *preset, void **codec_data);
+	int (*init) (struct audio_preset *preset, uint16_t mtu,
+				void **codec_data);
 	int (*cleanup) (void *codec_data);
 	int (*get_config) (void *codec_data,
 					struct audio_input_config *config);
@@ -200,9 +270,14 @@ static void sbc_init_encoder(struct sbc_data *sbc_data)
 	out->bitpool = in->max_bitpool;
 }
 
-static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
+static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
+				void **codec_data)
 {
 	struct sbc_data *sbc_data;
+	size_t hdr_len = sizeof(struct media_packet);
+	size_t in_frame_len;
+	size_t out_frame_len;
+	size_t num_frames;
 
 	DBG("");
 
@@ -217,6 +292,18 @@ static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 
 	sbc_init_encoder(sbc_data);
 
+	in_frame_len = sbc_get_codesize(&sbc_data->enc);
+	out_frame_len = sbc_get_frame_length(&sbc_data->enc);
+	num_frames = (mtu - hdr_len) / out_frame_len;
+
+	sbc_data->in_frame_len = in_frame_len;
+	sbc_data->in_buf_size = num_frames * in_frame_len;
+
+	sbc_data->out_buf_size = hdr_len + num_frames * out_frame_len;
+	sbc_data->out_buf = calloc(1, sbc_data->out_buf_size);
+
+	sbc_data->frame_duration = sbc_get_frame_duration(&sbc_data->enc);
+
 	*codec_data = sbc_data;
 
 	return AUDIO_STATUS_SUCCESS;
@@ -229,6 +316,7 @@ static int sbc_cleanup(void *codec_data)
 	DBG("");
 
 	sbc_finish(&sbc_data->enc);
+	free(sbc_data->out_buf);
 	free(codec_data);
 
 	return AUDIO_STATUS_SUCCESS;
@@ -460,7 +548,7 @@ static int ipc_close_cmd(uint8_t endpoint_id)
 	return result;
 }
 
-static int ipc_open_stream_cmd(uint8_t endpoint_id,
+static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu,
 					struct audio_preset **caps)
 {
 	char buf[BLUEZ_AUDIO_MTU];
@@ -483,6 +571,7 @@ static int ipc_open_stream_cmd(uint8_t endpoint_id,
 	if (result == AUDIO_STATUS_SUCCESS) {
 		size_t buf_len = sizeof(struct audio_preset) +
 					rsp->preset[0].len;
+		*mtu = rsp->mtu;
 		*caps = malloc(buf_len);
 		memcpy(*caps, &rsp->preset, buf_len);
 	} else {
@@ -868,6 +957,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 	struct a2dp_stream_out *out;
 	struct audio_preset *preset;
 	const struct audio_codec *codec;
+	uint16_t mtu;
 
 	out = calloc(1, sizeof(struct a2dp_stream_out));
 	if (!out)
@@ -895,7 +985,8 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 	/* TODO: for now we always use endpoint 0 */
 	out->ep = &audio_endpoints[0];
 
-	if (ipc_open_stream_cmd(out->ep->id, &preset) != AUDIO_STATUS_SUCCESS)
+	if (ipc_open_stream_cmd(out->ep->id, &mtu, &preset) !=
+			AUDIO_STATUS_SUCCESS)
 		goto fail;
 
 	if (!preset)
@@ -903,7 +994,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 
 	codec = out->ep->codec;
 
-	codec->init(preset, &out->ep->codec_data);
+	codec->init(preset, mtu, &out->ep->codec_data);
 	codec->get_config(out->ep->codec_data, &out->cfg);
 
 	DBG("rate=%d channels=%d format=%d", out->cfg.rate,
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 04/10] android/hal-audio: Initialize SBC encoder
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 android/hal-audio.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index f53dba0..8d604db 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -32,6 +32,7 @@
 #include "hal-log.h"
 #include "hal-msg.h"
 #include "../profiles/audio/a2dp-codecs.h"
+#include <sbc/sbc.h>
 
 static const uint8_t a2dp_src_uuid[] = {
 		0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00,
@@ -53,6 +54,8 @@ struct audio_input_config {
 
 struct sbc_data {
 	a2dp_sbc_t sbc;
+
+	sbc_t enc;
 };
 
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
@@ -184,6 +187,19 @@ static int sbc_get_presets(struct audio_preset *preset, size_t *len)
 	return i;
 }
 
+static void sbc_init_encoder(struct sbc_data *sbc_data)
+{
+	a2dp_sbc_t *in = &sbc_data->sbc;
+	sbc_t *out = &sbc_data->enc;
+
+	DBG("");
+
+	sbc_init_a2dp(out, 0L, in, sizeof(*in));
+
+	out->endian = SBC_LE;
+	out->bitpool = in->max_bitpool;
+}
+
 static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 {
 	struct sbc_data *sbc_data;
@@ -199,6 +215,8 @@ static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 
 	memcpy(&sbc_data->sbc, preset->data, preset->len);
 
+	sbc_init_encoder(sbc_data);
+
 	*codec_data = sbc_data;
 
 	return AUDIO_STATUS_SUCCESS;
@@ -206,8 +224,11 @@ static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 
 static int sbc_cleanup(void *codec_data)
 {
+	struct sbc_data *sbc_data = (struct sbc_data *) codec_data;
+
 	DBG("");
 
+	sbc_finish(&sbc_data->enc);
 	free(codec_data);
 
 	return AUDIO_STATUS_SUCCESS;
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 03/10] android/hal-audio: Rename sbc_init to avoid collision with libsbc
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 android/hal-audio.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 2f6f8c2..f53dba0 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -56,7 +56,7 @@ struct sbc_data {
 };
 
 static int sbc_get_presets(struct audio_preset *preset, size_t *len);
-static int sbc_init(struct audio_preset *preset, void **codec_data);
+static int sbc_codec_init(struct audio_preset *preset, void **codec_data);
 static int sbc_cleanup(void *codec_data);
 static int sbc_get_config(void *codec_data,
 					struct audio_input_config *config);
@@ -80,7 +80,7 @@ static const struct audio_codec audio_codecs[] = {
 
 		.get_presets = sbc_get_presets,
 
-		.init = sbc_init,
+		.init = sbc_codec_init,
 		.cleanup = sbc_cleanup,
 		.get_config = sbc_get_config,
 	}
@@ -184,7 +184,7 @@ static int sbc_get_presets(struct audio_preset *preset, size_t *len)
 	return i;
 }
 
-static int sbc_init(struct audio_preset *preset, void **codec_data)
+static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
 {
 	struct sbc_data *sbc_data;
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 02/10] android: Build Audio HAL with SBC
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

Build for Android requires libsbc sources to be available in
external/bluetooth/sbc. Build for host requires libsbc package to be
installed.
---
 android/Android.mk  | 37 +++++++++++++++++++++++++++++++++++--
 android/Makefile.am |  2 ++
 configure.ac        |  7 +++++++
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index 43e6036..c274295 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -3,8 +3,9 @@ LOCAL_PATH := external/bluetooth
 # Retrieve BlueZ version from configure.ac file
 BLUEZ_VERSION := $(shell grep ^AC_INIT $(LOCAL_PATH)/bluez/configure.ac | cpp -P -D'AC_INIT(_,v)=v')
 
-# Specify pathmap for glib
-pathmap_INCL += glib:external/bluetooth/glib
+# Specify pathmap for glib and sbc
+pathmap_INCL += glib:external/bluetooth/glib \
+	sbc:external/bluetooth/sbc
 
 # Specify common compiler flags
 BLUEZ_COMMON_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\" \
@@ -225,9 +226,11 @@ LOCAL_SRC_FILES := bluez/android/hal-audio.c
 LOCAL_C_INCLUDES = \
 	$(call include-path-for, system-core) \
 	$(call include-path-for, libhardware) \
+	$(call include-path-for, sbc) \
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
+	libsbc \
 
 LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) \
 
@@ -348,3 +351,33 @@ LOCAL_MODULE_TAGS := debug
 LOCAL_MODULE := l2ping
 
 include $(BUILD_EXECUTABLE)
+
+#
+# libsbc
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	sbc/sbc/sbc.c \
+	sbc/sbc/sbc_primitives.c \
+	sbc/sbc/sbc_primitives_mmx.c \
+	sbc/sbc/sbc_primitives_neon.c \
+	sbc/sbc/sbc_primitives_armv6.c \
+	sbc/sbc/sbc_primitives_iwmmxt.c \
+
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/sbc/ \
+	$(LOCAL_PATH)/sbc/sbc/ \
+
+LOCAL_CFLAGS:= \
+	-Os \
+	-Wno-sign-compare \
+	-Wno-missing-field-initializers \
+	-Wno-unused-parameter \
+	-Wno-type-limits \
+	-Wno-empty-body \
+
+LOCAL_MODULE := libsbc
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/android/Makefile.am b/android/Makefile.am
index 910beb5..9045a99 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -149,6 +149,8 @@ android_audio_a2dp_default_la_SOURCES = android/audio-msg.h \
 
 android_audio_a2dp_default_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
 
+android_audio_a2dp_default_la_LIBADD = @SBC_LIBS@
+
 android_audio_a2dp_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
 					-no-undefined -pthread
 
diff --git a/configure.ac b/configure.ac
index b5c87cc..f607d7a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -252,6 +252,13 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
 					[enable_android=${enableval}])
 AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
 
+if (test "${enable_android}" = "yes"); then
+	PKG_CHECK_MODULES(SBC, sbc >= 1.2, dummy=yes,
+					AC_MSG_ERROR(SBC library >= 1.2 is required))
+	AC_SUBST(SBC_CFLAGS)
+	AC_SUBST(SBC_LIBS)
+fi
+
 AC_DEFINE_UNQUOTED(ANDROID_STORAGEDIR, "${storagedir}/android",
 			[Directory for the Android daemon storage files])
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 01/10] android: Add MTU data to Open Stream Audio IPC
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1390386893-8212-1-git-send-email-andrzej.kaczmarek@tieto.com>

MTU value for transport channel is sent in Open Stream response, which
is required to calculate number of frames which can be packed into
single media packet.

This is to avoid including GPLv2 licensed headers in Audio HAL
implementation.
---
 android/a2dp.c      | 8 ++++++--
 android/audio-msg.h | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index a996f79..95ecf9b 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -1304,6 +1304,7 @@ static void bt_stream_open(const void *buf, uint16_t len)
 	struct audio_rsp_open_stream *rsp;
 	struct a2dp_setup *setup;
 	int fd;
+	uint16_t omtu;
 
 	DBG("");
 
@@ -1314,14 +1315,17 @@ static void bt_stream_open(const void *buf, uint16_t len)
 		return;
 	}
 
-	if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, NULL, NULL)) {
+	if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, &omtu,
+						NULL)) {
 		error("avdtp_stream_get_transport: failed");
 		audio_ipc_send_rsp(AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED);
 		return;
 	}
 
-	len = sizeof(struct audio_preset) + setup->preset->len;
+	len = sizeof(struct audio_rsp_open_stream) +
+			sizeof(struct audio_preset) + setup->preset->len;
 	rsp = g_malloc0(len);
+	rsp->mtu = omtu;
 	rsp->preset->len = setup->preset->len;
 	memcpy(rsp->preset->data, setup->preset->data, setup->preset->len);
 
diff --git a/android/audio-msg.h b/android/audio-msg.h
index 8f03274..17cde09 100644
--- a/android/audio-msg.h
+++ b/android/audio-msg.h
@@ -63,6 +63,7 @@ struct audio_cmd_open_stream {
 } __attribute__((packed));
 
 struct audio_rsp_open_stream {
+	uint16_t mtu;
 	struct audio_preset preset[0];
 } __attribute__((packed));
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH v3 00/10] android: Add SBC encoding
From: Andrzej Kaczmarek @ 2014-01-22 10:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

Hi,

v1 -> v2
- fixed comments
- added dependency to libsbc shared library on Android

v2 -> v3
- added comment explaining why we need to sleep in out_write
- updated to new SBC API
- libsbc shared library is now built from our Android.mk
- implemented proper get_latency callback



Andrzej Kaczmarek (10):
  android: Add MTU data to Open Stream Audio IPC
  android: Build Audio HAL with SBC
  android/hal-audio: Rename sbc_init to avoid collision with libsbc
  android/hal-audio: Initialize SBC encoder
  android/hal-audio: Calculate SBC stream parameters
  android/hal-audio: Add resume to codec callbacks
  android/hal-audio: Return proper buffer size to AudioFlinger
  android/hal-audio: Read fd from Output Stream response
  android/hal-audio: Add proper SBC encoding
  android/hal-audio: Return proper latency for stream

 android/Android.mk  |  37 ++++++-
 android/Makefile.am |   2 +
 android/a2dp.c      |   8 +-
 android/audio-msg.h |   1 +
 android/hal-audio.c | 301 +++++++++++++++++++++++++++++++++++++++++++++++++---
 configure.ac        |   7 ++
 6 files changed, 338 insertions(+), 18 deletions(-)

-- 
1.8.5.2


^ permalink raw reply

* Re: [RFC v5 00/14] LE auto connection and connection parameters
From: Johan Hedberg @ 2014-01-22  9:08 UTC (permalink / raw)
  To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1387540675-2466-1-git-send-email-andre.guedes@openbossa.org>

Hi Andre,

On Fri, Dec 20, 2013, Andre Guedes wrote:
> This patch set is pretty much the same of previous one, except it implements
> a different approach to handle discovery and LE connection (as discussed on
> "[RFC v4 05/12] Bluetooth: Stop scanning on LE connection").
> 
> Regards,
> 
> Andre
> 
> 
> Andre Guedes (14):
>   Bluetooth: Save connection interval parameters in hci_conn
>   Bluetooth: Group list_head fields from strcut hci_dev together
>   Bluetooth: Introduce connection parameters list
>   Bluetooth: Use connection parameters if any
>   Bluetooth: Introduce fail_conn_attempt() helper
>   Bluetooth: Stop scanning on LE connection
>   Bluetooth: Remove unused function
>   Bluetooth: Introduce hdev->pend_le_conn list
>   Bluetooth: Introduce LE auto connection infrastructure
>   Bluetooth: Re-enable background scan in case of error
>   Bluetooth: Temporarily stop background scanning on discovery
>   Bluetooth: Auto connection and power on
>   Bleutooth: Add support for auto connect options
>   Bluetooth: Add le_auto_conn file on debugfs
> 
>  include/net/bluetooth/hci.h      |   1 +
>  include/net/bluetooth/hci_core.h |  43 +++++-
>  net/bluetooth/hci_conn.c         | 111 +++++++++++---
>  net/bluetooth/hci_core.c         | 318 +++++++++++++++++++++++++++++++++++++++
>  net/bluetooth/hci_event.c        |  60 ++++++++
>  net/bluetooth/mgmt.c             |  25 ++-
>  6 files changed, 530 insertions(+), 28 deletions(-)

Besides the couple of minor things I just pointed out I didn't find
anything else obviously wrong with this patch set. It might be worth to
send a rebased non-RFC version of it (with the changes I suggested if
you agree with them) so we get this moving forward.

Johan
.

^ permalink raw reply

* Re: [RFC v5 06/14] Bluetooth: Stop scanning on LE connection
From: Johan Hedberg @ 2014-01-22  9:03 UTC (permalink / raw)
  To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1387540675-2466-7-git-send-email-andre.guedes@openbossa.org>

Hi Andre,

On Fri, Dec 20, 2013, Andre Guedes wrote:
> +	hci_req_init(&req, hdev);
> +
> +	memset(&cp, 0, sizeof(cp));
> +	cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
> +	cp.scan_window = cpu_to_le16(hdev->le_scan_window);
> +	bacpy(&cp.peer_addr, &conn->dst);
> +	cp.peer_addr_type = conn->dst_type;
> +	cp.own_address_type = conn->src_type;
> +	cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
> +	cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
> +	cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
> +	cp.min_ce_len = __constant_cpu_to_le16(0x0000);
> +	cp.max_ce_len = __constant_cpu_to_le16(0x0000);
> +	hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);

You might wanna split out hci_req_add a bit with an empty line before it
to make this block of assignments more readable.

> +		memset(&cp, 0, sizeof(cp));
> +		cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
> +		cp.scan_window = cpu_to_le16(hdev->le_scan_window);
> +		bacpy(&cp.peer_addr, &conn->dst);
> +		cp.peer_addr_type = conn->dst_type;
> +		cp.own_address_type = conn->src_type;
> +		cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
> +		cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
> +		cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
> +		cp.min_ce_len = __constant_cpu_to_le16(0x0000);
> +		cp.max_ce_len = __constant_cpu_to_le16(0x0000);
> +		hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
> +
> +		err = hci_req_run(&req, create_le_conn_complete);
> +	}
> +
> +	if (err) {
> +		hci_conn_del(conn);
>  		return ERR_PTR(err);
> +	}

Instead of duplicating the HCI_LE_Create_Connection parameter encoding,
did you consider refactoring this into its own function, maybe something
like:

static void le_create_conn_req(struct hci_request *req,
			       struct hci_dev *hdev, struct hci_conn *conn)
{
	...
}


	le_create_conn_req(&req, hdev, conn);
	err = hci_req_run(&req, le_create_conn_complete);
	if (err)
		...

Johan

^ permalink raw reply

* Re: [RFC v5 05/14] Bluetooth: Introduce fail_conn_attempt() helper
From: Johan Hedberg @ 2014-01-22  8:58 UTC (permalink / raw)
  To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1387540675-2466-6-git-send-email-andre.guedes@openbossa.org>

Hi Andre,

On Fri, Dec 20, 2013, Andre Guedes wrote:
> This patch moves connection attempt failure code to its own function
> so it can be reused in the next patch.
> 
> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> ---
>  net/bluetooth/hci_conn.c | 24 ++++++++++++++++--------
>  1 file changed, 16 insertions(+), 8 deletions(-)
> 
> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> index b5c3ebff..870bc31 100644
> --- a/net/bluetooth/hci_conn.c
> +++ b/net/bluetooth/hci_conn.c
> @@ -514,6 +514,21 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
>  }
>  EXPORT_SYMBOL(hci_get_route);
>  
> +/* This function requires the caller holds hdev->lock */
> +static void fail_conn_attempt(struct hci_conn *conn, u8 status)
> +{
> +	struct hci_dev *hdev = conn->hdev;
> +
> +	conn->state = BT_CLOSED;
> +
> +	mgmt_connect_failed(hdev, &conn->dst, conn->type, conn->dst_type,
> +			    status);
> +
> +	hci_proto_connect_cfm(conn, status);
> +
> +	hci_conn_del(conn);
> +}

Looks otherwise good, but could we call this le_conn_failed instead of
fail_conn_attempt? It would sound less awkward to me.

Johan

^ permalink raw reply

* Re: [PATCH SBC v5 1/2] sbc: Add sbc_init_a2dp
From: Luiz Augusto von Dentz @ 2014-01-22  8:51 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390295313-5951-1-git-send-email-luiz.dentz@gmail.com>

Hi,

On Tue, Jan 21, 2014 at 11:08 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds sbc_init_a2dp that can be used to convert A2DP configuration to
> the internal representation since they are not binary compatible.
> ---
>  sbc/sbc.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  sbc/sbc.h |   2 +
>  2 files changed, 146 insertions(+)
>
> diff --git a/sbc/sbc.c b/sbc/sbc.c
> index c589217..ee6a2ab 100644
> --- a/sbc/sbc.c
> +++ b/sbc/sbc.c
> @@ -57,6 +57,55 @@
>  #define MSBC_SYNCWORD  0xAD
>  #define MSBC_BLOCKS    15
>
> +#define A2DP_SAMPLING_FREQ_16000               (1 << 3)
> +#define A2DP_SAMPLING_FREQ_32000               (1 << 2)
> +#define A2DP_SAMPLING_FREQ_44100               (1 << 1)
> +#define A2DP_SAMPLING_FREQ_48000               (1 << 0)
> +
> +#define A2DP_CHANNEL_MODE_MONO                 (1 << 3)
> +#define A2DP_CHANNEL_MODE_DUAL_CHANNEL         (1 << 2)
> +#define A2DP_CHANNEL_MODE_STEREO               (1 << 1)
> +#define A2DP_CHANNEL_MODE_JOINT_STEREO         (1 << 0)
> +
> +#define A2DP_BLOCK_LENGTH_4                    (1 << 3)
> +#define A2DP_BLOCK_LENGTH_8                    (1 << 2)
> +#define A2DP_BLOCK_LENGTH_12                   (1 << 1)
> +#define A2DP_BLOCK_LENGTH_16                   (1 << 0)
> +
> +#define A2DP_SUBBANDS_4                                (1 << 1)
> +#define A2DP_SUBBANDS_8                                (1 << 0)
> +
> +#define A2DP_ALLOCATION_SNR                    (1 << 1)
> +#define A2DP_ALLOCATION_LOUDNESS               (1 << 0)
> +
> +#if __BYTE_ORDER == __LITTLE_ENDIAN
> +
> +struct a2dp_sbc {
> +       uint8_t channel_mode:4;
> +       uint8_t frequency:4;
> +       uint8_t allocation_method:2;
> +       uint8_t subbands:2;
> +       uint8_t block_length:4;
> +       uint8_t min_bitpool;
> +       uint8_t max_bitpool;
> +} __attribute__ ((packed));
> +
> +#elif __BYTE_ORDER == __BIG_ENDIAN
> +
> +struct a2dp_sbc {
> +       uint8_t frequency:4;
> +       uint8_t channel_mode:4;
> +       uint8_t block_length:4;
> +       uint8_t subbands:2;
> +       uint8_t allocation_method:2;
> +       uint8_t min_bitpool;
> +       uint8_t max_bitpool;
> +} __attribute__ ((packed));
> +
> +#else
> +#error "Unknown byte order"
> +#endif
> +
>  /* This structure contains an unpacked SBC frame.
>     Yes, there is probably quite some unused space herein */
>  struct sbc_frame {
> @@ -1046,6 +1095,101 @@ SBC_EXPORT int sbc_init_msbc(sbc_t *sbc, unsigned long flags)
>         return 0;
>  }
>
> +SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
> +                                       const void *conf, size_t conf_len)
> +{
> +       const struct a2dp_sbc *a2dp;
> +       int err;
> +
> +       if (conf_len != sizeof(*a2dp))
> +               return -EINVAL;
> +
> +       err = sbc_init(sbc, flags);
> +       if (err < 0)
> +               return err;
> +
> +       a2dp = conf;
> +
> +       switch (a2dp->frequency) {
> +       case A2DP_SAMPLING_FREQ_16000:
> +               sbc->frequency = SBC_FREQ_16000;
> +               break;
> +       case A2DP_SAMPLING_FREQ_32000:
> +               sbc->frequency = SBC_FREQ_32000;
> +               break;
> +       case A2DP_SAMPLING_FREQ_44100:
> +               sbc->frequency = SBC_FREQ_44100;
> +               break;
> +       case A2DP_SAMPLING_FREQ_48000:
> +               sbc->frequency = SBC_FREQ_48000;
> +               break;
> +       default:
> +               goto failed;
> +       }
> +
> +       switch (a2dp->channel_mode) {
> +       case A2DP_CHANNEL_MODE_MONO:
> +               sbc->mode = SBC_MODE_MONO;
> +               break;
> +       case A2DP_CHANNEL_MODE_DUAL_CHANNEL:
> +               sbc->mode = SBC_MODE_DUAL_CHANNEL;
> +               break;
> +       case A2DP_CHANNEL_MODE_STEREO:
> +               sbc->mode = SBC_MODE_STEREO;
> +               break;
> +       case A2DP_CHANNEL_MODE_JOINT_STEREO:
> +               sbc->mode = SBC_MODE_JOINT_STEREO;
> +               break;
> +       default:
> +               goto failed;
> +       }
> +
> +       switch (a2dp->allocation_method) {
> +       case A2DP_ALLOCATION_SNR:
> +               sbc->allocation = SBC_AM_SNR;
> +               break;
> +       case A2DP_ALLOCATION_LOUDNESS:
> +               sbc->allocation = SBC_AM_LOUDNESS;
> +               break;
> +       default:
> +               goto failed;
> +       }
> +
> +       switch (a2dp->subbands) {
> +       case A2DP_SUBBANDS_4:
> +               sbc->subbands = SBC_SB_4;
> +               break;
> +       case A2DP_SUBBANDS_8:
> +               sbc->subbands = SBC_SB_8;
> +               break;
> +       default:
> +               goto failed;
> +       }
> +
> +       switch (a2dp->block_length) {
> +       case A2DP_BLOCK_LENGTH_4:
> +               sbc->blocks = SBC_BLK_4;
> +               break;
> +       case A2DP_BLOCK_LENGTH_8:
> +               sbc->blocks = SBC_BLK_8;
> +               break;
> +       case A2DP_BLOCK_LENGTH_12:
> +               sbc->blocks = SBC_BLK_12;
> +               break;
> +       case A2DP_BLOCK_LENGTH_16:
> +               sbc->blocks = SBC_BLK_16;
> +               break;
> +       default:
> +               goto failed;
> +       }
> +
> +       return 0;
> +
> +failed:
> +       sbc_finish(sbc);
> +       return -EINVAL;
> +}
> +
>  SBC_EXPORT ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len)
>  {
>         return sbc_decode(sbc, input, input_len, NULL, 0, NULL);
> diff --git a/sbc/sbc.h b/sbc/sbc.h
> index 5f8a1fc..32eb2e9 100644
> --- a/sbc/sbc.h
> +++ b/sbc/sbc.h
> @@ -84,6 +84,8 @@ typedef struct sbc_struct sbc_t;
>  int sbc_init(sbc_t *sbc, unsigned long flags);
>  int sbc_reinit(sbc_t *sbc, unsigned long flags);
>  int sbc_init_msbc(sbc_t *sbc, unsigned long flags);
> +int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
> +                                       const void *conf, size_t conf_len);
>
>  ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len);
>
> --
> 1.8.4.2

Pushed.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH] android: Refactor paths in Android.mk
From: Szymon Janc @ 2014-01-22  8:37 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1390347953-29901-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Andrzej,

On Wednesday 22 of January 2014 00:45:53 Andrzej Kaczmarek wrote:
> Using source paths relative to android/ directory created mess in
> Android's obj directory since object files are created also relative
> to bluetoothd_intermediates (thus can be created outside it).
> 
> To avoid this we set LOCAL_PATH to absolute path (in terms of Android
> build root) of directory in which bluez/ is located and change and
> update source paths accordingly.
> 
> This also allows us to build in future glib and sbc easily using
> Android.mk in BlueZ.

Applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH 9/9] android/ipc-tester: Add case for BT Set remote prop
From: Jakub Tyszkowski @ 2014-01-22  8:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390379124-16426-1-git-send-email-jakub.tyszkowski@tieto.com>

This patch adds test for verifying data length inside
hal_cmd_set_remote_device_prop struct.
---
 android/ipc-tester.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index e44afb3..e1aeb2e 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -687,6 +687,41 @@ static struct bt_set_adapter_prop_data bt_set_adapter_prop_data_unders = {
 	.buf = set_name,
 };
 
+struct bt_set_remote_prop_data {
+	struct hal_hdr hdr;
+	struct hal_cmd_set_remote_device_prop prop;
+
+	/* data placeholder for hal_cmd_set_remote_device_prop.val[0] */
+	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+				sizeof(struct hal_cmd_set_remote_device_prop)];
+} __attribute__((packed));
+
+static struct bt_set_remote_prop_data bt_set_remote_prop_data_overs = {
+	.hdr.service_id = HAL_SERVICE_ID_BLUETOOTH,
+	.hdr.opcode = HAL_OP_SET_REMOTE_DEVICE_PROP,
+	.hdr.len = sizeof(struct hal_cmd_set_remote_device_prop) +
+						sizeof(set_name),
+
+	.prop.bdaddr = {},
+	.prop.type = HAL_PROP_DEVICE_NAME,
+	/* declare wrong descriptor length */
+	.prop.len = sizeof(set_name) + 1,
+	.buf = set_name,
+};
+
+static struct bt_set_remote_prop_data bt_set_remote_prop_data_unders = {
+	.hdr.service_id = HAL_SERVICE_ID_BLUETOOTH,
+	.hdr.opcode = HAL_OP_SET_REMOTE_DEVICE_PROP,
+	.hdr.len = sizeof(struct hal_cmd_set_remote_device_prop) +
+						sizeof(set_name),
+
+	.prop.bdaddr = {},
+	.prop.type = HAL_PROP_DEVICE_NAME,
+	/* declare wrong descriptor length */
+	.prop.len = sizeof(set_name) - 1,
+	.buf = set_name,
+};
+
 struct hidhost_set_info_data {
 	struct hal_hdr hdr;
 	struct hal_cmd_hidhost_set_info info;
@@ -931,6 +966,20 @@ int main(int argc, char *argv[])
 			HAL_OP_SET_REMOTE_DEVICE_PROP,
 			sizeof(struct hal_cmd_set_remote_device_prop), -1,
 			HAL_SERVICE_ID_BLUETOOTH);
+	test_generic("Data size BT Set Remote Prop Vardata+",
+			ipc_send_tc, setup, teardown,
+			&bt_set_remote_prop_data_overs,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_set_remote_device_prop) +
+				sizeof(set_name)),
+			HAL_SERVICE_ID_BLUETOOTH);
+	test_generic("Data size BT Set Remote Prop Vardata-",
+			ipc_send_tc, setup, teardown,
+			&bt_set_remote_prop_data_unders,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_set_remote_device_prop) +
+				sizeof(set_name)),
+			HAL_SERVICE_ID_BLUETOOTH);
 	test_datasize_valid("BT Get Remote SV Rec+", HAL_SERVICE_ID_BLUETOOTH,
 			HAL_OP_GET_REMOTE_SERVICE_REC,
 			sizeof(struct hal_cmd_get_remote_service_rec), 1,
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 8/9] android/ipc-tester: Add case for BT Set adapter prop
From: Jakub Tyszkowski @ 2014-01-22  8:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390379124-16426-1-git-send-email-jakub.tyszkowski@tieto.com>

This patch adds test for verifying data length inside
hal_cmd_set_adapter_prop struct.
---
 android/ipc-tester.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index c621167..e44afb3 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -650,6 +650,43 @@ struct hal_hdr enable_bt_service_hdr = {
 	.len = 0,
 };
 
+struct bt_set_adapter_prop_data {
+	struct hal_hdr hdr;
+	struct hal_cmd_set_adapter_prop prop;
+
+	/* data placeholder for hal_cmd_set_adapter_prop.val[0] */
+	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+				sizeof(struct hal_cmd_set_adapter_prop)];
+} __attribute__((packed));
+
+#define set_name "new name"
+
+static struct bt_set_adapter_prop_data bt_set_adapter_prop_data_overs = {
+	.hdr.service_id = HAL_SERVICE_ID_BLUETOOTH,
+	.hdr.opcode = HAL_OP_SET_ADAPTER_PROP,
+	.hdr.len = sizeof(struct hal_cmd_set_adapter_prop) +
+						sizeof(set_name),
+
+	.prop.type = HAL_PROP_ADAPTER_NAME,
+	/* declare wrong descriptor length */
+	.prop.len = sizeof(set_name) + 1,
+	/* init prop.val[0] */
+	.buf = set_name,
+};
+
+static struct bt_set_adapter_prop_data bt_set_adapter_prop_data_unders = {
+	.hdr.service_id = HAL_SERVICE_ID_BLUETOOTH,
+	.hdr.opcode = HAL_OP_SET_ADAPTER_PROP,
+	.hdr.len = sizeof(struct hal_cmd_set_adapter_prop) +
+						sizeof(set_name),
+
+	.prop.type = HAL_PROP_ADAPTER_NAME,
+	/* declare wrong descriptor length */
+	.prop.len = sizeof(set_name) - 1,
+	/* init prop.val[0] */
+	.buf = set_name,
+};
+
 struct hidhost_set_info_data {
 	struct hal_hdr hdr;
 	struct hal_cmd_hidhost_set_info info;
@@ -856,6 +893,20 @@ int main(int argc, char *argv[])
 			HAL_OP_SET_ADAPTER_PROP,
 			sizeof(struct hal_cmd_set_adapter_prop), -1,
 			HAL_SERVICE_ID_BLUETOOTH);
+	test_generic("Data size BT Set Adapter Prop Vardata+",
+			ipc_send_tc, setup, teardown,
+			&bt_set_adapter_prop_data_overs,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_set_adapter_prop) +
+				sizeof(set_name)),
+			HAL_SERVICE_ID_BLUETOOTH);
+	test_generic("Data size BT Set Adapter Prop Vardata+",
+			ipc_send_tc, setup, teardown,
+			&bt_set_adapter_prop_data_unders,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_set_adapter_prop) +
+				sizeof(set_name)),
+			HAL_SERVICE_ID_BLUETOOTH);
 	test_datasize_valid("BT Get Remote Props+", HAL_SERVICE_ID_BLUETOOTH,
 			HAL_OP_GET_REMOTE_DEVICE_PROPS,
 			sizeof(struct hal_cmd_get_remote_device_props), 1,
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 7/9] android/ipc-tester: Add cases for A2DP msg size
From: Jakub Tyszkowski @ 2014-01-22  8:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390379124-16426-1-git-send-email-jakub.tyszkowski@tieto.com>

Add cases testing message size veification for A2DP opcodes.
---
 android/ipc-tester.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 11239e7..c621167 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -1133,5 +1133,23 @@ int main(int argc, char *argv[])
 			sizeof(struct hal_cmd_pan_disconnect), -1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN);
 
+	/* check for valid data size for A2DP */
+	test_datasize_valid("A2DP Connect+", HAL_SERVICE_ID_A2DP,
+			HAL_OP_A2DP_CONNECT,
+			sizeof(struct hal_cmd_a2dp_connect), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP);
+	test_datasize_valid("A2DP Connect-", HAL_SERVICE_ID_A2DP,
+			HAL_OP_A2DP_CONNECT,
+			sizeof(struct hal_cmd_a2dp_connect), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP);
+	test_datasize_valid("A2DP Disconnect+", HAL_SERVICE_ID_A2DP,
+			HAL_OP_A2DP_DISCONNECT,
+			sizeof(struct hal_cmd_a2dp_disconnect), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP);
+	test_datasize_valid("A2DP Disconnect-", HAL_SERVICE_ID_A2DP,
+			HAL_OP_A2DP_DISCONNECT,
+			sizeof(struct hal_cmd_a2dp_disconnect), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP);
+
 	return tester_run();
 }
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 6/9] android/ipc-tester: Add cases for PAN msg size
From: Jakub Tyszkowski @ 2014-01-22  8:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390379124-16426-1-git-send-email-jakub.tyszkowski@tieto.com>

Add cases testing message size verification for PAN opcodes.
---
 android/ipc-tester.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index b161049..11239e7 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -1103,5 +1103,35 @@ int main(int argc, char *argv[])
 				sizeof(send_data_data)),
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
 
+	/* check for valid data size for PAN */
+	test_datasize_valid("PAN Enable+", HAL_SERVICE_ID_PAN,
+			HAL_OP_PAN_ENABLE,
+			sizeof(struct hal_cmd_pan_enable), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN);
+	test_datasize_valid("PAN Enable-", HAL_SERVICE_ID_PAN,
+			HAL_OP_PAN_ENABLE,
+			sizeof(struct hal_cmd_pan_enable), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN);
+	test_datasize_valid("PAN Get Role+", HAL_SERVICE_ID_PAN,
+			HAL_OP_PAN_GET_ROLE,
+			0, 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN);
+	test_datasize_valid("PAN Connect+", HAL_SERVICE_ID_PAN,
+			HAL_OP_PAN_CONNECT,
+			sizeof(struct hal_cmd_pan_connect), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN);
+	test_datasize_valid("PAN Connect-", HAL_SERVICE_ID_PAN,
+			HAL_OP_PAN_CONNECT,
+			sizeof(struct hal_cmd_pan_connect), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN);
+	test_datasize_valid("PAN Disconnect+", HAL_SERVICE_ID_PAN,
+			HAL_OP_PAN_DISCONNECT,
+			sizeof(struct hal_cmd_pan_disconnect), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN);
+	test_datasize_valid("PAN Disconnect-", HAL_SERVICE_ID_PAN,
+			HAL_OP_PAN_DISCONNECT,
+			sizeof(struct hal_cmd_pan_disconnect), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN);
+
 	return tester_run();
 }
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 5/9] android/ipc-tester: Add case for HIDHOST Send Data
From: Jakub Tyszkowski @ 2014-01-22  8:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390379124-16426-1-git-send-email-jakub.tyszkowski@tieto.com>

This adds test for verifying data length inside
hal_cmd_hidhost_send_data struct.
---
 android/ipc-tester.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index ca4d9b9..b161049 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -720,6 +720,41 @@ static struct hidhost_set_report_data hidhost_set_report_data_unders = {
 	.buf = set_rep_data,
 };
 
+struct hidhost_send_data_data {
+	struct hal_hdr hdr;
+	struct hal_cmd_hidhost_send_data hiddata;
+
+	/* data placeholder for hal_cmd_hidhost_send_data.data[0] field */
+	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+				sizeof(struct hal_cmd_hidhost_send_data)];
+} __attribute__((packed));
+
+#define send_data_data "1234567890"
+
+static struct hidhost_send_data_data hidhost_send_data_overs = {
+	.hdr.service_id = HAL_SERVICE_ID_HIDHOST,
+	.hdr.opcode = HAL_OP_HIDHOST_SEND_DATA,
+	.hdr.len = sizeof(struct hal_cmd_hidhost_send_data) +
+							sizeof(send_data_data),
+
+	/* declare wrong descriptor length */
+	.hiddata.len = sizeof(send_data_data) + 1,
+	/* init .hiddata.data[0] */
+	.buf = send_data_data,
+};
+
+static struct hidhost_send_data_data hidhost_send_data_unders = {
+	.hdr.service_id = HAL_SERVICE_ID_HIDHOST,
+	.hdr.opcode = HAL_OP_HIDHOST_SEND_DATA,
+	.hdr.len = sizeof(struct hal_cmd_hidhost_send_data) +
+							sizeof(send_data_data),
+
+	/* declare wrong descriptor length */
+	.hiddata.len = sizeof(send_data_data) - 1,
+	/* init .hiddata.data[0] */
+	.buf = send_data_data,
+};
+
 int main(int argc, char *argv[])
 {
 	snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
@@ -1053,6 +1088,20 @@ int main(int argc, char *argv[])
 			HAL_OP_HIDHOST_SEND_DATA,
 			sizeof(struct hal_cmd_hidhost_send_data), -1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_generic("Data size HIDHOST Send Vardata+",
+			ipc_send_tc, setup, teardown,
+			&hidhost_send_data_overs,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_hidhost_send_data) +
+				sizeof(send_data_data)),
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_generic("Data size HIDHOST Send Vardata-",
+			ipc_send_tc, setup, teardown,
+			&hidhost_send_data_unders,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_hidhost_send_data) +
+				sizeof(send_data_data)),
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
 
 	return tester_run();
 }
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 4/9] android/ipc-tester: Add case for HIDHOST Set Report
From: Jakub Tyszkowski @ 2014-01-22  8:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390379124-16426-1-git-send-email-jakub.tyszkowski@tieto.com>

This patch adds test for verifying data length inside
hal_cmd_hidhost_set_report struct.
---
 android/ipc-tester.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 641bc5b..ca4d9b9 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -685,6 +685,41 @@ static struct hidhost_set_info_data hidhost_set_info_data_unders = {
 	.buf = set_info_data,
 };
 
+struct hidhost_set_report_data {
+	struct hal_hdr hdr;
+	struct hal_cmd_hidhost_set_report report;
+
+	/* data placeholder for hal_cmd_hidhost_set_report.data[0] field */
+	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+				sizeof(struct hal_cmd_hidhost_set_report)];
+} __attribute__((packed));
+
+#define set_rep_data "1234567890"
+
+static struct hidhost_set_report_data hidhost_set_report_data_overs = {
+	.hdr.service_id = HAL_SERVICE_ID_HIDHOST,
+	.hdr.opcode = HAL_OP_HIDHOST_SET_REPORT,
+	.hdr.len = sizeof(struct hal_cmd_hidhost_set_report) +
+							sizeof(set_rep_data),
+
+	/* declare wrong descriptor length */
+	.report.len = sizeof(set_rep_data) + 1,
+	/* init report.data[0] */
+	.buf = set_rep_data,
+};
+
+static struct hidhost_set_report_data hidhost_set_report_data_unders = {
+	.hdr.service_id = HAL_SERVICE_ID_HIDHOST,
+	.hdr.opcode = HAL_OP_HIDHOST_SET_REPORT,
+	.hdr.len = sizeof(struct hal_cmd_hidhost_set_report) +
+							sizeof(set_rep_data),
+
+	/* declare wrong descriptor length */
+	.report.len = sizeof(set_rep_data) - 1,
+	/* init report.data[0] */
+	.buf = set_rep_data,
+};
+
 int main(int argc, char *argv[])
 {
 	snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
@@ -996,6 +1031,20 @@ int main(int argc, char *argv[])
 			HAL_OP_HIDHOST_SET_REPORT,
 			sizeof(struct hal_cmd_hidhost_set_report), -1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_generic("Data size HIDHOST Set Report Vardata+",
+			ipc_send_tc, setup, teardown,
+			&hidhost_set_report_data_overs,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_hidhost_set_report) +
+				sizeof(set_rep_data)),
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_generic("Data size HIDHOST Set Report Vardata-",
+			ipc_send_tc, setup, teardown,
+			&hidhost_set_report_data_unders,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_hidhost_set_report) +
+				sizeof(set_rep_data)),
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
 	test_datasize_valid("HIDHOST Send Data+", HAL_SERVICE_ID_HIDHOST,
 			HAL_OP_HIDHOST_SEND_DATA,
 			sizeof(struct hal_cmd_hidhost_send_data), 1,
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 3/9] android/ipc-tester: Add case for HIDHOST Set Info
From: Jakub Tyszkowski @ 2014-01-22  8:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390379124-16426-1-git-send-email-jakub.tyszkowski@tieto.com>

This patch adds test for verifying data length inside
hal_cmd_hidhost_set_info struct.
---
 android/ipc-tester.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 2871587..641bc5b 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -650,6 +650,41 @@ struct hal_hdr enable_bt_service_hdr = {
 	.len = 0,
 };
 
+struct hidhost_set_info_data {
+	struct hal_hdr hdr;
+	struct hal_cmd_hidhost_set_info info;
+
+	/* data placeholder for hal_cmd_hidhost_set_info.descr[0] field */
+	uint8_t buf[BLUEZ_HAL_MTU - sizeof(struct hal_hdr) -
+				sizeof(struct hal_cmd_hidhost_set_info)];
+} __attribute__((packed));
+
+#define set_info_data "some descriptor"
+
+static struct hidhost_set_info_data hidhost_set_info_data_overs = {
+	.hdr.service_id = HAL_SERVICE_ID_HIDHOST,
+	.hdr.opcode = HAL_OP_HIDHOST_SET_INFO,
+	.hdr.len = sizeof(struct hal_cmd_hidhost_set_info) +
+							sizeof(set_info_data),
+
+	/* declare wrong descriptor length */
+	.info.descr_len = sizeof(set_info_data) + 1,
+	/* init .info.descr[0] */
+	.buf = set_info_data,
+};
+
+static struct hidhost_set_info_data hidhost_set_info_data_unders = {
+	.hdr.service_id = HAL_SERVICE_ID_HIDHOST,
+	.hdr.opcode = HAL_OP_HIDHOST_SET_INFO,
+	.hdr.len = sizeof(struct hal_cmd_hidhost_set_info) +
+							sizeof(set_info_data),
+
+	/* declare wrong descriptor length */
+	.info.descr_len = sizeof(set_info_data) - 1,
+	/* init .info.descr[0] */
+	.buf = set_info_data,
+};
+
 int main(int argc, char *argv[])
 {
 	snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
@@ -915,6 +950,20 @@ int main(int argc, char *argv[])
 			HAL_OP_HIDHOST_SET_INFO,
 			sizeof(struct hal_cmd_hidhost_set_info), -1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_generic("Data size HIDHOST Set Info Vardata+",
+			ipc_send_tc, setup, teardown,
+			&hidhost_set_info_data_overs,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_hidhost_set_info) +
+				sizeof(set_info_data)),
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_generic("Data size HIDHOST Set Info Vardata-",
+			ipc_send_tc, setup, teardown,
+			&hidhost_set_info_data_unders,
+			(sizeof(struct hal_hdr) +
+				sizeof(struct hal_cmd_hidhost_set_info) +
+				sizeof(set_info_data)),
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
 	test_datasize_valid("HIDHOST Get Protocol+", HAL_SERVICE_ID_HIDHOST,
 			HAL_OP_HIDHOST_GET_PROTOCOL,
 			sizeof(struct hal_cmd_hidhost_get_protocol), 1,
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 2/9] android/ipc-tester: Add cases for HIDHOST msg size
From: Jakub Tyszkowski @ 2014-01-22  8:25 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390379124-16426-1-git-send-email-jakub.tyszkowski@tieto.com>

Add cases testing message size verification for HIDHOST opcodes.
---
 android/ipc-tester.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 088c324..2871587 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -882,5 +882,79 @@ int main(int argc, char *argv[])
 			sizeof(struct hal_cmd_sock_connect), -1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCK);
 
+	/* check for valid data size for HID Host */
+	test_datasize_valid("HIDHOST Connect+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_CONNECT,
+			sizeof(struct hal_cmd_hidhost_connect), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Connect-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_CONNECT,
+			sizeof(struct hal_cmd_hidhost_connect), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Disconnect+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_DISCONNECT,
+			sizeof(struct hal_cmd_hidhost_disconnect), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Disconnect-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_DISCONNECT,
+			sizeof(struct hal_cmd_hidhost_disconnect), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Virt. Unplug+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_VIRTUAL_UNPLUG,
+			sizeof(struct hal_cmd_hidhost_virtual_unplug), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Virt. Unplug-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_VIRTUAL_UNPLUG,
+			sizeof(struct hal_cmd_hidhost_virtual_unplug), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Set Info+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_SET_INFO,
+			sizeof(struct hal_cmd_hidhost_set_info), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Set Info-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_SET_INFO,
+			sizeof(struct hal_cmd_hidhost_set_info), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Get Protocol+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_GET_PROTOCOL,
+			sizeof(struct hal_cmd_hidhost_get_protocol), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Get Protocol-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_GET_PROTOCOL,
+			sizeof(struct hal_cmd_hidhost_get_protocol), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Set Protocol+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_SET_PROTOCOL,
+			sizeof(struct hal_cmd_hidhost_set_protocol), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Set Protocol-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_SET_PROTOCOL,
+			sizeof(struct hal_cmd_hidhost_set_protocol), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Get Report+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_GET_REPORT,
+			sizeof(struct hal_cmd_hidhost_get_report), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Get Report-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_GET_REPORT,
+			sizeof(struct hal_cmd_hidhost_get_report), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Set Report+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_SET_REPORT,
+			sizeof(struct hal_cmd_hidhost_set_report), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Set Report-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_SET_REPORT,
+			sizeof(struct hal_cmd_hidhost_set_report), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Send Data+", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_SEND_DATA,
+			sizeof(struct hal_cmd_hidhost_send_data), 1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+	test_datasize_valid("HIDHOST Send Data-", HAL_SERVICE_ID_HIDHOST,
+			HAL_OP_HIDHOST_SEND_DATA,
+			sizeof(struct hal_cmd_hidhost_send_data), -1,
+			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST);
+
 	return tester_run();
 }
-- 
1.8.5.2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox