diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 27 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 9 |
4 files changed, 34 insertions, 4 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 996ed065b6c2..747a0c3d9947 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -458,6 +458,7 @@ struct hci_conn_params { | |||
458 | enum { | 458 | enum { |
459 | HCI_AUTO_CONN_DISABLED, | 459 | HCI_AUTO_CONN_DISABLED, |
460 | HCI_AUTO_CONN_REPORT, | 460 | HCI_AUTO_CONN_REPORT, |
461 | HCI_AUTO_CONN_DIRECT, | ||
461 | HCI_AUTO_CONN_ALWAYS, | 462 | HCI_AUTO_CONN_ALWAYS, |
462 | HCI_AUTO_CONN_LINK_LOSS, | 463 | HCI_AUTO_CONN_LINK_LOSS, |
463 | } auto_connect; | 464 | } auto_connect; |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 078f1ecbc058..d8f91d5b0e56 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -3647,6 +3647,7 @@ int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, | |||
3647 | list_add(¶ms->action, &hdev->pend_le_reports); | 3647 | list_add(¶ms->action, &hdev->pend_le_reports); |
3648 | hci_update_background_scan(hdev); | 3648 | hci_update_background_scan(hdev); |
3649 | break; | 3649 | break; |
3650 | case HCI_AUTO_CONN_DIRECT: | ||
3650 | case HCI_AUTO_CONN_ALWAYS: | 3651 | case HCI_AUTO_CONN_ALWAYS: |
3651 | if (!is_connected(hdev, addr, addr_type)) { | 3652 | if (!is_connected(hdev, addr, addr_type)) { |
3652 | list_add(¶ms->action, &hdev->pend_le_conns); | 3653 | list_add(¶ms->action, &hdev->pend_le_conns); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 293dd98ae98f..ba26fbfe481a 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2259,6 +2259,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2259 | break; | 2259 | break; |
2260 | /* Fall through */ | 2260 | /* Fall through */ |
2261 | 2261 | ||
2262 | case HCI_AUTO_CONN_DIRECT: | ||
2262 | case HCI_AUTO_CONN_ALWAYS: | 2263 | case HCI_AUTO_CONN_ALWAYS: |
2263 | list_del_init(¶ms->action); | 2264 | list_del_init(¶ms->action); |
2264 | list_add(¶ms->action, &hdev->pend_le_conns); | 2265 | list_add(¶ms->action, &hdev->pend_le_conns); |
@@ -4251,6 +4252,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, | |||
4251 | u8 addr_type, u8 adv_type) | 4252 | u8 addr_type, u8 adv_type) |
4252 | { | 4253 | { |
4253 | struct hci_conn *conn; | 4254 | struct hci_conn *conn; |
4255 | struct hci_conn_params *params; | ||
4254 | 4256 | ||
4255 | /* If the event is not connectable don't proceed further */ | 4257 | /* If the event is not connectable don't proceed further */ |
4256 | if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) | 4258 | if (adv_type != LE_ADV_IND && adv_type != LE_ADV_DIRECT_IND) |
@@ -4269,8 +4271,31 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, | |||
4269 | /* If we're not connectable only connect devices that we have in | 4271 | /* If we're not connectable only connect devices that we have in |
4270 | * our pend_le_conns list. | 4272 | * our pend_le_conns list. |
4271 | */ | 4273 | */ |
4272 | if (!hci_pend_le_action_lookup(&hdev->pend_le_conns, addr, addr_type)) | 4274 | params = hci_pend_le_action_lookup(&hdev->pend_le_conns, |
4275 | addr, addr_type); | ||
4276 | if (!params) | ||
4277 | return; | ||
4278 | |||
4279 | switch (params->auto_connect) { | ||
4280 | case HCI_AUTO_CONN_DIRECT: | ||
4281 | /* Only devices advertising with ADV_DIRECT_IND are | ||
4282 | * triggering a connection attempt. This is allowing | ||
4283 | * incoming connections from slave devices. | ||
4284 | */ | ||
4285 | if (adv_type != LE_ADV_DIRECT_IND) | ||
4286 | return; | ||
4287 | break; | ||
4288 | case HCI_AUTO_CONN_ALWAYS: | ||
4289 | /* Devices advertising with ADV_IND or ADV_DIRECT_IND | ||
4290 | * are triggering a connection attempt. This means | ||
4291 | * that incoming connectioms from slave device are | ||
4292 | * accepted and also outgoing connections to slave | ||
4293 | * devices are established when found. | ||
4294 | */ | ||
4295 | break; | ||
4296 | default: | ||
4273 | return; | 4297 | return; |
4298 | } | ||
4274 | 4299 | ||
4275 | conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, | 4300 | conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, |
4276 | HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); | 4301 | HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 190668367e42..ccc4653ce658 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -5271,7 +5271,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, | |||
5271 | MGMT_STATUS_INVALID_PARAMS, | 5271 | MGMT_STATUS_INVALID_PARAMS, |
5272 | &cp->addr, sizeof(cp->addr)); | 5272 | &cp->addr, sizeof(cp->addr)); |
5273 | 5273 | ||
5274 | if (cp->action != 0x00 && cp->action != 0x01) | 5274 | if (cp->action != 0x00 && cp->action != 0x01 && cp->action != 0x02) |
5275 | return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, | 5275 | return cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, |
5276 | MGMT_STATUS_INVALID_PARAMS, | 5276 | MGMT_STATUS_INVALID_PARAMS, |
5277 | &cp->addr, sizeof(cp->addr)); | 5277 | &cp->addr, sizeof(cp->addr)); |
@@ -5281,7 +5281,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, | |||
5281 | if (cp->addr.type == BDADDR_BREDR) { | 5281 | if (cp->addr.type == BDADDR_BREDR) { |
5282 | bool update_scan; | 5282 | bool update_scan; |
5283 | 5283 | ||
5284 | /* Only "connect" action supported for now */ | 5284 | /* Only incoming connections action is supported for now */ |
5285 | if (cp->action != 0x01) { | 5285 | if (cp->action != 0x01) { |
5286 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, | 5286 | err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, |
5287 | MGMT_STATUS_INVALID_PARAMS, | 5287 | MGMT_STATUS_INVALID_PARAMS, |
@@ -5307,8 +5307,10 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, | |||
5307 | else | 5307 | else |
5308 | addr_type = ADDR_LE_DEV_RANDOM; | 5308 | addr_type = ADDR_LE_DEV_RANDOM; |
5309 | 5309 | ||
5310 | if (cp->action) | 5310 | if (cp->action == 0x02) |
5311 | auto_conn = HCI_AUTO_CONN_ALWAYS; | 5311 | auto_conn = HCI_AUTO_CONN_ALWAYS; |
5312 | else if (cp->action == 0x01) | ||
5313 | auto_conn = HCI_AUTO_CONN_DIRECT; | ||
5312 | else | 5314 | else |
5313 | auto_conn = HCI_AUTO_CONN_REPORT; | 5315 | auto_conn = HCI_AUTO_CONN_REPORT; |
5314 | 5316 | ||
@@ -5870,6 +5872,7 @@ static void restart_le_actions(struct hci_dev *hdev) | |||
5870 | list_del_init(&p->action); | 5872 | list_del_init(&p->action); |
5871 | 5873 | ||
5872 | switch (p->auto_connect) { | 5874 | switch (p->auto_connect) { |
5875 | case HCI_AUTO_CONN_DIRECT: | ||
5873 | case HCI_AUTO_CONN_ALWAYS: | 5876 | case HCI_AUTO_CONN_ALWAYS: |
5874 | list_add(&p->action, &hdev->pend_le_conns); | 5877 | list_add(&p->action, &hdev->pend_le_conns); |
5875 | break; | 5878 | break; |