All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v10 00/10] sco: SCO socket option for voice_setting
@ 2013-08-14 17:03 Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 01/10] Bluetooth: Use hci_connect_sco directly Frédéric Dalleau
                   ` (9 more replies)
  0 siblings, 10 replies; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau

Hi,

v10 include contribution from Johan, he reworks fallback handling and fixes
Marcel remarks from v9.
error 0x0d handling moved into a separate patch

v9 is mostly cosmetics. Introduces LMP_TRANSPARENT bit in patch 8/8.

v8 declares BT_VOICE_CVSD_16BIT
Merge T*, S* and D* patches in one
The last patch returns -ECONNABORTED when trying to setup a transparent data
connection if eSCO is not supported.

v7 changes defaults to BT_VOICE_CVSD
Remove mask parameter to sco_conn_defer_accept, it was always 0
check the bits for air codec instead of use constants.
Add S3, S2, S1, D1, D0 settings.
The controller default is now only used to initialize the controller or fill
in the missing information in case of using the old Add_SCO command

v6 fixes style issues

v5 changes interface to SOL_BLUETOOTH, BT_VOICE.
Rework fallback mechanism.

This is the patch version 4 of the socket option for enabling transparent SCO.
As requested by Marcel, this is now a 16-bit voice_setting.
0x0000 is the value corresponding to current behavior.
0x0003 is the value to use for enabling transparent data.
It is easy to allow all possible values from Bluetooth core spec, but I guess
results can be unexpected...
Should we filter allowed values in setsockopt ?

Let me know what you think.
Regards,
Fred


Frédéric Dalleau (10):
  Bluetooth: Use hci_connect_sco directly
  Bluetooth: Remove unused mask parameter in sco_conn_defer_accept
  Bluetooth: Add Bluetooth socket voice option
  Bluetooth: Add constants for SCO airmode
  Bluetooth: Use voice setting in deferred SCO connection request
  Bluetooth: Parameters for outgoing SCO connections
  Bluetooth: Add constants and macro declaration for transparent data
  Bluetooth: Prevent transparent SCO on older devices
  Bluetooth: Handle specific error for SCO connection fallback
  Bluetooth: Add SCO connection fallback

 include/net/bluetooth/bluetooth.h |    8 ++++
 include/net/bluetooth/hci.h       |    1 +
 include/net/bluetooth/hci_core.h  |   10 ++++-
 include/net/bluetooth/sco.h       |    1 +
 net/bluetooth/hci_conn.c          |   59 ++++++++++++++++++++++------
 net/bluetooth/hci_event.c         |    7 ++--
 net/bluetooth/sco.c               |   77 ++++++++++++++++++++++++++++++-------
 7 files changed, 134 insertions(+), 29 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v10 01/10] Bluetooth: Use hci_connect_sco directly
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 02/10] Bluetooth: Remove unused mask parameter in sco_conn_defer_accept Frédéric Dalleau
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

hci_connect is a super function for connecting hci protocols. But the
voice_setting parameter (introduced in subsequent patches) is only
needed by SCO and security requirements are not needed for SCO channels.
Thus, it makes sense to have a separate function for SCO.

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>
---
 include/net/bluetooth/hci_core.h |    2 ++
 net/bluetooth/hci_conn.c         |    8 ++------
 net/bluetooth/sco.c              |    3 +--
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f77885e..307a192 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -584,6 +584,8 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
 			     __u8 dst_type, __u8 sec_level, __u8 auth_type);
+struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
+				 bdaddr_t *dst);
 int hci_conn_check_link_mode(struct hci_conn *conn);
 int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
 int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 6c7f363..5f1f448 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -560,13 +560,12 @@ static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
 	return acl;
 }
 
-static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
-				bdaddr_t *dst, u8 sec_level, u8 auth_type)
+struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst)
 {
 	struct hci_conn *acl;
 	struct hci_conn *sco;
 
-	acl = hci_connect_acl(hdev, dst, sec_level, auth_type);
+	acl = hci_connect_acl(hdev, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
 	if (IS_ERR(acl))
 		return acl;
 
@@ -612,9 +611,6 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
 		return hci_connect_le(hdev, dst, dst_type, sec_level, auth_type);
 	case ACL_LINK:
 		return hci_connect_acl(hdev, dst, sec_level, auth_type);
-	case SCO_LINK:
-	case ESCO_LINK:
-		return hci_connect_sco(hdev, type, dst, sec_level, auth_type);
 	}
 
 	return ERR_PTR(-EINVAL);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index e7bd4ee..9e20a30 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -176,8 +176,7 @@ static int sco_connect(struct sock *sk)
 	else
 		type = SCO_LINK;
 
-	hcon = hci_connect(hdev, type, dst, BDADDR_BREDR, BT_SECURITY_LOW,
-			   HCI_AT_NO_BONDING);
+	hcon = hci_connect_sco(hdev, type, dst);
 	if (IS_ERR(hcon)) {
 		err = PTR_ERR(hcon);
 		goto done;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 02/10] Bluetooth: Remove unused mask parameter in sco_conn_defer_accept
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 01/10] Bluetooth: Use hci_connect_sco directly Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 03/10] Bluetooth: Add Bluetooth socket voice option Frédéric Dalleau
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

>From Bluetooth Core v4.0 specification, 7.1.8 Accept Connection Request
Command "When accepting synchronous connection request, the Role
parameter is not used and will be ignored by the BR/EDR Controller."

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>
---
 net/bluetooth/sco.c |   10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 9e20a30..05c2fc1 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -651,7 +651,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 	return err;
 }
 
-static void sco_conn_defer_accept(struct hci_conn *conn, int mask)
+static void sco_conn_defer_accept(struct hci_conn *conn)
 {
 	struct hci_dev *hdev = conn->hdev;
 
@@ -663,11 +663,7 @@ static void sco_conn_defer_accept(struct hci_conn *conn, int mask)
 		struct hci_cp_accept_conn_req cp;
 
 		bacpy(&cp.bdaddr, &conn->dst);
-
-		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-			cp.role = 0x00; /* Become master */
-		else
-			cp.role = 0x01; /* Remain slave */
+		cp.role = 0x00; /* Ignored */
 
 		hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
 	} else {
@@ -697,7 +693,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
 	if (sk->sk_state == BT_CONNECT2 &&
 	    test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
-		sco_conn_defer_accept(pi->conn->hcon, 0);
+		sco_conn_defer_accept(pi->conn->hcon);
 		sk->sk_state = BT_CONFIG;
 		msg->msg_namelen = 0;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 03/10] Bluetooth: Add Bluetooth socket voice option
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 01/10] Bluetooth: Use hci_connect_sco directly Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 02/10] Bluetooth: Remove unused mask parameter in sco_conn_defer_accept Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 04/10] Bluetooth: Add constants for SCO airmode Frédéric Dalleau
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

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>
---
 include/net/bluetooth/bluetooth.h |    8 ++++++++
 include/net/bluetooth/sco.h       |    1 +
 net/bluetooth/sco.c               |   40 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 10eb9b3..10d43d8 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -107,6 +107,14 @@ struct bt_power {
  */
 #define BT_CHANNEL_POLICY_AMP_PREFERRED		2
 
+#define BT_VOICE		11
+struct bt_voice {
+	__u16 setting;
+};
+
+#define BT_VOICE_TRANSPARENT			0x0003
+#define BT_VOICE_CVSD_16BIT			0x0060
+
 __printf(1, 2)
 int bt_info(const char *fmt, ...);
 __printf(1, 2)
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index 1e35c43..e252a31 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -73,6 +73,7 @@ struct sco_conn {
 struct sco_pinfo {
 	struct bt_sock	bt;
 	__u32		flags;
+	__u16		setting;
 	struct sco_conn	*conn;
 };
 
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 05c2fc1..e8cda67 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
 	sk->sk_protocol = proto;
 	sk->sk_state    = BT_OPEN;
 
+	sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT;
+
 	setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
 
 	bt_sock_link(&sco_sk_list, sk);
@@ -709,7 +711,8 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
 	struct sock *sk = sock->sk;
-	int err = 0;
+	int len, err = 0;
+	struct bt_voice voice;
 	u32 opt;
 
 	BT_DBG("sk %p", sk);
@@ -735,6 +738,31 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
 			clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
 		break;
 
+	case BT_VOICE:
+		if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND &&
+		    sk->sk_state != BT_CONNECT2) {
+			err = -EINVAL;
+			break;
+		}
+
+		voice.setting = sco_pi(sk)->setting;
+
+		len = min_t(unsigned int, sizeof(voice), optlen);
+		if (copy_from_user((char *) &voice, optval, len)) {
+			err = -EFAULT;
+			break;
+		}
+
+		/* Explicitly check for these values */
+		if (voice.setting != BT_VOICE_TRANSPARENT &&
+		    voice.setting != BT_VOICE_CVSD_16BIT) {
+			err = -EINVAL;
+			break;
+		}
+
+		sco_pi(sk)->setting = voice.setting;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -804,6 +832,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
 {
 	struct sock *sk = sock->sk;
 	int len, err = 0;
+	struct bt_voice voice;
 
 	BT_DBG("sk %p", sk);
 
@@ -829,6 +858,15 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
 
 		break;
 
+	case BT_VOICE:
+		voice.setting = sco_pi(sk)->setting;
+
+		len = min_t(unsigned int, len, sizeof(voice));
+		if (copy_to_user(optval, (char *)&voice, len))
+			err = -EFAULT;
+
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 04/10] Bluetooth: Add constants for SCO airmode
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
                   ` (2 preceding siblings ...)
  2013-08-14 17:03 ` [PATCH v10 03/10] Bluetooth: Add Bluetooth socket voice option Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 05/10] Bluetooth: Use voice setting in deferred SCO connection request Frédéric Dalleau
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

This patch defines constants for SCO airmode from SCO voice setting. It
refers to Bluetooth Core V4.0 specification, Part E, Chap 6.12 which
describe SCO voice setting format.

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>
---
 include/net/bluetooth/hci_core.h |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 307a192..f403509 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1215,4 +1215,8 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
 
 u8 bdaddr_to_le(u8 bdaddr_type);
 
+#define SCO_AIRMODE_MASK       0x0003
+#define SCO_AIRMODE_CVSD       0x0000
+#define SCO_AIRMODE_TRANSP     0x0003
+
 #endif /* __HCI_CORE_H */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 05/10] Bluetooth: Use voice setting in deferred SCO connection request
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
                   ` (3 preceding siblings ...)
  2013-08-14 17:03 ` [PATCH v10 04/10] Bluetooth: Add constants for SCO airmode Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-16 18:47   ` Marcel Holtmann
  2013-08-14 17:03 ` [PATCH v10 06/10] Bluetooth: Parameters for outgoing SCO connections Frédéric Dalleau
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

When an incoming eSCO connection is requested, check the selected voice
setting and reply appropriately. Voice setting should have been
negotiated previously.  For example, in case of HFP, the codec is
negotiated using AT commands on the RFCOMM channel. This patch only
changes replies for socket with deferred setup enabled.

Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/sco.c |   22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index e8cda67..3b3d24a 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -653,7 +653,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 	return err;
 }
 
-static void sco_conn_defer_accept(struct hci_conn *conn)
+static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting)
 {
 	struct hci_dev *hdev = conn->hdev;
 
@@ -676,9 +676,21 @@ static void sco_conn_defer_accept(struct hci_conn *conn)
 
 		cp.tx_bandwidth   = __constant_cpu_to_le32(0x00001f40);
 		cp.rx_bandwidth   = __constant_cpu_to_le32(0x00001f40);
-		cp.max_latency    = __constant_cpu_to_le16(0xffff);
-		cp.content_format = cpu_to_le16(hdev->voice_setting);
-		cp.retrans_effort = 0xff;
+		cp.content_format = cpu_to_le16(setting);
+
+		switch (setting & SCO_AIRMODE_MASK) {
+		case SCO_AIRMODE_TRANSP:
+			if (conn->pkt_type & ESCO_2EV3)
+				cp.max_latency = __constant_cpu_to_le16(0x0008);
+			else
+				cp.max_latency = __constant_cpu_to_le16(0x000D);
+			cp.retrans_effort = 0x02;
+			break;
+		case SCO_AIRMODE_CVSD:
+			cp.max_latency = __constant_cpu_to_le16(0xffff);
+			cp.retrans_effort = 0xff;
+			break;
+		}
 
 		hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
 			     sizeof(cp), &cp);
@@ -695,7 +707,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
 	if (sk->sk_state == BT_CONNECT2 &&
 	    test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
-		sco_conn_defer_accept(pi->conn->hcon);
+		sco_conn_defer_accept(pi->conn->hcon, pi->setting);
 		sk->sk_state = BT_CONFIG;
 		msg->msg_namelen = 0;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 06/10] Bluetooth: Parameters for outgoing SCO connections
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
                   ` (4 preceding siblings ...)
  2013-08-14 17:03 ` [PATCH v10 05/10] Bluetooth: Use voice setting in deferred SCO connection request Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-16 18:47   ` Marcel Holtmann
  2013-08-14 17:03 ` [PATCH v10 07/10] Bluetooth: Add constants and macro declaration for transparent data Frédéric Dalleau
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

In order to establish a transparent SCO connection, the correct settings
must be specified in the Setup Synchronous Connection request. For that,
a setting field is added to ACL connection data to set up the desired
parameters. The patch also removes usage of hdev->voice_setting in CVSD
connection and makes use of T2 parameters for transparent data.

Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h |    5 +++--
 net/bluetooth/hci_conn.c         |   24 +++++++++++++++++++-----
 net/bluetooth/sco.c              |    2 +-
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f403509..61ca2ce 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -320,6 +320,7 @@ struct hci_conn {
 	__u32		passkey_notify;
 	__u8		passkey_entered;
 	__u16		disc_timeout;
+	__u16		setting;
 	unsigned long	flags;
 
 	__u8		remote_cap;
@@ -584,8 +585,8 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
 			     __u8 dst_type, __u8 sec_level, __u8 auth_type);
-struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
-				 bdaddr_t *dst);
+struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
+				 __u16 setting);
 int hci_conn_check_link_mode(struct hci_conn *conn);
 int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
 int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 5f1f448..c0e56a5 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -185,13 +185,24 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
 	conn->attempt++;
 
 	cp.handle   = cpu_to_le16(handle);
-	cp.pkt_type = cpu_to_le16(conn->pkt_type);
 
 	cp.tx_bandwidth   = __constant_cpu_to_le32(0x00001f40);
 	cp.rx_bandwidth   = __constant_cpu_to_le32(0x00001f40);
-	cp.max_latency    = __constant_cpu_to_le16(0xffff);
-	cp.voice_setting  = cpu_to_le16(hdev->voice_setting);
-	cp.retrans_effort = 0xff;
+	cp.voice_setting  = cpu_to_le16(conn->setting);
+
+	switch (conn->setting & SCO_AIRMODE_MASK) {
+	case SCO_AIRMODE_TRANSP:
+		cp.pkt_type = __constant_cpu_to_le16(EDR_ESCO_MASK &
+						     ~ESCO_2EV3);
+		cp.max_latency = __constant_cpu_to_le16(0x000d);
+		cp.retrans_effort = 0x02;
+		break;
+	case SCO_AIRMODE_CVSD:
+		cp.pkt_type = cpu_to_le16(conn->pkt_type);
+		cp.max_latency = __constant_cpu_to_le16(0xffff);
+		cp.retrans_effort = 0xff;
+		break;
+	}
 
 	hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
 }
@@ -560,7 +571,8 @@ static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
 	return acl;
 }
 
-struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst)
+struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
+				 __u16 setting)
 {
 	struct hci_conn *acl;
 	struct hci_conn *sco;
@@ -583,6 +595,8 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst)
 
 	hci_conn_hold(sco);
 
+	sco->setting = setting;
+
 	if (acl->state == BT_CONNECTED &&
 	    (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
 		set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 3b3d24a..e82d792 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -176,7 +176,7 @@ static int sco_connect(struct sock *sk)
 	else
 		type = SCO_LINK;
 
-	hcon = hci_connect_sco(hdev, type, dst);
+	hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->setting);
 	if (IS_ERR(hcon)) {
 		err = PTR_ERR(hcon);
 		goto done;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 07/10] Bluetooth: Add constants and macro declaration for transparent data
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
                   ` (5 preceding siblings ...)
  2013-08-14 17:03 ` [PATCH v10 06/10] Bluetooth: Parameters for outgoing SCO connections Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 08/10] Bluetooth: Prevent transparent SCO on older devices Frédéric Dalleau
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

This patch defines constants and macro for transparent data LMP
features. It refers to Bluetooth Core V4.0 specification, Part C, Chap
3.3 which defines LMP feature mask.

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>
---
 include/net/bluetooth/hci.h      |    1 +
 include/net/bluetooth/hci_core.h |    1 +
 2 files changed, 2 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index a01fbb4..aaeaf09 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -238,6 +238,7 @@ enum {
 #define LMP_CVSD	0x01
 #define LMP_PSCHEME	0x02
 #define LMP_PCONTROL	0x04
+#define LMP_TRANSPARENT	0x08
 
 #define LMP_RSSI_INQ	0x40
 #define LMP_ESCO	0x80
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 61ca2ce..b2bfab8 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -800,6 +800,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define lmp_lsto_capable(dev)      ((dev)->features[0][7] & LMP_LSTO)
 #define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR)
 #define lmp_ext_feat_capable(dev)  ((dev)->features[0][7] & LMP_EXTFEATURES)
+#define lmp_transp_capable(dev)    ((dev)->features[0][2] & LMP_TRANSPARENT)
 
 /* ----- Extended LMP capabilities ----- */
 #define lmp_host_ssp_capable(dev)  ((dev)->features[1][0] & LMP_HOST_SSP)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 08/10] Bluetooth: Prevent transparent SCO on older devices
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
                   ` (6 preceding siblings ...)
  2013-08-14 17:03 ` [PATCH v10 07/10] Bluetooth: Add constants and macro declaration for transparent data Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-16 18:45   ` Marcel Holtmann
  2013-08-14 17:03 ` [PATCH v10 09/10] Bluetooth: Handle specific error for SCO connection fallback Frédéric Dalleau
  2013-08-14 17:03 ` [PATCH v10 10/10] Bluetooth: Add " Frédéric Dalleau
  9 siblings, 1 reply; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

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>
---
 net/bluetooth/sco.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index e82d792..1170b6e 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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 09/10] Bluetooth: Handle specific error for SCO connection fallback
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
                   ` (7 preceding siblings ...)
  2013-08-14 17:03 ` [PATCH v10 08/10] Bluetooth: Prevent transparent SCO on older devices Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-16 18:48   ` Marcel Holtmann
  2013-08-14 17:03 ` [PATCH v10 10/10] Bluetooth: Add " Frédéric Dalleau
  9 siblings, 1 reply; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau

Synchronous Connection Complete event can return error "Connection
Rejected due to Limited resources (0x10)".
Handling this error is required for SCO connection fallback. This error
happens when the server tried to accept the connection but failed to
negotiate settings.
This error code has been verified experimentally by sending a T2 request
to a T1 only SCO listener.

Client dump follows :

< HCI Command (0x01|0x0028) plen 17 [hci0] 3.696064
        Handle: 12
        Transmit bandwidth: 8000
        Receive bandwidth: 8000
        Max latency: 13
        Setting: 0x0003
        Retransmission effort: Optimize for link quality (0x02)
        Packet type: 0x0380
> HCI Event (0x0f) plen 4 [hci0] 3.697034
      Setup Synchronous Connection (0x01|0x0028) ncmd 1
        Status: Success (0x00)
> HCI Event (0x2c) plen 17 [hci0] 3.736059
        Status: Connection Rejected due to Limited Resources (0x0d)
        Handle: 0
        Address: xx:xx:xx:xx:xx:AB (OUI 70-F3-95)
        Link type: eSCO (0x02)
        Transmission interval: 0x0c
        Retransmission window: 0x06
        RX packet length: 60
        TX packet length: 60
        Air mode: Transparent (0x03)

Server dump follows :

> HCI Event (0x04) plen 10 [hci0] 4.741513
        Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
        Class: 0x620100
          Major class: Computer (desktop, notebook, PDA, organizers)
          Minor class: Uncategorized, code for device not assigned
          Networking (LAN, Ad hoc)
          Audio (Speaker, Microphone, Headset)
          Telephony (Cordless telephony, Modem, Headset)
        Link type: eSCO (0x02)
< HCI Command (0x01|0x0029) plen 21 [hci0] 4.743269
        Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
        Transmit bandwidth: 8000
        Receive bandwidth: 8000
        Max latency: 13
        Setting: 0x0003
        Retransmission effort: Optimize for link quality (0x02)
        Packet type: 0x03c1
> HCI Event (0x0f) plen 4 [hci0] 4.745517
      Accept Synchronous Connection (0x01|0x0029) ncmd 1
        Status: Success (0x00)
> HCI Event (0x2c) plen 17 [hci0] 4.749508
        Status: Connection Rejected due to Limited Resources (0x0d)
        Handle: 0
        Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
        Link type: eSCO (0x02)
        Transmission interval: 0x0c
        Retransmission window: 0x06
        RX packet length: 60
        TX packet length: 60
        Air mode: Transparent (0x03)

Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
---
 net/bluetooth/hci_event.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 50e39f4..a8bb7bb 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2904,6 +2904,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
 		hci_conn_add_sysfs(conn);
 		break;
 
+	case 0x0d:	/* Connection Rejected due to Limited Resources */
 	case 0x11:	/* Unsupported Feature or Parameter Value */
 	case 0x1c:	/* SCO interval rejected */
 	case 0x1a:	/* Unsupported Remote Feature */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v10 10/10] Bluetooth: Add SCO connection fallback
  2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
                   ` (8 preceding siblings ...)
  2013-08-14 17:03 ` [PATCH v10 09/10] Bluetooth: Handle specific error for SCO connection fallback Frédéric Dalleau
@ 2013-08-14 17:03 ` Frédéric Dalleau
  2013-08-16 18:55   ` Marcel Holtmann
  9 siblings, 1 reply; 16+ messages in thread
From: Frédéric Dalleau @ 2013-08-14 17:03 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau, Johan Hedberg

When initiating a transparent eSCO connection, make use of T2 settings
at first try. T2 is the recommended settings from HFP 1.6 WideBand
Speech. Upon connection failure, try T1 settings.

When CVSD is requested and eSCO is supported, try to establish eSCO
connection using S3 settings. If it fails, fallback in sequence to S2,
S1, D1, D0 settings.

To know which setting should be used, conn->attempt is used. It
indicates the currently ongoing SCO connection attempt and can be used
as the index for the fallback settings table.

These setting and the fallback order are described in Bluetooth HFP 1.6
specification p. 101.

Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h |    2 +-
 net/bluetooth/hci_conn.c         |   41 ++++++++++++++++++++++++++++++--------
 net/bluetooth/hci_event.c        |    6 +++---
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b2bfab8..1f95e9b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -570,7 +570,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
 }
 
 void hci_disconnect(struct hci_conn *conn, __u8 reason);
-void hci_setup_sync(struct hci_conn *conn, __u16 handle);
+int hci_setup_sync(struct hci_conn *conn, __u16 handle);
 void hci_sco_setup(struct hci_conn *conn, __u8 status);
 
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index c0e56a5..d3befac 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -31,6 +31,24 @@
 #include <net/bluetooth/a2mp.h>
 #include <net/bluetooth/smp.h>
 
+struct sco_param {
+	u16 pkt_type;
+	u16 max_latency;
+};
+
+static const struct sco_param sco_param_cvsd[] = {
+	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a }, /* S3 */
+	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007 }, /* S2 */
+	{ EDR_ESCO_MASK | ESCO_EV3,   0x0007 }, /* S1 */
+	{ EDR_ESCO_MASK | ESCO_HV3,   0xffff }, /* D1 */
+	{ EDR_ESCO_MASK | ESCO_HV1,   0xffff }, /* D0 */
+};
+
+static const struct sco_param sco_param_wideband[] = {
+	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d }, /* T2 */
+	{ EDR_ESCO_MASK | ESCO_EV3,   0x0008 }, /* T1 */
+};
+
 static void hci_le_create_connection(struct hci_conn *conn)
 {
 	struct hci_dev *hdev = conn->hdev;
@@ -172,10 +190,11 @@ static void hci_add_sco(struct hci_conn *conn, __u16 handle)
 	hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
 }
 
-void hci_setup_sync(struct hci_conn *conn, __u16 handle)
+int hci_setup_sync(struct hci_conn *conn, __u16 handle)
 {
 	struct hci_dev *hdev = conn->hdev;
 	struct hci_cp_setup_sync_conn cp;
+	const struct sco_param *param;
 
 	BT_DBG("hcon %p", conn);
 
@@ -192,19 +211,25 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
 
 	switch (conn->setting & SCO_AIRMODE_MASK) {
 	case SCO_AIRMODE_TRANSP:
-		cp.pkt_type = __constant_cpu_to_le16(EDR_ESCO_MASK &
-						     ~ESCO_2EV3);
-		cp.max_latency = __constant_cpu_to_le16(0x000d);
+		if (conn->attempt > ARRAY_SIZE(sco_param_wideband))
+			return -ECONNREFUSED;
 		cp.retrans_effort = 0x02;
+		param = &sco_param_wideband[conn->attempt - 1];
 		break;
 	case SCO_AIRMODE_CVSD:
-		cp.pkt_type = cpu_to_le16(conn->pkt_type);
-		cp.max_latency = __constant_cpu_to_le16(0xffff);
-		cp.retrans_effort = 0xff;
+		if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
+			return -ECONNREFUSED;
+		cp.retrans_effort = 0x01;
+		param = &sco_param_cvsd[conn->attempt - 1];
 		break;
+	default:
+		return -EINVAL;
 	}
 
-	hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
+	cp.pkt_type = __cpu_to_le16(param->pkt_type);
+	cp.max_latency = __cpu_to_le16(param->max_latency);
+
+	return hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
 }
 
 void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index a8bb7bb..491c5fb 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2909,11 +2909,11 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
 	case 0x1c:	/* SCO interval rejected */
 	case 0x1a:	/* Unsupported Remote Feature */
 	case 0x1f:	/* Unspecified error */
-		if (conn->out && conn->attempt < 2) {
+		if (conn->out) {
 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
 					(hdev->esco_type & EDR_ESCO_MASK);
-			hci_setup_sync(conn, conn->link->handle);
-			goto unlock;
+			if (hci_setup_sync(conn, conn->link->handle) == 0)
+				goto unlock;
 		}
 		/* fall through */
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v10 08/10] Bluetooth: Prevent transparent SCO on older devices
  2013-08-14 17:03 ` [PATCH v10 08/10] Bluetooth: Prevent transparent SCO on older devices Frédéric Dalleau
@ 2013-08-16 18:45   ` Marcel Holtmann
  0 siblings, 0 replies; 16+ messages in thread
From: Marcel Holtmann @ 2013-08-16 18:45 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth, Johan Hedberg

Hi Fred,

> 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>
> ---
> net/bluetooth/sco.c |    6 ++++++
> 1 file changed, 6 insertions(+)

lets go with EOPNOTSUPP.

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v10 05/10] Bluetooth: Use voice setting in deferred SCO connection request
  2013-08-14 17:03 ` [PATCH v10 05/10] Bluetooth: Use voice setting in deferred SCO connection request Frédéric Dalleau
@ 2013-08-16 18:47   ` Marcel Holtmann
  0 siblings, 0 replies; 16+ messages in thread
From: Marcel Holtmann @ 2013-08-16 18:47 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth, Johan Hedberg

Hi Fred,

> When an incoming eSCO connection is requested, check the selected voice
> setting and reply appropriately. Voice setting should have been
> negotiated previously.  For example, in case of HFP, the codec is
> negotiated using AT commands on the RFCOMM channel. This patch only
> changes replies for socket with deferred setup enabled.
> 
> Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/sco.c |   22 +++++++++++++++++-----
> 1 file changed, 17 insertions(+), 5 deletions(-)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v10 06/10] Bluetooth: Parameters for outgoing SCO connections
  2013-08-14 17:03 ` [PATCH v10 06/10] Bluetooth: Parameters for outgoing SCO connections Frédéric Dalleau
@ 2013-08-16 18:47   ` Marcel Holtmann
  0 siblings, 0 replies; 16+ messages in thread
From: Marcel Holtmann @ 2013-08-16 18:47 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth, Johan Hedberg

Hi Fred,

> In order to establish a transparent SCO connection, the correct settings
> must be specified in the Setup Synchronous Connection request. For that,
> a setting field is added to ACL connection data to set up the desired
> parameters. The patch also removes usage of hdev->voice_setting in CVSD
> connection and makes use of T2 parameters for transparent data.
> 
> Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h |    5 +++--
> net/bluetooth/hci_conn.c         |   24 +++++++++++++++++++-----
> net/bluetooth/sco.c              |    2 +-
> 3 files changed, 23 insertions(+), 8 deletions(-)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v10 09/10] Bluetooth: Handle specific error for SCO connection fallback
  2013-08-14 17:03 ` [PATCH v10 09/10] Bluetooth: Handle specific error for SCO connection fallback Frédéric Dalleau
@ 2013-08-16 18:48   ` Marcel Holtmann
  0 siblings, 0 replies; 16+ messages in thread
From: Marcel Holtmann @ 2013-08-16 18:48 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth

Hi Fred,

