summaryrefslogtreecommitdiff
path: root/net/bluetooth
diff options
context:
space:
mode:
authorFrédéric Dalleau <frederic.dalleau@linux.intel.com>2013-08-19 12:24:01 (GMT)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-08-21 14:47:12 (GMT)
commit79dc0087c33f06a8c35d8c9e37ea6307b790bc4c (patch)
tree50dafbbecdae221a96143df5842cc29239fce0ce /net/bluetooth
parent07a5c61eda7f23883273f738edbf6caaebb71923 (diff)
downloadlinux-fsl-qoriq-79dc0087c33f06a8c35d8c9e37ea6307b790bc4c.tar.xz
Bluetooth: Prevent transparent SCO on older devices
Older Bluetooth devices may not support Setup Synchronous Connection or SCO transparent data. This is indicated by the corresponding LMP feature bits. It is not possible to know if the adapter support these features before setting BT_VOICE option since the socket is not bound to an adapter. An adapter can also be added after the socket is created. The socket can be bound to an address before adapter is plugged in. Thus, on a such adapters, if user request BT_VOICE_TRANSPARENT, outgoing connections fail on connect() and returns -EOPNOTSUPP. Incoming connections do not fail. However, they should only be allowed depending on what was specified in Write_Voice_Settings command. EOPNOTSUPP is choosen because connect() system call is failing after selecting route but before any connection attempt. Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/sco.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index ed581b4..96bd388 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -176,6 +176,12 @@ static int sco_connect(struct sock *sk)
else
type = SCO_LINK;
+ if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT &&
+ (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) {
+ err = -EOPNOTSUPP;
+ goto done;
+ }
+
hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting);
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);