* [PATCH BlueZ v2 3/4] gas: Fix not sending response to indication
From: Vinicius Costa Gomes @ 2013-01-29 19:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1359486007-3273-1-git-send-email-vinicius.gomes@openbossa.org>
Even if the remote device is not bonded, we should send the response to the
indication. If we don't the remote device may disconnect.
---
profiles/gatt/gas.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index c0520af..9360201 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -183,16 +183,16 @@ static void indication_cb(const uint8_t *pdu, uint16_t len, gpointer user_data)
DBG("Service Changed start: 0x%04X end: 0x%04X", start, end);
- if (device_is_bonded(gas->device) == FALSE) {
- DBG("Ignoring Service Changed: device is not bonded");
- return;
- }
-
/* Confirming indication received */
opdu = g_attrib_get_buffer(gas->attrib, &plen);
olen = enc_confirmation(opdu, plen);
g_attrib_send(gas->attrib, 0, opdu, olen, NULL, NULL, NULL);
+ if (device_is_bonded(gas->device) == FALSE) {
+ DBG("Ignoring Service Changed: device is not bonded");
+ return;
+ }
+
btd_device_gatt_set_service_changed(gas->device, start, end);
}
--
1.8.1.1
^ permalink raw reply related
* [PATCH BlueZ v2 4/4] device: Fix missing PDUs during encryption procedure
From: Vinicius Costa Gomes @ 2013-01-29 19:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1359486007-3273-1-git-send-email-vinicius.gomes@openbossa.org>
In case the remote device sends an ATT PDU while encryption is going
on, we may lose it because the ATT socket (with security level medium),
would only be attached when encryption finishes.
---
src/device.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/src/device.c b/src/device.c
index ceaa575..0d2d3ee 100644
--- a/src/device.c
+++ b/src/device.c
@@ -3167,7 +3167,6 @@ int device_connect_le(struct btd_device *dev)
{
struct btd_adapter *adapter = dev->adapter;
struct att_callbacks *attcb;
- BtIOSecLevel sec_level;
GIOChannel *io;
GError *gerr = NULL;
char addr[18];
@@ -3185,21 +3184,18 @@ int device_connect_le(struct btd_device *dev)
attcb->success = att_success_cb;
attcb->user_data = dev;
- if (dev->paired)
- sec_level = BT_IO_SEC_MEDIUM;
- else
- sec_level = BT_IO_SEC_LOW;
-
/*
* This connection will help us catch any PDUs that comes before
- * pairing finishes
+ * pairing finishes. Its security level is low, because we don't
+ * want to miss any PDU that may come before the encryption
+ * procedure finishes
*/
io = bt_io_connect(att_connect_cb, attcb, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, adapter_get_address(adapter),
BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
BT_IO_OPT_CID, ATT_CID,
- BT_IO_OPT_SEC_LEVEL, sec_level,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
BT_IO_OPT_INVALID);
if (io == NULL) {
--
1.8.1.1
^ permalink raw reply related
* Re: [PATCH 1/2] neard: Fix passing negative error code to strerror
From: Johan Hedberg @ 2013-01-29 21:59 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1359449671-14584-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Tue, Jan 29, 2013, Szymon Janc wrote:
> error_reply expects non-negative error code.
> ---
> plugins/neard.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ] core: Fix g_source_remove() with zero ID while removing device
From: Johan Hedberg @ 2013-01-29 22:01 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1359485546-28790-1-git-send-email-anderson.lizardo@openbossa.org>
Hi Lizardo,
On Tue, Jan 29, 2013, Anderson Lizardo wrote:
> store_device_info_cb() is also used as callback for g_idle_add() and
> therefore sets device->store_id to zero. During device removal it may be
> called manually, which must be done only after the existing
> device->store_id is removed from mainloop.
>
> Fix this GLib error (and a bunch of invalid read/writes when
> store_device_info_cb() was called after device removal due to this bug):
>
> bluetoothd[1192]: src/device.c:device_remove() Removing device
> /org/bluez/hci0/dev_12_34_12_34_12_34
>
> (bluetoothd:1192): GLib-CRITICAL **: g_source_remove: assertion `tag >
> 0' failed
> bluetoothd[1192]: src/device.c:btd_device_unref() Freeing device
> /org/bluez/hci0/dev_12_34_12_34_12_34
> bluetoothd[1192]: src/device.c:device_free() 0x463a2a0
> ---
> src/device.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ v2 1/4] device: Fix invalid memory access during Find Included
From: Johan Hedberg @ 2013-01-29 22:05 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1359486007-3273-1-git-send-email-vinicius.gomes@openbossa.org>
Hi Vinicius,
On Tue, Jan 29, 2013, Vinicius Costa Gomes wrote:
> When doing the Find Included Services GATT procedure, the status of the ATT
> procedure was being ignored, and in the case of a timeout it is possible to
> crash bluetooth with an invalid memory access.
>
> Valgrind log:
>
> ==1755== Invalid read of size 8
> ==1755== at 0x46971A: find_included_cb (device.c:2964)
> ==1755== by 0x4465AE: isd_unref (gatt.c:92)
> ==1755== by 0x446885: find_included_cb (gatt.c:425)
> ==1755== by 0x448266: disconnect_timeout (gattrib.c:269)
> ==1755== by 0x4E76BCA: g_timeout_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76044: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76377: g_main_context_iterate.isra.24 (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76771: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x40A2EE: main (main.c:583)
> ==1755== Address 0x69530a8 is 8 bytes inside a block of size 64 free'd
> ==1755== at 0x4C2874F: free (vg_replace_malloc.c:446)
> ==1755== by 0x40BFA6: service_filter (watch.c:486)
> ==1755== by 0x40BC6A: message_filter (watch.c:554)
> ==1755== by 0x5160A1D: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.7.2)
> ==1755== by 0x40AAB7: message_dispatch (mainloop.c:76)
> ==1755== by 0x4E76BCA: g_timeout_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76044: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76377: g_main_context_iterate.isra.24 (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76771: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x40A2EE: main (main.c:583)
> ==1755==
> ==1755== Invalid read of size 8
> ==1755== at 0x4486D5: g_attrib_get_buffer (gattrib.c:657)
> ==1755== by 0x4467C5: find_included (gatt.c:363)
> ==1755== by 0x4465AE: isd_unref (gatt.c:92)
> ==1755== by 0x446885: find_included_cb (gatt.c:425)
> ==1755== by 0x448266: disconnect_timeout (gattrib.c:269)
> ==1755== by 0x4E76BCA: g_timeout_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76044: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76377: g_main_context_iterate.isra.24 (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76771: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x40A2EE: main (main.c:583)
> ==1755== Address 0x18 is not stack'd, malloc'd or (recently) free'd
> ==1755==
> ==1755==
> ==1755== Process terminating with default action of signal 11 (SIGSEGV)
> ==1755== Access not within mapped region at address 0x18
> ==1755== at 0x4486D5: g_attrib_get_buffer (gattrib.c:657)
> ==1755== by 0x4467C5: find_included (gatt.c:363)
> ==1755== by 0x4465AE: isd_unref (gatt.c:92)
> ==1755== by 0x446885: find_included_cb (gatt.c:425)
> ==1755== by 0x448266: disconnect_timeout (gattrib.c:269)
> ==1755== by 0x4E76BCA: g_timeout_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76044: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76377: g_main_context_iterate.isra.24 (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x4E76771: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3400.2)
> ==1755== by 0x40A2EE: main (main.c:583)
> ---
> attrib/gatt.c | 5 ++++-
> src/device.c | 6 ++++++
> 2 files changed, 10 insertions(+), 1 deletion(-)
Patches 1-3 have been applied. We still need to discuss 4/4 though since
1) We should always try to secure the link as well as possible (meaning
encrypt it if we have an LTK)
and
2) Even if we do try to encrypt the link the ATT socket still needs to
remain functional all the time since there could be PDUs coming and
going that do not need high security.
Johan
^ permalink raw reply
* [PATCH 1/5] Bluetooth: Fix L2CAP socket shutdown for LE connections
From: Andre Guedes @ 2013-01-29 22:59 UTC (permalink / raw)
To: linux-bluetooth
During the L2CAP socket shutdown, the LE connection is not terminated
as expected. This bug can be reproduced using l2test tool. Once the
LE connection is established, kill l2test and the LE connection will
not terminate.
This patch fixes hci_conn_disconnect function so it is able to
terminate LE connections.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_conn.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 25bfce0..0492949 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -250,6 +250,7 @@ static void hci_conn_disconnect(struct hci_conn *conn)
switch (conn->type) {
case ACL_LINK:
+ case LE_LINK:
hci_acl_disconn(conn, reason);
break;
case AMP_LINK:
--
1.8.1.1
^ permalink raw reply related
* [PATCH 2/5] Bluetooth: Fix SCO socket shutdown
From: Andre Guedes @ 2013-01-29 22:59 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1359500396-8184-1-git-send-email-andre.guedes@openbossa.org>
During the SCO socket shutdown, the connection is not terminated a
expected. This bug can be reproduced using scotest tool. Once the
connection is established, kill scotest and the connection will not
terminate.
This patch fixes hci_conn_disconnect function so it is able to
terminate SCO connections.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_conn.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 0492949..28cfa72 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -251,6 +251,8 @@ static void hci_conn_disconnect(struct hci_conn *conn)
switch (conn->type) {
case ACL_LINK:
case LE_LINK:
+ case SCO_LINK:
+ case ESCO_LINK:
hci_acl_disconn(conn, reason);
break;
case AMP_LINK:
--
1.8.1.1
^ permalink raw reply related
* [PATCH 3/5] Bluetooth: Refactor hci_conn_disconnect
From: Andre Guedes @ 2013-01-29 22:59 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1359500396-8184-1-git-send-email-andre.guedes@openbossa.org>
This patch does a trivial refactoring in hci_conn_disconnect function.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_conn.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 28cfa72..4925a02 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -249,15 +249,12 @@ static void hci_conn_disconnect(struct hci_conn *conn)
__u8 reason = hci_proto_disconn_ind(conn);
switch (conn->type) {
- case ACL_LINK:
- case LE_LINK:
- case SCO_LINK:
- case ESCO_LINK:
- hci_acl_disconn(conn, reason);
- break;
case AMP_LINK:
hci_amp_disconn(conn, reason);
break;
+ default:
+ hci_acl_disconn(conn, reason);
+ break;
}
}
--
1.8.1.1
^ permalink raw reply related
* [PATCH 4/5] Bluetooth: Rename hci_acl_disconn
From: Andre Guedes @ 2013-01-29 22:59 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1359500396-8184-1-git-send-email-andre.guedes@openbossa.org>
As hci_acl_disconn function basically sends the HCI Disconnect Command
and it is used to disconnect ACL, SCO and LE links, renaming it to
hci_disconnect is more suitable.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/hci_conn.c | 4 ++--
net/bluetooth/hci_core.c | 2 +-
net/bluetooth/hci_event.c | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 90cf75a..787d3b9 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -574,7 +574,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
return NULL;
}
-void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
+void hci_disconnect(struct hci_conn *conn, __u8 reason);
void hci_setup_sync(struct hci_conn *conn, __u16 handle);
void hci_sco_setup(struct hci_conn *conn, __u8 status);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 4925a02..b9f9016 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -117,7 +117,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn)
hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
}
-void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
+void hci_disconnect(struct hci_conn *conn, __u8 reason)
{
struct hci_cp_disconnect cp;
@@ -253,7 +253,7 @@ static void hci_conn_disconnect(struct hci_conn *conn)
hci_amp_disconn(conn, reason);
break;
default:
- hci_acl_disconn(conn, reason);
+ hci_disconnect(conn, reason);
break;
}
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 618ca1a..388c456 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2398,7 +2398,7 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
if (c->type == type && c->sent) {
BT_ERR("%s killing stalled connection %pMR",
hdev->name, &c->dst);
- hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM);
+ hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
}
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d4fcba6..5c78480 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2399,7 +2399,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
if (ev->status && conn->state == BT_CONNECTED) {
- hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
+ hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
hci_conn_put(conn);
goto unlock;
}
@@ -3472,7 +3472,7 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
if (ev->status && conn->state == BT_CONNECTED) {
- hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
+ hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
hci_conn_put(conn);
goto unlock;
}
--
1.8.1.1
^ permalink raw reply related
* [PATCH 5/5] Bluetooth: Reduce critical section in sco_conn_ready
From: Andre Guedes @ 2013-01-29 22:59 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1359500396-8184-1-git-send-email-andre.guedes@openbossa.org>
This patch reduces the critical section protected by sco_conn_lock in
sco_conn_ready function. The lock is acquired only when it is really
needed.
This patch fixes the following lockdep warning which is generated
when the host terminates a SCO connection.
Today, this warning is a false positive. There is no way those
two threads reported by lockdep are running at the same time since
hdev->workqueue (where rx_work is queued) is single-thread. However,
if somehow this behavior is changed in future, we will have a
potential deadlock.
======================================================
[ INFO: possible circular locking dependency detected ]
3.8.0-rc1+ #7 Not tainted
-------------------------------------------------------
kworker/u:1H/1018 is trying to acquire lock:
(&(&conn->lock)->rlock){+.+...}, at: [<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
but task is already holding lock:
(slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}, at: [<ffffffffa0033d5a>] sco_conn_del+0x8a/0xe0 [bluetooth]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}:
[<ffffffff81083011>] lock_acquire+0xb1/0xe0
[<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
[<ffffffffa003436e>] sco_connect_cfm+0xbe/0x350 [bluetooth]
[<ffffffffa0015d6c>] hci_event_packet+0xd3c/0x29b0 [bluetooth]
[<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
[<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
[<ffffffff81050022>] worker_thread+0x2b2/0x3e0
[<ffffffff81056021>] kthread+0xd1/0xe0
[<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
-> #0 (&(&conn->lock)->rlock){+.+...}:
[<ffffffff81082215>] __lock_acquire+0x1465/0x1c70
[<ffffffff81083011>] lock_acquire+0xb1/0xe0
[<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
[<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
[<ffffffffa0033d6d>] sco_conn_del+0x9d/0xe0 [bluetooth]
[<ffffffffa0034653>] sco_disconn_cfm+0x53/0x60 [bluetooth]
[<ffffffffa000fef3>] hci_disconn_complete_evt.isra.54+0x363/0x3c0 [bluetooth]
[<ffffffffa00150f7>] hci_event_packet+0xc7/0x29b0 [bluetooth]
[<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
[<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
[<ffffffff81050022>] worker_thread+0x2b2/0x3e0
[<ffffffff81056021>] kthread+0xd1/0xe0
[<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
lock(&(&conn->lock)->rlock);
lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
lock(&(&conn->lock)->rlock);
*** DEADLOCK ***
4 locks held by kworker/u:1H/1018:
#0: (hdev->name#2){.+.+.+}, at: [<ffffffff8104d5f8>] process_one_work+0x258/0x4f0
#1: ((&hdev->rx_work)){+.+.+.}, at: [<ffffffff8104d5f8>] process_one_work+0x258/0x4f0
#2: (&hdev->lock){+.+.+.}, at: [<ffffffffa000fbe9>] hci_disconn_complete_evt.isra.54+0x59/0x3c0 [bluetooth]
#3: (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}, at: [<ffffffffa0033d5a>] sco_conn_del+0x8a/0xe0 [bluetooth]
stack backtrace:
Pid: 1018, comm: kworker/u:1H Not tainted 3.8.0-rc1+ #7
Call Trace:
[<ffffffff813e92f9>] print_circular_bug+0x1fb/0x20c
[<ffffffff81082215>] __lock_acquire+0x1465/0x1c70
[<ffffffff81083011>] lock_acquire+0xb1/0xe0
[<ffffffffa0033ba6>] ? sco_chan_del+0x66/0x190 [bluetooth]
[<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
[<ffffffffa0033ba6>] ? sco_chan_del+0x66/0x190 [bluetooth]
[<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
[<ffffffffa0033d6d>] sco_conn_del+0x9d/0xe0 [bluetooth]
[<ffffffffa0034653>] sco_disconn_cfm+0x53/0x60 [bluetooth]
[<ffffffffa000fef3>] hci_disconn_complete_evt.isra.54+0x363/0x3c0 [bluetooth]
[<ffffffffa000fbd0>] ? hci_disconn_complete_evt.isra.54+0x40/0x3c0 [bluetooth]
[<ffffffffa00150f7>] hci_event_packet+0xc7/0x29b0 [bluetooth]
[<ffffffff81202e90>] ? __dynamic_pr_debug+0x80/0x90
[<ffffffff8133ff7d>] ? kfree_skb+0x2d/0x40
[<ffffffffa0021644>] ? hci_send_to_monitor+0x1a4/0x1c0 [bluetooth]
[<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
[<ffffffff8104d5f8>] ? process_one_work+0x258/0x4f0
[<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
[<ffffffff8104d5f8>] ? process_one_work+0x258/0x4f0
[<ffffffff8104fdc1>] ? worker_thread+0x51/0x3e0
[<ffffffffa0004450>] ? hci_tx_work+0x800/0x800 [bluetooth]
[<ffffffff81050022>] worker_thread+0x2b2/0x3e0
[<ffffffff8104fd70>] ? busy_worker_rebind_fn+0x100/0x100
[<ffffffff81056021>] kthread+0xd1/0xe0
[<ffffffff81055f50>] ? flush_kthread_worker+0xc0/0xc0
[<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
[<ffffffff81055f50>] ? flush_kthread_worker+0xc0/0xc0
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
This lockdep warning has been around for a long time. I could test
until Linux 3.4, but it seems it is older than that. However, in
current bluetooth-next, this warning has been masked by commit
53502d69be49e3dd5bc95ab0f2deeaea260bd617 which introduced a bug in
SCO socket shutdown routine.
The bug in SCO socket shutdown routine has been fixed by patch 02/05
from this patchset.
net/bluetooth/sco.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 531a93d..e435641 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -900,8 +900,6 @@ static void sco_conn_ready(struct sco_conn *conn)
BT_DBG("conn %p", conn);
- sco_conn_lock(conn);
-
if (sk) {
sco_sock_clear_timer(sk);
bh_lock_sock(sk);
@@ -909,9 +907,13 @@ static void sco_conn_ready(struct sco_conn *conn)
sk->sk_state_change(sk);
bh_unlock_sock(sk);
} else {
+ sco_conn_lock(conn);
+
parent = sco_get_sock_listen(conn->src);
- if (!parent)
- goto done;
+ if (!parent) {
+ sco_conn_unlock(conn);
+ return;
+ }
bh_lock_sock(parent);
@@ -919,7 +921,8 @@ static void sco_conn_ready(struct sco_conn *conn)
BTPROTO_SCO, GFP_ATOMIC);
if (!sk) {
bh_unlock_sock(parent);
- goto done;
+ sco_conn_unlock(conn);
+ return;
}
sco_sock_init(sk, parent);
@@ -939,10 +942,9 @@ static void sco_conn_ready(struct sco_conn *conn)
parent->sk_data_ready(parent, 1);
bh_unlock_sock(parent);
- }
-done:
- sco_conn_unlock(conn);
+ sco_conn_unlock(conn);
+ }
}
/* ----- SCO interface with lower layer (HCI) ----- */
--
1.8.1.1
^ permalink raw reply related
* Re: [PATCH] Add heartrate monitoring LE device to auto connect list.
From: Johan Hedberg @ 2013-01-29 23:36 UTC (permalink / raw)
To: Damjan Cvetko; +Cc: linux-bluetooth
In-Reply-To: <1359408442-8002-1-git-send-email-damjan.cvetko@monotek.net>
Hi Damjan,
On Mon, Jan 28, 2013, Damjan Cvetko wrote:
> ---
> profiles/heartrate/heartrate.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/profiles/heartrate/heartrate.c b/profiles/heartrate/heartrate.c
> index 5c56d3f..1788d4f 100644
> --- a/profiles/heartrate/heartrate.c
> +++ b/profiles/heartrate/heartrate.c
> @@ -801,6 +801,8 @@ static int heartrate_device_register(struct btd_device *device,
> hr->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
> attio_disconnected_cb, hr);
>
> + device_set_auto_connect(device, TRUE);
> +
> return 0;
> }
This patch isn't needed anymore since btd_device_add_attio_callback was
fixed to enable the auto connecting. Please verify that latest git works
for you.
Johan
^ permalink raw reply
* Re: [PATCH 3/5] Bluetooth: Refactor hci_conn_disconnect
From: Marcel Holtmann @ 2013-01-30 8:01 UTC (permalink / raw)
To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <1359500396-8184-3-git-send-email-andre.guedes@openbossa.org>
Hi Andre,
> This patch does a trivial refactoring in hci_conn_disconnect function.
>
> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> ---
> net/bluetooth/hci_conn.c | 9 +++------
> 1 file changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> index 28cfa72..4925a02 100644
> --- a/net/bluetooth/hci_conn.c
> +++ b/net/bluetooth/hci_conn.c
> @@ -249,15 +249,12 @@ static void hci_conn_disconnect(struct hci_conn *conn)
> __u8 reason = hci_proto_disconn_ind(conn);
>
> switch (conn->type) {
> - case ACL_LINK:
> - case LE_LINK:
> - case SCO_LINK:
> - case ESCO_LINK:
> - hci_acl_disconn(conn, reason);
> - break;
> case AMP_LINK:
> hci_amp_disconn(conn, reason);
> break;
> + default:
> + hci_acl_disconn(conn, reason);
> + break;
> }
just make it one patch that fixes all cases. Trying to make 3 patches
out of this is just confusing. Rather write a proper commit message that
explains it all.
Regards
Marcel
^ permalink raw reply
* [PATCH v2 1/3] Bluetooth: Fix hci_conn timeout routine
From: Andre Guedes @ 2013-01-30 14:50 UTC (permalink / raw)
To: linux-bluetooth
If occurs a LE or SCO hci_conn timeout and the connection is already
established (BT_CONNECTED state), the connection is not terminated as
expected. This bug can be reproduced using l2test or scotest tool.
Once the connection is established, kill l2test/scotest and the
connection won't be terminated.
This patch fixes hci_conn_disconnect helper so it is able to
terminate LE and SCO connections, as well as ACL.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_conn.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 25bfce0..4925a02 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -249,12 +249,12 @@ static void hci_conn_disconnect(struct hci_conn *conn)
__u8 reason = hci_proto_disconn_ind(conn);
switch (conn->type) {
- case ACL_LINK:
- hci_acl_disconn(conn, reason);
- break;
case AMP_LINK:
hci_amp_disconn(conn, reason);
break;
+ default:
+ hci_acl_disconn(conn, reason);
+ break;
}
}
--
1.8.1.1
^ permalink raw reply related
* [PATCH v2 2/3] Bluetooth: Rename hci_acl_disconn
From: Andre Guedes @ 2013-01-30 14:50 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1359557457-10199-1-git-send-email-andre.guedes@openbossa.org>
As hci_acl_disconn function basically sends the HCI Disconnect Command
and it is used to disconnect ACL, SCO and LE links, renaming it to
hci_disconnect is more suitable.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/hci_conn.c | 4 ++--
net/bluetooth/hci_core.c | 2 +-
net/bluetooth/hci_event.c | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 90cf75a..787d3b9 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -574,7 +574,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
return NULL;
}
-void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
+void hci_disconnect(struct hci_conn *conn, __u8 reason);
void hci_setup_sync(struct hci_conn *conn, __u16 handle);
void hci_sco_setup(struct hci_conn *conn, __u8 status);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 4925a02..b9f9016 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -117,7 +117,7 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn)
hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
}
-void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
+void hci_disconnect(struct hci_conn *conn, __u8 reason)
{
struct hci_cp_disconnect cp;
@@ -253,7 +253,7 @@ static void hci_conn_disconnect(struct hci_conn *conn)
hci_amp_disconn(conn, reason);
break;
default:
- hci_acl_disconn(conn, reason);
+ hci_disconnect(conn, reason);
break;
}
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 618ca1a..388c456 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2398,7 +2398,7 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
if (c->type == type && c->sent) {
BT_ERR("%s killing stalled connection %pMR",
hdev->name, &c->dst);
- hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM);
+ hci_disconnect(c, HCI_ERROR_REMOTE_USER_TERM);
}
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d4fcba6..5c78480 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2399,7 +2399,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
if (ev->status && conn->state == BT_CONNECTED) {
- hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
+ hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
hci_conn_put(conn);
goto unlock;
}
@@ -3472,7 +3472,7 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
if (ev->status && conn->state == BT_CONNECTED) {
- hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
+ hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
hci_conn_put(conn);
goto unlock;
}
--
1.8.1.1
^ permalink raw reply related
* [PATCH v2 3/3] Bluetooth: Reduce critical section in sco_conn_ready
From: Andre Guedes @ 2013-01-30 14:50 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1359557457-10199-1-git-send-email-andre.guedes@openbossa.org>
This patch reduces the critical section protected by sco_conn_lock in
sco_conn_ready function. The lock is acquired only when it is really
needed.
This patch fixes the following lockdep warning which is generated
when the host terminates a SCO connection.
Today, this warning is a false positive. There is no way those
two threads reported by lockdep are running at the same time since
hdev->workqueue (where rx_work is queued) is single-thread. However,
if somehow this behavior is changed in future, we will have a
potential deadlock.
======================================================
[ INFO: possible circular locking dependency detected ]
3.8.0-rc1+ #7 Not tainted
-------------------------------------------------------
kworker/u:1H/1018 is trying to acquire lock:
(&(&conn->lock)->rlock){+.+...}, at: [<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
but task is already holding lock:
(slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}, at: [<ffffffffa0033d5a>] sco_conn_del+0x8a/0xe0 [bluetooth]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}:
[<ffffffff81083011>] lock_acquire+0xb1/0xe0
[<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
[<ffffffffa003436e>] sco_connect_cfm+0xbe/0x350 [bluetooth]
[<ffffffffa0015d6c>] hci_event_packet+0xd3c/0x29b0 [bluetooth]
[<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
[<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
[<ffffffff81050022>] worker_thread+0x2b2/0x3e0
[<ffffffff81056021>] kthread+0xd1/0xe0
[<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
-> #0 (&(&conn->lock)->rlock){+.+...}:
[<ffffffff81082215>] __lock_acquire+0x1465/0x1c70
[<ffffffff81083011>] lock_acquire+0xb1/0xe0
[<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
[<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
[<ffffffffa0033d6d>] sco_conn_del+0x9d/0xe0 [bluetooth]
[<ffffffffa0034653>] sco_disconn_cfm+0x53/0x60 [bluetooth]
[<ffffffffa000fef3>] hci_disconn_complete_evt.isra.54+0x363/0x3c0 [bluetooth]
[<ffffffffa00150f7>] hci_event_packet+0xc7/0x29b0 [bluetooth]
[<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
[<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
[<ffffffff81050022>] worker_thread+0x2b2/0x3e0
[<ffffffff81056021>] kthread+0xd1/0xe0
[<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
lock(&(&conn->lock)->rlock);
lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
lock(&(&conn->lock)->rlock);
*** DEADLOCK ***
4 locks held by kworker/u:1H/1018:
#0: (hdev->name#2){.+.+.+}, at: [<ffffffff8104d5f8>] process_one_work+0x258/0x4f0
#1: ((&hdev->rx_work)){+.+.+.}, at: [<ffffffff8104d5f8>] process_one_work+0x258/0x4f0
#2: (&hdev->lock){+.+.+.}, at: [<ffffffffa000fbe9>] hci_disconn_complete_evt.isra.54+0x59/0x3c0 [bluetooth]
#3: (slock-AF_BLUETOOTH-BTPROTO_SCO){+.+...}, at: [<ffffffffa0033d5a>] sco_conn_del+0x8a/0xe0 [bluetooth]
stack backtrace:
Pid: 1018, comm: kworker/u:1H Not tainted 3.8.0-rc1+ #7
Call Trace:
[<ffffffff813e92f9>] print_circular_bug+0x1fb/0x20c
[<ffffffff81082215>] __lock_acquire+0x1465/0x1c70
[<ffffffff81083011>] lock_acquire+0xb1/0xe0
[<ffffffffa0033ba6>] ? sco_chan_del+0x66/0x190 [bluetooth]
[<ffffffff813efd01>] _raw_spin_lock+0x41/0x80
[<ffffffffa0033ba6>] ? sco_chan_del+0x66/0x190 [bluetooth]
[<ffffffffa0033ba6>] sco_chan_del+0x66/0x190 [bluetooth]
[<ffffffffa0033d6d>] sco_conn_del+0x9d/0xe0 [bluetooth]
[<ffffffffa0034653>] sco_disconn_cfm+0x53/0x60 [bluetooth]
[<ffffffffa000fef3>] hci_disconn_complete_evt.isra.54+0x363/0x3c0 [bluetooth]
[<ffffffffa000fbd0>] ? hci_disconn_complete_evt.isra.54+0x40/0x3c0 [bluetooth]
[<ffffffffa00150f7>] hci_event_packet+0xc7/0x29b0 [bluetooth]
[<ffffffff81202e90>] ? __dynamic_pr_debug+0x80/0x90
[<ffffffff8133ff7d>] ? kfree_skb+0x2d/0x40
[<ffffffffa0021644>] ? hci_send_to_monitor+0x1a4/0x1c0 [bluetooth]
[<ffffffffa0004583>] hci_rx_work+0x133/0x870 [bluetooth]
[<ffffffff8104d5f8>] ? process_one_work+0x258/0x4f0
[<ffffffff8104d65f>] process_one_work+0x2bf/0x4f0
[<ffffffff8104d5f8>] ? process_one_work+0x258/0x4f0
[<ffffffff8104fdc1>] ? worker_thread+0x51/0x3e0
[<ffffffffa0004450>] ? hci_tx_work+0x800/0x800 [bluetooth]
[<ffffffff81050022>] worker_thread+0x2b2/0x3e0
[<ffffffff8104fd70>] ? busy_worker_rebind_fn+0x100/0x100
[<ffffffff81056021>] kthread+0xd1/0xe0
[<ffffffff81055f50>] ? flush_kthread_worker+0xc0/0xc0
[<ffffffff813f14bc>] ret_from_fork+0x7c/0xb0
[<ffffffff81055f50>] ? flush_kthread_worker+0xc0/0xc0
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
This lockdep warning has been around for a long time. I could test
until Linux 3.4, but it seems it is older than that. However, in
current bluetooth-next, this warning has been masked by commit
53502d69be49e3dd5bc95ab0f2deeaea260bd617 which introduced a bug in
SCO hci_conn timeout routine.
The bug in SCO hci_conn timeout has been fixed by patch 01/03 from
this patchset.
net/bluetooth/sco.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 531a93d..e435641 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -900,8 +900,6 @@ static void sco_conn_ready(struct sco_conn *conn)
BT_DBG("conn %p", conn);
- sco_conn_lock(conn);
-
if (sk) {
sco_sock_clear_timer(sk);
bh_lock_sock(sk);
@@ -909,9 +907,13 @@ static void sco_conn_ready(struct sco_conn *conn)
sk->sk_state_change(sk);
bh_unlock_sock(sk);
} else {
+ sco_conn_lock(conn);
+
parent = sco_get_sock_listen(conn->src);
- if (!parent)
- goto done;
+ if (!parent) {
+ sco_conn_unlock(conn);
+ return;
+ }
bh_lock_sock(parent);
@@ -919,7 +921,8 @@ static void sco_conn_ready(struct sco_conn *conn)
BTPROTO_SCO, GFP_ATOMIC);
if (!sk) {
bh_unlock_sock(parent);
- goto done;
+ sco_conn_unlock(conn);
+ return;
}
sco_sock_init(sk, parent);
@@ -939,10 +942,9 @@ static void sco_conn_ready(struct sco_conn *conn)
parent->sk_data_ready(parent, 1);
bh_unlock_sock(parent);
- }
-done:
- sco_conn_unlock(conn);
+ sco_conn_unlock(conn);
+ }
}
/* ----- SCO interface with lower layer (HCI) ----- */
--
1.8.1.1
^ permalink raw reply related
* [PATCH v2 0/4] sco: SCO socket option for mode
From: Frédéric Dalleau @ 2013-01-30 16:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
Hi,
This is the patch version 2 of the socket option for enabling transparent SCO
sockets. I kept the mode name.
The initial mode corresponding to current behavior is SCO_MODE_CVSD.
SCO_MODE_TRANSPARENT is the mode for setting up transparent data sockets.
Because it is still foggy, SCO_MODE_ENHANCED is no longer declared in this
series, it is sent as an additional RFC.
Let me know what you think.
Best regards,
Frédéric Dalleau (4):
Bluetooth: Add option for SCO socket mode
Bluetooth: Use mode to create SCO connection
Bluetooth: Parameters for outgoing SCO connections
Bluetooth: Fallback transparent SCO from T2 to T1
include/net/bluetooth/hci_core.h | 5 ++-
include/net/bluetooth/sco.h | 7 +++++
net/bluetooth/hci_conn.c | 38 ++++++++++++++++------
net/bluetooth/hci_event.c | 22 ++++++++++---
net/bluetooth/sco.c | 64 ++++++++++++++++++++++++++++++++++++--
5 files changed, 118 insertions(+), 18 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH v2 1/4] Bluetooth: Add option for SCO socket mode
From: Frédéric Dalleau @ 2013-01-30 16:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1359561800-12870-1-git-send-email-frederic.dalleau@linux.intel.com>
This patch extends the current SCO socket option to add a 'mode' field. This
field is intended to choose data type at runtime. Current modes are CVSD and
transparent SCO, but adding new modes could allow support for CSA2 and fine
tuning a sco connection, for example latency, bandwith, voice setting. Incoming
connections will be setup during defered setup. Outgoing connections have to
be setup before connect(). The selected type is stored in the sco socket info.
This patch declares needed members, modifies getsockopt() and implements
setsockopt(). Setting the mtu is not supported.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
---
include/net/bluetooth/sco.h | 7 +++++
net/bluetooth/sco.c | 59 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index 1e35c43..c8c228f 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -41,8 +41,14 @@ struct sockaddr_sco {
/* SCO socket options */
#define SCO_OPTIONS 0x01
+
+#define SCO_MODE_CVSD 0x00
+#define SCO_MODE_TRANSPARENT 0x01
+#define SCO_MODE_MAX 0x02
+
struct sco_options {
__u16 mtu;
+ __u8 mode;
};
#define SCO_CONNINFO 0x02
@@ -73,6 +79,7 @@ struct sco_conn {
struct sco_pinfo {
struct bt_sock bt;
__u32 flags;
+ __u8 mode;
struct sco_conn *conn;
};
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 531a93d..927119e6 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -418,6 +418,8 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro
sk->sk_protocol = proto;
sk->sk_state = BT_OPEN;
+ sco_pi(sk)->mode = SCO_MODE_CVSD;
+
setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
bt_sock_link(&sco_sk_list, sk);
@@ -676,6 +678,59 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
return bt_sock_recvmsg(iocb, sock, msg, len, flags);
}
+static int sco_sock_setsockopt_old(struct socket *sock, int optname,
+ char __user *optval, unsigned int optlen)
+{
+ struct sock *sk = sock->sk;
+ struct sco_options opts;
+ int len, err = 0;
+
+ BT_DBG("sk %p", sk);
+
+ lock_sock(sk);
+
+ switch (optname) {
+ case SCO_OPTIONS:
+ if (sk->sk_state != BT_OPEN &&
+ sk->sk_state != BT_BOUND &&
+ sk->sk_state != BT_CONNECT2) {
+ err = -EINVAL;
+ break;
+ }
+
+ opts.mtu = 0;
+ opts.mode = SCO_MODE_CVSD;
+
+ len = min_t(unsigned int, sizeof(opts), optlen);
+ if (copy_from_user((char *) &opts, optval, len)) {
+ err = -EFAULT;
+ break;
+ }
+
+ if (opts.mtu != 0) {
+ err = -EINVAL;
+ break;
+ }
+
+ BT_DBG("mode %d", opts.mode);
+
+ if (opts.mode >= SCO_MODE_MAX) {
+ err = -EINVAL;
+ break;
+ }
+
+ sco_pi(sk)->mode = opts.mode;
+ break;
+
+ default:
+ err = -ENOPROTOOPT;
+ break;
+ }
+
+ release_sock(sk);
+ return err;
+}
+
static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
@@ -684,6 +739,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char
BT_DBG("sk %p", sk);
+ if (level == SOL_SCO)
+ return sco_sock_setsockopt_old(sock, optname, optval, optlen);
+
lock_sock(sk);
switch (optname) {
@@ -736,6 +794,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user
}
opts.mtu = sco_pi(sk)->conn->mtu;
+ opts.mode = sco_pi(sk)->mode;
BT_DBG("mtu %d", opts.mtu);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 2/4] Bluetooth: Use mode to create SCO connection
From: Frédéric Dalleau @ 2013-01-30 16:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1359561800-12870-1-git-send-email-frederic.dalleau@linux.intel.com>
When an incoming SCO connection is requested, check the selected mode, and
reply appropriately. Mode should have been negotiated previously. For example,
in case of HFP, the codec is negotiated using AT commands on the RFCOMM
channel. This patch only changes replies for socket with defered setup enabled.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/hci_event.c | 21 +++++++++++++++++----
net/bluetooth/sco.c | 2 +-
3 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 90cf75a..494b660 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -582,7 +582,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
int hci_conn_del(struct hci_conn *conn);
void hci_conn_hash_flush(struct hci_dev *hdev);
void hci_conn_check_pending(struct hci_dev *hdev);
-void hci_conn_accept(struct hci_conn *conn, int mask);
+void hci_conn_accept(struct hci_conn *conn, int mask, int mode);
struct hci_chan *hci_chan_create(struct hci_conn *conn);
void hci_chan_del(struct hci_chan *chan);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d4fcba6..188bb83 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2095,7 +2095,7 @@ unlock:
hci_conn_check_pending(hdev);
}
-void hci_conn_accept(struct hci_conn *conn, int mask)
+void hci_conn_accept(struct hci_conn *conn, int mask, int mode)
{
struct hci_dev *hdev = conn->hdev;
@@ -2122,9 +2122,22 @@ void hci_conn_accept(struct hci_conn *conn, int mask)
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
- cp.max_latency = __constant_cpu_to_le16(0xffff);
- cp.content_format = cpu_to_le16(hdev->voice_setting);
- cp.retrans_effort = 0xff;
+
+ switch (mode) {
+ case 0:
+ cp.max_latency = __constant_cpu_to_le16(0xffff);
+ cp.content_format = cpu_to_le16(hdev->voice_setting);
+ cp.retrans_effort = 0xff;
+ break;
+ case 1:
+ if (conn->pkt_type & ESCO_2EV3)
+ cp.max_latency = __constant_cpu_to_le16(0x0008);
+ else
+ cp.max_latency = __constant_cpu_to_le16(0x000D);
+ cp.content_format = __constant_cpu_to_le16(0x0003);
+ cp.retrans_effort = 0x02;
+ break;
+ }
hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
sizeof(cp), &cp);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 927119e6..1527012 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -666,7 +666,7 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (sk->sk_state == BT_CONNECT2 &&
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
- hci_conn_accept(pi->conn->hcon, 0);
+ hci_conn_accept(pi->conn->hcon, 0, pi->mode);
sk->sk_state = BT_CONFIG;
release_sock(sk);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 3/4] Bluetooth: Parameters for outgoing SCO connections
From: Frédéric Dalleau @ 2013-01-30 16:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1359561800-12870-1-git-send-email-frederic.dalleau@linux.intel.com>
In order to establish a transparent SCO connection, the correct settings must
be specified in the SetupSynchronousConnection request. For that, a bit is set
in ACL connection flags to set up the desired parameters. If this bit is not
set, a legacy SCO connection will be requested.
This patch uses T2 settings.
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
---
include/net/bluetooth/hci_core.h | 3 +++
net/bluetooth/hci_conn.c | 29 +++++++++++++++++++----------
net/bluetooth/sco.c | 3 +--
3 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 494b660..039c263 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -443,6 +443,7 @@ enum {
HCI_CONN_SSP_ENABLED,
HCI_CONN_POWER_SAVE,
HCI_CONN_REMOTE_OOB,
+ HCI_CONN_SCO_TRANSPARENT,
};
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
@@ -591,6 +592,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,
+ u8 codec);
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);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 25bfce0..7f290ad 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -175,13 +175,22 @@ 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.max_latency = __constant_cpu_to_le16(0xffff);
- cp.voice_setting = cpu_to_le16(hdev->voice_setting);
- cp.retrans_effort = 0xff;
+
+ if (test_and_clear_bit(HCI_CONN_SCO_TRANSPARENT, &conn->flags)) {
+ cp.pkt_type = __constant_cpu_to_le16(EDR_ESCO_MASK &
+ ~ESCO_2EV3);
+ cp.max_latency = __constant_cpu_to_le16(0x000d);
+ cp.voice_setting = __constant_cpu_to_le16(0x0003);
+ cp.retrans_effort = 0x02;
+ } else {
+ 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;
+ }
hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
}
@@ -551,13 +560,13 @@ static struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
return acl;
}
-static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
- bdaddr_t *dst, u8 sec_level, u8 auth_type)
+struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ u8 codec)
{
struct hci_conn *acl;
struct hci_conn *sco;
- acl = hci_connect_acl(hdev, dst, sec_level, auth_type);
+ acl = hci_connect_acl(hdev, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
if (IS_ERR(acl))
return acl;
@@ -575,6 +584,9 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
hci_conn_hold(sco);
+ if (codec)
+ set_bit(HCI_CONN_SCO_TRANSPARENT, &sco->flags);
+
if (acl->state == BT_CONNECTED &&
(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
set_bit(HCI_CONN_POWER_SAVE, &acl->flags);
@@ -603,9 +615,6 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
return hci_connect_le(hdev, dst, dst_type, sec_level, auth_type);
case ACL_LINK:
return hci_connect_acl(hdev, dst, sec_level, auth_type);
- case SCO_LINK:
- case ESCO_LINK:
- return hci_connect_sco(hdev, type, dst, sec_level, auth_type);
}
return ERR_PTR(-EINVAL);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 1527012..3af07ce 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -176,8 +176,7 @@ static int sco_connect(struct sock *sk)
else
type = SCO_LINK;
- hcon = hci_connect(hdev, type, dst, BDADDR_BREDR, BT_SECURITY_LOW,
- HCI_AT_NO_BONDING);
+ hcon = hci_connect_sco(hdev, type, dst, sco_pi(sk)->mode);
if (IS_ERR(hcon)) {
err = PTR_ERR(hcon);
goto done;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 4/4] Bluetooth: Fallback transparent SCO from T2 to T1
From: Frédéric Dalleau @ 2013-01-30 16:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1359561800-12870-1-git-send-email-frederic.dalleau@linux.intel.com>
When initiating a transparent eSCO connection, make use of T2 settings at
first try. T2 is the recommended settings from HFP 1.6 WideBand Speech. Upon
connection failure, try T1 settings.
To know which of T2 or T1 should be used, the connection attempt index is used.
T2 failure is detected if Synchronous Connection Complete Event fails with
error 0x0d. This error code has been found experimentally by sending a T2
request to a T1 only SCO listener. It means "Connection Rejected due to
Limited resource".
Signed-off-by: Frédéric Dalleau <frederic.dalleau@linux.intel.com>
---
net/bluetooth/hci_conn.c | 11 ++++++++++-
net/bluetooth/hci_event.c | 1 +
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 7f290ad..2172d42 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -179,12 +179,21 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
- if (test_and_clear_bit(HCI_CONN_SCO_TRANSPARENT, &conn->flags)) {
+ if (conn->attempt == 1 &&
+ test_bit(HCI_CONN_SCO_TRANSPARENT, &conn->flags)) {
cp.pkt_type = __constant_cpu_to_le16(EDR_ESCO_MASK &
~ESCO_2EV3);
cp.max_latency = __constant_cpu_to_le16(0x000d);
cp.voice_setting = __constant_cpu_to_le16(0x0003);
cp.retrans_effort = 0x02;
+ } else if (conn->attempt == 2 &&
+ test_bit(HCI_CONN_SCO_TRANSPARENT, &conn->flags)) {
+ cp.pkt_type = __constant_cpu_to_le16(EDR_ESCO_MASK |
+ ESCO_EV3);
+ cp.max_latency = __constant_cpu_to_le16(0x0007);
+ cp.voice_setting = __constant_cpu_to_le16(0x0003);
+ cp.retrans_effort = 0x02;
+ clear_bit(HCI_CONN_SCO_TRANSPARENT, &conn->flags);
} else {
cp.pkt_type = cpu_to_le16(conn->pkt_type);
cp.max_latency = __constant_cpu_to_le16(0xffff);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 188bb83..86ce811 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3379,6 +3379,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
hci_conn_add_sysfs(conn);
break;
+ case 0x0d: /* No resource available */
case 0x11: /* Unsupported Feature or Parameter Value */
case 0x1c: /* SCO interval rejected */
case 0x1a: /* Unsupported Remote Feature */
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/4] sco: Integrate SCO socket option in user space.
From: Frédéric Dalleau @ 2013-01-30 17:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
Hi,
This is the required patches for taking advantage of SCO codec mode from
userspace.
Regards,
Frédéric
Frédéric Dalleau (4):
lib: Declare mode field in sco_options
scotest: Add option for SCO socket mode
btio: Add option for SCO socket mode
btiotest: Add option for SCO socket mode
btio/btio.c | 11 ++++++++---
btio/btio.h | 1 +
lib/sco.h | 1 +
tools/btiotest.c | 19 ++++++++++++++-----
tools/scotest.c | 36 ++++++++++++++++++++++++++++++++++--
5 files changed, 58 insertions(+), 10 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH 1/4] lib: Declare mode field in sco_options
From: Frédéric Dalleau @ 2013-01-30 17:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1359565384-4656-1-git-send-email-frederic.dalleau@linux.intel.com>
---
lib/sco.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/sco.h b/lib/sco.h
index 75336a5..c3a03ce 100644
--- a/lib/sco.h
+++ b/lib/sco.h
@@ -47,6 +47,7 @@ struct sockaddr_sco {
#define SCO_OPTIONS 0x01
struct sco_options {
uint16_t mtu;
+ uint8_t mode;
};
#define SCO_CONNINFO 0x02
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/4] scotest: Add option for SCO socket mode
From: Frédéric Dalleau @ 2013-01-30 17:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1359565384-4656-1-git-send-email-frederic.dalleau@linux.intel.com>
---
tools/scotest.c | 36 ++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/tools/scotest.c b/tools/scotest.c
index a40e395..ea71c41 100644
--- a/tools/scotest.c
+++ b/tools/scotest.c
@@ -58,6 +58,7 @@ static long data_size = 672;
static bdaddr_t bdaddr;
static int defer_setup = 0;
+static int mode = 0;
static float tv2fl(struct timeval tv)
{
@@ -68,6 +69,7 @@ static int do_connect(char *svr)
{
struct sockaddr_sco addr;
struct sco_conninfo conn;
+ struct sco_options opts;
socklen_t optlen;
int sk;
@@ -90,6 +92,15 @@ static int do_connect(char *svr)
goto error;
}
+ /* Add SCO options */
+ memset(&opts, 0, sizeof(opts));
+ opts.mode = mode;
+ if (setsockopt(sk, SOL_SCO, SCO_OPTIONS, &opts, sizeof(opts)) < 0) {
+ syslog(LOG_ERR, "Can't set socket options: %s (%d)",
+ strerror(errno), errno);
+ goto error;
+ }
+
/* Connect to remote device */
memset(&addr, 0, sizeof(addr));
addr.sco_family = AF_BLUETOOTH;
@@ -229,8 +240,16 @@ error:
static void dump_mode(int sk)
{
+ struct sco_options opts;
int len;
+ /* Add SCO options */
+ memset(&opts, 0, sizeof(opts));
+ opts.mode = mode;
+ if (setsockopt(sk, SOL_SCO, SCO_OPTIONS, &opts, sizeof(opts)) < 0)
+ syslog(LOG_ERR, "Can't set socket options: %s (%d)",
+ strerror(errno), errno);
+
if (defer_setup) {
len = read(sk, buf, sizeof(buf));
if (len < 0)
@@ -248,9 +267,17 @@ static void dump_mode(int sk)
static void recv_mode(int sk)
{
struct timeval tv_beg,tv_end,tv_diff;
+ struct sco_options opts;
long total;
int len;
+ /* Add SCO options */
+ memset(&opts, 0, sizeof(opts));
+ opts.mode = mode;
+ if (setsockopt(sk, SOL_SCO, SCO_OPTIONS, &opts, sizeof(opts)) < 0)
+ syslog(LOG_ERR, "Can't set socket options: %s (%d)",
+ strerror(errno), errno);
+
if (defer_setup) {
len = read(sk, buf, sizeof(buf));
if (len < 0)
@@ -381,7 +408,8 @@ static void usage(void)
"\t-n connect and be silent (client)\n"
"Options:\n"
"\t[-b bytes]\n"
- "\t[-W seconds] enable deferred setup\n");
+ "\t[-W seconds] enable deferred setup\n"
+ "\t[-M mode] select mode (sco only: 0 cvsd, 1 transparent)\n");
}
int main(int argc ,char *argv[])
@@ -389,7 +417,7 @@ int main(int argc ,char *argv[])
struct sigaction sa;
int opt, sk, mode = RECV;
- while ((opt = getopt(argc, argv, "rdscmnb:W:")) != EOF) {
+ while ((opt = getopt(argc, argv, "rdscmnb:W:M:")) != EOF) {
switch(opt) {
case 'r':
mode = RECV;
@@ -423,6 +451,10 @@ int main(int argc ,char *argv[])
defer_setup = atoi(optarg);
break;
+ case 'M':
+ mode = atoi(optarg);
+ break;
+
default:
usage();
exit(1);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 3/4] btio: Add option for SCO socket mode
From: Frédéric Dalleau @ 2013-01-30 17:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1359565384-4656-1-git-send-email-frederic.dalleau@linux.intel.com>
---
btio/btio.c | 11 ++++++++---
btio/btio.h | 1 +
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/btio/btio.c b/btio/btio.c
index bbf1208..f9afc36 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -77,6 +77,7 @@ struct set_opts {
uint8_t mode;
int flushable;
uint32_t priority;
+ uint8_t sco_mode;
};
struct connect {
@@ -720,7 +721,7 @@ static int sco_connect(int sock, const bdaddr_t *dst)
return 0;
}
-static gboolean sco_set(int sock, uint16_t mtu, GError **err)
+static gboolean sco_set(int sock, uint16_t mtu, uint8_t mode, GError **err)
{
struct sco_options sco_opt;
socklen_t len;
@@ -736,6 +737,7 @@ static gboolean sco_set(int sock, uint16_t mtu, GError **err)
}
sco_opt.mtu = mtu;
+ sco_opt.mode = mode;
if (setsockopt(sock, SOL_SCO, SCO_OPTIONS, &sco_opt,
sizeof(sco_opt)) < 0) {
ERROR_FAILED(err, "setsockopt(SCO_OPTIONS)", errno);
@@ -825,6 +827,9 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err,
case BT_IO_OPT_PRIORITY:
opts->priority = va_arg(args, int);
break;
+ case BT_IO_OPT_SCO_MODE:
+ opts->sco_mode = va_arg(args, int);
+ break;
default:
g_set_error(err, BT_IO_ERROR, EINVAL,
"Unknown option %d", opt);
@@ -1303,7 +1308,7 @@ gboolean bt_io_set(GIOChannel *io, GError **err, BtIOOption opt1, ...)
case BT_IO_RFCOMM:
return rfcomm_set(sock, opts.sec_level, opts.master, err);
case BT_IO_SCO:
- return sco_set(sock, opts.mtu, err);
+ return sco_set(sock, opts.mtu, opts.sco_mode, err);
default:
g_set_error(err, BT_IO_ERROR, EINVAL,
"Unknown BtIO type %d", type);
@@ -1370,7 +1375,7 @@ static GIOChannel *create_io(gboolean server, struct set_opts *opts,
}
if (sco_bind(sock, &opts->src, err) < 0)
goto failed;
- if (!sco_set(sock, opts->mtu, err))
+ if (!sco_set(sock, opts->mtu, opts->sco_mode, err))
goto failed;
break;
default:
diff --git a/btio/btio.h b/btio/btio.h
index a6ff5a2..e6ef990 100644
--- a/btio/btio.h
+++ b/btio/btio.h
@@ -54,6 +54,7 @@ typedef enum {
BT_IO_OPT_MODE,
BT_IO_OPT_FLUSHABLE,
BT_IO_OPT_PRIORITY,
+ BT_IO_OPT_SCO_MODE,
} BtIOOption;
typedef enum {
--
1.7.9.5
^ permalink raw reply related
* [PATCH 4/4] btiotest: Add option for SCO socket mode
From: Frédéric Dalleau @ 2013-01-30 17:03 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1359565384-4656-1-git-send-email-frederic.dalleau@linux.intel.com>
---
tools/btiotest.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/tools/btiotest.c b/tools/btiotest.c
index 7a77bb7..853d6d4 100644
--- a/tools/btiotest.c
+++ b/tools/btiotest.c
@@ -436,7 +436,8 @@ static void rfcomm_listen(const char *src, uint8_t ch, gboolean defer,
g_io_channel_unref(rc_srv);
}
-static void sco_connect(const char *src, const char *dst, gint disconn)
+static void sco_connect(const char *src, const char *dst, gint disconn,
+ gint mode)
{
struct io_data *data;
GError *err = NULL;
@@ -451,12 +452,14 @@ static void sco_connect(const char *src, const char *dst, gint disconn)
&err,
BT_IO_OPT_SOURCE, src,
BT_IO_OPT_DEST, dst,
+ BT_IO_OPT_SCO_MODE, mode,
BT_IO_OPT_INVALID);
else
data->io = bt_io_connect(connect_cb, data,
(GDestroyNotify) io_data_unref,
&err,
BT_IO_OPT_DEST, dst,
+ BT_IO_OPT_SCO_MODE, mode,
BT_IO_OPT_INVALID);
if (!data->io) {
@@ -467,7 +470,7 @@ static void sco_connect(const char *src, const char *dst, gint disconn)
}
static void sco_listen(const char *src, gboolean defer, gint reject,
- gint disconn, gint accept)
+ gint disconn, gint accept, gint mode)
{
struct io_data *data;
BtIOConnect conn;
@@ -492,11 +495,14 @@ static void sco_listen(const char *src, gboolean defer, gint reject,
(GDestroyNotify) io_data_unref,
&err,
BT_IO_OPT_SOURCE, src,
+ BT_IO_OPT_SCO_MODE, mode,
BT_IO_OPT_INVALID);
else
sco_srv = bt_io_listen(conn, cfm, data,
(GDestroyNotify) io_data_unref,
- &err, BT_IO_OPT_INVALID);
+ &err,
+ BT_IO_OPT_SCO_MODE, mode,
+ BT_IO_OPT_INVALID);
if (!sco_srv) {
printf("Listening failed: %s\n", err->message);
@@ -511,6 +517,7 @@ static gint opt_channel = -1;
static gint opt_psm = 0;
static gboolean opt_sco = FALSE;
static gboolean opt_defer = FALSE;
+static gint opt_mode = 0;
static char *opt_dev = NULL;
static gint opt_reject = -1;
static gint opt_disconn = -1;
@@ -537,6 +544,8 @@ static GOptionEntry options[] = {
"Use SCO" },
{ "defer", 'd', 0, G_OPTION_ARG_NONE, &opt_defer,
"Use DEFER_SETUP for incoming connections" },
+ { "mode", 'M', 0, G_OPTION_ARG_NONE, &opt_mode,
+ "Use specified mode (0 CVSD, 1 Transparent)" },
{ "sec-level", 'S', 0, G_OPTION_ARG_INT, &opt_sec,
"Security level" },
{ "update-sec-level", 'U', 0, G_OPTION_ARG_INT, &opt_update_sec,
@@ -602,10 +611,10 @@ int main(int argc, char *argv[])
if (opt_sco) {
if (argc > 1)
- sco_connect(opt_dev, argv[1], opt_disconn);
+ sco_connect(opt_dev, argv[1], opt_disconn, opt_mode);
else
sco_listen(opt_dev, opt_defer, opt_reject,
- opt_disconn, opt_accept);
+ opt_disconn, opt_accept, opt_mode);
}
signal(SIGTERM, sig_term);
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox