diff options
author | John W. Linville <linville@tuxdriver.com> | 2014-05-29 13:03:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-29 13:03:47 -0400 |
commit | a5eb1aeb25df89c627248a162cc35ffb556dc486 (patch) | |
tree | 934fd6b18f17f72d5e57708b8e3a12b0071f1327 /net | |
parent | 737be10d8cb783d1cadb1868b061abb2b4314eae (diff) | |
parent | d7b2545023ecfde94d3ea9c03c5480ac18da96c9 (diff) |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Conflicts:
drivers/bluetooth/btusb.c
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_conn.c | 3 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 64 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 61 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 236 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 2 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 20 | ||||
-rw-r--r-- | net/bluetooth/smp.c | 153 | ||||
-rw-r--r-- | net/bluetooth/smp.h | 30 |
8 files changed, 449 insertions, 120 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 095943c02d6e..8671bc79a35b 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include <net/bluetooth/bluetooth.h> | 29 | #include <net/bluetooth/bluetooth.h> |
30 | #include <net/bluetooth/hci_core.h> | 30 | #include <net/bluetooth/hci_core.h> |
31 | #include <net/bluetooth/l2cap.h> | ||
31 | 32 | ||
32 | #include "smp.h" | 33 | #include "smp.h" |
33 | #include "a2mp.h" | 34 | #include "a2mp.h" |
@@ -407,6 +408,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
407 | conn->io_capability = hdev->io_capability; | 408 | conn->io_capability = hdev->io_capability; |
408 | conn->remote_auth = 0xff; | 409 | conn->remote_auth = 0xff; |
409 | conn->key_type = 0xff; | 410 | conn->key_type = 0xff; |
411 | conn->tx_power = HCI_TX_POWER_INVALID; | ||
412 | conn->max_tx_power = HCI_TX_POWER_INVALID; | ||
410 | 413 | ||
411 | set_bit(HCI_CONN_POWER_SAVE, &conn->flags); | 414 | set_bit(HCI_CONN_POWER_SAVE, &conn->flags); |
412 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 415 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index d31f144860d1..0a43cce9a914 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <net/bluetooth/bluetooth.h> | 35 | #include <net/bluetooth/bluetooth.h> |
36 | #include <net/bluetooth/hci_core.h> | 36 | #include <net/bluetooth/hci_core.h> |
37 | #include <net/bluetooth/l2cap.h> | ||
37 | 38 | ||
38 | #include "smp.h" | 39 | #include "smp.h" |
39 | 40 | ||
@@ -579,6 +580,62 @@ static int sniff_max_interval_get(void *data, u64 *val) | |||
579 | DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, | 580 | DEFINE_SIMPLE_ATTRIBUTE(sniff_max_interval_fops, sniff_max_interval_get, |
580 | sniff_max_interval_set, "%llu\n"); | 581 | sniff_max_interval_set, "%llu\n"); |
581 | 582 | ||
583 | static int conn_info_min_age_set(void *data, u64 val) | ||
584 | { | ||
585 | struct hci_dev *hdev = data; | ||
586 | |||
587 | if (val == 0 || val > hdev->conn_info_max_age) | ||
588 | return -EINVAL; | ||
589 | |||
590 | hci_dev_lock(hdev); | ||
591 | hdev->conn_info_min_age = val; | ||
592 | hci_dev_unlock(hdev); | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | static int conn_info_min_age_get(void *data, u64 *val) | ||
598 | { | ||
599 | struct hci_dev *hdev = data; | ||
600 | |||
601 | hci_dev_lock(hdev); | ||
602 | *val = hdev->conn_info_min_age; | ||
603 | hci_dev_unlock(hdev); | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | DEFINE_SIMPLE_ATTRIBUTE(conn_info_min_age_fops, conn_info_min_age_get, | ||
609 | conn_info_min_age_set, "%llu\n"); | ||
610 | |||
611 | static int conn_info_max_age_set(void *data, u64 val) | ||
612 | { | ||
613 | struct hci_dev *hdev = data; | ||
614 | |||
615 | if (val == 0 || val < hdev->conn_info_min_age) | ||
616 | return -EINVAL; | ||
617 | |||
618 | hci_dev_lock(hdev); | ||
619 | hdev->conn_info_max_age = val; | ||
620 | hci_dev_unlock(hdev); | ||
621 | |||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static int conn_info_max_age_get(void *data, u64 *val) | ||
626 | { | ||
627 | struct hci_dev *hdev = data; | ||
628 | |||
629 | hci_dev_lock(hdev); | ||
630 | *val = hdev->conn_info_max_age; | ||
631 | hci_dev_unlock(hdev); | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | DEFINE_SIMPLE_ATTRIBUTE(conn_info_max_age_fops, conn_info_max_age_get, | ||
637 | conn_info_max_age_set, "%llu\n"); | ||
638 | |||
582 | static int identity_show(struct seq_file *f, void *p) | 639 | static int identity_show(struct seq_file *f, void *p) |
583 | { | 640 | { |
584 | struct hci_dev *hdev = f->private; | 641 | struct hci_dev *hdev = f->private; |
@@ -1754,6 +1811,11 @@ static int __hci_init(struct hci_dev *hdev) | |||
1754 | &blacklist_fops); | 1811 | &blacklist_fops); |
1755 | debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); | 1812 | debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); |
1756 | 1813 | ||
1814 | debugfs_create_file("conn_info_min_age", 0644, hdev->debugfs, hdev, | ||
1815 | &conn_info_min_age_fops); | ||
1816 | debugfs_create_file("conn_info_max_age", 0644, hdev->debugfs, hdev, | ||
1817 | &conn_info_max_age_fops); | ||
1818 | |||
1757 | if (lmp_bredr_capable(hdev)) { | 1819 | if (lmp_bredr_capable(hdev)) { |
1758 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, | 1820 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, |
1759 | hdev, &inquiry_cache_fops); | 1821 | hdev, &inquiry_cache_fops); |
@@ -3789,6 +3851,8 @@ struct hci_dev *hci_alloc_dev(void) | |||
3789 | 3851 | ||
3790 | hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; | 3852 | hdev->rpa_timeout = HCI_DEFAULT_RPA_TIMEOUT; |
3791 | hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; | 3853 | hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; |
3854 | hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; | ||
3855 | hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; | ||
3792 | 3856 | ||
3793 | mutex_init(&hdev->lock); | 3857 | mutex_init(&hdev->lock); |
3794 | mutex_init(&hdev->req_lock); | 3858 | mutex_init(&hdev->req_lock); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index ca19fd4bbb8f..3454807a40c5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1245,6 +1245,59 @@ static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, | |||
1245 | amp_write_rem_assoc_continue(hdev, rp->phy_handle); | 1245 | amp_write_rem_assoc_continue(hdev, rp->phy_handle); |
1246 | } | 1246 | } |
1247 | 1247 | ||
1248 | static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) | ||
1249 | { | ||
1250 | struct hci_rp_read_rssi *rp = (void *) skb->data; | ||
1251 | struct hci_conn *conn; | ||
1252 | |||
1253 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | ||
1254 | |||
1255 | if (rp->status) | ||
1256 | return; | ||
1257 | |||
1258 | hci_dev_lock(hdev); | ||
1259 | |||
1260 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); | ||
1261 | if (conn) | ||
1262 | conn->rssi = rp->rssi; | ||
1263 | |||
1264 | hci_dev_unlock(hdev); | ||
1265 | } | ||
1266 | |||
1267 | static void hci_cc_read_tx_power(struct hci_dev *hdev, struct sk_buff *skb) | ||
1268 | { | ||
1269 | struct hci_cp_read_tx_power *sent; | ||
1270 | struct hci_rp_read_tx_power *rp = (void *) skb->data; | ||
1271 | struct hci_conn *conn; | ||
1272 | |||
1273 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | ||
1274 | |||
1275 | if (rp->status) | ||
1276 | return; | ||
1277 | |||
1278 | sent = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); | ||
1279 | if (!sent) | ||
1280 | return; | ||
1281 | |||
1282 | hci_dev_lock(hdev); | ||
1283 | |||
1284 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); | ||
1285 | if (!conn) | ||
1286 | goto unlock; | ||
1287 | |||
1288 | switch (sent->type) { | ||
1289 | case 0x00: | ||
1290 | conn->tx_power = rp->tx_power; | ||
1291 | break; | ||
1292 | case 0x01: | ||
1293 | conn->max_tx_power = rp->tx_power; | ||
1294 | break; | ||
1295 | } | ||
1296 | |||
1297 | unlock: | ||
1298 | hci_dev_unlock(hdev); | ||
1299 | } | ||
1300 | |||
1248 | static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 1301 | static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
1249 | { | 1302 | { |
1250 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 1303 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
@@ -2637,6 +2690,14 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2637 | hci_cc_write_remote_amp_assoc(hdev, skb); | 2690 | hci_cc_write_remote_amp_assoc(hdev, skb); |
2638 | break; | 2691 | break; |
2639 | 2692 | ||
2693 | case HCI_OP_READ_RSSI: | ||
2694 | hci_cc_read_rssi(hdev, skb); | ||
2695 | break; | ||
2696 | |||
2697 | case HCI_OP_READ_TX_POWER: | ||
2698 | hci_cc_read_tx_power(hdev, skb); | ||
2699 | break; | ||
2700 | |||
2640 | default: | 2701 | default: |
2641 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); | 2702 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
2642 | break; | 2703 | break; |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 54abbce3a39e..5e9c21a5525f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -29,12 +29,13 @@ | |||
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/l2cap.h> | ||
32 | #include <net/bluetooth/mgmt.h> | 33 | #include <net/bluetooth/mgmt.h> |
33 | 34 | ||
34 | #include "smp.h" | 35 | #include "smp.h" |
35 | 36 | ||
36 | #define MGMT_VERSION 1 | 37 | #define MGMT_VERSION 1 |
37 | #define MGMT_REVISION 5 | 38 | #define MGMT_REVISION 6 |
38 | 39 | ||
39 | static const u16 mgmt_commands[] = { | 40 | static const u16 mgmt_commands[] = { |
40 | MGMT_OP_READ_INDEX_LIST, | 41 | MGMT_OP_READ_INDEX_LIST, |
@@ -83,6 +84,7 @@ static const u16 mgmt_commands[] = { | |||
83 | MGMT_OP_SET_DEBUG_KEYS, | 84 | MGMT_OP_SET_DEBUG_KEYS, |
84 | MGMT_OP_SET_PRIVACY, | 85 | MGMT_OP_SET_PRIVACY, |
85 | MGMT_OP_LOAD_IRKS, | 86 | MGMT_OP_LOAD_IRKS, |
87 | MGMT_OP_GET_CONN_INFO, | ||
86 | }; | 88 | }; |
87 | 89 | ||
88 | static const u16 mgmt_events[] = { | 90 | static const u16 mgmt_events[] = { |
@@ -4532,7 +4534,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, | |||
4532 | 4534 | ||
4533 | for (i = 0; i < key_count; i++) { | 4535 | for (i = 0; i < key_count; i++) { |
4534 | struct mgmt_ltk_info *key = &cp->keys[i]; | 4536 | struct mgmt_ltk_info *key = &cp->keys[i]; |
4535 | u8 type, addr_type; | 4537 | u8 type, addr_type, authenticated; |
4536 | 4538 | ||
4537 | if (key->addr.type == BDADDR_LE_PUBLIC) | 4539 | if (key->addr.type == BDADDR_LE_PUBLIC) |
4538 | addr_type = ADDR_LE_DEV_PUBLIC; | 4540 | addr_type = ADDR_LE_DEV_PUBLIC; |
@@ -4544,8 +4546,13 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, | |||
4544 | else | 4546 | else |
4545 | type = HCI_SMP_LTK_SLAVE; | 4547 | type = HCI_SMP_LTK_SLAVE; |
4546 | 4548 | ||
4549 | if (key->type == MGMT_LTK_UNAUTHENTICATED) | ||
4550 | authenticated = 0x00; | ||
4551 | else | ||
4552 | authenticated = 0x01; | ||
4553 | |||
4547 | hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type, | 4554 | hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type, |
4548 | key->type, key->val, key->enc_size, key->ediv, | 4555 | authenticated, key->val, key->enc_size, key->ediv, |
4549 | key->rand); | 4556 | key->rand); |
4550 | } | 4557 | } |
4551 | 4558 | ||
@@ -4557,6 +4564,218 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, | |||
4557 | return err; | 4564 | return err; |
4558 | } | 4565 | } |
4559 | 4566 | ||
4567 | struct cmd_conn_lookup { | ||
4568 | struct hci_conn *conn; | ||
4569 | bool valid_tx_power; | ||
4570 | u8 mgmt_status; | ||
4571 | }; | ||
4572 | |||
4573 | static void get_conn_info_complete(struct pending_cmd *cmd, void *data) | ||
4574 | { | ||
4575 | struct cmd_conn_lookup *match = data; | ||
4576 | struct mgmt_cp_get_conn_info *cp; | ||
4577 | struct mgmt_rp_get_conn_info rp; | ||
4578 | struct hci_conn *conn = cmd->user_data; | ||
4579 | |||
4580 | if (conn != match->conn) | ||
4581 | return; | ||
4582 | |||
4583 | cp = (struct mgmt_cp_get_conn_info *) cmd->param; | ||
4584 | |||
4585 | memset(&rp, 0, sizeof(rp)); | ||
4586 | bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr); | ||
4587 | rp.addr.type = cp->addr.type; | ||
4588 | |||
4589 | if (!match->mgmt_status) { | ||
4590 | rp.rssi = conn->rssi; | ||
4591 | |||
4592 | if (match->valid_tx_power) { | ||
4593 | rp.tx_power = conn->tx_power; | ||
4594 | rp.max_tx_power = conn->max_tx_power; | ||
4595 | } else { | ||
4596 | rp.tx_power = HCI_TX_POWER_INVALID; | ||
4597 | rp.max_tx_power = HCI_TX_POWER_INVALID; | ||
4598 | } | ||
4599 | } | ||
4600 | |||
4601 | cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, | ||
4602 | match->mgmt_status, &rp, sizeof(rp)); | ||
4603 | |||
4604 | hci_conn_drop(conn); | ||
4605 | |||
4606 | mgmt_pending_remove(cmd); | ||
4607 | } | ||
4608 | |||
4609 | static void conn_info_refresh_complete(struct hci_dev *hdev, u8 status) | ||
4610 | { | ||
4611 | struct hci_cp_read_rssi *cp; | ||
4612 | struct hci_conn *conn; | ||
4613 | struct cmd_conn_lookup match; | ||
4614 | u16 handle; | ||
4615 | |||
4616 | BT_DBG("status 0x%02x", status); | ||
4617 | |||
4618 | hci_dev_lock(hdev); | ||
4619 | |||
4620 | /* TX power data is valid in case request completed successfully, | ||
4621 | * otherwise we assume it's not valid. At the moment we assume that | ||
4622 | * either both or none of current and max values are valid to keep code | ||
4623 | * simple. | ||
4624 | */ | ||
4625 | match.valid_tx_power = !status; | ||
4626 | |||
4627 | /* Commands sent in request are either Read RSSI or Read Transmit Power | ||
4628 | * Level so we check which one was last sent to retrieve connection | ||
4629 | * handle. Both commands have handle as first parameter so it's safe to | ||
4630 | * cast data on the same command struct. | ||
4631 | * | ||
4632 | * First command sent is always Read RSSI and we fail only if it fails. | ||
4633 | * In other case we simply override error to indicate success as we | ||
4634 | * already remembered if TX power value is actually valid. | ||
4635 | */ | ||
4636 | cp = hci_sent_cmd_data(hdev, HCI_OP_READ_RSSI); | ||
4637 | if (!cp) { | ||
4638 | cp = hci_sent_cmd_data(hdev, HCI_OP_READ_TX_POWER); | ||
4639 | status = 0; | ||
4640 | } | ||
4641 | |||
4642 | if (!cp) { | ||
4643 | BT_ERR("invalid sent_cmd in response"); | ||
4644 | goto unlock; | ||
4645 | } | ||
4646 | |||
4647 | handle = __le16_to_cpu(cp->handle); | ||
4648 | conn = hci_conn_hash_lookup_handle(hdev, handle); | ||
4649 | if (!conn) { | ||
4650 | BT_ERR("unknown handle (%d) in response", handle); | ||
4651 | goto unlock; | ||
4652 | } | ||
4653 | |||
4654 | match.conn = conn; | ||
4655 | match.mgmt_status = mgmt_status(status); | ||
4656 | |||
4657 | /* Cache refresh is complete, now reply for mgmt request for given | ||
4658 | * connection only. | ||
4659 | */ | ||
4660 | mgmt_pending_foreach(MGMT_OP_GET_CONN_INFO, hdev, | ||
4661 | get_conn_info_complete, &match); | ||
4662 | |||
4663 | unlock: | ||
4664 | hci_dev_unlock(hdev); | ||
4665 | } | ||
4666 | |||
4667 | static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, | ||
4668 | u16 len) | ||
4669 | { | ||
4670 | struct mgmt_cp_get_conn_info *cp = data; | ||
4671 | struct mgmt_rp_get_conn_info rp; | ||
4672 | struct hci_conn *conn; | ||
4673 | unsigned long conn_info_age; | ||
4674 | int err = 0; | ||
4675 | |||
4676 | BT_DBG("%s", hdev->name); | ||
4677 | |||
4678 | memset(&rp, 0, sizeof(rp)); | ||
4679 | bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr); | ||
4680 | rp.addr.type = cp->addr.type; | ||
4681 | |||
4682 | if (!bdaddr_type_is_valid(cp->addr.type)) | ||
4683 | return cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, | ||
4684 | MGMT_STATUS_INVALID_PARAMS, | ||
4685 | &rp, sizeof(rp)); | ||
4686 | |||
4687 | hci_dev_lock(hdev); | ||
4688 | |||
4689 | if (!hdev_is_powered(hdev)) { | ||
4690 | err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, | ||
4691 | MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp)); | ||
4692 | goto unlock; | ||
4693 | } | ||
4694 | |||
4695 | if (cp->addr.type == BDADDR_BREDR) | ||
4696 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, | ||
4697 | &cp->addr.bdaddr); | ||
4698 | else | ||
4699 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); | ||
4700 | |||
4701 | if (!conn || conn->state != BT_CONNECTED) { | ||
4702 | err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, | ||
4703 | MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp)); | ||
4704 | goto unlock; | ||
4705 | } | ||
4706 | |||
4707 | /* To avoid client trying to guess when to poll again for information we | ||
4708 | * calculate conn info age as random value between min/max set in hdev. | ||
4709 | */ | ||
4710 | conn_info_age = hdev->conn_info_min_age + | ||
4711 | prandom_u32_max(hdev->conn_info_max_age - | ||
4712 | hdev->conn_info_min_age); | ||
4713 | |||
4714 | /* Query controller to refresh cached values if they are too old or were | ||
4715 | * never read. | ||
4716 | */ | ||
4717 | if (time_after(jiffies, conn->conn_info_timestamp + | ||
4718 | msecs_to_jiffies(conn_info_age)) || | ||
4719 | !conn->conn_info_timestamp) { | ||
4720 | struct hci_request req; | ||
4721 | struct hci_cp_read_tx_power req_txp_cp; | ||
4722 | struct hci_cp_read_rssi req_rssi_cp; | ||
4723 | struct pending_cmd *cmd; | ||
4724 | |||
4725 | hci_req_init(&req, hdev); | ||
4726 | req_rssi_cp.handle = cpu_to_le16(conn->handle); | ||
4727 | hci_req_add(&req, HCI_OP_READ_RSSI, sizeof(req_rssi_cp), | ||
4728 | &req_rssi_cp); | ||
4729 | |||
4730 | /* For LE links TX power does not change thus we don't need to | ||
4731 | * query for it once value is known. | ||
4732 | */ | ||
4733 | if (!bdaddr_type_is_le(cp->addr.type) || | ||
4734 | conn->tx_power == HCI_TX_POWER_INVALID) { | ||
4735 | req_txp_cp.handle = cpu_to_le16(conn->handle); | ||
4736 | req_txp_cp.type = 0x00; | ||
4737 | hci_req_add(&req, HCI_OP_READ_TX_POWER, | ||
4738 | sizeof(req_txp_cp), &req_txp_cp); | ||
4739 | } | ||
4740 | |||
4741 | /* Max TX power needs to be read only once per connection */ | ||
4742 | if (conn->max_tx_power == HCI_TX_POWER_INVALID) { | ||
4743 | req_txp_cp.handle = cpu_to_le16(conn->handle); | ||
4744 | req_txp_cp.type = 0x01; | ||
4745 | hci_req_add(&req, HCI_OP_READ_TX_POWER, | ||
4746 | sizeof(req_txp_cp), &req_txp_cp); | ||
4747 | } | ||
4748 | |||
4749 | err = hci_req_run(&req, conn_info_refresh_complete); | ||
4750 | if (err < 0) | ||
4751 | goto unlock; | ||
4752 | |||
4753 | cmd = mgmt_pending_add(sk, MGMT_OP_GET_CONN_INFO, hdev, | ||
4754 | data, len); | ||
4755 | if (!cmd) { | ||
4756 | err = -ENOMEM; | ||
4757 | goto unlock; | ||
4758 | } | ||
4759 | |||
4760 | hci_conn_hold(conn); | ||
4761 | cmd->user_data = conn; | ||
4762 | |||
4763 | conn->conn_info_timestamp = jiffies; | ||
4764 | } else { | ||
4765 | /* Cache is valid, just reply with values cached in hci_conn */ | ||
4766 | rp.rssi = conn->rssi; | ||
4767 | rp.tx_power = conn->tx_power; | ||
4768 | rp.max_tx_power = conn->max_tx_power; | ||
4769 | |||
4770 | err = cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO, | ||
4771 | MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); | ||
4772 | } | ||
4773 | |||
4774 | unlock: | ||
4775 | hci_dev_unlock(hdev); | ||
4776 | return err; | ||
4777 | } | ||
4778 | |||
4560 | static const struct mgmt_handler { | 4779 | static const struct mgmt_handler { |
4561 | int (*func) (struct sock *sk, struct hci_dev *hdev, void *data, | 4780 | int (*func) (struct sock *sk, struct hci_dev *hdev, void *data, |
4562 | u16 data_len); | 4781 | u16 data_len); |
@@ -4612,6 +4831,7 @@ static const struct mgmt_handler { | |||
4612 | { set_debug_keys, false, MGMT_SETTING_SIZE }, | 4831 | { set_debug_keys, false, MGMT_SETTING_SIZE }, |
4613 | { set_privacy, false, MGMT_SET_PRIVACY_SIZE }, | 4832 | { set_privacy, false, MGMT_SET_PRIVACY_SIZE }, |
4614 | { load_irks, true, MGMT_LOAD_IRKS_SIZE }, | 4833 | { load_irks, true, MGMT_LOAD_IRKS_SIZE }, |
4834 | { get_conn_info, false, MGMT_GET_CONN_INFO_SIZE }, | ||
4615 | }; | 4835 | }; |
4616 | 4836 | ||
4617 | 4837 | ||
@@ -5007,6 +5227,14 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, | |||
5007 | mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); | 5227 | mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); |
5008 | } | 5228 | } |
5009 | 5229 | ||
5230 | static u8 mgmt_ltk_type(struct smp_ltk *ltk) | ||
5231 | { | ||
5232 | if (ltk->authenticated) | ||
5233 | return MGMT_LTK_AUTHENTICATED; | ||
5234 | |||
5235 | return MGMT_LTK_UNAUTHENTICATED; | ||
5236 | } | ||
5237 | |||
5010 | void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) | 5238 | void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) |
5011 | { | 5239 | { |
5012 | struct mgmt_ev_new_long_term_key ev; | 5240 | struct mgmt_ev_new_long_term_key ev; |
@@ -5032,7 +5260,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent) | |||
5032 | 5260 | ||
5033 | bacpy(&ev.key.addr.bdaddr, &key->bdaddr); | 5261 | bacpy(&ev.key.addr.bdaddr, &key->bdaddr); |
5034 | ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); | 5262 | ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type); |
5035 | ev.key.type = key->authenticated; | 5263 | ev.key.type = mgmt_ltk_type(key); |
5036 | ev.key.enc_size = key->enc_size; | 5264 | ev.key.enc_size = key->enc_size; |
5037 | ev.key.ediv = key->ediv; | 5265 | ev.key.ediv = key->ediv; |
5038 | ev.key.rand = key->rand; | 5266 | ev.key.rand = key->rand; |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index cf620260affa..754b6fe4f742 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -307,7 +307,7 @@ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio) | |||
307 | setup_timer(&d->timer, rfcomm_dlc_timeout, (unsigned long)d); | 307 | setup_timer(&d->timer, rfcomm_dlc_timeout, (unsigned long)d); |
308 | 308 | ||
309 | skb_queue_head_init(&d->tx_queue); | 309 | skb_queue_head_init(&d->tx_queue); |
310 | spin_lock_init(&d->lock); | 310 | mutex_init(&d->lock); |
311 | atomic_set(&d->refcnt, 1); | 311 | atomic_set(&d->refcnt, 1); |
312 | 312 | ||
313 | rfcomm_dlc_clear_state(d); | 313 | rfcomm_dlc_clear_state(d); |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 403ec09f480a..8e385a0ae60e 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -70,7 +70,7 @@ struct rfcomm_dev { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | static LIST_HEAD(rfcomm_dev_list); | 72 | static LIST_HEAD(rfcomm_dev_list); |
73 | static DEFINE_SPINLOCK(rfcomm_dev_lock); | 73 | static DEFINE_MUTEX(rfcomm_dev_lock); |
74 | 74 | ||
75 | static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb); | 75 | static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb); |
76 | static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err); | 76 | static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err); |
@@ -96,9 +96,9 @@ static void rfcomm_dev_destruct(struct tty_port *port) | |||
96 | if (dev->tty_dev) | 96 | if (dev->tty_dev) |
97 | tty_unregister_device(rfcomm_tty_driver, dev->id); | 97 | tty_unregister_device(rfcomm_tty_driver, dev->id); |
98 | 98 | ||
99 | spin_lock(&rfcomm_dev_lock); | 99 | mutex_lock(&rfcomm_dev_lock); |
100 | list_del(&dev->list); | 100 | list_del(&dev->list); |
101 | spin_unlock(&rfcomm_dev_lock); | 101 | mutex_unlock(&rfcomm_dev_lock); |
102 | 102 | ||
103 | kfree(dev); | 103 | kfree(dev); |
104 | 104 | ||
@@ -161,14 +161,14 @@ static struct rfcomm_dev *rfcomm_dev_get(int id) | |||
161 | { | 161 | { |
162 | struct rfcomm_dev *dev; | 162 | struct rfcomm_dev *dev; |
163 | 163 | ||
164 | spin_lock(&rfcomm_dev_lock); | 164 | mutex_lock(&rfcomm_dev_lock); |
165 | 165 | ||
166 | dev = __rfcomm_dev_lookup(id); | 166 | dev = __rfcomm_dev_lookup(id); |
167 | 167 | ||
168 | if (dev && !tty_port_get(&dev->port)) | 168 | if (dev && !tty_port_get(&dev->port)) |
169 | dev = NULL; | 169 | dev = NULL; |
170 | 170 | ||
171 | spin_unlock(&rfcomm_dev_lock); | 171 | mutex_unlock(&rfcomm_dev_lock); |
172 | 172 | ||
173 | return dev; | 173 | return dev; |
174 | } | 174 | } |
@@ -224,7 +224,7 @@ static struct rfcomm_dev *__rfcomm_dev_add(struct rfcomm_dev_req *req, | |||
224 | if (!dev) | 224 | if (!dev) |
225 | return ERR_PTR(-ENOMEM); | 225 | return ERR_PTR(-ENOMEM); |
226 | 226 | ||
227 | spin_lock(&rfcomm_dev_lock); | 227 | mutex_lock(&rfcomm_dev_lock); |
228 | 228 | ||
229 | if (req->dev_id < 0) { | 229 | if (req->dev_id < 0) { |
230 | dev->id = 0; | 230 | dev->id = 0; |
@@ -305,11 +305,11 @@ static struct rfcomm_dev *__rfcomm_dev_add(struct rfcomm_dev_req *req, | |||
305 | holds reference to this module. */ | 305 | holds reference to this module. */ |
306 | __module_get(THIS_MODULE); | 306 | __module_get(THIS_MODULE); |
307 | 307 | ||
308 | spin_unlock(&rfcomm_dev_lock); | 308 | mutex_unlock(&rfcomm_dev_lock); |
309 | return dev; | 309 | return dev; |
310 | 310 | ||
311 | out: | 311 | out: |
312 | spin_unlock(&rfcomm_dev_lock); | 312 | mutex_unlock(&rfcomm_dev_lock); |
313 | kfree(dev); | 313 | kfree(dev); |
314 | return ERR_PTR(err); | 314 | return ERR_PTR(err); |
315 | } | 315 | } |
@@ -524,7 +524,7 @@ static int rfcomm_get_dev_list(void __user *arg) | |||
524 | 524 | ||
525 | di = dl->dev_info; | 525 | di = dl->dev_info; |
526 | 526 | ||
527 | spin_lock(&rfcomm_dev_lock); | 527 | mutex_lock(&rfcomm_dev_lock); |
528 | 528 | ||
529 | list_for_each_entry(dev, &rfcomm_dev_list, list) { | 529 | list_for_each_entry(dev, &rfcomm_dev_list, list) { |
530 | if (!tty_port_get(&dev->port)) | 530 | if (!tty_port_get(&dev->port)) |
@@ -540,7 +540,7 @@ static int rfcomm_get_dev_list(void __user *arg) | |||
540 | break; | 540 | break; |
541 | } | 541 | } |
542 | 542 | ||
543 | spin_unlock(&rfcomm_dev_lock); | 543 | mutex_unlock(&rfcomm_dev_lock); |
544 | 544 | ||
545 | dl->dev_num = n; | 545 | dl->dev_num = n; |
546 | size = sizeof(*dl) + n * sizeof(*di); | 546 | size = sizeof(*dl) + n * sizeof(*di); |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index dfb4e1161c10..4f9662d0fd81 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -35,6 +35,33 @@ | |||
35 | 35 | ||
36 | #define AUTH_REQ_MASK 0x07 | 36 | #define AUTH_REQ_MASK 0x07 |
37 | 37 | ||
38 | #define SMP_FLAG_TK_VALID 1 | ||
39 | #define SMP_FLAG_CFM_PENDING 2 | ||
40 | #define SMP_FLAG_MITM_AUTH 3 | ||
41 | #define SMP_FLAG_COMPLETE 4 | ||
42 | #define SMP_FLAG_INITIATOR 5 | ||
43 | |||
44 | struct smp_chan { | ||
45 | struct l2cap_conn *conn; | ||
46 | u8 preq[7]; /* SMP Pairing Request */ | ||
47 | u8 prsp[7]; /* SMP Pairing Response */ | ||
48 | u8 prnd[16]; /* SMP Pairing Random (local) */ | ||
49 | u8 rrnd[16]; /* SMP Pairing Random (remote) */ | ||
50 | u8 pcnf[16]; /* SMP Pairing Confirm */ | ||
51 | u8 tk[16]; /* SMP Temporary Key */ | ||
52 | u8 enc_key_size; | ||
53 | u8 remote_key_dist; | ||
54 | bdaddr_t id_addr; | ||
55 | u8 id_addr_type; | ||
56 | u8 irk[16]; | ||
57 | struct smp_csrk *csrk; | ||
58 | struct smp_csrk *slave_csrk; | ||
59 | struct smp_ltk *ltk; | ||
60 | struct smp_ltk *slave_ltk; | ||
61 | struct smp_irk *remote_irk; | ||
62 | unsigned long flags; | ||
63 | }; | ||
64 | |||
38 | static inline void swap128(const u8 src[16], u8 dst[16]) | 65 | static inline void swap128(const u8 src[16], u8 dst[16]) |
39 | { | 66 | { |
40 | int i; | 67 | int i; |
@@ -369,7 +396,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
369 | 396 | ||
370 | /* Initialize key for JUST WORKS */ | 397 | /* Initialize key for JUST WORKS */ |
371 | memset(smp->tk, 0, sizeof(smp->tk)); | 398 | memset(smp->tk, 0, sizeof(smp->tk)); |
372 | clear_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | 399 | clear_bit(SMP_FLAG_TK_VALID, &smp->flags); |
373 | 400 | ||
374 | BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); | 401 | BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); |
375 | 402 | ||
@@ -388,19 +415,18 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
388 | method = JUST_WORKS; | 415 | method = JUST_WORKS; |
389 | 416 | ||
390 | /* Don't confirm locally initiated pairing attempts */ | 417 | /* Don't confirm locally initiated pairing attempts */ |
391 | if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, | 418 | if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) |
392 | &smp->smp_flags)) | ||
393 | method = JUST_WORKS; | 419 | method = JUST_WORKS; |
394 | 420 | ||
395 | /* If Just Works, Continue with Zero TK */ | 421 | /* If Just Works, Continue with Zero TK */ |
396 | if (method == JUST_WORKS) { | 422 | if (method == JUST_WORKS) { |
397 | set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | 423 | set_bit(SMP_FLAG_TK_VALID, &smp->flags); |
398 | return 0; | 424 | return 0; |
399 | } | 425 | } |
400 | 426 | ||
401 | /* Not Just Works/Confirm results in MITM Authentication */ | 427 | /* Not Just Works/Confirm results in MITM Authentication */ |
402 | if (method != JUST_CFM) | 428 | if (method != JUST_CFM) |
403 | set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags); | 429 | set_bit(SMP_FLAG_MITM_AUTH, &smp->flags); |
404 | 430 | ||
405 | /* If both devices have Keyoard-Display I/O, the master | 431 | /* If both devices have Keyoard-Display I/O, the master |
406 | * Confirms and the slave Enters the passkey. | 432 | * Confirms and the slave Enters the passkey. |
@@ -419,7 +445,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
419 | passkey %= 1000000; | 445 | passkey %= 1000000; |
420 | put_unaligned_le32(passkey, smp->tk); | 446 | put_unaligned_le32(passkey, smp->tk); |
421 | BT_DBG("PassKey: %d", passkey); | 447 | BT_DBG("PassKey: %d", passkey); |
422 | set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | 448 | set_bit(SMP_FLAG_TK_VALID, &smp->flags); |
423 | } | 449 | } |
424 | 450 | ||
425 | hci_dev_lock(hcon->hdev); | 451 | hci_dev_lock(hcon->hdev); |
@@ -441,15 +467,13 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | |||
441 | return ret; | 467 | return ret; |
442 | } | 468 | } |
443 | 469 | ||
444 | static void confirm_work(struct work_struct *work) | 470 | static u8 smp_confirm(struct smp_chan *smp) |
445 | { | 471 | { |
446 | struct smp_chan *smp = container_of(work, struct smp_chan, confirm); | ||
447 | struct l2cap_conn *conn = smp->conn; | 472 | struct l2cap_conn *conn = smp->conn; |
448 | struct hci_dev *hdev = conn->hcon->hdev; | 473 | struct hci_dev *hdev = conn->hcon->hdev; |
449 | struct crypto_blkcipher *tfm = hdev->tfm_aes; | 474 | struct crypto_blkcipher *tfm = hdev->tfm_aes; |
450 | struct smp_cmd_pairing_confirm cp; | 475 | struct smp_cmd_pairing_confirm cp; |
451 | int ret; | 476 | int ret; |
452 | u8 reason; | ||
453 | 477 | ||
454 | BT_DBG("conn %p", conn); | 478 | BT_DBG("conn %p", conn); |
455 | 479 | ||
@@ -463,35 +487,27 @@ static void confirm_work(struct work_struct *work) | |||
463 | 487 | ||
464 | hci_dev_unlock(hdev); | 488 | hci_dev_unlock(hdev); |
465 | 489 | ||
466 | if (ret) { | 490 | if (ret) |
467 | reason = SMP_UNSPECIFIED; | 491 | return SMP_UNSPECIFIED; |
468 | goto error; | ||
469 | } | ||
470 | 492 | ||
471 | clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); | 493 | clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags); |
472 | 494 | ||
473 | smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); | 495 | smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); |
474 | 496 | ||
475 | return; | 497 | return 0; |
476 | |||
477 | error: | ||
478 | smp_failure(conn, reason); | ||
479 | } | 498 | } |
480 | 499 | ||
481 | static void random_work(struct work_struct *work) | 500 | static u8 smp_random(struct smp_chan *smp) |
482 | { | 501 | { |
483 | struct smp_chan *smp = container_of(work, struct smp_chan, random); | ||
484 | struct l2cap_conn *conn = smp->conn; | 502 | struct l2cap_conn *conn = smp->conn; |
485 | struct hci_conn *hcon = conn->hcon; | 503 | struct hci_conn *hcon = conn->hcon; |
486 | struct hci_dev *hdev = hcon->hdev; | 504 | struct hci_dev *hdev = hcon->hdev; |
487 | struct crypto_blkcipher *tfm = hdev->tfm_aes; | 505 | struct crypto_blkcipher *tfm = hdev->tfm_aes; |
488 | u8 reason, confirm[16]; | 506 | u8 confirm[16]; |
489 | int ret; | 507 | int ret; |
490 | 508 | ||
491 | if (IS_ERR_OR_NULL(tfm)) { | 509 | if (IS_ERR_OR_NULL(tfm)) |
492 | reason = SMP_UNSPECIFIED; | 510 | return SMP_UNSPECIFIED; |
493 | goto error; | ||
494 | } | ||
495 | 511 | ||
496 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); | 512 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); |
497 | 513 | ||
@@ -504,15 +520,12 @@ static void random_work(struct work_struct *work) | |||
504 | 520 | ||
505 | hci_dev_unlock(hdev); | 521 | hci_dev_unlock(hdev); |
506 | 522 | ||
507 | if (ret) { | 523 | if (ret) |
508 | reason = SMP_UNSPECIFIED; | 524 | return SMP_UNSPECIFIED; |
509 | goto error; | ||
510 | } | ||
511 | 525 | ||
512 | if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) { | 526 | if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) { |
513 | BT_ERR("Pairing failed (confirmation values mismatch)"); | 527 | BT_ERR("Pairing failed (confirmation values mismatch)"); |
514 | reason = SMP_CONFIRM_FAILED; | 528 | return SMP_CONFIRM_FAILED; |
515 | goto error; | ||
516 | } | 529 | } |
517 | 530 | ||
518 | if (hcon->out) { | 531 | if (hcon->out) { |
@@ -525,10 +538,8 @@ static void random_work(struct work_struct *work) | |||
525 | memset(stk + smp->enc_key_size, 0, | 538 | memset(stk + smp->enc_key_size, 0, |
526 | SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); | 539 | SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); |
527 | 540 | ||
528 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) { | 541 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) |
529 | reason = SMP_UNSPECIFIED; | 542 | return SMP_UNSPECIFIED; |
530 | goto error; | ||
531 | } | ||
532 | 543 | ||
533 | hci_le_start_enc(hcon, ediv, rand, stk); | 544 | hci_le_start_enc(hcon, ediv, rand, stk); |
534 | hcon->enc_key_size = smp->enc_key_size; | 545 | hcon->enc_key_size = smp->enc_key_size; |
@@ -550,10 +561,7 @@ static void random_work(struct work_struct *work) | |||
550 | ediv, rand); | 561 | ediv, rand); |
551 | } | 562 | } |
552 | 563 | ||
553 | return; | 564 | return 0; |
554 | |||
555 | error: | ||
556 | smp_failure(conn, reason); | ||
557 | } | 565 | } |
558 | 566 | ||
559 | static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | 567 | static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) |
@@ -564,9 +572,6 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | |||
564 | if (!smp) | 572 | if (!smp) |
565 | return NULL; | 573 | return NULL; |
566 | 574 | ||
567 | INIT_WORK(&smp->confirm, confirm_work); | ||
568 | INIT_WORK(&smp->random, random_work); | ||
569 | |||
570 | smp->conn = conn; | 575 | smp->conn = conn; |
571 | conn->smp_chan = smp; | 576 | conn->smp_chan = smp; |
572 | conn->hcon->smp_conn = conn; | 577 | conn->hcon->smp_conn = conn; |
@@ -583,7 +588,7 @@ void smp_chan_destroy(struct l2cap_conn *conn) | |||
583 | 588 | ||
584 | BUG_ON(!smp); | 589 | BUG_ON(!smp); |
585 | 590 | ||
586 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); | 591 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); |
587 | mgmt_smp_complete(conn->hcon, complete); | 592 | mgmt_smp_complete(conn->hcon, complete); |
588 | 593 | ||
589 | kfree(smp->csrk); | 594 | kfree(smp->csrk); |
@@ -634,7 +639,7 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | |||
634 | put_unaligned_le32(value, smp->tk); | 639 | put_unaligned_le32(value, smp->tk); |
635 | /* Fall Through */ | 640 | /* Fall Through */ |
636 | case MGMT_OP_USER_CONFIRM_REPLY: | 641 | case MGMT_OP_USER_CONFIRM_REPLY: |
637 | set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | 642 | set_bit(SMP_FLAG_TK_VALID, &smp->flags); |
638 | break; | 643 | break; |
639 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: | 644 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: |
640 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: | 645 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: |
@@ -646,8 +651,11 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | |||
646 | } | 651 | } |
647 | 652 | ||
648 | /* If it is our turn to send Pairing Confirm, do so now */ | 653 | /* If it is our turn to send Pairing Confirm, do so now */ |
649 | if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags)) | 654 | if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { |
650 | queue_work(hcon->hdev->workqueue, &smp->confirm); | 655 | u8 rsp = smp_confirm(smp); |
656 | if (rsp) | ||
657 | smp_failure(conn, rsp); | ||
658 | } | ||
651 | 659 | ||
652 | return 0; | 660 | return 0; |
653 | } | 661 | } |
@@ -656,14 +664,13 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
656 | { | 664 | { |
657 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; | 665 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; |
658 | struct smp_chan *smp; | 666 | struct smp_chan *smp; |
659 | u8 key_size; | 667 | u8 key_size, auth; |
660 | u8 auth = SMP_AUTH_NONE; | ||
661 | int ret; | 668 | int ret; |
662 | 669 | ||
663 | BT_DBG("conn %p", conn); | 670 | BT_DBG("conn %p", conn); |
664 | 671 | ||
665 | if (skb->len < sizeof(*req)) | 672 | if (skb->len < sizeof(*req)) |
666 | return SMP_UNSPECIFIED; | 673 | return SMP_INVALID_PARAMS; |
667 | 674 | ||
668 | if (conn->hcon->link_mode & HCI_LM_MASTER) | 675 | if (conn->hcon->link_mode & HCI_LM_MASTER) |
669 | return SMP_CMD_NOTSUPP; | 676 | return SMP_CMD_NOTSUPP; |
@@ -681,8 +688,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
681 | skb_pull(skb, sizeof(*req)); | 688 | skb_pull(skb, sizeof(*req)); |
682 | 689 | ||
683 | /* We didn't start the pairing, so match remote */ | 690 | /* We didn't start the pairing, so match remote */ |
684 | if (req->auth_req & SMP_AUTH_BONDING) | 691 | auth = req->auth_req; |
685 | auth = req->auth_req; | ||
686 | 692 | ||
687 | conn->hcon->pending_sec_level = authreq_to_seclevel(auth); | 693 | conn->hcon->pending_sec_level = authreq_to_seclevel(auth); |
688 | 694 | ||
@@ -704,7 +710,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
704 | if (ret) | 710 | if (ret) |
705 | return SMP_UNSPECIFIED; | 711 | return SMP_UNSPECIFIED; |
706 | 712 | ||
707 | clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags); | 713 | clear_bit(SMP_FLAG_INITIATOR, &smp->flags); |
708 | 714 | ||
709 | return 0; | 715 | return 0; |
710 | } | 716 | } |
@@ -713,14 +719,13 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
713 | { | 719 | { |
714 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; | 720 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; |
715 | struct smp_chan *smp = conn->smp_chan; | 721 | struct smp_chan *smp = conn->smp_chan; |
716 | struct hci_dev *hdev = conn->hcon->hdev; | ||
717 | u8 key_size, auth = SMP_AUTH_NONE; | 722 | u8 key_size, auth = SMP_AUTH_NONE; |
718 | int ret; | 723 | int ret; |
719 | 724 | ||
720 | BT_DBG("conn %p", conn); | 725 | BT_DBG("conn %p", conn); |
721 | 726 | ||
722 | if (skb->len < sizeof(*rsp)) | 727 | if (skb->len < sizeof(*rsp)) |
723 | return SMP_UNSPECIFIED; | 728 | return SMP_INVALID_PARAMS; |
724 | 729 | ||
725 | if (!(conn->hcon->link_mode & HCI_LM_MASTER)) | 730 | if (!(conn->hcon->link_mode & HCI_LM_MASTER)) |
726 | return SMP_CMD_NOTSUPP; | 731 | return SMP_CMD_NOTSUPP; |
@@ -753,11 +758,11 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
753 | if (ret) | 758 | if (ret) |
754 | return SMP_UNSPECIFIED; | 759 | return SMP_UNSPECIFIED; |
755 | 760 | ||
756 | set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); | 761 | set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); |
757 | 762 | ||
758 | /* Can't compose response until we have been confirmed */ | 763 | /* Can't compose response until we have been confirmed */ |
759 | if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) | 764 | if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) |
760 | queue_work(hdev->workqueue, &smp->confirm); | 765 | return smp_confirm(smp); |
761 | 766 | ||
762 | return 0; | 767 | return 0; |
763 | } | 768 | } |
@@ -765,12 +770,11 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
765 | static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | 770 | static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) |
766 | { | 771 | { |
767 | struct smp_chan *smp = conn->smp_chan; | 772 | struct smp_chan *smp = conn->smp_chan; |
768 | struct hci_dev *hdev = conn->hcon->hdev; | ||
769 | 773 | ||
770 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); | 774 | BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); |
771 | 775 | ||
772 | if (skb->len < sizeof(smp->pcnf)) | 776 | if (skb->len < sizeof(smp->pcnf)) |
773 | return SMP_UNSPECIFIED; | 777 | return SMP_INVALID_PARAMS; |
774 | 778 | ||
775 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); | 779 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); |
776 | skb_pull(skb, sizeof(smp->pcnf)); | 780 | skb_pull(skb, sizeof(smp->pcnf)); |
@@ -778,10 +782,10 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | |||
778 | if (conn->hcon->out) | 782 | if (conn->hcon->out) |
779 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), | 783 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), |
780 | smp->prnd); | 784 | smp->prnd); |
781 | else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) | 785 | else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) |
782 | queue_work(hdev->workqueue, &smp->confirm); | 786 | return smp_confirm(smp); |
783 | else | 787 | else |
784 | set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); | 788 | set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); |
785 | 789 | ||
786 | return 0; | 790 | return 0; |
787 | } | 791 | } |
@@ -789,19 +793,16 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | |||
789 | static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) | 793 | static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) |
790 | { | 794 | { |
791 | struct smp_chan *smp = conn->smp_chan; | 795 | struct smp_chan *smp = conn->smp_chan; |
792 | struct hci_dev *hdev = conn->hcon->hdev; | ||
793 | 796 | ||
794 | BT_DBG("conn %p", conn); | 797 | BT_DBG("conn %p", conn); |
795 | 798 | ||
796 | if (skb->len < sizeof(smp->rrnd)) | 799 | if (skb->len < sizeof(smp->rrnd)) |
797 | return SMP_UNSPECIFIED; | 800 | return SMP_INVALID_PARAMS; |
798 | 801 | ||
799 | memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); | 802 | memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); |
800 | skb_pull(skb, sizeof(smp->rrnd)); | 803 | skb_pull(skb, sizeof(smp->rrnd)); |
801 | 804 | ||
802 | queue_work(hdev->workqueue, &smp->random); | 805 | return smp_random(smp); |
803 | |||
804 | return 0; | ||
805 | } | 806 | } |
806 | 807 | ||
807 | static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) | 808 | static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) |
@@ -836,7 +837,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
836 | BT_DBG("conn %p", conn); | 837 | BT_DBG("conn %p", conn); |
837 | 838 | ||
838 | if (skb->len < sizeof(*rp)) | 839 | if (skb->len < sizeof(*rp)) |
839 | return SMP_UNSPECIFIED; | 840 | return SMP_INVALID_PARAMS; |
840 | 841 | ||
841 | if (!(conn->hcon->link_mode & HCI_LM_MASTER)) | 842 | if (!(conn->hcon->link_mode & HCI_LM_MASTER)) |
842 | return SMP_CMD_NOTSUPP; | 843 | return SMP_CMD_NOTSUPP; |
@@ -861,7 +862,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
861 | 862 | ||
862 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); | 863 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); |
863 | 864 | ||
864 | clear_bit(SMP_FLAG_INITIATOR, &smp->smp_flags); | 865 | clear_bit(SMP_FLAG_INITIATOR, &smp->flags); |
865 | 866 | ||
866 | return 0; | 867 | return 0; |
867 | } | 868 | } |
@@ -928,7 +929,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
928 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); | 929 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); |
929 | } | 930 | } |
930 | 931 | ||
931 | set_bit(SMP_FLAG_INITIATOR, &smp->smp_flags); | 932 | set_bit(SMP_FLAG_INITIATOR, &smp->flags); |
932 | 933 | ||
933 | done: | 934 | done: |
934 | hcon->pending_sec_level = sec_level; | 935 | hcon->pending_sec_level = sec_level; |
@@ -944,7 +945,7 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
944 | BT_DBG("conn %p", conn); | 945 | BT_DBG("conn %p", conn); |
945 | 946 | ||
946 | if (skb->len < sizeof(*rp)) | 947 | if (skb->len < sizeof(*rp)) |
947 | return SMP_UNSPECIFIED; | 948 | return SMP_INVALID_PARAMS; |
948 | 949 | ||
949 | /* Ignore this PDU if it wasn't requested */ | 950 | /* Ignore this PDU if it wasn't requested */ |
950 | if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) | 951 | if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) |
@@ -969,7 +970,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | |||
969 | BT_DBG("conn %p", conn); | 970 | BT_DBG("conn %p", conn); |
970 | 971 | ||
971 | if (skb->len < sizeof(*rp)) | 972 | if (skb->len < sizeof(*rp)) |
972 | return SMP_UNSPECIFIED; | 973 | return SMP_INVALID_PARAMS; |
973 | 974 | ||
974 | /* Ignore this PDU if it wasn't requested */ | 975 | /* Ignore this PDU if it wasn't requested */ |
975 | if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) | 976 | if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) |
@@ -1001,7 +1002,7 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1001 | BT_DBG(""); | 1002 | BT_DBG(""); |
1002 | 1003 | ||
1003 | if (skb->len < sizeof(*info)) | 1004 | if (skb->len < sizeof(*info)) |
1004 | return SMP_UNSPECIFIED; | 1005 | return SMP_INVALID_PARAMS; |
1005 | 1006 | ||
1006 | /* Ignore this PDU if it wasn't requested */ | 1007 | /* Ignore this PDU if it wasn't requested */ |
1007 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) | 1008 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) |
@@ -1025,7 +1026,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, | |||
1025 | BT_DBG(""); | 1026 | BT_DBG(""); |
1026 | 1027 | ||
1027 | if (skb->len < sizeof(*info)) | 1028 | if (skb->len < sizeof(*info)) |
1028 | return SMP_UNSPECIFIED; | 1029 | return SMP_INVALID_PARAMS; |
1029 | 1030 | ||
1030 | /* Ignore this PDU if it wasn't requested */ | 1031 | /* Ignore this PDU if it wasn't requested */ |
1031 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) | 1032 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) |
@@ -1075,7 +1076,7 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1075 | BT_DBG("conn %p", conn); | 1076 | BT_DBG("conn %p", conn); |
1076 | 1077 | ||
1077 | if (skb->len < sizeof(*rp)) | 1078 | if (skb->len < sizeof(*rp)) |
1078 | return SMP_UNSPECIFIED; | 1079 | return SMP_INVALID_PARAMS; |
1079 | 1080 | ||
1080 | /* Ignore this PDU if it wasn't requested */ | 1081 | /* Ignore this PDU if it wasn't requested */ |
1081 | if (!(smp->remote_key_dist & SMP_DIST_SIGN)) | 1082 | if (!(smp->remote_key_dist & SMP_DIST_SIGN)) |
@@ -1358,7 +1359,7 @@ int smp_distribute_keys(struct l2cap_conn *conn) | |||
1358 | 1359 | ||
1359 | clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); | 1360 | clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); |
1360 | cancel_delayed_work_sync(&conn->security_timer); | 1361 | cancel_delayed_work_sync(&conn->security_timer); |
1361 | set_bit(SMP_FLAG_COMPLETE, &smp->smp_flags); | 1362 | set_bit(SMP_FLAG_COMPLETE, &smp->flags); |
1362 | smp_notify_keys(conn); | 1363 | smp_notify_keys(conn); |
1363 | 1364 | ||
1364 | smp_chan_destroy(conn); | 1365 | smp_chan_destroy(conn); |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 1277147a9150..5a8dc36460a1 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -111,39 +111,11 @@ struct smp_cmd_security_req { | |||
111 | #define SMP_CMD_NOTSUPP 0x07 | 111 | #define SMP_CMD_NOTSUPP 0x07 |
112 | #define SMP_UNSPECIFIED 0x08 | 112 | #define SMP_UNSPECIFIED 0x08 |
113 | #define SMP_REPEATED_ATTEMPTS 0x09 | 113 | #define SMP_REPEATED_ATTEMPTS 0x09 |
114 | #define SMP_INVALID_PARAMS 0x0a | ||
114 | 115 | ||
115 | #define SMP_MIN_ENC_KEY_SIZE 7 | 116 | #define SMP_MIN_ENC_KEY_SIZE 7 |
116 | #define SMP_MAX_ENC_KEY_SIZE 16 | 117 | #define SMP_MAX_ENC_KEY_SIZE 16 |
117 | 118 | ||
118 | #define SMP_FLAG_TK_VALID 1 | ||
119 | #define SMP_FLAG_CFM_PENDING 2 | ||
120 | #define SMP_FLAG_MITM_AUTH 3 | ||
121 | #define SMP_FLAG_COMPLETE 4 | ||
122 | #define SMP_FLAG_INITIATOR 5 | ||
123 | |||
124 | struct smp_chan { | ||
125 | struct l2cap_conn *conn; | ||
126 | u8 preq[7]; /* SMP Pairing Request */ | ||
127 | u8 prsp[7]; /* SMP Pairing Response */ | ||
128 | u8 prnd[16]; /* SMP Pairing Random (local) */ | ||
129 | u8 rrnd[16]; /* SMP Pairing Random (remote) */ | ||
130 | u8 pcnf[16]; /* SMP Pairing Confirm */ | ||
131 | u8 tk[16]; /* SMP Temporary Key */ | ||
132 | u8 enc_key_size; | ||
133 | u8 remote_key_dist; | ||
134 | bdaddr_t id_addr; | ||
135 | u8 id_addr_type; | ||
136 | u8 irk[16]; | ||
137 | struct smp_csrk *csrk; | ||
138 | struct smp_csrk *slave_csrk; | ||
139 | struct smp_ltk *ltk; | ||
140 | struct smp_ltk *slave_ltk; | ||
141 | struct smp_irk *remote_irk; | ||
142 | unsigned long smp_flags; | ||
143 | struct work_struct confirm; | ||
144 | struct work_struct random; | ||
145 | }; | ||
146 | |||
147 | /* SMP Commands */ | 119 | /* SMP Commands */ |
148 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); | 120 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); |
149 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); | 121 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); |