aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-01-30 15:39:54 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-30 15:39:54 -0500
commitde8d7a53807c8d2bb04b59ff3a0daa225e81a775 (patch)
treefcd911aff52d3192af95f1e2aee7ecfd4187d5ec /net/bluetooth/mgmt.c
parent97c7952792018589640ecb3e62e1ab8f06005546 (diff)
parentc331997b6c9ad7f4b8075e6e60d3caa6e36f5938 (diff)
Merge remote-tracking branch 'wireless-next/master' into iwlwifi-next
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c270
1 files changed, 192 insertions, 78 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f559b966279c..e7f944f52ff2 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -777,14 +777,19 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
777 777
778 BT_DBG("request for %s", hdev->name); 778 BT_DBG("request for %s", hdev->name);
779 779
780 if (cp->val != 0x00 && cp->val != 0x01)
781 return cmd_status(sk, hdev->id, MGMT_OP_SET_POWERED,
782 MGMT_STATUS_INVALID_PARAMS);
783
780 hci_dev_lock(hdev); 784 hci_dev_lock(hdev);
781 785
782 if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) { 786 if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
783 cancel_delayed_work(&hdev->power_off); 787 cancel_delayed_work(&hdev->power_off);
784 788
785 if (cp->val) { 789 if (cp->val) {
786 err = send_settings_rsp(sk, MGMT_OP_SET_POWERED, hdev); 790 mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev,
787 mgmt_powered(hdev, 1); 791 data, len);
792 err = mgmt_powered(hdev, 1);
788 goto failed; 793 goto failed;
789 } 794 }
790 } 795 }
@@ -807,9 +812,9 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
807 } 812 }
808 813
809 if (cp->val) 814 if (cp->val)
810 schedule_work(&hdev->power_on); 815 queue_work(hdev->req_workqueue, &hdev->power_on);
811 else 816 else
812 schedule_work(&hdev->power_off.work); 817 queue_work(hdev->req_workqueue, &hdev->power_off.work);
813 818
814 err = 0; 819 err = 0;
815 820
@@ -872,6 +877,10 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
872 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, 877 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
873 MGMT_STATUS_NOT_SUPPORTED); 878 MGMT_STATUS_NOT_SUPPORTED);
874 879
880 if (cp->val != 0x00 && cp->val != 0x01)
881 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
882 MGMT_STATUS_INVALID_PARAMS);
883
875 timeout = __le16_to_cpu(cp->timeout); 884 timeout = __le16_to_cpu(cp->timeout);
876 if (!cp->val && timeout > 0) 885 if (!cp->val && timeout > 0)
877 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, 886 return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE,
@@ -971,6 +980,10 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
971 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, 980 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
972 MGMT_STATUS_NOT_SUPPORTED); 981 MGMT_STATUS_NOT_SUPPORTED);
973 982
983 if (cp->val != 0x00 && cp->val != 0x01)
984 return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
985 MGMT_STATUS_INVALID_PARAMS);
986
974 hci_dev_lock(hdev); 987 hci_dev_lock(hdev);
975 988
976 if (!hdev_is_powered(hdev)) { 989 if (!hdev_is_powered(hdev)) {
@@ -1041,6 +1054,10 @@ static int set_pairable(struct sock *sk, struct hci_dev *hdev, void *data,
1041 1054
1042 BT_DBG("request for %s", hdev->name); 1055 BT_DBG("request for %s", hdev->name);
1043 1056
1057 if (cp->val != 0x00 && cp->val != 0x01)
1058 return cmd_status(sk, hdev->id, MGMT_OP_SET_PAIRABLE,
1059 MGMT_STATUS_INVALID_PARAMS);
1060
1044 hci_dev_lock(hdev); 1061 hci_dev_lock(hdev);
1045 1062
1046 if (cp->val) 1063 if (cp->val)
@@ -1073,6 +1090,10 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data,
1073 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, 1090 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
1074 MGMT_STATUS_NOT_SUPPORTED); 1091 MGMT_STATUS_NOT_SUPPORTED);
1075 1092
1093 if (cp->val != 0x00 && cp->val != 0x01)
1094 return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY,
1095 MGMT_STATUS_INVALID_PARAMS);
1096
1076 hci_dev_lock(hdev); 1097 hci_dev_lock(hdev);
1077 1098
1078 if (!hdev_is_powered(hdev)) { 1099 if (!hdev_is_powered(hdev)) {
@@ -1133,13 +1154,15 @@ static int set_ssp(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1133 1154
1134 BT_DBG("request for %s", hdev->name); 1155 BT_DBG("request for %s", hdev->name);
1135 1156
1136 hci_dev_lock(hdev); 1157 if (!lmp_ssp_capable(hdev))
1158 return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
1159 MGMT_STATUS_NOT_SUPPORTED);
1137 1160
1138 if (!lmp_ssp_capable(hdev)) { 1161 if (cp->val != 0x00 && cp->val != 0x01)
1139 err = cmd_status(sk, hdev->id, MGMT_OP_SET_SSP, 1162 return cmd_status(sk, hdev->id, MGMT_OP_SET_SSP,
1140 MGMT_STATUS_NOT_SUPPORTED); 1163 MGMT_STATUS_INVALID_PARAMS);
1141 goto failed; 1164
1142 } 1165 hci_dev_lock(hdev);
1143 1166
1144 val = !!cp->val; 1167 val = !!cp->val;
1145 1168
@@ -1199,6 +1222,10 @@ static int set_hs(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1199 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS, 1222 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
1200 MGMT_STATUS_NOT_SUPPORTED); 1223 MGMT_STATUS_NOT_SUPPORTED);
1201 1224
1225 if (cp->val != 0x00 && cp->val != 0x01)
1226 return cmd_status(sk, hdev->id, MGMT_OP_SET_HS,
1227 MGMT_STATUS_INVALID_PARAMS);
1228
1202 if (cp->val) 1229 if (cp->val)
1203 set_bit(HCI_HS_ENABLED, &hdev->dev_flags); 1230 set_bit(HCI_HS_ENABLED, &hdev->dev_flags);
1204 else 1231 else
@@ -1217,13 +1244,15 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1217 1244
1218 BT_DBG("request for %s", hdev->name); 1245 BT_DBG("request for %s", hdev->name);
1219 1246
1220 hci_dev_lock(hdev); 1247 if (!lmp_le_capable(hdev))
1248 return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
1249 MGMT_STATUS_NOT_SUPPORTED);
1221 1250
1222 if (!lmp_le_capable(hdev)) { 1251 if (cp->val != 0x00 && cp->val != 0x01)
1223 err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE, 1252 return cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
1224 MGMT_STATUS_NOT_SUPPORTED); 1253 MGMT_STATUS_INVALID_PARAMS);
1225 goto unlock; 1254
1226 } 1255 hci_dev_lock(hdev);
1227 1256
1228 val = !!cp->val; 1257 val = !!cp->val;
1229 enabled = lmp_host_le_capable(hdev); 1258 enabled = lmp_host_le_capable(hdev);
@@ -1332,7 +1361,8 @@ static bool enable_service_cache(struct hci_dev *hdev)
1332 return false; 1361 return false;
1333 1362
1334 if (!test_and_set_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) { 1363 if (!test_and_set_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
1335 schedule_delayed_work(&hdev->service_cache, CACHE_TIMEOUT); 1364 queue_delayed_work(hdev->workqueue, &hdev->service_cache,
1365 CACHE_TIMEOUT);
1336 return true; 1366 return true;
1337 } 1367 }
1338 1368
@@ -1422,13 +1452,19 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
1422 1452
1423 BT_DBG("request for %s", hdev->name); 1453 BT_DBG("request for %s", hdev->name);
1424 1454
1425 hci_dev_lock(hdev); 1455 if (!lmp_bredr_capable(hdev))
1456 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1457 MGMT_STATUS_NOT_SUPPORTED);
1426 1458
1427 if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) { 1459 if (test_bit(HCI_PENDING_CLASS, &hdev->dev_flags))
1428 err = cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 1460 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1429 MGMT_STATUS_BUSY); 1461 MGMT_STATUS_BUSY);
1430 goto unlock; 1462
1431 } 1463 if ((cp->minor & 0x03) != 0 || (cp->major & 0xe0) != 0)
1464 return cmd_status(sk, hdev->id, MGMT_OP_SET_DEV_CLASS,
1465 MGMT_STATUS_INVALID_PARAMS);
1466
1467 hci_dev_lock(hdev);
1432 1468
1433 hdev->major_class = cp->major; 1469 hdev->major_class = cp->major;
1434 hdev->minor_class = cp->minor; 1470 hdev->minor_class = cp->minor;
@@ -1483,9 +1519,21 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data,
1483 MGMT_STATUS_INVALID_PARAMS); 1519 MGMT_STATUS_INVALID_PARAMS);
1484 } 1520 }
1485 1521
1522 if (cp->debug_keys != 0x00 && cp->debug_keys != 0x01)
1523 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
1524 MGMT_STATUS_INVALID_PARAMS);
1525
1486 BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys, 1526 BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys,
1487 key_count); 1527 key_count);
1488 1528
1529 for (i = 0; i < key_count; i++) {
1530 struct mgmt_link_key_info *key = &cp->keys[i];
1531
1532 if (key->addr.type != BDADDR_BREDR)
1533 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS,
1534 MGMT_STATUS_INVALID_PARAMS);
1535 }
1536
1489 hci_dev_lock(hdev); 1537 hci_dev_lock(hdev);
1490 1538
1491 hci_link_keys_clear(hdev); 1539 hci_link_keys_clear(hdev);
@@ -1533,12 +1581,22 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data,
1533 struct hci_conn *conn; 1581 struct hci_conn *conn;
1534 int err; 1582 int err;
1535 1583
1536 hci_dev_lock(hdev);
1537
1538 memset(&rp, 0, sizeof(rp)); 1584 memset(&rp, 0, sizeof(rp));
1539 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr); 1585 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1540 rp.addr.type = cp->addr.type; 1586 rp.addr.type = cp->addr.type;
1541 1587
1588 if (!bdaddr_type_is_valid(cp->addr.type))
1589 return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
1590 MGMT_STATUS_INVALID_PARAMS,
1591 &rp, sizeof(rp));
1592
1593 if (cp->disconnect != 0x00 && cp->disconnect != 0x01)
1594 return cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
1595 MGMT_STATUS_INVALID_PARAMS,
1596 &rp, sizeof(rp));
1597
1598 hci_dev_lock(hdev);
1599
1542 if (!hdev_is_powered(hdev)) { 1600 if (!hdev_is_powered(hdev)) {
1543 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE, 1601 err = cmd_complete(sk, hdev->id, MGMT_OP_UNPAIR_DEVICE,
1544 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp)); 1602 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
@@ -1596,6 +1654,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1596 u16 len) 1654 u16 len)
1597{ 1655{
1598 struct mgmt_cp_disconnect *cp = data; 1656 struct mgmt_cp_disconnect *cp = data;
1657 struct mgmt_rp_disconnect rp;
1599 struct hci_cp_disconnect dc; 1658 struct hci_cp_disconnect dc;
1600 struct pending_cmd *cmd; 1659 struct pending_cmd *cmd;
1601 struct hci_conn *conn; 1660 struct hci_conn *conn;
@@ -1603,17 +1662,26 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1603 1662
1604 BT_DBG(""); 1663 BT_DBG("");
1605 1664
1665 memset(&rp, 0, sizeof(rp));
1666 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1667 rp.addr.type = cp->addr.type;
1668
1669 if (!bdaddr_type_is_valid(cp->addr.type))
1670 return cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1671 MGMT_STATUS_INVALID_PARAMS,
1672 &rp, sizeof(rp));
1673
1606 hci_dev_lock(hdev); 1674 hci_dev_lock(hdev);
1607 1675
1608 if (!test_bit(HCI_UP, &hdev->flags)) { 1676 if (!test_bit(HCI_UP, &hdev->flags)) {
1609 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1677 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1610 MGMT_STATUS_NOT_POWERED); 1678 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
1611 goto failed; 1679 goto failed;
1612 } 1680 }
1613 1681
1614 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) { 1682 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) {
1615 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1683 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1616 MGMT_STATUS_BUSY); 1684 MGMT_STATUS_BUSY, &rp, sizeof(rp));
1617 goto failed; 1685 goto failed;
1618 } 1686 }
1619 1687
@@ -1624,8 +1692,8 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data,
1624 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); 1692 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
1625 1693
1626 if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) { 1694 if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) {
1627 err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, 1695 err = cmd_complete(sk, hdev->id, MGMT_OP_DISCONNECT,
1628 MGMT_STATUS_NOT_CONNECTED); 1696 MGMT_STATUS_NOT_CONNECTED, &rp, sizeof(rp));
1629 goto failed; 1697 goto failed;
1630 } 1698 }
1631 1699
@@ -1903,11 +1971,20 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
1903 1971
1904 BT_DBG(""); 1972 BT_DBG("");
1905 1973
1974 memset(&rp, 0, sizeof(rp));
1975 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1976 rp.addr.type = cp->addr.type;
1977
1978 if (!bdaddr_type_is_valid(cp->addr.type))
1979 return cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
1980 MGMT_STATUS_INVALID_PARAMS,
1981 &rp, sizeof(rp));
1982
1906 hci_dev_lock(hdev); 1983 hci_dev_lock(hdev);
1907 1984
1908 if (!hdev_is_powered(hdev)) { 1985 if (!hdev_is_powered(hdev)) {
1909 err = cmd_status(sk, hdev->id, MGMT_OP_PAIR_DEVICE, 1986 err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE,
1910 MGMT_STATUS_NOT_POWERED); 1987 MGMT_STATUS_NOT_POWERED, &rp, sizeof(rp));
1911 goto unlock; 1988 goto unlock;
1912 } 1989 }
1913 1990
@@ -1924,10 +2001,6 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
1924 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr, 2001 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr,
1925 cp->addr.type, sec_level, auth_type); 2002 cp->addr.type, sec_level, auth_type);
1926 2003
1927 memset(&rp, 0, sizeof(rp));
1928 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1929 rp.addr.type = cp->addr.type;
1930
1931 if (IS_ERR(conn)) { 2004 if (IS_ERR(conn)) {
1932 int status; 2005 int status;
1933 2006
@@ -2254,24 +2327,16 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
2254 2327
2255 hci_dev_lock(hdev); 2328 hci_dev_lock(hdev);
2256 2329
2257 if (!hdev_is_powered(hdev)) {
2258 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA,
2259 MGMT_STATUS_NOT_POWERED, &cp->addr,
2260 sizeof(cp->addr));
2261 goto unlock;
2262 }
2263
2264 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash, 2330 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash,
2265 cp->randomizer); 2331 cp->randomizer);
2266 if (err < 0) 2332 if (err < 0)
2267 status = MGMT_STATUS_FAILED; 2333 status = MGMT_STATUS_FAILED;
2268 else 2334 else
2269 status = 0; 2335 status = MGMT_STATUS_SUCCESS;
2270 2336
2271 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status, 2337 err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_REMOTE_OOB_DATA, status,
2272 &cp->addr, sizeof(cp->addr)); 2338 &cp->addr, sizeof(cp->addr));
2273 2339
2274unlock:
2275 hci_dev_unlock(hdev); 2340 hci_dev_unlock(hdev);
2276 return err; 2341 return err;
2277} 2342}
@@ -2287,24 +2352,15 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev,
2287 2352
2288 hci_dev_lock(hdev); 2353 hci_dev_lock(hdev);
2289 2354
2290 if (!hdev_is_powered(hdev)) {
2291 err = cmd_complete(sk, hdev->id,
2292 MGMT_OP_REMOVE_REMOTE_OOB_DATA,
2293 MGMT_STATUS_NOT_POWERED, &cp->addr,
2294 sizeof(cp->addr));
2295 goto unlock;
2296 }
2297
2298 err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr); 2355 err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr);
2299 if (err < 0) 2356 if (err < 0)
2300 status = MGMT_STATUS_INVALID_PARAMS; 2357 status = MGMT_STATUS_INVALID_PARAMS;
2301 else 2358 else
2302 status = 0; 2359 status = MGMT_STATUS_SUCCESS;
2303 2360
2304 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA, 2361 err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
2305 status, &cp->addr, sizeof(cp->addr)); 2362 status, &cp->addr, sizeof(cp->addr));
2306 2363
2307unlock:
2308 hci_dev_unlock(hdev); 2364 hci_dev_unlock(hdev);
2309 return err; 2365 return err;
2310} 2366}
@@ -2365,31 +2421,45 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
2365 2421
2366 switch (hdev->discovery.type) { 2422 switch (hdev->discovery.type) {
2367 case DISCOV_TYPE_BREDR: 2423 case DISCOV_TYPE_BREDR:
2368 if (lmp_bredr_capable(hdev)) 2424 if (!lmp_bredr_capable(hdev)) {
2369 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR); 2425 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2370 else 2426 MGMT_STATUS_NOT_SUPPORTED);
2371 err = -ENOTSUPP; 2427 mgmt_pending_remove(cmd);
2428 goto failed;
2429 }
2430
2431 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
2372 break; 2432 break;
2373 2433
2374 case DISCOV_TYPE_LE: 2434 case DISCOV_TYPE_LE:
2375 if (lmp_host_le_capable(hdev)) 2435 if (!lmp_host_le_capable(hdev)) {
2376 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, 2436 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2377 LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY); 2437 MGMT_STATUS_NOT_SUPPORTED);
2378 else 2438 mgmt_pending_remove(cmd);
2379 err = -ENOTSUPP; 2439 goto failed;
2440 }
2441
2442 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT,
2443 LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY);
2380 break; 2444 break;
2381 2445
2382 case DISCOV_TYPE_INTERLEAVED: 2446 case DISCOV_TYPE_INTERLEAVED:
2383 if (lmp_host_le_capable(hdev) && lmp_bredr_capable(hdev)) 2447 if (!lmp_host_le_capable(hdev) || !lmp_bredr_capable(hdev)) {
2384 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, 2448 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2385 LE_SCAN_WIN, 2449 MGMT_STATUS_NOT_SUPPORTED);
2386 LE_SCAN_TIMEOUT_BREDR_LE); 2450 mgmt_pending_remove(cmd);
2387 else 2451 goto failed;
2388 err = -ENOTSUPP; 2452 }
2453
2454 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT, LE_SCAN_WIN,
2455 LE_SCAN_TIMEOUT_BREDR_LE);
2389 break; 2456 break;
2390 2457
2391 default: 2458 default:
2392 err = -EINVAL; 2459 err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
2460 MGMT_STATUS_INVALID_PARAMS);
2461 mgmt_pending_remove(cmd);
2462 goto failed;
2393 } 2463 }
2394 2464
2395 if (err < 0) 2465 if (err < 0)
@@ -2510,7 +2580,8 @@ static int confirm_name(struct sock *sk, struct hci_dev *hdev, void *data,
2510 hci_inquiry_cache_update_resolve(hdev, e); 2580 hci_inquiry_cache_update_resolve(hdev, e);
2511 } 2581 }
2512 2582
2513 err = 0; 2583 err = cmd_complete(sk, hdev->id, MGMT_OP_CONFIRM_NAME, 0, &cp->addr,
2584 sizeof(cp->addr));
2514 2585
2515failed: 2586failed:
2516 hci_dev_unlock(hdev); 2587 hci_dev_unlock(hdev);
@@ -2526,13 +2597,18 @@ static int block_device(struct sock *sk, struct hci_dev *hdev, void *data,
2526 2597
2527 BT_DBG("%s", hdev->name); 2598 BT_DBG("%s", hdev->name);
2528 2599
2600 if (!bdaddr_type_is_valid(cp->addr.type))
2601 return cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE,
2602 MGMT_STATUS_INVALID_PARAMS,
2603 &cp->addr, sizeof(cp->addr));
2604
2529 hci_dev_lock(hdev); 2605 hci_dev_lock(hdev);
2530 2606
2531 err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type); 2607 err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type);
2532 if (err < 0) 2608 if (err < 0)
2533 status = MGMT_STATUS_FAILED; 2609 status = MGMT_STATUS_FAILED;
2534 else 2610 else
2535 status = 0; 2611 status = MGMT_STATUS_SUCCESS;
2536 2612
2537 err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status, 2613 err = cmd_complete(sk, hdev->id, MGMT_OP_BLOCK_DEVICE, status,
2538 &cp->addr, sizeof(cp->addr)); 2614 &cp->addr, sizeof(cp->addr));
@@ -2551,13 +2627,18 @@ static int unblock_device(struct sock *sk, struct hci_dev *hdev, void *data,
2551 2627
2552 BT_DBG("%s", hdev->name); 2628 BT_DBG("%s", hdev->name);
2553 2629
2630 if (!bdaddr_type_is_valid(cp->addr.type))
2631 return cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE,
2632 MGMT_STATUS_INVALID_PARAMS,
2633 &cp->addr, sizeof(cp->addr));
2634
2554 hci_dev_lock(hdev); 2635 hci_dev_lock(hdev);
2555 2636
2556 err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type); 2637 err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type);
2557 if (err < 0) 2638 if (err < 0)
2558 status = MGMT_STATUS_INVALID_PARAMS; 2639 status = MGMT_STATUS_INVALID_PARAMS;
2559 else 2640 else
2560 status = 0; 2641 status = MGMT_STATUS_SUCCESS;
2561 2642
2562 err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status, 2643 err = cmd_complete(sk, hdev->id, MGMT_OP_UNBLOCK_DEVICE, status,
2563 &cp->addr, sizeof(cp->addr)); 2644 &cp->addr, sizeof(cp->addr));
@@ -2612,6 +2693,10 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
2612 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 2693 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2613 MGMT_STATUS_NOT_SUPPORTED); 2694 MGMT_STATUS_NOT_SUPPORTED);
2614 2695
2696 if (cp->val != 0x00 && cp->val != 0x01)
2697 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2698 MGMT_STATUS_INVALID_PARAMS);
2699
2615 if (!hdev_is_powered(hdev)) 2700 if (!hdev_is_powered(hdev))
2616 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, 2701 return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE,
2617 MGMT_STATUS_NOT_POWERED); 2702 MGMT_STATUS_NOT_POWERED);
@@ -2659,12 +2744,23 @@ done:
2659 return err; 2744 return err;
2660} 2745}
2661 2746
2747static bool ltk_is_valid(struct mgmt_ltk_info *key)
2748{
2749 if (key->authenticated != 0x00 && key->authenticated != 0x01)
2750 return false;
2751 if (key->master != 0x00 && key->master != 0x01)
2752 return false;
2753 if (!bdaddr_type_is_le(key->addr.type))
2754 return false;
2755 return true;
2756}
2757
2662static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, 2758static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
2663 void *cp_data, u16 len) 2759 void *cp_data, u16 len)
2664{ 2760{
2665 struct mgmt_cp_load_long_term_keys *cp = cp_data; 2761 struct mgmt_cp_load_long_term_keys *cp = cp_data;
2666 u16 key_count, expected_len; 2762 u16 key_count, expected_len;
2667 int i; 2763 int i, err;
2668 2764
2669 key_count = __le16_to_cpu(cp->key_count); 2765 key_count = __le16_to_cpu(cp->key_count);
2670 2766
@@ -2674,11 +2770,20 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
2674 BT_ERR("load_keys: expected %u bytes, got %u bytes", 2770 BT_ERR("load_keys: expected %u bytes, got %u bytes",
2675 len, expected_len); 2771 len, expected_len);
2676 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 2772 return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS,
2677 EINVAL); 2773 MGMT_STATUS_INVALID_PARAMS);
2678 } 2774 }
2679 2775
2680 BT_DBG("%s key_count %u", hdev->name, key_count); 2776 BT_DBG("%s key_count %u", hdev->name, key_count);
2681 2777
2778 for (i = 0; i < key_count; i++) {
2779 struct mgmt_ltk_info *key = &cp->keys[i];
2780
2781 if (!ltk_is_valid(key))
2782 return cmd_status(sk, hdev->id,
2783 MGMT_OP_LOAD_LONG_TERM_KEYS,
2784 MGMT_STATUS_INVALID_PARAMS);
2785 }
2786
2682 hci_dev_lock(hdev); 2787 hci_dev_lock(hdev);
2683 2788
2684 hci_smp_ltks_clear(hdev); 2789 hci_smp_ltks_clear(hdev);
@@ -2698,9 +2803,12 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev,
2698 key->enc_size, key->ediv, key->rand); 2803 key->enc_size, key->ediv, key->rand);
2699 } 2804 }
2700 2805
2806 err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, 0,
2807 NULL, 0);
2808
2701 hci_dev_unlock(hdev); 2809 hci_dev_unlock(hdev);
2702 2810
2703 return 0; 2811 return err;
2704} 2812}
2705 2813
2706static const struct mgmt_handler { 2814static const struct mgmt_handler {
@@ -2946,7 +3054,13 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2946 } 3054 }
2947 } else { 3055 } else {
2948 u8 status = MGMT_STATUS_NOT_POWERED; 3056 u8 status = MGMT_STATUS_NOT_POWERED;
3057 u8 zero_cod[] = { 0, 0, 0 };
3058
2949 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); 3059 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
3060
3061 if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0)
3062 mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
3063 zero_cod, sizeof(zero_cod), NULL);
2950 } 3064 }
2951 3065
2952 err = new_settings(hdev, match.sk); 3066 err = new_settings(hdev, match.sk);