> Synchronous Connection Complete event can return error "Connection
> Rejected due to Limited resources (0x10)".
> Handling this error is required for SCO connection fallback. This error
> happens when the server tried to accept the connection but failed to
> negotiate settings.
> This error code has been verified experimentally by sending a T2 request
> to a T1 only SCO listener.
> 
> Client dump follows :
> 
> < HCI Command (0x01|0x0028) plen 17 [hci0] 3.696064
>        Handle: 12
>        Transmit bandwidth: 8000
>        Receive bandwidth: 8000
>        Max latency: 13
>        Setting: 0x0003
>        Retransmission effort: Optimize for link quality (0x02)
>        Packet type: 0x0380
>> HCI Event (0x0f) plen 4 [hci0] 3.697034
>      Setup Synchronous Connection (0x01|0x0028) ncmd 1
>        Status: Success (0x00)
>> HCI Event (0x2c) plen 17 [hci0] 3.736059
>        Status: Connection Rejected due to Limited Resources (0x0d)
>        Handle: 0
>        Address: xx:xx:xx:xx:xx:AB (OUI 70-F3-95)
>        Link type: eSCO (0x02)
>        Transmission interval: 0x0c
>        Retransmission window: 0x06
>        RX packet length: 60
>        TX packet length: 60
>        Air mode: Transparent (0x03)
> 
> Server dump follows :
> 
>> HCI Event (0x04) plen 10 [hci0] 4.741513
>        Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
>        Class: 0x620100
>          Major class: Computer (desktop, notebook, PDA, organizers)
>          Minor class: Uncategorized, code for device not assigned
>          Networking (LAN, Ad hoc)
>          Audio (Speaker, Microphone, Headset)
>          Telephony (Cordless telephony, Modem, Headset)
>        Link type: eSCO (0x02)
> < HCI Command (0x01|0x0029) plen 21 [hci0] 4.743269
>        Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
>        Transmit bandwidth: 8000
>        Receive bandwidth: 8000
>        Max latency: 13
>        Setting: 0x0003
>        Retransmission effort: Optimize for link quality (0x02)
>        Packet type: 0x03c1
>> HCI Event (0x0f) plen 4 [hci0] 4.745517
>      Accept Synchronous Connection (0x01|0x0029) ncmd 1
>        Status: Success (0x00)
>> HCI Event (0x2c) plen 17 [hci0] 4.749508
>        Status: Connection Rejected due to Limited Resources (0x0d)
>        Handle: 0
>        Address: xx:xx:xx:xx:xx:D9 (OUI 20-68-9D)
>        Link type: eSCO (0x02)
>        Transmission interval: 0x0c
>        Retransmission window: 0x06
>        RX packet length: 60
>        TX packet length: 60
>        Air mode: Transparent (0x03)
> 
> Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
> ---
> net/bluetooth/hci_event.c |    1 +
> 1 file changed, 1 insertion(+)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v10 10/10] Bluetooth: Add SCO connection fallback
  2013-08-14 17:03 ` [PATCH v10 10/10] Bluetooth: Add " Frédéric Dalleau
@ 2013-08-16 18:55   ` Marcel Holtmann
  0 siblings, 0 replies; 16+ messages in thread
From: Marcel Holtmann @ 2013-08-16 18:55 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth, Johan Hedberg

Hi Fred,

> When initiating a transparent eSCO connection, make use of T2 settings
> at first try. T2 is the recommended settings from HFP 1.6 WideBand
> Speech. Upon connection failure, try T1 settings.
> 
> When CVSD is requested and eSCO is supported, try to establish eSCO
> connection using S3 settings. If it fails, fallback in sequence to S2,
> S1, D1, D0 settings.
> 
> To know which setting should be used, conn->attempt is used. It
> indicates the currently ongoing SCO connection attempt and can be used
> as the index for the fallback settings table.
> 
> These setting and the fallback order are described in Bluetooth HFP 1.6
> specification p. 101.
> 
> Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci_core.h |    2 +-
> net/bluetooth/hci_conn.c         |   41 ++++++++++++++++++++++++++++++--------
> net/bluetooth/hci_event.c        |    6 +++---
> 3 files changed, 37 insertions(+), 12 deletions(-)
> 
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index b2bfab8..1f95e9b 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -570,7 +570,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
> }
> 
> void hci_disconnect(struct hci_conn *conn, __u8 reason);
> -void hci_setup_sync(struct hci_conn *conn, __u16 handle);
> +int hci_setup_sync(struct hci_conn *conn, __u16 handle);
> void hci_sco_setup(struct hci_conn *conn, __u8 status);
> 
> struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> index c0e56a5..d3befac 100644
> --- a/net/bluetooth/hci_conn.c
> +++ b/net/bluetooth/hci_conn.c
> @@ -31,6 +31,24 @@
> #include <net/bluetooth/a2mp.h>
> #include <net/bluetooth/smp.h>
> 
> +struct sco_param {
> +	u16 pkt_type;
> +	u16 max_latency;
> +};
> +
> +static const struct sco_param sco_param_cvsd[] = {
> +	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a }, /* S3 */
> +	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007 }, /* S2 */
> +	{ EDR_ESCO_MASK | ESCO_EV3,   0x0007 }, /* S1 */
> +	{ EDR_ESCO_MASK | ESCO_HV3,   0xffff }, /* D1 */
> +	{ EDR_ESCO_MASK | ESCO_HV1,   0xffff }, /* D0 */
> +};
> +
> +static const struct sco_param sco_param_wideband[] = {
> +	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d }, /* T2 */
> +	{ EDR_ESCO_MASK | ESCO_EV3,   0x0008 }, /* T1 */
> +};
> +
> static void hci_le_create_connection(struct hci_conn *conn)
> {
> 	struct hci_dev *hdev = conn->hdev;
> @@ -172,10 +190,11 @@ static void hci_add_sco(struct hci_conn *conn, __u16 handle)
> 	hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
> }
> 
> -void hci_setup_sync(struct hci_conn *conn, __u16 handle)
> +int hci_setup_sync(struct hci_conn *conn, __u16 handle)
> {
> 	struct hci_dev *hdev = conn->hdev;
> 	struct hci_cp_setup_sync_conn cp;
> +	const struct sco_param *param;
> 
> 	BT_DBG("hcon %p", conn);
> 
> @@ -192,19 +211,25 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
> 
> 	switch (conn->setting & SCO_AIRMODE_MASK) {
> 	case SCO_AIRMODE_TRANSP:
> -		cp.pkt_type = __constant_cpu_to_le16(EDR_ESCO_MASK &
> -						     ~ESCO_2EV3);
> -		cp.max_latency = __constant_cpu_to_le16(0x000d);
> +		if (conn->attempt > ARRAY_SIZE(sco_param_wideband))
> +			return -ECONNREFUSED;
> 		cp.retrans_effort = 0x02;
> +		param = &sco_param_wideband[conn->attempt - 1];
> 		break;
> 	case SCO_AIRMODE_CVSD:
> -		cp.pkt_type = cpu_to_le16(conn->pkt_type);
> -		cp.max_latency = __constant_cpu_to_le16(0xffff);
> -		cp.retrans_effort = 0xff;
> +		if (conn->attempt > ARRAY_SIZE(sco_param_cvsd))
> +			return -ECONNREFUSED;
> +		cp.retrans_effort = 0x01;
> +		param = &sco_param_cvsd[conn->attempt - 1];
> 		break;
> +	default:
> +		return -EINVAL;
> 	}
> 
> -	hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
> +	cp.pkt_type = __cpu_to_le16(param->pkt_type);
> +	cp.max_latency = __cpu_to_le16(param->max_latency);
> +
> +	return hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
> }

since we are not using the return value for anything, I would propose that you use a bool here and just give true for success and false for failure. And since hci_send_cmd can only fail on skb allocation, you can just do this:

	if (hci_send_cmd(…) < 0)
		return false;

	return true;

> 
> void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index a8bb7bb..491c5fb 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -2909,11 +2909,11 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
> 	case 0x1c:	/* SCO interval rejected */
> 	case 0x1a:	/* Unsupported Remote Feature */
> 	case 0x1f:	/* Unspecified error */
> -		if (conn->out && conn->attempt < 2) {
> +		if (conn->out) {
> 			conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
> 					(hdev->esco_type & EDR_ESCO_MASK);
> -			hci_setup_sync(conn, conn->link->handle);
> -			goto unlock;
> +			if (hci_setup_sync(conn, conn->link->handle) == 0)
> +				goto unlock;

And this one becomes this then:

			if (hci_setup_sync(…))
				goto unlock;

> 		}
> 		/* fall through */

Regards

Marcel


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2013-08-16 18:55 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-14 17:03 [PATCH v10 00/10] sco: SCO socket option for voice_setting Frédéric Dalleau
2013-08-14 17:03 ` [PATCH v10 01/10] Bluetooth: Use hci_connect_sco directly Frédéric Dalleau
2013-08-14 17:03 ` [PATCH v10 02/10] Bluetooth: Remove unused mask parameter in sco_conn_defer_accept Frédéric Dalleau
2013-08-14 17:03 ` [PATCH v10 03/10] Bluetooth: Add Bluetooth socket voice option Frédéric Dalleau
2013-08-14 17:03 ` [PATCH v10 04/10] Bluetooth: Add constants for SCO airmode Frédéric Dalleau
2013-08-14 17:03 ` [PATCH v10 05/10] Bluetooth: Use voice setting in deferred SCO connection request Frédéric Dalleau
2013-08-16 18:47   ` Marcel Holtmann
2013-08-14 17:03 ` [PATCH v10 06/10] Bluetooth: Parameters for outgoing SCO connections Frédéric Dalleau
2013-08-16 18:47   ` Marcel Holtmann
2013-08-14 17:03 ` [PATCH v10 07/10] Bluetooth: Add constants and macro declaration for transparent data Frédéric Dalleau
2013-08-14 17:03 ` [PATCH v10 08/10] Bluetooth: Prevent transparent SCO on older devices Frédéric Dalleau
2013-08-16 18:45   ` Marcel Holtmann
2013-08-14 17:03 ` [PATCH v10 09/10] Bluetooth: Handle specific error for SCO connection fallback Frédéric Dalleau
2013-08-16 18:48   ` Marcel Holtmann
2013-08-14 17:03 ` [PATCH v10 10/10] Bluetooth: Add " Frédéric Dalleau
2013-08-16 18:55   ` Marcel Holtmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.