Linux bluetooth development
 help / color / mirror / Atom feed
* [RFC 06/15] android/client-audio: Add get_buffer_size for output
From: Jakub Tyszkowski @ 2014-01-30 11:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391081001-30723-1-git-send-email-jakub.tyszkowski@tieto.com>

Get buffer size for output stream.

---
 android/client/if-audio.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/android/client/if-audio.c b/android/client/if-audio.c
index 1ca84f5..2b158a5 100644
--- a/android/client/if-audio.c
+++ b/android/client/if-audio.c
@@ -295,6 +295,15 @@ static void get_latency_p(int argc, const char **argv)
 					stream_out->get_latency(stream_out));
 }
 
+static void get_buffer_size_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_audio);
+	RETURN_IF_NULL(stream_out);
+
+	haltest_info("Current output buffer size: %d\n",
+		stream_out->common.get_buffer_size(&stream_out->common));
+}
+
 static struct method methods[] = {
 	STD_METHOD(init),
 	STD_METHOD(cleanup),
@@ -305,6 +314,7 @@ static struct method methods[] = {
 	STD_METHOD(suspend),
 	STD_METHOD(resume),
 	STD_METHOD(get_latency),
+	STD_METHOD(get_buffer_size),
 	END_METHOD
 };
 
-- 
1.8.5.2


^ permalink raw reply related

* [RFC 05/15] android/client-audio: Add get_latency for output
From: Jakub Tyszkowski @ 2014-01-30 11:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391081001-30723-1-git-send-email-jakub.tyszkowski@tieto.com>

Get output stream latency.

---
 android/client/if-audio.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/android/client/if-audio.c b/android/client/if-audio.c
index 985b60c..1ca84f5 100644
--- a/android/client/if-audio.c
+++ b/android/client/if-audio.c
@@ -286,6 +286,15 @@ static void resume_p(int argc, const char **argv)
 	pthread_mutex_unlock(&state_mutex);
 }
 
+static void get_latency_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_audio);
+	RETURN_IF_NULL(stream_out);
+
+	haltest_info("Output audio stream latency: %d\n",
+					stream_out->get_latency(stream_out));
+}
+
 static struct method methods[] = {
 	STD_METHOD(init),
 	STD_METHOD(cleanup),
@@ -295,6 +304,7 @@ static struct method methods[] = {
 	STD_METHOD(stop),
 	STD_METHOD(suspend),
 	STD_METHOD(resume),
+	STD_METHOD(get_latency),
 	END_METHOD
 };
 
-- 
1.8.5.2


^ permalink raw reply related

* [RFC 04/15] android/client-audio: Add playback suspend/resume
From: Jakub Tyszkowski @ 2014-01-30 11:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391081001-30723-1-git-send-email-jakub.tyszkowski@tieto.com>

Add audio stream suspending and resuming.

---
 android/client/if-audio.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/android/client/if-audio.c b/android/client/if-audio.c
index cd0a851..985b60c 100644
--- a/android/client/if-audio.c
+++ b/android/client/if-audio.c
@@ -104,6 +104,10 @@ static void *playback_thread(void *data)
 		if (current_state == STATE_STOPPING) {
 			pthread_mutex_unlock(&state_mutex);
 			break;
+		} else if (current_state == STATE_SUSPENDED) {
+				pthread_mutex_unlock(&state_mutex);
+				usleep(500);
+				continue;
 		}
 		pthread_mutex_unlock(&state_mutex);
 
@@ -253,6 +257,35 @@ static void cleanup_p(int argc, const char **argv)
 	if_audio = NULL;
 }
 
+static void suspend_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_audio);
+	RETURN_IF_NULL(stream_out);
+
+	pthread_mutex_lock(&state_mutex);
+	if (current_state != STATE_PLAYING) {
+		pthread_mutex_unlock(&state_mutex);
+		return;
+	}
+	current_state = STATE_SUSPENDED;
+	pthread_mutex_unlock(&state_mutex);
+
+	pthread_mutex_lock(&outstream_mutex);
+	stream_out->common.standby(&stream_out->common);
+	pthread_mutex_unlock(&outstream_mutex);
+}
+
+static void resume_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_audio);
+	RETURN_IF_NULL(stream_out);
+
+	pthread_mutex_lock(&state_mutex);
+	if (current_state == STATE_SUSPENDED)
+		current_state = STATE_PLAYING;
+	pthread_mutex_unlock(&state_mutex);
+}
+
 static struct method methods[] = {
 	STD_METHOD(init),
 	STD_METHOD(cleanup),
@@ -260,6 +293,8 @@ static struct method methods[] = {
 	STD_METHOD(close_output_stream),
 	STD_METHODH(play, "<path to pcm file>"),
 	STD_METHOD(stop),
+	STD_METHOD(suspend),
+	STD_METHOD(resume),
 	END_METHOD
 };
 
-- 
1.8.5.2


^ permalink raw reply related

* [RFC 03/15] android/client-audio: Add audio file playback
From: Jakub Tyszkowski @ 2014-01-30 11:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391081001-30723-1-git-send-email-jakub.tyszkowski@tieto.com>

This patch adds audio file playback capability. Proper 16-bit signed
float stereo PCM file is needed.

---
 android/client/if-audio.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 163 insertions(+)

diff --git a/android/client/if-audio.c b/android/client/if-audio.c
index 4c1efce..cd0a851 100644
--- a/android/client/if-audio.c
+++ b/android/client/if-audio.c
@@ -17,11 +17,26 @@
 
 #include "if-main.h"
 #include "../hal-utils.h"
+#include "pthread.h"
+#include "unistd.h"
 
 audio_hw_device_t *if_audio = NULL;
 struct audio_stream_out *stream_out = NULL;
 
 static size_t buffer_size = 0;
+static pthread_t play_thread = 0;
+static pthread_mutex_t outstream_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+enum state {
+	STATE_STOPPED,
+	STATE_STOPPING,
+	STATE_PLAYING,
+	STATE_SUSPENDED,
+	STATE_MAX
+};
+
+static int current_state = STATE_STOPPED;
 
 static void init_p(int argc, const char **argv)
 {
@@ -45,12 +60,142 @@ static void init_p(int argc, const char **argv)
 	if_audio = device;
 }
 
+static void playthread_cleanup(void *arg)
+{
+	pthread_mutex_lock(&state_mutex);
+	current_state = STATE_STOPPED;
+	pthread_mutex_unlock(&state_mutex);
+
+	haltest_info("Done playing.\n");
+}
+
+static int feed_from_file(short *buffer, void *data)
+{
+	FILE *in = data;
+	return fread(buffer, buffer_size, 1, in);
+}
+
+static void *playback_thread(void *data)
+{
+	int (*filbuff_cb) (short*, void*);
+	short buffer[buffer_size / sizeof(short)];
+	size_t len = 0;
+	size_t w_len = 0;
+	FILE *in = data;
+	void *cb_data = NULL;
+
+	pthread_cleanup_push(playthread_cleanup, NULL);
+
+	/* Use file or fall back to generator */
+	if (in) {
+		filbuff_cb = feed_from_file;
+		cb_data = in;
+	} else {
+		/* TODO: Use generator */
+		goto end;
+	}
+
+	pthread_mutex_lock(&state_mutex);
+	current_state = STATE_PLAYING;
+	pthread_mutex_unlock(&state_mutex);
+
+	do {
+		pthread_mutex_lock(&state_mutex);
+		if (current_state == STATE_STOPPING) {
+			pthread_mutex_unlock(&state_mutex);
+			break;
+		}
+		pthread_mutex_unlock(&state_mutex);
+
+		len = filbuff_cb(buffer, cb_data);
+
+		pthread_mutex_lock(&outstream_mutex);
+		if (!stream_out) {
+			pthread_mutex_unlock(&outstream_mutex);
+			break;
+		}
+
+		w_len = stream_out->write(stream_out, buffer, buffer_size);
+		pthread_mutex_unlock(&outstream_mutex);
+	} while (len && w_len);
+
+	if (in) {
+		fclose(in);
+		in = NULL;
+	}
+end:
+	pthread_cleanup_pop(1);
+	return NULL;
+}
+
+static void play_p(int argc, const char **argv)
+{
+	const char *fname = NULL;
+	FILE *in = NULL;
+
+	RETURN_IF_NULL(if_audio);
+	RETURN_IF_NULL(stream_out);
+
+	if (argc < 3) {
+		haltest_error("Invalid audio file path.\n");
+	} else {
+		fname = argv[2];
+		in = fopen(fname, "r");
+
+		if (in == NULL) {
+			haltest_error("Cannot open file: %s\n", fname);
+			return;
+		}
+		haltest_info("Playing file: %s\n", fname);
+	}
+
+	if (buffer_size == 0) {
+		haltest_error("Invalid buffer size. Was stream_out opened?\n");
+		return;
+	}
+
+	pthread_mutex_lock(&state_mutex);
+	if (current_state != STATE_STOPPED) {
+		haltest_error("Already playing or stream suspended!\n");
+		pthread_mutex_unlock(&state_mutex);
+		return;
+	}
+	pthread_mutex_unlock(&state_mutex);
+
+	if (pthread_create(&play_thread, NULL, playback_thread, in) != 0)
+		haltest_error("Cannot create playback thread!\n");
+}
+
+static void stop_p(int argc, const char **argv)
+{
+	pthread_mutex_lock(&state_mutex);
+	if (current_state == STATE_STOPPED || current_state == STATE_STOPPING) {
+		pthread_mutex_unlock(&state_mutex);
+		return;
+	}
+
+	current_state = STATE_STOPPING;
+	pthread_mutex_unlock(&state_mutex);
+
+	pthread_mutex_lock(&outstream_mutex);
+	stream_out->common.standby(&stream_out->common);
+	pthread_mutex_unlock(&outstream_mutex);
+}
+
 static void open_output_stream_p(int argc, const char **argv)
 {
 	int err;
 
 	RETURN_IF_NULL(if_audio);
 
+	pthread_mutex_lock(&state_mutex);
+	if (current_state == STATE_PLAYING) {
+		haltest_error("Already playing!\n");
+		pthread_mutex_unlock(&state_mutex);
+		return;
+	}
+	pthread_mutex_unlock(&state_mutex);
+
 	err = if_audio->open_output_stream(if_audio,
 						0,
 						AUDIO_DEVICE_OUT_ALL_A2DP,
@@ -74,7 +219,15 @@ static void close_output_stream_p(int argc, const char **argv)
 	RETURN_IF_NULL(if_audio);
 	RETURN_IF_NULL(stream_out);
 
+	stop_p(argc, argv);
+
+	haltest_info("Waiting for playback thread...\n");
+	pthread_join(play_thread, NULL);
+
 	if_audio->close_output_stream(if_audio, stream_out);
+
+	stream_out = NULL;
+	buffer_size = 0;
 }
 
 static void cleanup_p(int argc, const char **argv)
@@ -83,6 +236,14 @@ static void cleanup_p(int argc, const char **argv)
 
 	RETURN_IF_NULL(if_audio);
 
+	pthread_mutex_lock(&state_mutex);
+	if (current_state != STATE_STOPPED) {
+		pthread_mutex_unlock(&state_mutex);
+		close_output_stream_p(0, NULL);
+	} else {
+		pthread_mutex_unlock(&state_mutex);
+	}
+
 	err = audio_hw_device_close(if_audio);
 	if (err < 0) {
 		haltest_error("audio_hw_device_close returned %d\n", err);
@@ -97,6 +258,8 @@ static struct method methods[] = {
 	STD_METHOD(cleanup),
 	STD_METHOD(open_output_stream),
 	STD_METHOD(close_output_stream),
+	STD_METHODH(play, "<path to pcm file>"),
+	STD_METHOD(stop),
 	END_METHOD
 };
 
-- 
1.8.5.2


^ permalink raw reply related

* [RFC 02/15] android/client-audio: Add open/close output stream
From: Jakub Tyszkowski @ 2014-01-30 11:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391081001-30723-1-git-send-email-jakub.tyszkowski@tieto.com>

Add opening and closing output stream.

---
 android/client/if-audio.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/android/client/if-audio.c b/android/client/if-audio.c
index 203e088..4c1efce 100644
--- a/android/client/if-audio.c
+++ b/android/client/if-audio.c
@@ -19,6 +19,9 @@
 #include "../hal-utils.h"
 
 audio_hw_device_t *if_audio = NULL;
+struct audio_stream_out *stream_out = NULL;
+
+static size_t buffer_size = 0;
 
 static void init_p(int argc, const char **argv)
 {
@@ -34,12 +37,46 @@ static void init_p(int argc, const char **argv)
 	}
 
 	err = audio_hw_device_open(module, &device);
-	if (err)
+	if (err) {
 		haltest_error("audio_hw_device_open returned %d\n", err);
+		return;
+	}
 
 	if_audio = device;
 }
 
+static void open_output_stream_p(int argc, const char **argv)
+{
+	int err;
+
+	RETURN_IF_NULL(if_audio);
+
+	err = if_audio->open_output_stream(if_audio,
+						0,
+						AUDIO_DEVICE_OUT_ALL_A2DP,
+						AUDIO_OUTPUT_FLAG_NONE,
+						NULL,
+						&stream_out);
+	if (err < 0) {
+		haltest_error("open output stream returned %d\n", err);
+		return;
+	}
+
+	buffer_size = stream_out->common.get_buffer_size(&stream_out->common);
+	if (buffer_size == 0)
+		haltest_error("Invalid buffer size received!\n");
+	else
+		haltest_info("Using buffer size: %d\n", buffer_size);
+}
+
+static void close_output_stream_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_audio);
+	RETURN_IF_NULL(stream_out);
+
+	if_audio->close_output_stream(if_audio, stream_out);
+}
+
 static void cleanup_p(int argc, const char **argv)
 {
 	int err;
@@ -58,6 +95,8 @@ static void cleanup_p(int argc, const char **argv)
 static struct method methods[] = {
 	STD_METHOD(init),
 	STD_METHOD(cleanup),
+	STD_METHOD(open_output_stream),
+	STD_METHOD(close_output_stream),
 	END_METHOD
 };
 
-- 
1.8.5.2


^ permalink raw reply related

* [RFC 01/15] android/client-av: Fix checking for a2dp interface
From: Jakub Tyszkowski @ 2014-01-30 11:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391081001-30723-1-git-send-email-jakub.tyszkowski@tieto.com>

---
 android/client/if-av.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/android/client/if-av.c b/android/client/if-av.c
index 0470e0d..8d1f69b 100644
--- a/android/client/if-av.c
+++ b/android/client/if-av.c
@@ -80,7 +80,7 @@ static void connect_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
 
-	RETURN_IF_NULL(if_hh);
+	RETURN_IF_NULL(if_av);
 	VERIFY_ADDR_ARG(2, &addr);
 
 	EXEC(if_av->connect, &addr);
@@ -101,7 +101,7 @@ static void disconnect_p(int argc, const char **argv)
 {
 	bt_bdaddr_t addr;
 
-	RETURN_IF_NULL(if_hh);
+	RETURN_IF_NULL(if_av);
 	VERIFY_ADDR_ARG(2, &addr);
 
 	EXEC(if_av->disconnect, &addr);
-- 
1.8.5.2


^ permalink raw reply related

* [RFC 00/15] android/client: Add audio support
From: Jakub Tyszkowski @ 2014-01-30 11:23 UTC (permalink / raw)
  To: linux-bluetooth

This patch set adds audio support for haltest tool. It provides basic audio HAL
functionality and adds ability to play PCM audio files.

I've also added sound generator when no file path is provided for "play"
command. We can leave that be or push sample audio file to the tree, and/or
hardcode the path. I think that leaving audio file selection to the user and
providing fallback to sound generator is the right solution. Please let me know
what is yours preference.

Regards.

Jakub Tyszkowski (15):
  android/client-av: Fix checking for a2dp interface
  android/client-audio: Add open/close output stream
  android/client-audio: Add audio file playback
  android/client-audio: Add playback suspend/resume
  android/client-audio: Add get_latency for output
  android/client-audio: Add get_buffer_size for output
  android/client-audio: Add get_channels
  android/client-audio: Add getting audio format
  android/client-audio: Add getting sample rate
  android/client-audio: Add get_parameters for output
  android/client-audio: Add set_parameters
  android/client-audio: Add setting sample rate
  android/client-audio: Add init_check
  android/client-audio: Add sine generator as fallback
  android/client-audio: Fix getting audio module on Android

 android/Makefile.am       |   2 +-
 android/client/if-audio.c | 477 +++++++++++++++++++++++++++++++++++++++++++++-
 android/client/if-av.c    |   4 +-
 3 files changed, 479 insertions(+), 4 deletions(-)

--
1.8.5.2


^ permalink raw reply

* [PATCHv3] hog: Use HoG device name as uHID input device name
From: Petri Gynther @ 2014-01-30  3:55 UTC (permalink / raw)
  To: linux-bluetooth

If HoG BLE device name is known, use it when creating uHID input device.
Pass adapter and device addresses to uHID as well.
---
 profiles/input/hog.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index ded6303..030dc91 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -392,7 +392,15 @@ static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
 	/* create uHID device */
 	memset(&ev, 0, sizeof(ev));
 	ev.type = UHID_CREATE;
-	strcpy((char *) ev.u.create.name, "bluez-hog-device");
+	if (device_name_known(hogdev->device)) {
+		device_get_name(hogdev->device, (char *) ev.u.create.name,
+				sizeof(ev.u.create.name) - 1);
+	} else {
+		strcpy((char *) ev.u.create.name, "bluez-hog-device");
+	}
+	ba2str(btd_adapter_get_address(device_get_adapter(hogdev->device)),
+		(char *) ev.u.create.phys);
+	ba2str(device_get_address(hogdev->device), (char *) ev.u.create.uniq);
 	ev.u.create.vendor = vendor;
 	ev.u.create.product = product;
 	ev.u.create.version = version;
-- 
1.8.5.3


^ permalink raw reply related

* [PATCHv2] hog: Use HoG device name as uHID input device name
From: Petri Gynther @ 2014-01-30  2:55 UTC (permalink / raw)
  To: linux-bluetooth

If HoG BLE device name is known, use it when creating uHID input device.
Pass BLE device address to uHID as well.
---
 profiles/input/hog.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index ded6303..7ad184a 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -392,7 +392,13 @@ static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
 	/* create uHID device */
 	memset(&ev, 0, sizeof(ev));
 	ev.type = UHID_CREATE;
-	strcpy((char *) ev.u.create.name, "bluez-hog-device");
+	if (device_name_known(hogdev->device)) {
+		device_get_name(hogdev->device, (char *) ev.u.create.name,
+				sizeof(ev.u.create.name) - 1);
+	} else {
+		strcpy((char *) ev.u.create.name, "bluez-hog-device");
+	}
+	ba2str(device_get_address(hogdev->device), (char *) ev.u.create.phys);
 	ev.u.create.vendor = vendor;
 	ev.u.create.product = product;
 	ev.u.create.version = version;
-- 
1.8.5.3


^ permalink raw reply related

* Re: [PATCH] hog: Use HoG device name as uHID input device name
From: Petri Gynther @ 2014-01-30  2:50 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20140129053008.829BC100AC4@puck.mtv.corp.google.com>

On Tue, Jan 28, 2014 at 9:30 PM, Petri Gynther <pgynther@google.com> wrote:
> If HoG BLE device name is known, use it when creating uHID input device.
> ---
>  profiles/input/hog.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/profiles/input/hog.c b/profiles/input/hog.c
> index ded6303..3af0406 100644
> --- a/profiles/input/hog.c
> +++ b/profiles/input/hog.c
> @@ -392,7 +392,12 @@ static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
>         /* create uHID device */
>         memset(&ev, 0, sizeof(ev));
>         ev.type = UHID_CREATE;
> -       strcpy((char *) ev.u.create.name, "bluez-hog-device");
> +       if (device_name_known(hogdev->device)) {
> +               device_get_name(hogdev->device, (char *) ev.u.create.name,
> +                               sizeof(ev.u.create.name) - 1);
> +       } else {
> +               strcpy((char *) ev.u.create.name, "bluez-hog-device");
> +       }
>         ev.u.create.vendor = vendor;
>         ev.u.create.product = product;
>         ev.u.create.version = version;
> --
> 1.8.5.3
>

I'll add the BLE device address to ev.u.create.phys. New patch coming soon.

^ permalink raw reply

* Re: [PATCHv2 0/3] AVCTP test cases
From: Luiz Augusto von Dentz @ 2014-01-29 23:29 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390999274-15631-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Wed, Jan 29, 2014 at 4:41 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Set of test cases which are feasible to implement with socketpair.
> Fragmentation of AVCTP is not supported yet.
>
> Andrei Emeltchenko (3):
>   unit/avctp: Add AVCTP unit test skeleton and first test
>   unit/avctp: Add TP/NFR/BV-02-C test
>   unit/avctp: Add TP/NFR/BI-01-C test
>
>  Makefile.am       |   8 ++
>  unit/test-avctp.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 283 insertions(+)
>  create mode 100644 unit/test-avctp.c
>
> --
> 1.8.3.2

Applied, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH] Bluetooth: Enable LTK distribution to slave devices
From: johan.hedberg @ 2014-01-29 21:55 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

So far we've only been requesting the LTK to be distributed to the
master (initiator) of pairing, which is usually enough since it's the
master that will establish future connections and initiate encryption.
However, in the case that both devices support switching to the opposing
role (which seems to be increasingly common) pairing will have to
performed again since the "new" master will not have all information.

As there is no real harm in it, this patch updates the code to always
try distributing the LTK also to the slave device, thereby enabling role
switches for future connections.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/smp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 45007362683b..9b1167007653 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -216,7 +216,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
 		req->io_capability = conn->hcon->io_capability;
 		req->oob_flag = SMP_OOB_NOT_PRESENT;
 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
-		req->init_key_dist = 0;
+		req->init_key_dist = dist_keys;
 		req->resp_key_dist = dist_keys;
 		req->auth_req = (authreq & AUTH_REQ_MASK);
 		return;
@@ -225,7 +225,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
 	rsp->io_capability = conn->hcon->io_capability;
 	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
-	rsp->init_key_dist = 0;
+	rsp->init_key_dist = req->init_key_dist & dist_keys;
 	rsp->resp_key_dist = req->resp_key_dist & dist_keys;
 	rsp->auth_req = (authreq & AUTH_REQ_MASK);
 }
-- 
1.8.5.3


^ permalink raw reply related

* Re: [RFC BlueZ 0/2] Print bluetoothd messages in btmon
From: Vinicius Costa Gomes @ 2014-01-29 21:35 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: BlueZ development
In-Reply-To: <ACF337D1-0BF3-494E-959C-27B210C3E532@holtmann.org>

Hi Marcel,

On 22:42 Tue 28 Jan, Marcel Holtmann wrote:
> Hi Vinicius,
>
> > It is very common when debugging issues, specially users' problems to
> > ask for btmon logs and the accompaining bluetoothd logs. And depending
> > on the issue, it takes some time to relate the HCI/MGMT commands to
> > bluetoothd messages that help narrow down the problem.
> >
> > This is just a proof of concept, to know if this will be generally
> > helpful. And so, it needs some improvements: sending bluetoothd the USR2
> > signal so debug is enabled, color support and better formatting.
>
> so I am thinking to do this completely different.
>
> I think that the btsnoop 2.0 format should get a section for notes/comments/logs where we can store text information. So you can actually interline HCI traffic with human readable comments. For example Apple is doing that with their Packet Logger. Obvious this is only useful if everything is in a single file that can be easily shared.
>
> For this to work we need to read all the data from monitor interface of the kernel. Which means that the kernel also needs to have the debug/log output of bluetoothd. Meaning that bluetoothd would write the debug/logs into the kernel monitor interface and then they would be distributed to every btmon instance.
>
> As a result bluetoothd would only log warnings, error and info messages to syslog/journal and all debug information should go back to the kernel.

