diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 351 |
1 files changed, 325 insertions, 26 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0383635f91fb..9f5c5f244502 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | /* Bluetooth HCI event handling. */ | 25 | /* Bluetooth HCI event handling. */ |
26 | 26 | ||
27 | #include <linux/export.h> | ||
28 | #include <asm/unaligned.h> | 27 | #include <asm/unaligned.h> |
29 | 28 | ||
30 | #include <net/bluetooth/bluetooth.h> | 29 | #include <net/bluetooth/bluetooth.h> |
@@ -203,6 +202,11 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) | |||
203 | BIT(HCI_PERIODIC_INQ)); | 202 | BIT(HCI_PERIODIC_INQ)); |
204 | 203 | ||
205 | hdev->discovery.state = DISCOVERY_STOPPED; | 204 | hdev->discovery.state = DISCOVERY_STOPPED; |
205 | hdev->inq_tx_power = HCI_TX_POWER_INVALID; | ||
206 | hdev->adv_tx_power = HCI_TX_POWER_INVALID; | ||
207 | |||
208 | memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); | ||
209 | hdev->adv_data_len = 0; | ||
206 | } | 210 | } |
207 | 211 | ||
208 | static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | 212 | static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -225,6 +229,9 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
225 | 229 | ||
226 | hci_dev_unlock(hdev); | 230 | hci_dev_unlock(hdev); |
227 | 231 | ||
232 | if (!status && !test_bit(HCI_INIT, &hdev->flags)) | ||
233 | hci_update_ad(hdev); | ||
234 | |||
228 | hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status); | 235 | hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status); |
229 | } | 236 | } |
230 | 237 | ||
@@ -440,7 +447,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) | |||
440 | static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | 447 | static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) |
441 | { | 448 | { |
442 | __u8 status = *((__u8 *) skb->data); | 449 | __u8 status = *((__u8 *) skb->data); |
443 | void *sent; | 450 | struct hci_cp_write_ssp_mode *sent; |
444 | 451 | ||
445 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 452 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
446 | 453 | ||
@@ -448,10 +455,17 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
448 | if (!sent) | 455 | if (!sent) |
449 | return; | 456 | return; |
450 | 457 | ||
458 | if (!status) { | ||
459 | if (sent->mode) | ||
460 | hdev->host_features[0] |= LMP_HOST_SSP; | ||
461 | else | ||
462 | hdev->host_features[0] &= ~LMP_HOST_SSP; | ||
463 | } | ||
464 | |||
451 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | 465 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
452 | mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status); | 466 | mgmt_ssp_enable_complete(hdev, sent->mode, status); |
453 | else if (!status) { | 467 | else if (!status) { |
454 | if (*((u8 *) sent)) | 468 | if (sent->mode) |
455 | set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); | 469 | set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); |
456 | else | 470 | else |
457 | clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); | 471 | clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); |
@@ -460,10 +474,10 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
460 | 474 | ||
461 | static u8 hci_get_inquiry_mode(struct hci_dev *hdev) | 475 | static u8 hci_get_inquiry_mode(struct hci_dev *hdev) |
462 | { | 476 | { |
463 | if (hdev->features[6] & LMP_EXT_INQ) | 477 | if (lmp_ext_inq_capable(hdev)) |
464 | return 2; | 478 | return 2; |
465 | 479 | ||
466 | if (hdev->features[3] & LMP_RSSI_INQ) | 480 | if (lmp_inq_rssi_capable(hdev)) |
467 | return 1; | 481 | return 1; |
468 | 482 | ||
469 | if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && | 483 | if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && |
@@ -507,28 +521,30 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
507 | if (hdev->hci_ver < BLUETOOTH_VER_1_2) | 521 | if (hdev->hci_ver < BLUETOOTH_VER_1_2) |
508 | return; | 522 | return; |
509 | 523 | ||
510 | events[4] |= 0x01; /* Flow Specification Complete */ | 524 | if (lmp_bredr_capable(hdev)) { |
511 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | 525 | events[4] |= 0x01; /* Flow Specification Complete */ |
512 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ | 526 | events[4] |= 0x02; /* Inquiry Result with RSSI */ |
513 | events[5] |= 0x08; /* Synchronous Connection Complete */ | 527 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ |
514 | events[5] |= 0x10; /* Synchronous Connection Changed */ | 528 | events[5] |= 0x08; /* Synchronous Connection Complete */ |
529 | events[5] |= 0x10; /* Synchronous Connection Changed */ | ||
530 | } | ||
515 | 531 | ||
516 | if (hdev->features[3] & LMP_RSSI_INQ) | 532 | if (lmp_inq_rssi_capable(hdev)) |
517 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | 533 | events[4] |= 0x02; /* Inquiry Result with RSSI */ |
518 | 534 | ||
519 | if (lmp_sniffsubr_capable(hdev)) | 535 | if (lmp_sniffsubr_capable(hdev)) |
520 | events[5] |= 0x20; /* Sniff Subrating */ | 536 | events[5] |= 0x20; /* Sniff Subrating */ |
521 | 537 | ||
522 | if (hdev->features[5] & LMP_PAUSE_ENC) | 538 | if (lmp_pause_enc_capable(hdev)) |
523 | events[5] |= 0x80; /* Encryption Key Refresh Complete */ | 539 | events[5] |= 0x80; /* Encryption Key Refresh Complete */ |
524 | 540 | ||
525 | if (hdev->features[6] & LMP_EXT_INQ) | 541 | if (lmp_ext_inq_capable(hdev)) |
526 | events[5] |= 0x40; /* Extended Inquiry Result */ | 542 | events[5] |= 0x40; /* Extended Inquiry Result */ |
527 | 543 | ||
528 | if (lmp_no_flush_capable(hdev)) | 544 | if (lmp_no_flush_capable(hdev)) |
529 | events[7] |= 0x01; /* Enhanced Flush Complete */ | 545 | events[7] |= 0x01; /* Enhanced Flush Complete */ |
530 | 546 | ||
531 | if (hdev->features[7] & LMP_LSTO) | 547 | if (lmp_lsto_capable(hdev)) |
532 | events[6] |= 0x80; /* Link Supervision Timeout Changed */ | 548 | events[6] |= 0x80; /* Link Supervision Timeout Changed */ |
533 | 549 | ||
534 | if (lmp_ssp_capable(hdev)) { | 550 | if (lmp_ssp_capable(hdev)) { |
@@ -548,6 +564,53 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
548 | events[7] |= 0x20; /* LE Meta-Event */ | 564 | events[7] |= 0x20; /* LE Meta-Event */ |
549 | 565 | ||
550 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); | 566 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); |
567 | |||
568 | if (lmp_le_capable(hdev)) { | ||
569 | memset(events, 0, sizeof(events)); | ||
570 | events[0] = 0x1f; | ||
571 | hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK, | ||
572 | sizeof(events), events); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | static void bredr_setup(struct hci_dev *hdev) | ||
577 | { | ||
578 | struct hci_cp_delete_stored_link_key cp; | ||
579 | __le16 param; | ||
580 | __u8 flt_type; | ||
581 | |||
582 | /* Read Buffer Size (ACL mtu, max pkt, etc.) */ | ||
583 | hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); | ||
584 | |||
585 | /* Read Class of Device */ | ||
586 | hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); | ||
587 | |||
588 | /* Read Local Name */ | ||
589 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); | ||
590 | |||
591 | /* Read Voice Setting */ | ||
592 | hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); | ||
593 | |||
594 | /* Clear Event Filters */ | ||
595 | flt_type = HCI_FLT_CLEAR_ALL; | ||
596 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); | ||
597 | |||
598 | /* Connection accept timeout ~20 secs */ | ||
599 | param = __constant_cpu_to_le16(0x7d00); | ||
600 | hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); | ||
601 | |||
602 | bacpy(&cp.bdaddr, BDADDR_ANY); | ||
603 | cp.delete_all = 1; | ||
604 | hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); | ||
605 | } | ||
606 | |||
607 | static void le_setup(struct hci_dev *hdev) | ||
608 | { | ||
609 | /* Read LE Buffer Size */ | ||
610 | hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); | ||
611 | |||
612 | /* Read LE Advertising Channel TX Power */ | ||
613 | hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); | ||
551 | } | 614 | } |
552 | 615 | ||
553 | static void hci_setup(struct hci_dev *hdev) | 616 | static void hci_setup(struct hci_dev *hdev) |
@@ -555,6 +618,15 @@ static void hci_setup(struct hci_dev *hdev) | |||
555 | if (hdev->dev_type != HCI_BREDR) | 618 | if (hdev->dev_type != HCI_BREDR) |
556 | return; | 619 | return; |
557 | 620 | ||
621 | /* Read BD Address */ | ||
622 | hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); | ||
623 | |||
624 | if (lmp_bredr_capable(hdev)) | ||
625 | bredr_setup(hdev); | ||
626 | |||
627 | if (lmp_le_capable(hdev)) | ||
628 | le_setup(hdev); | ||
629 | |||
558 | hci_setup_event_mask(hdev); | 630 | hci_setup_event_mask(hdev); |
559 | 631 | ||
560 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) | 632 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) |
@@ -575,13 +647,13 @@ static void hci_setup(struct hci_dev *hdev) | |||
575 | } | 647 | } |
576 | } | 648 | } |
577 | 649 | ||
578 | if (hdev->features[3] & LMP_RSSI_INQ) | 650 | if (lmp_inq_rssi_capable(hdev)) |
579 | hci_setup_inquiry_mode(hdev); | 651 | hci_setup_inquiry_mode(hdev); |
580 | 652 | ||
581 | if (hdev->features[7] & LMP_INQ_TX_PWR) | 653 | if (lmp_inq_tx_pwr_capable(hdev)) |
582 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); | 654 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); |
583 | 655 | ||
584 | if (hdev->features[7] & LMP_EXTFEATURES) { | 656 | if (lmp_ext_feat_capable(hdev)) { |
585 | struct hci_cp_read_local_ext_features cp; | 657 | struct hci_cp_read_local_ext_features cp; |
586 | 658 | ||
587 | cp.page = 0x01; | 659 | cp.page = 0x01; |
@@ -628,11 +700,11 @@ static void hci_setup_link_policy(struct hci_dev *hdev) | |||
628 | 700 | ||
629 | if (lmp_rswitch_capable(hdev)) | 701 | if (lmp_rswitch_capable(hdev)) |
630 | link_policy |= HCI_LP_RSWITCH; | 702 | link_policy |= HCI_LP_RSWITCH; |
631 | if (hdev->features[0] & LMP_HOLD) | 703 | if (lmp_hold_capable(hdev)) |
632 | link_policy |= HCI_LP_HOLD; | 704 | link_policy |= HCI_LP_HOLD; |
633 | if (lmp_sniff_capable(hdev)) | 705 | if (lmp_sniff_capable(hdev)) |
634 | link_policy |= HCI_LP_SNIFF; | 706 | link_policy |= HCI_LP_SNIFF; |
635 | if (hdev->features[1] & LMP_PARK) | 707 | if (lmp_park_capable(hdev)) |
636 | link_policy |= HCI_LP_PARK; | 708 | link_policy |= HCI_LP_PARK; |
637 | 709 | ||
638 | cp.policy = cpu_to_le16(link_policy); | 710 | cp.policy = cpu_to_le16(link_policy); |
@@ -722,10 +794,10 @@ static void hci_set_le_support(struct hci_dev *hdev) | |||
722 | 794 | ||
723 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | 795 | if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { |
724 | cp.le = 1; | 796 | cp.le = 1; |
725 | cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); | 797 | cp.simul = !!lmp_le_br_capable(hdev); |
726 | } | 798 | } |
727 | 799 | ||
728 | if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE)) | 800 | if (cp.le != !!lmp_host_le_capable(hdev)) |
729 | hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), | 801 | hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), |
730 | &cp); | 802 | &cp); |
731 | } | 803 | } |
@@ -1018,6 +1090,31 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, | |||
1018 | hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); | 1090 | hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); |
1019 | } | 1091 | } |
1020 | 1092 | ||
1093 | static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, | ||
1094 | struct sk_buff *skb) | ||
1095 | { | ||
1096 | struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; | ||
1097 | |||
1098 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | ||
1099 | |||
1100 | if (!rp->status) { | ||
1101 | hdev->adv_tx_power = rp->tx_power; | ||
1102 | if (!test_bit(HCI_INIT, &hdev->flags)) | ||
1103 | hci_update_ad(hdev); | ||
1104 | } | ||
1105 | |||
1106 | hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status); | ||
1107 | } | ||
1108 | |||
1109 | static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) | ||
1110 | { | ||
1111 | __u8 status = *((__u8 *) skb->data); | ||
1112 | |||
1113 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
1114 | |||
1115 | hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status); | ||
1116 | } | ||
1117 | |||
1021 | static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) | 1118 | static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) |
1022 | { | 1119 | { |
1023 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | 1120 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; |
@@ -1093,6 +1190,33 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | |||
1093 | hci_dev_unlock(hdev); | 1190 | hci_dev_unlock(hdev); |
1094 | } | 1191 | } |
1095 | 1192 | ||
1193 | static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) | ||
1194 | { | ||
1195 | __u8 *sent, status = *((__u8 *) skb->data); | ||
1196 | |||
1197 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
1198 | |||
1199 | sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); | ||
1200 | if (!sent) | ||
1201 | return; | ||
1202 | |||
1203 | hci_dev_lock(hdev); | ||
1204 | |||
1205 | if (!status) { | ||
1206 | if (*sent) | ||
1207 | set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); | ||
1208 | else | ||
1209 | clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); | ||
1210 | } | ||
1211 | |||
1212 | hci_dev_unlock(hdev); | ||
1213 | |||
1214 | if (!test_bit(HCI_INIT, &hdev->flags)) | ||
1215 | hci_update_ad(hdev); | ||
1216 | |||
1217 | hci_req_complete(hdev, HCI_OP_LE_SET_ADV_ENABLE, status); | ||
1218 | } | ||
1219 | |||
1096 | static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) | 1220 | static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) |
1097 | { | 1221 | { |
1098 | __u8 status = *((__u8 *) skb->data); | 1222 | __u8 status = *((__u8 *) skb->data); |
@@ -1207,6 +1331,11 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, | |||
1207 | hdev->host_features[0] |= LMP_HOST_LE; | 1331 | hdev->host_features[0] |= LMP_HOST_LE; |
1208 | else | 1332 | else |
1209 | hdev->host_features[0] &= ~LMP_HOST_LE; | 1333 | hdev->host_features[0] &= ~LMP_HOST_LE; |
1334 | |||
1335 | if (sent->simul) | ||
1336 | hdev->host_features[0] |= LMP_HOST_LE_BREDR; | ||
1337 | else | ||
1338 | hdev->host_features[0] &= ~LMP_HOST_LE_BREDR; | ||
1210 | } | 1339 | } |
1211 | 1340 | ||
1212 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && | 1341 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && |
@@ -1718,14 +1847,23 @@ static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) | |||
1718 | 1847 | ||
1719 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 1848 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1720 | 1849 | ||
1721 | if (status) | ||
1722 | return; | ||
1723 | |||
1724 | cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); | 1850 | cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); |
1725 | if (!cp) | 1851 | if (!cp) |
1726 | return; | 1852 | return; |
1727 | 1853 | ||
1728 | amp_write_remote_assoc(hdev, cp->phy_handle); | 1854 | hci_dev_lock(hdev); |
1855 | |||
1856 | if (status) { | ||
1857 | struct hci_conn *hcon; | ||
1858 | |||
1859 | hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle); | ||
1860 | if (hcon) | ||
1861 | hci_conn_del(hcon); | ||
1862 | } else { | ||
1863 | amp_write_remote_assoc(hdev, cp->phy_handle); | ||
1864 | } | ||
1865 | |||
1866 | hci_dev_unlock(hdev); | ||
1729 | } | 1867 | } |
1730 | 1868 | ||
1731 | static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) | 1869 | static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) |
@@ -1744,6 +1882,11 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) | |||
1744 | amp_write_remote_assoc(hdev, cp->phy_handle); | 1882 | amp_write_remote_assoc(hdev, cp->phy_handle); |
1745 | } | 1883 | } |
1746 | 1884 | ||
1885 | static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status) | ||
1886 | { | ||
1887 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
1888 | } | ||
1889 | |||
1747 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1890 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1748 | { | 1891 | { |
1749 | __u8 status = *((__u8 *) skb->data); | 1892 | __u8 status = *((__u8 *) skb->data); |
@@ -2441,6 +2584,14 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2441 | hci_cc_le_read_buffer_size(hdev, skb); | 2584 | hci_cc_le_read_buffer_size(hdev, skb); |
2442 | break; | 2585 | break; |
2443 | 2586 | ||
2587 | case HCI_OP_LE_READ_ADV_TX_POWER: | ||
2588 | hci_cc_le_read_adv_tx_power(hdev, skb); | ||
2589 | break; | ||
2590 | |||
2591 | case HCI_OP_LE_SET_EVENT_MASK: | ||
2592 | hci_cc_le_set_event_mask(hdev, skb); | ||
2593 | break; | ||
2594 | |||
2444 | case HCI_OP_USER_CONFIRM_REPLY: | 2595 | case HCI_OP_USER_CONFIRM_REPLY: |
2445 | hci_cc_user_confirm_reply(hdev, skb); | 2596 | hci_cc_user_confirm_reply(hdev, skb); |
2446 | break; | 2597 | break; |
@@ -2461,6 +2612,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2461 | hci_cc_le_set_scan_param(hdev, skb); | 2612 | hci_cc_le_set_scan_param(hdev, skb); |
2462 | break; | 2613 | break; |
2463 | 2614 | ||
2615 | case HCI_OP_LE_SET_ADV_ENABLE: | ||
2616 | hci_cc_le_set_adv_enable(hdev, skb); | ||
2617 | break; | ||
2618 | |||
2464 | case HCI_OP_LE_SET_SCAN_ENABLE: | 2619 | case HCI_OP_LE_SET_SCAN_ENABLE: |
2465 | hci_cc_le_set_scan_enable(hdev, skb); | 2620 | hci_cc_le_set_scan_enable(hdev, skb); |
2466 | break; | 2621 | break; |
@@ -2570,6 +2725,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2570 | hci_cs_accept_phylink(hdev, ev->status); | 2725 | hci_cs_accept_phylink(hdev, ev->status); |
2571 | break; | 2726 | break; |
2572 | 2727 | ||
2728 | case HCI_OP_CREATE_LOGICAL_LINK: | ||
2729 | hci_cs_create_logical_link(hdev, ev->status); | ||
2730 | break; | ||
2731 | |||
2573 | default: | 2732 | default: |
2574 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 2733 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
2575 | break; | 2734 | break; |
@@ -3544,6 +3703,130 @@ unlock: | |||
3544 | hci_dev_unlock(hdev); | 3703 | hci_dev_unlock(hdev); |
3545 | } | 3704 | } |
3546 | 3705 | ||
3706 | static void hci_phy_link_complete_evt(struct hci_dev *hdev, | ||
3707 | struct sk_buff *skb) | ||
3708 | { | ||
3709 | struct hci_ev_phy_link_complete *ev = (void *) skb->data; | ||
3710 | struct hci_conn *hcon, *bredr_hcon; | ||
3711 | |||
3712 | BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, | ||
3713 | ev->status); | ||
3714 | |||
3715 | hci_dev_lock(hdev); | ||
3716 | |||
3717 | hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); | ||
3718 | if (!hcon) { | ||
3719 | hci_dev_unlock(hdev); | ||
3720 | return; | ||
3721 | } | ||
3722 | |||
3723 | if (ev->status) { | ||
3724 | hci_conn_del(hcon); | ||
3725 | hci_dev_unlock(hdev); | ||
3726 | return; | ||
3727 | } | ||
3728 | |||
3729 | bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; | ||
3730 | |||
3731 | hcon->state = BT_CONNECTED; | ||
3732 | bacpy(&hcon->dst, &bredr_hcon->dst); | ||
3733 | |||
3734 | hci_conn_hold(hcon); | ||
3735 | hcon->disc_timeout = HCI_DISCONN_TIMEOUT; | ||
3736 | hci_conn_put(hcon); | ||
3737 | |||
3738 | hci_conn_hold_device(hcon); | ||
3739 | hci_conn_add_sysfs(hcon); | ||
3740 | |||
3741 | amp_physical_cfm(bredr_hcon, hcon); | ||
3742 | |||
3743 | hci_dev_unlock(hdev); | ||
3744 | } | ||
3745 | |||
3746 | static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
3747 | { | ||
3748 | struct hci_ev_logical_link_complete *ev = (void *) skb->data; | ||
3749 | struct hci_conn *hcon; | ||
3750 | struct hci_chan *hchan; | ||
3751 | struct amp_mgr *mgr; | ||
3752 | |||
3753 | BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", | ||
3754 | hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, | ||
3755 | ev->status); | ||
3756 | |||
3757 | hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); | ||
3758 | if (!hcon) | ||
3759 | return; | ||
3760 | |||
3761 | /* Create AMP hchan */ | ||
3762 | hchan = hci_chan_create(hcon); | ||
3763 | if (!hchan) | ||
3764 | return; | ||
3765 | |||
3766 | hchan->handle = le16_to_cpu(ev->handle); | ||
3767 | |||
3768 | BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); | ||
3769 | |||
3770 | mgr = hcon->amp_mgr; | ||
3771 | if (mgr && mgr->bredr_chan) { | ||
3772 | struct l2cap_chan *bredr_chan = mgr->bredr_chan; | ||
3773 | |||
3774 | l2cap_chan_lock(bredr_chan); | ||
3775 | |||
3776 | bredr_chan->conn->mtu = hdev->block_mtu; | ||
3777 | l2cap_logical_cfm(bredr_chan, hchan, 0); | ||
3778 | hci_conn_hold(hcon); | ||
3779 | |||
3780 | l2cap_chan_unlock(bredr_chan); | ||
3781 | } | ||
3782 | } | ||
3783 | |||
3784 | static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, | ||
3785 | struct sk_buff *skb) | ||
3786 | { | ||
3787 | struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; | ||
3788 | struct hci_chan *hchan; | ||
3789 | |||
3790 | BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, | ||
3791 | le16_to_cpu(ev->handle), ev->status); | ||
3792 | |||
3793 | if (ev->status) | ||
3794 | return; | ||
3795 | |||
3796 | hci_dev_lock(hdev); | ||
3797 | |||
3798 | hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); | ||
3799 | if (!hchan) | ||
3800 | goto unlock; | ||
3801 | |||
3802 | amp_destroy_logical_link(hchan, ev->reason); | ||
3803 | |||
3804 | unlock: | ||
3805 | hci_dev_unlock(hdev); | ||
3806 | } | ||
3807 | |||
3808 | static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, | ||
3809 | struct sk_buff *skb) | ||
3810 | { | ||
3811 | struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; | ||
3812 | struct hci_conn *hcon; | ||
3813 | |||
3814 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); | ||
3815 | |||
3816 | if (ev->status) | ||
3817 | return; | ||
3818 | |||
3819 | hci_dev_lock(hdev); | ||
3820 | |||
3821 | hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); | ||
3822 | if (hcon) { | ||
3823 | hcon->state = BT_CLOSED; | ||
3824 | hci_conn_del(hcon); | ||
3825 | } | ||
3826 | |||
3827 | hci_dev_unlock(hdev); | ||
3828 | } | ||
3829 | |||
3547 | static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 3830 | static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
3548 | { | 3831 | { |
3549 | struct hci_ev_le_conn_complete *ev = (void *) skb->data; | 3832 | struct hci_ev_le_conn_complete *ev = (void *) skb->data; |
@@ -3871,6 +4154,22 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
3871 | hci_remote_oob_data_request_evt(hdev, skb); | 4154 | hci_remote_oob_data_request_evt(hdev, skb); |
3872 | break; | 4155 | break; |
3873 | 4156 | ||
4157 | case HCI_EV_PHY_LINK_COMPLETE: | ||
4158 | hci_phy_link_complete_evt(hdev, skb); | ||
4159 | break; | ||
4160 | |||
4161 | case HCI_EV_LOGICAL_LINK_COMPLETE: | ||
4162 | hci_loglink_complete_evt(hdev, skb); | ||
4163 | break; | ||
4164 | |||
4165 | case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: | ||
4166 | hci_disconn_loglink_complete_evt(hdev, skb); | ||
4167 | break; | ||
4168 | |||
4169 | case HCI_EV_DISCONN_PHY_LINK_COMPLETE: | ||
4170 | hci_disconn_phylink_complete_evt(hdev, skb); | ||
4171 | break; | ||
4172 | |||
3874 | case HCI_EV_NUM_COMP_BLOCKS: | 4173 | case HCI_EV_NUM_COMP_BLOCKS: |
3875 | hci_num_comp_blocks_evt(hdev, skb); | 4174 | hci_num_comp_blocks_evt(hdev, skb); |
3876 | break; | 4175 | break; |