diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 190 |
1 files changed, 130 insertions, 60 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 715d7e33fba0..2022b43c7353 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
31 | #include <net/bluetooth/hci_core.h> | 31 | #include <net/bluetooth/hci_core.h> |
32 | #include <net/bluetooth/mgmt.h> | ||
32 | 33 | ||
33 | /* Handle HCI Event packets */ | 34 | /* Handle HCI Event packets */ |
34 | 35 | ||
@@ -303,7 +304,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
303 | 304 | ||
304 | hci_dev_lock(hdev); | 305 | hci_dev_lock(hdev); |
305 | 306 | ||
306 | if (status != 0) { | 307 | if (status) { |
307 | mgmt_write_scan_failed(hdev, param, status); | 308 | mgmt_write_scan_failed(hdev, param, status); |
308 | hdev->discov_timeout = 0; | 309 | hdev->discov_timeout = 0; |
309 | goto done; | 310 | goto done; |
@@ -513,7 +514,7 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
513 | if (hdev->features[3] & LMP_RSSI_INQ) | 514 | if (hdev->features[3] & LMP_RSSI_INQ) |
514 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | 515 | events[4] |= 0x02; /* Inquiry Result with RSSI */ |
515 | 516 | ||
516 | if (hdev->features[5] & LMP_SNIFF_SUBR) | 517 | if (lmp_sniffsubr_capable(hdev)) |
517 | events[5] |= 0x20; /* Sniff Subrating */ | 518 | events[5] |= 0x20; /* Sniff Subrating */ |
518 | 519 | ||
519 | if (hdev->features[5] & LMP_PAUSE_ENC) | 520 | if (hdev->features[5] & LMP_PAUSE_ENC) |
@@ -522,13 +523,13 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
522 | if (hdev->features[6] & LMP_EXT_INQ) | 523 | if (hdev->features[6] & LMP_EXT_INQ) |
523 | events[5] |= 0x40; /* Extended Inquiry Result */ | 524 | events[5] |= 0x40; /* Extended Inquiry Result */ |
524 | 525 | ||
525 | if (hdev->features[6] & LMP_NO_FLUSH) | 526 | if (lmp_no_flush_capable(hdev)) |
526 | events[7] |= 0x01; /* Enhanced Flush Complete */ | 527 | events[7] |= 0x01; /* Enhanced Flush Complete */ |
527 | 528 | ||
528 | if (hdev->features[7] & LMP_LSTO) | 529 | if (hdev->features[7] & LMP_LSTO) |
529 | events[6] |= 0x80; /* Link Supervision Timeout Changed */ | 530 | events[6] |= 0x80; /* Link Supervision Timeout Changed */ |
530 | 531 | ||
531 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { | 532 | if (lmp_ssp_capable(hdev)) { |
532 | events[6] |= 0x01; /* IO Capability Request */ | 533 | events[6] |= 0x01; /* IO Capability Request */ |
533 | events[6] |= 0x02; /* IO Capability Response */ | 534 | events[6] |= 0x02; /* IO Capability Response */ |
534 | events[6] |= 0x04; /* User Confirmation Request */ | 535 | events[6] |= 0x04; /* User Confirmation Request */ |
@@ -541,7 +542,7 @@ static void hci_setup_event_mask(struct hci_dev *hdev) | |||
541 | * Features Notification */ | 542 | * Features Notification */ |
542 | } | 543 | } |
543 | 544 | ||
544 | if (hdev->features[4] & LMP_LE) | 545 | if (lmp_le_capable(hdev)) |
545 | events[7] |= 0x20; /* LE Meta-Event */ | 546 | events[7] |= 0x20; /* LE Meta-Event */ |
546 | 547 | ||
547 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); | 548 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); |
@@ -623,11 +624,11 @@ static void hci_setup_link_policy(struct hci_dev *hdev) | |||
623 | struct hci_cp_write_def_link_policy cp; | 624 | struct hci_cp_write_def_link_policy cp; |
624 | u16 link_policy = 0; | 625 | u16 link_policy = 0; |
625 | 626 | ||
626 | if (hdev->features[0] & LMP_RSWITCH) | 627 | if (lmp_rswitch_capable(hdev)) |
627 | link_policy |= HCI_LP_RSWITCH; | 628 | link_policy |= HCI_LP_RSWITCH; |
628 | if (hdev->features[0] & LMP_HOLD) | 629 | if (hdev->features[0] & LMP_HOLD) |
629 | link_policy |= HCI_LP_HOLD; | 630 | link_policy |= HCI_LP_HOLD; |
630 | if (hdev->features[0] & LMP_SNIFF) | 631 | if (lmp_sniff_capable(hdev)) |
631 | link_policy |= HCI_LP_SNIFF; | 632 | link_policy |= HCI_LP_SNIFF; |
632 | if (hdev->features[1] & LMP_PARK) | 633 | if (hdev->features[1] & LMP_PARK) |
633 | link_policy |= HCI_LP_PARK; | 634 | link_policy |= HCI_LP_PARK; |
@@ -686,7 +687,7 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, | |||
686 | hdev->esco_type |= (ESCO_HV3); | 687 | hdev->esco_type |= (ESCO_HV3); |
687 | } | 688 | } |
688 | 689 | ||
689 | if (hdev->features[3] & LMP_ESCO) | 690 | if (lmp_esco_capable(hdev)) |
690 | hdev->esco_type |= (ESCO_EV3); | 691 | hdev->esco_type |= (ESCO_EV3); |
691 | 692 | ||
692 | if (hdev->features[4] & LMP_EV4) | 693 | if (hdev->features[4] & LMP_EV4) |
@@ -746,7 +747,7 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | |||
746 | break; | 747 | break; |
747 | } | 748 | } |
748 | 749 | ||
749 | if (test_bit(HCI_INIT, &hdev->flags) && hdev->features[4] & LMP_LE) | 750 | if (test_bit(HCI_INIT, &hdev->flags) && lmp_le_capable(hdev)) |
750 | hci_set_le_support(hdev); | 751 | hci_set_le_support(hdev); |
751 | 752 | ||
752 | done: | 753 | done: |
@@ -925,7 +926,7 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
925 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | 926 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
926 | mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); | 927 | mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status); |
927 | 928 | ||
928 | if (rp->status != 0) | 929 | if (rp->status) |
929 | goto unlock; | 930 | goto unlock; |
930 | 931 | ||
931 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); | 932 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); |
@@ -1625,43 +1626,30 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) | |||
1625 | 1626 | ||
1626 | static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) | 1627 | static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) |
1627 | { | 1628 | { |
1628 | struct hci_cp_le_create_conn *cp; | ||
1629 | struct hci_conn *conn; | 1629 | struct hci_conn *conn; |
1630 | 1630 | ||
1631 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 1631 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1632 | 1632 | ||
1633 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); | 1633 | if (status) { |
1634 | if (!cp) | 1634 | hci_dev_lock(hdev); |
1635 | return; | ||
1636 | 1635 | ||
1637 | hci_dev_lock(hdev); | 1636 | conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); |
1637 | if (!conn) { | ||
1638 | hci_dev_unlock(hdev); | ||
1639 | return; | ||
1640 | } | ||
1638 | 1641 | ||
1639 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); | 1642 | BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&conn->dst), |
1643 | conn); | ||
1640 | 1644 | ||
1641 | BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr), | 1645 | conn->state = BT_CLOSED; |
1642 | conn); | 1646 | mgmt_connect_failed(hdev, &conn->dst, conn->type, |
1647 | conn->dst_type, status); | ||
1648 | hci_proto_connect_cfm(conn, status); | ||
1649 | hci_conn_del(conn); | ||
1643 | 1650 | ||
1644 | if (status) { | 1651 | hci_dev_unlock(hdev); |
1645 | if (conn && conn->state == BT_CONNECT) { | ||
1646 | conn->state = BT_CLOSED; | ||
1647 | mgmt_connect_failed(hdev, &cp->peer_addr, conn->type, | ||
1648 | conn->dst_type, status); | ||
1649 | hci_proto_connect_cfm(conn, status); | ||
1650 | hci_conn_del(conn); | ||
1651 | } | ||
1652 | } else { | ||
1653 | if (!conn) { | ||
1654 | conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr); | ||
1655 | if (conn) { | ||
1656 | conn->dst_type = cp->peer_addr_type; | ||
1657 | conn->out = true; | ||
1658 | } else { | ||
1659 | BT_ERR("No memory for new connection"); | ||
1660 | } | ||
1661 | } | ||
1662 | } | 1652 | } |
1663 | |||
1664 | hci_dev_unlock(hdev); | ||
1665 | } | 1653 | } |
1666 | 1654 | ||
1667 | static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) | 1655 | static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) |
@@ -1904,6 +1892,22 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1904 | } | 1892 | } |
1905 | } | 1893 | } |
1906 | 1894 | ||
1895 | static u8 hci_to_mgmt_reason(u8 err) | ||
1896 | { | ||
1897 | switch (err) { | ||
1898 | case HCI_ERROR_CONNECTION_TIMEOUT: | ||
1899 | return MGMT_DEV_DISCONN_TIMEOUT; | ||
1900 | case HCI_ERROR_REMOTE_USER_TERM: | ||
1901 | case HCI_ERROR_REMOTE_LOW_RESOURCES: | ||
1902 | case HCI_ERROR_REMOTE_POWER_OFF: | ||
1903 | return MGMT_DEV_DISCONN_REMOTE; | ||
1904 | case HCI_ERROR_LOCAL_HOST_TERM: | ||
1905 | return MGMT_DEV_DISCONN_LOCAL_HOST; | ||
1906 | default: | ||
1907 | return MGMT_DEV_DISCONN_UNKNOWN; | ||
1908 | } | ||
1909 | } | ||
1910 | |||
1907 | static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1911 | static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1908 | { | 1912 | { |
1909 | struct hci_ev_disconn_complete *ev = (void *) skb->data; | 1913 | struct hci_ev_disconn_complete *ev = (void *) skb->data; |
@@ -1922,12 +1926,15 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1922 | 1926 | ||
1923 | if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && | 1927 | if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && |
1924 | (conn->type == ACL_LINK || conn->type == LE_LINK)) { | 1928 | (conn->type == ACL_LINK || conn->type == LE_LINK)) { |
1925 | if (ev->status != 0) | 1929 | if (ev->status) { |
1926 | mgmt_disconnect_failed(hdev, &conn->dst, conn->type, | 1930 | mgmt_disconnect_failed(hdev, &conn->dst, conn->type, |
1927 | conn->dst_type, ev->status); | 1931 | conn->dst_type, ev->status); |
1928 | else | 1932 | } else { |
1933 | u8 reason = hci_to_mgmt_reason(ev->reason); | ||
1934 | |||
1929 | mgmt_device_disconnected(hdev, &conn->dst, conn->type, | 1935 | mgmt_device_disconnected(hdev, &conn->dst, conn->type, |
1930 | conn->dst_type); | 1936 | conn->dst_type, reason); |
1937 | } | ||
1931 | } | 1938 | } |
1932 | 1939 | ||
1933 | if (ev->status == 0) { | 1940 | if (ev->status == 0) { |
@@ -3268,12 +3275,67 @@ static void hci_user_passkey_request_evt(struct hci_dev *hdev, | |||
3268 | 3275 | ||
3269 | BT_DBG("%s", hdev->name); | 3276 | BT_DBG("%s", hdev->name); |
3270 | 3277 | ||
3271 | hci_dev_lock(hdev); | ||
3272 | |||
3273 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | 3278 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
3274 | mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); | 3279 | mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); |
3280 | } | ||
3275 | 3281 | ||
3276 | hci_dev_unlock(hdev); | 3282 | static void hci_user_passkey_notify_evt(struct hci_dev *hdev, |
3283 | struct sk_buff *skb) | ||
3284 | { | ||
3285 | struct hci_ev_user_passkey_notify *ev = (void *) skb->data; | ||
3286 | struct hci_conn *conn; | ||
3287 | |||
3288 | BT_DBG("%s", hdev->name); | ||
3289 | |||
3290 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
3291 | if (!conn) | ||
3292 | return; | ||
3293 | |||
3294 | conn->passkey_notify = __le32_to_cpu(ev->passkey); | ||
3295 | conn->passkey_entered = 0; | ||
3296 | |||
3297 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | ||
3298 | mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, | ||
3299 | conn->dst_type, conn->passkey_notify, | ||
3300 | conn->passkey_entered); | ||
3301 | } | ||
3302 | |||
3303 | static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
3304 | { | ||
3305 | struct hci_ev_keypress_notify *ev = (void *) skb->data; | ||
3306 | struct hci_conn *conn; | ||
3307 | |||
3308 | BT_DBG("%s", hdev->name); | ||
3309 | |||
3310 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
3311 | if (!conn) | ||
3312 | return; | ||
3313 | |||
3314 | switch (ev->type) { | ||
3315 | case HCI_KEYPRESS_STARTED: | ||
3316 | conn->passkey_entered = 0; | ||
3317 | return; | ||
3318 | |||
3319 | case HCI_KEYPRESS_ENTERED: | ||
3320 | conn->passkey_entered++; | ||
3321 | break; | ||
3322 | |||
3323 | case HCI_KEYPRESS_ERASED: | ||
3324 | conn->passkey_entered--; | ||
3325 | break; | ||
3326 | |||
3327 | case HCI_KEYPRESS_CLEARED: | ||
3328 | conn->passkey_entered = 0; | ||
3329 | break; | ||
3330 | |||
3331 | case HCI_KEYPRESS_COMPLETED: | ||
3332 | return; | ||
3333 | } | ||
3334 | |||
3335 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | ||
3336 | mgmt_user_passkey_notify(hdev, &conn->dst, conn->type, | ||
3337 | conn->dst_type, conn->passkey_notify, | ||
3338 | conn->passkey_entered); | ||
3277 | } | 3339 | } |
3278 | 3340 | ||
3279 | static void hci_simple_pair_complete_evt(struct hci_dev *hdev, | 3341 | static void hci_simple_pair_complete_evt(struct hci_dev *hdev, |
@@ -3295,7 +3357,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, | |||
3295 | * initiated the authentication. A traditional auth_complete | 3357 | * initiated the authentication. A traditional auth_complete |
3296 | * event gets always produced as initiator and is also mapped to | 3358 | * event gets always produced as initiator and is also mapped to |
3297 | * the mgmt_auth_failed event */ | 3359 | * the mgmt_auth_failed event */ |
3298 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0) | 3360 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) |
3299 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, | 3361 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, |
3300 | ev->status); | 3362 | ev->status); |
3301 | 3363 | ||
@@ -3366,11 +3428,23 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3366 | 3428 | ||
3367 | hci_dev_lock(hdev); | 3429 | hci_dev_lock(hdev); |
3368 | 3430 | ||
3369 | if (ev->status) { | 3431 | conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); |
3370 | conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); | 3432 | if (!conn) { |
3371 | if (!conn) | 3433 | conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); |
3434 | if (!conn) { | ||
3435 | BT_ERR("No memory for new connection"); | ||
3372 | goto unlock; | 3436 | goto unlock; |
3437 | } | ||
3438 | |||
3439 | conn->dst_type = ev->bdaddr_type; | ||
3373 | 3440 | ||
3441 | if (ev->role == LE_CONN_ROLE_MASTER) { | ||
3442 | conn->out = true; | ||
3443 | conn->link_mode |= HCI_LM_MASTER; | ||
3444 | } | ||
3445 | } | ||
3446 | |||
3447 | if (ev->status) { | ||
3374 | mgmt_connect_failed(hdev, &conn->dst, conn->type, | 3448 | mgmt_connect_failed(hdev, &conn->dst, conn->type, |
3375 | conn->dst_type, ev->status); | 3449 | conn->dst_type, ev->status); |
3376 | hci_proto_connect_cfm(conn, ev->status); | 3450 | hci_proto_connect_cfm(conn, ev->status); |
@@ -3379,18 +3453,6 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3379 | goto unlock; | 3453 | goto unlock; |
3380 | } | 3454 | } |
3381 | 3455 | ||
3382 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); | ||
3383 | if (!conn) { | ||
3384 | conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); | ||
3385 | if (!conn) { | ||
3386 | BT_ERR("No memory for new connection"); | ||
3387 | hci_dev_unlock(hdev); | ||
3388 | return; | ||
3389 | } | ||
3390 | |||
3391 | conn->dst_type = ev->bdaddr_type; | ||
3392 | } | ||
3393 | |||
3394 | if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) | 3456 | if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) |
3395 | mgmt_device_connected(hdev, &ev->bdaddr, conn->type, | 3457 | mgmt_device_connected(hdev, &ev->bdaddr, conn->type, |
3396 | conn->dst_type, 0, NULL, 0, NULL); | 3458 | conn->dst_type, 0, NULL, 0, NULL); |
@@ -3640,6 +3702,14 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
3640 | hci_user_passkey_request_evt(hdev, skb); | 3702 | hci_user_passkey_request_evt(hdev, skb); |
3641 | break; | 3703 | break; |
3642 | 3704 | ||
3705 | case HCI_EV_USER_PASSKEY_NOTIFY: | ||
3706 | hci_user_passkey_notify_evt(hdev, skb); | ||
3707 | break; | ||
3708 | |||
3709 | case HCI_EV_KEYPRESS_NOTIFY: | ||
3710 | hci_keypress_notify_evt(hdev, skb); | ||
3711 | break; | ||
3712 | |||
3643 | case HCI_EV_SIMPLE_PAIR_COMPLETE: | 3713 | case HCI_EV_SIMPLE_PAIR_COMPLETE: |
3644 | hci_simple_pair_complete_evt(hdev, skb); | 3714 | hci_simple_pair_complete_evt(hdev, skb); |
3645 | break; | 3715 | break; |