aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2011-04-28 16:55:53 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-08 15:58:16 -0400
commit4519de9a0478d8de438f8b80ab2e94668ef63ab4 (patch)
tree50c7ef0a0a4b2592306c1ba3c45b25fc6be5c1ea /net
parent37e1c55de7b1edd3fb8fc3411ad0c32a213723d0 (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.c97
-rw-r--r--net/bluetooth/l2cap_sock.c85
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
70static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, 70static 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);
72static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
73 void *data);
72static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); 74static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
75static void l2cap_send_disconn_req(struct l2cap_conn *conn,
76 struct l2cap_chan *chan, int err);
73 77
74static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); 78static 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. */
274void l2cap_chan_del(struct l2cap_chan *chan, int err) 278static 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. */
335static 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
344static 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
358void __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
330static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) 415static 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
396void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) 481static 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
536void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err) 621static 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. */
817static 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
826static 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
840void __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
897static int l2cap_sock_shutdown(struct socket *sock, int how) 816static 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,