Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCHv4 1/7] Add support for Out of Band (OOB) association model
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1290509592-9262-1-git-send-email-szymon.janc@tieto.com>

---
 Makefile.am      |    3 +-
 lib/hci.h        |    3 ++
 plugins/hciops.c |   86 +++++++++++++++++++++++++++++++++++++++++++++--------
 src/adapter.c    |   14 ++++++++-
 src/adapter.h    |    6 ++++
 src/device.c     |   74 ++++++++++++++++++++++++++++++++++++++++++++++
 src/device.h     |   12 +++++++
 src/event.c      |   53 +++++++++++++++++++++------------
 src/event.h      |    3 +-
 src/oob.c        |   67 ++++++++++++++++++++++++++++++++++++++++++
 src/oob.h        |   47 +++++++++++++++++++++++++++++
 11 files changed, 332 insertions(+), 36 deletions(-)
 create mode 100644 src/oob.c
 create mode 100644 src/oob.h

diff --git a/Makefile.am b/Makefile.am
index 5f96975..47da8eb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -240,7 +240,8 @@ src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
 			src/adapter.h src/adapter.c \
 			src/device.h src/device.c \
 			src/dbus-common.c src/dbus-common.h \
-			src/event.h src/event.c
+			src/event.h src/event.c \
+			src/oob.c
 src_bluetoothd_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @DBUS_LIBS@ \
 							@CAPNG_LIBS@ -ldl -lrt
 src_bluetoothd_LDFLAGS = -Wl,--export-dynamic \
diff --git a/lib/hci.h b/lib/hci.h
index 0cb120f..409abd9 100644
--- a/lib/hci.h
+++ b/lib/hci.h
@@ -524,6 +524,9 @@ typedef struct {
 
 #define OCF_REMOTE_OOB_DATA_NEG_REPLY	0x0033
 
+#define OOB_DATA_NOT_PRESENT	0x00
+#define OOB_DATA_PRESENT	0x01
+
 #define OCF_IO_CAPABILITY_NEG_REPLY	0x0034
 typedef struct {
 	bdaddr_t	bdaddr;
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 9abe477..c62ac51 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -3,6 +3,7 @@
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *  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
@@ -47,6 +48,7 @@
 #include "event.h"
 #include "device.h"
 #include "manager.h"
+#include "oob.h"
 
 #define HCI_REQ_TIMEOUT         5000
 
@@ -652,20 +654,41 @@ static void user_passkey_notify(int index, void *ptr)
 
 static void remote_oob_data_request(int index, void *ptr)
 {
-	hci_send_cmd(SK(index), OGF_LINK_CTL,
-				OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr);
+	bdaddr_t *dba = ptr;
+	struct btd_adapter *adapter;
+	struct btd_device *device;
+	char da[18];
+
+	ba2str(dba, da);
+	adapter = manager_find_adapter(&BDADDR(index));
+	device = adapter_find_device(adapter, da);
+
+	if (!device_get_oob_data(device, NULL, NULL) {
+		remote_oob_data_reply_cp cp;
+
+		bacpy(&cp.bdaddr, dba);
+		device_get_oob_data(device,cp.hash,cp.randomizer);
+
+		hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
+				REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+	} else
+		hci_send_cmd(SK(index),
+				OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6,
+				ptr);
 }
 
 static void io_capa_request(int index, void *ptr)
 {
 	bdaddr_t *dba = ptr;
 	char sa[18], da[18];
-	uint8_t cap, auth;
 
 	ba2str(&BDADDR(index), sa); ba2str(dba, da);
 	info("io_capa_request (sba=%s, dba=%s)", sa, da);
 
-	if (btd_event_get_io_cap(&BDADDR(index), dba, &cap, &auth) < 0) {
+	/* If failed to establish IO capabilities then send negative reply
+	 * immediately. Positive reply will be sent when IO capabilities are
+	 * established. */
+	if (btd_event_request_io_cap(&BDADDR(index), dba)) {
 		io_capability_neg_reply_cp cp;
 		memset(&cp, 0, sizeof(cp));
 		bacpy(&cp.bdaddr, dba);
@@ -673,15 +696,6 @@ static void io_capa_request(int index, void *ptr)
 		hci_send_cmd(SK(index), OGF_LINK_CTL,
 					OCF_IO_CAPABILITY_NEG_REPLY,
 					IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp);
-	} else {
-		io_capability_reply_cp cp;
-		memset(&cp, 0, sizeof(cp));
-		bacpy(&cp.bdaddr, dba);
-		cp.capability = cap;
-		cp.oob_data = 0x00;
-		cp.authentication = auth;
-		hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
-					IO_CAPABILITY_REPLY_CP_SIZE, &cp);
 	}
 }
 
@@ -995,6 +1009,9 @@ static inline void cmd_status(int index, void *ptr)
 
 	if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY))
 		start_inquiry(&BDADDR(index), evt->status, FALSE);
+	else if (opcode == cmd_opcode_pack(OGF_HOST_CTL,
+						OCF_READ_LOCAL_OOB_DATA))
+		oob_local_data_read(&BDADDR(index), NULL, NULL);
 }
 
 static void read_scan_complete(int index, uint8_t status, void *ptr)
@@ -1012,6 +1029,15 @@ static void read_scan_complete(int index, uint8_t status, void *ptr)
 	adapter_mode_changed(adapter, rp->enable);
 }
 
+static void read_local_oob_data_complete(bdaddr_t *local, uint8_t status,
+						read_local_oob_data_rp *rp)
+{
+	if (status)
+		oob_local_data_read(local, NULL, NULL);
+	else
+		oob_local_data_read(local, rp->hash, rp->randomizer);
+}
+
 static inline void cmd_complete(int index, void *ptr)
 {
 	evt_cmd_complete *evt = ptr;
@@ -1083,6 +1109,10 @@ static inline void cmd_complete(int index, void *ptr)
 		ptr += sizeof(evt_cmd_complete);
 		read_tx_power_complete(index, ptr);
 		break;
+	case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA):
+		ptr += sizeof(evt_cmd_complete);
+		read_local_oob_data_complete(&BDADDR(index), status, ptr);
+		break;
 	};
 }
 
@@ -2514,6 +2544,34 @@ static int hciops_get_remote_version(int index, uint16_t handle,
 	return 0;
 }
 
+static int hciops_read_local_oob_data(int index)
+{
+	if (hci_send_cmd(SK(index), OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA, 0, 0)
+			< 0)
+		return -errno;
+
+	return 0;
+}
+
+
+static void hciops_io_capa_request_reply(int index, struct btd_device *device)
+{
+	io_capability_reply_cp cp;
+
+	memset(&cp, 0, sizeof(cp));
+	device_get_address(device, &cp.bdaddr);
+	device_get_local_auth_cap(device, &cp.authentication, &cp.capability);
+	cp.oob_data = device_get_oob_data(device, NULL, NULL)
+			? OOB_DATA_PRESENT : OOB_DATA_NOT_PRESENT;
+
+	DBG("final capabilities reply is cap=0x%02x, auth=0x%02x, oob=0x%02x",
+	cp.capability, cp.authentication, cp.oob_data);
+
+	hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
+					IO_CAPABILITY_REPLY_CP_SIZE, &cp);
+}
+
+
 static struct btd_adapter_ops hci_ops = {
 	.setup = hciops_setup,
 	.cleanup = hciops_cleanup,
@@ -2554,6 +2612,8 @@ static struct btd_adapter_ops hci_ops = {
 	.write_le_host = hciops_write_le_host,
 	.get_remote_version = hciops_get_remote_version,
 	.encrypt_link = hciops_encrypt_link,
+	.read_local_oob_data = hciops_read_local_oob_data,
+	.io_capa_request_reply = hciops_io_capa_request_reply
 };
 
 static int hciops_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 6b4a354..f0c2dad 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3245,7 +3245,8 @@ void adapter_remove_connection(struct btd_adapter *adapter,
 	/* clean pending HCI cmds */
 	device_get_address(device, &bdaddr);
 
-	if (device_is_authenticating(device))
+	if (device_is_authenticating(device) ||
+			device_get_oob_data(device, NULL, NULL))
 		device_cancel_authentication(device, TRUE);
 
 	if (device_is_temporary(device)) {
@@ -3713,3 +3714,14 @@ int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 {
 	return adapter_ops->encrypt_link(adapter->dev_id, bdaddr, cb, user_data);
 }
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter)
+{
+	return adapter_ops->read_local_oob_data(adapter->dev_id);
+}
+
+void btd_adapter_io_capa_request_reply(struct btd_adapter *adapter,
+					struct btd_device *device)
+{
+	adapter_ops->io_capa_request_reply(adapter->dev_id, device);
+}
diff --git a/src/adapter.h b/src/adapter.h
index de6a6f5..16b7f67 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -232,6 +232,8 @@ struct btd_adapter_ops {
 						gboolean delayed);
 	int (*encrypt_link) (int index, bdaddr_t *bdaddr, bt_hci_result_t cb,
 							gpointer user_data);
+	int (*read_local_oob_data) (int index);
+	void (*io_capa_request_reply) (int index, struct btd_device *device);
 };
 
 int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);
@@ -291,3 +293,7 @@ int btd_adapter_get_remote_version(struct btd_adapter *adapter,
 
 int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				bt_hci_result_t cb, gpointer user_data);
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter);
+void btd_adapter_io_capa_request_reply(struct btd_adapter *adapter,
+					struct btd_device *device);
diff --git a/src/device.c b/src/device.c
index 7c421e3..fd3c3b3 100644
--- a/src/device.c
+++ b/src/device.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -59,6 +60,7 @@
 #include "sdp-xml.h"
 #include "storage.h"
 #include "btio.h"
+#include "oob.h"
 
 #define DEFAULT_XML_BUF_SIZE	1024
 #define DISCONNECT_TIMER	2
@@ -132,6 +134,9 @@ struct btd_device {
 	uint8_t		cap;
 	uint8_t		auth;
 
+	uint8_t		local_cap;
+	uint8_t		local_auth;
+
 	uint16_t	handle;			/* Connection handle */
 
 	/* Whether were creating a security mode 3 connection */
@@ -149,6 +154,12 @@ struct btd_device {
 
 	gboolean	has_debug_key;
 	uint8_t		debug_key[16];
+
+	/* For OOB association model */
+	void (*oob_request_cb)(struct btd_device *device);
+	gboolean	has_oob_data;
+	uint8_t		hash[16];
+	uint8_t		randomizer[16];
 };
 
 static uint16_t uuid_list[] = {
@@ -829,6 +840,67 @@ static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
 	return NULL;
 }
 
+void device_set_oob_data(struct btd_device *device, uint8_t *hash,
+				uint8_t *randomizer)
+{
+	if (!device)
+		return;
+
+	if (hash && randomizer) {
+		memcpy(device->hash, hash, 16);
+		memcpy(device->randomizer, randomizer, 16);
+		device->has_oob_data = TRUE;
+	}
+
+	if (device->oob_request_cb) {
+		device->oob_request_cb(device);
+		device->oob_request_cb = NULL;
+	}
+}
+
+gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
+				uint8_t *randomizer)
+{
+	if (!device || !device->has_oob_data)
+		return FALSE;
+
+	if (hash && randomizer) {
+		memcpy(hash, device->hash, 16);
+		memcpy(randomizer, device->randomizer, 16);
+	}
+
+	return TRUE;
+}
+
+gboolean device_request_oob_data(struct btd_device *device,
+					void (*cb)(struct btd_device *device))
+{
+	if (!device)
+		return FALSE;
+
+	device->oob_request_cb = cb;
+	return oob_request_remote_data(device);
+}
+
+void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
+				uint8_t cap)
+{
+	if (!device)
+		return;
+
+	device->local_auth = auth;
+	device->local_cap = cap;
+}
+void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
+				uint8_t *cap)
+{
+	if (!device)
+		return;
+
+	*auth = device->local_auth;
+	*cap = device->local_cap;
+}
+
 static GDBusMethodTable device_methods[] = {
 	{ "GetProperties",	"",	"a{sv}",	get_properties	},
 	{ "SetProperty",	"sv",	"",		set_property	},
@@ -2264,6 +2336,8 @@ void device_cancel_authentication(struct btd_device *device, gboolean aborted)
 {
 	struct authentication_req *auth = device->authr;
 
+	device->has_oob_data = FALSE;
+
 	if (!auth)
 		return;
 
diff --git a/src/device.h b/src/device.h
index b570bd1..1823f65 100644
--- a/src/device.h
+++ b/src/device.h
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -89,6 +90,17 @@ void device_remove_connection(struct btd_device *device, DBusConnection *conn,
 gboolean device_has_connection(struct btd_device *device, uint16_t handle);
 void device_request_disconnect(struct btd_device *device, DBusMessage *msg);
 
+void device_set_oob_data(struct btd_device *device, uint8_t *hash,
+				uint8_t *randomizer);
+gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
+				uint8_t *randomizer);
+gboolean device_request_oob_data(struct btd_device *device,
+					void (*cb)(struct btd_device *device));
+void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
+				uint8_t cap);
+void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
+				uint8_t *cap);
+
 typedef void (*disconnect_watch) (struct btd_device *device, gboolean removal,
 					void *user_data);
 
diff --git a/src/event.c b/src/event.c
index daab71a..a88a8f5 100644
--- a/src/event.c
+++ b/src/event.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -274,7 +275,8 @@ void btd_event_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
 	if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 		return;
 
-	if (!device_is_authenticating(device)) {
+	if (!device_is_authenticating(device) &&
+			!device_get_oob_data(device, NULL, NULL)) {
 		/* This means that there was no pending PIN or SSP token
 		 * request from the controller, i.e. this is not a new
 		 * pairing */
@@ -724,26 +726,33 @@ void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer)
 	device_set_paired(device, TRUE);
 }
 
-int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
-						uint8_t *cap, uint8_t *auth)
+static void btd_event_io_cap_reply(struct btd_device *device)
+{
+	struct btd_adapter *adapter = device_get_adapter(device);
+
+	btd_adapter_io_capa_request_reply(adapter, device);
+}
+
+int btd_event_request_io_cap(bdaddr_t *local, bdaddr_t *remote)
 {
 	struct btd_adapter *adapter;
 	struct btd_device *device;
 	struct agent *agent = NULL;
 	uint8_t agent_cap;
 	int err;
+	uint8_t cap, auth;
 
 	if (!get_adapter_and_device(local, remote, &adapter, &device, TRUE))
 		return -ENODEV;
 
-	err = btd_adapter_get_auth_info(adapter, remote, auth);
+	err = btd_adapter_get_auth_info(adapter, remote, &auth);
 	if (err < 0)
 		return err;
 
-	DBG("initial authentication requirement is 0x%02x", *auth);
+	DBG("initial authentication requirement is 0x%02x", auth);
 
-	if (*auth == 0xff)
-		*auth = device_get_auth(device);
+	if (auth == 0xff)
+		auth = device_get_auth(device);
 
 	/* Check if the adapter is not pairable and if there isn't a bonding
 	 * in progress */
@@ -752,11 +761,11 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		if (device_get_auth(device) < 0x02) {
 			DBG("Allowing no bonding in non-bondable mode");
 			/* No input, no output */
-			*cap = 0x03;
+			cap = 0x03;
 			/* Kernel defaults to general bonding and so
 			 * overwrite for this special case. Otherwise
 			 * non-pairable test cases will fail. */
-			*auth = 0x00;
+			auth = 0x00;
 			goto done;
 		}
 		return -EPERM;
@@ -772,13 +781,13 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		}
 
 		/* No agent available, and no bonding case */
-		if (*auth == 0x00 || *auth == 0x04) {
+		if (auth == 0x00 || auth == 0x04) {
 			DBG("Allowing no bonding without agent");
 			/* No input, no output */
-			*cap = 0x03;
+			cap = 0x03;
 			/* If kernel defaults to general bonding, set it
 			 * back to no bonding */
-			*auth = 0x00;
+			auth = 0x00;
 			goto done;
 		}
 
@@ -788,7 +797,7 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 
 	agent_cap = agent_get_io_capability(agent);
 
-	if (*auth == 0x00 || *auth == 0x04) {
+	if (auth == 0x00 || auth == 0x04) {
 		/* If remote requests dedicated bonding follow that lead */
 		if (device_get_auth(device) == 0x02 ||
 				device_get_auth(device) == 0x03) {
@@ -797,9 +806,9 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 			 * then require it, otherwise don't */
 			if (device_get_cap(device) == 0x03 ||
 							agent_cap == 0x03)
-				*auth = 0x02;
+				auth = 0x02;
 			else
-				*auth = 0x03;
+				auth = 0x03;
 		}
 
 		/* If remote indicates no bonding then follow that. This
@@ -807,7 +816,7 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		 * as default. */
 		if (device_get_auth(device) == 0x00 ||
 					device_get_auth(device) == 0x01)
-			*auth = 0x00;
+			auth = 0x00;
 
 		/* If remote requires MITM then also require it, unless
 		 * our IO capability is NoInputNoOutput (so some
@@ -815,13 +824,19 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		if (device_get_auth(device) != 0xff &&
 					(device_get_auth(device) & 0x01) &&
 					agent_cap != 0x03)
-			*auth |= 0x01;
+			auth |= 0x01;
 	}
 
-	*cap = agent_get_io_capability(agent);
+	cap = agent_get_io_capability(agent);
 
 done:
-	DBG("final authentication requirement is 0x%02x", *auth);
+	DBG("final authentication requirement is 0x%02x", auth);
+
+	device_set_local_auth_cap(device, auth, cap);
+
+	/* If failed to request remote OOB data then reply immediately. */
+	if (!device_request_oob_data(device, btd_event_io_cap_reply))
+		btd_event_io_cap_reply(device);
 
 	return 0;
 }
diff --git a/src/event.h b/src/event.h
index 4321949..5c122ea 100644
--- a/src/event.h
+++ b/src/event.h
@@ -35,8 +35,7 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t
 void btd_event_setscan_enable_complete(bdaddr_t *local);
 void btd_event_le_set_scan_enable_complete(bdaddr_t *local, uint8_t status);
 void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer);
-int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
-						uint8_t *cap, uint8_t *auth);
+int btd_event_request_io_cap(bdaddr_t *local, bdaddr_t *remote);
 int btd_event_set_io_cap(bdaddr_t *local, bdaddr_t *remote,
 						uint8_t cap, uint8_t auth);
 int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
diff --git a/src/oob.c b/src/oob.c
new file mode 100644
index 0000000..3b9714c
--- /dev/null
+++ b/src/oob.c
@@ -0,0 +1,67 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  ST-Ericsson SA
+ *
+ *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ *  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
+ *
+ */
+
+#include <glib.h>
+#include "manager.h"
+#include "adapter.h"
+#include "oob.h"
+
+static struct oob_plugin *active_plugin = NULL;
+
+void oob_activate_plugin(struct oob_plugin *plugin)
+{
+	if (!plugin)
+		return;
+
+	if (!plugin->local_data_read || !plugin->plugin_deactivated ||
+			!plugin->request_remote_data)
+		return;
+
+	if (active_plugin == plugin)
+		return;
+
+	if (active_plugin)
+		active_plugin->plugin_deactivated();
+
+	active_plugin = plugin;
+}
+
+void oob_deactivate_plugin(struct oob_plugin *plugin)
+{
+	if (active_plugin == plugin)
+		active_plugin = NULL;
+}
+
+gboolean oob_request_remote_data(struct btd_device *device)
+{
+	return active_plugin && active_plugin->request_remote_data(device);
+}
+
+void oob_local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer)
+{
+	if (active_plugin)
+		active_plugin->local_data_read(manager_find_adapter(ba), hash,
+								randomizer);
+}
diff --git a/src/oob.h b/src/oob.h
new file mode 100644
index 0000000..db678de
--- /dev/null
+++ b/src/oob.h
@@ -0,0 +1,47 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  ST-Ericsson SA
+ *
+ *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ *  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
+ *
+ */
+
+struct oob_plugin
+{
+	/* If request was successfully send this functions should return TRUE.
+	 * Function should not block for too long. */
+	gboolean (*request_remote_data)(struct btd_device *device);
+
+	/* New local OOB data was read. If corresponding HCI command failed,
+	 * hash and randomizer are NULL */
+	void (*local_data_read)(struct btd_adapter *adapter, uint8_t *hash,
+			uint8_t *randomizer);
+
+	/* Plug-in was deactivated (called only for active plug-in). */
+	void (*plugin_deactivated)(void);
+};
+
+/* These functions are called by OOB plug-in. */
+void oob_activate_plugin(struct oob_plugin *plugin);
+void oob_deactivate_plugin(struct oob_plugin *plugin);
+
+/* These functions are called from stack to interact with OOB plug-in. */
+gboolean oob_request_remote_data(struct btd_device *device);
+void oob_local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer);
-- 
1.7.1


^ permalink raw reply related

* [PATCHv4 0/7] Support for out of band association model
From: Szymon Janc @ 2010-11-23 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Changes in this version:
  - code style/flow comments from Johan included
  - changes in D-Bus OOB api - ReadLocalOobData and provider
    register/unregister moved to adapter path (OobManager interface), provider
    is registered per adapter now
  - some bug fixes

Some things I'd like to collect comments about:
  - OobManager interface could be only available on 2.1 or higher adapters
    (this would require some adapter interface to be able check this in
    dbusoob plugin)
  - Agent's RequestPairing method name
  - RequestPairing is called only on device accepting incoming connection when
    it has OOB data for remote device (on RequestRemoteOobData event).
    Consequence is that when only initiator has OOB data RequestPairing is not
    called. We could store initiator's OOB capability in device structure (now
    only auth and cap are stored) to be able to know if initiator has OOB data.
    Yet, in such case RequestRemoteOobData on accepting device will not be 
    called and I have no idea where/when OOB capability should be check to call
    RequestPairing (and reject pairing if necessary)..


Comments are welcome.

BR,
Szymon Janc
on behalf of ST-Ericsson


Szymon Janc (7):
  Add support for Out of Band (OOB) association model
  Add D-Bus OOB plugin
  Add D-Bus OOB API documentation
  Add simple-oobprovider for testing
  Add request for accepting incoming pairing requests with OOB
    mechanism
  Update D-Bus OOB API with RequestPairing method
  Add RequestPairing method in simple-agent for accepting incoming OOB 
       pairing requests

 Makefile.am             |   10 +-
 acinclude.m4            |    6 +
 doc/oob-api.txt         |   76 +++++++++
 doc/oob-api.txt.orig    |   79 +++++++++
 lib/hci.h               |    3 +
 plugins/dbusoob.c       |  412 +++++++++++++++++++++++++++++++++++++++++++++++
 plugins/hciops.c        |  107 +++++++++++--
 src/adapter.c           |   21 +++-
 src/adapter.h           |   10 ++
 src/agent.c             |   59 +++++++-
 src/agent.h             |    3 +
 src/device.c            |   96 +++++++++++
 src/device.h            |   13 ++
 src/event.c             |   89 ++++++++---
 src/event.h             |    4 +-
 src/oob.c               |   67 ++++++++
 src/oob.h               |   47 ++++++
 test/simple-agent       |   10 ++
 test/simple-oobprovider |   57 +++++++
 19 files changed, 1131 insertions(+), 38 deletions(-)
 create mode 100644 doc/oob-api.txt
 create mode 100644 doc/oob-api.txt.orig
 create mode 100644 plugins/dbusoob.c
 create mode 100644 src/oob.c
 create mode 100644 src/oob.h
 create mode 100755 test/simple-oobprovider


^ permalink raw reply

* [PATCH] hciattach: makes set_speed return error if any one operation fail
From: Suraj Sumangala @ 2010-11-23 10:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jothikumar.Mothilal, Suraj Sumangala

This patch lets set_speed function changing UART baud rate
to return an error code if any one operation fails
instead of returning only the last operation's status.

---
 tools/hciattach.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/tools/hciattach.c b/tools/hciattach.c
index fd53710..7cb8e9e 100644
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -144,9 +144,16 @@ static int uart_speed(int s)
 
 int set_speed(int fd, struct termios *ti, int speed)
 {
-	cfsetospeed(ti, uart_speed(speed));
-	cfsetispeed(ti, uart_speed(speed));
-	return tcsetattr(fd, TCSANOW, ti);
+	if (cfsetospeed(ti, uart_speed(speed)) < 0)
+		return -errno;
+
+	if (cfsetispeed(ti, uart_speed(speed)) < 0)
+		return -errno;
+
+	if (tcsetattr(fd, TCSANOW, ti) < 0)
+		return -errno;
+
+	return 0;
 }
 
 /*
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] hciattach: download configuration at maximum baud rate possible
From: Johan Hedberg @ 2010-11-23 10:15 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <4CEB9296.2060702@Atheros.com>

Hi Suraj,

On Tue, Nov 23, 2010, Suraj Sumangala wrote:
> The set_speed function is defined in hciattach.c as
> 
> int set_speed(...)
> {
> 	cfsetospeed(...);
> 	cfsetispeed(...);
> 	return tcsetattr(...);
> }
> 
> I think this function could end up returning Success even if the
> first two function calls failed?

Seems so, yes.

> Does it makes sense to rewrite it to
> 
> int set_speed(...)
> {
> 	if(cfsetospeed(...) < 0)
> 		return -errno;
> 	if(cfsetispeed(...) < 0)
> 		return -errno;

This looks fine, except for the coding style: space between if and (

> 	return tcsetattr(...);

I guess this should be a similar if statement as for the other two
calls, and then a final "return 0" at the end of the function. This
set_speed fix should be in a separate patch though.

Johan

^ permalink raw reply

* Re: [PATCH] hciattach: download configuration at maximum baud rate possible
From: Suraj Sumangala @ 2010-11-23 10:08 UTC (permalink / raw)
  To: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <20101123092346.GB28017@jh-x301>

Hi Johan,

On 11/23/2010 2:53 PM, Johan Hedberg wrote:
> In general the patch looks ok'ish, but:
>
>> >  +	if (set_speed(fd, ti, speed)<  0) {
>> >  +		perror("Can't set required baud rate");
>> >  +		return -1;
>> >  +	}
> To be consistent with the other return values, instead of -1 you should
> be returning a proper errno here. I.e. probably something like:
>
> 	if (set_speed(fd, ti, speed)<  0) {
> 		err = -errno;
> 		perror("Can't set required baud rate");
> 		return err;

The set_speed function is defined in hciattach.c as

int set_speed(...)
{
	cfsetospeed(...);
	cfsetispeed(...);
	return tcsetattr(...);
}

I think this function could end up returning Success even if the first 
two function calls failed?

Does it makes sense to rewrite it to

int set_speed(...)
{
	if(cfsetospeed(...) < 0)
		return -errno;
	if(cfsetispeed(...) < 0)
		return -errno;
	return tcsetattr(...);
}

Then, I can return the error code directly in my function call.

Regards
Suraj
	

^ permalink raw reply

* Re: [PATCH] hciattach: download configuration at maximum baud rate possible
From: Johan Hedberg @ 2010-11-23  9:23 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <1290423480-29840-1-git-send-email-suraj@atheros.com>

Hi Suraj,

On Mon, Nov 22, 2010, Suraj Sumangala wrote:
> This patch support downloading configuration files for
> Atheros AR300x HCI UART chip at user requested baud rate
> instead of the initial baud rate.
> ---
>  tools/hciattach.c       |    2 +-
>  tools/hciattach.h       |    3 +-
>  tools/hciattach_ath3k.c |   97 +++++++++++++++++++++++++++++++++-------------
>  3 files changed, 72 insertions(+), 30 deletions(-)

In general the patch looks ok'ish, but:

> +	if (set_speed(fd, ti, speed) < 0) {
> +		perror("Can't set required baud rate");
> +		return -1;
> +	}

To be consistent with the other return values, instead of -1 you should
be returning a proper errno here. I.e. probably something like:

	if (set_speed(fd, ti, speed) < 0) {
		err = -errno;
		perror("Can't set required baud rate");
		return err;
	}


> +exit:

Could you use a label name that's more consistent with the rest of the
BlueZ code base. I think "failed" would be the most suitable one here.

Johan

^ permalink raw reply

* Re: [PATCH] Add a runtime option to set the BCSP communication rate
From: Johan Hedberg @ 2010-11-23  9:13 UTC (permalink / raw)
  To: Wade Brown; +Cc: linux-bluetooth
In-Reply-To: <1290466992-5023-1-git-send-email-brownw@us.panasonic.com>

Hi Wade,

On Mon, Nov 22, 2010, Wade Brown wrote:
> ---
>  tools/bccmd.c    |   45 ++++++++++++++++++++++++++++++++++++++++-----
>  tools/csr.h      |    3 ++-
>  tools/csr_bcsp.c |    4 ++--
>  3 files changed, 44 insertions(+), 8 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* How to change the waiting time when building bluetooth connection
From: Roc Bai @ 2010-11-23  8:06 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth

2010/11/22 Gustavo F. Padovan <padovan@profusion.mobi>:
> Hi Roc,
>
> * Roc Bai <buroc83@gmail.com> [2010-11-22 11:13:27 +0800]:
>
>> Hi, All:
>>  When i pair my phone with the PC, i have to quickly input the PIN code
>> with the linux-2.6.35.1 kernel. But i can do it slowly with linux-2.6.26
>> kernel. All the application and library are same. So i think the waiting
>> timeout is changed, but i cann't find the changement. I hope get your help
>> on the issue. Thanks very much!
>>
>> My hcid version is 3.36.
>
> Please move to the latest bluez 4 version and then report it again if it
> is the case.

The same phenomenon. But one strange result, some phone can connect
normally, but some phone should input PIN quickly.  But those phones
can work in the old kernel. I think some phones have special
parameters and the changement of new kernel are sensitive with them.
More idea ?
>
> --
> Gustavo F. Padovan
> http://profusion.mobi
>



-- 
------------------------

Thinking before action, but you are wasting time if you don't do action.

^ permalink raw reply

* sdptool hanging remote
From: Grahame Jordan @ 2010-11-23  5:37 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

I am using bluez-4.77 on a Gumstix Verdex kernel 2.4.32 patch 21

When I run:
sdptool records 00:80:37:2F:06:08"
from the Workstation Ubuntu 10.04 Bluez-4.6? to the Gumstix the Gumstix 
hangs.
It does not hang completely but is very busy. It hangs for about 20 
seconds and then releases for about 1 second
before it locks up again.

I have tried this on several different Gumstix with the same issue.

Changing workstations from Ubuntu 10.04 to Ubuntu 8.04 does make a 
difference.
 From Ubuntu 8.04 there seems to be no problem. blue-utils 3.26?

Appreciate help


Thanks

Grahame Jordan

^ permalink raw reply

* Re: [PATCH] Fix managing dbus filters depending on BT state
From: Bartosz Szatkowski @ 2010-11-22 23:17 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <AANLkTin5t-=bMeBmAJ2A+hV4h=dXQeu5dNFbMby43ssS@mail.gmail.com>

On Mon, Nov 22, 2010 at 8:12 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi,
>
> On Mon, Nov 22, 2010 at 4:33 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
>> Hi Bartosz,
>>
>> On Mon, Nov 22, 2010, Bartosz Szatkowski wrote:
>>> Previously even if BT was disabled, bluetoothd would handle some dbus
>>> singals (mostly connected with HFP). Now filters are added when
>>> BT is enabled and removed when BT is disabled.
>>> ---
>>>  audio/manager.c          |    4 ++--
>>>  audio/telephony-dummy.c  |   10 ++++++++++
>>>  audio/telephony-maemo5.c |   10 ++++++++++
>>>  audio/telephony-maemo6.c |   10 ++++++++++
>>>  audio/telephony-ofono.c  |   10 ++++++++++
>>>  audio/telephony.h        |    1 +
>>>  src/adapter.c            |    5 +++++
>>>  7 files changed, 48 insertions(+), 2 deletions(-)
>>
>> Nack on this one. I understand the issue you're trying to fix but it
>> needs to be done differently.
>>
>>> diff --git a/audio/manager.c b/audio/manager.c
>>> index 816c807..2fc7bf1 100644
>>> --- a/audio/manager.c
>>> +++ b/audio/manager.c
>>> @@ -1178,7 +1178,7 @@ proceed:
>>>               btd_register_adapter_driver(&media_server_driver);
>>>
>>>       if (enabled.headset) {
>>> -             telephony_init();
>>> +             telephony_set_state(1);
>>>               btd_register_adapter_driver(&headset_server_driver);
>>>       }
>>
>> If you're gonna call this "state" you should have proper defines or
>> enums for the values, however in this case it's essentially a boolean so
>> that's not necessary. In fact since it's a boolean you don't even need
>> to have any new function or variable at all for it: just use
>> telephony_init and telephony_exit.
>>
>>> --- a/src/adapter.c
>>> +++ b/src/adapter.c
>>> @@ -57,6 +57,7 @@
>>>  #include "glib-helper.h"
>>>  #include "agent.h"
>>>  #include "storage.h"
>>> +#include "../audio/telephony.h"
>>>
>>>  #define IO_CAPABILITY_DISPLAYONLY    0x00
>>>  #define IO_CAPABILITY_DISPLAYYESNO   0x01
>>> @@ -2404,6 +2405,8 @@ int adapter_start(struct btd_adapter *adapter)
>>>
>>>       err = adapter_up(adapter, mode);
>>>
>>> +     telephony_init();
>>> +
>>
>> This is just wrong. The core daemon should never have direct access to
>> the telephony driver. Instead, you should have the audio plugin
>> (probably audio/manager.c or audio/headset.c) register a adapter powered
>> callback and then call telehony_init/exit from that callback.
>
> I have an almost working version of this using adapter drivers and
> powered changes via callback registration, the tricky part here is how
> to detect when to do headset_init/headset_exit since those should be
> called only once. I didn't know there somebody working on this but
> anyway I gonna try to finish this asap.
>
> --
> Luiz Augusto von Dentz
> Computer Engineer
>

Hi Luiz,
please fell free to send it (no hard fillings :) ) Ive just getting to
know bluez so probably it would take me a while to get through whole
plugin/callback subsystem.

-- 
Pozdrowienia,
Bartosz Szatkowski

^ permalink raw reply

* [PATCH] Add a runtime option to set the BCSP communication rate
From: Wade Brown @ 2010-11-22 23:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Wade Brown

---
 tools/bccmd.c    |   45 ++++++++++++++++++++++++++++++++++++++++-----
 tools/csr.h      |    3 ++-
 tools/csr_bcsp.c |    4 ++--
 3 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/tools/bccmd.c b/tools/bccmd.c
index 686e858..5cb9255 100644
--- a/tools/bccmd.c
+++ b/tools/bccmd.c
@@ -59,7 +59,7 @@
 #define CSR_TYPE_ARRAY		CSR_TYPE_COMPLEX
 #define CSR_TYPE_BDADDR		CSR_TYPE_COMPLEX
 
-static inline int transport_open(int transport, char *device)
+static inline int transport_open(int transport, char *device, speed_t bcsp_rate)
 {
 	switch (transport) {
 	case CSR_TRANSPORT_HCI:
@@ -69,7 +69,7 @@ static inline int transport_open(int transport, char *device)
 		return csr_open_usb(device);
 #endif
 	case CSR_TRANSPORT_BCSP:
-		return csr_open_bcsp(device);
+		return csr_open_bcsp(device, bcsp_rate);
 	case CSR_TRANSPORT_H4:
 		return csr_open_h4(device);
 	case CSR_TRANSPORT_3WIRE:
@@ -1109,6 +1109,7 @@ static void usage(void)
 	printf("Options:\n"
 		"\t-t <transport>     Select the transport\n"
 		"\t-d <device>        Select the device\n"
+		"\t-b <bcsp rate>     Select the bcsp transfer rate\n"
 		"\t-h, --help         Display help\n"
 		"\n");
 
@@ -1137,6 +1138,7 @@ static void usage(void)
 static struct option main_options[] = {
 	{ "transport",	1, 0, 't' },
 	{ "device",	1, 0, 'd' },
+	{ "bcsprate", 1, 0, 'b'},
 	{ "help",	0, 0, 'h' },
 	{ 0, 0, 0, 0 }
 };
@@ -1145,8 +1147,9 @@ int main(int argc, char *argv[])
 {
 	char *device = NULL;
 	int i, err, opt, transport = CSR_TRANSPORT_HCI;
+	speed_t bcsp_rate = B38400;
 
-	while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) {
+	while ((opt=getopt_long(argc, argv, "+t:d:i:b:h", main_options, NULL)) != EOF) {
 		switch (opt) {
 		case 't':
 			if (!strcasecmp(optarg, "hci"))
@@ -1171,7 +1174,39 @@ int main(int argc, char *argv[])
 		case 'i':
 			device = strdup(optarg);
 			break;
-
+		case 'b':
+			switch (atoi(optarg)) {
+			case 9600: bcsp_rate = B9600; break;
+			case 19200: bcsp_rate = B19200; break;
+			case 38400: bcsp_rate = B38400; break;
+			case 57600: bcsp_rate = B57600; break;
+			case 115200: bcsp_rate = B115200; break;
+			case 230400: bcsp_rate = B230400; break;
+			case 460800: bcsp_rate = B460800; break;
+			case 500000: bcsp_rate = B500000; break;
+			case 576000: bcsp_rate = B576000; break;
+			case 921600: bcsp_rate = B921600; break;
+			case 1000000: bcsp_rate = B1000000; break;
+			case 1152000: bcsp_rate = B1152000; break;
+			case 1500000: bcsp_rate = B1500000; break;
+			case 2000000: bcsp_rate = B2000000; break;
+#ifdef B2500000
+			case 2500000: bcsp_rate = B2500000; break;
+#endif
+#ifdef B3000000
+			case 3000000: bcsp_rate = B3000000; break;
+#endif
+#ifdef B3500000
+			case 3500000: bcsp_rate = B3500000; break;
+#endif
+#ifdef B4000000
+			case 4000000: bcsp_rate = B4000000; break;
+#endif
+			default:
+				printf("Unknown BCSP baud rate specified, defaulting to 38400bps\n");
+				bcsp_rate = B38400;
+			}
+			break;
 		case 'h':
 		default:
 			usage();
@@ -1188,7 +1223,7 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
-	if (transport_open(transport, device) < 0)
+	if (transport_open(transport, device, bcsp_rate) < 0)
 		exit(1);
 
 	if (device)
diff --git a/tools/csr.h b/tools/csr.h
index 1d70491..8b94d7b 100644
--- a/tools/csr.h
+++ b/tools/csr.h
@@ -22,6 +22,7 @@
  */
 
 #include <stdint.h>
+#include <termios.h>
 
 #define CSR_VARID_PS_CLR_ALL			0x000b	/* valueless */
 #define CSR_VARID_PS_FACTORY_SET		0x000c	/* valueless */
@@ -519,7 +520,7 @@ int csr_read_usb(uint16_t varid, uint8_t *value, uint16_t length);
 int csr_write_usb(uint16_t varid, uint8_t *value, uint16_t length);
 void csr_close_usb(void);
 
-int csr_open_bcsp(char *device);
+int csr_open_bcsp(char *device, speed_t bcsp_rate);
 int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length);
 int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length);
 void csr_close_bcsp(void);
diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c
index e551311..df247a2 100644
--- a/tools/csr_bcsp.c
+++ b/tools/csr_bcsp.c
@@ -46,7 +46,7 @@ static uint8_t send_buffer[512];
 static struct ubcsp_packet receive_packet;
 static uint8_t receive_buffer[512];
 
-int csr_open_bcsp(char *device)
+int csr_open_bcsp(char *device, speed_t bcsp_rate)
 {
 	struct termios ti;
 	uint8_t delay, activity = 0x00;
@@ -84,7 +84,7 @@ int csr_open_bcsp(char *device)
 	ti.c_cc[VMIN] = 1;
 	ti.c_cc[VTIME] = 0;
 
-	cfsetospeed(&ti, B38400);
+	cfsetospeed(&ti, bcsp_rate);
 
 	if (tcsetattr(fd, TCSANOW, &ti) < 0) {
 		fprintf(stderr, "Can't change port settings: %s (%d)\n",
-- 
1.7.2.2


^ permalink raw reply related

* Re: [PATCH] Fix typo in adapter documentation
From: Johan Hedberg @ 2010-11-22 22:07 UTC (permalink / raw)
  To: Jose Antonio Santos Cadenas; +Cc: linux-bluetooth
In-Reply-To: <1290452756-7967-1-git-send-email-santoscadenas@gmail.com>

Hi Jose,

On Mon, Nov 22, 2010, Jose Antonio Santos Cadenas wrote:
> ---
>  doc/adapter-api.txt |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
> index 65e2887..f287f29 100644
> --- a/doc/adapter-api.txt
> +++ b/doc/adapter-api.txt
> @@ -148,7 +148,7 @@ Methods		dict GetProperties()
>  
>  			This registers the adapter wide agent.
>  
> -			The object path defines the path the of the agent
> +			The object path defines the path of the agent
>  			that will be called when user input is needed.
>  
>  			If an application disconnects from the bus all

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: pull request: bluetooth-2.6 2010-11-22
From: Johan Hedberg @ 2010-11-22 22:03 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: John W. Linville, linux-wireless, linux-bluetooth
In-Reply-To: <20101122201330.GE23109@vigoh>

Hi,

On Mon, Nov 22, 2010, Gustavo F. Padovan wrote:
> > The other fixes are larger than I would like to see.  What is the
> > effect of the bug?  Does the Bluetooth controller stop completely?
> > Does it cause a crash?
> > 
> > Is this a newly-introduced bug?  Or one that has been around for
> > a while?
> 
> No, it is not serious like that. By not having this patch we won't have
> the remote name request command during connection setup, The remote name
> request was done by bluetoothd, but we already removed it from
> userspace. It is not a really big problem once we also cache the remote
> devices names in bluetoothd.
> So I'm seeing no way to convince you tou pull this patch (actually I'm
> now also covinced to queue this to bluetooth-next).  I'll sent a new
> pull request soon, after wait some time for new patches.

IIRC the symptom that prompted the initial investigation was the failure
to properly connect to one specific Bluetooth headset. After discussions
with Marcel the conculsion was to move more control of these commands to
the kernel side. OTOH, this is certainly not the first time a BT
controller chokes up when receiving too many commands at the same time
(I've seen this several times during the last 8 years or so that I've
been involved with Bluetooth). Anyway, I agree that this might be better
suited for bluetooth-next.

Johan

^ permalink raw reply

* Re: [PATCH 2/2] Bluetooth: Automate remote name requests
From: Johan Hedberg @ 2010-11-22 21:51 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: Arun K. Singh, linux-bluetooth
In-Reply-To: <AANLkTikHPWyjS+m2NMrxcL0FP6WhX+APExNELRuw4=Pe@mail.gmail.com>

Hi Luiz,

On Mon, Nov 22, 2010, Luiz Augusto von Dentz wrote:
> >> Could you be bit more explicit about such user space versions that you
> >> recommend? Would latest bluez versions such as 4.80 qualify for your
> >> recommendation?
> >
> > The automated name requests upon "connect complete" events were removed
> > in 4.78 so any version from there onwards would qualify.
> 
> Maybe there is some way to detect that the kernel is not doing it, or
> at least force bluetoothd to resolve once to make sure it can be used
> with older kernel versions so it doesn't have to always update as it
> was used to be but if we are to authenticate or authorize a device it
> should have a name so the ui can display it to the user.

Regarding the kernel version detection, this was certainly considered
but there doesn't seem to be any simple way to do it. However, now that
you mention it, this can certainly be an inconvenient issue with
incoming connections for devices which we've never seen during a device
discovery. Therefore, some kind of a userspace workaround for this would
imho be desirable and I'd certainly be willing to accept a patch for it
as long as it doesn't get too complicated. I suppose it's sufficient if
the patch would be for hciops only since any system running mgmtops
would also have a kernel that does the name request.

Johan

^ permalink raw reply

* Re: [PATCH 2/2] Bluetooth: Automate remote name requests
From: Luiz Augusto von Dentz @ 2010-11-22 20:35 UTC (permalink / raw)
  To: Arun K. Singh, linux-bluetooth
In-Reply-To: <20101122071243.GA23443@jh-x301>

Hi Johan,

On Mon, Nov 22, 2010 at 9:12 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Arun,
>
> On Mon, Nov 22, 2010, Arun K. Singh wrote:
>> > The code will work sub-optimally with userspace versions that still
>> > do the name requesting themselves (it shouldn't break anything
>> > though) so it is recommended to combine this with a userspace
>> > software version that doesn't have automated name requests.
>>
>> Could you be bit more explicit about such user space versions that you
>> recommend? Would latest bluez versions such as 4.80 qualify for your
>> recommendation?
>
> The automated name requests upon "connect complete" events were removed
> in 4.78 so any version from there onwards would qualify.

Maybe there is some way to detect that the kernel is not doing it, or
at least force bluetoothd to resolve once to make sure it can be used
with older kernel versions so it doesn't have to always update as it
was used to be but if we are to authenticate or authorize a device it
should have a name so the ui can display it to the user.

-- 
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply

* Re: pull request: bluetooth-2.6 2010-11-22
From: Gustavo F. Padovan @ 2010-11-22 20:13 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, linux-bluetooth
In-Reply-To: <20101122193029.GE2117@tuxdriver.com>

* John W. Linville <linville@tuxdriver.com> [2010-11-22 14:30:30 -0500]:

> On Mon, Nov 22, 2010 at 04:14:11PM -0200, Gustavo F. Padovan wrote:
> > Hi John,
> > 
> > Following batch is intended to 2.6.37, it includes a very trivial return
> > err fix from myself and an remote name request fix from Johan Hedberg.
> > This fix move the remote name request (during the connection creation
> > process) to the kernelspace. In addition we have removed this operation
> > from BlueZ in userspace. Quoting part of Johan's patch which already
> > explain the change:
> > 
> >    "So far userspace has been responsible for this extra name request but
> >     tighter control is needed in order not to flood Bluetooth controllers
> >     with two many commands during connection creation. It has been shown
> >     that some controllers simply fail to function correctly if they get too
> >     many (almost) simultaneous commands during connection creation. The
> >     simplest way to acheive better control of these commands is to move
> >     their sending completely to the kernel side."
> > 
> > As side effect, we have a clean up patch in preparation to this fix.
> > 
> > Please pull, or let me know any problems you find here. Thanks.
> 
> The return code fix seems reasonable -- small and obvious, etc.
> 
> The other fixes are larger than I would like to see.  What is the
> effect of the bug?  Does the Bluetooth controller stop completely?
> Does it cause a crash?
> 
> Is this a newly-introduced bug?  Or one that has been around for
> a while?

No, it is not serious like that. By not having this patch we won't have
the remote name request command during connection setup, The remote name
request was done by bluetoothd, but we already removed it from
userspace. It is not a really big problem once we also cache the remote
devices names in bluetoothd.
So I'm seeing no way to convince you tou pull this patch (actually I'm
now also covinced to queue this to bluetooth-next).  I'll sent a new
pull request soon, after wait some time for new patches.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH] Fix managing dbus filters depending on BT state
From: Luiz Augusto von Dentz @ 2010-11-22 20:12 UTC (permalink / raw)
  To: Bartosz Szatkowski, linux-bluetooth
In-Reply-To: <20101122143345.GA2303@jh-x301>

Hi,

On Mon, Nov 22, 2010 at 4:33 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Bartosz,
>
> On Mon, Nov 22, 2010, Bartosz Szatkowski wrote:
>> Previously even if BT was disabled, bluetoothd would handle some dbus
>> singals (mostly connected with HFP). Now filters are added when
>> BT is enabled and removed when BT is disabled.
>> ---
>>  audio/manager.c          |    4 ++--
>>  audio/telephony-dummy.c  |   10 ++++++++++
>>  audio/telephony-maemo5.c |   10 ++++++++++
>>  audio/telephony-maemo6.c |   10 ++++++++++
>>  audio/telephony-ofono.c  |   10 ++++++++++
>>  audio/telephony.h        |    1 +
>>  src/adapter.c            |    5 +++++
>>  7 files changed, 48 insertions(+), 2 deletions(-)
>
> Nack on this one. I understand the issue you're trying to fix but it
> needs to be done differently.
>
>> diff --git a/audio/manager.c b/audio/manager.c
>> index 816c807..2fc7bf1 100644
>> --- a/audio/manager.c
>> +++ b/audio/manager.c
>> @@ -1178,7 +1178,7 @@ proceed:
>>               btd_register_adapter_driver(&media_server_driver);
>>
>>       if (enabled.headset) {
>> -             telephony_init();
>> +             telephony_set_state(1);
>>               btd_register_adapter_driver(&headset_server_driver);
>>       }
>
> If you're gonna call this "state" you should have proper defines or
> enums for the values, however in this case it's essentially a boolean so
> that's not necessary. In fact since it's a boolean you don't even need
> to have any new function or variable at all for it: just use
> telephony_init and telephony_exit.
>
>> --- a/src/adapter.c
>> +++ b/src/adapter.c
>> @@ -57,6 +57,7 @@
>>  #include "glib-helper.h"
>>  #include "agent.h"
>>  #include "storage.h"
>> +#include "../audio/telephony.h"
>>
>>  #define IO_CAPABILITY_DISPLAYONLY    0x00
>>  #define IO_CAPABILITY_DISPLAYYESNO   0x01
>> @@ -2404,6 +2405,8 @@ int adapter_start(struct btd_adapter *adapter)
>>
>>       err = adapter_up(adapter, mode);
>>
>> +     telephony_init();
>> +
>
> This is just wrong. The core daemon should never have direct access to
> the telephony driver. Instead, you should have the audio plugin
> (probably audio/manager.c or audio/headset.c) register a adapter powered
> callback and then call telehony_init/exit from that callback.

I have an almost working version of this using adapter drivers and
powered changes via callback registration, the tricky part here is how
to detect when to do headset_init/headset_exit since those should be
called only once. I didn't know there somebody working on this but
anyway I gonna try to finish this asap.

-- 
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply

* [PATCH] ath3k: reduce memory usage
From: Alexander Holler @ 2010-11-22 20:09 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Alicke Xu, Luis R. Rodriguez, Vikram Kandukuri, linux-bluetooth,
	Alexander Holler

There is no need to hold the firmware in memory.

Signed-off-by: Alexander Holler <holler@ahsoftware.de>
---
 drivers/bluetooth/ath3k.c |   75 ++++++++++++---------------------------------
 1 files changed, 20 insertions(+), 55 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 128cae4..81cd1ed 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -43,46 +43,40 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 #define USB_REQ_DFU_DNLOAD	1
 #define BULK_SIZE		4096
 
-struct ath3k_data {
-	struct usb_device *udev;
-	u8 *fw_data;
-	u32 fw_size;
-	u32 fw_sent;
-};
-
-static int ath3k_load_firmware(struct ath3k_data *data,
-				unsigned char *firmware,
-				int count)
+static int ath3k_load_firmware(struct usb_device *udev,
+				const struct firmware *firmware)
 {
 	u8 *send_buf;
 	int err, pipe, len, size, sent = 0;
+	int count = firmware->size;
 
-	BT_DBG("ath3k %p udev %p", data, data->udev);
+	BT_DBG("udev %p", udev);
 
-	pipe = usb_sndctrlpipe(data->udev, 0);
+	pipe = usb_sndctrlpipe(udev, 0);
 
-	if ((usb_control_msg(data->udev, pipe,
+	send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+	if (!send_buf) {
+		BT_ERR("Can't allocate memory chunk for firmware");
+		return -ENOMEM;
+	}
+
+	memcpy(send_buf, firmware->data, 20);
+	if ((err = usb_control_msg(udev, pipe,
 				USB_REQ_DFU_DNLOAD,
 				USB_TYPE_VENDOR, 0, 0,
-				firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
+				send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
 		BT_ERR("Can't change to loading configuration err");
-		return -EBUSY;
+		goto error;
 	}
 	sent += 20;
 	count -= 20;
 
-	send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
-	if (!send_buf) {
-		BT_ERR("Can't allocate memory chunk for firmware");
-		return -ENOMEM;
-	}
-
 	while (count) {
 		size = min_t(uint, count, BULK_SIZE);
-		pipe = usb_sndbulkpipe(data->udev, 0x02);
-		memcpy(send_buf, firmware + sent, size);
+		pipe = usb_sndbulkpipe(udev, 0x02);
+		memcpy(send_buf, firmware->data + sent, size);
 
-		err = usb_bulk_msg(data->udev, pipe, send_buf, size,
+		err = usb_bulk_msg(udev, pipe, send_buf, size,
 					&len, 3000);
 
 		if (err || (len != size)) {
@@ -108,57 +102,28 @@ static int ath3k_probe(struct usb_interface *intf,
 {
 	const struct firmware *firmware;
 	struct usb_device *udev = interface_to_usbdev(intf);
-	struct ath3k_data *data;
-	int size;
 
 	BT_DBG("intf %p id %p", intf, id);
 
 	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
 		return -ENODEV;
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	data->udev = udev;
-
 	if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
-		kfree(data);
 		return -EIO;
 	}
 
-	size = max_t(uint, firmware->size, 4096);
-	data->fw_data = kmalloc(size, GFP_KERNEL);
-	if (!data->fw_data) {
+	if (ath3k_load_firmware(udev, firmware)) {
 		release_firmware(firmware);
-		kfree(data);
-		return -ENOMEM;
-	}
-
-	memcpy(data->fw_data, firmware->data, firmware->size);
-	data->fw_size = firmware->size;
-	data->fw_sent = 0;
-	release_firmware(firmware);
-
-	usb_set_intfdata(intf, data);
-	if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) {
-		usb_set_intfdata(intf, NULL);
-		kfree(data->fw_data);
-		kfree(data);
 		return -EIO;
 	}
+	release_firmware(firmware);
 
 	return 0;
 }
 
 static void ath3k_disconnect(struct usb_interface *intf)
 {
-	struct ath3k_data *data = usb_get_intfdata(intf);
-
 	BT_DBG("ath3k_disconnect intf %p", intf);
-
-	kfree(data->fw_data);
-	kfree(data);
 }
 
 static struct usb_driver ath3k_driver = {
-- 
1.7.2.3

^ permalink raw reply related

* Re: pull request: bluetooth-2.6 2010-11-22
From: John W. Linville @ 2010-11-22 19:30 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-wireless, linux-bluetooth
In-Reply-To: <20101122181411.GD23109@vigoh>

On Mon, Nov 22, 2010 at 04:14:11PM -0200, Gustavo F. Padovan wrote:
> Hi John,
> 
> Following batch is intended to 2.6.37, it includes a very trivial return
> err fix from myself and an remote name request fix from Johan Hedberg.
> This fix move the remote name request (during the connection creation
> process) to the kernelspace. In addition we have removed this operation
> from BlueZ in userspace. Quoting part of Johan's patch which already
> explain the change:
> 
>    "So far userspace has been responsible for this extra name request but
>     tighter control is needed in order not to flood Bluetooth controllers
>     with two many commands during connection creation. It has been shown
>     that some controllers simply fail to function correctly if they get too
>     many (almost) simultaneous commands during connection creation. The
>     simplest way to acheive better control of these commands is to move
>     their sending completely to the kernel side."
> 
> As side effect, we have a clean up patch in preparation to this fix.
> 
> Please pull, or let me know any problems you find here. Thanks.

The return code fix seems reasonable -- small and obvious, etc.

The other fixes are larger than I would like to see.  What is the
effect of the bug?  Does the Bluetooth controller stop completely?
Does it cause a crash?

Is this a newly-introduced bug?  Or one that has been around for
a while?

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [PATCH 2/2] Fix: increment MDL and MCL reference counter in IO watchers.
From: Jose Antonio Santos Cadenas @ 2010-11-22 19:14 UTC (permalink / raw)
  To: Jose Antonio Santos Cadenas, linux-bluetooth
In-Reply-To: <20101122170525.GA13003@jh-x301>

2010/11/22 Johan Hedberg <johan.hedberg@gmail.com>:
> Hi Jose,
>
> On Mon, Nov 22, 2010, Jose Antonio Santos Cadenas wrote:
>> When a io_watcher is added to an MDL or an MCL channel, its reference
>> should be incremented because the watcher should keep its own
>> reference the the structure.
>>
>> Also  a destroy function is added in order to decrement the reference
>> once the watcher is removed.
>> ---
>>  health/mcap.c |   28 +++++++++++++++++++---------
>>  1 files changed, 19 insertions(+), 9 deletions(-)
>
> Thanks. Pushed upstream, but I still had to tweak the summary line a
> little bit (take a look at the upstream tree if you're interested).

I have to avoid dots at the end of the commit message I always think
that, but sometimes my fingers are quicker than my mind. Sorry :) .

>
> Johan
>

^ permalink raw reply

* [PATCH] Fix typo in adapter documentation
From: Jose Antonio Santos Cadenas @ 2010-11-22 19:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas

---
 doc/adapter-api.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
index 65e2887..f287f29 100644
--- a/doc/adapter-api.txt
+++ b/doc/adapter-api.txt
@@ -148,7 +148,7 @@ Methods		dict GetProperties()
 
 			This registers the adapter wide agent.
 
-			The object path defines the path the of the agent
+			The object path defines the path of the agent
 			that will be called when user input is needed.
 
 			If an application disconnects from the bus all
-- 
1.7.1


^ permalink raw reply related

* pull request: bluetooth-2.6 2010-11-22
From: Gustavo F. Padovan @ 2010-11-22 18:14 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, linux-bluetooth

Hi John,

Following batch is intended to 2.6.37, it includes a very trivial return
err fix from myself and an remote name request fix from Johan Hedberg.
This fix move the remote name request (during the connection creation
process) to the kernelspace. In addition we have removed this operation
from BlueZ in userspace. Quoting part of Johan's patch which already
explain the change:

   "So far userspace has been responsible for this extra name request but
    tighter control is needed in order not to flood Bluetooth controllers
    with two many commands during connection creation. It has been shown
    that some controllers simply fail to function correctly if they get too
    many (almost) simultaneous commands during connection creation. The
    simplest way to acheive better control of these commands is to move
    their sending completely to the kernel side."

As side effect, we have a clean up patch in preparation to this fix.

Please pull, or let me know any problems you find here. Thanks.


The following changes since commit 3bf30b56c4f0a1c4fae34050b7db4527c92891e8:

  ath9k_htc: Avoid setting QoS control for non-QoS frames (2010-11-18 13:17:47 -0500)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git master

Gustavo F. Padovan (1):
      Bluetooth: Fix not returning proper error in SCO

Johan Hedberg (3):
      Bluetooth: Simplify remote features callback function logic
      Bluetooth: Create a unified authentication request function
      Bluetooth: Automate remote name requests

 net/bluetooth/hci_event.c |  153 ++++++++++++++++++++++++++++++++-------------
 net/bluetooth/sco.c       |    6 +-
 2 files changed, 112 insertions(+), 47 deletions(-)

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH v2] Bluetooth: Fix error handling for l2cap_init()
From: Anderson Lizardo @ 2010-11-22 18:05 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <20101122173447.GA23109@vigoh>

Hi Gustavo,

On Mon, Nov 22, 2010 at 1:34 PM, Gustavo F. Padovan
<padovan@profusion.mobi> wrote:
> * Anderson Lizardo <anderson.lizardo@openbossa.org> [2010-11-22 06:57:14 -0400]:
>> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
>> index 18a802c..7980e24 100644
>> --- a/net/bluetooth/l2cap.c
>> +++ b/net/bluetooth/l2cap.c
>> @@ -4875,8 +4875,10 @@ static int __init l2cap_init(void)
>>               return err;
>>
>>       _busy_wq = create_singlethread_workqueue("l2cap");
>> -     if (!_busy_wq)
>> -             goto error;
>> +     if (!_busy_wq) {
>> +             err = -ENOMEM;
>> +             goto error_busy_wq;
>> +     }
>
> I prefer if you move the workqueue creation to after the
> hci_register_proto block. That will make things easier.

I wonder if that might not introduce a race condition, because after
hci_register_proto() new connections may already arrive?

Or is it guaranteed to only happen after l2cap_init() has finished?

If not, I can make this change without problem.

Regards,
-- 
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH 2/2] Bluetooth: Get ride of __rfcomm_get_sock_by_channel()
From: Gustavo F. Padovan @ 2010-11-22 17:44 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1290036176-4022-2-git-send-email-padovan@profusion.mobi>

* Gustavo F. Padovan <padovan@profusion.mobi> [2010-11-17 21:22:56 -0200]:

> rfcomm_get_sock_by_channel() was the only user of this function, so I merged
> both into rfcomm_get_sock_by_channel(). The socket lock now should be hold
> outside of rfcomm_get_sock_by_channel() once we hold and release it inside the
> same function now.
> 
> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
> ---
>  net/bluetooth/rfcomm/sock.c |   19 +++++++------------
>  1 files changed, 7 insertions(+), 12 deletions(-)

I'm also pushing these two to bluetooth-next. It should be good as
nobody commented on it, or people don't looked to it since there is a
clear typo and in commit messase (ride -> rid)

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH] Bluetooth: do not use assignment in if condition
From: Gustavo F. Padovan @ 2010-11-22 17:40 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1290424897-32463-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2010-11-22 13:21:37 +0200]:

> From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> 
> Fix checkpatch errors like:
> "ERROR: do not use assignment in if condition"
> Simplify code and fix one long line.
> 
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> ---
>  net/bluetooth/hci_event.c |   18 ++++++++++++------
>  1 files changed, 12 insertions(+), 6 deletions(-)

Applied, thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply


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