diff options
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 88 |
1 files changed, 77 insertions, 11 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 3163330cd4f1..ea7f031f3b04 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -53,11 +53,13 @@ static void hci_le_connect(struct hci_conn *conn) | |||
53 | conn->state = BT_CONNECT; | 53 | conn->state = BT_CONNECT; |
54 | conn->out = 1; | 54 | conn->out = 1; |
55 | conn->link_mode |= HCI_LM_MASTER; | 55 | conn->link_mode |= HCI_LM_MASTER; |
56 | conn->sec_level = BT_SECURITY_LOW; | ||
56 | 57 | ||
57 | memset(&cp, 0, sizeof(cp)); | 58 | memset(&cp, 0, sizeof(cp)); |
58 | cp.scan_interval = cpu_to_le16(0x0004); | 59 | cp.scan_interval = cpu_to_le16(0x0004); |
59 | cp.scan_window = cpu_to_le16(0x0004); | 60 | cp.scan_window = cpu_to_le16(0x0004); |
60 | bacpy(&cp.peer_addr, &conn->dst); | 61 | bacpy(&cp.peer_addr, &conn->dst); |
62 | cp.peer_addr_type = conn->dst_type; | ||
61 | cp.conn_interval_min = cpu_to_le16(0x0008); | 63 | cp.conn_interval_min = cpu_to_le16(0x0008); |
62 | cp.conn_interval_max = cpu_to_le16(0x0100); | 64 | cp.conn_interval_max = cpu_to_le16(0x0100); |
63 | cp.supervision_timeout = cpu_to_le16(0x0064); | 65 | cp.supervision_timeout = cpu_to_le16(0x0064); |
@@ -203,6 +205,55 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, | |||
203 | } | 205 | } |
204 | EXPORT_SYMBOL(hci_le_conn_update); | 206 | EXPORT_SYMBOL(hci_le_conn_update); |
205 | 207 | ||
208 | void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], | ||
209 | __u8 ltk[16]) | ||
210 | { | ||
211 | struct hci_dev *hdev = conn->hdev; | ||
212 | struct hci_cp_le_start_enc cp; | ||
213 | |||
214 | BT_DBG("%p", conn); | ||
215 | |||
216 | memset(&cp, 0, sizeof(cp)); | ||
217 | |||
218 | cp.handle = cpu_to_le16(conn->handle); | ||
219 | memcpy(cp.ltk, ltk, sizeof(cp.ltk)); | ||
220 | cp.ediv = ediv; | ||
221 | memcpy(cp.rand, rand, sizeof(rand)); | ||
222 | |||
223 | hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp); | ||
224 | } | ||
225 | EXPORT_SYMBOL(hci_le_start_enc); | ||
226 | |||
227 | void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]) | ||
228 | { | ||
229 | struct hci_dev *hdev = conn->hdev; | ||
230 | struct hci_cp_le_ltk_reply cp; | ||
231 | |||
232 | BT_DBG("%p", conn); | ||
233 | |||
234 | memset(&cp, 0, sizeof(cp)); | ||
235 | |||
236 | cp.handle = cpu_to_le16(conn->handle); | ||
237 | memcpy(cp.ltk, ltk, sizeof(ltk)); | ||
238 | |||
239 | hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); | ||
240 | } | ||
241 | EXPORT_SYMBOL(hci_le_ltk_reply); | ||
242 | |||
243 | void hci_le_ltk_neg_reply(struct hci_conn *conn) | ||
244 | { | ||
245 | struct hci_dev *hdev = conn->hdev; | ||
246 | struct hci_cp_le_ltk_neg_reply cp; | ||
247 | |||
248 | BT_DBG("%p", conn); | ||
249 | |||
250 | memset(&cp, 0, sizeof(cp)); | ||
251 | |||
252 | cp.handle = cpu_to_le16(conn->handle); | ||
253 | |||
254 | hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(cp), &cp); | ||
255 | } | ||
256 | |||
206 | /* Device _must_ be locked */ | 257 | /* Device _must_ be locked */ |
207 | void hci_sco_setup(struct hci_conn *conn, __u8 status) | 258 | void hci_sco_setup(struct hci_conn *conn, __u8 status) |
208 | { | 259 | { |
@@ -393,6 +444,9 @@ int hci_conn_del(struct hci_conn *conn) | |||
393 | 444 | ||
394 | hci_dev_put(hdev); | 445 | hci_dev_put(hdev); |
395 | 446 | ||
447 | if (conn->handle == 0) | ||
448 | kfree(conn); | ||
449 | |||
396 | return 0; | 450 | return 0; |
397 | } | 451 | } |
398 | 452 | ||
@@ -447,14 +501,23 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
447 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); | 501 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); |
448 | 502 | ||
449 | if (type == LE_LINK) { | 503 | if (type == LE_LINK) { |
504 | struct adv_entry *entry; | ||
505 | |||
450 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); | 506 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); |
451 | if (le) | 507 | if (le) |
452 | return ERR_PTR(-EBUSY); | 508 | return ERR_PTR(-EBUSY); |
509 | |||
510 | entry = hci_find_adv_entry(hdev, dst); | ||
511 | if (!entry) | ||
512 | return ERR_PTR(-EHOSTUNREACH); | ||
513 | |||
453 | le = hci_conn_add(hdev, LE_LINK, dst); | 514 | le = hci_conn_add(hdev, LE_LINK, dst); |
454 | if (!le) | 515 | if (!le) |
455 | return ERR_PTR(-ENOMEM); | 516 | return ERR_PTR(-ENOMEM); |
456 | if (le->state == BT_OPEN) | 517 | |
457 | hci_le_connect(le); | 518 | le->dst_type = entry->bdaddr_type; |
519 | |||
520 | hci_le_connect(le); | ||
458 | 521 | ||
459 | hci_conn_hold(le); | 522 | hci_conn_hold(le); |
460 | 523 | ||
@@ -497,7 +560,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
497 | if (acl->state == BT_CONNECTED && | 560 | if (acl->state == BT_CONNECTED && |
498 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { | 561 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { |
499 | acl->power_save = 1; | 562 | acl->power_save = 1; |
500 | hci_conn_enter_active_mode(acl); | 563 | hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON); |
501 | 564 | ||
502 | if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { | 565 | if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { |
503 | /* defer SCO setup until mode change completed */ | 566 | /* defer SCO setup until mode change completed */ |
@@ -548,6 +611,8 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
548 | cp.handle = cpu_to_le16(conn->handle); | 611 | cp.handle = cpu_to_le16(conn->handle); |
549 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, | 612 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, |
550 | sizeof(cp), &cp); | 613 | sizeof(cp), &cp); |
614 | if (conn->key_type != 0xff) | ||
615 | set_bit(HCI_CONN_REAUTH_PEND, &conn->pend); | ||
551 | } | 616 | } |
552 | 617 | ||
553 | return 0; | 618 | return 0; |
@@ -608,11 +673,11 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
608 | goto encrypt; | 673 | goto encrypt; |
609 | 674 | ||
610 | auth: | 675 | auth: |
611 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 676 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
612 | return 0; | 677 | return 0; |
613 | 678 | ||
614 | hci_conn_auth(conn, sec_level, auth_type); | 679 | if (!hci_conn_auth(conn, sec_level, auth_type)) |
615 | return 0; | 680 | return 0; |
616 | 681 | ||
617 | encrypt: | 682 | encrypt: |
618 | if (conn->link_mode & HCI_LM_ENCRYPT) | 683 | if (conn->link_mode & HCI_LM_ENCRYPT) |
@@ -631,9 +696,7 @@ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) | |||
631 | if (sec_level != BT_SECURITY_HIGH) | 696 | if (sec_level != BT_SECURITY_HIGH) |
632 | return 1; /* Accept if non-secure is required */ | 697 | return 1; /* Accept if non-secure is required */ |
633 | 698 | ||
634 | if (conn->key_type == HCI_LK_AUTH_COMBINATION || | 699 | if (conn->sec_level == BT_SECURITY_HIGH) |
635 | (conn->key_type == HCI_LK_COMBINATION && | ||
636 | conn->pin_length == 16)) | ||
637 | return 1; | 700 | return 1; |
638 | 701 | ||
639 | return 0; /* Reject not secure link */ | 702 | return 0; /* Reject not secure link */ |
@@ -676,7 +739,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) | |||
676 | EXPORT_SYMBOL(hci_conn_switch_role); | 739 | EXPORT_SYMBOL(hci_conn_switch_role); |
677 | 740 | ||
678 | /* Enter active mode */ | 741 | /* Enter active mode */ |
679 | void hci_conn_enter_active_mode(struct hci_conn *conn) | 742 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) |
680 | { | 743 | { |
681 | struct hci_dev *hdev = conn->hdev; | 744 | struct hci_dev *hdev = conn->hdev; |
682 | 745 | ||
@@ -685,7 +748,10 @@ void hci_conn_enter_active_mode(struct hci_conn *conn) | |||
685 | if (test_bit(HCI_RAW, &hdev->flags)) | 748 | if (test_bit(HCI_RAW, &hdev->flags)) |
686 | return; | 749 | return; |
687 | 750 | ||
688 | if (conn->mode != HCI_CM_SNIFF || !conn->power_save) | 751 | if (conn->mode != HCI_CM_SNIFF) |
752 | goto timer; | ||
753 | |||
754 | if (!conn->power_save && !force_active) | ||
689 | goto timer; | 755 | goto timer; |
690 | 756 | ||
691 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | 757 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { |