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: 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>
This commit is contained in:
parent
2f69a82acf
commit
10c62ddc6f
|
@ -320,6 +320,7 @@ struct hci_conn {
|
||||||
__u32 passkey_notify;
|
__u32 passkey_notify;
|
||||||
__u8 passkey_entered;
|
__u8 passkey_entered;
|
||||||
__u16 disc_timeout;
|
__u16 disc_timeout;
|
||||||
|
__u16 setting;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
__u8 remote_cap;
|
__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,
|
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||||
__u8 dst_type, __u8 sec_level, __u8 auth_type);
|
__u8 dst_type, __u8 sec_level, __u8 auth_type);
|
||||||
struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
|
struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||||
bdaddr_t *dst);
|
__u16 setting);
|
||||||
int hci_conn_check_link_mode(struct hci_conn *conn);
|
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_check_secure(struct hci_conn *conn, __u8 sec_level);
|
||||||
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
|
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
|
||||||
|
|
|
@ -185,13 +185,24 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
|
||||||
conn->attempt++;
|
conn->attempt++;
|
||||||
|
|
||||||
cp.handle = cpu_to_le16(handle);
|
cp.handle = cpu_to_le16(handle);
|
||||||
cp.pkt_type = cpu_to_le16(conn->pkt_type);
|
|
||||||
|
|
||||||
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
|
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
|
||||||
cp.rx_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(conn->setting);
|
||||||
cp.voice_setting = cpu_to_le16(hdev->voice_setting);
|
|
||||||
cp.retrans_effort = 0xff;
|
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);
|
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;
|
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 *acl;
|
||||||
struct hci_conn *sco;
|
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);
|
hci_conn_hold(sco);
|
||||||
|
|
||||||
|
sco->setting = setting;
|
||||||
|
|
||||||
if (acl->state == BT_CONNECTED &&
|
if (acl->state == BT_CONNECTED &&
|
||||||
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
|
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
|
||||||
set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
|
set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
|
||||||
|
|
|
@ -176,7 +176,7 @@ static int sco_connect(struct sock *sk)
|
||||||
else
|
else
|
||||||
type = SCO_LINK;
|
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)) {
|
if (IS_ERR(hcon)) {
|
||||||
err = PTR_ERR(hcon);
|
err = PTR_ERR(hcon);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
Loading…
Reference in New Issue