aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/rfcomm/sock.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-01-15 15:56:48 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:23 -0500
commitbb23c0ab824653be4aa7dfca15b07b3059717004 (patch)
treebd0390c67d129e8b5ddc2a70a1b12e383db6fa16 /net/bluetooth/rfcomm/sock.c
parentc4f912e155504e94dd4f3d63c378dab0ff03dbda (diff)
Bluetooth: Add support for deferring RFCOMM connection setup
In order to decide if listening RFCOMM sockets should be accept()ed the BD_ADDR of the remote device needs to be known. This patch adds a socket option which defines a timeout for deferring the actual connection setup. The connection setup is done after reading from the socket for the first time. Until then writing to the socket returns ENOTCONN. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/rfcomm/sock.c')
-rw-r--r--net/bluetooth/rfcomm/sock.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 65dd7133d72b..d37a829a81e4 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -262,8 +262,10 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
262 if (parent) { 262 if (parent) {
263 sk->sk_type = parent->sk_type; 263 sk->sk_type = parent->sk_type;
264 pi->link_mode = rfcomm_pi(parent)->link_mode; 264 pi->link_mode = rfcomm_pi(parent)->link_mode;
265 pi->dlc->defer_setup = bt_sk(parent)->defer_setup;
265 } else { 266 } else {
266 pi->link_mode = 0; 267 pi->link_mode = 0;
268 pi->dlc->defer_setup = 0;
267 } 269 }
268 270
269 pi->dlc->link_mode = pi->link_mode; 271 pi->dlc->link_mode = pi->link_mode;
@@ -554,6 +556,9 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
554 struct sk_buff *skb; 556 struct sk_buff *skb;
555 int sent = 0; 557 int sent = 0;
556 558
559 if (test_bit(RFCOMM_DEFER_SETUP, &d->flags))
560 return -ENOTCONN;
561
557 if (msg->msg_flags & MSG_OOB) 562 if (msg->msg_flags & MSG_OOB)
558 return -EOPNOTSUPP; 563 return -EOPNOTSUPP;
559 564
@@ -633,10 +638,16 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
633 struct msghdr *msg, size_t size, int flags) 638 struct msghdr *msg, size_t size, int flags)
634{ 639{
635 struct sock *sk = sock->sk; 640 struct sock *sk = sock->sk;
641 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
636 int err = 0; 642 int err = 0;
637 size_t target, copied = 0; 643 size_t target, copied = 0;
638 long timeo; 644 long timeo;
639 645
646 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
647 rfcomm_dlc_accept(d);
648 return 0;
649 }
650
640 if (flags & MSG_OOB) 651 if (flags & MSG_OOB)
641 return -EOPNOTSUPP; 652 return -EOPNOTSUPP;
642 653
@@ -746,6 +757,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
746{ 757{
747 struct sock *sk = sock->sk; 758 struct sock *sk = sock->sk;
748 int err = 0; 759 int err = 0;
760 u32 opt;
749 761
750 BT_DBG("sk %p", sk); 762 BT_DBG("sk %p", sk);
751 763
@@ -755,6 +767,20 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
755 lock_sock(sk); 767 lock_sock(sk);
756 768
757 switch (optname) { 769 switch (optname) {
770 case BT_DEFER_SETUP:
771 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
772 err = -EINVAL;
773 break;
774 }
775
776 if (get_user(opt, (u32 __user *) optval)) {
777 err = -EFAULT;
778 break;
779 }
780
781 bt_sk(sk)->defer_setup = opt;
782 break;
783
758 default: 784 default:
759 err = -ENOPROTOOPT; 785 err = -ENOPROTOOPT;
760 break; 786 break;
@@ -785,7 +811,8 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
785 break; 811 break;
786 812
787 case RFCOMM_CONNINFO: 813 case RFCOMM_CONNINFO:
788 if (sk->sk_state != BT_CONNECTED) { 814 if (sk->sk_state != BT_CONNECTED &&
815 !rfcomm_pi(sk)->dlc->defer_setup) {
789 err = -ENOTCONN; 816 err = -ENOTCONN;
790 break; 817 break;
791 } 818 }
@@ -826,6 +853,17 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c
826 lock_sock(sk); 853 lock_sock(sk);
827 854
828 switch (optname) { 855 switch (optname) {
856 case BT_DEFER_SETUP:
857 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
858 err = -EINVAL;
859 break;
860 }
861
862 if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval))
863 err = -EFAULT;
864
865 break;
866
829 default: 867 default:
830 err = -ENOPROTOOPT; 868 err = -ENOPROTOOPT;
831 break; 869 break;
@@ -938,6 +976,10 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
938 976
939done: 977done:
940 bh_unlock_sock(parent); 978 bh_unlock_sock(parent);
979
980 if (bt_sk(parent)->defer_setup)
981 parent->sk_state_change(parent);
982
941 return result; 983 return result;
942} 984}
943 985