aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/sco.c
diff options
context:
space:
mode:
authorFrédéric Dalleau <frederic.dalleau@linux.intel.com>2013-08-19 08:23:56 -0400
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-08-21 10:47:09 -0400
commitad10b1a48754b1381582d96f070a39832e41382d (patch)
tree7111567e3b1e7b283ec7d2617136f244660487ad /net/bluetooth/sco.c
parent33f2404823f000f9b5fc570b0a08b1008e241578 (diff)
Bluetooth: Add Bluetooth socket voice option
This patch extends the current Bluetooth socket options with BT_VOICE. This is intended to choose voice data type at runtime. It only applies to SCO sockets. Incoming connections shall be setup during deferred setup. Outgoing connections shall be setup before connect(). The desired setting is stored in the SCO socket info. This patch declares needed members, modifies getsockopt() and setsockopt(). Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r--net/bluetooth/sco.c40
1 files changed, 39 insertions, 1 deletions
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;