aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-05-02 17:25:01 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-08 15:58:16 -0400
commitab07801d28985090ac38047b5a4d8952a7e1689f (patch)
tree9ae945f55141b32b779c6a5969806725b39c09c3 /net
parent715ec005cd10c5d53109ffe513e4d403644e3e48 (diff)
Bluetooth: create channel timer to replace sk_timer
The new timer does not belong to struct sock, tought it still touch some sock things, but this will be sorted out soon. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap_core.c100
-rw-r--r--net/bluetooth/l2cap_sock.c50
2 files changed, 76 insertions, 74 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index f5e50bf7ace0..fce48f9b85bf 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -208,6 +208,56 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
208 return 0; 208 return 0;
209} 209}
210 210
211static void l2cap_chan_set_timer(struct l2cap_chan *chan, long timeout)
212{
213 BT_DBG("chan %p state %d timeout %ld", chan->sk, chan->sk->sk_state,
214 timeout);
215 if (!mod_timer(&chan->chan_timer, jiffies + timeout))
216 sock_hold(chan->sk);
217}
218
219void l2cap_chan_clear_timer(struct l2cap_chan *chan)
220{
221 BT_DBG("chan %p state %d", chan, chan->sk->sk_state);
222
223 if (timer_pending(&chan->chan_timer) && del_timer(&chan->chan_timer))
224 __sock_put(chan->sk);
225}
226
227static void l2cap_chan_timeout(unsigned long arg)
228{
229 struct l2cap_chan *chan = (struct l2cap_chan *) arg;
230 struct sock *sk = chan->sk;
231 int reason;
232
233 BT_DBG("chan %p state %d", chan, sk->sk_state);
234
235 bh_lock_sock(sk);
236
237 if (sock_owned_by_user(sk)) {
238 /* sk is owned by user. Try again later */
239 l2cap_chan_set_timer(chan, HZ / 5);
240 bh_unlock_sock(sk);
241 sock_put(sk);
242 return;
243 }
244
245 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
246 reason = ECONNREFUSED;
247 else if (sk->sk_state == BT_CONNECT &&
248 chan->sec_level != BT_SECURITY_SDP)
249 reason = ECONNREFUSED;
250 else
251 reason = ETIMEDOUT;
252
253 __l2cap_chan_close(chan, reason);
254
255 bh_unlock_sock(sk);
256
257 l2cap_sock_kill(sk);
258 sock_put(sk);
259}
260
211struct l2cap_chan *l2cap_chan_create(struct sock *sk) 261struct l2cap_chan *l2cap_chan_create(struct sock *sk)
212{ 262{
213 struct l2cap_chan *chan; 263 struct l2cap_chan *chan;
@@ -222,6 +272,8 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk)
222 list_add(&chan->global_l, &chan_list); 272 list_add(&chan->global_l, &chan_list);
223 write_unlock_bh(&chan_list_lock); 273 write_unlock_bh(&chan_list_lock);
224 274
275 setup_timer(&chan->chan_timer, l2cap_chan_timeout, (unsigned long) chan);
276
225 return chan; 277 return chan;
226} 278}
227 279
@@ -281,7 +333,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
281 struct l2cap_conn *conn = chan->conn; 333 struct l2cap_conn *conn = chan->conn;
282 struct sock *parent = bt_sk(sk)->parent; 334 struct sock *parent = bt_sk(sk)->parent;
283 335
284 l2cap_sock_clear_timer(sk); 336 l2cap_chan_clear_timer(chan);
285 337
286 BT_DBG("chan %p, conn %p, err %d", chan, conn, err); 338 BT_DBG("chan %p, conn %p, err %d", chan, conn, err);
287 339
@@ -334,7 +386,7 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
334/* Must be called on unlocked socket. */ 386/* Must be called on unlocked socket. */
335static void l2cap_chan_close(struct sock *sk) 387static void l2cap_chan_close(struct sock *sk)
336{ 388{
337 l2cap_sock_clear_timer(sk); 389 l2cap_chan_clear_timer(l2cap_pi(sk)->chan);
338 lock_sock(sk); 390 lock_sock(sk);
339 __l2cap_chan_close(l2cap_pi(sk)->chan, ECONNRESET); 391 __l2cap_chan_close(l2cap_pi(sk)->chan, ECONNRESET);
340 release_sock(sk); 392 release_sock(sk);
@@ -371,7 +423,7 @@ void __l2cap_chan_close(struct l2cap_chan *chan, int reason)
371 case BT_CONFIG: 423 case BT_CONFIG:
372 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && 424 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
373 conn->hcon->type == ACL_LINK) { 425 conn->hcon->type == ACL_LINK) {
374 l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 426 l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
375 l2cap_send_disconn_req(conn, chan, reason); 427 l2cap_send_disconn_req(conn, chan, reason);
376 } else 428 } else
377 l2cap_chan_del(chan, reason); 429 l2cap_chan_del(chan, reason);
@@ -814,7 +866,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
814 866
815 __l2cap_chan_add(conn, chan); 867 __l2cap_chan_add(conn, chan);
816 868
817 l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 869 l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
818 870
819 sk->sk_state = BT_CONNECTED; 871 sk->sk_state = BT_CONNECTED;
820 parent->sk_data_ready(parent, 0); 872 parent->sk_data_ready(parent, 0);
@@ -842,13 +894,13 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
842 bh_lock_sock(sk); 894 bh_lock_sock(sk);
843 895
844 if (conn->hcon->type == LE_LINK) { 896 if (conn->hcon->type == LE_LINK) {
845 l2cap_sock_clear_timer(sk); 897 l2cap_chan_clear_timer(chan);
846 sk->sk_state = BT_CONNECTED; 898 sk->sk_state = BT_CONNECTED;
847 sk->sk_state_change(sk); 899 sk->sk_state_change(sk);
848 } 900 }
849 901
850 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { 902 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
851 l2cap_sock_clear_timer(sk); 903 l2cap_chan_clear_timer(chan);
852 sk->sk_state = BT_CONNECTED; 904 sk->sk_state = BT_CONNECTED;
853 sk->sk_state_change(sk); 905 sk->sk_state_change(sk);
854 } else if (sk->sk_state == BT_CONNECT) 906 } else if (sk->sk_state == BT_CONNECT)
@@ -1047,11 +1099,11 @@ int l2cap_chan_connect(struct l2cap_chan *chan)
1047 l2cap_chan_add(conn, chan); 1099 l2cap_chan_add(conn, chan);
1048 1100
1049 sk->sk_state = BT_CONNECT; 1101 sk->sk_state = BT_CONNECT;
1050 l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 1102 l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
1051 1103
1052 if (hcon->state == BT_CONNECTED) { 1104 if (hcon->state == BT_CONNECTED) {
1053 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { 1105 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
1054 l2cap_sock_clear_timer(sk); 1106 l2cap_chan_clear_timer(chan);
1055 if (l2cap_check_security(chan)) 1107 if (l2cap_check_security(chan))
1056 sk->sk_state = BT_CONNECTED; 1108 sk->sk_state = BT_CONNECTED;
1057 } else 1109 } else
@@ -1615,7 +1667,7 @@ static void l2cap_chan_ready(struct sock *sk)
1615 BT_DBG("sk %p, parent %p", sk, parent); 1667 BT_DBG("sk %p, parent %p", sk, parent);
1616 1668
1617 chan->conf_state = 0; 1669 chan->conf_state = 0;
1618 l2cap_sock_clear_timer(sk); 1670 l2cap_chan_clear_timer(chan);
1619 1671
1620 if (!parent) { 1672 if (!parent) {
1621 /* Outgoing channel. 1673 /* Outgoing channel.
@@ -2317,7 +2369,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
2317 2369
2318 dcid = chan->scid; 2370 dcid = chan->scid;
2319 2371
2320 l2cap_sock_set_timer(sk, sk->sk_sndtimeo); 2372 l2cap_chan_set_timer(chan, sk->sk_sndtimeo);
2321 2373
2322 chan->ident = cmd->ident; 2374 chan->ident = cmd->ident;
2323 2375
@@ -2434,8 +2486,8 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
2434 /* don't delete l2cap channel if sk is owned by user */ 2486 /* don't delete l2cap channel if sk is owned by user */
2435 if (sock_owned_by_user(sk)) { 2487 if (sock_owned_by_user(sk)) {
2436 sk->sk_state = BT_DISCONN; 2488 sk->sk_state = BT_DISCONN;
2437 l2cap_sock_clear_timer(sk); 2489 l2cap_chan_clear_timer(chan);
2438 l2cap_sock_set_timer(sk, HZ / 5); 2490 l2cap_chan_set_timer(chan, HZ / 5);
2439 break; 2491 break;
2440 } 2492 }
2441 2493
@@ -2608,7 +2660,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
2608 2660
2609 default: 2661 default:
2610 sk->sk_err = ECONNRESET; 2662 sk->sk_err = ECONNRESET;
2611 l2cap_sock_set_timer(sk, HZ * 5); 2663 l2cap_chan_set_timer(chan, HZ * 5);
2612 l2cap_send_disconn_req(conn, chan, ECONNRESET); 2664 l2cap_send_disconn_req(conn, chan, ECONNRESET);
2613 goto done; 2665 goto done;
2614 } 2666 }
@@ -2664,8 +2716,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
2664 /* don't delete l2cap channel if sk is owned by user */ 2716 /* don't delete l2cap channel if sk is owned by user */
2665 if (sock_owned_by_user(sk)) { 2717 if (sock_owned_by_user(sk)) {
2666 sk->sk_state = BT_DISCONN; 2718 sk->sk_state = BT_DISCONN;
2667 l2cap_sock_clear_timer(sk); 2719 l2cap_chan_clear_timer(chan);
2668 l2cap_sock_set_timer(sk, HZ / 5); 2720 l2cap_chan_set_timer(chan, HZ / 5);
2669 bh_unlock_sock(sk); 2721 bh_unlock_sock(sk);
2670 return 0; 2722 return 0;
2671 } 2723 }
@@ -2698,8 +2750,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
2698 /* don't delete l2cap channel if sk is owned by user */ 2750 /* don't delete l2cap channel if sk is owned by user */
2699 if (sock_owned_by_user(sk)) { 2751 if (sock_owned_by_user(sk)) {
2700 sk->sk_state = BT_DISCONN; 2752 sk->sk_state = BT_DISCONN;
2701 l2cap_sock_clear_timer(sk); 2753 l2cap_chan_clear_timer(chan);
2702 l2cap_sock_set_timer(sk, HZ / 5); 2754 l2cap_chan_set_timer(chan, HZ / 5);
2703 bh_unlock_sock(sk); 2755 bh_unlock_sock(sk);
2704 return 0; 2756 return 0;
2705 } 2757 }
@@ -4090,20 +4142,18 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
4090 4142
4091static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) 4143static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
4092{ 4144{
4093 struct sock *sk = chan->sk;
4094
4095 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) 4145 if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
4096 return; 4146 return;
4097 4147
4098 if (encrypt == 0x00) { 4148 if (encrypt == 0x00) {
4099 if (chan->sec_level == BT_SECURITY_MEDIUM) { 4149 if (chan->sec_level == BT_SECURITY_MEDIUM) {
4100 l2cap_sock_clear_timer(sk); 4150 l2cap_chan_clear_timer(chan);
4101 l2cap_sock_set_timer(sk, HZ * 5); 4151 l2cap_chan_set_timer(chan, HZ * 5);
4102 } else if (chan->sec_level == BT_SECURITY_HIGH) 4152 } else if (chan->sec_level == BT_SECURITY_HIGH)
4103 __l2cap_chan_close(chan, ECONNREFUSED); 4153 __l2cap_chan_close(chan, ECONNREFUSED);
4104 } else { 4154 } else {
4105 if (chan->sec_level == BT_SECURITY_MEDIUM) 4155 if (chan->sec_level == BT_SECURITY_MEDIUM)
4106 l2cap_sock_clear_timer(sk); 4156 l2cap_chan_clear_timer(chan);
4107 } 4157 }
4108} 4158}
4109 4159
@@ -4148,8 +4198,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
4148 l2cap_send_cmd(conn, chan->ident, 4198 l2cap_send_cmd(conn, chan->ident,
4149 L2CAP_CONN_REQ, sizeof(req), &req); 4199 L2CAP_CONN_REQ, sizeof(req), &req);
4150 } else { 4200 } else {
4151 l2cap_sock_clear_timer(sk); 4201 l2cap_chan_clear_timer(chan);
4152 l2cap_sock_set_timer(sk, HZ / 10); 4202 l2cap_chan_set_timer(chan, HZ / 10);
4153 } 4203 }
4154 } else if (sk->sk_state == BT_CONNECT2) { 4204 } else if (sk->sk_state == BT_CONNECT2) {
4155 struct l2cap_conn_rsp rsp; 4205 struct l2cap_conn_rsp rsp;
@@ -4160,7 +4210,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
4160 result = L2CAP_CR_SUCCESS; 4210 result = L2CAP_CR_SUCCESS;
4161 } else { 4211 } else {
4162 sk->sk_state = BT_DISCONN; 4212 sk->sk_state = BT_DISCONN;
4163 l2cap_sock_set_timer(sk, HZ / 10); 4213 l2cap_chan_set_timer(chan, HZ / 10);
4164 result = L2CAP_CR_SEC_BLOCK; 4214 result = L2CAP_CR_SEC_BLOCK;
4165 } 4215 }
4166 4216
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 2fcdf5eacb4d..89433a439bd8 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -32,52 +32,6 @@
32 32
33static const struct proto_ops l2cap_sock_ops; 33static const struct proto_ops l2cap_sock_ops;
34 34
35/* ---- L2CAP timers ---- */
36static void l2cap_sock_timeout(unsigned long arg)
37{
38 struct sock *sk = (struct sock *) arg;
39 int reason;
40
41 BT_DBG("sock %p state %d", sk, sk->sk_state);
42
43 bh_lock_sock(sk);
44
45 if (sock_owned_by_user(sk)) {
46 /* sk is owned by user. Try again later */
47 l2cap_sock_set_timer(sk, HZ / 5);
48 bh_unlock_sock(sk);
49 sock_put(sk);
50 return;
51 }
52
53 if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG)
54 reason = ECONNREFUSED;
55 else if (sk->sk_state == BT_CONNECT &&
56 l2cap_pi(sk)->chan->sec_level != BT_SECURITY_SDP)
57 reason = ECONNREFUSED;
58 else
59 reason = ETIMEDOUT;
60
61 __l2cap_chan_close(l2cap_pi(sk)->chan, reason);
62
63 bh_unlock_sock(sk);
64
65 l2cap_sock_kill(sk);
66 sock_put(sk);
67}
68
69void l2cap_sock_set_timer(struct sock *sk, long timeout)
70{
71 BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
72 sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
73}
74
75void l2cap_sock_clear_timer(struct sock *sk)
76{
77 BT_DBG("sock %p state %d", sk, sk->sk_state);
78 sk_stop_timer(sk, &sk->sk_timer);
79}
80
81static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) 35static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
82{ 36{
83 struct sock *sk = sock->sk; 37 struct sock *sk = sock->sk;
@@ -753,7 +707,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
753 err = __l2cap_wait_ack(sk); 707 err = __l2cap_wait_ack(sk);
754 708
755 sk->sk_shutdown = SHUTDOWN_MASK; 709 sk->sk_shutdown = SHUTDOWN_MASK;
756 l2cap_sock_clear_timer(sk); 710 l2cap_chan_clear_timer(chan);
757 __l2cap_chan_close(chan, 0); 711 __l2cap_chan_close(chan, 0);
758 712
759 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) 713 if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
@@ -879,8 +833,6 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, g
879 sk->sk_protocol = proto; 833 sk->sk_protocol = proto;
880 sk->sk_state = BT_OPEN; 834 sk->sk_state = BT_OPEN;
881 835
882 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
883
884 return sk; 836 return sk;
885} 837}
886 838