Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] android/pics: Add PICS and PIXIT for HSP
From: Sebastian Chlad @ 2014-02-24 11:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

Added PICS and PIXIT target Android 4.4
---
 android/Makefile.am   |   2 +
 android/pics-hsp.txt  | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++
 android/pixit-hsp.txt |  30 +++++++++++++++
 3 files changed, 135 insertions(+)
 create mode 100644 android/pics-hsp.txt
 create mode 100644 android/pixit-hsp.txt

diff --git a/android/Makefile.am b/android/Makefile.am
index 50d0dc0..58cfbae 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -188,6 +188,7 @@ EXTRA_DIST += android/Android.mk android/README \
 				android/pics-a2dp.txt \
 				android/pics-avctp.txt \
 				android/pics-avrcp.txt \
+				android/pics-hsp.txt \
 				android/pixit-l2cap.txt \
 				android/pixit-gap.txt \
 				android/pixit-did.txt \
@@ -199,6 +200,7 @@ EXTRA_DIST += android/Android.mk android/README \
 				android/pixit-a2dp.txt \
 				android/pixit-avctp.txt \
 				android/pixit-avrcp.txt \
+				android/pixit-hsp.txt \
 				android/pts-l2cap.txt \
 				android/pts-gap.txt \
 				android/pts-did.txt \
diff --git a/android/pics-hsp.txt b/android/pics-hsp.txt
new file mode 100644
index 0000000..015b619
--- /dev/null
+++ b/android/pics-hsp.txt
@@ -0,0 +1,103 @@
+HSP PICS for the PTS tool.
+
+PTS version: 5.0
+
+* - different than PTS defaults
+# - not yet implemented/supported
+
+M - mandatory
+O - optional
+
+		Version
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_HSP_0_1	False		Version: Headset Profile v1.1 (C.1)
+TSPC_HSP_0_2	True		Version: Headset Profile v1.2 (C.1)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support one and only one of these versions.
+-------------------------------------------------------------------------------
+
+
+		Roles
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_HSP_1_1	True		Role: Audio Gateway (AG) (C.1)
+TSPC_HSP_1_2	False		Role: Headset (HS) (C.1)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support at least one of the defined roles.
+-------------------------------------------------------------------------------
+
+
+		Audio Gateway Role
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_HSP_2_1	True		Incoming audio connection establishment (M)
+TSPC_HSP_2_2	True		Ring (AT command) (C.3)
+TSPC_HSP_2_3	False		Inband ring tone (O)
+TSPC_HSP_2_4	True		Outgoing audio connection establishment (O)
+TSPC_HSP_2_5	True		Audio connection release from HS (C.5)
+TSPC_HSP_2_6	True		Audio connection release from AG (M)
+TSPC_HSP_2_7	True		Audio connection transfer: AG to HS (M)
+TSPC_HSP_2_8	True		Audio connection transfer: HS to AG (M)
+TSPC_HSP_2_9	False		Remote audio volume control (C.1)
+TSPC_HSP_2_10	False		HS informs AG about local changes of audio
+					volume (O)
+TSPC_HSP_2_11	False		Audio volume setting storage by HS (O)
+TSPC_HSP_2_12	False		Remote microphone gain control (C.2)
+TSPC_HSP_2_13	False		HS informs AG about local changes of microphone
+					gain (O)
+TSPC_HSP_2_14	False		Microphone gain setting storage by HS (O)
+TSPC_HSP_2_15	True		Connection handling with Detach/Page (M)
+TSPC_HSP_2_16	False		Connection handling with Park Mode (C.4)
+-------------------------------------------------------------------------------
+C.1: Mandatory if TSPC_HSP_2_10 is supported, otherwise optional
+C:2: Mandatory if TSPC_HSP_2_13 is supported, otherwise optional
+C.3: Excluded if TSPC_HSP_2_3 and TSPC_HSP_4_1 ("Show that in-band
+	ringing and RING are mutually exclusive") are supported,
+	otherwise optional
+C.4: Excluded if TSPC_HSP_0_2 is supported, otherwise optional
+C.5: Mandatory if TSPC_HSP_0_1 is supported, otherwise optional
+-------------------------------------------------------------------------------
+
+
+		Headset Application Features
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_HSP_3_1	False		Incoming audio connection establishment (M)
+TSPC_HSP_3_2	False		Ring (AT command) (M)
+TSPC_HSP_3_3	False		Inband ring tone (M)
+TSPC_HSP_3_4	False		Outgoing audio connection establishment (M)
+TSPC_HSP_3_5	False		Audio connection release from HS (M)
+TSPC_HSP_3_6	False		Audio connection release from AG (M)
+TSPC_HSP_3_7	False		Audio connection transfer: AG to HS (M)
+TSPC_HSP_3_8	False		Audio connection transfer: HS to AG (M)
+TSPC_HSP_3_9	False		Remote audio volume control (C.1)
+TSPC_HSP_3_10	False		HS informs AG about local changes of audio
+                                        volume (O)
+TSPC_HSP_3_11	False		Audio volume setting storage by HS (O)
+TSPC_HSP_3_12	False		Remote microphone gain control (C.2)
+TSPC_HSP_3_13	False		HS informs AG about local changes of microphone
+                                        gain (O)
+TSPC_HSP_3_14	False		Microphone gain setting storage by HS (O)
+TSPC_HSP_3_15	False		Connection handling with Detach/Page (M)
+TSPC_HSP_3_16	False		Connection handling with Park Mode (C.3)
+-------------------------------------------------------------------------------
+C.1: Mandatory if TSPC_HSP_3_10 is supported, otherwise optional
+C.2: Mandatory if TSPC_HSP_2_13 is supported, otherwise optional
+C.3: Excluded if TSPC_HSP_0_2 is supported, otherwise optional
+-------------------------------------------------------------------------------
+
+
+		Errata Service Releases
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_HSP_4_1	False		Show that in-band ringing and RING are
+					mutually exclusive (C.1)
+-------------------------------------------------------------------------------
+C.1: Excluded if TSPC_HSP_0_2 is supported, otherwise optional
+-------------------------------------------------------------------------------
diff --git a/android/pixit-hsp.txt b/android/pixit-hsp.txt
new file mode 100644
index 0000000..2bda4fa
--- /dev/null
+++ b/android/pixit-hsp.txt
@@ -0,0 +1,30 @@
+HSP PIXIT for the PTS tool.
+
+PTS version: 5.0
+
+* - different than PTS defaults
+& - should be set to IUT Bluetooth address
+
+		Required PIXIT settings
+-------------------------------------------------------------------------------
+Parameter Name						Value
+-------------------------------------------------------------------------------
+TSPX_security_enabled					TRUE
+TSPX_bd_addr_iut					08606E414394 (&)
+TSPX_hs_class_of_device					200404
+TSPX_ag_class_of_device					400204
+TSPX_packet_type_sco					00A0
+TSPX_pin_code						0000
+TSPX_time_guard						20000000
+TSPX_use_implicit_send					TRUE
+TSPX_verbose_implicit_send				FALSE
+TSPX_delete_link_key					FALSE
+TSPX_server_channel_tester				01
+TSPX_server_channel_iut					00
+TSPX_no_fail_verdict					FALSE
+TSPX_remote_audio_volume_control			TRUE
+TSPX_secure_simple_pairing_pass_key_confirmation	FALSE
+TSPX_inband_ring_only					FALSE
+TSPX_no_ring_or_inband_ring_tone			FALSE
+TSPX_iut_establish_audio_before_RING			FALSE
+-------------------------------------------------------------------------------
-- 
1.8.5.3


^ permalink raw reply related

* Re: [PATCH v2 1/7] shared: Add support for disconnect handler to GLib based IO handling
From: Szymon Janc @ 2014-02-24  9:57 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1393103365-19908-1-git-send-email-szymon.janc@gmail.com>

On Saturday 22 of February 2014 22:09:19 Szymon Janc wrote:
> From: Szymon Janc <szymon.janc@tieto.com>
> 
> ---
>  src/shared/io-glib.c | 76 +++++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 67 insertions(+), 9 deletions(-)
> 
> diff --git a/src/shared/io-glib.c b/src/shared/io-glib.c
> index 5bd9ac0..5490fc0 100644
> --- a/src/shared/io-glib.c
> +++ b/src/shared/io-glib.c
> @@ -40,6 +40,10 @@ struct io {
>  	io_callback_func_t write_callback;
>  	io_destroy_func_t write_destroy;
>  	void *write_data;
> +	guint disconnect_watch;
> +	io_callback_func_t disconnect_callback;
> +	io_destroy_func_t disconnect_destroy;
> +	void *disconnect_data;
>  };
>  
>  static struct io *io_ref(struct io *io)
> @@ -157,7 +161,7 @@ static gboolean read_callback(GIOChannel *channel, GIOCondition cond,
>  	struct io *io = user_data;
>  	bool result;
>  
> -	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
> +	if (cond & (G_IO_ERR | G_IO_NVAL))
>  		return FALSE;
>  
>  	if (io->read_callback)
> @@ -183,9 +187,9 @@ bool io_set_read_handler(struct io *io, io_callback_func_t callback,
>  		goto done;
>  
>  	io->read_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
> -				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
> -				read_callback, io_ref(io),
> -				read_watch_destroy);
> +						G_IO_IN | G_IO_ERR | G_IO_NVAL,
> +						read_callback, io_ref(io),
> +						read_watch_destroy);
>  	if (io->read_watch == 0)
>  		return false;
>  
> @@ -218,7 +222,7 @@ static gboolean write_callback(GIOChannel *channel, GIOCondition cond,
>  	struct io *io = user_data;
>  	bool result;
>  
> -	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
> +	if (cond & (G_IO_ERR | G_IO_NVAL))
>  		return FALSE;
>  
>  	if (io->write_callback)
> @@ -244,9 +248,9 @@ bool io_set_write_handler(struct io *io, io_callback_func_t callback,
>  		goto done;
>  
>  	io->write_watch = g_io_add_watch_full(io->channel, G_PRIORITY_DEFAULT,
> -				G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
> -				write_callback, io_ref(io),
> -				write_watch_destroy);
> +						G_IO_OUT | G_IO_ERR | G_IO_NVAL,
> +						write_callback, io_ref(io),
> +						write_watch_destroy);
>  	if (io->write_watch == 0)
>  		return false;
>  
> @@ -258,8 +262,62 @@ done:
>  	return true;
>  }
>  
> +static void disconnect_watch_destroy(gpointer user_data)
> +{
> +	struct io *io = user_data;
> +
> +	if (io->disconnect_destroy)
> +		io->disconnect_destroy(io->disconnect_data);
> +
> +	io->disconnect_watch = 0;
> +	io->disconnect_callback = NULL;
> +	io->disconnect_destroy = NULL;
> +	io->disconnect_data = NULL;
> +
> +	io_unref(io);
> +}
> +
> +static gboolean disconnect_callback(GIOChannel *channel, GIOCondition cond,
> +							gpointer user_data)
> +{
> +	struct io *io = user_data;
> +	bool result;
> +
> +	if (io->disconnect_callback)
> +		result = io->disconnect_callback(io, io->disconnect_data);
> +	else
> +		result = false;
> +
> +	return result ? TRUE : FALSE;
> +}
> +
>  bool io_set_disconnect_handler(struct io *io, io_callback_func_t callback,
>  				void *user_data, io_destroy_func_t destroy)
>  {
> -	return false;
> +	if (!io)
> +		return false;
> +
> +	if (io->disconnect_watch > 0) {
> +		g_source_remove(io->disconnect_watch);
> +		io->disconnect_watch = 0;
> +	}
> +
> +	if (!callback)
> +		goto done;
> +
> +	io->disconnect_watch = g_io_add_watch_full(io->channel,
> +						G_PRIORITY_DEFAULT,
> +						G_IO_HUP | G_IO_ERR | G_IO_NVAL,
> +						disconnect_callback, io_ref(io),
> +						disconnect_watch_destroy);
> +	if (io->disconnect_watch == 0)
> +		return false;
> +
> +	io->disconnect_destroy = destroy;
> +	io->disconnect_data = user_data;
> +
> +done:
> +	io->disconnect_callback = callback;
> +
> +	return true;
>  }
> 

This is now applied.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH 2/2] unit/avrcp: Add /TP/ICC/BV-02-I test
From: Andrei Emeltchenko @ 2014-02-24  9:45 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1393235125-28822-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

The test verifies that the Target responds to SUBUNIT INFO command
initiated by Controller.
---
 unit/test-avrcp.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index edbcad1..381e7cb 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -293,5 +293,11 @@ int main(int argc, char *argv[])
 			raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0xf8, 0x30,
 				0x07, 0x48, 0xff, 0xff, 0xff));
 
+	define_test("/TP/ICC/BV-02-I", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x01, 0xf8, 0x31,
+				0x07, 0xff, 0xff, 0xff, 0xff),
+			raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0xf8, 0x31,
+				0x07, 0x48, 0xff, 0xff, 0xff));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/2] unit/avrcp: Add /TP/ICC/BV-01-I test
From: Andrei Emeltchenko @ 2014-02-24  9:45 UTC (permalink / raw)
  To: linux-bluetooth

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

Test verifies that the Target responds to UNIT INFO command initiated by
Controller.
---
 unit/test-avrcp.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index f1c0f46..edbcad1 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -242,6 +242,30 @@ static void test_dummy(gconstpointer data)
 	destroy_context(context);
 }
 
+static void execute_context(struct context *context)
+{
+	g_main_loop_run(context->main_loop);
+
+	if (context->source > 0)
+		g_source_remove(context->source);
+
+	avrcp_shutdown(context->session);
+
+	g_main_loop_unref(context->main_loop);
+
+	test_free(context->data);
+	g_free(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);
@@ -261,5 +285,13 @@ int main(int argc, char *argv[])
 	define_test("/TP/CRC/BV-01-I", test_dummy, raw_pdu(0x00));
 	define_test("/TP/CRC/BV-02-I", test_dummy, raw_pdu(0x00));
 
+	/* Information collection for control tests */
+
+	define_test("/TP/ICC/BV-01-I", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x01, 0xf8, 0x30,
+				0xff, 0xff, 0xff, 0xff, 0xff),
+			raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0xf8, 0x30,
+				0x07, 0x48, 0xff, 0xff, 0xff));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH] android/tester: Fix slang "never used" warning
From: Szymon Janc @ 2014-02-24  9:30 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1393226144-21605-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Monday 24 of February 2014 09:15:44 Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> The patch fixes following warning:
> ...
> android/android-tester.c:2185:2: warning: Value stored to
> 'adapter_status' is never read
>         adapter_status = data->if_bluetooth->set_adapter_property(prop);
>         ^                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ...
> ---
>  android/android-tester.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/android/android-tester.c b/android/android-tester.c
> index 84c6ca9..a376b11 100644
> --- a/android/android-tester.c
> +++ b/android/android-tester.c
> @@ -2190,6 +2190,10 @@ static void test_getprop_bdname_success(const void *test_data)
>  	init_test_conditions(data);
>  
>  	adapter_status = data->if_bluetooth->set_adapter_property(prop);
> +	if (adapter_status != BT_STATUS_SUCCESS) {
> +		tester_test_failed();
> +		return;
> +	}
>  
>  	adapter_status = data->if_bluetooth->get_adapter_property((*prop).type);
>  	check_expected_status(adapter_status);
> 

Applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH] Bluetooth: Enable RPA resolving if mgmt_set_privacy is called
From: Marcel Holtmann @ 2014-02-24  9:21 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1393233030-5912-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> A user space that supports the Set Privacy command is also expected to
> be able to handle New IRK events. Therefore, set the HCI_RPA_RESOLVING
> flag whenever the Set Privacy command is received.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/mgmt.c | 5 +++++
> 1 file changed, 5 insertions(+)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* [PATCH] Bluetooth: Enable RPA resolving if mgmt_set_privacy is called
From: johan.hedberg @ 2014-02-24  9:10 UTC (permalink / raw)
  To: linux-bluetooth

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

A user space that supports the Set Privacy command is also expected to
be able to handle New IRK events. Therefore, set the HCI_RPA_RESOLVING
flag whenever the Set Privacy command is received.

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

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 53b9408af16b..9865e523df20 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -4257,6 +4257,11 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data,
 
 	hci_dev_lock(hdev);
 
+	/* If user space supports this command it is also expected to
+	 * handle IRKs. Therefore, set the HCI_RPA_RESOLVING flag.
+	 */
+	set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags);
+
 	if (cp->privacy) {
 		changed = !test_and_set_bit(HCI_PRIVACY, &hdev->dev_flags);
 		memcpy(hdev->irk, cp->irk, sizeof(hdev->irk));
-- 
1.8.5.3


^ permalink raw reply related

* Re: [PATCH BlueZ v7 07/11] gatt: Add external services tracking
From: Johan Hedberg @ 2014-02-24  8:33 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth, Alvaro Silva
In-Reply-To: <1392835893-6723-8-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

On Wed, Feb 19, 2014, Claudio Takahasi wrote:
> From: Alvaro Silva <alvaro.silva@openbossa.org>
> 
> All primary services declarations provided by an external application
> will be automatically inserted in the attribute database.
> ---
>  src/gatt-dbus.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 109 insertions(+)

I've applied patches 1-6 but this one seems a bit strange.

> +static void proxy_added(GDBusProxy *proxy, void *user_data)
> +{
> +	struct external_app *eapp = user_data;
> +	const char *interface, *path;
> +
> +	interface = g_dbus_proxy_get_interface(proxy);
> +	path = g_dbus_proxy_get_path(proxy);
> +
> +	DBG("path %s iface %s", path, interface);
> +
> +	if (g_strcmp0(interface, SERVICE_IFACE) != 0)
> +		return;
> +
> +	eapp->proxies = g_slist_append(eapp->proxies, proxy);
> +}
> +
> +static void proxy_removed(GDBusProxy *proxy, void *user_data)
> +{
> +	struct external_app *eapp = user_data;
> +	const char *interface, *path;
> +
> +	interface = g_dbus_proxy_get_interface(proxy);
> +	path = g_dbus_proxy_get_path(proxy);
> +
> +	DBG("path %s iface %s", path, interface);
> +
> +	eapp->proxies = g_slist_remove(eapp->proxies, proxy);
> +}
> +
> +

Double empty line above - please fix (not related to my main issue with
this patch though)

> +static gboolean finish_register(gpointer user_data)
> +{
> +	struct external_app *eapp = user_data;
> +	GSList *list;
> +
> +	/*
> +	 * It is not possible to detect when the last proxy object
> +	 * was reported. "Proxy added" handler reports objects
> +	 * added on demand or returned by GetManagedObjects().
> +	 * This timer helps to register all the GATT declarations
> +	 * (services, characteristics and descriptors) after fetching
> +	 * all the D-Bus objects.
> +	 */
> +
> +	eapp->register_timer = 0;
> +
> +	for (list = eapp->proxies; list; list = g_slist_next(list)) {
> +		const char *interface, *path;
> +		GDBusProxy *proxy = list->data;
> +
> +		interface = g_dbus_proxy_get_interface(proxy);
> +		path = g_dbus_proxy_get_path(proxy);
> +
> +		if (g_strcmp0(SERVICE_IFACE, interface) != 0)
> +			continue;
> +
> +		if (g_strcmp0(path, eapp->path) != 0)
> +			continue;
> +
> +		if (register_external_service(proxy) < 0) {
> +			DBG("Inconsistent external service: %s", path);
> +			continue;
> +		}
> +
> +		DBG("External service: %s", path);
> +	}
> +
> +	return FALSE;
> +}

This whole timer thing seems too hackish to me.

A better way to fix this might be to have something like
g_dbus_client_set_proxies_complete_watch (or some better name) to let
the code wait until GetManagedObjects has returned and the initial
proxies added. Do you agree?

Johan

^ permalink raw reply

* Re: [PATCHv2 2/6] android/avctp: Add UNIT INFO command request
From: Luiz Augusto von Dentz @ 2014-02-24  8:28 UTC (permalink / raw)
  To: Andrei Emeltchenko, Luiz Augusto von Dentz,
	linux-bluetooth@vger.kernel.org
In-Reply-To: <20140224065425.GA4133@aemeltch-MOBL1>

Hi Andrei,

On Mon, Feb 24, 2014 at 8:54 AM, Andrei Emeltchenko
<andrei.emeltchenko@gmail.com> wrote:
> Hi Luiz,
>
> On Sun, Feb 23, 2014 at 01:57:05PM +0200, Luiz Augusto von Dentz wrote:
>> Hi Andrei,
>>
>> On Fri, Feb 21, 2014 at 5:23 PM, Andrei Emeltchenko
>> <andrei.emeltchenko@gmail.com> wrote:
>> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>> >
>> > ---
>> >  android/avctp.c | 13 +++++++++++++
>> >  android/avctp.h |  3 +++
>> >  2 files changed, 16 insertions(+)
>> >
>> > diff --git a/android/avctp.c b/android/avctp.c
>> > index 1e414d1..57a8c23 100644
>> > --- a/android/avctp.c
>> > +++ b/android/avctp.c
>> > @@ -1266,6 +1266,19 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
>> >                                                 func, user_data);
>> >  }
>> >
>> > +int avctp_send_unit_info_req(struct avctp *session, avctp_rsp_cb func,
>> > +                                                               void *user_data)
>> > +{
>> > +       uint8_t operands[5];
>> > +
>> > +       memset(operands, 0xFF, sizeof(operands));
>> > +
>> > +       return avctp_send_req(session, AVC_CTYPE_STATUS,
>> > +                               AVC_SUBUNIT_UNIT, AVC_OP_UNITINFO,
>> > +                               operands, sizeof(operands),
>> > +                               func, user_data);
>> > +}
>> > +
>> >  unsigned int avctp_register_passthrough_handler(struct avctp *session,
>> >                                                 avctp_passthrough_cb cb,
>> >                                                 void *user_data)
>> > diff --git a/android/avctp.h b/android/avctp.h
>> > index dfa0ca6..7496e53 100644
>> > --- a/android/avctp.h
>> > +++ b/android/avctp.h
>> > @@ -46,6 +46,7 @@
>> >
>> >  /* subunits of interest */
>> >  #define AVC_SUBUNIT_PANEL              0x09
>> > +#define AVC_SUBUNIT_UNIT               0x1f
>> >
>> >  /* operands in passthrough commands */
>> >  #define AVC_SELECT                     0x00
>> > @@ -170,3 +171,5 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
>> >  int avctp_send_browsing_req(struct avctp *session,
>> >                                 uint8_t *operands, size_t operand_count,
>> >                                 avctp_browsing_rsp_cb func, void *user_data);
>> > +int avctp_send_unit_info_req(struct avctp *session, avctp_rsp_cb func,
>> > +                                                       void *user_data);
>> > --
>> > 1.8.3.2
>>
>> This probably needs to be internal and sent automatically once
>> connected specially if it is for a mandatory test.
>
> So what do you propose with this case? Make it private and send this
> command in avrcp_new() ?

If it is mandatory, yes we should do it automatically, perhaps we can
trigger it with passthrough registration.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCHv2 1/6] unit/avrcp: First unit test for AVRCP profile
From: Luiz Augusto von Dentz @ 2014-02-24  8:25 UTC (permalink / raw)
  To: Andrei Emeltchenko, linux-bluetooth@vger.kernel.org
In-Reply-To: <20140224070911.GD4133@aemeltch-MOBL1>

Hi Andrei,

On Mon, Feb 24, 2014 at 9:09 AM, Andrei Emeltchenko
<andrei.emeltchenko@gmail.com> wrote:
> On Fri, Feb 21, 2014 at 05:23:45PM +0200, Andrei Emeltchenko wrote:
>> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>>
>> The tests verifies connection establishment for control.
>
> ping
>
>
>> ---
>>  Makefile.am       |   9 ++
>>  unit/test-avrcp.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 274 insertions(+)
>>  create mode 100644 unit/test-avrcp.c
>>
>> diff --git a/Makefile.am b/Makefile.am
>> index 11f2aa1..5fe58eb 100644
>> --- a/Makefile.am
>> +++ b/Makefile.am
>> @@ -282,6 +282,15 @@ unit_test_avctp_SOURCES = unit/test-avctp.c \
>>                               android/avctp.c android/avctp.h
>>  unit_test_avctp_LDADD = @GLIB_LIBS@
>>
>> +unit_tests += unit/test-avrcp
>> +
>> +unit_test_avrcp_SOURCES = unit/test-avrcp.c \
>> +                             src/shared/util.h src/shared/util.c \
>> +                             src/log.h src/log.c \
>> +                             android/avctp.c android/avctp.h \
>> +                             android/avrcp-lib.c android/avrcp-lib.h
>> +unit_test_avrcp_LDADD = @GLIB_LIBS@ lib/libbluetooth-internal.la
>> +
>>  unit_tests += unit/test-gdbus-client
>>
>>  unit_test_gdbus_client_SOURCES = unit/test-gdbus-client.c
>> diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
>> new file mode 100644
>> index 0000000..f1c0f46
>> --- /dev/null
>> +++ b/unit/test-avrcp.c
>> @@ -0,0 +1,265 @@
>> +/*
>> + *
>> + *  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 "lib/bluetooth.h"
>> +
>> +#include "android/avctp.h"
>> +#include "android/avrcp-lib.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 avrcp *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, "AVRCP: ");
>> +
>> +     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, "AVRCP: ");
>> +
>> +     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 = avrcp_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 destroy_context(struct context *context)
>> +{
>> +     if (context->source > 0)
>> +             g_source_remove(context->source);
>> +
>> +     avrcp_shutdown(context->session);
>> +
>> +     g_main_loop_unref(context->main_loop);
>> +
>> +     test_free(context->data);
>> +     g_free(context);
>> +}
>> +
>> +static void test_dummy(gconstpointer data)
>> +{
>> +     struct context *context =  create_context(0x0100, data);
>> +
>> +     destroy_context(context);
>> +}
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +     g_test_init(&argc, &argv, NULL);
>> +
>> +     if (g_test_verbose())
>> +             __btd_log_init("*", 0);
>> +
>> +     /* Connection Establishment for Control tests */
>> +
>> +     /*
>> +      * Tests are checking connection establishement and release
>> +      * for control channel. Since we are connected through socketpair
>> +      * the tests are dummy
>> +      */
>> +     define_test("/TP/CEC/BV-01-I", test_dummy, raw_pdu(0x00));
>> +     define_test("/TP/CEC/BV-02-I", test_dummy, raw_pdu(0x00));
>> +     define_test("/TP/CRC/BV-01-I", test_dummy, raw_pdu(0x00));
>> +     define_test("/TP/CRC/BV-02-I", test_dummy, raw_pdu(0x00));
>> +
>> +     return g_test_run();
>> +}
>> --
>> 1.8.3.2
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Applied, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: Wireshark and new BlueZ BTSNOOP format
From: Michal Labedzki @ 2014-02-24  7:30 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org development; +Cc: Szymon Janc, Marcel Holtmann
In-Reply-To: <CALkxMhECbmeiHHaekdpfQtoZBM+w-BTmYkvnSSFT1SPF-jbKYA@mail.gmail.com>

Hello again,

>From now Wireshark and libpcap support new Bluetooth interface called:
"bluetooth-monitor", so you are able to realtime sniffing on all
Bluetooth adapters right now (like btmon).

Try latest git sources:
1. libpcap: git clone https://github.com/the-tcpdump-group/libpcap.git
2. Wireshark: git clone https://code.wireshark.org/review/wireshark
And do not forget to switch default profile to Bluetooth profile
(right down corner)

If somebody have new idea/feature or see a bug please let me know.

--=20

Pozdrawiam / Best regards
---------------------------------------------------------------------------=
----------------------------------
Micha=C5=82 =C5=81ab=C4=99dzki, Software Engineer
Tieto Corporation

Product Development Services

http://www.tieto.com / http://www.tieto.pl
---
ASCII: Michal Labedzki
location: Swobodna 1 Street, 50-088 Wroc=C5=82aw, Poland
room: 5.01 (desk next to 5.08)
---
Please note: The information contained in this message may be legally
privileged and confidential and protected from disclosure. If the
reader of this message is not the intended recipient, you are hereby
notified that any unauthorised use, distribution or copying of this
communication is strictly prohibited. If you have received this
communication in error, please notify us immediately by replying to
the message and deleting it from your computer. Thank You.
---
Please consider the environment before printing this e-mail.
---
Tieto Poland sp=C3=B3=C5=82ka z ograniczon=C4=85 odpowiedzialno=C5=9Bci=C4=
=85 z siedzib=C4=85 w
Szczecinie, ul. Malczewskiego 26. Zarejestrowana w S=C4=85dzie Rejonowym
Szczecin-Centrum w Szczecinie, XIII Wydzia=C5=82 Gospodarczy Krajowego
Rejestru S=C4=85dowego pod numerem 0000124858. NIP: 8542085557. REGON:
812023656. Kapita=C5=82 zak=C5=82adowy: 4 271500 PLN

^ permalink raw reply

* [PATCH] Dump advertisement data for LE
From: Jérôme Poulin @ 2014-02-24  7:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jérôme Poulin

This patch allows hcidump to dump data inside currently unknown fields, LE
devices like the RFduino will include this kind of data in every broadcast.
---
 tools/parser/hci.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/tools/parser/hci.c b/tools/parser/hci.c
index 17b776d..bf117ce 100644
--- a/tools/parser/hci.c
+++ b/tools/parser/hci.c
@@ -766,6 +766,7 @@ static inline void ext_inquiry_data_dump(int level, struct frame *frm,
 {
 	uint8_t len = data[0];
 	uint8_t type;
+	char *hexdump;
 	char *str;
 	int i;
 
@@ -821,6 +822,22 @@ static inline void ext_inquiry_data_dump(int level, struct frame *frm,
 		p_indent(level, frm);
 		printf("Unknown type 0x%02x with %d bytes data\n",
 							type, len);
+		str = malloc(len + 1);
+		hexdump = malloc(len*3 + 1);
+		if (str && hexdump) {
+			memcpy(str, data, len);
+			str[len + 1] = 0;
+			for (i = 0; i < len; i++) {
+				sprintf(hexdump+i*3, "%02x ",
+					(unsigned char) str[i]);
+				if (!isprint(str[i]))
+					str[i] = '.';
+			}
+			p_indent(level + 1, frm);
+			printf("data: %s| %s\n", hexdump, str);
+			free(hexdump);
+			free(str);
+		}
 		break;
 	}
 }
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH] android/tester: Fix slang "never used" warning
From: Andrei Emeltchenko @ 2014-02-24  7:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1480378.m0ANBe2P0I@uw000953>

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

The patch fixes following warning:
...
android/android-tester.c:2185:2: warning: Value stored to
'adapter_status' is never read
        adapter_status = data->if_bluetooth->set_adapter_property(prop);
        ^                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
---
 android/android-tester.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index 84c6ca9..a376b11 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -2190,6 +2190,10 @@ static void test_getprop_bdname_success(const void *test_data)
 	init_test_conditions(data);
 
 	adapter_status = data->if_bluetooth->set_adapter_property(prop);
+	if (adapter_status != BT_STATUS_SUCCESS) {
+		tester_test_failed();
+		return;
+	}
 
 	adapter_status = data->if_bluetooth->get_adapter_property((*prop).type);
 	check_expected_status(adapter_status);
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCHv2 1/6] unit/avrcp: First unit test for AVRCP profile
From: Andrei Emeltchenko @ 2014-02-24  7:09 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392996230-11789-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

On Fri, Feb 21, 2014 at 05:23:45PM +0200, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> The tests verifies connection establishment for control.

ping


> ---
>  Makefile.am       |   9 ++
>  unit/test-avrcp.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 274 insertions(+)
>  create mode 100644 unit/test-avrcp.c
> 
> diff --git a/Makefile.am b/Makefile.am
> index 11f2aa1..5fe58eb 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -282,6 +282,15 @@ unit_test_avctp_SOURCES = unit/test-avctp.c \
>  				android/avctp.c android/avctp.h
>  unit_test_avctp_LDADD = @GLIB_LIBS@
>  
> +unit_tests += unit/test-avrcp
> +
> +unit_test_avrcp_SOURCES = unit/test-avrcp.c \
> +				src/shared/util.h src/shared/util.c \
> +				src/log.h src/log.c \
> +				android/avctp.c android/avctp.h \
> +				android/avrcp-lib.c android/avrcp-lib.h
> +unit_test_avrcp_LDADD = @GLIB_LIBS@ lib/libbluetooth-internal.la
> +
>  unit_tests += unit/test-gdbus-client
>  
>  unit_test_gdbus_client_SOURCES = unit/test-gdbus-client.c
> diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
> new file mode 100644
> index 0000000..f1c0f46
> --- /dev/null
> +++ b/unit/test-avrcp.c
> @@ -0,0 +1,265 @@
> +/*
> + *
> + *  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 "lib/bluetooth.h"
> +
> +#include "android/avctp.h"
> +#include "android/avrcp-lib.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 avrcp *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, "AVRCP: ");
> +
> +	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, "AVRCP: ");
> +
> +	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 = avrcp_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 destroy_context(struct context *context)
> +{
> +	if (context->source > 0)
> +		g_source_remove(context->source);
> +
> +	avrcp_shutdown(context->session);
> +
> +	g_main_loop_unref(context->main_loop);
> +
> +	test_free(context->data);
> +	g_free(context);
> +}
> +
> +static void test_dummy(gconstpointer data)
> +{
> +	struct context *context =  create_context(0x0100, data);
> +
> +	destroy_context(context);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	g_test_init(&argc, &argv, NULL);
> +
> +	if (g_test_verbose())
> +		__btd_log_init("*", 0);
> +
> +	/* Connection Establishment for Control tests */
> +
> +	/*
> +	 * Tests are checking connection establishement and release
> +	 * for control channel. Since we are connected through socketpair
> +	 * the tests are dummy
> +	 */
> +	define_test("/TP/CEC/BV-01-I", test_dummy, raw_pdu(0x00));
> +	define_test("/TP/CEC/BV-02-I", test_dummy, raw_pdu(0x00));
> +	define_test("/TP/CRC/BV-01-I", test_dummy, raw_pdu(0x00));
> +	define_test("/TP/CRC/BV-02-I", test_dummy, raw_pdu(0x00));
> +
> +	return g_test_run();
> +}
> -- 
> 1.8.3.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCHv2 5/6] unit/avrcp: Add /TP/ICC/BV-01-I/CT test
From: Andrei Emeltchenko @ 2014-02-24  7:03 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZKcpH-7QeYcFv3wV=sToyeeOBd19+4mTW2k8vzSfxaYVA@mail.gmail.com>

Hi Luiz,

On Sun, Feb 23, 2014 at 02:06:59PM +0200, Luiz Augusto von Dentz wrote:
> HI Andrei,
> 
> On Fri, Feb 21, 2014 at 5:23 PM, Andrei Emeltchenko
> <andrei.emeltchenko@gmail.com> wrote:
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > Test verifies that the Controller can collect information of Target
> > by UNIT INFO command.
> > ---
> >  unit/test-avrcp.c | 37 +++++++++++++++++++++++++++++++++++++
> >  1 file changed, 37 insertions(+)
> >
> > diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
> > index f1c0f46..2cb28b1 100644
> > --- a/unit/test-avrcp.c
> > +++ b/unit/test-avrcp.c
> > @@ -242,6 +242,37 @@ static void test_dummy(gconstpointer data)
> >         destroy_context(context);
> >  }
> >
> > +static void execute_context(struct context *context)
> > +{
> > +       g_main_loop_run(context->main_loop);
> > +
> > +       if (context->source > 0)
> > +               g_source_remove(context->source);
> > +
> > +       avrcp_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);
> > +       struct avctp *session = avrcp_get_avctp(context->session);
> > +       int ret = 0;
> > +
> > +       if (g_str_equal(context->data->test_name, "/TP/ICC/BV-01-I/CT"))
> > +               ret = avctp_send_unit_info_req(session, NULL, NULL);
> > +
> > +       DBG("ret = %d", ret);
> > +
> > +       g_assert(!ret);
> > +
> > +       execute_context(context);
> > +}
> > +
> >  int main(int argc, char *argv[])
> >  {
> >         g_test_init(&argc, &argv, NULL);
> > @@ -261,5 +292,11 @@ int main(int argc, char *argv[])
> >         define_test("/TP/CRC/BV-01-I", test_dummy, raw_pdu(0x00));
> >         define_test("/TP/CRC/BV-02-I", test_dummy, raw_pdu(0x00));
> >
> > +       /* Information collection for control tests */
> > +
> > +       define_test("/TP/ICC/BV-01-I/CT", test_client,
> > +                       raw_pdu(0x00, 0x11, 0x0e, 0x01, 0xf8, 0x30,
> > +                               0xff, 0xff, 0xff, 0xff, 0xff));
> > +
> >         return g_test_run();
> >  }
> > --
> > 1.8.3.2
> 
> There is no such test in the test spec, there is only TP/ICC/BV-01-I,
> perhaps you adding CT yourself just to be able to define the same test
> for the TG but in that case I think it is better to separate with
> different macros e.g. define_test_ct prefixing with "CT" to make
> better distinction and don't mess with test names otherwise we may
> confuse people looking at those tests.

Sorry don't get it. How we might confuse people with it? Anybody who
looked at least once to the spec wouldn't be confused, and others do not
care.

Anyway please propose any way I will follow example.

BTW: What is really confusing are names in pts-avrcp.txt. They are
almost completely different like for the case above:

"TC_TG_ICC_BV_01_I"

Best regards 
Andrei Emeltchenko 

^ permalink raw reply

* Re: [PATCHv2 4/6] android/avrcp: Use NULL for zero pointers
From: Andrei Emeltchenko @ 2014-02-24  6:55 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392996230-11789-4-git-send-email-Andrei.Emeltchenko.news@gmail.com>

On Fri, Feb 21, 2014 at 05:23:48PM +0200, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

ping

> 
> ---
>  android/avrcp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/android/avrcp.c b/android/avrcp.c
> index 8ac9e2f..acffd56 100644
> --- a/android/avrcp.c
> +++ b/android/avrcp.c
> @@ -222,7 +222,7 @@ static sdp_record_t *avrcp_record(void)
>  	features = sdp_data_alloc(SDP_UINT16, &feat);
>  	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
>  
> -	sdp_set_info_attr(record, "AVRCP TG", 0, 0);
> +	sdp_set_info_attr(record, "AVRCP TG", NULL, NULL);
>  
>  	sdp_data_free(psm);
>  	sdp_data_free(version);
> -- 
> 1.8.3.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCHv2 2/6] android/avctp: Add UNIT INFO command request
From: Andrei Emeltchenko @ 2014-02-24  6:54 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZL9G3odx=Dgo_R9e0M0N8ZwewLqx1PPnnCrxTz8NuXFxw@mail.gmail.com>

Hi Luiz,

On Sun, Feb 23, 2014 at 01:57:05PM +0200, Luiz Augusto von Dentz wrote:
> Hi Andrei,
> 
> On Fri, Feb 21, 2014 at 5:23 PM, Andrei Emeltchenko
> <andrei.emeltchenko@gmail.com> wrote:
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > ---
> >  android/avctp.c | 13 +++++++++++++
> >  android/avctp.h |  3 +++
> >  2 files changed, 16 insertions(+)
> >
> > diff --git a/android/avctp.c b/android/avctp.c
> > index 1e414d1..57a8c23 100644
> > --- a/android/avctp.c
> > +++ b/android/avctp.c
> > @@ -1266,6 +1266,19 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
> >                                                 func, user_data);
> >  }
> >
> > +int avctp_send_unit_info_req(struct avctp *session, avctp_rsp_cb func,
> > +                                                               void *user_data)
> > +{
> > +       uint8_t operands[5];
> > +
> > +       memset(operands, 0xFF, sizeof(operands));
> > +
> > +       return avctp_send_req(session, AVC_CTYPE_STATUS,
> > +                               AVC_SUBUNIT_UNIT, AVC_OP_UNITINFO,
> > +                               operands, sizeof(operands),
> > +                               func, user_data);
> > +}
> > +
> >  unsigned int avctp_register_passthrough_handler(struct avctp *session,
> >                                                 avctp_passthrough_cb cb,
> >                                                 void *user_data)
> > diff --git a/android/avctp.h b/android/avctp.h
> > index dfa0ca6..7496e53 100644
> > --- a/android/avctp.h
> > +++ b/android/avctp.h
> > @@ -46,6 +46,7 @@
> >
> >  /* subunits of interest */
> >  #define AVC_SUBUNIT_PANEL              0x09
> > +#define AVC_SUBUNIT_UNIT               0x1f
> >
> >  /* operands in passthrough commands */
> >  #define AVC_SELECT                     0x00
> > @@ -170,3 +171,5 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
> >  int avctp_send_browsing_req(struct avctp *session,
> >                                 uint8_t *operands, size_t operand_count,
> >                                 avctp_browsing_rsp_cb func, void *user_data);
> > +int avctp_send_unit_info_req(struct avctp *session, avctp_rsp_cb func,
> > +                                                       void *user_data);
> > --
> > 1.8.3.2
> 
> This probably needs to be internal and sent automatically once
> connected specially if it is for a mandatory test.

So what do you propose with this case? Make it private and send this
command in avrcp_new() ?

Best regards 
Andrei Emeltchenko 

^ permalink raw reply

* Re: [PATCH 1/2] Bluetooth: Store current RPA and update it if needed
From: Johan Hedberg @ 2014-02-24  6:51 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1393216763-14836-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sun, Feb 23, 2014, Marcel Holtmann wrote:
> The RPA needs to be stored to know which is the current one. Otherwise
> it is impossible to ensure that always the correct RPA can be programmed
> into the controller when it is needed.
> 
> Current code checks if the address in the controller is a RPA, but that
> can potentially lead to using a RPA that can not be resolved with the
> IRK that has been distributed.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  include/net/bluetooth/hci_core.h |  1 +
>  net/bluetooth/hci_core.c         | 11 +++++------
>  2 files changed, 6 insertions(+), 6 deletions(-)

Both patches have been applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/2] Bluetooth: Use unresolvable private address for active scanning
From: Johan Hedberg @ 2014-02-24  6:49 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1393215955-3907-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sun, Feb 23, 2014, Marcel Holtmann wrote:
> When running active scanning during LE discovery, do not reveal the own
> identity to the peer devices. In case LE privacy has been enabled, then
> a resolvable private address is used. If the LE privacy option is off,
> then use an unresolvable private address.
> 
> The public address or static random address is never used in active
> scanning anymore. This ensures that scan request are send using a
> random address.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  include/net/bluetooth/hci_core.h |  3 ++-
>  net/bluetooth/hci_conn.c         |  2 +-
>  net/bluetooth/hci_core.c         | 18 +++++++++++++++++-
>  net/bluetooth/mgmt.c             |  8 ++++++--
>  4 files changed, 26 insertions(+), 5 deletions(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] Bluetooth: Expose current identity information in debugfs
From: Johan Hedberg @ 2014-02-24  6:32 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1393188265-55337-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sun, Feb 23, 2014, Marcel Holtmann wrote:
> When using LE Privacy it is useful to know the local identity address,
> identity address type and identity resolving key. For debugging purposes
> add these information to debugfs.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  net/bluetooth/hci_core.c | 42 ++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 40 insertions(+), 2 deletions(-)

Applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* [PATCH 2/2] Bluetooth: Export current local RPA with identity information
From: Marcel Holtmann @ 2014-02-24  4:39 UTC (permalink / raw)
  To: linux-bluetooth

The identity information in debugfs currently do not include the
current in use local RPA. Since the RPA is now stored in the
controller information, include it in the debugfs as well.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6928989ec906..14f7a3ecfef1 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -596,7 +596,8 @@ static int identity_show(struct seq_file *f, void *p)
 		addr_type = ADDR_LE_DEV_PUBLIC;
 	}
 
-	seq_printf(f, "%pMR (type %u) %*phN\n", addr, addr_type, 16, hdev->irk);
+	seq_printf(f, "%pMR (type %u) %*phN %pMR\n", addr, addr_type,
+		   16, hdev->irk, &hdev->rpa);
 
 	hci_dev_unlock(hdev);
 
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Store current RPA and update it if needed
From: Marcel Holtmann @ 2014-02-24  4:39 UTC (permalink / raw)
  To: linux-bluetooth

The RPA needs to be stored to know which is the current one. Otherwise
it is impossible to ensure that always the correct RPA can be programmed
into the controller when it is needed.

Current code checks if the address in the controller is a RPA, but that
can potentially lead to using a RPA that can not be resolved with the
IRK that has been distributed.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 11 +++++------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b0350c032b26..2ad907cf23e8 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -308,6 +308,7 @@ struct hci_dev {
 	__u8			irk[16];
 	__u32			rpa_timeout;
 	struct delayed_work	rpa_expired;
+	bdaddr_t		rpa;
 
 	int (*open)(struct hci_dev *hdev);
 	int (*close)(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e3caad5c1e6e..6928989ec906 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3339,26 +3339,25 @@ int hci_update_random_address(struct hci_request *req, bool allow_privacy,
 	int err;
 
 	/* If privacy is enabled use a resolvable private address. If
-	 * the current RPA has expired or there's something else than an
-	 * RPA currently in use regenerate a new one.
+	 * current RPA has expired or there is something else than
+	 * the current RPA in use, then generate a new one.
 	 */
 	if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
-		bdaddr_t rpa;
 		int to;
 
 		*own_addr_type = ADDR_LE_DEV_RANDOM;
 
 		if (!test_and_clear_bit(HCI_RPA_EXPIRED, &hdev->dev_flags) &&
-		    hci_bdaddr_is_rpa(&hdev->random_addr, ADDR_LE_DEV_RANDOM))
+		    !bacmp(&hdev->random_addr, &hdev->rpa))
 			return 0;
 
-		err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &rpa);
+		err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa);
 		if (err < 0) {
 			BT_ERR("%s failed to generate new RPA", hdev->name);
 			return err;
 		}
 
-		hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &rpa);
+		hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &hdev->rpa);
 
 		to = msecs_to_jiffies(hdev->rpa_timeout * 1000);
 		queue_delayed_work(hdev->workqueue, &hdev->rpa_expired, to);
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 2/2] Bluetooth: Use privacy mode for non-connectable advertising
From: Marcel Holtmann @ 2014-02-24  4:25 UTC (permalink / raw)
  To: linux-bluetooth

When enabling non-connectable advertising, there is no need to advertise
with a public address or static address. In case LE privacy has not been
enabled a unresolvable private address will be used.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/mgmt.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 5d309d4ab527..50d86e2e6bc5 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -841,12 +841,14 @@ static void enable_advertising(struct hci_request *req)
 	struct hci_dev *hdev = req->hdev;
 	struct hci_cp_le_set_adv_param cp;
 	u8 own_addr_type, enable = 0x01;
+	bool allow_privacy;
 
-	memset(&cp, 0, sizeof(cp));
+	allow_privacy = !test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
 
-	if (hci_update_random_address(req, false, &own_addr_type) < 0)
+	if (hci_update_random_address(req, allow_privacy, &own_addr_type) < 0)
 		return;
 
+	memset(&cp, 0, sizeof(cp));
 	cp.min_interval = __constant_cpu_to_le16(0x0800);
 	cp.max_interval = __constant_cpu_to_le16(0x0800);
 	cp.type = get_adv_type(hdev);
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Use unresolvable private address for active scanning
From: Marcel Holtmann @ 2014-02-24  4:25 UTC (permalink / raw)
  To: linux-bluetooth

When running active scanning during LE discovery, do not reveal the own
identity to the peer devices. In case LE privacy has been enabled, then
a resolvable private address is used. If the LE privacy option is off,
then use an unresolvable private address.

The public address or static random address is never used in active
scanning anymore. This ensures that scan request are send using a
random address.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |  3 ++-
 net/bluetooth/hci_conn.c         |  2 +-
 net/bluetooth/hci_core.c         | 18 +++++++++++++++++-
 net/bluetooth/mgmt.c             |  8 ++++++--
 4 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 43b6d1131c4d..b0350c032b26 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1256,7 +1256,8 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
 void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
 							__u8 ltk[16]);
 
-int hci_update_random_address(struct hci_request *req, u8 *own_addr_type);
+int hci_update_random_address(struct hci_request *req, bool allow_privacy,
+			      u8 *own_addr_type);
 
 #define SCO_AIRMODE_MASK       0x0003
 #define SCO_AIRMODE_CVSD       0x0000
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a1efa1c62de8..744b3d49da1a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -563,7 +563,7 @@ static int hci_create_le_conn(struct hci_conn *conn)
 
 	memset(&cp, 0, sizeof(cp));
 
-	err = hci_update_random_address(&req, &own_addr_type);
+	err = hci_update_random_address(&req, false, &own_addr_type);
 	if (err < 0)
 		return err;
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 80462a126ebd..e3caad5c1e6e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3332,7 +3332,8 @@ static void le_scan_disable_work(struct work_struct *work)
 		BT_ERR("Disable LE scanning request failed: err %d", err);
 }
 
-int hci_update_random_address(struct hci_request *req, u8 *own_addr_type)
+int hci_update_random_address(struct hci_request *req, bool allow_privacy,
+			      u8 *own_addr_type)
 {
 	struct hci_dev *hdev = req->hdev;
 	int err;
@@ -3365,6 +3366,21 @@ int hci_update_random_address(struct hci_request *req, u8 *own_addr_type)
 		return 0;
 	}
 
+	/* In case of allowed privacy without resolvable private address,
+	 * use an unresolvable private address. This is useful for active
+	 * scanning and non-connectable advertising.
+	 */
+	if (allow_privacy) {
+		bdaddr_t urpa;
+
+		get_random_bytes(&urpa, 6);
+		urpa.b[5] &= 0x3f;	/* Clear two most significant bits */
+
+		*own_addr_type = ADDR_LE_DEV_RANDOM;
+		hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, &urpa);
+		return 0;
+	}
+
 	/* If forcing static address is in use or there is no public
 	 * address use the static address as random address (but skip
 	 * the HCI command if the current random address is already the
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 37305facf4d6..5d309d4ab527 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -844,7 +844,7 @@ static void enable_advertising(struct hci_request *req)
 
 	memset(&cp, 0, sizeof(cp));
 
-	if (hci_update_random_address(req, &own_addr_type) < 0)
+	if (hci_update_random_address(req, false, &own_addr_type) < 0)
 		return;
 
 	cp.min_interval = __constant_cpu_to_le16(0x0800);
@@ -3389,7 +3389,11 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
 
 		memset(&param_cp, 0, sizeof(param_cp));
 
-		err = hci_update_random_address(&req, &own_addr_type);
+		/* All active scans will be done with either a resolvable
+		 * private address (when privacy feature has been enabled)
+		 * or unresolvable private address.
+		 */
+		err = hci_update_random_address(&req, true, &own_addr_type);
 		if (err < 0) {
 			err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
 					 MGMT_STATUS_FAILED);
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH] Bluetooth: Expose current identity information in debugfs
From: Marcel Holtmann @ 2014-02-23 20:44 UTC (permalink / raw)
  To: linux-bluetooth

When using LE Privacy it is useful to know the local identity address,
identity address type and identity resolving key. For debugging purposes
add these information to debugfs.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1651de959d9c..80462a126ebd 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -579,6 +579,42 @@ static int sniff_max_interval_get(void *data, u64 *val)
 DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get,
 			sniff_max_interval_set, "%llu\n");
 
+static int identity_show(struct seq_file *f, void *p)
+{
+	struct hci_dev *hdev = f->private;
+	bdaddr_t *addr;
+	u8 addr_type;
+
+	hci_dev_lock(hdev);
+
+	if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
+	    !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
+		addr = &hdev->static_addr;
+		addr_type = ADDR_LE_DEV_RANDOM;
+	} else {
+		addr = &hdev->bdaddr;
+		addr_type = ADDR_LE_DEV_PUBLIC;
+	}
+
+	seq_printf(f, "%pMR (type %u) %*phN\n", addr, addr_type, 16, hdev->irk);
+
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int identity_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, identity_show, inode->i_private);
+}
+
+static const struct file_operations identity_fops = {
+	.open		= identity_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int random_address_show(struct seq_file *f, void *p)
 {
 	struct hci_dev *hdev = f->private;
@@ -1624,12 +1660,14 @@ static int __hci_init(struct hci_dev *hdev)
 	}
 
 	if (lmp_le_capable(hdev)) {
+		debugfs_create_file("identity", 0400, hdev->debugfs,
+				    hdev, &identity_fops);
+		debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
+				    hdev, &rpa_timeout_fops);
 		debugfs_create_file("random_address", 0444, hdev->debugfs,
 				    hdev, &random_address_fops);
 		debugfs_create_file("static_address", 0444, hdev->debugfs,
 				    hdev, &static_address_fops);
-		debugfs_create_file("rpa_timeout", 0644, hdev->debugfs,
-				    hdev, &rpa_timeout_fops);
 
 		/* For controllers with a public address, provide a debug
 		 * option to force the usage of the configured static
-- 
1.8.5.3


^ 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