[Bluetooth] Support create connection cancel command

In case of non-blocking connects it is possible that the last user
of an ACL link quits before the connection has been fully established.
This will lead to a race condition where the internal state of a
connection is closed, but the actual link has been established and is
active. In case of Bluetooth 1.2 and later devices it is possible to
call create connection cancel to abort the connect. For older devices
the disconnect timer will be used to trigger the needed disconnect.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
Marcel Holtmann
2006-09-26 09:43:48 +02:00
committed by David S. Miller
parent 1143e5a6d4
commit 6ac59344ef
4 changed files with 43 additions and 7 deletions

View File

@ -84,6 +84,20 @@ static void hci_acl_connect(struct hci_conn *conn)
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
}
static void hci_acl_connect_cancel(struct hci_conn *conn)
{
struct hci_cp_create_conn_cancel cp;
BT_DBG("%p", conn);
if (conn->hdev->hci_ver < 2)
return;
bacpy(&cp.bdaddr, &conn->dst);
hci_send_cmd(conn->hdev, OGF_LINK_CTL,
OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp);
}
void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
{
struct hci_cp_disconnect cp;
@ -94,7 +108,8 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
cp.handle = __cpu_to_le16(conn->handle);
cp.reason = reason;
hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, sizeof(cp), &cp);
hci_send_cmd(conn->hdev, OGF_LINK_CTL,
OCF_DISCONNECT, sizeof(cp), &cp);
}
void hci_add_sco(struct hci_conn *conn, __u16 handle)
@ -124,12 +139,20 @@ static void hci_conn_timeout(unsigned long arg)
return;
hci_dev_lock(hdev);
if (conn->state == BT_CONNECTED)
switch (conn->state) {
case BT_CONNECT:
hci_acl_connect_cancel(conn);
break;
case BT_CONNECTED:
hci_acl_disconn(conn, 0x13);
else
break;
default:
conn->state = BT_CLOSED;
break;
}
hci_dev_unlock(hdev);
return;
}
static void hci_conn_idle(unsigned long arg)