Commit 732547f9 authored by Marcel Holtmann's avatar Marcel Holtmann

Bluetooth: Fallback from eSCO to SCO on unspecified error

Some Bluetooth chips (like the ones from Texas Instruments) don't do
proper eSCO negotiations inside the Link Manager. They just return an
error code and in case of the Kyocera ED-8800 headset it is just a
random error.

  < HCI Command: Setup Synchronous Connection 0x01|0x0028) plen 17
    handle 1 voice setting 0x0060
  > HCI Event: Command Status (0x0f) plen 4
    Setup Synchronous Connection (0x01|0x0028) status 0x00 ncmd 1
  > HCI Event: Synchronous Connect Complete (0x2c) plen 17
    status 0x1f handle 257 bdaddr 00:14:0A:xx:xx:xx type eSCO
    Error: Unspecified Error

In these cases it is up to the host stack to fallback to a SCO setup
and so retry with SCO parameters.

Based on a report by Nick Pelly <npelly@google.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent e2139b32
...@@ -1646,20 +1646,28 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu ...@@ -1646,20 +1646,28 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
conn->type = SCO_LINK; conn->type = SCO_LINK;
} }
if (conn->out && ev->status == 0x1c && conn->attempt < 2) { switch (ev->status) {
conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | case 0x00:
(hdev->esco_type & EDR_ESCO_MASK);
hci_setup_sync(conn, conn->link->handle);
goto unlock;
}
if (!ev->status) {
conn->handle = __le16_to_cpu(ev->handle); conn->handle = __le16_to_cpu(ev->handle);
conn->state = BT_CONNECTED; conn->state = BT_CONNECTED;
hci_conn_add_sysfs(conn); hci_conn_add_sysfs(conn);
} else break;
case 0x1c: /* SCO interval rejected */
case 0x1f: /* Unspecified error */
if (conn->out && conn->attempt < 2) {
conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
(hdev->esco_type & EDR_ESCO_MASK);
hci_setup_sync(conn, conn->link->handle);
goto unlock;
}
/* fall through */
default:
conn->state = BT_CLOSED; conn->state = BT_CLOSED;
break;
}
hci_proto_connect_cfm(conn, ev->status); hci_proto_connect_cfm(conn, ev->status);
if (ev->status) if (ev->status)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment