aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-02-12 08:02:50 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:43 -0500
commit2950f21acb0f6b8fcd964485c2ebf1e06545ac20 (patch)
treea38b8c5a78849b9c88df24abe51d4e9c3a35424a /net/bluetooth/hci_conn.c
parentf29972de8e7476706ab3c01304a505e7c95d9040 (diff)
Bluetooth: Ask upper layers for HCI disconnect reason
Some of the qualification tests demand that in case of failures in L2CAP the HCI disconnect should indicate a reason why L2CAP fails. This is a bluntly layer violation since multiple L2CAP connections could be using the same ACL and thus forcing a disconnect reason is not a good idea. To comply with the Bluetooth test specification, the disconnect reason is now stored in the L2CAP connection structure and every time a new L2CAP channel is added it will set back to its default. So only in the case where the L2CAP channel with the disconnect reason is really the last one, it will propagated to the HCI layer. The HCI layer has been extended with a disconnect indication that allows it to ask upper layers for a disconnect reason. The upper layer must not support this callback and in that case it will nicely default to the existing behavior. If an upper layer like L2CAP can provide a disconnect reason that one will be used to disconnect the ACL or SCO link. No modification to the ACL disconnect timeout have been made. So in case of Linux to Linux connection the initiator will disconnect the ACL link before the acceptor side can signal the specific disconnect reason. That is perfectly fine since Linux doesn't make use of this value anyway. The L2CAP layer has a perfect valid error code for rejecting connection due to a security violation. It is unclear why the Bluetooth specification insists on having specific HCI disconnect reason. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index dcdaa4be7847..96281a11a186 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -159,6 +159,7 @@ static void hci_conn_timeout(unsigned long arg)
159{ 159{
160 struct hci_conn *conn = (void *) arg; 160 struct hci_conn *conn = (void *) arg;
161 struct hci_dev *hdev = conn->hdev; 161 struct hci_dev *hdev = conn->hdev;
162 __u8 reason;
162 163
163 BT_DBG("conn %p state %d", conn, conn->state); 164 BT_DBG("conn %p state %d", conn, conn->state);
164 165
@@ -177,7 +178,8 @@ static void hci_conn_timeout(unsigned long arg)
177 break; 178 break;
178 case BT_CONFIG: 179 case BT_CONFIG:
179 case BT_CONNECTED: 180 case BT_CONNECTED:
180 hci_acl_disconn(conn, 0x13); 181 reason = hci_proto_disconn_ind(conn);
182 hci_acl_disconn(conn, reason);
181 break; 183 break;
182 default: 184 default:
183 conn->state = BT_CLOSED; 185 conn->state = BT_CLOSED;
@@ -562,7 +564,7 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
562 564
563 hci_conn_del_sysfs(c); 565 hci_conn_del_sysfs(c);
564 566
565 hci_proto_disconn_ind(c, 0x16); 567 hci_proto_disconn_cfm(c, 0x16);
566 hci_conn_del(c); 568 hci_conn_del(c);
567 } 569 }
568} 570}