linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Support for OOB in mgmt interface
@ 2011-03-01 17:23 Szymon Janc
  2011-03-01 17:23 ` [PATCH v2 1/4] Bluetooth: Rename cmd to cmd_params in pending_cmd Szymon Janc
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Szymon Janc @ 2011-03-01 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

Patches rebased to match changes after moving index to mgmt_hdr.
Dropped patches already applied.

BR,
Szymon Janc
on behalf of ST-Ericsson

Szymon Janc (4):
  Bluetooth: Rename cmd to cmd_params in pending_cmd
  Bluetooth: Allow for NULL data in mgmt_pending_add
  Bluetooth: Add read_local_oob_data management command
  Bluetooth: Add add/remove_remote_oob_data management commands

 include/net/bluetooth/hci.h      |   26 ++++++
 include/net/bluetooth/hci_core.h |   18 ++++
 include/net/bluetooth/mgmt.h     |   18 ++++
 net/bluetooth/hci_core.c         |   76 ++++++++++++++++
 net/bluetooth/hci_event.c        |   56 ++++++++++++-
 net/bluetooth/mgmt.c             |  175 ++++++++++++++++++++++++++++++++++++--
 6 files changed, 361 insertions(+), 8 deletions(-)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/4] Bluetooth: Rename cmd to cmd_params in pending_cmd
  2011-03-01 17:23 [PATCH v2 0/4] Support for OOB in mgmt interface Szymon Janc
@ 2011-03-01 17:23 ` Szymon Janc
  2011-03-17 18:15   ` Gustavo F. Padovan
  2011-03-01 17:23 ` [PATCH v2 2/4] Bluetooth: Allow for NULL data in mgmt_pending_add Szymon Janc
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Szymon Janc @ 2011-03-01 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

This field holds not whole command but only command specific
parameters.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/mgmt.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e6efaae..bde42a5 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -36,7 +36,7 @@ struct pending_cmd {
 	struct list_head list;
 	__u16 opcode;
 	int index;
-	void *cmd;
+	void *cmd_params;
 	struct sock *sk;
 	void *user_data;
 };
@@ -213,7 +213,7 @@ static int read_controller_info(struct sock *sk, u16 index)
 static void mgmt_pending_free(struct pending_cmd *cmd)
 {
 	sock_put(cmd->sk);
-	kfree(cmd->cmd);
+	kfree(cmd->cmd_params);
 	kfree(cmd);
 }
 
@@ -229,13 +229,13 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
 	cmd->opcode = opcode;
 	cmd->index = index;
 
-	cmd->cmd = kmalloc(len, GFP_ATOMIC);
-	if (!cmd->cmd) {
+	cmd->cmd_params = kmalloc(len, GFP_ATOMIC);
+	if (!cmd->cmd_params) {
 		kfree(cmd);
 		return NULL;
 	}
 
-	memcpy(cmd->cmd, data, len);
+	memcpy(cmd->cmd_params, data, len);
 
 	cmd->sk = sk;
 	sock_hold(sk);
@@ -1386,7 +1386,7 @@ struct cmd_lookup {
 
 static void mode_rsp(struct pending_cmd *cmd, void *data)
 {
-	struct mgmt_mode *cp = cmd->cmd;
+	struct mgmt_mode *cp = cmd->cmd_params;
 	struct cmd_lookup *match = data;
 
 	if (cp->val != match->val)
@@ -1486,7 +1486,7 @@ int mgmt_connected(u16 index, bdaddr_t *bdaddr)
 
 static void disconnect_rsp(struct pending_cmd *cmd, void *data)
 {
-	struct mgmt_cp_disconnect *cp = cmd->cmd;
+	struct mgmt_cp_disconnect *cp = cmd->cmd_params;
 	struct sock **sk = data;
 	struct mgmt_rp_disconnect rp;
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/4] Bluetooth: Allow for NULL data in mgmt_pending_add
  2011-03-01 17:23 [PATCH v2 0/4] Support for OOB in mgmt interface Szymon Janc
  2011-03-01 17:23 ` [PATCH v2 1/4] Bluetooth: Rename cmd to cmd_params in pending_cmd Szymon Janc
@ 2011-03-01 17:23 ` Szymon Janc
  2011-03-01 17:23 ` [PATCH v2 3/4] Bluetooth: Add read_local_oob_data management command Szymon Janc
  2011-03-01 17:23 ` [PATCH v2 4/4] Bluetooth: Add add/remove_remote_oob_data management commands Szymon Janc
  3 siblings, 0 replies; 8+ messages in thread
From: Szymon Janc @ 2011-03-01 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

Since index is in mgmt_hdr it is possible to have mgmt command with
no parameters that still needs to add itself to pending list.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/mgmt.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bde42a5..97d7240 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -235,7 +235,8 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
 		return NULL;
 	}
 
-	memcpy(cmd->cmd_params, data, len);
+	if (data)
+		memcpy(cmd->cmd_params, data, len);
 
 	cmd->sk = sk;
 	sock_hold(sk);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/4] Bluetooth: Add read_local_oob_data management command
  2011-03-01 17:23 [PATCH v2 0/4] Support for OOB in mgmt interface Szymon Janc
  2011-03-01 17:23 ` [PATCH v2 1/4] Bluetooth: Rename cmd to cmd_params in pending_cmd Szymon Janc
  2011-03-01 17:23 ` [PATCH v2 2/4] Bluetooth: Allow for NULL data in mgmt_pending_add Szymon Janc
@ 2011-03-01 17:23 ` Szymon Janc
  2011-03-17 18:18   ` Gustavo F. Padovan
  2011-03-01 17:23 ` [PATCH v2 4/4] Bluetooth: Add add/remove_remote_oob_data management commands Szymon Janc
  3 siblings, 1 reply; 8+ messages in thread
From: Szymon Janc @ 2011-03-01 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

This patch adds a command to read local OOB data to the managment interface.
The command maps directly to the Read Local OOB Data HCI command.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 include/net/bluetooth/hci.h      |    7 +++
 include/net/bluetooth/hci_core.h |    2 +
 include/net/bluetooth/mgmt.h     |    6 +++
 net/bluetooth/hci_event.c        |   15 +++++++
 net/bluetooth/mgmt.c             |   85 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ec6acf2..20840dc 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -611,6 +611,13 @@ struct hci_cp_write_ssp_mode {
 	__u8     mode;
 } __packed;
 
+#define HCI_OP_READ_LOCAL_OOB_DATA		0x0c57
+struct hci_rp_read_local_oob_data {
+	__u8     status;
+	__u8     hash[16];
+	__u8     randomizer[16];
+} __packed;
+
 #define HCI_OP_READ_INQ_RSP_TX_POWER	0x0c58
 
 #define HCI_OP_READ_LOCAL_VERSION	0x1001
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 441dadb..c8b7ee6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -767,6 +767,8 @@ int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
 								u8 status);
 int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
+int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
+								u8 status);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 5fabfa8..916b1c6 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -167,6 +167,12 @@ struct mgmt_rp_user_confirm_reply {
 
 #define MGMT_OP_USER_CONFIRM_NEG_REPLY	0x0016
 
+#define MGMT_OP_READ_LOCAL_OOB_DATA	0x0017
+struct mgmt_rp_read_local_oob_data {
+	__u8 hash[16];
+	__u8 randomizer[16];
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3fbfa50..4faab87 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -807,6 +807,17 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
 								rp->status);
 }
 
+static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
+						rp->randomizer, rp->status);
+}
+
 static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
 							struct sk_buff *skb)
 {
@@ -1749,6 +1760,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_pin_code_neg_reply(hdev, skb);
 		break;
 
+	case HCI_OP_READ_LOCAL_OOB_DATA:
+		hci_cc_read_local_oob_data_reply(hdev, skb);
+		break;
+
 	case HCI_OP_LE_READ_BUFFER_SIZE:
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 97d7240..ba43b85 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1259,6 +1259,57 @@ failed:
 	return err;
 }
 
+static int read_local_oob_data(struct sock *sk, u16 index)
+{
+	struct hci_dev *hdev;
+	struct pending_cmd *cmd;
+	int err;
+
+	BT_DBG("hci%u", index);
+
+	hdev = hci_dev_get(index);
+	if (!hdev)
+		return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+									ENODEV);
+
+	hci_dev_lock_bh(hdev);
+
+	if (!test_bit(HCI_UP, &hdev->flags)) {
+		err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+								ENETDOWN);
+		goto unlock;
+	}
+
+	if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
+		err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+								EOPNOTSUPP);
+		goto unlock;
+	}
+
+	if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index)) {
+		err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY);
+		goto unlock;
+	}
+
+	cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, index, NULL, 0);
+
+	if (!cmd) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+
+	if (err < 0)
+		mgmt_pending_remove(cmd);
+
+unlock:
+	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;
@@ -1354,6 +1405,10 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
 		err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0);
 		break;
+	case MGMT_OP_READ_LOCAL_OOB_DATA:
+		err = read_local_oob_data(sk, index);
+		break;
+
 	default:
 		BT_DBG("Unknown op %u", opcode);
 		err = cmd_status(sk, index, opcode, 0x01);
@@ -1652,3 +1707,33 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
 
 	return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL);
 }
+
+int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
+								u8 status)
+{
+	struct pending_cmd *cmd;
+	int err;
+
+	BT_DBG("hci%u status %u", index, status);
+
+	cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index);
+	if (!cmd)
+		return -ENOENT;
+
+	if (status) {
+		err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+									EIO);
+	} else {
+		struct mgmt_rp_read_local_oob_data rp;
+
+		memcpy(rp.hash, hash, 16);
+		memcpy(rp.randomizer, randomizer, 16);
+
+		err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+							&rp, sizeof(rp));
+	}
+
+	mgmt_pending_remove(cmd);
+
+	return err;
+}
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/4] Bluetooth: Add add/remove_remote_oob_data management commands
  2011-03-01 17:23 [PATCH v2 0/4] Support for OOB in mgmt interface Szymon Janc
                   ` (2 preceding siblings ...)
  2011-03-01 17:23 ` [PATCH v2 3/4] Bluetooth: Add read_local_oob_data management command Szymon Janc
@ 2011-03-01 17:23 ` Szymon Janc
  2011-03-17 18:26   ` Gustavo F. Padovan
  3 siblings, 1 reply; 8+ messages in thread
From: Szymon Janc @ 2011-03-01 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc

This patch adds commands to add and remove remote OOB data to the managment
interface. Remote data is stored in kernel and used by corresponding HCI
commands and events (also implemented in this patch) when needed.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 include/net/bluetooth/hci.h      |   19 +++++++++
 include/net/bluetooth/hci_core.h |   16 ++++++++
 include/net/bluetooth/mgmt.h     |   12 ++++++
 net/bluetooth/hci_core.c         |   76 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |   41 ++++++++++++++++++++-
 net/bluetooth/mgmt.c             |   75 +++++++++++++++++++++++++++++++++++++
 6 files changed, 238 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 20840dc..b37ed33 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -426,6 +426,20 @@ struct hci_rp_user_confirm_reply {
 
 #define HCI_OP_USER_CONFIRM_NEG_REPLY	0x042d
 
+
+#define HCI_OP_REMOTE_OOB_DATA_REPLY	0x0430
+struct hci_cp_remote_oob_data_reply {
+	bdaddr_t bdaddr;
+	__u8     hash[16];
+	__u8     randomizer[16];
+} __packed;
+
+#define HCI_OP_REMOTE_OOB_DATA_NEG_REPLY	0x0433
+struct hci_cp_remote_oob_data_neg_reply {
+	bdaddr_t bdaddr;
+} __packed;
+
+
 #define HCI_OP_IO_CAPABILITY_NEG_REPLY	0x0434
 struct hci_cp_io_capability_neg_reply {
 	bdaddr_t bdaddr;
@@ -960,6 +974,11 @@ struct hci_ev_user_confirm_req {
 	__le32		passkey;
 } __packed;
 
+#define HCI_EV_REMOTE_OOB_DATA_REQUEST	0x35
+struct hci_ev_remote_oob_data_request {
+	bdaddr_t bdaddr;
+} __packed;
+
 #define HCI_EV_SIMPLE_PAIR_COMPLETE	0x36
 struct hci_ev_simple_pair_complete {
 	__u8     status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c8b7ee6..0f1e1d6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -82,6 +82,13 @@ struct link_key {
 	u8 pin_len;
 };
 
+struct oob_data {
+	struct list_head list;
+	bdaddr_t bdaddr;
+	u8 hash[16];
+	u8 randomizer[16];
+};
+
 #define NUM_REASSEMBLY 4
 struct hci_dev {
 	struct list_head list;
@@ -169,6 +176,8 @@ struct hci_dev {
 
 	struct list_head	link_keys;
 
+	struct list_head	remote_oob_data;
+
 	struct hci_dev_stats	stat;
 
 	struct sk_buff_head	driver_init;
@@ -505,6 +514,13 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 						u8 *key, u8 type, u8 pin_len);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
+int hci_remote_oob_data_clear(struct hci_dev *hdev);
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+							bdaddr_t *bdaddr);
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+								u8 *randomizer);
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
+
 void hci_del_off_timer(struct hci_dev *hdev);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 916b1c6..ebe288c 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -173,6 +173,18 @@ struct mgmt_rp_read_local_oob_data {
 	__u8 randomizer[16];
 } __packed;
 
+#define MGMT_OP_ADD_REMOTE_OOB_DATA	0x0018
+struct mgmt_cp_add_remote_oob_data {
+	bdaddr_t bdaddr;
+	__u8 hash[16];
+	__u8 randomizer[16];
+} __packed;
+
+#define MGMT_OP_REMOVE_REMOTE_OOB_DATA	0x0019
+struct mgmt_cp_remove_remote_oob_data {
+	bdaddr_t bdaddr;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b372fb8..a1d2263 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1077,6 +1077,79 @@ static void hci_cmd_timer(unsigned long arg)
 	tasklet_schedule(&hdev->cmd_task);
 }
 
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+							bdaddr_t *bdaddr)
+{
+	struct list_head *p;
+
+	list_for_each(p, &hdev->remote_oob_data) {
+		struct oob_data *data;
+
+		data = list_entry(p, struct oob_data, list);
+
+		if (bacmp(bdaddr, &data->bdaddr) == 0)
+			return data;
+	}
+
+	return NULL;
+}
+
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct oob_data *data;
+
+	data = hci_find_remote_oob_data(hdev, bdaddr);
+	if (!data)
+		return -ENOENT;
+
+	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+
+	list_del(&data->list);
+	kfree(data);
+
+	return 0;
+}
+
+int hci_remote_oob_data_clear(struct hci_dev *hdev)
+{
+	struct list_head *p, *n;
+
+	list_for_each_safe(p, n, &hdev->remote_oob_data) {
+		struct oob_data *data;
+
+		data = list_entry(p, struct oob_data, list);
+
+		list_del(p);
+		kfree(data);
+	}
+
+	return 0;
+}
+
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+								u8 *randomizer)
+{
+	struct oob_data *data;
+
+	data = hci_find_remote_oob_data(hdev, bdaddr);
+
+	if (!data) {
+		data = kmalloc(sizeof(*data), GFP_ATOMIC);
+		if (!data)
+			return -ENOMEM;
+
+		bacpy(&data->bdaddr, bdaddr);
+		list_add(&data->list, &hdev->remote_oob_data);
+	}
+
+	memcpy(data->hash, hash, 16);
+	memcpy(data->randomizer, randomizer, 16);
+
+	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
+
+	return 0;
+}
+
 /* Register HCI device */
 int hci_register_dev(struct hci_dev *hdev)
 {
@@ -1141,6 +1214,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	INIT_LIST_HEAD(&hdev->link_keys);
 
+	INIT_LIST_HEAD(&hdev->remote_oob_data);
+
 	INIT_WORK(&hdev->power_on, hci_power_on);
 	INIT_WORK(&hdev->power_off, hci_power_off);
 	setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1220,6 +1295,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
 	hci_blacklist_clear(hdev);
 	hci_uuids_clear(hdev);
 	hci_link_keys_clear(hdev);
+	hci_remote_oob_data_clear(hdev);
 	hci_dev_unlock_bh(hdev);
 
 	__hci_dev_put(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4faab87..955b86a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2368,9 +2368,14 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
 
 		bacpy(&cp.bdaddr, &ev->bdaddr);
 		cp.capability = conn->io_capability;
-		cp.oob_data = 0;
 		cp.authentication = hci_get_auth_req(conn);
 
+		if ((conn->out == 1 || conn->remote_oob == 0x01) &&
+				hci_find_remote_oob_data(hdev, &conn->dst))
+			cp.oob_data = 0x01;
+		else
+			cp.oob_data = 0x00;
+
 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
 							sizeof(cp), &cp);
 	} else {
@@ -2468,6 +2473,37 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
+	struct oob_data *data;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
+	if (data) {
+		struct hci_cp_remote_oob_data_reply cp;
+
+		bacpy(&cp.bdaddr, &ev->bdaddr);
+		memcpy(cp.hash, data->hash, 16);
+		memcpy(cp.randomizer, data->randomizer, 16);
+
+		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
+									&cp);
+	} else {
+		struct hci_cp_remote_oob_data_neg_reply cp;
+
+		bacpy(&cp.bdaddr, &ev->bdaddr);
+		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
+									&cp);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
 static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -2668,6 +2704,9 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 
 	case HCI_EV_LE_META:
 		hci_le_meta_evt(hdev, skb);
+
+	case HCI_EV_REMOTE_OOB_DATA_REQUEST:
+		hci_remote_oob_data_request_evt(hdev, skb);
 		break;
 
 	default:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ba43b85..323b722 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1310,6 +1310,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;
@@ -1408,6 +1476,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);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/4] Bluetooth: Rename cmd to cmd_params in pending_cmd
  2011-03-01 17:23 ` [PATCH v2 1/4] Bluetooth: Rename cmd to cmd_params in pending_cmd Szymon Janc
@ 2011-03-17 18:15   ` Gustavo F. Padovan
  0 siblings, 0 replies; 8+ messages in thread
From: Gustavo F. Padovan @ 2011-03-17 18:15 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2011-03-01 18:23:33 +0100]:

> This field holds not whole command but only command specific
> parameters.
> 
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  net/bluetooth/mgmt.c |   14 +++++++-------
>  1 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index e6efaae..bde42a5 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -36,7 +36,7 @@ struct pending_cmd {
>  	struct list_head list;
>  	__u16 opcode;
>  	int index;
> -	void *cmd;
> +	void *cmd_params;

I prefer 'param' then.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 3/4] Bluetooth: Add read_local_oob_data management command
  2011-03-01 17:23 ` [PATCH v2 3/4] Bluetooth: Add read_local_oob_data management command Szymon Janc
@ 2011-03-17 18:18   ` Gustavo F. Padovan
  0 siblings, 0 replies; 8+ messages in thread
From: Gustavo F. Padovan @ 2011-03-17 18:18 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2011-03-01 18:23:35 +0100]:

> This patch adds a command to read local OOB data to the managment interface.
> The command maps directly to the Read Local OOB Data HCI command.
> 
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  include/net/bluetooth/hci.h      |    7 +++
>  include/net/bluetooth/hci_core.h |    2 +
>  include/net/bluetooth/mgmt.h     |    6 +++
>  net/bluetooth/hci_event.c        |   15 +++++++
>  net/bluetooth/mgmt.c             |   85 ++++++++++++++++++++++++++++++++++++++
>  5 files changed, 115 insertions(+), 0 deletions(-)
> 
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index ec6acf2..20840dc 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -611,6 +611,13 @@ struct hci_cp_write_ssp_mode {
>  	__u8     mode;
>  } __packed;
>  
> +#define HCI_OP_READ_LOCAL_OOB_DATA		0x0c57
> +struct hci_rp_read_local_oob_data {
> +	__u8     status;
> +	__u8     hash[16];
> +	__u8     randomizer[16];
> +} __packed;
> +
>  #define HCI_OP_READ_INQ_RSP_TX_POWER	0x0c58
>  
>  #define HCI_OP_READ_LOCAL_VERSION	0x1001
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 441dadb..c8b7ee6 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -767,6 +767,8 @@ int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
>  int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
>  								u8 status);
>  int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
> +int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
> +								u8 status);
>  
>  /* HCI info for socket */
>  #define hci_pi(sk) ((struct hci_pinfo *) sk)
> diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
> index 5fabfa8..916b1c6 100644
> --- a/include/net/bluetooth/mgmt.h
> +++ b/include/net/bluetooth/mgmt.h
> @@ -167,6 +167,12 @@ struct mgmt_rp_user_confirm_reply {
>  
>  #define MGMT_OP_USER_CONFIRM_NEG_REPLY	0x0016
>  
> +#define MGMT_OP_READ_LOCAL_OOB_DATA	0x0017
> +struct mgmt_rp_read_local_oob_data {
> +	__u8 hash[16];
> +	__u8 randomizer[16];
> +} __packed;
> +
>  #define MGMT_EV_CMD_COMPLETE		0x0001
>  struct mgmt_ev_cmd_complete {
>  	__le16 opcode;
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 3fbfa50..4faab87 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -807,6 +807,17 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
>  								rp->status);
>  }
>  
> +static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
> +							struct sk_buff *skb)
> +{
> +	struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
> +
> +	BT_DBG("%s status 0x%x", hdev->name, rp->status);
> +
> +	mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
> +						rp->randomizer, rp->status);
> +}
> +

This should be after hci_cc_pin_code_neg_reply() and not
hci_cc_user_confirm_reply().


-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 4/4] Bluetooth: Add add/remove_remote_oob_data management commands
  2011-03-01 17:23 ` [PATCH v2 4/4] Bluetooth: Add add/remove_remote_oob_data management commands Szymon Janc
@ 2011-03-17 18:26   ` Gustavo F. Padovan
  0 siblings, 0 replies; 8+ messages in thread
From: Gustavo F. Padovan @ 2011-03-17 18:26 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2011-03-01 18:23:36 +0100]:

> This patch adds commands to add and remove remote OOB data to the managment
> interface. Remote data is stored in kernel and used by corresponding HCI
> commands and events (also implemented in this patch) when needed.
> 
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  include/net/bluetooth/hci.h      |   19 +++++++++
>  include/net/bluetooth/hci_core.h |   16 ++++++++
>  include/net/bluetooth/mgmt.h     |   12 ++++++
>  net/bluetooth/hci_core.c         |   76 ++++++++++++++++++++++++++++++++++++++
>  net/bluetooth/hci_event.c        |   41 ++++++++++++++++++++-
>  net/bluetooth/mgmt.c             |   75 +++++++++++++++++++++++++++++++++++++
>  6 files changed, 238 insertions(+), 1 deletions(-)
> 
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index 20840dc..b37ed33 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -426,6 +426,20 @@ struct hci_rp_user_confirm_reply {
>  
>  #define HCI_OP_USER_CONFIRM_NEG_REPLY	0x042d
>  
> +
> +#define HCI_OP_REMOTE_OOB_DATA_REPLY	0x0430
> +struct hci_cp_remote_oob_data_reply {
> +	bdaddr_t bdaddr;
> +	__u8     hash[16];
> +	__u8     randomizer[16];
> +} __packed;
> +
> +#define HCI_OP_REMOTE_OOB_DATA_NEG_REPLY	0x0433
> +struct hci_cp_remote_oob_data_neg_reply {
> +	bdaddr_t bdaddr;
> +} __packed;
> +
> +
>  #define HCI_OP_IO_CAPABILITY_NEG_REPLY	0x0434
>  struct hci_cp_io_capability_neg_reply {
>  	bdaddr_t bdaddr;
> @@ -960,6 +974,11 @@ struct hci_ev_user_confirm_req {
>  	__le32		passkey;
>  } __packed;
>  
> +#define HCI_EV_REMOTE_OOB_DATA_REQUEST	0x35
> +struct hci_ev_remote_oob_data_request {
> +	bdaddr_t bdaddr;
> +} __packed;
> +
>  #define HCI_EV_SIMPLE_PAIR_COMPLETE	0x36
>  struct hci_ev_simple_pair_complete {
>  	__u8     status;
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index c8b7ee6..0f1e1d6 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -82,6 +82,13 @@ struct link_key {
>  	u8 pin_len;
>  };
>  
> +struct oob_data {
> +	struct list_head list;
> +	bdaddr_t bdaddr;
> +	u8 hash[16];
> +	u8 randomizer[16];
> +};
> +
>  #define NUM_REASSEMBLY 4
>  struct hci_dev {
>  	struct list_head list;
> @@ -169,6 +176,8 @@ struct hci_dev {
>  
>  	struct list_head	link_keys;
>  
> +	struct list_head	remote_oob_data;
> +
>  	struct hci_dev_stats	stat;
>  
>  	struct sk_buff_head	driver_init;
> @@ -505,6 +514,13 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
>  						u8 *key, u8 type, u8 pin_len);
>  int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
>  
> +int hci_remote_oob_data_clear(struct hci_dev *hdev);
> +struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
> +							bdaddr_t *bdaddr);
> +int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
> +								u8 *randomizer);
> +int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
> +
>  void hci_del_off_timer(struct hci_dev *hdev);
>  
>  void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
> diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
> index 916b1c6..ebe288c 100644
> --- a/include/net/bluetooth/mgmt.h
> +++ b/include/net/bluetooth/mgmt.h
> @@ -173,6 +173,18 @@ struct mgmt_rp_read_local_oob_data {
>  	__u8 randomizer[16];
>  } __packed;
>  
> +#define MGMT_OP_ADD_REMOTE_OOB_DATA	0x0018
> +struct mgmt_cp_add_remote_oob_data {
> +	bdaddr_t bdaddr;
> +	__u8 hash[16];
> +	__u8 randomizer[16];
> +} __packed;
> +
> +#define MGMT_OP_REMOVE_REMOTE_OOB_DATA	0x0019
> +struct mgmt_cp_remove_remote_oob_data {
> +	bdaddr_t bdaddr;
> +} __packed;
> +
>  #define MGMT_EV_CMD_COMPLETE		0x0001
>  struct mgmt_ev_cmd_complete {
>  	__le16 opcode;
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index b372fb8..a1d2263 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -1077,6 +1077,79 @@ static void hci_cmd_timer(unsigned long arg)
>  	tasklet_schedule(&hdev->cmd_task);
>  }
>  
> +struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
> +							bdaddr_t *bdaddr)
> +{
> +	struct list_head *p;
> +
> +	list_for_each(p, &hdev->remote_oob_data) {
> +		struct oob_data *data;
> +
> +		data = list_entry(p, struct oob_data, list);

list_for_each_entry() here.

> +
> +		if (bacmp(bdaddr, &data->bdaddr) == 0)
> +			return data;
> +	}
> +
> +	return NULL;
> +}
> +
> +int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
> +{
> +	struct oob_data *data;
> +
> +	data = hci_find_remote_oob_data(hdev, bdaddr);
> +	if (!data)
> +		return -ENOENT;
> +
> +	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
> +
> +	list_del(&data->list);
> +	kfree(data);
> +
> +	return 0;
> +}
> +
> +int hci_remote_oob_data_clear(struct hci_dev *hdev)
> +{
> +	struct list_head *p, *n;
> +
> +	list_for_each_safe(p, n, &hdev->remote_oob_data) {

list_for_each_entry_safe() here.


-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-03-17 18:26 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-01 17:23 [PATCH v2 0/4] Support for OOB in mgmt interface Szymon Janc
2011-03-01 17:23 ` [PATCH v2 1/4] Bluetooth: Rename cmd to cmd_params in pending_cmd Szymon Janc
2011-03-17 18:15   ` Gustavo F. Padovan
2011-03-01 17:23 ` [PATCH v2 2/4] Bluetooth: Allow for NULL data in mgmt_pending_add Szymon Janc
2011-03-01 17:23 ` [PATCH v2 3/4] Bluetooth: Add read_local_oob_data management command Szymon Janc
2011-03-17 18:18   ` Gustavo F. Padovan
2011-03-01 17:23 ` [PATCH v2 4/4] Bluetooth: Add add/remove_remote_oob_data management commands Szymon Janc
2011-03-17 18:26   ` Gustavo F. Padovan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).