aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorSzymon Janc <szymon.janc@tieto.com>2011-03-22 13:12:22 +0100
committerGustavo F. Padovan <padovan@profusion.mobi>2011-03-31 14:22:57 -0300
commit2763eda6ccaf126633bb3180f440c8f3589f0679 (patch)
tree7239d220f4a233b31184ddb50c2914f7406c4675 /net/bluetooth/mgmt.c
parentc35938b2f56547ee77b5a038fe0db394aeac59bb (diff)
downloadkernel_samsung_smdk4412-2763eda6ccaf126633bb3180f440c8f3589f0679.zip
kernel_samsung_smdk4412-2763eda6ccaf126633bb3180f440c8f3589f0679.tar.gz
kernel_samsung_smdk4412-2763eda6ccaf126633bb3180f440c8f3589f0679.tar.bz2
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 33b1f74..a42dc8c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1345,6 +1345,74 @@ unlock:
return err;
}
+static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
+{
+ struct hci_dev *hdev;
+ struct mgmt_cp_add_remote_oob_data *cp = (void *) data;
+ int err;
+
+ BT_DBG("hci%u ", index);
+
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
+ EINVAL);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
+ ENODEV);
+
+ hci_dev_lock_bh(hdev);
+
+ err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
+ cp->randomizer);
+ if (err < 0)
+ err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, -err);
+ else
+ err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
+ 0);
+
+ hci_dev_unlock_bh(hdev);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+static int remove_remote_oob_data(struct sock *sk, u16 index,
+ unsigned char *data, u16 len)
+{
+ struct hci_dev *hdev;
+ struct mgmt_cp_remove_remote_oob_data *cp = (void *) data;
+ int err;
+
+ BT_DBG("hci%u ", index);
+
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ EINVAL);
+
+ hdev = hci_dev_get(index);
+ if (!hdev)
+ return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ ENODEV);
+
+ hci_dev_lock_bh(hdev);
+
+ err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
+ if (err < 0)
+ err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ -err);
+ else
+ err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ NULL, 0);
+
+ hci_dev_unlock_bh(hdev);
+ hci_dev_put(hdev);
+
+ return err;
+}
+
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
unsigned char *buf;
@@ -1446,6 +1514,13 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
case MGMT_OP_READ_LOCAL_OOB_DATA:
err = read_local_oob_data(sk, index);
break;
+ case MGMT_OP_ADD_REMOTE_OOB_DATA:
+ err = add_remote_oob_data(sk, index, buf + sizeof(*hdr), len);
+ break;
+ case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
+ err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
+ len);
+ break;
default:
BT_DBG("Unknown op %u", opcode);