aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/sco.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r--net/bluetooth/sco.c57
1 files changed, 51 insertions, 6 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 46fd8bf9a690..51ae0c3e470a 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -195,7 +195,7 @@ static int sco_connect(struct sock *sk)
195 else 195 else
196 type = SCO_LINK; 196 type = SCO_LINK;
197 197
198 hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING); 198 hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
199 if (!hcon) 199 if (!hcon)
200 goto done; 200 goto done;
201 201
@@ -668,7 +668,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
668 return err; 668 return err;
669} 669}
670 670
671static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) 671static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
672{ 672{
673 struct sock *sk = sock->sk; 673 struct sock *sk = sock->sk;
674 struct sco_options opts; 674 struct sco_options opts;
@@ -723,6 +723,31 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
723 return err; 723 return err;
724} 724}
725 725
726static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
727{
728 struct sock *sk = sock->sk;
729 int len, err = 0;
730
731 BT_DBG("sk %p", sk);
732
733 if (level == SOL_SCO)
734 return sco_sock_getsockopt_old(sock, optname, optval, optlen);
735
736 if (get_user(len, optlen))
737 return -EFAULT;
738
739 lock_sock(sk);
740
741 switch (optname) {
742 default:
743 err = -ENOPROTOOPT;
744 break;
745 }
746
747 release_sock(sk);
748 return err;
749}
750
726static int sco_sock_release(struct socket *sock) 751static int sco_sock_release(struct socket *sock)
727{ 752{
728 struct sock *sk = sock->sk; 753 struct sock *sk = sock->sk;
@@ -832,10 +857,30 @@ done:
832/* ----- SCO interface with lower layer (HCI) ----- */ 857/* ----- SCO interface with lower layer (HCI) ----- */
833static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) 858static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
834{ 859{
860 register struct sock *sk;
861 struct hlist_node *node;
862 int lm = 0;
863
864 if (type != SCO_LINK && type != ESCO_LINK)
865 return 0;
866
835 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); 867 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
836 868
837 /* Always accept connection */ 869 /* Find listening sockets */
838 return HCI_LM_ACCEPT; 870 read_lock(&sco_sk_list.lock);
871 sk_for_each(sk, node, &sco_sk_list.head) {
872 if (sk->sk_state != BT_LISTEN)
873 continue;
874
875 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) ||
876 !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
877 lm |= HCI_LM_ACCEPT;
878 break;
879 }
880 }
881 read_unlock(&sco_sk_list.lock);
882
883 return lm;
839} 884}
840 885
841static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) 886static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
@@ -857,7 +902,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
857 return 0; 902 return 0;
858} 903}
859 904
860static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason) 905static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
861{ 906{
862 BT_DBG("hcon %p reason %d", hcon, reason); 907 BT_DBG("hcon %p reason %d", hcon, reason);
863 908
@@ -940,7 +985,7 @@ static struct hci_proto sco_hci_proto = {
940 .id = HCI_PROTO_SCO, 985 .id = HCI_PROTO_SCO,
941 .connect_ind = sco_connect_ind, 986 .connect_ind = sco_connect_ind,
942 .connect_cfm = sco_connect_cfm, 987 .connect_cfm = sco_connect_cfm,
943 .disconn_ind = sco_disconn_ind, 988 .disconn_cfm = sco_disconn_cfm,
944 .recv_scodata = sco_recv_scodata 989 .recv_scodata = sco_recv_scodata
945}; 990};
946 991