diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_core.c | 11 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 18 |
2 files changed, 25 insertions, 4 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 9a08f341f0a4..f4224dc58e4d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3202,7 +3202,8 @@ struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, /* This function requires the caller holds hdev->lock */ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, - u16 conn_min_interval, u16 conn_max_interval) + u8 auto_connect, u16 conn_min_interval, + u16 conn_max_interval) { struct hci_conn_params *params; @@ -3210,6 +3211,7 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, if (params) { params->conn_min_interval = conn_min_interval; params->conn_max_interval = conn_max_interval; + params->auto_connect = auto_connect; return; } @@ -3223,12 +3225,13 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, params->addr_type = addr_type; params->conn_min_interval = conn_min_interval; params->conn_max_interval = conn_max_interval; + params->auto_connect = auto_connect; list_add(¶ms->list, &hdev->le_conn_params); - BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x " - "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval, - conn_max_interval); + BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x " + "conn_max_interval 0x%.4x", addr, addr_type, auto_connect, + conn_min_interval, conn_max_interval); } /* This function requires the caller holds hdev->lock */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index b6631d7e2ddf..46da8b6f4368 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1841,6 +1841,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_disconn_complete *ev = (void *) skb->data; u8 reason = hci_to_mgmt_reason(ev->reason); + struct hci_conn_params *params; struct hci_conn *conn; bool mgmt_connected; u8 type; @@ -1868,6 +1869,23 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) if (conn->type == ACL_LINK && conn->flush_key) hci_remove_link_key(hdev, &conn->dst); + params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); + if (params) { + switch (params->auto_connect) { + case HCI_AUTO_CONN_LINK_LOSS: + if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) + break; + /* Fall through */ + + case HCI_AUTO_CONN_ALWAYS: + hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type); + break; + + default: + break; + } + } + type = conn->type; hci_proto_disconn_cfm(conn, ev->reason); |