aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2011-06-14 12:37:41 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-14 13:54:05 -0400
commit5d3de7df18077a0f508ae2c3e3f1866da65fdffd (patch)
tree7a52c5136964e89c80f1c26595603021ba29e2b9 /net/bluetooth
parent94ac02726cb87dd569bac4536f33e4b696b692eb (diff)
Bluetooth: Add support for SMP timeout
This patch adds support for disconnecting the link when SMP procedure takes more than 30 seconds. SMP begins when either the Pairing Request command is sent or the Pairing Response is received, and it ends when the link is encrypted (or terminated). Vol 3, Part H Section 3.4. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/l2cap_core.c74
-rw-r--r--net/bluetooth/smp.c14
2 files changed, 58 insertions, 30 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 584a4237eb3f..bbbae2e0aa84 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -970,6 +970,45 @@ static void l2cap_info_timeout(unsigned long arg)
970 l2cap_conn_start(conn); 970 l2cap_conn_start(conn);
971} 971}
972 972
973static void l2cap_conn_del(struct hci_conn *hcon, int err)
974{
975 struct l2cap_conn *conn = hcon->l2cap_data;
976 struct l2cap_chan *chan, *l;
977 struct sock *sk;
978
979 if (!conn)
980 return;
981
982 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
983
984 kfree_skb(conn->rx_skb);
985
986 /* Kill channels */
987 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
988 sk = chan->sk;
989 bh_lock_sock(sk);
990 l2cap_chan_del(chan, err);
991 bh_unlock_sock(sk);
992 chan->ops->close(chan->data);
993 }
994
995 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
996 del_timer_sync(&conn->info_timer);
997
998 if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
999 del_timer(&conn->security_timer);
1000
1001 hcon->l2cap_data = NULL;
1002 kfree(conn);
1003}
1004
1005static void security_timeout(unsigned long arg)
1006{
1007 struct l2cap_conn *conn = (void *) arg;
1008
1009 l2cap_conn_del(conn->hcon, ETIMEDOUT);
1010}
1011
973static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) 1012static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
974{ 1013{
975 struct l2cap_conn *conn = hcon->l2cap_data; 1014 struct l2cap_conn *conn = hcon->l2cap_data;
@@ -1001,7 +1040,10 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1001 1040
1002 INIT_LIST_HEAD(&conn->chan_l); 1041 INIT_LIST_HEAD(&conn->chan_l);
1003 1042
1004 if (hcon->type != LE_LINK) 1043 if (hcon->type == LE_LINK)
1044 setup_timer(&conn->security_timer, security_timeout,
1045 (unsigned long) conn);
1046 else
1005 setup_timer(&conn->info_timer, l2cap_info_timeout, 1047 setup_timer(&conn->info_timer, l2cap_info_timeout,
1006 (unsigned long) conn); 1048 (unsigned long) conn);
1007 1049
@@ -1010,35 +1052,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1010 return conn; 1052 return conn;
1011} 1053}
1012 1054
1013static void l2cap_conn_del(struct hci_conn *hcon, int err)
1014{
1015 struct l2cap_conn *conn = hcon->l2cap_data;
1016 struct l2cap_chan *chan, *l;
1017 struct sock *sk;
1018
1019 if (!conn)
1020 return;
1021
1022 BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
1023
1024 kfree_skb(conn->rx_skb);
1025
1026 /* Kill channels */
1027 list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
1028 sk = chan->sk;
1029 bh_lock_sock(sk);
1030 l2cap_chan_del(chan, err);
1031 bh_unlock_sock(sk);
1032 chan->ops->close(chan->data);
1033 }
1034
1035 if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
1036 del_timer_sync(&conn->info_timer);
1037
1038 hcon->l2cap_data = NULL;
1039 kfree(conn);
1040}
1041
1042static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) 1055static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
1043{ 1056{
1044 write_lock_bh(&conn->chan_lock); 1057 write_lock_bh(&conn->chan_lock);
@@ -4182,6 +4195,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
4182 if (chan->scid == L2CAP_CID_LE_DATA) { 4195 if (chan->scid == L2CAP_CID_LE_DATA) {
4183 if (!status && encrypt) { 4196 if (!status && encrypt) {
4184 chan->sec_level = hcon->sec_level; 4197 chan->sec_level = hcon->sec_level;
4198 del_timer(&conn->security_timer);
4185 l2cap_chan_ready(sk); 4199 l2cap_chan_ready(sk);
4186 } 4200 }
4187 4201
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index dfd6891b9c86..39886786eb7f 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -27,6 +27,8 @@
27#include <linux/crypto.h> 27#include <linux/crypto.h>
28#include <crypto/b128ops.h> 28#include <crypto/b128ops.h>
29 29
30#define SMP_TIMEOUT 30000 /* 30 seconds */
31
30static inline void swap128(u8 src[16], u8 dst[16]) 32static inline void swap128(u8 src[16], u8 dst[16])
31{ 33{
32 int i; 34 int i;
@@ -228,6 +230,9 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
228 230
229 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp); 231 smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
230 232
233 mod_timer(&conn->security_timer, jiffies +
234 msecs_to_jiffies(SMP_TIMEOUT));
235
231 return 0; 236 return 0;
232} 237}
233 238
@@ -303,6 +308,9 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
303 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); 308 smp_send_cmd(conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
304 } 309 }
305 310
311 mod_timer(&conn->security_timer, jiffies +
312 msecs_to_jiffies(SMP_TIMEOUT));
313
306 return 0; 314 return 0;
307} 315}
308 316
@@ -382,6 +390,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
382 390
383 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 391 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
384 392
393 mod_timer(&conn->security_timer, jiffies +
394 msecs_to_jiffies(SMP_TIMEOUT));
395
385 set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend); 396 set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
386 397
387 return 0; 398 return 0;
@@ -415,6 +426,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
415 conn->preq[0] = SMP_CMD_PAIRING_REQ; 426 conn->preq[0] = SMP_CMD_PAIRING_REQ;
416 memcpy(&conn->preq[1], &cp, sizeof(cp)); 427 memcpy(&conn->preq[1], &cp, sizeof(cp));
417 428
429 mod_timer(&conn->security_timer, jiffies +
430 msecs_to_jiffies(SMP_TIMEOUT));
431
418 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 432 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
419 } else { 433 } else {
420 struct smp_cmd_security_req cp; 434 struct smp_cmd_security_req cp;