Bluetooth: Added support for HFP 1.6 Wide Band Speech
Signed-off-by: Kun Han Kim <kunhank@codeaurora.org>
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index bcc65ff..7ee9ff0 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -181,13 +181,23 @@
conn->attempt++;
cp.handle = cpu_to_le16(handle);
- cp.pkt_type = cpu_to_le16(conn->pkt_type);
cp.tx_bandwidth = cpu_to_le32(0x00001f40);
cp.rx_bandwidth = cpu_to_le32(0x00001f40);
- cp.max_latency = cpu_to_le16(0x000A);
- cp.voice_setting = cpu_to_le16(hdev->voice_setting);
- cp.retrans_effort = 0x01;
+ if (conn->hdev->is_wbs) {
+ /* Transparent Data */
+ uint16_t voice_setting = hdev->voice_setting | ACF_TRANS;
+ cp.max_latency = cpu_to_le16(0x000D);
+ cp.pkt_type = cpu_to_le16(ESCO_WBS);
+ cp.voice_setting = cpu_to_le16(voice_setting);
+ /* Retransmission Effort */
+ cp.retrans_effort = RE_LINK_QUALITY;
+ } else {
+ cp.max_latency = cpu_to_le16(0x000A);
+ cp.pkt_type = cpu_to_le16(conn->pkt_type);
+ cp.voice_setting = cpu_to_le16(hdev->voice_setting);
+ cp.retrans_effort = RE_POWER_CONSUMP;
+ }
hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0c731f9..43ad520 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2739,7 +2739,9 @@
case 0x1a: /* Unsupported Remote Feature */
case 0x1f: /* Unspecified error */
if (conn->out && conn->attempt < 2) {
- conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
+ if (!conn->hdev->is_wbs)
+ conn->pkt_type =
+ (hdev->esco_type & SCO_ESCO_MASK) |
(hdev->esco_type & EDR_ESCO_MASK);
hci_setup_sync(conn, conn->link->handle);
goto unlock;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index e692b9d..3b1e54c 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -1,6 +1,7 @@
/*
BlueZ - Bluetooth protocol stack for Linux
Copyright (C) 2000-2001 Qualcomm Incorporated
+ Copyright (c) 2011, Code Aurora Forum. All rights reserved.
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
@@ -173,7 +174,7 @@
return err;
}
-static int sco_connect(struct sock *sk)
+static int sco_connect(struct sock *sk, __s8 is_wbs)
{
bdaddr_t *src = &bt_sk(sk)->src;
bdaddr_t *dst = &bt_sk(sk)->dst;
@@ -191,13 +192,19 @@
hci_dev_lock_bh(hdev);
- if (lmp_esco_capable(hdev) && !disable_esco)
+ hdev->is_wbs = is_wbs;
+
+ if (lmp_esco_capable(hdev) && !disable_esco) {
type = ESCO_LINK;
- else {
+ } else if (is_wbs) {
+ return -ENAVAIL;
+ } else {
type = SCO_LINK;
pkt_type &= SCO_ESCO_MASK;
}
+ BT_DBG("type: %d, pkt_type: 0x%x", type, pkt_type);
+
hcon = hci_connect(hdev, type, pkt_type, dst,
BT_SECURITY_LOW, HCI_AT_NO_BONDING);
if (IS_ERR(hcon)) {
@@ -205,6 +212,13 @@
goto done;
}
+ if (is_wbs && (hcon->type != ESCO_LINK)) {
+ BT_ERR("WBS [ hcon->type: 0x%x, hcon->pkt_type: 0x%x ]",
+ hcon->type, hcon->pkt_type);
+ err = -EREMOTEIO;
+ goto done;
+ }
+
conn = sco_conn_add(hcon, 0);
if (!conn) {
hci_conn_put(hcon);
@@ -527,7 +541,7 @@
bacpy(&bt_sk(sk)->dst, &sa.sco_bdaddr);
sco_pi(sk)->pkt_type = sa.sco_pkt_type;
- err = sco_connect(sk);
+ err = sco_connect(sk, sa.is_wbs);
if (err)
goto done;