2003-12-21 01:52:32

by Marcel Holtmann

[permalink] [raw]
Subject: [Bluez-devel] Apple mouse and disconnect problem

Hi Folks,

I played with the Apple Bluetooth mouse and I had a problem with the
termination of the ACL link after the two L2CAP channels are closed. The
ACL link still stays there, but not always. After a long time of testing
and tracking possible errors I found that the Apple mouse itself never
terminates the ACL link (like it does not role switch itself or go to
sniff mode after idle time). So the host stack has to terminate the ACL
link if no other L2CAP connection is open. In the case of BlueZ we do
this only for outgoing and not for incoming ones. And this means that if
the mouse reconnects the ACL link will never closed if we terminate the
connection because of idle time or because the bthid daemon was shut
down. I looked through the revisions of the HCI core code, but we never
close the ACL link if the connection was not created by us and so I must
assume that no one else had this problem before. However the relevant
code is in include/net/bluetooth/hci_core.h

static inline void hci_conn_put(struct hci_conn *conn)
{
if (atomic_dec_and_test(&conn->refcnt)) {
if (conn->type == SCO_LINK)
hci_conn_set_timer(conn, HZ / 100);
else if (conn->out)
hci_conn_set_timer(conn, HCI_DISCONN_TIMEOUT);
}
}

My question is now, why we only initiate the disconnect timer for
outgoing connections? Is the device that creates the ACL link also
responsible for its termination? If yes, why the hell is the Bluetooth
stack on the Apple mouse not doing this and how did this device then got
qualified?

I used the attached patch and everything seems to be ok. Any comments?

Regards

Marcel


Attachments:
patch (540.00 B)

2004-01-05 17:15:20

by Steven Singer

[permalink] [raw]
Subject: Re: [Bluez-devel] Apple mouse and disconnect problem

> So the question is if it is ok if both ends call hci_disconnect? Do you
> have seen any problems both ends are trying to terminate the ACL link?
> How do the link manager handles this? I can't find any valuable comment
> in the specification or the profiles which end should terminate the ACL
> link.

In theory link managers should handle this fine. If they don't then it's
a bug in the link manager and not the host's fault. Just be aware of the
race hazard. You may get two disconnection_complete events one with an
error code.

Note that when I say that a disconnection_complete event is flagged with
an error, I mean that the status field is non-zero, not that the reason
field is non-zero.

So I'd expect something like (local side wins the race):

v Disconnect hnd:h
^ Command_Status Pending
^ Disconnect_Complete Success hnd:h Connection_Terminated_By_Local_Host

or (local side loses the race):

v Disconnect hnd:h
^ Disconnect_Complete Success hnd:h Other_End_Terminated_Connection:...
^ Command_Status No_Connection

or (if the race is a little closer and the link manager is not taking
special care to avoid this situation):

v Disconnect hnd:h
^ Command_Status Pending
^ Disconnect_Complete Success hnd:h Other_End_Terminated_Connection:...
^ Disconnect_Complete No_Connection hnd:h

Note, however, that these are no worse than the races you get if you try
to disconnect a link just as the supervision timeout fires.

I'm straining my memory here, but I vaguely recall having seen bugs with
this race in some link managers in the distant past so you should be
robust against suprious errors. One likely error is to get two successful
disconnection_complete events for the same handle (you should either get
just one or the second should be flagged with an error). A second
possible error is that you get two disconnection_complete events and one
is marked with an invalid connection handle (such as 0x0000).

My memory is a little hazy - I may be confusing this scenario with other
problems I've seen in the past (they all blur into one after a while).

Basically, every level in the stack should be able to cope with abrupt
and unexpected disconnections as they have to be able to cope with
supervision timeouts. Once you get above HCI, apart from the reason code
in the disconnection_complete event, there's no difference between a
supervision timeout and the remote end cleanly terminating the link.

- Steven
--



**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

This footnote also confirms that this email message has been swept by
MIMEsweeper for the presence of computer viruses.

http://www.mimesweeper.com
**********************************************************************

2004-01-05 16:52:33

by Chris Hubball

[permalink] [raw]
Subject: RE: [Bluez-devel] Apple mouse and disconnect problem

Hi Marcel,

There shouldn't be any problems with both sides sending HCI_disconnect
at the same time. When the connection closes, both sides receive
HCI_Disconnect_Complete whichever end detached. They only part that may
be misleading is that the Error code may state that the other end closed
it when you thought you had!

Chris.

-----Original Message-----
From: Marcel Holtmann [mailto:[email protected]]=20
Sent: 05 January 2004 16:27
To: Chris Hubball
Cc: BlueZ Mailing List
Subject: RE: [Bluez-devel] Apple mouse and disconnect problem


Hi Chris,

> There is no defined "owner" of an ACL connection mainly because the=20
> L2CAP connections on top of it can be established by either end.
>=20
> From general interop experience, if you close the last L2CAP=20
> connection on the ACL, you should also disconnect the ACL. Not sure=20
> if you've got this feature, but it's also a nice idea to add a timeout

> before closing an ACL as it's common to open another L2CAP connection=20
> immediately after e.g. SDP search followed by HID. This saves the=20
> paging time to re-open the ACL.

we got all these things, but we only take care of the ACL links that we
set up. If the other side reconnects to us and had to create an ACL link
(because none exists) we don't terminate the ACL link after the timeout.
So the question is if it is ok if both ends call hci_disconnect? Do you
have seen any problems both ends are trying to terminate the ACL link?
How do the link manager handles this? I can't find any valuable comment
in the specification or the profiles which end should terminate the ACL
link.

Regards

Marcel




**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

This footnote also confirms that this email message has been swept by
MIMEsweeper for the presence of computer viruses.

http://www.mimesweeper.com
**********************************************************************

2004-01-05 16:27:00

by Marcel Holtmann

[permalink] [raw]
Subject: RE: [Bluez-devel] Apple mouse and disconnect problem

Hi Chris,

> There is no defined "owner" of an ACL connection mainly because the
> L2CAP connections on top of it can be established by either end.
>
> From general interop experience, if you close the last L2CAP connection
> on the ACL, you should also disconnect the ACL. Not sure if you've got
> this feature, but it's also a nice idea to add a timeout before closing
> an ACL as it's common to open another L2CAP connection immediately after
> e.g. SDP search followed by HID. This saves the paging time to re-open
> the ACL.

we got all these things, but we only take care of the ACL links that we
set up. If the other side reconnects to us and had to create an ACL link
(because none exists) we don't terminate the ACL link after the timeout.
So the question is if it is ok if both ends call hci_disconnect? Do you
have seen any problems both ends are trying to terminate the ACL link?
How do the link manager handles this? I can't find any valuable comment
in the specification or the profiles which end should terminate the ACL
link.

Regards

Marcel




-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills. Sign up for IBM's
Free Linux Tutorials. Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel

2004-01-05 16:07:16

by Chris Hubball

[permalink] [raw]
Subject: RE: [Bluez-devel] Apple mouse and disconnect problem

Hi,

There is no defined "owner" of an ACL connection mainly because the
L2CAP connections on top of it can be established by either end.

>From general interop experience, if you close the last L2CAP connection
on the ACL, you should also disconnect the ACL. Not sure if you've got
this feature, but it's also a nice idea to add a timeout before closing
an ACL as it's common to open another L2CAP connection immediately after
e.g. SDP search followed by HID. This saves the paging time to re-open
the ACL.

Chris.

-------- Original Message --------
Subject: [Bluez-devel] Apple mouse and disconnect problem
Date: Sun, 21 Dec 2003 02:52:32 +0100
From: Marcel Holtmann <[email protected]>
To: BlueZ Mailing List <[email protected]>

Hi Folks,

I played with the Apple Bluetooth mouse and I had a problem with the
termination of the ACL link after the two L2CAP channels are closed. The
ACL link still stays there, but not always. After a long time of testing
and tracking possible errors I found that the Apple mouse itself never
terminates the ACL link (like it does not role switch itself or go to
sniff mode after idle time). So the host stack has to terminate the ACL
link if no other L2CAP connection is open. In the case of BlueZ we do
this only for outgoing and not for incoming ones. And this means that if
the mouse reconnects the ACL link will never closed if we terminate the
connection because of idle time or because the bthid daemon was shut
down. I looked through the revisions of the HCI core code, but we never
close the ACL link if the connection was not created by us and so I must
assume that no one else had this problem before. However the relevant
code is in include/net/bluetooth/hci_core.h

static inline void hci_conn_put(struct hci_conn *conn)
{
if (atomic_dec_and_test(&conn->refcnt)) {
if (conn->type =3D=3D SCO_LINK)
hci_conn_set_timer(conn, HZ / 100);
else if (conn->out)
hci_conn_set_timer(conn,
HCI_DISCONN_TIMEOUT);
}
}

My question is now, why we only initiate the disconnect timer for
outgoing connections? Is the device that creates the ACL link also
responsible for its termination? If yes, why the hell is the Bluetooth
stack on the Apple mouse not doing this and how did this device then got
qualified?

I used the attached patch and everything seems to be ok. Any comments?

Regards

Marcel




--=20


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

This footnote also confirms that this email message has been swept by
MIMEsweeper for the presence of computer viruses.

http://www.mimesweeper.com
**********************************************************************



-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills. Sign up for IBM's
Free Linux Tutorials. Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel