diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 328 |
1 files changed, 279 insertions, 49 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 77930aa522e..5a7074a7b5b 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <net/bluetooth/bluetooth.h> | 45 | #include <net/bluetooth/bluetooth.h> |
46 | #include <net/bluetooth/hci_core.h> | 46 | #include <net/bluetooth/hci_core.h> |
47 | 47 | ||
48 | static int enable_le; | ||
49 | |||
48 | /* Handle HCI Event packets */ | 50 | /* Handle HCI Event packets */ |
49 | 51 | ||
50 | static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | 52 | static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -56,8 +58,8 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
56 | if (status) | 58 | if (status) |
57 | return; | 59 | return; |
58 | 60 | ||
59 | if (test_bit(HCI_MGMT, &hdev->flags) && | 61 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && |
60 | test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | 62 | test_bit(HCI_MGMT, &hdev->flags)) |
61 | mgmt_discovering(hdev->id, 0); | 63 | mgmt_discovering(hdev->id, 0); |
62 | 64 | ||
63 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); | 65 | hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); |
@@ -74,8 +76,8 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) | |||
74 | if (status) | 76 | if (status) |
75 | return; | 77 | return; |
76 | 78 | ||
77 | if (test_bit(HCI_MGMT, &hdev->flags) && | 79 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && |
78 | test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | 80 | test_bit(HCI_MGMT, &hdev->flags)) |
79 | mgmt_discovering(hdev->id, 0); | 81 | mgmt_discovering(hdev->id, 0); |
80 | 82 | ||
81 | hci_conn_check_pending(hdev); | 83 | hci_conn_check_pending(hdev); |
@@ -525,6 +527,20 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
525 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); | 527 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); |
526 | } | 528 | } |
527 | 529 | ||
530 | static void hci_set_le_support(struct hci_dev *hdev) | ||
531 | { | ||
532 | struct hci_cp_write_le_host_supported cp; | ||
533 | |||
534 | memset(&cp, 0, sizeof(cp)); | ||
535 | |||
536 | if (enable_le) { | ||
537 | cp.le = 1; | ||
538 | cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); | ||
539 | } | ||
540 | |||
541 | hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp); | ||
542 | } | ||
543 | |||
528 | static void hci_setup(struct hci_dev *hdev) | 544 | static void hci_setup(struct hci_dev *hdev) |
529 | { | 545 | { |
530 | hci_setup_event_mask(hdev); | 546 | hci_setup_event_mask(hdev); |
@@ -542,6 +558,17 @@ static void hci_setup(struct hci_dev *hdev) | |||
542 | 558 | ||
543 | if (hdev->features[7] & LMP_INQ_TX_PWR) | 559 | if (hdev->features[7] & LMP_INQ_TX_PWR) |
544 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); | 560 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); |
561 | |||
562 | if (hdev->features[7] & LMP_EXTFEATURES) { | ||
563 | struct hci_cp_read_local_ext_features cp; | ||
564 | |||
565 | cp.page = 0x01; | ||
566 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, | ||
567 | sizeof(cp), &cp); | ||
568 | } | ||
569 | |||
570 | if (hdev->features[4] & LMP_LE) | ||
571 | hci_set_le_support(hdev); | ||
545 | } | 572 | } |
546 | 573 | ||
547 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | 574 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -658,6 +685,21 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb | |||
658 | hdev->features[6], hdev->features[7]); | 685 | hdev->features[6], hdev->features[7]); |
659 | } | 686 | } |
660 | 687 | ||
688 | static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | ||
689 | struct sk_buff *skb) | ||
690 | { | ||
691 | struct hci_rp_read_local_ext_features *rp = (void *) skb->data; | ||
692 | |||
693 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
694 | |||
695 | if (rp->status) | ||
696 | return; | ||
697 | |||
698 | memcpy(hdev->extfeatures, rp->features, 8); | ||
699 | |||
700 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status); | ||
701 | } | ||
702 | |||
661 | static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) | 703 | static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) |
662 | { | 704 | { |
663 | struct hci_rp_read_buffer_size *rp = (void *) skb->data; | 705 | struct hci_rp_read_buffer_size *rp = (void *) skb->data; |
@@ -841,6 +883,72 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | |||
841 | rp->randomizer, rp->status); | 883 | rp->randomizer, rp->status); |
842 | } | 884 | } |
843 | 885 | ||
886 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | ||
887 | struct sk_buff *skb) | ||
888 | { | ||
889 | struct hci_cp_le_set_scan_enable *cp; | ||
890 | __u8 status = *((__u8 *) skb->data); | ||
891 | |||
892 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
893 | |||
894 | if (status) | ||
895 | return; | ||
896 | |||
897 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); | ||
898 | if (!cp) | ||
899 | return; | ||
900 | |||
901 | hci_dev_lock(hdev); | ||
902 | |||
903 | if (cp->enable == 0x01) { | ||
904 | del_timer(&hdev->adv_timer); | ||
905 | hci_adv_entries_clear(hdev); | ||
906 | } else if (cp->enable == 0x00) { | ||
907 | mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT); | ||
908 | } | ||
909 | |||
910 | hci_dev_unlock(hdev); | ||
911 | } | ||
912 | |||
913 | static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
914 | { | ||
915 | struct hci_rp_le_ltk_reply *rp = (void *) skb->data; | ||
916 | |||
917 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
918 | |||
919 | if (rp->status) | ||
920 | return; | ||
921 | |||
922 | hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status); | ||
923 | } | ||
924 | |||
925 | static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
926 | { | ||
927 | struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data; | ||
928 | |||
929 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
930 | |||
931 | if (rp->status) | ||
932 | return; | ||
933 | |||
934 | hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); | ||
935 | } | ||
936 | |||
937 | static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, | ||
938 | struct sk_buff *skb) | ||
939 | { | ||
940 | struct hci_cp_read_local_ext_features cp; | ||
941 | __u8 status = *((__u8 *) skb->data); | ||
942 | |||
943 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
944 | |||
945 | if (status) | ||
946 | return; | ||
947 | |||
948 | cp.page = 0x01; | ||
949 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp); | ||
950 | } | ||
951 | |||
844 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 952 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
845 | { | 953 | { |
846 | BT_DBG("%s status 0x%x", hdev->name, status); | 954 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -851,9 +959,8 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | |||
851 | return; | 959 | return; |
852 | } | 960 | } |
853 | 961 | ||
854 | if (test_bit(HCI_MGMT, &hdev->flags) && | 962 | if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags) && |
855 | !test_and_set_bit(HCI_INQUIRY, | 963 | test_bit(HCI_MGMT, &hdev->flags)) |
856 | &hdev->flags)) | ||
857 | mgmt_discovering(hdev->id, 1); | 964 | mgmt_discovering(hdev->id, 1); |
858 | } | 965 | } |
859 | 966 | ||
@@ -885,7 +992,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | |||
885 | } | 992 | } |
886 | } else { | 993 | } else { |
887 | if (!conn) { | 994 | if (!conn) { |
888 | conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr); | 995 | conn = hci_conn_add(hdev, ACL_LINK, 0, &cp->bdaddr); |
889 | if (conn) { | 996 | if (conn) { |
890 | conn->out = 1; | 997 | conn->out = 1; |
891 | conn->link_mode |= HCI_LM_MASTER; | 998 | conn->link_mode |= HCI_LM_MASTER; |
@@ -1208,25 +1315,32 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) | |||
1208 | } | 1315 | } |
1209 | } else { | 1316 | } else { |
1210 | if (!conn) { | 1317 | if (!conn) { |
1211 | conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr); | 1318 | conn = hci_conn_add(hdev, LE_LINK, 0, &cp->peer_addr); |
1212 | if (conn) | 1319 | if (conn) { |
1320 | conn->dst_type = cp->peer_addr_type; | ||
1213 | conn->out = 1; | 1321 | conn->out = 1; |
1214 | else | 1322 | } else { |
1215 | BT_ERR("No memory for new connection"); | 1323 | BT_ERR("No memory for new connection"); |
1324 | } | ||
1216 | } | 1325 | } |
1217 | } | 1326 | } |
1218 | 1327 | ||
1219 | hci_dev_unlock(hdev); | 1328 | hci_dev_unlock(hdev); |
1220 | } | 1329 | } |
1221 | 1330 | ||
1331 | static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) | ||
1332 | { | ||
1333 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
1334 | } | ||
1335 | |||
1222 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1336 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1223 | { | 1337 | { |
1224 | __u8 status = *((__u8 *) skb->data); | 1338 | __u8 status = *((__u8 *) skb->data); |
1225 | 1339 | ||
1226 | BT_DBG("%s status %d", hdev->name, status); | 1340 | BT_DBG("%s status %d", hdev->name, status); |
1227 | 1341 | ||
1228 | if (test_bit(HCI_MGMT, &hdev->flags) && | 1342 | if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && |
1229 | test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) | 1343 | test_bit(HCI_MGMT, &hdev->flags)) |
1230 | mgmt_discovering(hdev->id, 0); | 1344 | mgmt_discovering(hdev->id, 0); |
1231 | 1345 | ||
1232 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 1346 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
@@ -1348,6 +1462,15 @@ unlock: | |||
1348 | hci_conn_check_pending(hdev); | 1462 | hci_conn_check_pending(hdev); |
1349 | } | 1463 | } |
1350 | 1464 | ||
1465 | static inline bool is_sco_active(struct hci_dev *hdev) | ||
1466 | { | ||
1467 | if (hci_conn_hash_lookup_state(hdev, SCO_LINK, BT_CONNECTED) || | ||
1468 | (hci_conn_hash_lookup_state(hdev, ESCO_LINK, | ||
1469 | BT_CONNECTED))) | ||
1470 | return true; | ||
1471 | return false; | ||
1472 | } | ||
1473 | |||
1351 | static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1474 | static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1352 | { | 1475 | { |
1353 | struct hci_ev_conn_request *ev = (void *) skb->data; | 1476 | struct hci_ev_conn_request *ev = (void *) skb->data; |
@@ -1372,7 +1495,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1372 | 1495 | ||
1373 | conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); | 1496 | conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); |
1374 | if (!conn) { | 1497 | if (!conn) { |
1375 | conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); | 1498 | /* pkt_type not yet used for incoming connections */ |
1499 | conn = hci_conn_add(hdev, ev->link_type, 0, &ev->bdaddr); | ||
1376 | if (!conn) { | 1500 | if (!conn) { |
1377 | BT_ERR("No memory for new connection"); | 1501 | BT_ERR("No memory for new connection"); |
1378 | hci_dev_unlock(hdev); | 1502 | hci_dev_unlock(hdev); |
@@ -1390,7 +1514,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1390 | 1514 | ||
1391 | bacpy(&cp.bdaddr, &ev->bdaddr); | 1515 | bacpy(&cp.bdaddr, &ev->bdaddr); |
1392 | 1516 | ||
1393 | if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) | 1517 | if (lmp_rswitch_capable(hdev) && ((mask & HCI_LM_MASTER) |
1518 | || is_sco_active(hdev))) | ||
1394 | cp.role = 0x00; /* Become master */ | 1519 | cp.role = 0x00; /* Become master */ |
1395 | else | 1520 | else |
1396 | cp.role = 0x01; /* Remain slave */ | 1521 | cp.role = 0x01; /* Remain slave */ |
@@ -1462,51 +1587,58 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1462 | hci_dev_lock(hdev); | 1587 | hci_dev_lock(hdev); |
1463 | 1588 | ||
1464 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 1589 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
1465 | if (conn) { | 1590 | if (!conn) |
1466 | if (!ev->status) { | 1591 | goto unlock; |
1592 | |||
1593 | if (!ev->status) { | ||
1594 | if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) && | ||
1595 | test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) { | ||
1596 | BT_INFO("re-auth of legacy device is not possible."); | ||
1597 | } else { | ||
1467 | conn->link_mode |= HCI_LM_AUTH; | 1598 | conn->link_mode |= HCI_LM_AUTH; |
1468 | conn->sec_level = conn->pending_sec_level; | 1599 | conn->sec_level = conn->pending_sec_level; |
1469 | } else { | ||
1470 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | ||
1471 | } | 1600 | } |
1601 | } else { | ||
1602 | mgmt_auth_failed(hdev->id, &conn->dst, ev->status); | ||
1603 | } | ||
1472 | 1604 | ||
1473 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1605 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
1606 | clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend); | ||
1474 | 1607 | ||
1475 | if (conn->state == BT_CONFIG) { | 1608 | if (conn->state == BT_CONFIG) { |
1476 | if (!ev->status && hdev->ssp_mode > 0 && | 1609 | if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) { |
1477 | conn->ssp_mode > 0) { | 1610 | struct hci_cp_set_conn_encrypt cp; |
1478 | struct hci_cp_set_conn_encrypt cp; | 1611 | cp.handle = ev->handle; |
1479 | cp.handle = ev->handle; | 1612 | cp.encrypt = 0x01; |
1480 | cp.encrypt = 0x01; | 1613 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), |
1481 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, | 1614 | &cp); |
1482 | sizeof(cp), &cp); | ||
1483 | } else { | ||
1484 | conn->state = BT_CONNECTED; | ||
1485 | hci_proto_connect_cfm(conn, ev->status); | ||
1486 | hci_conn_put(conn); | ||
1487 | } | ||
1488 | } else { | 1615 | } else { |
1489 | hci_auth_cfm(conn, ev->status); | 1616 | conn->state = BT_CONNECTED; |
1490 | 1617 | hci_proto_connect_cfm(conn, ev->status); | |
1491 | hci_conn_hold(conn); | ||
1492 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | ||
1493 | hci_conn_put(conn); | 1618 | hci_conn_put(conn); |
1494 | } | 1619 | } |
1620 | } else { | ||
1621 | hci_auth_cfm(conn, ev->status); | ||
1495 | 1622 | ||
1496 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { | 1623 | hci_conn_hold(conn); |
1497 | if (!ev->status) { | 1624 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
1498 | struct hci_cp_set_conn_encrypt cp; | 1625 | hci_conn_put(conn); |
1499 | cp.handle = ev->handle; | 1626 | } |
1500 | cp.encrypt = 0x01; | 1627 | |
1501 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, | 1628 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { |
1502 | sizeof(cp), &cp); | 1629 | if (!ev->status) { |
1503 | } else { | 1630 | struct hci_cp_set_conn_encrypt cp; |
1504 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | 1631 | cp.handle = ev->handle; |
1505 | hci_encrypt_cfm(conn, ev->status, 0x00); | 1632 | cp.encrypt = 0x01; |
1506 | } | 1633 | hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), |
1634 | &cp); | ||
1635 | } else { | ||
1636 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); | ||
1637 | hci_encrypt_cfm(conn, ev->status, 0x00); | ||
1507 | } | 1638 | } |
1508 | } | 1639 | } |
1509 | 1640 | ||
1641 | unlock: | ||
1510 | hci_dev_unlock(hdev); | 1642 | hci_dev_unlock(hdev); |
1511 | } | 1643 | } |
1512 | 1644 | ||
@@ -1557,6 +1689,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * | |||
1557 | /* Encryption implies authentication */ | 1689 | /* Encryption implies authentication */ |
1558 | conn->link_mode |= HCI_LM_AUTH; | 1690 | conn->link_mode |= HCI_LM_AUTH; |
1559 | conn->link_mode |= HCI_LM_ENCRYPT; | 1691 | conn->link_mode |= HCI_LM_ENCRYPT; |
1692 | conn->sec_level = conn->pending_sec_level; | ||
1560 | } else | 1693 | } else |
1561 | conn->link_mode &= ~HCI_LM_ENCRYPT; | 1694 | conn->link_mode &= ~HCI_LM_ENCRYPT; |
1562 | } | 1695 | } |
@@ -1760,6 +1893,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1760 | hci_cc_read_local_features(hdev, skb); | 1893 | hci_cc_read_local_features(hdev, skb); |
1761 | break; | 1894 | break; |
1762 | 1895 | ||
1896 | case HCI_OP_READ_LOCAL_EXT_FEATURES: | ||
1897 | hci_cc_read_local_ext_features(hdev, skb); | ||
1898 | break; | ||
1899 | |||
1763 | case HCI_OP_READ_BUFFER_SIZE: | 1900 | case HCI_OP_READ_BUFFER_SIZE: |
1764 | hci_cc_read_buffer_size(hdev, skb); | 1901 | hci_cc_read_buffer_size(hdev, skb); |
1765 | break; | 1902 | break; |
@@ -1816,6 +1953,22 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1816 | hci_cc_user_confirm_neg_reply(hdev, skb); | 1953 | hci_cc_user_confirm_neg_reply(hdev, skb); |
1817 | break; | 1954 | break; |
1818 | 1955 | ||
1956 | case HCI_OP_LE_SET_SCAN_ENABLE: | ||
1957 | hci_cc_le_set_scan_enable(hdev, skb); | ||
1958 | break; | ||
1959 | |||
1960 | case HCI_OP_LE_LTK_REPLY: | ||
1961 | hci_cc_le_ltk_reply(hdev, skb); | ||
1962 | break; | ||
1963 | |||
1964 | case HCI_OP_LE_LTK_NEG_REPLY: | ||
1965 | hci_cc_le_ltk_neg_reply(hdev, skb); | ||
1966 | break; | ||
1967 | |||
1968 | case HCI_OP_WRITE_LE_HOST_SUPPORTED: | ||
1969 | hci_cc_write_le_host_supported(hdev, skb); | ||
1970 | break; | ||
1971 | |||
1819 | default: | 1972 | default: |
1820 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 1973 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1821 | break; | 1974 | break; |
@@ -1894,6 +2047,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1894 | hci_cs_le_create_conn(hdev, ev->status); | 2047 | hci_cs_le_create_conn(hdev, ev->status); |
1895 | break; | 2048 | break; |
1896 | 2049 | ||
2050 | case HCI_OP_LE_START_ENC: | ||
2051 | hci_cs_le_start_enc(hdev, ev->status); | ||
2052 | break; | ||
2053 | |||
1897 | default: | 2054 | default: |
1898 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 2055 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1899 | break; | 2056 | break; |
@@ -2333,6 +2490,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu | |||
2333 | hci_conn_add_sysfs(conn); | 2490 | hci_conn_add_sysfs(conn); |
2334 | break; | 2491 | break; |
2335 | 2492 | ||
2493 | case 0x10: /* Connection Accept Timeout */ | ||
2336 | case 0x11: /* Unsupported Feature or Parameter Value */ | 2494 | case 0x11: /* Unsupported Feature or Parameter Value */ |
2337 | case 0x1c: /* SCO interval rejected */ | 2495 | case 0x1c: /* SCO interval rejected */ |
2338 | case 0x1a: /* Unsupported Remote Feature */ | 2496 | case 0x1a: /* Unsupported Remote Feature */ |
@@ -2652,12 +2810,14 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
2652 | 2810 | ||
2653 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); | 2811 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); |
2654 | if (!conn) { | 2812 | if (!conn) { |
2655 | conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); | 2813 | conn = hci_conn_add(hdev, LE_LINK, 0, &ev->bdaddr); |
2656 | if (!conn) { | 2814 | if (!conn) { |
2657 | BT_ERR("No memory for new connection"); | 2815 | BT_ERR("No memory for new connection"); |
2658 | hci_dev_unlock(hdev); | 2816 | hci_dev_unlock(hdev); |
2659 | return; | 2817 | return; |
2660 | } | 2818 | } |
2819 | |||
2820 | conn->dst_type = ev->bdaddr_type; | ||
2661 | } | 2821 | } |
2662 | 2822 | ||
2663 | if (ev->status) { | 2823 | if (ev->status) { |
@@ -2670,6 +2830,7 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
2670 | 2830 | ||
2671 | mgmt_connected(hdev->id, &ev->bdaddr); | 2831 | mgmt_connected(hdev->id, &ev->bdaddr); |
2672 | 2832 | ||
2833 | conn->sec_level = BT_SECURITY_LOW; | ||
2673 | conn->handle = __le16_to_cpu(ev->handle); | 2834 | conn->handle = __le16_to_cpu(ev->handle); |
2674 | conn->state = BT_CONNECTED; | 2835 | conn->state = BT_CONNECTED; |
2675 | 2836 | ||
@@ -2682,6 +2843,64 @@ unlock: | |||
2682 | hci_dev_unlock(hdev); | 2843 | hci_dev_unlock(hdev); |
2683 | } | 2844 | } |
2684 | 2845 | ||
2846 | static inline void hci_le_adv_report_evt(struct hci_dev *hdev, | ||
2847 | struct sk_buff *skb) | ||
2848 | { | ||
2849 | struct hci_ev_le_advertising_info *ev; | ||
2850 | u8 num_reports; | ||
2851 | |||
2852 | num_reports = skb->data[0]; | ||
2853 | ev = (void *) &skb->data[1]; | ||
2854 | |||
2855 | hci_dev_lock(hdev); | ||
2856 | |||
2857 | hci_add_adv_entry(hdev, ev); | ||
2858 | |||
2859 | while (--num_reports) { | ||
2860 | ev = (void *) (ev->data + ev->length + 1); | ||
2861 | hci_add_adv_entry(hdev, ev); | ||
2862 | } | ||
2863 | |||
2864 | hci_dev_unlock(hdev); | ||
2865 | } | ||
2866 | |||
2867 | static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, | ||
2868 | struct sk_buff *skb) | ||
2869 | { | ||
2870 | struct hci_ev_le_ltk_req *ev = (void *) skb->data; | ||
2871 | struct hci_cp_le_ltk_reply cp; | ||
2872 | struct hci_cp_le_ltk_neg_reply neg; | ||
2873 | struct hci_conn *conn; | ||
2874 | struct link_key *ltk; | ||
2875 | |||
2876 | BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle)); | ||
2877 | |||
2878 | hci_dev_lock(hdev); | ||
2879 | |||
2880 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
2881 | if (conn == NULL) | ||
2882 | goto not_found; | ||
2883 | |||
2884 | ltk = hci_find_ltk(hdev, ev->ediv, ev->random); | ||
2885 | if (ltk == NULL) | ||
2886 | goto not_found; | ||
2887 | |||
2888 | memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); | ||
2889 | cp.handle = cpu_to_le16(conn->handle); | ||
2890 | conn->pin_length = ltk->pin_len; | ||
2891 | |||
2892 | hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); | ||
2893 | |||
2894 | hci_dev_unlock(hdev); | ||
2895 | |||
2896 | return; | ||
2897 | |||
2898 | not_found: | ||
2899 | neg.handle = ev->handle; | ||
2900 | hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg); | ||
2901 | hci_dev_unlock(hdev); | ||
2902 | } | ||
2903 | |||
2685 | static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2904 | static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) |
2686 | { | 2905 | { |
2687 | struct hci_ev_le_meta *le_ev = (void *) skb->data; | 2906 | struct hci_ev_le_meta *le_ev = (void *) skb->data; |
@@ -2693,6 +2912,14 @@ static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2693 | hci_le_conn_complete_evt(hdev, skb); | 2912 | hci_le_conn_complete_evt(hdev, skb); |
2694 | break; | 2913 | break; |
2695 | 2914 | ||
2915 | case HCI_EV_LE_ADVERTISING_REPORT: | ||
2916 | hci_le_adv_report_evt(hdev, skb); | ||
2917 | break; | ||
2918 | |||
2919 | case HCI_EV_LE_LTK_REQ: | ||
2920 | hci_le_ltk_request_evt(hdev, skb); | ||
2921 | break; | ||
2922 | |||
2696 | default: | 2923 | default: |
2697 | break; | 2924 | break; |
2698 | } | 2925 | } |
@@ -2886,3 +3113,6 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) | |||
2886 | hci_send_to_sock(hdev, skb, NULL); | 3113 | hci_send_to_sock(hdev, skb, NULL); |
2887 | kfree_skb(skb); | 3114 | kfree_skb(skb); |
2888 | } | 3115 | } |
3116 | |||
3117 | module_param(enable_le, bool, 0444); | ||
3118 | MODULE_PARM_DESC(enable_le, "Enable LE support"); | ||