aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/bluetooth.h8
-rw-r--r--include/net/bluetooth/sco.h1
-rw-r--r--net/bluetooth/sco.c40
3 files changed, 48 insertions, 1 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 10eb9b389014..10d43d8c7037 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -107,6 +107,14 @@ struct bt_power {
107 */ 107 */
108#define BT_CHANNEL_POLICY_AMP_PREFERRED 2 108#define BT_CHANNEL_POLICY_AMP_PREFERRED 2
109 109
110#define BT_VOICE 11
111struct bt_voice {
112 __u16 setting;
113};
114
115#define BT_VOICE_TRANSPARENT 0x0003
116#define BT_VOICE_CVSD_16BIT 0x0060
117
110__printf(1, 2) 118__printf(1, 2)
111int bt_info(const char *fmt, ...); 119int bt_info(const char *fmt, ...);
112__printf(1, 2) 120__printf(1, 2)
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index 1e35c43657c8..e252a31ee6b6 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -73,6 +73,7 @@ struct sco_conn {
73struct sco_pinfo { 73struct sco_pinfo {
74 struct bt_sock bt; 74 struct bt_sock bt;
75 __u32 flags; 75 __u32 flags;
76 __u16 setting;
76 struct sco_conn *conn; 77 struct sco_conn *conn;
77}; 78};
78 79
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index acdca68806db..678747e2e389 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -416,6 +416,8 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro
416 sk->sk_protocol = proto; 416 sk->sk_protocol = proto;
417 sk->sk_state = BT_OPEN; 417 sk->sk_state = BT_OPEN;
418 418
419 sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
420
419 setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk); 421 setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
420 422
421 bt_sock_link(&sco_sk_list, sk); 423 bt_sock_link(&sco_sk_list, sk);
@@ -709,7 +711,8 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
709static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) 711static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
710{ 712{
711 struct sock *sk = sock->sk; 713 struct sock *sk = sock->sk;
712 int err = 0; 714 int len, err = 0;
715 struct bt_voice voice;
713 u32 opt; 716 u32 opt;
714 717
715 BT_DBG("sk %p", sk); 718 BT_DBG("sk %p", sk);
@@ -735,6 +738,31 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
735 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); 738 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
736 break; 739 break;
737 740
741 case BT_VOICE:
742 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
743 sk->sk_state != BT_CONNECT2) {
744 err = -EINVAL;
745 break;
746 }
747
748 voice.setting = sco_pi(sk)->setting;
749
750 len = min_t(unsigned int, sizeof(voice), optlen);
751 if (copy_from_user((char *) &voice, optval, len)) {
752 err = -EFAULT;
753 break;
754 }
755
756 /* Explicitly check for these values */
757 if (voice.setting != BT_VOICE_TRANSPARENT &&
758 voice.setting != BT_VOICE_CVSD_16BIT) {
759 err = -EINVAL;
760 break;
761 }
762
763 sco_pi(sk)->setting = voice.setting;
764 break;
765
738 default: 766 default:
739 err = -ENOPROTOOPT; 767 err = -ENOPROTOOPT;
740 break; 768 break;
@@ -808,6 +836,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
808{ 836{
809 struct sock *sk = sock->sk; 837 struct sock *sk = sock->sk;
810 int len, err = 0; 838 int len, err = 0;
839 struct bt_voice voice;
811 840
812 BT_DBG("sk %p", sk); 841 BT_DBG("sk %p", sk);
813 842
@@ -833,6 +862,15 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
833 862
834 break; 863 break;
835 864
865 case BT_VOICE:
866 voice.setting = sco_pi(sk)->setting;
867
868 len = min_t(unsigned int, len, sizeof(voice));
869 if (copy_to_user(optval, (char *)&voice, len))
870 err = -EFAULT;
871
872 break;
873
836 default: 874 default:
837 err = -ENOPROTOOPT; 875 err = -ENOPROTOOPT;
838 break; 876 break;