Message ID | 20200311191939.v2.1.I12c0712e93f74506385b67c6df287658c8fdad04@changeid (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Marcel Holtmann |
Headers | show |
Series | [v2] Bluetooth: clean up connection in hci_cs_disconnect | expand |
Hi Manish, > In bluetooth core specification 4.2, > Vol 2, Part E, 7.8.9 LE Set Advertise Enable Command, it says > > The Controller shall continue advertising until ... > or until a connection is created or ... > In these cases, advertising is then disabled. > > Hence, advertising would be disabled before a connection is > established. In current kernel implementation, advertising would > be re-enabled when all connections are terminated. > > The correct disconnection flow looks like > > < HCI Command: Disconnect > >> HCI Event: Command Status > Status: Success > >> HCI Event: Disconnect Complete > Status: Success > > Specifically, the last Disconnect Complete Event would trigger a > callback function hci_event.c:hci_disconn_complete_evt() to > cleanup the connection and re-enable advertising when proper. > > However, sometimes, there might occur an exception in the controller > when disconnection is being executed. The disconnection flow might > then look like > > < HCI Command: Disconnect > >> HCI Event: Command Status > Status: Unknown Connection Identifier > > Note that "> HCI Event: Disconnect Complete" is missing when such an > exception occurs. This would result in advertising staying disabled > forever since the connection in question is not cleaned up correctly. > > To fix the controller exception issue, we need to do some connection > cleanup when the disconnect command status indicates an error. > > Signed-off-by: Joseph Hwang <josephsih@chromium.org> > Signed-off-by: Manish Mandlik <mmandlik@google.com> > --- > > Changes in v2: > - Moved "u8 type" declaration inside if block > > net/bluetooth/hci_event.c | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) patch has been applied to bluetooth-next tree. Regards Marcel
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a40ed31f6eb8f..a116114279107 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2202,10 +2202,22 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); - if (conn) + if (conn) { + u8 type = conn->type; + mgmt_disconnect_failed(hdev, &conn->dst, conn->type, conn->dst_type, status); + /* If the disconnection failed for any reason, the upper layer + * does not retry to disconnect in current implementation. + * Hence, we need to do some basic cleanup here and re-enable + * advertising if necessary. + */ + hci_conn_del(conn); + if (type == LE_LINK) + hci_req_reenable_advertising(hdev); + } + hci_dev_unlock(hdev); }