Re: bug? kernel does not send HCI Create Connection Cancel Command on shutdown() or close() of a connecting rfcomm socket

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jul 13, 2009 at 2:27 PM, Luiz Augusto von
Dentz<luiz.dentz@xxxxxxxxx> wrote:
> Hi Nick,
>
> On Mon, Jul 13, 2009 at 12:46 PM, Nick Pelly<npelly@xxxxxxxxxx> wrote:
>> Any comments on this patch?
>>
>> It works for me, but my understanding of the RFCOMM state machine is naive.
>>
>
> iirc BT_CONFIG(PN frame) means the DLC is being configured than we got
> into connecting phase (BT_CONNECT) and send SABM frame. Only when
> receiving UA frame DLC is consider connected (BT_CONNECTED), so your
> patch seems good by assuming that we don't need to send a DISC for a
> DLC not connected. But there is still a good use for it to cancel the
> DLC connection attempt, so perhaps a better alternative would be to
> use a much shorter timeout in those cases.

Thanks for the advice.

I have prepared a new patch which uses a very short timeout (10ms) on
the DLC disconnect when in BT_CONFIG. I have tested this patch and it
also resolves the issue. Patch attached.

Nick
From 80bc07e9703e4303f04c26158b096bcbd00fd665 Mon Sep 17 00:00:00 2001
From: Nick Pelly <npelly@xxxxxxxxxx>
Date: Tue, 14 Jul 2009 07:57:54 -0700
Subject: [PATCH] Bluetooth: Use a very short timeout for dlci disconnect when in BT_CONFIG.

This fixes a bug where shutdown() and close() on a rfcomm socket during ACL
connection would not cause HCI Create Connection Cancel.

Signed-off-by: Nick Pelly <npelly@xxxxxxxxxx>
---
 include/net/bluetooth/rfcomm.h |    7 ++++---
 net/bluetooth/rfcomm/core.c    |   10 +++++++---
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 8007261..eeb3ffa 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -26,9 +26,10 @@
 
 #define RFCOMM_PSM 3
 
-#define RFCOMM_CONN_TIMEOUT (HZ * 30)
-#define RFCOMM_DISC_TIMEOUT (HZ * 20)
-#define RFCOMM_AUTH_TIMEOUT (HZ * 25)
+#define RFCOMM_CONN_TIMEOUT 		(HZ * 30)
+#define RFCOMM_DISC_TIMEOUT 		(HZ * 20)
+#define RFCOMM_AUTH_TIMEOUT 		(HZ * 25)
+#define RFCOMM_CONFIG_DISC_TIMEOUT 	(HZ / 100)
 
 #define RFCOMM_DEFAULT_MTU	127
 #define RFCOMM_DEFAULT_CREDITS	7
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 1d0fb0f..476d856 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -419,6 +419,7 @@ int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 chann
 
 static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
 {
+	long timeout = RFCOMM_DISC_TIMEOUT;
 	struct rfcomm_session *s = d->session;
 	if (!s)
 		return 0;
@@ -427,8 +428,11 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
 			d, d->state, d->dlci, err, s);
 
 	switch (d->state) {
-	case BT_CONNECT:
 	case BT_CONFIG:
+		timeout = RFCOMM_CONFIG_DISC_TIMEOUT;
+		/* Fall-through */
+
+	case BT_CONNECT:
 		if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
 			set_bit(RFCOMM_AUTH_REJECT, &d->flags);
 			rfcomm_schedule(RFCOMM_SCHED_AUTH);
@@ -440,10 +444,10 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
 		d->state = BT_DISCONN;
 		if (skb_queue_empty(&d->tx_queue)) {
 			rfcomm_send_disc(s, d->dlci);
-			rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
+			rfcomm_dlc_set_timer(d, timeout);
 		} else {
 			rfcomm_queue_disc(d);
-			rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
+			rfcomm_dlc_set_timer(d, timeout * 2);
 		}
 		break;
 
-- 
1.6.3.1


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux