aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorBrian Gix <bgix@codeaurora.org>2011-11-16 16:53:13 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-11-21 11:44:50 -0500
commit0df4c185ed84d914fa2671fa5f4cec2f8dee2d2e (patch)
tree7f423343ae9152cb08420103b03e74ba23b091f2 /net/bluetooth/mgmt.c
parent7784d78f184a80ca576f87b5a663b7b40e7a9b25 (diff)
Bluetooth: User Pairing Response restructuring
There are 4 possible User Responses to pairing requests, and they all share the same checks and handling. This restructures the handling of the two Confirm responses in preperation for the second two. Signed-off-by: Brian Gix <bgix@codeaurora.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 1ae14c91bb0..394222ef67a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1567,29 +1567,14 @@ unlock:
1567 return err; 1567 return err;
1568} 1568}
1569 1569
1570static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, 1570static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr,
1571 u16 len, int success) 1571 u16 mgmt_op, u16 hci_op, __le32 passkey)
1572{ 1572{
1573 struct mgmt_cp_user_confirm_reply *cp = (void *) data;
1574 u16 mgmt_op, hci_op;
1575 struct pending_cmd *cmd; 1573 struct pending_cmd *cmd;
1576 struct hci_dev *hdev; 1574 struct hci_dev *hdev;
1575 struct hci_conn *conn;
1577 int err; 1576 int err;
1578 1577
1579 BT_DBG("");
1580
1581 if (success) {
1582 mgmt_op = MGMT_OP_USER_CONFIRM_REPLY;
1583 hci_op = HCI_OP_USER_CONFIRM_REPLY;
1584 } else {
1585 mgmt_op = MGMT_OP_USER_CONFIRM_NEG_REPLY;
1586 hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY;
1587 }
1588
1589 if (len != sizeof(*cp))
1590 return cmd_status(sk, index, mgmt_op,
1591 MGMT_STATUS_INVALID_PARAMS);
1592
1593 hdev = hci_dev_get(index); 1578 hdev = hci_dev_get(index);
1594 if (!hdev) 1579 if (!hdev)
1595 return cmd_status(sk, index, mgmt_op, 1580 return cmd_status(sk, index, mgmt_op,
@@ -1598,27 +1583,59 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
1598 hci_dev_lock_bh(hdev); 1583 hci_dev_lock_bh(hdev);
1599 1584
1600 if (!test_bit(HCI_UP, &hdev->flags)) { 1585 if (!test_bit(HCI_UP, &hdev->flags)) {
1601 err = cmd_status(sk, index, mgmt_op, ENETDOWN); 1586 err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_NOT_POWERED);
1602 goto failed; 1587 goto done;
1603 } 1588 }
1604 1589
1605 cmd = mgmt_pending_add(sk, mgmt_op, hdev, data, len); 1590 cmd = mgmt_pending_add(sk, mgmt_op, hdev, bdaddr, sizeof(*bdaddr));
1606 if (!cmd) { 1591 if (!cmd) {
1607 err = -ENOMEM; 1592 err = -ENOMEM;
1608 goto failed; 1593 goto done;
1609 } 1594 }
1610 1595
1611 err = hci_send_cmd(hdev, hci_op, sizeof(cp->bdaddr), &cp->bdaddr); 1596 /* Continue with pairing via HCI */
1597 err = hci_send_cmd(hdev, hci_op, sizeof(*bdaddr), bdaddr);
1612 if (err < 0) 1598 if (err < 0)
1613 mgmt_pending_remove(cmd); 1599 mgmt_pending_remove(cmd);
1614 1600
1615failed: 1601done:
1616 hci_dev_unlock_bh(hdev); 1602 hci_dev_unlock_bh(hdev);
1617 hci_dev_put(hdev); 1603 hci_dev_put(hdev);
1618 1604
1619 return err; 1605 return err;
1620} 1606}
1621 1607
1608static int user_confirm_reply(struct sock *sk, u16 index, void *data, u16 len)
1609{
1610 struct mgmt_cp_user_confirm_reply *cp = (void *) data;
1611
1612 BT_DBG("");
1613
1614 if (len != sizeof(*cp))
1615 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_REPLY,
1616 MGMT_STATUS_INVALID_PARAMS);
1617
1618 return user_pairing_resp(sk, index, &cp->bdaddr,
1619 MGMT_OP_USER_CONFIRM_REPLY,
1620 HCI_OP_USER_CONFIRM_REPLY, 0);
1621}
1622
1623static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data,
1624 u16 len)
1625{
1626 struct mgmt_cp_user_confirm_reply *cp = (void *) data;
1627
1628 BT_DBG("");
1629
1630 if (len != sizeof(*cp))
1631 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_NEG_REPLY,
1632 MGMT_STATUS_INVALID_PARAMS);
1633
1634 return user_pairing_resp(sk, index, &cp->bdaddr,
1635 MGMT_OP_USER_CONFIRM_NEG_REPLY,
1636 HCI_OP_USER_CONFIRM_NEG_REPLY, 0);
1637}
1638
1622static int set_local_name(struct sock *sk, u16 index, unsigned char *data, 1639static int set_local_name(struct sock *sk, u16 index, unsigned char *data,
1623 u16 len) 1640 u16 len)
1624{ 1641{
@@ -2070,10 +2087,11 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
2070 err = pair_device(sk, index, buf + sizeof(*hdr), len); 2087 err = pair_device(sk, index, buf + sizeof(*hdr), len);
2071 break; 2088 break;
2072 case MGMT_OP_USER_CONFIRM_REPLY: 2089 case MGMT_OP_USER_CONFIRM_REPLY:
2073 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 1); 2090 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len);
2074 break; 2091 break;
2075 case MGMT_OP_USER_CONFIRM_NEG_REPLY: 2092 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
2076 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0); 2093 err = user_confirm_neg_reply(sk, index, buf + sizeof(*hdr),
2094 len);
2077 break; 2095 break;
2078 case MGMT_OP_SET_LOCAL_NAME: 2096 case MGMT_OP_SET_LOCAL_NAME:
2079 err = set_local_name(sk, index, buf + sizeof(*hdr), len); 2097 err = set_local_name(sk, index, buf + sizeof(*hdr), len);
@@ -2435,7 +2453,7 @@ int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
2435 NULL); 2453 NULL);
2436} 2454}
2437 2455
2438static int confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 2456static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2439 u8 status, u8 opcode) 2457 u8 status, u8 opcode)
2440{ 2458{
2441 struct pending_cmd *cmd; 2459 struct pending_cmd *cmd;
@@ -2458,14 +2476,14 @@ static int confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2458int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 2476int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2459 u8 status) 2477 u8 status)
2460{ 2478{
2461 return confirm_reply_complete(hdev, bdaddr, mgmt_status(status), 2479 return user_pairing_resp_complete(hdev, bdaddr, status,
2462 MGMT_OP_USER_CONFIRM_REPLY); 2480 MGMT_OP_USER_CONFIRM_REPLY);
2463} 2481}
2464 2482
2465int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, 2483int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev,
2466 bdaddr_t *bdaddr, u8 status) 2484 bdaddr_t *bdaddr, u8 status)
2467{ 2485{
2468 return confirm_reply_complete(hdev, bdaddr, mgmt_status(status), 2486 return user_pairing_resp_complete(hdev, bdaddr, status,
2469 MGMT_OP_USER_CONFIRM_NEG_REPLY); 2487 MGMT_OP_USER_CONFIRM_NEG_REPLY);
2470} 2488}
2471 2489