From f1cb9af557dd8fb5d98fbcc4b5d3eb9d6d235af7 Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Wed, 26 Jan 2011 21:42:57 -0300 Subject: Bluetooth: Add support for resuming socket when SMP is finished This adds support for resuming the user space traffic when SMP negotiation is complete. Signed-off-by: Vinicius Costa Gomes Signed-off-by: Gustavo F. Padovan --- net/bluetooth/smp.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'net/bluetooth/smp.c') diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 6983979..da46d76 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -336,9 +336,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_security_req *rp = (void *) skb->data; struct smp_cmd_pairing cp; + struct hci_conn *hcon = conn->hcon; BT_DBG("conn %p", conn); + if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) + return; + skb_pull(skb, sizeof(*rp)); memset(&cp, 0, sizeof(cp)); @@ -353,6 +357,20 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) memcpy(&conn->preq[1], &cp, sizeof(cp)); smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); + + set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend); +} + +static __u8 seclevel_to_authreq(__u8 level) +{ + switch (level) { + case BT_SECURITY_HIGH: + /* For now we don't support bonding */ + return SMP_AUTH_MITM; + + default: + return SMP_AUTH_NONE; + } } int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) @@ -365,21 +383,16 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) if (IS_ERR(hcon->hdev->tfm)) return 1; - switch (sec_level) { - case BT_SECURITY_MEDIUM: - /* Encrypted, no MITM protection */ - authreq = HCI_AT_NO_BONDING_MITM; - break; + if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) + return 0; - case BT_SECURITY_HIGH: - /* Bonding, MITM protection */ - authreq = HCI_AT_GENERAL_BONDING_MITM; - break; + if (sec_level == BT_SECURITY_LOW) + return 1; - case BT_SECURITY_LOW: - default: + if (hcon->sec_level >= sec_level) return 1; - } + + authreq = seclevel_to_authreq(sec_level); if (hcon->link_mode & HCI_LM_MASTER) { struct smp_cmd_pairing cp; @@ -400,6 +413,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); } + hcon->pending_sec_level = sec_level; + set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend); + return 0; } -- cgit v1.1