Sounds great.

>
> Initially I was thinking just adding writing support monitor channel, but that is silly since it will turn on promiscuous mode. Something that is causing a bit of overhead on a production system. So we rather not do that. Maybe it would be better to assign a new HCI channel for bluetoothd logging data.
>
> The one thing that is pretty obvious already is that we want to log per HCI index from bluetoothd. Which means we need to change the logging to be HCI controller aware. Without being HCI controller aware it is pretty much useless.
>

I liked this. And having the logs HCI aware even makes sense if the logs go the usual places (syslog/journal). So it is a nice intermediate stage.

> One interesting thing to think about is if we should tie enabling debug logs to the fact if btmon is running or not. And if we might allow btmon to configure the level of logs we want. It would be kinda cool if we can start btmon with -d ‘*audio*’ and then it magically gets all audio logs. Now it gets a bit funny with a kernel interface writing back into userspace to configure the logging level of a daemon.

This gets complicated when we have multiple btmon's running. Interesting nonetheless.

>
> I have been toying with the idea of having filters on btmon already and making the kernel just filter out packets so that userspace does not get woken up. I just never figured out the right API to do it.
>
> Regards
>
> Marcel
>


Cheers,
--
Vinicius

^ permalink raw reply

* Re: [PATCH] android/a2dp: Fix crash on remote disconnection
From: Luiz Augusto von Dentz @ 2014-01-29 18:38 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1391010302-13231-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Wed, Jan 29, 2014 at 7:45 AM, Szymon Janc <szymon.janc@tieto.com> wrote:
> Remove setups when a2dp device is removed. This fix following:
>
> Invalid read of size 4
>    at 0x115E32: bt_stream_close (a2dp.c:1352)
>    by 0x111DFB: ipc_handle_msg (ipc.c:95)
>    by 0x11234B: audio_watch_cb (audio-ipc.c:67)
>    by 0x48BD9C7: ??? (in /system/lib/libglib.so)
>  Address 0x4a590f4 is 12 bytes inside a block of size 20 free'd
>    at 0x4897E6C: free (in
>        /system/lib/valgrind/vgpreload_memcheck-arm-linux.so)
>    by 0x48C5E2B: g_free (in /system/lib/libglib.so)
>
> Invalid read of size 4
>    at 0x113638: avdtp_close (avdtp.c:3201)
>    by 0x115E39: bt_stream_close (a2dp.c:1352)
>    by 0x111DFB: ipc_handle_msg (ipc.c:95)
>    by 0x11234B: audio_watch_cb (audio-ipc.c:67)
>    by 0x48BD9C7: ??? (in /system/lib/libglib.so)
>  Address 0x4a594a4 is 28 bytes inside a block of size 1,100 free'd
>    at 0x4897E6C: free (in
>        /system/lib/valgrind/vgpreload_memcheck-arm-linux.so)
>    by 0x48C5E2B: g_free (in /system/lib/libglib.so)
> ---
>  android/a2dp.c | 49 +++++++++++++++++++++++++++++++++----------------
>  1 file changed, 33 insertions(+), 16 deletions(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 8d8fa7d..a215ce2 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -122,6 +122,37 @@ static void unregister_endpoint(void *data)
>         g_free(endpoint);
>  }
>
> +static void setup_free(void *data)
> +{
> +       struct a2dp_setup *setup = data;
> +
> +       if (!g_slist_find(setup->endpoint->presets, setup->preset))
> +               preset_free(setup->preset);
> +
> +       g_free(setup);
> +}
> +
> +static void setup_remove(struct a2dp_setup *setup)
> +{
> +       setups = g_slist_remove(setups, setup);
> +       setup_free(setup);
> +}
> +
> +static void setup_remove_all_by_dev(struct a2dp_device *dev)
> +{
> +       GSList *l = setups;
> +
> +       while (l) {
> +               struct a2dp_setup *setup = l->data;
> +               GSList *next = g_slist_next(l);
> +
> +               if (setup->dev == dev)
> +                       setup_remove(setup);
> +
> +               l = next;
> +       }
> +}
> +
>  static void a2dp_device_free(void *data)
>  {
>         struct a2dp_device *dev = data;
> @@ -137,6 +168,8 @@ static void a2dp_device_free(void *data)
>                 g_io_channel_unref(dev->io);
>         }
>
> +       setup_remove_all_by_dev(dev);
> +
>         devices = g_slist_remove(devices, dev);
>         g_free(dev);
>  }
> @@ -828,22 +861,6 @@ static struct a2dp_device *find_device_by_session(struct avdtp *session)
>         return NULL;
>  }
>
> -static void setup_free(void *data)
> -{
> -       struct a2dp_setup *setup = data;
> -
> -       if (!g_slist_find(setup->endpoint->presets, setup->preset))
> -               preset_free(setup->preset);
> -
> -       g_free(setup);
> -}
> -
> -static void setup_remove(struct a2dp_setup *setup)
> -{
> -       setups = g_slist_remove(setups, setup);
> -       setup_free(setup);
> -}
> -
>  static struct a2dp_setup *find_setup(uint8_t id)
>  {
>         GSList *l;
> --
> 1.8.5.3

Pushed, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH BlueZ] audio/AVRCP: Fix sending invalid response to GetCapabilities
From: Luiz Augusto von Dentz @ 2014-01-29 17:07 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390939534-15699-1-git-send-email-luiz.dentz@gmail.com>

Hi,

On Tue, Jan 28, 2014 at 12:05 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> The attribute count has to be initialized with 0 since we reuse the same
> buffer for both command and responses it may be already be set causing
> invalid response to be generated.
> ---
>  profiles/audio/avrcp.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> index 59a966e..ad5dc34 100644
> --- a/profiles/audio/avrcp.c
> +++ b/profiles/audio/avrcp.c
> @@ -921,6 +921,7 @@ static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
>
>                 return AVC_CTYPE_STABLE;
>         case CAP_EVENTS_SUPPORTED:
> +               pdu->params[1] = 0;
>                 for (i = 1; i <= AVRCP_EVENT_LAST; i++) {
>                         if (session->supported_events & (1 << i)) {
>                                 pdu->params[1]++;
> --
> 1.8.4.2

Applied.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCHv2 0/8] Set of AVCTP fixes
From: Luiz Augusto von Dentz @ 2014-01-29 17:07 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390998967-24610-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Wed, Jan 29, 2014 at 4:35 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> AVCTP issues found during writing test cases.
>
> Changes:
>         * v2: Added last 2 patches to series.
>
> Andrei Emeltchenko (8):
>   android/avctp: Use predefined HEADER_LENGTH instead of sizeof
>   android/avctp: Fix wrong error message
>   avctp: Use already calculated avc header
>   avctp: trivial: Do not break short line
>   avctp: Use predefined HEADER_LENGTH instead of sizeof
>   avctp: Fix wrong error message
>   android/avctp: Move AVC_HEADER_LENGTH from avctp header
>   avctp: Fix unchecked return value
>
>  android/avctp.c        | 16 +++++++------
>  android/avctp.h        |  1 -
>  profiles/audio/avctp.c | 64 +++++++++++++++++++++++++++++++++++---------------
>  3 files changed, 54 insertions(+), 27 deletions(-)
>
> --
> 1.8.3.2

Patches 1-7 applied, patch 8 needs some investigation if we can reduce
that many ioctl in a row.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH 1/2] android/bluetooth: Add threashold to RSSI change
From: Anderson Lizardo @ 2014-01-29 16:12 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Szymon Janc, BlueZ development
In-Reply-To: <755599B7-D32C-424C-B2B8-E0E8539C31EE@holtmann.org>

Hi Marcel,

On Tue, Jan 28, 2014 at 9:02 PM, Marcel Holtmann <marcel@holtmann.org> wrote:
>> And why not:
>>
>> int delta = abs(old - new);
>>
>> (unless there is no abs() in bionic)
>
> I remember that abs() needs -lm or something stupid.

>From my tests, it does not require any extra libraries other than
libc6 (at least in recent versions). It seems that at least for x86 it
is even optimized to a few machine instructions (as I could not find
the library call when using objdump on code that does
"abs(atoi(argv[1]))").

Best Regards,
-- 
Anderson Lizardo
http://www.indt.org/?lang=en
INdT - Manaus - Brazil

^ permalink raw reply

* [PATCH] android/a2dp: Fix crash on remote disconnection
From: Szymon Janc @ 2014-01-29 15:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Remove setups when a2dp device is removed. This fix following:

Invalid read of size 4
   at 0x115E32: bt_stream_close (a2dp.c:1352)
   by 0x111DFB: ipc_handle_msg (ipc.c:95)
   by 0x11234B: audio_watch_cb (audio-ipc.c:67)
   by 0x48BD9C7: ??? (in /system/lib/libglib.so)
 Address 0x4a590f4 is 12 bytes inside a block of size 20 free'd
   at 0x4897E6C: free (in
       /system/lib/valgrind/vgpreload_memcheck-arm-linux.so)
   by 0x48C5E2B: g_free (in /system/lib/libglib.so)

Invalid read of size 4
   at 0x113638: avdtp_close (avdtp.c:3201)
   by 0x115E39: bt_stream_close (a2dp.c:1352)
   by 0x111DFB: ipc_handle_msg (ipc.c:95)
   by 0x11234B: audio_watch_cb (audio-ipc.c:67)
   by 0x48BD9C7: ??? (in /system/lib/libglib.so)
 Address 0x4a594a4 is 28 bytes inside a block of size 1,100 free'd
   at 0x4897E6C: free (in
       /system/lib/valgrind/vgpreload_memcheck-arm-linux.so)
   by 0x48C5E2B: g_free (in /system/lib/libglib.so)
---
 android/a2dp.c | 49 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 8d8fa7d..a215ce2 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -122,6 +122,37 @@ static void unregister_endpoint(void *data)
 	g_free(endpoint);
 }
 
+static void setup_free(void *data)
+{
+	struct a2dp_setup *setup = data;
+
+	if (!g_slist_find(setup->endpoint->presets, setup->preset))
+		preset_free(setup->preset);
+
+	g_free(setup);
+}
+
+static void setup_remove(struct a2dp_setup *setup)
+{
+	setups = g_slist_remove(setups, setup);
+	setup_free(setup);
+}
+
+static void setup_remove_all_by_dev(struct a2dp_device *dev)
+{
+	GSList *l = setups;
+
+	while (l) {
+		struct a2dp_setup *setup = l->data;
+		GSList *next = g_slist_next(l);
+
+		if (setup->dev == dev)
+			setup_remove(setup);
+
+		l = next;
+	}
+}
+
 static void a2dp_device_free(void *data)
 {
 	struct a2dp_device *dev = data;
@@ -137,6 +168,8 @@ static void a2dp_device_free(void *data)
 		g_io_channel_unref(dev->io);
 	}
 
+	setup_remove_all_by_dev(dev);
+
 	devices = g_slist_remove(devices, dev);
 	g_free(dev);
 }
@@ -828,22 +861,6 @@ static struct a2dp_device *find_device_by_session(struct avdtp *session)
 	return NULL;
 }
 
-static void setup_free(void *data)
-{
-	struct a2dp_setup *setup = data;
-
-	if (!g_slist_find(setup->endpoint->presets, setup->preset))
-		preset_free(setup->preset);
-
-	g_free(setup);
-}
-
-static void setup_remove(struct a2dp_setup *setup)
-{
-	setups = g_slist_remove(setups, setup);
-	setup_free(setup);
-}
-
 static struct a2dp_setup *find_setup(uint8_t id)
 {
 	GSList *l;
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 2/2] android/pts: Add android version to PTS test
From: Sebastian Chlad @ 2014-01-29 13:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad
In-Reply-To: <1391002025-15997-1-git-send-email-sebastianx.chlad@intel.com>

---
 android/pts-avctp.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/android/pts-avctp.txt b/android/pts-avctp.txt
index a57ecee..efd525e 100644
--- a/android/pts-avctp.txt
+++ b/android/pts-avctp.txt
@@ -2,6 +2,7 @@ PTS test results for AVCTP
 
 PTS version: 5.0
 Tested: 29.01.2014
+Android version: 4.4
 
 Results:
 PASS	test passed
-- 
1.8.3.2

---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply related

* [PATCH 1/2] android/pts: PTS test results for AVCTP
From: Sebastian Chlad @ 2014-01-29 13:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

---
 android/pts-avctp.txt | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/android/pts-avctp.txt b/android/pts-avctp.txt
index c057a10..a57ecee 100644
--- a/android/pts-avctp.txt
+++ b/android/pts-avctp.txt
@@ -1,7 +1,7 @@
 PTS test results for AVCTP
 
 PTS version: 5.0
-Tested: --not yet tested--
+Tested: 29.01.2014
 
 Results:
 PASS	test passed
@@ -29,13 +29,13 @@ TC_CT_FRA_BV_04_C	N/A
 -------------------------------------------------------------------------------
 Test Name		Result	Notes
 -------------------------------------------------------------------------------
-TC_TG_CCM_BV_01_C	INC
-TC_TG_CCM_BV_02_C	INC
-TC_TG_CCM_BV_03_C	INC
-TC_TG_CCM_BV_04_C	INC
-TC_TG_NFR_BV_02_C	INC
-TC_TG_NFR_BV_03_C	INC
-TC_TG_NFR_BI_01_C	INC
-TC_TG_FRA_BV_02_C	INC
+TC_TG_CCM_BV_01_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
+TC_TG_CCM_BV_02_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
+TC_TG_CCM_BV_03_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
+TC_TG_CCM_BV_04_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
+TC_TG_NFR_BV_02_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
+TC_TG_NFR_BV_03_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
+TC_TG_NFR_BI_01_C	PASS
+TC_TG_FRA_BV_02_C	FAIL
 TC_TG_FRA_BV_03_C	INC
 -------------------------------------------------------------------------------
-- 
1.8.3.2

---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply related

* [PATCHv2 3/3] unit/avctp: Add TP/NFR/BI-01-C test
From: Andrei Emeltchenko @ 2014-01-29 12:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390999274-15631-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

To verify that the IUT (TG) reports to the test system (CT) the
reception of a control message intended for an invalid PID (PID not
registered for reception of messages).
---
 unit/test-avctp.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/unit/test-avctp.c b/unit/test-avctp.c
index 8c97a82..041e0c0 100644
--- a/unit/test-avctp.c
+++ b/unit/test-avctp.c
@@ -267,5 +267,9 @@ int main(int argc, char *argv[])
 				raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00),
 				raw_pdu(0x02, 0x11, 0x0e, 0x0a, 0x00, 0x00));
 
+	define_test("/TP/NFR/BI-01-C", test_server,
+				raw_pdu(0x00, 0xff, 0xff, 0x00, 0x00, 0x00),
+				raw_pdu(0x03, 0xff, 0xff));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2 2/3] unit/avctp: Add TP/NFR/BV-02-C test
From: Andrei Emeltchenko @ 2014-01-29 12:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390999274-15631-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

To verify that the IUT (TG) formats correctly the following fields of
the AVCTP response message: “transaction label”, "message type(R)", PID,
“packet type”, IPID and “message information”. Check that AVCTP send
response packet along with other information. Payload is out of scope of
this test (AVC_CTYPE_REJECTED is OK).
---
 unit/test-avctp.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/unit/test-avctp.c b/unit/test-avctp.c
index 49bd640..8c97a82 100644
--- a/unit/test-avctp.c
+++ b/unit/test-avctp.c
@@ -244,6 +244,15 @@ static void test_client(gconstpointer data)
 	execute_context(context);
 }
 
+static void test_server(gconstpointer data)
+{
+	struct context *context = create_context(0x0100, data);
+
+	g_idle_add(send_pdu, context);
+
+	execute_context(context);
+}
+
 int main(int argc, char *argv[])
 {
 	g_test_init(&argc, &argv, NULL);
@@ -254,5 +263,9 @@ int main(int argc, char *argv[])
 	define_test("/TP/NFR/BV-01-C", test_client,
 				raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00));
 
+	define_test("/TP/NFR/BV-02-C", test_server,
+				raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00),
+				raw_pdu(0x02, 0x11, 0x0e, 0x0a, 0x00, 0x00));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2 1/3] unit/avctp: Add AVCTP unit test skeleton and first test
From: Andrei Emeltchenko @ 2014-01-29 12:41 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390999274-15631-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Adds test TP/NFR/BV-01-C. To verify that the IUT (CT) formats correctly
the following fields of the AVCTP command message: “transaction label”,
"message type(C)", PID, “packet type”, IPID and “message information”.
---
 Makefile.am       |   8 ++
 unit/test-avctp.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 266 insertions(+)
 create mode 100644 unit/test-avctp.c

diff --git a/Makefile.am b/Makefile.am
index 3a1e6dc..1a44a9f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -273,6 +273,14 @@ unit_test_avdtp_SOURCES = unit/test-avdtp.c \
 				android/avdtp.c android/avdtp.h
 unit_test_avdtp_LDADD = @GLIB_LIBS@
 
+unit_tests += unit/test-avctp
+
+unit_test_avctp_SOURCES = unit/test-avctp.c \
+				src/shared/util.h src/shared/util.c \
+				src/log.h src/log.c \
+				android/avctp.c android/avctp.h
+unit_test_avctp_LDADD = @GLIB_LIBS@
+
 unit_tests += unit/test-gdbus-client
 
 unit_test_gdbus_client_SOURCES = unit/test-gdbus-client.c
diff --git a/unit/test-avctp.c b/unit/test-avctp.c
new file mode 100644
index 0000000..49bd640
--- /dev/null
+++ b/unit/test-avctp.c
@@ -0,0 +1,258 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+
+#include <glib.h>
+
+#include "src/shared/util.h"
+#include "src/log.h"
+
+#include "android/avctp.h"
+
+struct test_pdu {
+	bool valid;
+	bool fragmented;
+	const uint8_t *data;
+	size_t size;
+};
+
+struct test_data {
+	char *test_name;
+	struct test_pdu *pdu_list;
+};
+
+struct context {
+	GMainLoop *main_loop;
+	struct avctp *session;
+	guint source;
+	guint process;
+	int fd;
+	unsigned int pdu_offset;
+	const struct test_data *data;
+};
+
+#define data(args...) ((const unsigned char[]) { args })
+
+#define raw_pdu(args...)					\
+	{							\
+		.valid = true,					\
+		.data = data(args),				\
+		.size = sizeof(data(args)),			\
+	}
+
+#define frg_pdu(args...)					\
+	{							\
+		.valid = true,					\
+		.fragmented = true,				\
+		.data = data(args),				\
+		.size = sizeof(data(args)),			\
+	}
+
+#define define_test(name, function, args...)				\
+	do {								\
+		const struct test_pdu pdus[] = {			\
+			args, { }					\
+		};							\
+		static struct test_data data;				\
+		data.test_name = g_strdup(name);			\
+		data.pdu_list = g_malloc(sizeof(pdus));			\
+		memcpy(data.pdu_list, pdus, sizeof(pdus));		\
+		g_test_add_data_func(name, &data, function);		\
+	} while (0)
+
+static void test_debug(const char *str, void *user_data)
+{
+	const char *prefix = user_data;
+
+	g_print("%s%s\n", prefix, str);
+}
+
+static void test_free(gconstpointer user_data)
+{
+	const struct test_data *data = user_data;
+
+	g_free(data->test_name);
+	g_free(data->pdu_list);
+}
+
+static gboolean context_quit(gpointer user_data)
+{
+	struct context *context = user_data;
+
+	if (context->process > 0)
+		g_source_remove(context->process);
+
+	g_main_loop_quit(context->main_loop);
+
+	return FALSE;
+}
+
+static gboolean send_pdu(gpointer user_data)
+{
+	struct context *context = user_data;
+	const struct test_pdu *pdu;
+	ssize_t len;
+
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
+	len = write(context->fd, pdu->data, pdu->size);
+
+	if (g_test_verbose())
+		util_hexdump('<', pdu->data, len, test_debug, "AVCTP: ");
+
+	g_assert_cmpint(len, ==, pdu->size);
+
+	if (pdu->fragmented)
+		return send_pdu(user_data);
+
+	context->process = 0;
+	return FALSE;
+}
+
+static void context_process(struct context *context)
+{
+	if (!context->data->pdu_list[context->pdu_offset].valid) {
+		context_quit(context);
+		return;
+	}
+
+	context->process = g_idle_add(send_pdu, context);
+}
+
+static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
+							gpointer user_data)
+{
+	struct context *context = user_data;
+	const struct test_pdu *pdu;
+	unsigned char buf[512];
+	ssize_t len;
+	int fd;
+
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+		context->source = 0;
+		g_print("%s: cond %x\n", __func__, cond);
+		return FALSE;
+	}
+
+	fd = g_io_channel_unix_get_fd(channel);
+
+	len = read(fd, buf, sizeof(buf));
+
+	g_assert(len > 0);
+
+	if (g_test_verbose())
+		util_hexdump('>', buf, len, test_debug, "AVCTP: ");
+
+	g_assert_cmpint(len, ==, pdu->size);
+
+	g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
+
+	if (!pdu->fragmented)
+		context_process(context);
+
+	return TRUE;
+}
+
+static struct context *create_context(uint16_t version, gconstpointer data)
+{
+	struct context *context = g_new0(struct context, 1);
+	GIOChannel *channel;
+	int err, sv[2];
+
+	context->main_loop = g_main_loop_new(NULL, FALSE);
+	g_assert(context->main_loop);
+
+	err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
+	g_assert(err == 0);
+
+	context->session = avctp_new(sv[0], 672, 672, version);
+	g_assert(context->session != NULL);
+
+	channel = g_io_channel_unix_new(sv[1]);
+
+	g_io_channel_set_close_on_unref(channel, TRUE);
+	g_io_channel_set_encoding(channel, NULL, NULL);
+	g_io_channel_set_buffered(channel, FALSE);
+
+	context->source = g_io_add_watch(channel,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				test_handler, context);
+	g_assert(context->source > 0);
+
+	g_io_channel_unref(channel);
+
+	context->fd = sv[1];
+	context->data = data;
+
+	return context;
+}
+
+static void execute_context(struct context *context)
+{
+	g_main_loop_run(context->main_loop);
+
+	if (context->source > 0)
+		g_source_remove(context->source);
+
+	avctp_shutdown(context->session);
+
+	g_main_loop_unref(context->main_loop);
+
+	test_free(context->data);
+	g_free(context);
+}
+
+static void test_client(gconstpointer data)
+{
+	struct context *context = create_context(0x0100, data);
+
+	avctp_send_vendordep_req(context->session, 0, 0, NULL, 0, NULL, NULL);
+
+	execute_context(context);
+}
+
+int main(int argc, char *argv[])
+{
+	g_test_init(&argc, &argv, NULL);
+
+	if (g_test_verbose())
+		__btd_log_init("*", 0);
+
+	define_test("/TP/NFR/BV-01-C", test_client,
+				raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00));
+
+	return g_test_run();
+}
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2 0/3] AVCTP test cases
From: Andrei Emeltchenko @ 2014-01-29 12:41 UTC (permalink / raw)
  To: linux-bluetooth

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

Set of test cases which are feasible to implement with socketpair.
Fragmentation of AVCTP is not supported yet.

Andrei Emeltchenko (3):
  unit/avctp: Add AVCTP unit test skeleton and first test
  unit/avctp: Add TP/NFR/BV-02-C test
  unit/avctp: Add TP/NFR/BI-01-C test

 Makefile.am       |   8 ++
 unit/test-avctp.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 283 insertions(+)
 create mode 100644 unit/test-avctp.c

-- 
1.8.3.2


^ permalink raw reply

* [PATCH] android: Add avtest to debug builds
From: Sebastian Chlad @ 2014-01-29 12:40 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

---
 android/Android.mk | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/android/Android.mk b/android/Android.mk
index 1d12da5..238bb7c 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -354,6 +354,34 @@ LOCAL_MODULE := l2ping
 include $(BUILD_EXECUTABLE)
 
 #
+# avtest
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	bluez/tools/avtest.c \
+	bluez/lib/bluetooth.c \
+	bluez/lib/hci.c \
+
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/bluez/lib \
+
+lib_headers := \
+	bluetooth.h \
+	hci.h \
+
+$(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/bluez/lib/bluetooth/$(file)))
+
+LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE := avtest
+
+include $(BUILD_EXECUTABLE)
+
+#
 # libsbc
 #
 
-- 
1.8.3.2

---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ 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