diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-04-28 16:55:53 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-06-08 15:58:16 -0400 |
commit | 4519de9a0478d8de438f8b80ab2e94668ef63ab4 (patch) | |
tree | 50c7ef0a0a4b2592306c1ba3c45b25fc6be5c1ea /net | |
parent | 37e1c55de7b1edd3fb8fc3411ad0c32a213723d0 (diff) |
Bluetooth: Create __l2cap_chan_close()
This is actually __l2cap_sock_close() renamed to __l2cap_chan_close().
At a first look it may not make sense, but with the further cleanups that
will come it will.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 97 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 85 |
2 files changed, 93 insertions, 89 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index af1bc3085c44..14c760c8ffe7 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -69,7 +69,11 @@ static void l2cap_busy_work(struct work_struct *work); | |||
69 | 69 | ||
70 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 70 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
71 | u8 code, u8 ident, u16 dlen, void *data); | 71 | u8 code, u8 ident, u16 dlen, void *data); |
72 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, | ||
73 | void *data); | ||
72 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); | 74 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); |
75 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, | ||
76 | struct l2cap_chan *chan, int err); | ||
73 | 77 | ||
74 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); | 78 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); |
75 | 79 | ||
@@ -271,7 +275,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
271 | 275 | ||
272 | /* Delete channel. | 276 | /* Delete channel. |
273 | * Must be called on the locked socket. */ | 277 | * Must be called on the locked socket. */ |
274 | void l2cap_chan_del(struct l2cap_chan *chan, int err) | 278 | static void l2cap_chan_del(struct l2cap_chan *chan, int err) |
275 | { | 279 | { |
276 | struct sock *sk = chan->sk; | 280 | struct sock *sk = chan->sk; |
277 | struct l2cap_conn *conn = chan->conn; | 281 | struct l2cap_conn *conn = chan->conn; |
@@ -327,6 +331,87 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
327 | } | 331 | } |
328 | } | 332 | } |
329 | 333 | ||
334 | /* Must be called on unlocked socket. */ | ||
335 | static void l2cap_chan_close(struct sock *sk) | ||
336 | { | ||
337 | l2cap_sock_clear_timer(sk); | ||
338 | lock_sock(sk); | ||
339 | __l2cap_chan_close(l2cap_pi(sk)->chan, ECONNRESET); | ||
340 | release_sock(sk); | ||
341 | l2cap_sock_kill(sk); | ||
342 | } | ||
343 | |||
344 | static void l2cap_chan_cleanup_listen(struct sock *parent) | ||
345 | { | ||
346 | struct sock *sk; | ||
347 | |||
348 | BT_DBG("parent %p", parent); | ||
349 | |||
350 | /* Close not yet accepted channels */ | ||
351 | while ((sk = bt_accept_dequeue(parent, NULL))) | ||
352 | l2cap_chan_close(sk); | ||
353 | |||
354 | parent->sk_state = BT_CLOSED; | ||
355 | sock_set_flag(parent, SOCK_ZAPPED); | ||
356 | } | ||
357 | |||
358 | void __l2cap_chan_close(struct l2cap_chan *chan, int reason) | ||
359 | { | ||
360 | struct l2cap_conn *conn = chan->conn; | ||
361 | struct sock *sk = chan->sk; | ||
362 | |||
363 | BT_DBG("chan %p state %d socket %p", chan, sk->sk_state, sk->sk_socket); | ||
364 | |||
365 | switch (sk->sk_state) { | ||
366 | case BT_LISTEN: | ||
367 | l2cap_chan_cleanup_listen(sk); | ||
368 | break; | ||
369 | |||
370 | case BT_CONNECTED: | ||
371 | case BT_CONFIG: | ||
372 | if ((sk->sk_type == SOCK_SEQPACKET || | ||
373 | sk->sk_type == SOCK_STREAM) && | ||
374 | conn->hcon->type == ACL_LINK) { | ||
375 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | ||
376 | l2cap_send_disconn_req(conn, chan, reason); | ||
377 | } else | ||
378 | l2cap_chan_del(chan, reason); | ||
379 | break; | ||
380 | |||
381 | case BT_CONNECT2: | ||
382 | if ((sk->sk_type == SOCK_SEQPACKET || | ||
383 | sk->sk_type == SOCK_STREAM) && | ||
384 | conn->hcon->type == ACL_LINK) { | ||
385 | struct l2cap_conn_rsp rsp; | ||
386 | __u16 result; | ||
387 | |||
388 | if (bt_sk(sk)->defer_setup) | ||
389 | result = L2CAP_CR_SEC_BLOCK; | ||
390 | else | ||
391 | result = L2CAP_CR_BAD_PSM; | ||
392 | |||
393 | rsp.scid = cpu_to_le16(chan->dcid); | ||
394 | rsp.dcid = cpu_to_le16(chan->scid); | ||
395 | rsp.result = cpu_to_le16(result); | ||
396 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
397 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | ||
398 | sizeof(rsp), &rsp); | ||
399 | } | ||
400 | |||
401 | l2cap_chan_del(chan, reason); | ||
402 | break; | ||
403 | |||
404 | case BT_CONNECT: | ||
405 | case BT_DISCONN: | ||
406 | l2cap_chan_del(chan, reason); | ||
407 | break; | ||
408 | |||
409 | default: | ||
410 | sock_set_flag(sk, SOCK_ZAPPED); | ||
411 | break; | ||
412 | } | ||
413 | } | ||
414 | |||
330 | static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) | 415 | static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) |
331 | { | 416 | { |
332 | struct sock *sk = chan->sk; | 417 | struct sock *sk = chan->sk; |
@@ -393,7 +478,7 @@ u8 l2cap_get_ident(struct l2cap_conn *conn) | |||
393 | return id; | 478 | return id; |
394 | } | 479 | } |
395 | 480 | ||
396 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) | 481 | static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) |
397 | { | 482 | { |
398 | struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); | 483 | struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); |
399 | u8 flags; | 484 | u8 flags; |
@@ -533,7 +618,7 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | |||
533 | } | 618 | } |
534 | } | 619 | } |
535 | 620 | ||
536 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) | 621 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) |
537 | { | 622 | { |
538 | struct sock *sk; | 623 | struct sock *sk; |
539 | struct l2cap_disconn_req req; | 624 | struct l2cap_disconn_req req; |
@@ -591,10 +676,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
591 | conn->feat_mask) | 676 | conn->feat_mask) |
592 | && chan->conf_state & | 677 | && chan->conf_state & |
593 | L2CAP_CONF_STATE2_DEVICE) { | 678 | L2CAP_CONF_STATE2_DEVICE) { |
594 | /* __l2cap_sock_close() calls list_del(chan) | 679 | /* __l2cap_chan_close() calls list_del(chan) |
595 | * so release the lock */ | 680 | * so release the lock */ |
596 | read_unlock_bh(&conn->chan_lock); | 681 | read_unlock_bh(&conn->chan_lock); |
597 | __l2cap_sock_close(sk, ECONNRESET); | 682 | __l2cap_chan_close(chan, ECONNRESET); |
598 | read_lock_bh(&conn->chan_lock); | 683 | read_lock_bh(&conn->chan_lock); |
599 | bh_unlock_sock(sk); | 684 | bh_unlock_sock(sk); |
600 | continue; | 685 | continue; |
@@ -3943,7 +4028,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) | |||
3943 | l2cap_sock_clear_timer(sk); | 4028 | l2cap_sock_clear_timer(sk); |
3944 | l2cap_sock_set_timer(sk, HZ * 5); | 4029 | l2cap_sock_set_timer(sk, HZ * 5); |
3945 | } else if (chan->sec_level == BT_SECURITY_HIGH) | 4030 | } else if (chan->sec_level == BT_SECURITY_HIGH) |
3946 | __l2cap_sock_close(sk, ECONNREFUSED); | 4031 | __l2cap_chan_close(chan, ECONNREFUSED); |
3947 | } else { | 4032 | } else { |
3948 | if (chan->sec_level == BT_SECURITY_MEDIUM) | 4033 | if (chan->sec_level == BT_SECURITY_MEDIUM) |
3949 | l2cap_sock_clear_timer(sk); | 4034 | l2cap_sock_clear_timer(sk); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 18dc9888d8c2..290130ca1c4a 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -58,7 +58,7 @@ static void l2cap_sock_timeout(unsigned long arg) | |||
58 | else | 58 | else |
59 | reason = ETIMEDOUT; | 59 | reason = ETIMEDOUT; |
60 | 60 | ||
61 | __l2cap_sock_close(sk, reason); | 61 | __l2cap_chan_close(l2cap_pi(sk)->chan, reason); |
62 | 62 | ||
63 | bh_unlock_sock(sk); | 63 | bh_unlock_sock(sk); |
64 | 64 | ||
@@ -813,87 +813,6 @@ void l2cap_sock_kill(struct sock *sk) | |||
813 | sock_put(sk); | 813 | sock_put(sk); |
814 | } | 814 | } |
815 | 815 | ||
816 | /* Must be called on unlocked socket. */ | ||
817 | static void l2cap_sock_close(struct sock *sk) | ||
818 | { | ||
819 | l2cap_sock_clear_timer(sk); | ||
820 | lock_sock(sk); | ||
821 | __l2cap_sock_close(sk, ECONNRESET); | ||
822 | release_sock(sk); | ||
823 | l2cap_sock_kill(sk); | ||
824 | } | ||
825 | |||
826 | static void l2cap_sock_cleanup_listen(struct sock *parent) | ||
827 | { | ||
828 | struct sock *sk; | ||
829 | |||
830 | BT_DBG("parent %p", parent); | ||
831 | |||
832 | /* Close not yet accepted channels */ | ||
833 | while ((sk = bt_accept_dequeue(parent, NULL))) | ||
834 | l2cap_sock_close(sk); | ||
835 | |||
836 | parent->sk_state = BT_CLOSED; | ||
837 | sock_set_flag(parent, SOCK_ZAPPED); | ||
838 | } | ||
839 | |||
840 | void __l2cap_sock_close(struct sock *sk, int reason) | ||
841 | { | ||
842 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
843 | struct l2cap_conn *conn = chan->conn; | ||
844 | |||
845 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); | ||
846 | |||
847 | switch (sk->sk_state) { | ||
848 | case BT_LISTEN: | ||
849 | l2cap_sock_cleanup_listen(sk); | ||
850 | break; | ||
851 | |||
852 | case BT_CONNECTED: | ||
853 | case BT_CONFIG: | ||
854 | if ((sk->sk_type == SOCK_SEQPACKET || | ||
855 | sk->sk_type == SOCK_STREAM) && | ||
856 | conn->hcon->type == ACL_LINK) { | ||
857 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | ||
858 | l2cap_send_disconn_req(conn, chan, reason); | ||
859 | } else | ||
860 | l2cap_chan_del(chan, reason); | ||
861 | break; | ||
862 | |||
863 | case BT_CONNECT2: | ||
864 | if ((sk->sk_type == SOCK_SEQPACKET || | ||
865 | sk->sk_type == SOCK_STREAM) && | ||
866 | conn->hcon->type == ACL_LINK) { | ||
867 | struct l2cap_conn_rsp rsp; | ||
868 | __u16 result; | ||
869 | |||
870 | if (bt_sk(sk)->defer_setup) | ||
871 | result = L2CAP_CR_SEC_BLOCK; | ||
872 | else | ||
873 | result = L2CAP_CR_BAD_PSM; | ||
874 | |||
875 | rsp.scid = cpu_to_le16(chan->dcid); | ||
876 | rsp.dcid = cpu_to_le16(chan->scid); | ||
877 | rsp.result = cpu_to_le16(result); | ||
878 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
879 | l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, | ||
880 | sizeof(rsp), &rsp); | ||
881 | } | ||
882 | |||
883 | l2cap_chan_del(chan, reason); | ||
884 | break; | ||
885 | |||
886 | case BT_CONNECT: | ||
887 | case BT_DISCONN: | ||
888 | l2cap_chan_del(chan, reason); | ||
889 | break; | ||
890 | |||
891 | default: | ||
892 | sock_set_flag(sk, SOCK_ZAPPED); | ||
893 | break; | ||
894 | } | ||
895 | } | ||
896 | |||
897 | static int l2cap_sock_shutdown(struct socket *sock, int how) | 816 | static int l2cap_sock_shutdown(struct socket *sock, int how) |
898 | { | 817 | { |
899 | struct sock *sk = sock->sk; | 818 | struct sock *sk = sock->sk; |
@@ -912,7 +831,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
912 | 831 | ||
913 | sk->sk_shutdown = SHUTDOWN_MASK; | 832 | sk->sk_shutdown = SHUTDOWN_MASK; |
914 | l2cap_sock_clear_timer(sk); | 833 | l2cap_sock_clear_timer(sk); |
915 | __l2cap_sock_close(sk, 0); | 834 | __l2cap_chan_close(chan, 0); |
916 | 835 | ||
917 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) | 836 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) |
918 | err = bt_sock_wait_state(sk, BT_CLOSED, | 837 | err = bt_sock_wait_state(sk, BT_CLOSED, |