All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Bluetooth: SMP and some other fixes
@ 2014-09-11  0:37 johan.hedberg
  2014-09-11  0:37 ` [PATCH 1/6] Bluetooth: Remove unnecessary early initialization of variable johan.hedberg
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: johan.hedberg @ 2014-09-11  0:37 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

The first five patches from this set are various fixes to SMP. The sixth
one is a fix for properly notifying BR/EDR fixed channels, including on
setups when there are no registered connection-oriented BR/EDR channels.

Johan

----------------------------------------------------------------
Johan Hedberg (6):
      Bluetooth: Remove unnecessary early initialization of variable
      Bluetooth: Fix ignoring unknown SMP authentication requirement bits
      Bluetooth: Centralize disallowing SMP commands to a single place
      Bluetooth: Fix SMP security level when we have no IO capabilities
      Bluetooth: Add smp_ltk_sec_level() helper function
      Bluetooth: Fix L2CAP information request handling for fixed channels

 net/bluetooth/hci_event.c  |  5 +---
 net/bluetooth/l2cap_core.c | 53 +++++++++++++++++++++++++---------------
 net/bluetooth/smp.c        | 55 ++++++++++++++++++------------------------
 net/bluetooth/smp.h        |  8 ++++++
 4 files changed, 66 insertions(+), 55 deletions(-)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/6] Bluetooth: Remove unnecessary early initialization of variable
  2014-09-11  0:37 [PATCH 0/6] Bluetooth: SMP and some other fixes johan.hedberg
@ 2014-09-11  0:37 ` johan.hedberg
  2014-09-11  0:37 ` [PATCH 2/6] Bluetooth: Fix ignoring unknown SMP authentication requirement bits johan.hedberg
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: johan.hedberg @ 2014-09-11  0:37 UTC (permalink / raw)
  To: linux-bluetooth

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

We do nothing else with the auth variable in smp_cmd_pairing_rsp()
besides passing it to tk_request() which in turn only cares about
whether one of the sides had the MITM bit set. It is therefore
unnecessary to assign a value to it until just before calling
tk_request(), and this value can simply be the bit-wise or of the local
and remote requirements.

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

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index dc575aba2e65..dbd17a07dc2e 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1003,7 +1003,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
 	struct l2cap_chan *chan = conn->smp;
 	struct smp_chan *smp = chan->data;
-	u8 key_size, auth = SMP_AUTH_NONE;
+	u8 key_size, auth;
 	int ret;
 
 	BT_DBG("conn %p", conn);
@@ -1044,11 +1044,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	 */
 	smp->remote_key_dist &= rsp->resp_key_dist;
 
-	if ((req->auth_req & SMP_AUTH_BONDING) &&
-	    (rsp->auth_req & SMP_AUTH_BONDING))
-		auth = SMP_AUTH_BONDING;
-
-	auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM;
+	auth = (req->auth_req | rsp->auth_req);
 
 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
 	if (ret)
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/6] Bluetooth: Fix ignoring unknown SMP authentication requirement bits
  2014-09-11  0:37 [PATCH 0/6] Bluetooth: SMP and some other fixes johan.hedberg
  2014-09-11  0:37 ` [PATCH 1/6] Bluetooth: Remove unnecessary early initialization of variable johan.hedberg
@ 2014-09-11  0:37 ` johan.hedberg
  2014-09-11  0:37 ` [PATCH 3/6] Bluetooth: Centralize disallowing SMP commands to a single place johan.hedberg
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: johan.hedberg @ 2014-09-11  0:37 UTC (permalink / raw)
  To: linux-bluetooth

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

The SMP specification states that we should ignore any unknown bits from
the authentication requirement. We already have a define for masking out
unknown bits but we haven't used it in all places so far. This patch
adds usage of the AUTH_REQ_MASK to all places that need it and ensures
that we don't pass unknown bits onward to other functions.

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

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index dbd17a07dc2e..ef8f96d2c059 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -949,8 +949,11 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (!smp)
 		return SMP_UNSPECIFIED;
 
+	/* We didn't start the pairing, so match remote */
+	auth = req->auth_req & AUTH_REQ_MASK;
+
 	if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) &&
-	    (req->auth_req & SMP_AUTH_BONDING))
+	    (auth & SMP_AUTH_BONDING))
 		return SMP_PAIRING_NOTSUPP;
 
 	SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
@@ -959,9 +962,6 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&smp->preq[1], req, sizeof(*req));
 	skb_pull(skb, sizeof(*req));
 
-	/* We didn't start the pairing, so match remote */
-	auth = req->auth_req;
-
 	sec_level = authreq_to_seclevel(auth);
 	if (sec_level > conn->hcon->pending_sec_level)
 		conn->hcon->pending_sec_level = sec_level;
@@ -1024,6 +1024,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (check_enc_key_size(conn, key_size))
 		return SMP_ENC_KEY_SIZE;
 
+	auth = rsp->auth_req & AUTH_REQ_MASK;
+
 	/* If we need MITM check that it can be acheived */
 	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) {
 		u8 method;
@@ -1044,7 +1046,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	 */
 	smp->remote_key_dist &= rsp->resp_key_dist;
 
-	auth = (req->auth_req | rsp->auth_req);
+	auth |= req->auth_req;
 
 	ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability);
 	if (ret)
@@ -1160,7 +1162,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	struct smp_cmd_pairing cp;
 	struct hci_conn *hcon = conn->hcon;
 	struct smp_chan *smp;
-	u8 sec_level;
+	u8 sec_level, auth;
 
 	BT_DBG("conn %p", conn);
 
@@ -1170,7 +1172,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (hcon->role != HCI_ROLE_MASTER)
 		return SMP_CMD_NOTSUPP;
 
-	sec_level = authreq_to_seclevel(rp->auth_req);
+	auth = rp->auth_req & AUTH_REQ_MASK;
+
+	sec_level = authreq_to_seclevel(auth);
 	if (smp_sufficient_security(hcon, sec_level))
 		return 0;
 
@@ -1185,13 +1189,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 		return SMP_UNSPECIFIED;
 
 	if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) &&
-	    (rp->auth_req & SMP_AUTH_BONDING))
+	    (auth & SMP_AUTH_BONDING))
 		return SMP_PAIRING_NOTSUPP;
 
 	skb_pull(skb, sizeof(*rp));
 
 	memset(&cp, 0, sizeof(cp));
-	build_pairing_cmd(conn, &cp, NULL, rp->auth_req);
+	build_pairing_cmd(conn, &cp, NULL, auth);
 
 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
 	memcpy(&smp->preq[1], &cp, sizeof(cp));
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/6] Bluetooth: Centralize disallowing SMP commands to a single place
  2014-09-11  0:37 [PATCH 0/6] Bluetooth: SMP and some other fixes johan.hedberg
  2014-09-11  0:37 ` [PATCH 1/6] Bluetooth: Remove unnecessary early initialization of variable johan.hedberg
  2014-09-11  0:37 ` [PATCH 2/6] Bluetooth: Fix ignoring unknown SMP authentication requirement bits johan.hedberg
@ 2014-09-11  0:37 ` johan.hedberg
  2014-09-11  0:37 ` [PATCH 4/6] Bluetooth: Fix SMP security level when we have no IO capabilities johan.hedberg
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: johan.hedberg @ 2014-09-11  0:37 UTC (permalink / raw)
  To: linux-bluetooth

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

All the cases where we mark SMP commands as dissalowed are their
respective command handlers. We can therefore simplify the code by
always clearing the bit immediately after testing it. This patch
converts the corresponding test_bit() call to a test_and_clear_bit()
call and also removes the now unused SMP_DISALLOW_CMD macro.

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

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index ef8f96d2c059..be8371b4eb63 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -32,7 +32,6 @@
 #include "smp.h"
 
 #define SMP_ALLOW_CMD(smp, code)	set_bit(code, &smp->allow_cmd)
-#define SMP_DISALLOW_CMD(smp, code)	clear_bit(code, &smp->allow_cmd)
 
 #define SMP_TIMEOUT	msecs_to_jiffies(30000)
 
@@ -956,8 +955,6 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	    (auth & SMP_AUTH_BONDING))
 		return SMP_PAIRING_NOTSUPP;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
-
 	smp->preq[0] = SMP_CMD_PAIRING_REQ;
 	memcpy(&smp->preq[1], req, sizeof(*req));
 	skb_pull(skb, sizeof(*req));
@@ -1014,8 +1011,6 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (conn->hcon->role != HCI_ROLE_MASTER)
 		return SMP_CMD_NOTSUPP;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
-
 	skb_pull(skb, sizeof(*rsp));
 
 	req = (void *) &smp->preq[1];
@@ -1071,8 +1066,6 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(smp->pcnf))
 		return SMP_INVALID_PARAMS;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
-
 	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
 	skb_pull(skb, sizeof(smp->pcnf));
 
@@ -1101,8 +1094,6 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(smp->rrnd))
 		return SMP_INVALID_PARAMS;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
-
 	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
 	skb_pull(skb, sizeof(smp->rrnd));
 
@@ -1293,7 +1284,6 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(*rp))
 		return SMP_INVALID_PARAMS;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
 	SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
 
 	skb_pull(skb, sizeof(*rp));
@@ -1321,7 +1311,6 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 	/* Mark the information as received */
 	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
 	if (smp->remote_key_dist & SMP_DIST_ID_KEY)
 		SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
 	else if (smp->remote_key_dist & SMP_DIST_SIGN)
@@ -1353,7 +1342,6 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(*info))
 		return SMP_INVALID_PARAMS;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
 	SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
 
 	skb_pull(skb, sizeof(*info));
@@ -1380,7 +1368,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 	/* Mark the information as received */
 	smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
 	if (smp->remote_key_dist & SMP_DIST_SIGN)
 		SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
 
@@ -1436,8 +1423,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
 	/* Mark the information as received */
 	smp->remote_key_dist &= ~SMP_DIST_SIGN;
 
-	SMP_DISALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
-
 	skb_pull(skb, sizeof(*rp));
 
 	hci_dev_lock(hdev);
@@ -1482,7 +1467,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
 	if (code > SMP_CMD_MAX)
 		goto drop;
 
-	if (smp && !test_bit(code, &smp->allow_cmd))
+	if (smp && !test_and_clear_bit(code, &smp->allow_cmd))
 		goto drop;
 
 	/* If we don't have a context the only allowed commands are
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/6] Bluetooth: Fix SMP security level when we have no IO capabilities
  2014-09-11  0:37 [PATCH 0/6] Bluetooth: SMP and some other fixes johan.hedberg
                   ` (2 preceding siblings ...)
  2014-09-11  0:37 ` [PATCH 3/6] Bluetooth: Centralize disallowing SMP commands to a single place johan.hedberg
@ 2014-09-11  0:37 ` johan.hedberg
  2014-09-11  0:37 ` [PATCH 5/6] Bluetooth: Add smp_ltk_sec_level() helper function johan.hedberg
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: johan.hedberg @ 2014-09-11  0:37 UTC (permalink / raw)
  To: linux-bluetooth

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

When the local IO capability is NoInputNoOutput any attempt to convert
the remote authentication requirement to a target security level is
futile. This patch makes sure that we set the target security level at
most to MEDIUM if the local IO capability is NoInputNoOutput.

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

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index be8371b4eb63..a08b077cb725 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -959,7 +959,11 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 	memcpy(&smp->preq[1], req, sizeof(*req));
 	skb_pull(skb, sizeof(*req));
 
-	sec_level = authreq_to_seclevel(auth);
+	if (conn->hcon->io_capability == 0x03)
+		sec_level = BT_SECURITY_MEDIUM;
+	else
+		sec_level = authreq_to_seclevel(auth);
+
 	if (sec_level > conn->hcon->pending_sec_level)
 		conn->hcon->pending_sec_level = sec_level;
 
@@ -1165,7 +1169,11 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	auth = rp->auth_req & AUTH_REQ_MASK;
 
-	sec_level = authreq_to_seclevel(auth);
+	if (hcon->io_capability == 0x03)
+		sec_level = BT_SECURITY_MEDIUM;
+	else
+		sec_level = authreq_to_seclevel(auth);
+
 	if (smp_sufficient_security(hcon, sec_level))
 		return 0;
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/6] Bluetooth: Add smp_ltk_sec_level() helper function
  2014-09-11  0:37 [PATCH 0/6] Bluetooth: SMP and some other fixes johan.hedberg
                   ` (3 preceding siblings ...)
  2014-09-11  0:37 ` [PATCH 4/6] Bluetooth: Fix SMP security level when we have no IO capabilities johan.hedberg
@ 2014-09-11  0:37 ` johan.hedberg
  2014-09-11  0:37 ` [PATCH 6/6] Bluetooth: Fix L2CAP information request handling for fixed channels johan.hedberg
  2014-09-11  0:47 ` [PATCH 0/6] Bluetooth: SMP and some other fixes Marcel Holtmann
  6 siblings, 0 replies; 8+ messages in thread
From: johan.hedberg @ 2014-09-11  0:37 UTC (permalink / raw)
  To: linux-bluetooth

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

There are several places that need to determine the security level that
an LTK can provide. This patch adds a convenience function for this to
help make the code more readable.

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

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3a8381ab992f..603a17cc52ac 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -4506,10 +4506,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
 	cp.handle = cpu_to_le16(conn->handle);
 
-	if (ltk->authenticated)
-		conn->pending_sec_level = BT_SECURITY_HIGH;
-	else
-		conn->pending_sec_level = BT_SECURITY_MEDIUM;
+	conn->pending_sec_level = smp_ltk_sec_level(ltk);
 
 	conn->enc_key_size = ltk->enc_size;
 
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index a08b077cb725..3700dd8d9d0b 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1114,7 +1114,7 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
 	if (!key)
 		return false;
 
-	if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated)
+	if (smp_ltk_sec_level(key) < sec_level)
 		return false;
 
 	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 5240537efde3..86a683a8b491 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -125,6 +125,14 @@ enum {
 	SMP_LTK_SLAVE,
 };
 
+static inline u8 smp_ltk_sec_level(struct smp_ltk *key)
+{
+	if (key->authenticated)
+		return BT_SECURITY_HIGH;
+
+	return BT_SECURITY_MEDIUM;
+}
+
 /* SMP Commands */
 bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level);
 int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/6] Bluetooth: Fix L2CAP information request handling for fixed channels
  2014-09-11  0:37 [PATCH 0/6] Bluetooth: SMP and some other fixes johan.hedberg
                   ` (4 preceding siblings ...)
  2014-09-11  0:37 ` [PATCH 5/6] Bluetooth: Add smp_ltk_sec_level() helper function johan.hedberg
