aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorSzymon Janc <szymon.janc@tieto.com>2011-03-22 08:12:22 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-03-31 13:22:57 -0400
commit2763eda6ccaf126633bb3180f440c8f3589f0679 (patch)
tree7239d220f4a233b31184ddb50c2914f7406c4675 /net/bluetooth/mgmt.c
parentc35938b2f56547ee77b5a038fe0db394aeac59bb (diff)
Bluetooth: Add add/remove_remote_oob_data management commands
This patch adds commands to add and remove remote OOB data to the managment interface. Remote data is stored in kernel and can be used by corresponding HCI commands and events when needed. Signed-off-by: Szymon Janc <szymon.janc@tieto.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 33b1f7400dab..a42dc8ca0a6f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1345,6 +1345,74 @@ unlock:
1345 return err; 1345 return err;
1346} 1346}
1347 1347
1348static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data,
1349 u16 len)
1350{
1351 struct hci_dev *hdev;
1352 struct mgmt_cp_add_remote_oob_data *cp = (void *) data;
1353 int err;
1354
1355 BT_DBG("hci%u ", index);
1356
1357 if (len != sizeof(*cp))
1358 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
1359 EINVAL);
1360
1361 hdev = hci_dev_get(index);
1362 if (!hdev)
1363 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
1364 ENODEV);
1365
1366 hci_dev_lock_bh(hdev);
1367
1368 err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
1369 cp->randomizer);
1370 if (err < 0)
1371 err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, -err);
1372 else
1373 err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
1374 0);
1375
1376 hci_dev_unlock_bh(hdev);
1377 hci_dev_put(hdev);
1378
1379 return err;
1380}
1381
1382static int remove_remote_oob_data(struct sock *sk, u16 index,
1383 unsigned char *data, u16 len)
1384{
1385 struct hci_dev *hdev;
1386 struct mgmt_cp_remove_remote_oob_data *cp = (void *) data;
1387 int err;
1388
1389 BT_DBG("hci%u ", index);
1390
1391 if (len != sizeof(*cp))
1392 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1393 EINVAL);
1394
1395 hdev = hci_dev_get(index);
1396 if (!hdev)
1397 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1398 ENODEV);
1399
1400 hci_dev_lock_bh(hdev);
1401
1402 err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
1403 if (err < 0)
1404 err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1405 -err);
1406 else
1407 err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1408 NULL, 0);
1409
1410 hci_dev_unlock_bh(hdev);
1411 hci_dev_put(hdev);
1412
1413 return err;
1414}
1415
1348int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) 1416int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
1349{ 1417{
1350 unsigned char *buf; 1418 unsigned char *buf;
@@ -1446,6 +1514,13 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
1446 case MGMT_OP_READ_LOCAL_OOB_DATA: 1514 case MGMT_OP_READ_LOCAL_OOB_DATA:
1447 err = read_local_oob_data(sk, index); 1515 err = read_local_oob_data(sk, index);
1448 break; 1516 break;
1517 case MGMT_OP_ADD_REMOTE_OOB_DATA:
1518 err = add_remote_oob_data(sk, index, buf + sizeof(*hdr), len);
1519 break;
1520 case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
1521 err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
1522 len);
1523 break;
1449 1524
1450 default: 1525 default:
1451 BT_DBG("Unknown op %u", opcode); 1526 BT_DBG("Unknown op %u", opcode);