Skip to content

Commit ad10b1a

Browse files
Frédéric DalleauGustavo Padovan
Frédéric Dalleau
authored and
Gustavo Padovan
committed
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>
1 parent 33f2404 commit ad10b1a

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

include/net/bluetooth/bluetooth.h

+8
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ struct bt_power {
107107
*/
108108
#define BT_CHANNEL_POLICY_AMP_PREFERRED 2
109109

110+
#define BT_VOICE 11
111+
struct bt_voice {
112+
__u16 setting;
113+
};
114+
115+
#define BT_VOICE_TRANSPARENT 0x0003
116+
#define BT_VOICE_CVSD_16BIT 0x0060
117+
110118
__printf(1, 2)
111119
int bt_info(const char *fmt, ...);
112120
__printf(1, 2)

include/net/bluetooth/sco.h

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct sco_conn {
7373
struct sco_pinfo {
7474
struct bt_sock bt;
7575
__u32 flags;
76+
__u16 setting;
7677
struct sco_conn *conn;
7778
};
7879

net/bluetooth/sco.c

+39-1
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,8 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro
416416
sk->sk_protocol = proto;
417417
sk->sk_state = BT_OPEN;
418418

419+
sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
420+
419421
setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
420422

421423
bt_sock_link(&sco_sk_list, sk);
@@ -709,7 +711,8 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
709711
static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
710712
{
711713
struct sock *sk = sock->sk;
712-
int err = 0;
714+
int len, err = 0;
715+
struct bt_voice voice;
713716
u32 opt;
714717

715718
BT_DBG("sk %p", sk);
@@ -735,6 +738,31 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
735738
clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
736739
break;
737740

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+
738766
default:
739767
err = -ENOPROTOOPT;
740768
break;
@@ -808,6 +836,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
808836
{
809837
struct sock *sk = sock->sk;
810838
int len, err = 0;
839+
struct bt_voice voice;
811840

812841
BT_DBG("sk %p", sk);
813842

@@ -833,6 +862,15 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
833862

834863
break;
835864

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+
836874
default:
837875
err = -ENOPROTOOPT;
838876
break;

0 commit comments

Comments
 (0)