Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
This commit is contained in:
commit
791ef39cd1
18 changed files with 258 additions and 106 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue