diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 9 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 11 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 18 |
3 files changed, 33 insertions, 5 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 617cf495a449..b159810f67a6 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -402,6 +402,12 @@ struct hci_conn_params { | |||
402 | 402 | ||
403 | u16 conn_min_interval; | 403 | u16 conn_min_interval; |
404 | u16 conn_max_interval; | 404 | u16 conn_max_interval; |
405 | |||
406 | enum { | ||
407 | HCI_AUTO_CONN_DISABLED, | ||
408 | HCI_AUTO_CONN_ALWAYS, | ||
409 | HCI_AUTO_CONN_LINK_LOSS, | ||
410 | } auto_connect; | ||
405 | }; | 411 | }; |
406 | 412 | ||
407 | extern struct list_head hci_dev_list; | 413 | extern struct list_head hci_dev_list; |
@@ -796,7 +802,8 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); | |||
796 | struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, | 802 | struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, |
797 | bdaddr_t *addr, u8 addr_type); | 803 | bdaddr_t *addr, u8 addr_type); |
798 | void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, | 804 | void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, |
799 | u16 conn_min_interval, u16 conn_max_interval); | 805 | u8 auto_connect, u16 conn_min_interval, |
806 | u16 conn_max_interval); | ||
800 | void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); | 807 | void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); |
801 | void hci_conn_params_clear(struct hci_dev *hdev); | 808 | void hci_conn_params_clear(struct hci_dev *hdev); |
802 | 809 | ||
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, | |||
3202 | 3202 | ||
3203 | /* This function requires the caller holds hdev->lock */ | 3203 | /* This function requires the caller holds hdev->lock */ |
3204 | void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, | 3204 | void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, |
3205 | u16 conn_min_interval, u16 conn_max_interval) | 3205 | u8 auto_connect, u16 conn_min_interval, |
3206 | u16 conn_max_interval) | ||
3206 | { | 3207 | { |
3207 | struct hci_conn_params *params; | 3208 | struct hci_conn_params *params; |
3208 | 3209 | ||
@@ -3210,6 +3211,7 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, | |||
3210 | if (params) { | 3211 | if (params) { |
3211 | params->conn_min_interval = conn_min_interval; | 3212 | params->conn_min_interval = conn_min_interval; |
3212 | params->conn_max_interval = conn_max_interval; | 3213 | params->conn_max_interval = conn_max_interval; |
3214 | params->auto_connect = auto_connect; | ||
3213 | return; | 3215 | return; |
3214 | } | 3216 | } |
3215 | 3217 | ||
@@ -3223,12 +3225,13 @@ void hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, | |||
3223 | params->addr_type = addr_type; | 3225 | params->addr_type = addr_type; |
3224 | params->conn_min_interval = conn_min_interval; | 3226 | params->conn_min_interval = conn_min_interval; |
3225 | params->conn_max_interval = conn_max_interval; | 3227 | params->conn_max_interval = conn_max_interval; |
3228 | params->auto_connect = auto_connect; | ||
3226 | 3229 | ||
3227 | list_add(¶ms->list, &hdev->le_conn_params); | 3230 | list_add(¶ms->list, &hdev->le_conn_params); |
3228 | 3231 | ||
3229 | BT_DBG("addr %pMR (type %u) conn_min_interval 0x%.4x " | 3232 | BT_DBG("addr %pMR (type %u) auto_connect %u conn_min_interval 0x%.4x " |
3230 | "conn_max_interval 0x%.4x", addr, addr_type, conn_min_interval, | 3233 | "conn_max_interval 0x%.4x", addr, addr_type, auto_connect, |
3231 | conn_max_interval); | 3234 | conn_min_interval, conn_max_interval); |
3232 | } | 3235 | } |
3233 | 3236 | ||
3234 | /* This function requires the caller holds hdev->lock */ | 3237 | /* 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) | |||
1841 | { | 1841 | { |
1842 | struct hci_ev_disconn_complete *ev = (void *) skb->data; | 1842 | struct hci_ev_disconn_complete *ev = (void *) skb->data; |
1843 | u8 reason = hci_to_mgmt_reason(ev->reason); | 1843 | u8 reason = hci_to_mgmt_reason(ev->reason); |
1844 | struct hci_conn_params *params; | ||
1844 | struct hci_conn *conn; | 1845 | struct hci_conn *conn; |
1845 | bool mgmt_connected; | 1846 | bool mgmt_connected; |
1846 | u8 type; | 1847 | u8 type; |
@@ -1868,6 +1869,23 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1868 | if (conn->type == ACL_LINK && conn->flush_key) | 1869 | if (conn->type == ACL_LINK && conn->flush_key) |
1869 | hci_remove_link_key(hdev, &conn->dst); | 1870 | hci_remove_link_key(hdev, &conn->dst); |
1870 | 1871 | ||
1872 | params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); | ||
1873 | if (params) { | ||
1874 | switch (params->auto_connect) { | ||
1875 | case HCI_AUTO_CONN_LINK_LOSS: | ||
1876 | if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT) | ||
1877 | break; | ||
1878 | /* Fall through */ | ||
1879 | |||
1880 | case HCI_AUTO_CONN_ALWAYS: | ||
1881 | hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type); | ||
1882 | break; | ||
1883 | |||
1884 | default: | ||
1885 | break; | ||
1886 | } | ||
1887 | } | ||
1888 | |||
1871 | type = conn->type; | 1889 | type = conn->type; |
1872 | 1890 | ||
1873 | hci_proto_disconn_cfm(conn, ev->reason); | 1891 | hci_proto_disconn_cfm(conn, ev->reason); |