aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-02-04 00:35:20 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:46:02 -0500
commit6de0702b5b93da0ef097aa092b4597fbc024ebba (patch)
tree601d1ac548d2c5e83be23c9a81472665378e0503 /net/bluetooth/l2cap_sock.c
parent05fc1576dabb1defae3c8c0371fb9d21f7db997a (diff)
Bluetooth: move __l2cap_sock_close() to l2cap_sock.c
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r--net/bluetooth/l2cap_sock.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 4b4e0201ebb..adf41692daf 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -854,6 +854,84 @@ void l2cap_sock_kill(struct sock *sk)
854 sock_put(sk); 854 sock_put(sk);
855} 855}
856 856
857/* Must be called on unlocked socket. */
858static void l2cap_sock_close(struct sock *sk)
859{
860 l2cap_sock_clear_timer(sk);
861 lock_sock(sk);
862 __l2cap_sock_close(sk, ECONNRESET);
863 release_sock(sk);
864 l2cap_sock_kill(sk);
865}
866
867static void l2cap_sock_cleanup_listen(struct sock *parent)
868{
869 struct sock *sk;
870
871 BT_DBG("parent %p", parent);
872
873 /* Close not yet accepted channels */
874 while ((sk = bt_accept_dequeue(parent, NULL)))
875 l2cap_sock_close(sk);
876
877 parent->sk_state = BT_CLOSED;
878 sock_set_flag(parent, SOCK_ZAPPED);
879}
880
881void __l2cap_sock_close(struct sock *sk, int reason)
882{
883 BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
884
885 switch (sk->sk_state) {
886 case BT_LISTEN:
887 l2cap_sock_cleanup_listen(sk);
888 break;
889
890 case BT_CONNECTED:
891 case BT_CONFIG:
892 if (sk->sk_type == SOCK_SEQPACKET ||
893 sk->sk_type == SOCK_STREAM) {
894 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
895
896 l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
897 l2cap_send_disconn_req(conn, sk, reason);
898 } else
899 l2cap_chan_del(sk, reason);
900 break;
901
902 case BT_CONNECT2:
903 if (sk->sk_type == SOCK_SEQPACKET ||
904 sk->sk_type == SOCK_STREAM) {
905 struct l2cap_conn *conn = l2cap_pi(sk)->conn;
906 struct l2cap_conn_rsp rsp;
907 __u16 result;
908
909 if (bt_sk(sk)->defer_setup)
910 result = L2CAP_CR_SEC_BLOCK;
911 else
912 result = L2CAP_CR_BAD_PSM;
913
914 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
915 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
916 rsp.result = cpu_to_le16(result);
917 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
918 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
919 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
920 } else
921 l2cap_chan_del(sk, reason);
922 break;
923
924 case BT_CONNECT:
925 case BT_DISCONN:
926 l2cap_chan_del(sk, reason);
927 break;
928
929 default:
930 sock_set_flag(sk, SOCK_ZAPPED);
931 break;
932 }
933}
934
857static int l2cap_sock_shutdown(struct socket *sock, int how) 935static int l2cap_sock_shutdown(struct socket *sock, int how)
858{ 936{
859 struct sock *sk = sock->sk; 937 struct sock *sk = sock->sk;