diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-09-24 14:39:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-09-24 14:39:16 -0400 |
commit | 791ef39cd18ae2745a63c51a5dbbd23312be0744 (patch) | |
tree | 195a547ce1bde51ba3f37cd771648c18d84cc947 /net/bluetooth/hci_event.c | |
parent | e5a876250d05d9708895da3d5408bdf67f1180f3 (diff) | |
parent | 0c1abbd1aa0416258881c303a88e618cbca0759c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 99 |
1 files changed, 93 insertions, 6 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 4fd2cf3bcd05..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; |
@@ -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); |
@@ -1891,6 +1892,22 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1891 | } | 1892 | } |
1892 | } | 1893 | } |
1893 | 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 | |||
1894 | 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) |
1895 | { | 1912 | { |
1896 | struct hci_ev_disconn_complete *ev = (void *) skb->data; | 1913 | struct hci_ev_disconn_complete *ev = (void *) skb->data; |
@@ -1909,12 +1926,15 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1909 | 1926 | ||
1910 | if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && | 1927 | if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && |
1911 | (conn->type == ACL_LINK || conn->type == LE_LINK)) { | 1928 | (conn->type == ACL_LINK || conn->type == LE_LINK)) { |
1912 | if (ev->status != 0) | 1929 | if (ev->status) { |
1913 | mgmt_disconnect_failed(hdev, &conn->dst, conn->type, | 1930 | mgmt_disconnect_failed(hdev, &conn->dst, conn->type, |
1914 | conn->dst_type, ev->status); | 1931 | conn->dst_type, ev->status); |
1915 | else | 1932 | } else { |
1933 | u8 reason = hci_to_mgmt_reason(ev->reason); | ||
1934 | |||
1916 | mgmt_device_disconnected(hdev, &conn->dst, conn->type, | 1935 | mgmt_device_disconnected(hdev, &conn->dst, conn->type, |
1917 | conn->dst_type); | 1936 | conn->dst_type, reason); |
1937 | } | ||
1918 | } | 1938 | } |
1919 | 1939 | ||
1920 | if (ev->status == 0) { | 1940 | if (ev->status == 0) { |
@@ -3259,6 +3279,65 @@ static void hci_user_passkey_request_evt(struct hci_dev *hdev, | |||
3259 | mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); | 3279 | mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0); |
3260 | } | 3280 | } |
3261 | 3281 | ||
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); | ||
3339 | } | ||
3340 | |||
3262 | static void hci_simple_pair_complete_evt(struct hci_dev *hdev, | 3341 | static void hci_simple_pair_complete_evt(struct hci_dev *hdev, |
3263 | struct sk_buff *skb) | 3342 | struct sk_buff *skb) |
3264 | { | 3343 | { |
@@ -3278,7 +3357,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, | |||
3278 | * initiated the authentication. A traditional auth_complete | 3357 | * initiated the authentication. A traditional auth_complete |
3279 | * event gets always produced as initiator and is also mapped to | 3358 | * event gets always produced as initiator and is also mapped to |
3280 | * the mgmt_auth_failed event */ | 3359 | * the mgmt_auth_failed event */ |
3281 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0) | 3360 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) |
3282 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, | 3361 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, |
3283 | ev->status); | 3362 | ev->status); |
3284 | 3363 | ||
@@ -3623,6 +3702,14 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
3623 | hci_user_passkey_request_evt(hdev, skb); | 3702 | hci_user_passkey_request_evt(hdev, skb); |
3624 | break; | 3703 | break; |
3625 | 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 | |||
3626 | case HCI_EV_SIMPLE_PAIR_COMPLETE: | 3713 | case HCI_EV_SIMPLE_PAIR_COMPLETE: |
3627 | hci_simple_pair_complete_evt(hdev, skb); | 3714 | hci_simple_pair_complete_evt(hdev, skb); |
3628 | break; | 3715 | break; |