Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10c62ddc authored by Frédéric Dalleau's avatar Frédéric Dalleau Committed by Gustavo Padovan
Browse files

Bluetooth: Parameters for outgoing SCO connections



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: default avatarFrédéric Dalleau <frederic.dalleau@linux.intel.com>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent 2f69a82a
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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);
+19 −5
Original line number Diff line number Diff line
@@ -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.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.voice_setting  = cpu_to_le16(hdev->voice_setting);
		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);
+1 −1
Original line number Diff line number Diff line
@@ -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;