@ 2014-09-11  0:37 ` johan.hedberg
  2014-09-11  0:47 ` [PATCH 0/6] Bluetooth: SMP and some other fixes Marcel Holtmann
  6 siblings, 0 replies; 8+ messages in thread
From: johan.hedberg @ 2014-09-11  0:37 UTC (permalink / raw)
  To: linux-bluetooth

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

Even if we have no connection-oriented channels we should perform the
L2CAP Information Request procedures before notifying L2CAP channels of
the connection. This is so that the L2CAP channel implementations can
perform checks on what the remote side supports (e.g. does it support
the fixed channel in question).

So far the code has relied on the l2cap_do_start() function to initiate
the Information Request, however l2cap_do_start() is used on a
per-channel basis and only for connection-oriented channels. This means
that if there are no connection-oriented channels on the system we would
never start the Information Request procedure.

This patch creates a new l2cap_request_info() helper function to
initiate the Information Request procedure, and ensures that it is
called whenever a BR/EDR connection has been established. The patch also
updates fixed channels to be notified of connection readiness only once
the Information Request procedure has completed.

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

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b71430caab4a..8d53fc57faba 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1283,6 +1283,24 @@ static void l2cap_start_connection(struct l2cap_chan *chan)
 	}
 }
 
+static void l2cap_request_info(struct l2cap_conn *conn)
+{
+	struct l2cap_info_req req;
+
+	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
+		return;
+
+	req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+
+	conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
+	conn->info_ident = l2cap_get_ident(conn);
+
+	schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
+
+	l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
+		       sizeof(req), &req);
+}
+
 static void l2cap_do_start(struct l2cap_chan *chan)
 {
 	struct l2cap_conn *conn = chan->conn;
@@ -1292,26 +1310,17 @@ static void l2cap_do_start(struct l2cap_chan *chan)
 		return;
 	}
 
-	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
-		if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
-			return;
-
-		if (l2cap_chan_check_security(chan, true) &&
-		    __l2cap_no_conn_pending(chan)) {
-			l2cap_start_connection(chan);
-		}
-	} else {
-		struct l2cap_info_req req;
-		req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
-
-		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
-		conn->info_ident = l2cap_get_ident(conn);
+	if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) {
+		l2cap_request_info(conn);
+		return;
+	}
 
-		schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
+	if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
+		return;
 
-		l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
-			       sizeof(req), &req);
-	}
+	if (l2cap_chan_check_security(chan, true) &&
+	    __l2cap_no_conn_pending(chan))
+		l2cap_start_connection(chan);
 }
 
 static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
@@ -1370,6 +1379,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 		l2cap_chan_lock(chan);
 
 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
+			l2cap_chan_ready(chan);
 			l2cap_chan_unlock(chan);
 			continue;
 		}
@@ -1474,6 +1484,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 
 	BT_DBG("conn %p", conn);
 
+	if (hcon->type == ACL_LINK)
+		l2cap_request_info(conn);
+
 	mutex_lock(&conn->chan_lock);
 
 	list_for_each_entry(chan, &conn->chan_l, list) {
@@ -1488,8 +1501,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 		if (hcon->type == LE_LINK) {
 			l2cap_le_start(chan);
 		} else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
-			l2cap_chan_ready(chan);
-
+			if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
+				l2cap_chan_ready(chan);
 		} else if (chan->state == BT_CONNECT) {
 			l2cap_do_start(chan);
 		}
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/6] Bluetooth: SMP and some other fixes
  2014-09-11  0:37 [PATCH 0/6] Bluetooth: SMP and some other fixes johan.hedberg
                   ` (5 preceding siblings ...)
  2014-09-11  0:37 ` [PATCH 6/6] Bluetooth: Fix L2CAP information request handling for fixed channels johan.hedberg
@ 2014-09-11  0:47 ` Marcel Holtmann
  6 siblings, 0 replies; 8+ messages in thread
From: Marcel Holtmann @ 2014-09-11  0:47 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth

Hi Johan,

> The first five patches from this set are various fixes to SMP. The sixth
> one is a fix for properly notifying BR/EDR fixed channels, including on
> setups when there are no registered connection-oriented BR/EDR channels.
> 
> Johan
> 
> ----------------------------------------------------------------
> Johan Hedberg (6):
>      Bluetooth: Remove unnecessary early initialization of variable
>      Bluetooth: Fix ignoring unknown SMP authentication requirement bits
>      Bluetooth: Centralize disallowing SMP commands to a single place
>      Bluetooth: Fix SMP security level when we have no IO capabilities
>      Bluetooth: Add smp_ltk_sec_level() helper function
>      Bluetooth: Fix L2CAP information request handling for fixed channels
> 
> net/bluetooth/hci_event.c  |  5 +---
> net/bluetooth/l2cap_core.c | 53 +++++++++++++++++++++++++---------------
> net/bluetooth/smp.c        | 55 ++++++++++++++++++------------------------
> net/bluetooth/smp.h        |  8 ++++++
> 4 files changed, 66 insertions(+), 55 deletions(-)

all 6 patches have been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-09-11  0:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-11  0:37 [PATCH 0/6] Bluetooth: SMP and some other fixes johan.hedberg
2014-09-11  0:37 ` [PATCH 1/6] Bluetooth: Remove unnecessary early initialization of variable johan.hedberg
2014-09-11  0:37 ` [PATCH 2/6] Bluetooth: Fix ignoring unknown SMP authentication requirement bits johan.hedberg
2014-09-11  0:37 ` [PATCH 3/6] Bluetooth: Centralize disallowing SMP commands to a single place johan.hedberg
2014-09-11  0:37 ` [PATCH 4/6] Bluetooth: Fix SMP security level when we have no IO capabilities johan.hedberg
2014-09-11  0:37 ` [PATCH 5/6] Bluetooth: Add smp_ltk_sec_level() helper function johan.hedberg
2014-09-11  0:37 ` [PATCH 6/6] Bluetooth: Fix L2CAP information request handling for fixed channels johan.hedberg
2014-09-11  0:47 ` [PATCH 0/6] Bluetooth: SMP and some other fixes Marcel Holtmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.