aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-02-06 03:13:37 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:37 -0500
commitefc7688b557dd1be10eead7399b315efcb1dbc74 (patch)
treef51d32d047bbf27a106db679292c10a81b339836 /net/bluetooth/hci_event.c
parent255c76014af74165428e7aa16414b857e2bdccf2 (diff)
Bluetooth: Add SCO fallback for eSCO connection attempts
When attempting to setup eSCO connections it can happen that some link manager implementations fail to properly negotiate the eSCO parameters and thus fail the eSCO setup. Normally the link manager is responsible for the negotiation of the parameters and actually fallback to SCO if no agreement can be reached. In cases where the link manager is just too stupid, then at least try to establish a SCO link if eSCO fails. For the Bluetooth devices with EDR support this includes handling packet types of EDR basebands. This is particular tricky since for the EDR the logic of enabling/disabling one specific packet type is turned around. This fix contains an extra bitmask to disable eSCO EDR packet when trying to fallback to a SCO connection. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 014fc8b320ba..899b8991a466 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -484,6 +484,15 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb
484 if (hdev->features[4] & LMP_EV5) 484 if (hdev->features[4] & LMP_EV5)
485 hdev->esco_type |= (ESCO_EV5); 485 hdev->esco_type |= (ESCO_EV5);
486 486
487 if (hdev->features[5] & LMP_EDR_ESCO_2M)
488 hdev->esco_type |= (ESCO_2EV3);
489
490 if (hdev->features[5] & LMP_EDR_ESCO_3M)
491 hdev->esco_type |= (ESCO_3EV3);
492
493 if (hdev->features[5] & LMP_EDR_3S_ESCO)
494 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
495
487 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, 496 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
488 hdev->features[0], hdev->features[1], 497 hdev->features[0], hdev->features[1],
489 hdev->features[2], hdev->features[3], 498 hdev->features[2], hdev->features[3],
@@ -1639,6 +1648,13 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
1639 conn->type = SCO_LINK; 1648 conn->type = SCO_LINK;
1640 } 1649 }
1641 1650
1651 if (conn->out && ev->status == 0x1c && conn->attempt < 2) {
1652 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
1653 (hdev->esco_type & EDR_ESCO_MASK);
1654 hci_setup_sync(conn, conn->link->handle);
1655 goto unlock;
1656 }
1657
1642 if (!ev->status) { 1658 if (!ev->status) {
1643 conn->handle = __le16_to_cpu(ev->handle); 1659 conn->handle = __le16_to_cpu(ev->handle);
1644 conn->state = BT_CONNECTED; 1660 conn->state = BT_CONNECTED;