diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 74 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 14 |
2 files changed, 58 insertions, 30 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 584a4237eb3..bbbae2e0aa8 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 | ||
973 | static 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 | |||
1005 | static void security_timeout(unsigned long arg) | ||
1006 | { | ||
1007 | struct l2cap_conn *conn = (void *) arg; | ||
1008 | |||
1009 | l2cap_conn_del(conn->hcon, ETIMEDOUT); | ||
1010 | } | ||
1011 | |||
973 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | 1012 | static 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 | ||
1013 | static 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 | |||
1042 | static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 1055 | static 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 dfd6891b9c8..39886786eb7 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 | |||
30 | static inline void swap128(u8 src[16], u8 dst[16]) | 32 | static 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; |