Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

This commit is contained in:
John W. Linville 2012-09-24 14:39:16 -04:00
commit 791ef39cd1
18 changed files with 258 additions and 106 deletions

View file

@ -29,6 +29,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/mgmt.h>
/* Handle HCI Event packets */
@ -303,7 +304,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_lock(hdev);
if (status != 0) {
if (status) {
mgmt_write_scan_failed(hdev, param, status);
hdev->discov_timeout = 0;
goto done;
@ -925,7 +926,7 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
if (rp->status != 0)
if (rp->status)
goto unlock;
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)
}
}
static u8 hci_to_mgmt_reason(u8 err)
{
switch (err) {
case HCI_ERROR_CONNECTION_TIMEOUT:
return MGMT_DEV_DISCONN_TIMEOUT;
case HCI_ERROR_REMOTE_USER_TERM:
case HCI_ERROR_REMOTE_LOW_RESOURCES:
case HCI_ERROR_REMOTE_POWER_OFF:
return MGMT_DEV_DISCONN_REMOTE;
case HCI_ERROR_LOCAL_HOST_TERM:
return MGMT_DEV_DISCONN_LOCAL_HOST;
default:
return MGMT_DEV_DISCONN_UNKNOWN;
}
}
static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
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)
if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
(conn->type == ACL_LINK || conn->type == LE_LINK)) {
if (ev->status != 0)
if (ev->status) {
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, ev->status);
else
} else {
u8 reason = hci_to_mgmt_reason(ev->reason);
mgmt_device_disconnected(hdev, &conn->dst, conn->type,
conn->dst_type);
conn->dst_type, reason);
}
}
if (ev->status == 0) {
@ -3259,6 +3279,65 @@ static void hci_user_passkey_request_evt(struct hci_dev *hdev,
mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
}
static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s", hdev->name);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
return;
conn->passkey_notify = __le32_to_cpu(ev->passkey);
conn->passkey_entered = 0;
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
conn->dst_type, conn->passkey_notify,
conn->passkey_entered);
}
static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_keypress_notify *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s", hdev->name);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
return;
switch (ev->type) {
case HCI_KEYPRESS_STARTED:
conn->passkey_entered = 0;
return;
case HCI_KEYPRESS_ENTERED:
conn->passkey_entered++;
break;
case HCI_KEYPRESS_ERASED:
conn->passkey_entered--;
break;
case HCI_KEYPRESS_CLEARED:
conn->passkey_entered = 0;
break;
case HCI_KEYPRESS_COMPLETED:
return;
}
if (test_bit(HCI_MGMT, &hdev->dev_flags))
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
conn->dst_type, conn->passkey_notify,
conn->passkey_entered);
}
static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
@ -3278,7 +3357,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
* initiated the authentication. A traditional auth_complete
* event gets always produced as initiator and is also mapped to
* the mgmt_auth_failed event */
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
ev->status);
@ -3623,6 +3702,14 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_user_passkey_request_evt(hdev, skb);
break;
case HCI_EV_USER_PASSKEY_NOTIFY:
hci_user_passkey_notify_evt(hdev, skb);
break;
case HCI_EV_KEYPRESS_NOTIFY:
hci_keypress_notify_evt(hdev, skb);
break;
case HCI_EV_SIMPLE_PAIR_COMPLETE:
hci_simple_pair_complete_evt(hdev, skb);
break;