diff options
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 136 |
1 files changed, 116 insertions, 20 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index bcd158f40bb..33c4e0cd83b 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 | { |
@@ -282,7 +333,8 @@ static void hci_conn_auto_accept(unsigned long arg) | |||
282 | hci_dev_unlock(hdev); | 333 | hci_dev_unlock(hdev); |
283 | } | 334 | } |
284 | 335 | ||
285 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | 336 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, |
337 | __u16 pkt_type, bdaddr_t *dst) | ||
286 | { | 338 | { |
287 | struct hci_conn *conn; | 339 | struct hci_conn *conn; |
288 | 340 | ||
@@ -310,14 +362,22 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
310 | conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK; | 362 | conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK; |
311 | break; | 363 | break; |
312 | case SCO_LINK: | 364 | case SCO_LINK: |
313 | if (lmp_esco_capable(hdev)) | 365 | if (!pkt_type) |
314 | conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | | 366 | pkt_type = SCO_ESCO_MASK; |
315 | (hdev->esco_type & EDR_ESCO_MASK); | ||
316 | else | ||
317 | conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK; | ||
318 | break; | ||
319 | case ESCO_LINK: | 367 | case ESCO_LINK: |
320 | conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK; | 368 | if (!pkt_type) |
369 | pkt_type = ALL_ESCO_MASK; | ||
370 | if (lmp_esco_capable(hdev)) { | ||
371 | /* HCI Setup Synchronous Connection Command uses | ||
372 | reverse logic on the EDR_ESCO_MASK bits */ | ||
373 | conn->pkt_type = (pkt_type ^ EDR_ESCO_MASK) & | ||
374 | hdev->esco_type; | ||
375 | } else { | ||
376 | /* Legacy HCI Add Sco Connection Command uses a | ||
377 | shifted bitmask */ | ||
378 | conn->pkt_type = (pkt_type << 5) & hdev->pkt_type & | ||
379 | SCO_PTYPE_MASK; | ||
380 | } | ||
321 | break; | 381 | break; |
322 | } | 382 | } |
323 | 383 | ||
@@ -441,7 +501,9 @@ EXPORT_SYMBOL(hci_get_route); | |||
441 | 501 | ||
442 | /* Create SCO, ACL or LE connection. | 502 | /* Create SCO, ACL or LE connection. |
443 | * Device _must_ be locked */ | 503 | * Device _must_ be locked */ |
444 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type) | 504 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, |
505 | __u16 pkt_type, bdaddr_t *dst, | ||
506 | __u8 sec_level, __u8 auth_type) | ||
445 | { | 507 | { |
446 | struct hci_conn *acl; | 508 | struct hci_conn *acl; |
447 | struct hci_conn *sco; | 509 | struct hci_conn *sco; |
@@ -450,14 +512,23 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
450 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); | 512 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); |
451 | 513 | ||
452 | if (type == LE_LINK) { | 514 | if (type == LE_LINK) { |
515 | struct adv_entry *entry; | ||
516 | |||
453 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); | 517 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); |
454 | if (le) | 518 | if (le) |
455 | return ERR_PTR(-EBUSY); | 519 | return ERR_PTR(-EBUSY); |
456 | le = hci_conn_add(hdev, LE_LINK, dst); | 520 | |
521 | entry = hci_find_adv_entry(hdev, dst); | ||
522 | if (!entry) | ||
523 | return ERR_PTR(-EHOSTUNREACH); | ||
524 | |||
525 | le = hci_conn_add(hdev, LE_LINK, 0, dst); | ||
457 | if (!le) | 526 | if (!le) |
458 | return ERR_PTR(-ENOMEM); | 527 | return ERR_PTR(-ENOMEM); |
459 | if (le->state == BT_OPEN) | 528 | |
460 | hci_le_connect(le); | 529 | le->dst_type = entry->bdaddr_type; |
530 | |||
531 | hci_le_connect(le); | ||
461 | 532 | ||
462 | hci_conn_hold(le); | 533 | hci_conn_hold(le); |
463 | 534 | ||
@@ -466,7 +537,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
466 | 537 | ||
467 | acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 538 | acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
468 | if (!acl) { | 539 | if (!acl) { |
469 | acl = hci_conn_add(hdev, ACL_LINK, dst); | 540 | acl = hci_conn_add(hdev, ACL_LINK, 0, dst); |
470 | if (!acl) | 541 | if (!acl) |
471 | return NULL; | 542 | return NULL; |
472 | } | 543 | } |
@@ -485,7 +556,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
485 | 556 | ||
486 | sco = hci_conn_hash_lookup_ba(hdev, type, dst); | 557 | sco = hci_conn_hash_lookup_ba(hdev, type, dst); |
487 | if (!sco) { | 558 | if (!sco) { |
488 | sco = hci_conn_add(hdev, type, dst); | 559 | sco = hci_conn_add(hdev, type, pkt_type, dst); |
489 | if (!sco) { | 560 | if (!sco) { |
490 | hci_conn_put(acl); | 561 | hci_conn_put(acl); |
491 | return NULL; | 562 | return NULL; |
@@ -500,7 +571,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
500 | if (acl->state == BT_CONNECTED && | 571 | if (acl->state == BT_CONNECTED && |
501 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { | 572 | (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { |
502 | acl->power_save = 1; | 573 | acl->power_save = 1; |
503 | hci_conn_enter_active_mode(acl); | 574 | hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON); |
504 | 575 | ||
505 | if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { | 576 | if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { |
506 | /* defer SCO setup until mode change completed */ | 577 | /* defer SCO setup until mode change completed */ |
@@ -548,9 +619,15 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
548 | 619 | ||
549 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 620 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
550 | struct hci_cp_auth_requested cp; | 621 | struct hci_cp_auth_requested cp; |
622 | |||
623 | /* encrypt must be pending if auth is also pending */ | ||
624 | set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | ||
625 | |||
551 | cp.handle = cpu_to_le16(conn->handle); | 626 | cp.handle = cpu_to_le16(conn->handle); |
552 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, | 627 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, |
553 | sizeof(cp), &cp); | 628 | sizeof(cp), &cp); |
629 | if (conn->key_type != 0xff) | ||
630 | set_bit(HCI_CONN_REAUTH_PEND, &conn->pend); | ||
554 | } | 631 | } |
555 | 632 | ||
556 | return 0; | 633 | return 0; |
@@ -634,9 +711,7 @@ int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) | |||
634 | if (sec_level != BT_SECURITY_HIGH) | 711 | if (sec_level != BT_SECURITY_HIGH) |
635 | return 1; /* Accept if non-secure is required */ | 712 | return 1; /* Accept if non-secure is required */ |
636 | 713 | ||
637 | if (conn->key_type == HCI_LK_AUTH_COMBINATION || | 714 | if (conn->sec_level == BT_SECURITY_HIGH) |
638 | (conn->key_type == HCI_LK_COMBINATION && | ||
639 | conn->pin_length == 16)) | ||
640 | return 1; | 715 | return 1; |
641 | 716 | ||
642 | return 0; /* Reject not secure link */ | 717 | return 0; /* Reject not secure link */ |
@@ -679,7 +754,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) | |||
679 | EXPORT_SYMBOL(hci_conn_switch_role); | 754 | EXPORT_SYMBOL(hci_conn_switch_role); |
680 | 755 | ||
681 | /* Enter active mode */ | 756 | /* Enter active mode */ |
682 | void hci_conn_enter_active_mode(struct hci_conn *conn) | 757 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) |
683 | { | 758 | { |
684 | struct hci_dev *hdev = conn->hdev; | 759 | struct hci_dev *hdev = conn->hdev; |
685 | 760 | ||
@@ -688,7 +763,10 @@ void hci_conn_enter_active_mode(struct hci_conn *conn) | |||
688 | if (test_bit(HCI_RAW, &hdev->flags)) | 763 | if (test_bit(HCI_RAW, &hdev->flags)) |
689 | return; | 764 | return; |
690 | 765 | ||
691 | if (conn->mode != HCI_CM_SNIFF || !conn->power_save) | 766 | if (conn->mode != HCI_CM_SNIFF) |
767 | goto timer; | ||
768 | |||
769 | if (!conn->power_save && !force_active) | ||
692 | goto timer; | 770 | goto timer; |
693 | 771 | ||
694 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | 772 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { |
@@ -829,6 +907,15 @@ int hci_get_conn_list(void __user *arg) | |||
829 | (ci + n)->out = c->out; | 907 | (ci + n)->out = c->out; |
830 | (ci + n)->state = c->state; | 908 | (ci + n)->state = c->state; |
831 | (ci + n)->link_mode = c->link_mode; | 909 | (ci + n)->link_mode = c->link_mode; |
910 | if (c->type == SCO_LINK) { | ||
911 | (ci + n)->mtu = hdev->sco_mtu; | ||
912 | (ci + n)->cnt = hdev->sco_cnt; | ||
913 | (ci + n)->pkts = hdev->sco_pkts; | ||
914 | } else { | ||
915 | (ci + n)->mtu = hdev->acl_mtu; | ||
916 | (ci + n)->cnt = hdev->acl_cnt; | ||
917 | (ci + n)->pkts = hdev->acl_pkts; | ||
918 | } | ||
832 | if (++n >= req.conn_num) | 919 | if (++n >= req.conn_num) |
833 | break; | 920 | break; |
834 | } | 921 | } |
@@ -865,6 +952,15 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg) | |||
865 | ci.out = conn->out; | 952 | ci.out = conn->out; |
866 | ci.state = conn->state; | 953 | ci.state = conn->state; |
867 | ci.link_mode = conn->link_mode; | 954 | ci.link_mode = conn->link_mode; |
955 | if (req.type == SCO_LINK) { | ||
956 | ci.mtu = hdev->sco_mtu; | ||
957 | ci.cnt = hdev->sco_cnt; | ||
958 | ci.pkts = hdev->sco_pkts; | ||
959 | } else { | ||
960 | ci.mtu = hdev->acl_mtu; | ||
961 | ci.cnt = hdev->acl_cnt; | ||
962 | ci.pkts = hdev->acl_pkts; | ||
963 | } | ||
868 | } | 964 | } |
869 | hci_dev_unlock_bh(hdev); | 965 | hci_dev_unlock_bh(hdev); |
870 | 966 | ||