Linux bluetooth development
 help / color / mirror / Atom feed
* [RFC v9 06/10] Bluetooth: Introduce LE auto connection infrastructure
From: Andre Guedes @ 2014-02-18 17:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392746101-5981-1-git-send-email-andre.guedes@openbossa.org>

This patch introduces the LE auto connection infrastructure which
will be used to implement the LE auto connection options.

In summary, the auto connection mechanism works as follows: Once the
first pending LE connection is created, the background scanning is
started. When the target device is found in range, the kernel
autonomously starts the connection attempt. If connection is
established successfully, that pending LE connection is deleted and
the background is stopped.

To achieve that, this patch introduces the hci_update_background_scan()
which controls the background scanning state. This function starts or
stops the background scanning based on the hdev->pend_le_conns list. If
there is no pending LE connection, the background scanning is stopped.
Otherwise, we start the background scanning.

Then, every time a pending LE connection is added we call hci_update_
background_scan() so the background scanning is started (in case it is
not already running). Likewise, every time a pending LE connection is
deleted we call hci_update_background_scan() so the background scanning
is stopped (in case this was the last pending LE connection) or it is
started again (in case we have more pending LE connections). Finally,
we also call hci_update_background_scan() in hci_le_conn_failed() so
the background scan is restarted in case the connection establishment
fails. This way the background scanning keeps running until all pending
LE connection are established.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |  2 +
 net/bluetooth/hci_conn.c         |  5 +++
 net/bluetooth/hci_core.c         | 83 +++++++++++++++++++++++++++++++++++++++-
 net/bluetooth/hci_event.c        | 44 +++++++++++++++++++++
 4 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f60b2a7..d1f7784 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -788,6 +788,8 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
 void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
 void hci_pend_le_conns_clear(struct hci_dev *hdev);
 
+void hci_update_background_scan(struct hci_dev *hdev);
+
 void hci_uuids_clear(struct hci_dev *hdev);
 
 void hci_link_keys_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index da44390..a4dd033 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -527,6 +527,11 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
 	hci_proto_connect_cfm(conn, status);
 
 	hci_conn_del(conn);
+
+	/* Since we may have temporarily stopped the background scanning in
+	 * favor of connection establishment, we should restart it.
+	 */
+	hci_update_background_scan(hdev);
 }
 
 static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 0002c62..219a5aa 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3110,7 +3110,7 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
 
 	entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
 	if (entry)
-		return;
+		goto done;
 
 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 	if (!entry) {
@@ -3124,6 +3124,9 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
 	list_add(&entry->list, &hdev->pend_le_conns);
 
 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
+
+done:
+	hci_update_background_scan(hdev);
 }
 
 /* This function requires the caller holds hdev->lock */
@@ -3133,12 +3136,15 @@ void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
 
 	entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
 	if (!entry)
-		return;
+		goto done;
 
 	list_del(&entry->list);
 	kfree(entry);
 
 	BT_DBG("addr %pMR (type %u)", addr, addr_type);
+
+done:
+	hci_update_background_scan(hdev);
 }
 
 /* This function requires the caller holds hdev->lock */
@@ -4702,3 +4708,76 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
 	cp.enable = LE_SCAN_DISABLE;
 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
 }
+
+static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
+{
+	if (status)
+		BT_DBG("HCI request failed to update background scanning: "
+		       "status 0x%2.2x", status);
+}
+
+/* This function controls the background scanning based on hdev->pend_le_conns
+ * list. If there are pending LE connection we start the background scanning,
+ * otherwise we stop it.
+ *
+ * This function requires the caller holds hdev->lock.
+ */
+void hci_update_background_scan(struct hci_dev *hdev)
+{
+	struct hci_cp_le_set_scan_param param_cp;
+	struct hci_cp_le_set_scan_enable enable_cp;
+	struct hci_request req;
+	struct hci_conn *conn;
+	int err;
+
+	hci_req_init(&req, hdev);
+
+	if (list_empty(&hdev->pend_le_conns)) {
+		/* If there is no pending LE connections, we should stop
+		 * the background scanning.
+		 */
+
+		/* If controller is not scanning we are done. */
+		if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+			return;
+
+		hci_req_add_le_scan_disable(&req);
+
+		BT_DBG("%s stopping background scanning", hdev->name);
+	} else {
+		/* If there is at least one pending LE connection, we should
+		 * keep the background scan running.
+		 */
+
+		/* If controller is already scanning we are done. */
+		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+			return;
+
+		/* If controller is connecting, we should not start scanning
+		 * since some controllers are not able to scan and connect at
+		 * the same time.
+		 */
+		conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
+		if (conn)
+			return;
+
+		memset(&param_cp, 0, sizeof(param_cp));
+		param_cp.type = LE_SCAN_PASSIVE;
+		param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
+		param_cp.window = cpu_to_le16(hdev->le_scan_window);
+		hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
+			    &param_cp);
+
+		memset(&enable_cp, 0, sizeof(enable_cp));
+		enable_cp.enable = LE_SCAN_ENABLE;
+		enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
+		hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
+			    &enable_cp);
+
+		BT_DBG("%s starting background scanning", hdev->name);
+	}
+
+	err = hci_req_run(&req, update_background_scan_complete);
+	if (err)
+		BT_ERR("Failed to run HCI request: err %d", err);
+}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index df58cde..5796c06 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3620,25 +3620,69 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 	hci_proto_connect_cfm(conn, ev->status);
 
+	hci_pend_le_conn_del(hdev, &ev->bdaddr, ev->bdaddr_type);
+
 unlock:
 	hci_dev_unlock(hdev);
 }
 
+/* This function requires the caller holds hdev->lock */
+static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
+				  u8 addr_type)
+{
+	struct hci_conn *conn;
+	u8 bdaddr_type;
+
+	if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
+		return;
+
+	if (addr_type == ADDR_LE_DEV_PUBLIC)
+		bdaddr_type = BDADDR_LE_PUBLIC;
+	else
+		bdaddr_type = BDADDR_LE_RANDOM;
+
+	conn = hci_connect(hdev, LE_LINK, addr, bdaddr_type, BT_SECURITY_LOW,
+			   HCI_AT_NO_BONDING);
+	if (!IS_ERR(conn))
+		return;
+
+	switch (PTR_ERR(conn)) {
+	case -EBUSY:
+		/* If hci_connect() returns -EBUSY it means there is already
+		 * an LE connection attempt going on. Since controllers don't
+		 * support more than one connection attempt at the time, we
+		 * don't consider this an error case.
+		 */
+		break;
+	default:
+		BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
+	}
+}
+
 static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	u8 num_reports = skb->data[0];
 	void *ptr = &skb->data[1];
 	s8 rssi;
 
+	hci_dev_lock(hdev);
+
 	while (num_reports--) {
 		struct hci_ev_le_advertising_info *ev = ptr;
 
+		if (ev->evt_type == LE_ADV_IND ||
+		    ev->evt_type == LE_ADV_DIRECT_IND)
+			check_pending_le_conn(hdev, &ev->bdaddr,
+					      ev->bdaddr_type);
+
 		rssi = ev->data[ev->length];
 		mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
 				  NULL, rssi, 0, 1, ev->data, ev->length);
 
 		ptr += sizeof(*ev) + ev->length + 1;
 	}
+
+	hci_dev_unlock(hdev);
 }
 
 static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-- 
1.8.5.4


^ permalink raw reply related

* [RFC v9 05/10] Bluetooth: Introduce hdev->pend_le_conn list
From: Andre Guedes @ 2014-02-18 17:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392746101-5981-1-git-send-email-andre.guedes@openbossa.org>

This patch introduces the hdev->pend_le_conn list which holds the
device addresses the kernel should autonomously connect. It also
introduces some helper functions to manipulate the list.

The list and helper functions will be used by the next patch which
implements the LE auto connection infrastructure.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |  7 +++++
 net/bluetooth/hci_core.c         | 68 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 043b50e..f60b2a7 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -280,6 +280,7 @@ struct hci_dev {
 	struct list_head	identity_resolving_keys;
 	struct list_head	remote_oob_data;
 	struct list_head	le_conn_params;
+	struct list_head	pend_le_conns;
 
 	struct hci_dev_stats	stat;
 
@@ -781,6 +782,12 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
 void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
 void hci_conn_params_clear(struct hci_dev *hdev);
 
+struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
+					    bdaddr_t *addr, u8 addr_type);
+void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
+void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
+void hci_pend_le_conns_clear(struct hci_dev *hdev);
+
 void hci_uuids_clear(struct hci_dev *hdev);
 
 void hci_link_keys_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6a21dcf..0002c62 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3088,6 +3088,72 @@ void hci_conn_params_clear(struct hci_dev *hdev)
 	BT_DBG("All LE connection parameters were removed");
 }
 
+/* This function requires the caller holds hdev->lock */
+struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
+					    bdaddr_t *addr, u8 addr_type)
+{
+	struct bdaddr_list *entry;
+
+	list_for_each_entry(entry, &hdev->pend_le_conns, list) {
+		if (bacmp(&entry->bdaddr, addr) == 0 &&
+		    entry->bdaddr_type == addr_type)
+			return entry;
+	}
+
+	return NULL;
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
+{
+	struct bdaddr_list *entry;
+
+	entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
+	if (entry)
+		return;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry) {
+		BT_ERR("Out of memory");
+		return;
+	}
+
+	bacpy(&entry->bdaddr, addr);
+	entry->bdaddr_type = addr_type;
+
+	list_add(&entry->list, &hdev->pend_le_conns);
+
+	BT_DBG("addr %pMR (type %u)", addr, addr_type);
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
+{
+	struct bdaddr_list *entry;
+
+	entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
+	if (!entry)
+		return;
+
+	list_del(&entry->list);
+	kfree(entry);
+
+	BT_DBG("addr %pMR (type %u)", addr, addr_type);
+}
+
+/* This function requires the caller holds hdev->lock */
+void hci_pend_le_conns_clear(struct hci_dev *hdev)
+{
+	struct bdaddr_list *entry, *tmp;
+
+	list_for_each_entry_safe(entry, tmp, &hdev->pend_le_conns, list) {
+		list_del(&entry->list);
+		kfree(entry);
+	}
+
+	BT_DBG("All LE pending connections cleared");
+}
+
 static void inquiry_complete(struct hci_dev *hdev, u8 status)
 {
 	if (status) {
@@ -3197,6 +3263,7 @@ struct hci_dev *hci_alloc_dev(void)
 	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
 	INIT_LIST_HEAD(&hdev->remote_oob_data);
 	INIT_LIST_HEAD(&hdev->le_conn_params);
+	INIT_LIST_HEAD(&hdev->pend_le_conns);
 	INIT_LIST_HEAD(&hdev->conn_hash.list);
 
 	INIT_WORK(&hdev->rx_work, hci_rx_work);
@@ -3398,6 +3465,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
 	hci_smp_irks_clear(hdev);
 	hci_remote_oob_data_clear(hdev);
 	hci_conn_params_clear(hdev);
+	hci_pend_le_conns_clear(hdev);
 	hci_dev_unlock(hdev);
 
 	hci_dev_put(hdev);
-- 
1.8.5.4


^ permalink raw reply related

* [RFC v9 04/10] Bluetooth: Remove unused function
From: Andre Guedes @ 2014-02-18 17:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392746101-5981-1-git-send-email-andre.guedes@openbossa.org>

This patch removes hci_create_le_conn() since it is not used anymore.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 net/bluetooth/hci_conn.c | 32 --------------------------------
 1 file changed, 32 deletions(-)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 382d02a..da44390 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -551,38 +551,6 @@ done:
 	hci_dev_unlock(hdev);
 }
 
-static int hci_create_le_conn(struct hci_conn *conn)
-{
-	struct hci_dev *hdev = conn->hdev;
-	struct hci_cp_le_create_conn cp;
-	struct hci_request req;
-	int err;
-
-	hci_req_init(&req, hdev);
-
-	memset(&cp, 0, sizeof(cp));
-	cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
-	cp.scan_window = cpu_to_le16(hdev->le_scan_window);
-	bacpy(&cp.peer_addr, &conn->dst);
-	cp.peer_addr_type = conn->dst_type;
-	cp.own_address_type = conn->src_type;
-	cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
-	cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
-	cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
-	cp.min_ce_len = __constant_cpu_to_le16(0x0000);
-	cp.max_ce_len = __constant_cpu_to_le16(0x0000);
-
-	hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
-
-	err = hci_req_run(&req, create_le_conn_complete);
-	if (err) {
-		hci_conn_del(conn);
-		return err;
-	}
-
-	return 0;
-}
-
 static void hci_req_add_le_create_conn(struct hci_request *req,
 				       struct hci_conn *conn)
 {
-- 
1.8.5.4


^ permalink raw reply related

* [RFC v9 03/10] Bluetooth: Stop scanning on LE connection
From: Andre Guedes @ 2014-02-18 17:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392746101-5981-1-git-send-email-andre.guedes@openbossa.org>

Some LE controllers don't support scanning and creating a connection
at the same time. So we should always stop scanning in order to
establish the connection.

Since we may prematurely stop the discovery procedure in favor of
the connection establishment, we should also cancel hdev->le_scan_
disable delayed work and set the discovery state to DISCOVERY_STOPPED.

This change does a small improvement since it is not mandatory the
user stops scanning before connecting anymore. Moreover, this change
is required by upcoming LE auto connection mechanism in order to work
properly with controllers that don't support background scanning and
connection establishment at the same time.

In future, we might want to do a small optimization by checking if
controller is able to scan and connect at the same time. For now,
we want the simplest approach so we always stop scanning (even if
the controller is able to carry out both operations).

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci.h |  1 +
 net/bluetooth/hci_conn.c    | 79 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index d3a8fff..0962809 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -353,6 +353,7 @@ enum {
 
 /* ---- HCI Error Codes ---- */
 #define HCI_ERROR_AUTH_FAILURE		0x05
+#define HCI_ERROR_MEMORY_EXCEEDED	0x07
 #define HCI_ERROR_CONNECTION_TIMEOUT	0x08
 #define HCI_ERROR_REJ_BAD_ADDR		0x0f
 #define HCI_ERROR_REMOTE_USER_TERM	0x13
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 4f5029c..382d02a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -583,11 +583,72 @@ static int hci_create_le_conn(struct hci_conn *conn)
 	return 0;
 }
 
+static void hci_req_add_le_create_conn(struct hci_request *req,
+				       struct hci_conn *conn)
+{
+	struct hci_cp_le_create_conn cp;
+	struct hci_dev *hdev = conn->hdev;
+
+	memset(&cp, 0, sizeof(cp));
+	cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
+	cp.scan_window = cpu_to_le16(hdev->le_scan_window);
+	bacpy(&cp.peer_addr, &conn->dst);
+	cp.peer_addr_type = conn->dst_type;
+	cp.own_address_type = conn->src_type;
+	cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
+	cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
+	cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
+	cp.min_ce_len = __constant_cpu_to_le16(0x0000);
+	cp.max_ce_len = __constant_cpu_to_le16(0x0000);
+
+	hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
+}
+
+static void stop_scan_complete(struct hci_dev *hdev, u8 status)
+{
+	struct hci_request req;
+	struct hci_conn *conn;
+	int err;
+
+	conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
+	if (!conn)
+		return;
+
+	if (status) {
+		BT_DBG("HCI request failed to stop scanning: status 0x%2.2x",
+		       status);
+
+		hci_dev_lock(hdev);
+		hci_le_conn_failed(conn, status);
+		hci_dev_unlock(hdev);
+		return;
+	}
+
+	/* Since we may have prematurely stopped discovery procedure, we should
+	 * update discovery state.
+	 */
+	cancel_delayed_work(&hdev->le_scan_disable);
+	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+
+	hci_req_init(&req, hdev);
+
+	hci_req_add_le_create_conn(&req, conn);
+
+	err = hci_req_run(&req, create_le_conn_complete);
+	if (err) {
+		hci_dev_lock(hdev);
+		hci_le_conn_failed(conn, HCI_ERROR_MEMORY_EXCEEDED);
+		hci_dev_unlock(hdev);
+		return;
+	}
+}
+
 static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 				    u8 dst_type, u8 sec_level, u8 auth_type)
 {
 	struct hci_conn_params *params;
 	struct hci_conn *conn;
+	struct hci_request req;
 	int err;
 
 	if (test_bit(HCI_ADVERTISING, &hdev->flags))
@@ -643,9 +704,23 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 		conn->le_conn_max_interval = hdev->le_conn_max_interval;
 	}
 
-	err = hci_create_le_conn(conn);
-	if (err)
+	hci_req_init(&req, hdev);
+
+	/* If controller is scanning, we stop it since some controllers are
+	 * not able to scan and connect at the same time.
+	 */
+	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
+		hci_req_add_le_scan_disable(&req);
+		err = hci_req_run(&req, stop_scan_complete);
+	} else {
+		hci_req_add_le_create_conn(&req, conn);
+		err = hci_req_run(&req, create_le_conn_complete);
+	}
+
+	if (err) {
+		hci_conn_del(conn);
 		return ERR_PTR(err);
+	}
 
 done:
 	hci_conn_hold(conn);
-- 
1.8.5.4


^ permalink raw reply related

* [RFC v9 02/10] Bluetooth: Declare le_conn_failed in hci_core.h
From: Andre Guedes @ 2014-02-18 17:54 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392746101-5981-1-git-send-email-andre.guedes@openbossa.org>

This patch adds the "hci_" prefix to le_conn_failed() helper and
declares it in hci_core.h so it can be reused in hci_event.c.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci_core.h | 2 ++
 net/bluetooth/hci_conn.c         | 4 ++--
 net/bluetooth/hci_event.c        | 6 +-----
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 6a24756..043b50e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -637,6 +637,8 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
 
 void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
 
+void hci_le_conn_failed(struct hci_conn *conn, u8 status);
+
 /*
  * hci_conn_get() and hci_conn_put() are used to control the life-time of an
  * "hci_conn" object. They do not guarantee that the hci_conn object is running,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 6797292..4f5029c 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -515,7 +515,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
 EXPORT_SYMBOL(hci_get_route);
 
 /* This function requires the caller holds hdev->lock */
-static void le_conn_failed(struct hci_conn *conn, u8 status)
+void hci_le_conn_failed(struct hci_conn *conn, u8 status)
 {
 	struct hci_dev *hdev = conn->hdev;
 
@@ -545,7 +545,7 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
 	if (!conn)
 		goto done;
 
-	le_conn_failed(conn, status);
+	hci_le_conn_failed(conn, status);
 
 done:
 	hci_dev_unlock(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d2c6878..df58cde 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3601,11 +3601,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 
 	if (ev->status) {
-		mgmt_connect_failed(hdev, &conn->dst, conn->type,
-				    conn->dst_type, ev->status);
-		hci_proto_connect_cfm(conn, ev->status);
-		conn->state = BT_CLOSED;
-		hci_conn_del(conn);
+		hci_le_conn_failed(conn, ev->status);
 		goto unlock;
 	}
 
-- 
1.8.5.4


^ permalink raw reply related

* [RFC v9 01/10] Bluetooth: Create hci_req_add_le_scan_disable helper
From: Andre Guedes @ 2014-02-18 17:54 UTC (permalink / raw)
  To: linux-bluetooth

This patch moves stop LE scanning duplicate code to one single
place and reuses it. This will avoid more duplicate code in
upcoming patches.

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 14 ++++++++++----
 net/bluetooth/mgmt.c             |  6 +-----
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4461c00..6a24756 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1112,6 +1112,7 @@ void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
 void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
 		    const void *param, u8 event);
 void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
+void hci_req_add_le_scan_disable(struct hci_request *req);
 
 struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
 			       const void *param, u32 timeout);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cdba470..6a21dcf 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3147,7 +3147,6 @@ static void le_scan_disable_work(struct work_struct *work)
 {
 	struct hci_dev *hdev = container_of(work, struct hci_dev,
 					    le_scan_disable.work);
-	struct hci_cp_le_set_scan_enable cp;
 	struct hci_request req;
 	int err;
 
@@ -3155,9 +3154,7 @@ static void le_scan_disable_work(struct work_struct *work)
 
 	hci_req_init(&req, hdev);
 
-	memset(&cp, 0, sizeof(cp));
-	cp.enable = LE_SCAN_DISABLE;
-	hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
+	hci_req_add_le_scan_disable(&req);
 
 	err = hci_req_run(&req, le_scan_disable_work_complete);
 	if (err)
@@ -4628,3 +4625,12 @@ static void hci_cmd_work(struct work_struct *work)
 		}
 	}
 }
+
+void hci_req_add_le_scan_disable(struct hci_request *req)
+{
+	struct hci_cp_le_set_scan_enable cp;
+
+	memset(&cp, 0, sizeof(cp));
+	cp.enable = LE_SCAN_DISABLE;
+	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
+}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 90aac90..25a0c46 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3411,7 +3411,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
 	struct hci_cp_remote_name_req_cancel cp;
 	struct inquiry_entry *e;
 	struct hci_request req;
-	struct hci_cp_le_set_scan_enable enable_cp;
 	int err;
 
 	BT_DBG("%s", hdev->name);
@@ -3447,10 +3446,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
 		} else {
 			cancel_delayed_work(&hdev->le_scan_disable);
 
-			memset(&enable_cp, 0, sizeof(enable_cp));
-			enable_cp.enable = LE_SCAN_DISABLE;
-			hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE,
-				    sizeof(enable_cp), &enable_cp);
+			hci_req_add_le_scan_disable(&req);
 		}
 
 		break;
-- 
1.8.5.4


^ permalink raw reply related

* Re: [PATCH 1/2] Bluetooth: sort the list of IDs in the source code
From: Marcel Holtmann @ 2014-02-18 17:54 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-bluetooth, Heikki Krogerus
In-Reply-To: <1392740780-27372-1-git-send-email-andriy.shevchenko@linux.intel.com>

Hi Andy,

> This will help to manage table of supported IDs.
> 
> There is no functional change.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> drivers/bluetooth/ath3k.c | 78 +++++++++++++++++++++++------------------------
> drivers/bluetooth/btusb.c | 52 +++++++++++++++----------------
> 2 files changed, 65 insertions(+), 65 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH v2] Bluetooth: allocate static minor for vhci
From: Marcel Holtmann @ 2014-02-18 17:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Lucas De Marchi,
	bluez mailin list (linux-bluetooth@vger.kernel.org), Kay Sievers,
	linux-kernel, Lucas De Marchi
In-Reply-To: <20140218173308.GB17368@kroah.com>

Hi Lucas,

>>> Commit bfacbb9 (Bluetooth: Use devname:vhci module alias for virtual HCI
>>> driver) added the module alias to hci_vhci module so it's possible to
>>> create the /dev/vhci node. However creating an alias without
>>> specifying the minor doesn't allow us to create the node ahead,
>>> triggerring module auto-load when it's first accessed.
>>> 
>>> Starting with depmod from kmod 16 we started to warn if there's a
>>> devname alias without specifying the major and minor.
>>> 
>>> Let's do the same done for uhid, kvm, fuse and others, specifying a
>>> fixed minor. In systems with systemd as the init the following will
>>> happen: on early boot systemd will call "kmod static-nodes" to read
>>> /lib/modules/$(uname -r)/modules.devname and then create the nodes. When
>>> first accessed these "dead" nodes will trigger the module loading.
>>> 
>>> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
>>> ---
>>> 
>>> Changes from v1:
>>> - use minor=137, since 240 is reserved for local use
>>> 
>>> We talked about using 197, but that's being used by pxa3xx-gcu, too.
>> 
>> looks fine to me. If Kay and/or Greg want to ack it, then I take it through bluetooth-next tree.
> 
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> 

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH BlueZ v6 00/18] GATT API: External Services
From: Marcel Holtmann @ 2014-02-18 17:44 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1391536429-8345-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

> This patchset implements the minimal support for adding local services
> declarations.
> 
> Limitation: Remove services and multiple services exported by the same
> remote will be implemented the next series.

what is the deal with this unix socket you are using for local access? I think we should remove that functionality and keep it simple in the beginning.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH 01/10] Bluetooth: Remove SMP data specific crypto context
From: Marcel Holtmann @ 2014-02-18 17:34 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <20140218162926.GB13953@x220.p-661hnu-f1>

Hi Johan,

>>> so I am curious now to what happens if we are running SMP and at the
>>> same time are doing RPA resolving. Can the same crypto context be used
>>> that way?
>> 
>> That's a fair point, and after a quick look through the crypto API it
>> seems like this might not be safe. A simple fix would be to ensure that
>> any access is between hci_dev_lock & hci_dev_unlock.
> 
> A quick check shows that all access external to smp.c is already done
> under the hdev lock but the two places internal to smp.c are not (both
> of which are from within workqueue callbacks, so taking the lock there
> should be safe). Do you agree that this is the simplest/best solution?

since we always do only one AES round anyway, that seems to be a good solution to this.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH v2] Bluetooth: allocate static minor for vhci
From: Greg Kroah-Hartman @ 2014-02-18 17:33 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Lucas De Marchi,
	bluez mailin list (linux-bluetooth@vger.kernel.org), Kay Sievers,
	linux-kernel, Lucas De Marchi
In-Reply-To: <BD98E109-FE9C-4F67-84AC-3CEA048641BE@holtmann.org>

On Mon, Feb 17, 2014 at 11:01:11PM -0800, Marcel Holtmann wrote:
> Hi Lucas,
> 
> > Commit bfacbb9 (Bluetooth: Use devname:vhci module alias for virtual HCI
> > driver) added the module alias to hci_vhci module so it's possible to
> > create the /dev/vhci node. However creating an alias without
> > specifying the minor doesn't allow us to create the node ahead,
> > triggerring module auto-load when it's first accessed.
> > 
> > Starting with depmod from kmod 16 we started to warn if there's a
> > devname alias without specifying the major and minor.
> > 
> > Let's do the same done for uhid, kvm, fuse and others, specifying a
> > fixed minor. In systems with systemd as the init the following will
> > happen: on early boot systemd will call "kmod static-nodes" to read
> > /lib/modules/$(uname -r)/modules.devname and then create the nodes. When
> > first accessed these "dead" nodes will trigger the module loading.
> > 
> > Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
> > ---
> > 
> > Changes from v1:
> > - use minor=137, since 240 is reserved for local use
> > 
> > We talked about using 197, but that's being used by pxa3xx-gcu, too.
> 
> looks fine to me. If Kay and/or Greg want to ack it, then I take it through bluetooth-next tree.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply

* Re: [PATCH 08/10] Bluetooth: Track the LE Identity Address in struct hci_conn
From: Marcel Holtmann @ 2014-02-18 17:01 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1392736479-8808-9-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> Since we want user space to see and use the LE Identity Address whenever
> interfacing with the kernel it makes sense to track that instead of the
> real address (the two will only be different in the case of an RPA).
> This patch adds the necessary updates to when an LE connection gets
> established and when receiving the Identity Address from a remote
> device.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/hci_event.c | 7 +++++++
> net/bluetooth/smp.c       | 3 +++
> 2 files changed, 10 insertions(+)
> 
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index d2c6878a9d6a..f31410a071b5 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -3568,6 +3568,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
> {
> 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
> 	struct hci_conn *conn;
> +	struct smp_irk *irk;
> 
> 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
> 
> @@ -3600,6 +3601,12 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
> 		}
> 	}
> 
> +	irk = hci_get_irk(hdev, &ev->bdaddr, ev->bdaddr_type);
> +	if (irk) {
> +		bacpy(&conn->dst, &irk->bdaddr);
> +		conn->dst_type = irk->addr_type;
> +	}
> +
> 	if (ev->status) {
> 		mgmt_connect_failed(hdev, &conn->dst, conn->type,
> 				    conn->dst_type, ev->status);
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index 54672c9ab6a5..4d14ccc7b330 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -973,6 +973,9 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
> 	hci_add_irk(conn->hcon->hdev, &smp->id_addr, smp->id_addr_type,
> 		    smp->irk, &rpa);
> 
> +	bacpy(&hcon->dst, &smp->id_addr);
> +	hcon->dst_type = smp->id_addr_type;
> +

is this really safe to just overwrite the dst and dst_type. If we do that, we never really know the address that used for the actual connection.

For example what happens if now a stupid L2CAP connection gets intimated for the RPA or we have an incoming request for the same RPA. Can we really at this point say, we never need the RPA again?

Regards

Marcel


^ permalink raw reply

* Re: [PATCH 00/10] Bluetooth: More patches for privacy
From: Marcel Holtmann @ 2014-02-18 16:59 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1392736479-8808-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> Here are more patches towards implementing support for privacy. Included
> are also some cleanup and fix patches for issues I came accross when
> dealing with the code.
> 
> Johan
> 
> ----------------------------------------------------------------
> Johan Hedberg (10):
>      Bluetooth: Remove SMP data specific crypto context
>      Bluetooth: Fix missing address type check for removing LTKs
>      Bluetooth: Remove return values from functions that don't need them
>      Bluetooth: Fix hci_remove_ltk failure when no match is found
>      Bluetooth: Fix completing SMP as peripheral when no keys are expected
>      Bluetooth: Fix removing any IRKs when unpairing devices
>      Bluetooth: Add convenience function for fetching IRKs
>      Bluetooth: Track the LE Identity Address in struct hci_conn
>      Bluetooth: Fix updating Identity Address in L2CAP channels
>      Bluetooth: Wait for SMP key distribution completion when pairing
> 
> include/net/bluetooth/hci_core.h | 23 +++++++++++++-----
> include/net/bluetooth/l2cap.h    |  1 +
> net/bluetooth/hci_core.c         | 49 ++++++++++++++++++++++----------------
> net/bluetooth/hci_event.c        |  7 ++++++
> net/bluetooth/l2cap_core.c       | 17 +++++++++++++
> net/bluetooth/mgmt.c             | 45 ++++++++++++++++++++++++++--------
> net/bluetooth/smp.c              | 25 ++++++++++---------
> net/bluetooth/smp.h              |  2 +-
> 8 files changed, 119 insertions(+), 50 deletions(-)

I applied patches 2-7 to bluetooth-next now. For the rest I have questions/comments.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH BlueZ 8/8] doc/obex-api: Update documentation
From: Patrick Ohly @ 2014-02-18 16:54 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZ+-hu0G6cja-uBWPFuywj7S+bBDhitNoBhUnFnTFjYDcA@mail.gmail.com>

On Tue, 2014-02-18 at 11:30 +0200, Luiz Augusto von Dentz wrote:
> Hi Patrick,
> 
> On Tue, Feb 18, 2014 at 11:09 AM, Patrick Ohly <patrick.ohly@intel.com> wrote:
> > On Fri, 2014-02-14 at 17:53 +0200, Luiz Augusto von Dentz wrote:
> >> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> >>
> >> This adds Suspend and Resume methods and 'suspended' value as status in
> >> the Transfer interface documentation.
> >> ---
> >>  doc/obex-api.txt | 18 ++++++++++++++++--
> >>  1 file changed, 16 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/doc/obex-api.txt b/doc/obex-api.txt
> >> index 1f22fea..0f57ce1 100644
> >> --- a/doc/obex-api.txt
> >> +++ b/doc/obex-api.txt
> >> @@ -90,12 +90,26 @@ Methods           void Cancel()
> >>                                        org.bluez.obex.Error.InProgress
> >>                                        org.bluez.obex.Error.Failed
> >>
> >> +             void Suspend()
> >> +
> >> +                     Suspend transference.
> >> +
> >> +                     Possible errors: org.bluez.obex.Error.NotAuthorized
> >> +                                      org.bluez.obex.Error.NotInProgress
> >> +
> >> +             void Resume()
> >> +
> >> +                     Resume transference.
> >> +
> >> +                     Possible errors: org.bluez.obex.Error.NotAuthorized
> >> +                                      org.bluez.obex.Error.NotInProgress
> >                                                                 ^^^^^^^^^^^^^
> >
> > Should this be a NotSuspended error? Or is it not an error to resume a
> > transfer which is currently not suspended?
> 
> Hmm, I would go for InProgress like in Cancel although now that you
> mentioned we could perhaps ignore such errors if you don't see any
> value on those.

I think I would prefer to *not* get errors when Suspend() is called on
an already suspended transfer or when Resume() is called on a running
transfer. The rationale is that the caller will typically only care
about the end result and not so much whether it was the one who
triggered the change. If we remove NotInProgress resp. InProgress errors
from the API, then such a caller can treat all errors as fatal problem,
without having to check the exact error.

Bye, Patrick










^ permalink raw reply

* [PATCH BlueZ v2] gdbus: Fix incorrect DBusConnection reference counting
From: Anderson Lizardo @ 2014-02-18 16:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1392052498-9229-2-git-send-email-anderson.lizardo@openbossa.org>

Commit abfc2b0dd5c3e33abfdf1a815b16d492c1751c06 attempted to fix a crash
related to improper reference counting, but the main issue was that the
reference was taken only during the function call (which is usually
unnecessary for single thread), but still passed a pointer to
DBusConnection to a function that is called by the mainloop. This left a
window where the DBusConnection can be destroyed.

Fixes this crash on unit/test-gdbus-client:

==32642== Invalid read of size 4
==32642==    at 0x690D0A6: dbus_connection_ref (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x804CEDB: message_dispatch (mainloop.c:73)
==32642==    by 0x684580E: g_timeout_dispatch (gmain.c:4450)
==32642==    by 0x6844A75: g_main_context_dispatch (gmain.c:3065)
==32642==    by 0x6844E14: g_main_context_iterate.isra.23 (gmain.c:3712)
==32642==    by 0x68452FA: g_main_loop_run (gmain.c:3906)
==32642==    by 0x804C7D3: client_connect_disconnect
(test-gdbus-client.c:188)
==32642==    by 0x6868DB2: g_test_run_suite_internal (gtestutils.c:2067)
==32642==    by 0x6868F8D: g_test_run_suite_internal (gtestutils.c:2138)
==32642==    by 0x6869320: g_test_run_suite (gtestutils.c:2189)
==32642==    by 0x686936B: g_test_run (gtestutils.c:1508)
==32642==    by 0x696D4D2: (below main) (libc-start.c:226)
==32642==  Address 0x709c6e4 is 140 bytes inside a block of size 144
free'd
==32642==    at 0x67E806C: free (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==32642==    by 0x692D62E: dbus_free (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x690E1C2: ??? (in
/lib/i386-linux-gnu/libdbus-1.so.3.7.6)
==32642==    by 0x804AAEC: destroy_context (test-gdbus-client.c:104)
==32642==    by 0x6868DB2: g_test_run_suite_internal (gtestutils.c:2067)
==32642==    by 0x6868F8D: g_test_run_suite_internal (gtestutils.c:2138)
==32642==    by 0x6869320: g_test_run_suite (gtestutils.c:2189)
==32642==    by 0x686936B: g_test_run (gtestutils.c:1508)
==32642==    by 0x696D4D2: (below main) (libc-start.c:226)
---
 gdbus/mainloop.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/gdbus/mainloop.c b/gdbus/mainloop.c
index 099b67f..ec52554 100644
--- a/gdbus/mainloop.c
+++ b/gdbus/mainloop.c
@@ -70,8 +70,6 @@ static gboolean message_dispatch(void *data)
 {
 	DBusConnection *conn = data;
 
-	dbus_connection_ref(conn);
-
 	/* Dispatch messages */
 	while (dbus_connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS);
 
@@ -84,7 +82,8 @@ static inline void queue_dispatch(DBusConnection *conn,
 						DBusDispatchStatus status)
 {
 	if (status == DBUS_DISPATCH_DATA_REMAINS)
-		g_timeout_add(DISPATCH_TIMEOUT, message_dispatch, conn);
+		g_timeout_add(DISPATCH_TIMEOUT, message_dispatch,
+						dbus_connection_ref(conn));
 }
 
 static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
@@ -92,9 +91,6 @@ static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
 	struct watch_info *info = data;
 	unsigned int flags = 0;
 	DBusDispatchStatus status;
-	DBusConnection *conn;
-
-	conn = dbus_connection_ref(info->conn);
 
 	if (cond & G_IO_IN)  flags |= DBUS_WATCH_READABLE;
 	if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE;
@@ -103,10 +99,8 @@ static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
 
 	dbus_watch_handle(info->watch, flags);
 
-	status = dbus_connection_get_dispatch_status(conn);
-	queue_dispatch(conn, status);
-
-	dbus_connection_unref(conn);
+	status = dbus_connection_get_dispatch_status(info->conn);
+	queue_dispatch(info->conn, status);
 
 	return TRUE;
 }
-- 
1.8.5.3


^ permalink raw reply related

* Re: [PATCH 01/10] Bluetooth: Remove SMP data specific crypto context
From: Johan Hedberg @ 2014-02-18 16:29 UTC (permalink / raw)
  To: Marcel Holtmann,
	bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <20140218162438.GA13953@x220.p-661hnu-f1>

Hi Marcel,

On Tue, Feb 18, 2014, Johan Hedberg wrote:
> > so I am curious now to what happens if we are running SMP and at the
> > same time are doing RPA resolving. Can the same crypto context be used
> > that way?
> 
> That's a fair point, and after a quick look through the crypto API it
> seems like this might not be safe. A simple fix would be to ensure that
> any access is between hci_dev_lock & hci_dev_unlock.

A quick check shows that all access external to smp.c is already done
under the hdev lock but the two places internal to smp.c are not (both
of which are from within workqueue callbacks, so taking the lock there
should be safe). Do you agree that this is the simplest/best solution?

Johan

^ permalink raw reply

* Re: Help with AVDTP Connection accept
From: Luiz Augusto von Dentz @ 2014-02-18 16:27 UTC (permalink / raw)
  To: tony; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <5303720B.4090902@convergeddevices.net>

Hi Tony,

On Tue, Feb 18, 2014 at 4:45 PM, tony <tony.makkiel@convergeddevices.net> wrote:
> A2DP sdp record is not enabled by default. Once I added the source service
> using sdptool, I can get past the 'AVDTP CONNECT'. But now it cribs at AVDTP
> DISCOVER. Any ideas?
>
> Thanks,
> Tony
>
>
>
> On 17/02/14 20:08, tony wrote:
>>
>> Hi,
>>          I have BlueZ 4.101 and the daemon is running(log file
>> daemon.txt). I am trying to initiate an AVDTP connection from PTS suite.
>> But couldn't get(or not sure how) the BlueZ side accept the connection.
>>  From the log I can see the device reply with no Link key message. But
>> the connection gets dropped quickly.
>>
>> 1) From browsing the SDP entries (log :- sdptool.txt ), I don't see an
>> entry for A2DP. I ran the configure file with --enable audio and can see
>> from the daemon.txt audio plugin is loaded. Should I be adding SDP
>> record manually? How can I do that?
>>
>> 2) Am I right in understanding, I should be using test/simple-agent to
>> manage SSP? At present I don't see anything. From forums, I understand,
>> the script would prompt for PIN or any security as required. But in my
>> case nothing happens.  I have attached the btmon log as well.
>>
>> Thank you for any pointers or suggestions.

I suspect you don't have a endpoint registered in your system, you can
either use test/simple-endpoint or PulseAudio as endpoint or create
one yourself. The so called endpoint is required since bluetoothd
don't deal with the audio streams so normally this is part of the
platform integration where the audio/media server need to take over.

^ permalink raw reply

* [PATCH 2/2] Bluetooth: append new supported device to the list [0b05:17d0]
From: Andy Shevchenko @ 2014-02-18 16:26 UTC (permalink / raw)
  To: linux-bluetooth, Heikki Krogerus, Marcel Holtmann; +Cc: Andy Shevchenko
In-Reply-To: <1392740780-27372-1-git-send-email-andriy.shevchenko@linux.intel.com>

The device found on Asus Z87 Expert motherboard requires firmware to work
correctly.

T:  Bus=03 Lev=01 Prnt=01 Port=03 Cnt=02 Dev#=  3 Spd=12  MxCh= 0
D:  Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0b05 ProdID=17d0 Rev=00.02
C:  #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I:  If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/bluetooth/ath3k.c | 2 ++
 drivers/bluetooth/btusb.c | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index fc93ade..4f78a9d 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -86,6 +86,7 @@ static const struct usb_device_id ath3k_table[] = {
 	{ USB_DEVICE(0x04CA, 0x300b) },
 	{ USB_DEVICE(0x0930, 0x0219) },
 	{ USB_DEVICE(0x0930, 0x0220) },
+	{ USB_DEVICE(0x0b05, 0x17d0) },
 	{ USB_DEVICE(0x0CF3, 0x0036) },
 	{ USB_DEVICE(0x0CF3, 0x3004) },
 	{ USB_DEVICE(0x0CF3, 0x3008) },
@@ -133,6 +134,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
 	{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 46640e9..199b9d4 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -156,6 +156,7 @@ static const struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
-- 
1.9.0.rc3

^ permalink raw reply related

* [PATCH 1/2] Bluetooth: sort the list of IDs in the source code
From: Andy Shevchenko @ 2014-02-18 16:26 UTC (permalink / raw)
  To: linux-bluetooth, Heikki Krogerus, Marcel Holtmann; +Cc: Andy Shevchenko

This will help to manage table of supported IDs.

There is no functional change.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/bluetooth/ath3k.c | 78 +++++++++++++++++++++++------------------------
 drivers/bluetooth/btusb.c | 52 +++++++++++++++----------------
 2 files changed, 65 insertions(+), 65 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 41ec6f9..fc93ade 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -62,52 +62,52 @@ static const struct usb_device_id ath3k_table[] = {
 	{ USB_DEVICE(0x0CF3, 0x3000) },
 
 	/* Atheros AR3011 with sflash firmware*/
+	{ USB_DEVICE(0x0489, 0xE027) },
+	{ USB_DEVICE(0x0489, 0xE03D) },
+	{ USB_DEVICE(0x0930, 0x0215) },
 	{ USB_DEVICE(0x0CF3, 0x3002) },
 	{ USB_DEVICE(0x0CF3, 0xE019) },
 	{ USB_DEVICE(0x13d3, 0x3304) },
-	{ USB_DEVICE(0x0930, 0x0215) },
-	{ USB_DEVICE(0x0489, 0xE03D) },
-	{ USB_DEVICE(0x0489, 0xE027) },
 
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03F0, 0x311D) },
 
 	/* Atheros AR3012 with sflash firmware*/
+	{ USB_DEVICE(0x0489, 0xe04d) },
+	{ USB_DEVICE(0x0489, 0xe04e) },
+	{ USB_DEVICE(0x0489, 0xe057) },
+	{ USB_DEVICE(0x0489, 0xe056) },
+	{ USB_DEVICE(0x0489, 0xe05f) },
+	{ USB_DEVICE(0x04c5, 0x1330) },
+	{ USB_DEVICE(0x04CA, 0x3004) },
+	{ USB_DEVICE(0x04CA, 0x3005) },
+	{ USB_DEVICE(0x04CA, 0x3006) },
+	{ USB_DEVICE(0x04CA, 0x3008) },
+	{ USB_DEVICE(0x04CA, 0x300b) },
+	{ USB_DEVICE(0x0930, 0x0219) },
+	{ USB_DEVICE(0x0930, 0x0220) },
 	{ USB_DEVICE(0x0CF3, 0x0036) },
 	{ USB_DEVICE(0x0CF3, 0x3004) },
 	{ USB_DEVICE(0x0CF3, 0x3008) },
 	{ USB_DEVICE(0x0CF3, 0x311D) },
 	{ USB_DEVICE(0x0CF3, 0x311E) },
 	{ USB_DEVICE(0x0CF3, 0x311F) },
+	{ USB_DEVICE(0x0cf3, 0x3121) },
 	{ USB_DEVICE(0x0CF3, 0x817a) },
-	{ USB_DEVICE(0x13d3, 0x3375) },
-	{ USB_DEVICE(0x04CA, 0x3004) },
-	{ USB_DEVICE(0x04CA, 0x3005) },
-	{ USB_DEVICE(0x04CA, 0x3006) },
-	{ USB_DEVICE(0x04CA, 0x3008) },
-	{ USB_DEVICE(0x04CA, 0x300b) },
-	{ USB_DEVICE(0x13d3, 0x3362) },
+	{ USB_DEVICE(0x0cf3, 0xe003) },
 	{ USB_DEVICE(0x0CF3, 0xE004) },
 	{ USB_DEVICE(0x0CF3, 0xE005) },
-	{ USB_DEVICE(0x0930, 0x0219) },
-	{ USB_DEVICE(0x0930, 0x0220) },
-	{ USB_DEVICE(0x0489, 0xe057) },
+	{ USB_DEVICE(0x13d3, 0x3362) },
+	{ USB_DEVICE(0x13d3, 0x3375) },
 	{ USB_DEVICE(0x13d3, 0x3393) },
-	{ USB_DEVICE(0x0489, 0xe04e) },
-	{ USB_DEVICE(0x0489, 0xe056) },
-	{ USB_DEVICE(0x0489, 0xe04d) },
-	{ USB_DEVICE(0x04c5, 0x1330) },
 	{ USB_DEVICE(0x13d3, 0x3402) },
-	{ USB_DEVICE(0x0cf3, 0x3121) },
-	{ USB_DEVICE(0x0cf3, 0xe003) },
-	{ USB_DEVICE(0x0489, 0xe05f) },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE02C) },
 
 	/* Atheros AR5BBU22 with sflash firmware */
-	{ USB_DEVICE(0x0489, 0xE03C) },
 	{ USB_DEVICE(0x0489, 0xE036) },
+	{ USB_DEVICE(0x0489, 0xE03C) },
 
 	{ }	/* Terminating entry */
 };
@@ -120,38 +120,38 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 static const struct usb_device_id ath3k_blist_tbl[] = {
 
 	/* Atheros AR3012 with sflash firmware*/
+	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311F), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU22 with sflash firmware */
-	{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
 
 	{ }	/* Terminating entry */
 };
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e5680fa..46640e9 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -101,16 +101,16 @@ static const struct usb_device_id btusb_table[] = {
 	{ USB_DEVICE(0x0c10, 0x0000) },
 
 	/* Broadcom BCM20702A0 */
+	{ USB_DEVICE(0x0489, 0xe042) },
+	{ USB_DEVICE(0x04ca, 0x2003) },
 	{ USB_DEVICE(0x0b05, 0x17b5) },
 	{ USB_DEVICE(0x0b05, 0x17cb) },
-	{ USB_DEVICE(0x04ca, 0x2003) },
-	{ USB_DEVICE(0x0489, 0xe042) },
 	{ USB_DEVICE(0x413c, 0x8197) },
 
 	/* Foxconn - Hon Hai */
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) },
 
-	/*Broadcom devices with vendor specific id */
+	/* Broadcom devices with vendor specific id */
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
 
 	/* Belkin F8065bf - Broadcom based */
@@ -132,57 +132,57 @@ static const struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
 
 	/* Atheros 3011 with sflash firmware */
+	{ USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
+	{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
+	{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
 	{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
 	{ USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE },
 	{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
-	{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
-	{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
-	{ USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
 
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
 
 	/* Atheros 3012 with sflash firmware */
+	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
-	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
 
 	/* Atheros AR5BBU12 with sflash firmware */
-	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
 
 	/* Broadcom BCM2035 */
-	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
-	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
 	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
+	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
+	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
 
 	/* Broadcom BCM2045 */
 	{ USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU },
-- 
1.9.0.rc3

^ permalink raw reply related

* Re: [PATCH 01/10] Bluetooth: Remove SMP data specific crypto context
From: Johan Hedberg @ 2014-02-18 16:24 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <596B741F-5844-4C49-BE66-5413510692C4@holtmann.org>

Hi Marcel,

On Tue, Feb 18, 2014, Marcel Holtmann wrote:
> > Now that each HCI device has its own AES crypto context we don't need
> > the one stored in the SMP data any more. This patch removes the variable
> > from struct smp_chan and updates the SMP code to use the per-hdev crypto
> > context.
> > 
> > Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> > ---
> > net/bluetooth/smp.c | 15 ++-------------
> > net/bluetooth/smp.h |  1 -
> > 2 files changed, 2 insertions(+), 14 deletions(-)
> > 
> > diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> > index 5867c1c3f436..6dcb35640b6f 100644
> > --- a/net/bluetooth/smp.c
> > +++ b/net/bluetooth/smp.c
> > @@ -413,21 +413,13 @@ static void confirm_work(struct work_struct *work)
> > {
> > 	struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
> > 	struct l2cap_conn *conn = smp->conn;
> > -	struct crypto_blkcipher *tfm;
> > +	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm_aes;
> > 	struct smp_cmd_pairing_confirm cp;
> > 	int ret;
> > 	u8 res[16], reason;
> > 
> > 	BT_DBG("conn %p", conn);
> > 
> > -	tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
> > -	if (IS_ERR(tfm)) {
> > -		reason = SMP_UNSPECIFIED;
> > -		goto error;
> > -	}
> > -
> > -	smp->tfm = tfm;
> > -
> 
> so I am curious now to what happens if we are running SMP and at the
> same time are doing RPA resolving. Can the same crypto context be used
> that way?

That's a fair point, and after a quick look through the crypto API it
seems like this might not be safe. A simple fix would be to ensure that
any access is between hci_dev_lock & hci_dev_unlock.

Johan

^ permalink raw reply

* Re: [PATCH 01/10] Bluetooth: Remove SMP data specific crypto context
From: Marcel Holtmann @ 2014-02-18 16:04 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1392736479-8808-2-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> Now that each HCI device has its own AES crypto context we don't need
> the one stored in the SMP data any more. This patch removes the variable
> from struct smp_chan and updates the SMP code to use the per-hdev crypto
> context.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/smp.c | 15 ++-------------
> net/bluetooth/smp.h |  1 -
> 2 files changed, 2 insertions(+), 14 deletions(-)
> 
> diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
> index 5867c1c3f436..6dcb35640b6f 100644
> --- a/net/bluetooth/smp.c
> +++ b/net/bluetooth/smp.c
> @@ -413,21 +413,13 @@ static void confirm_work(struct work_struct *work)
> {
> 	struct smp_chan *smp = container_of(work, struct smp_chan, confirm);
> 	struct l2cap_conn *conn = smp->conn;
> -	struct crypto_blkcipher *tfm;
> +	struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm_aes;
> 	struct smp_cmd_pairing_confirm cp;
> 	int ret;
> 	u8 res[16], reason;
> 
> 	BT_DBG("conn %p", conn);
> 
> -	tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
> -	if (IS_ERR(tfm)) {
> -		reason = SMP_UNSPECIFIED;
> -		goto error;
> -	}
> -
> -	smp->tfm = tfm;
> -

so I am curious now to what happens if we are running SMP and at the same time are doing RPA resolving. Can the same crypto context be used that way?

Regards

Marcel


^ permalink raw reply

* [PATCH v2 10/10] Bluetooth: Wait for SMP key distribution completion when pairing
From: johan.hedberg @ 2014-02-18 15:44 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392736479-8808-11-git-send-email-johan.hedberg@gmail.com>

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

When we initiate pairing through mgmt_pair_device the code has so far
been waiting for a successful HCI Encrypt Change event in order to
respond to the mgmt command. However, putting privacy into the play we
actually want the key distribution to be complete before replying so
that we can include the Identity Address in the mgmt response.

This patch updates the various hci_conn callbacks for LE in mgmt.c to
only respond in the case of failure, and adds a new mgmt_smp_complete
function that the SMP code will call once key distribution has been
completed.

Since the smp_chan_destroy function that's used to indicate completion
and clean up the SMP context can be called from various places,
including outside of smp.c, the easiest way to track failure vs success
is a new flag that we set once key distribution has been successfully
completed.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
v2: Fix passing correct status value to pairing_complete()

 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/mgmt.c             | 27 +++++++++++++++++++++------
 net/bluetooth/smp.c              |  5 +++++
 net/bluetooth/smp.h              |  1 +
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4461c0051228..64c4e3f0a515 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1212,6 +1212,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
 void mgmt_reenable_advertising(struct hci_dev *hdev);
+void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 90aac905a98b..f9ae72ca556d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2655,6 +2655,18 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
 	mgmt_pending_remove(cmd);
 }
 
+void mgmt_smp_complete(struct hci_conn *conn, bool complete)
+{
+	u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED;
+	struct pending_cmd *cmd;
+
+	cmd = find_pairing(conn);
+	if (!cmd)
+		BT_DBG("Unable to find a pending command");
+	else
+		pairing_complete(cmd, status);
+}
+
 static void pairing_complete_cb(struct hci_conn *conn, u8 status)
 {
 	struct pending_cmd *cmd;
@@ -2668,7 +2680,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
 		pairing_complete(cmd, mgmt_status(status));
 }
 
-static void le_connect_complete_cb(struct hci_conn *conn, u8 status)
+static void le_pairing_complete_cb(struct hci_conn *conn, u8 status)
 {
 	struct pending_cmd *cmd;
 
@@ -2755,13 +2767,16 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 	}
 
 	/* For LE, just connecting isn't a proof that the pairing finished */
-	if (cp->addr.type == BDADDR_BREDR)
+	if (cp->addr.type == BDADDR_BREDR) {
 		conn->connect_cfm_cb = pairing_complete_cb;
-	else
-		conn->connect_cfm_cb = le_connect_complete_cb;
+		conn->security_cfm_cb = pairing_complete_cb;
+		conn->disconn_cfm_cb = pairing_complete_cb;
+	} else {
+		conn->connect_cfm_cb = le_pairing_complete_cb;
+		conn->security_cfm_cb = le_pairing_complete_cb;
+		conn->disconn_cfm_cb = le_pairing_complete_cb;
+	}
 
-	conn->security_cfm_cb = pairing_complete_cb;
-	conn->disconn_cfm_cb = pairing_complete_cb;
 	conn->io_capability = cp->io_cap;
 	cmd->user_data = conn;
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index faf04bd4263a..9741623de6e7 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -551,9 +551,13 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 void smp_chan_destroy(struct l2cap_conn *conn)
 {
 	struct smp_chan *smp = conn->smp_chan;
+	bool complete;
 
 	BUG_ON(!smp);
 
+	complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
+	mgmt_smp_complete(conn->hcon, complete);
+
 	kfree(smp);
 	conn->smp_chan = NULL;
 	conn->hcon->smp_conn = NULL;
@@ -1172,6 +1176,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 	if (conn->hcon->out || force || !(rsp->init_key_dist & 0x07)) {
 		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
 		cancel_delayed_work_sync(&conn->security_timer);
+		set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
 		smp_chan_destroy(conn);
 	}
 
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 8f54c9b152de..675fd3b21d2c 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -118,6 +118,7 @@ struct smp_cmd_security_req {
 #define SMP_FLAG_TK_VALID	1
 #define SMP_FLAG_CFM_PENDING	2
 #define SMP_FLAG_MITM_AUTH	3
+#define SMP_FLAG_COMPLETE	4
 
 struct smp_chan {
 	struct l2cap_conn *conn;
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 10/10] Bluetooth: Wait for SMP key distribution completion when pairing
From: johan.hedberg @ 2014-02-18 15:14 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392736479-8808-1-git-send-email-johan.hedberg@gmail.com>

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

When we initiate pairing through mgmt_pair_device the code has so far
been waiting for a successful HCI Encrypt Change event in order to
respond to the mgmt command. However, putting privacy into the play we
actually want the key distribution to be complete before replying so
that we can include the Identity Address in the mgmt response.

This patch updates the various hci_conn callbacks for LE in mgmt.c to
only respond in the case of failure, and adds a new mgmt_smp_complete
function that the SMP code will call once key distribution has been
completed.

Since the smp_chan_destroy function that's used to indicate completion
and clean up the SMP context can be called from various places,
including outside of smp.c, the easiest way to track failure vs success
is a new flag that we set once key distribution has been successfully
completed.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/mgmt.c             | 27 +++++++++++++++++++++------
 net/bluetooth/smp.c              |  5 +++++
 net/bluetooth/smp.h              |  1 +
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4461c0051228..64c4e3f0a515 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1212,6 +1212,7 @@ int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
 void mgmt_reenable_advertising(struct hci_dev *hdev);
+void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 90aac905a98b..58d7cc39f035 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2655,6 +2655,18 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
 	mgmt_pending_remove(cmd);
 }
 
+void mgmt_smp_complete(struct hci_conn *conn, bool complete)
+{
+	u8 status = complete ? MGMT_STATUS_SUCCESS : MGMT_STATUS_FAILED;
+	struct pending_cmd *cmd;
+
+	cmd = find_pairing(conn);
+	if (!cmd)
+		BT_DBG("Unable to find a pending command");
+	else
+		pairing_complete(cmd, mgmt_status(status));
+}
+
 static void pairing_complete_cb(struct hci_conn *conn, u8 status)
 {
 	struct pending_cmd *cmd;
@@ -2668,7 +2680,7 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
 		pairing_complete(cmd, mgmt_status(status));
 }
 
-static void le_connect_complete_cb(struct hci_conn *conn, u8 status)
+static void le_pairing_complete_cb(struct hci_conn *conn, u8 status)
 {
 	struct pending_cmd *cmd;
 
@@ -2755,13 +2767,16 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 	}
 
 	/* For LE, just connecting isn't a proof that the pairing finished */
-	if (cp->addr.type == BDADDR_BREDR)
+	if (cp->addr.type == BDADDR_BREDR) {
 		conn->connect_cfm_cb = pairing_complete_cb;
-	else
-		conn->connect_cfm_cb = le_connect_complete_cb;
+		conn->security_cfm_cb = pairing_complete_cb;
+		conn->disconn_cfm_cb = pairing_complete_cb;
+	} else {
+		conn->connect_cfm_cb = le_pairing_complete_cb;
+		conn->security_cfm_cb = le_pairing_complete_cb;
+		conn->disconn_cfm_cb = le_pairing_complete_cb;
+	}
 
-	conn->security_cfm_cb = pairing_complete_cb;
-	conn->disconn_cfm_cb = pairing_complete_cb;
 	conn->io_capability = cp->io_cap;
 	cmd->user_data = conn;
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index faf04bd4263a..9741623de6e7 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -551,9 +551,13 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 void smp_chan_destroy(struct l2cap_conn *conn)
 {
 	struct smp_chan *smp = conn->smp_chan;
+	bool complete;
 
 	BUG_ON(!smp);
 
+	complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
+	mgmt_smp_complete(conn->hcon, complete);
+
 	kfree(smp);
 	conn->smp_chan = NULL;
 	conn->hcon->smp_conn = NULL;
@@ -1172,6 +1176,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
 	if (conn->hcon->out || force || !(rsp->init_key_dist & 0x07)) {
 		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
 		cancel_delayed_work_sync(&conn->security_timer);
+		set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
 		smp_chan_destroy(conn);
 	}
 
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 8f54c9b152de..675fd3b21d2c 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -118,6 +118,7 @@ struct smp_cmd_security_req {
 #define SMP_FLAG_TK_VALID	1
 #define SMP_FLAG_CFM_PENDING	2
 #define SMP_FLAG_MITM_AUTH	3
+#define SMP_FLAG_COMPLETE	4
 
 struct smp_chan {
 	struct l2cap_conn *conn;
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 09/10] Bluetooth: Fix updating Identity Address in L2CAP channels
From: johan.hedberg @ 2014-02-18 15:14 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392736479-8808-1-git-send-email-johan.hedberg@gmail.com>

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

When we receive a remote identity address during SMP key distribution we
should ensure that any associated L2CAP channel instances get their
address information correspondingly updated (so that e.g. doing
getpeername on associated sockets returns the correct address).

This patch adds a new L2CAP core function l2cap_conn_update_id_addr()
which is used to iterate through all L2CAP channels associated with a
connection and update their address information.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/l2cap.h |  1 +
 net/bluetooth/l2cap_core.c    | 17 +++++++++++++++++
 net/bluetooth/smp.c           |  2 ++
 3 files changed, 20 insertions(+)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 13bec91785f4..4abdcb220e3a 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -881,6 +881,7 @@ int l2cap_ertm_init(struct l2cap_chan *chan);
 void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
 void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
 void l2cap_chan_del(struct l2cap_chan *chan, int err);
+void l2cap_conn_update_id_addr(struct hci_conn *hcon);
 void l2cap_send_conn_req(struct l2cap_chan *chan);
 void l2cap_move_start(struct l2cap_chan *chan);
 void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 6e6b3a9c8e6d..d25fefcc0bb5 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -609,6 +609,23 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 	return;
 }
 
+void l2cap_conn_update_id_addr(struct hci_conn *hcon)
+{
+	struct l2cap_conn *conn = hcon->l2cap_data;
+	struct l2cap_chan *chan;
+
+	mutex_lock(&conn->chan_lock);
+
+	list_for_each_entry(chan, &conn->chan_l, list) {
+		l2cap_chan_lock(chan);
+		bacpy(&chan->dst, &hcon->dst);
+		chan->dst_type = hcon->dst_type;
+		l2cap_chan_unlock(chan);
+	}
+
+	mutex_unlock(&conn->chan_lock);
+}
+
 static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
 {
 	struct l2cap_conn *conn = chan->conn;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 4d14ccc7b330..faf04bd4263a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -976,6 +976,8 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 	bacpy(&hcon->dst, &smp->id_addr);
 	hcon->dst_type = smp->id_addr_type;
 
+	l2cap_conn_update_id_addr(hcon);
+
 	smp_distribute_keys(conn, 1);
 
 	return 0;
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 08/10] Bluetooth: Track the LE Identity Address in struct hci_conn
From: johan.hedberg @ 2014-02-18 15:14 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392736479-8808-1-git-send-email-johan.hedberg@gmail.com>

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

Since we want user space to see and use the LE Identity Address whenever
interfacing with the kernel it makes sense to track that instead of the
real address (the two will only be different in the case of an RPA).
This patch adds the necessary updates to when an LE connection gets
established and when receiving the Identity Address from a remote
device.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/hci_event.c | 7 +++++++
 net/bluetooth/smp.c       | 3 +++
 2 files changed, 10 insertions(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d2c6878a9d6a..f31410a071b5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3568,6 +3568,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
+	struct smp_irk *irk;
 
 	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
 
@@ -3600,6 +3601,12 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		}
 	}
 
+	irk = hci_get_irk(hdev, &ev->bdaddr, ev->bdaddr_type);
+	if (irk) {
+		bacpy(&conn->dst, &irk->bdaddr);
+		conn->dst_type = irk->addr_type;
+	}
+
 	if (ev->status) {
 		mgmt_connect_failed(hdev, &conn->dst, conn->type,
 				    conn->dst_type, ev->status);
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 54672c9ab6a5..4d14ccc7b330 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -973,6 +973,9 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 	hci_add_irk(conn->hcon->hdev, &smp->id_addr, smp->id_addr_type,
 		    smp->irk, &rpa);
 
+	bacpy(&hcon->dst, &smp->id_addr);
+	hcon->dst_type = smp->id_addr_type;
+
 	smp_distribute_keys(conn, 1);
 
 	return 0;
-- 
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