Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 0/8] More Management interface patches
@ 2011-02-19 15:05 johan.hedberg
  2011-02-19 15:05 ` [PATCH 1/8] Bluetooth: Make pending_add return a pointer to the added entry johan.hedberg
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:05 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

Here's a new set of patches for the Management interface. Combined with
the latest user space git these patches enable both legacy and Secure
Simple Pairing procedures. After these the only big missing feature in
the management interface is device discovery which I'm just about to
start working on.

Johan


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

* [PATCH 1/8] Bluetooth: Make pending_add return a pointer to the added entry
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
@ 2011-02-19 15:05 ` johan.hedberg
  2011-02-19 15:05 ` [PATCH 2/8] Bluetooth: Add mgmt_pair_device command johan.hedberg
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:05 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@nokia.com>

This makes it more convenient to do manipulations on the entry (needed
by later commits).

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 net/bluetooth/mgmt.c |   62 ++++++++++++++++++++++++++++++++-----------------
 1 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f5ef7a3..52e5f88 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -219,14 +219,14 @@ static void mgmt_pending_free(struct pending_cmd *cmd)
 	kfree(cmd);
 }
 
-static int mgmt_pending_add(struct sock *sk, u16 opcode, int index,
-							void *data, u16 len)
+static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
+						u16 index, void *data, u16 len)
 {
 	struct pending_cmd *cmd;
 
 	cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
 	if (!cmd)
-		return -ENOMEM;
+		return NULL;
 
 	cmd->opcode = opcode;
 	cmd->index = index;
@@ -234,7 +234,7 @@ static int mgmt_pending_add(struct sock *sk, u16 opcode, int index,
 	cmd->cmd = kmalloc(len, GFP_ATOMIC);
 	if (!cmd->cmd) {
 		kfree(cmd);
-		return -ENOMEM;
+		return NULL;
 	}
 
 	memcpy(cmd->cmd, data, len);
@@ -244,7 +244,7 @@ static int mgmt_pending_add(struct sock *sk, u16 opcode, int index,
 
 	list_add(&cmd->list, &cmd_list);
 
-	return 0;
+	return cmd;
 }
 
 static void mgmt_pending_foreach(u16 opcode, int index,
@@ -305,8 +305,9 @@ static int set_powered(struct sock *sk, unsigned char *data, u16 len)
 {
 	struct mgmt_mode *cp;
 	struct hci_dev *hdev;
+	struct pending_cmd *cmd;
 	u16 dev_id;
-	int ret, up;
+	int err, up;
 
 	cp = (void *) data;
 	dev_id = get_unaligned_le16(&cp->index);
@@ -321,36 +322,39 @@ static int set_powered(struct sock *sk, unsigned char *data, u16 len)
 
 	up = test_bit(HCI_UP, &hdev->flags);
 	if ((cp->val && up) || (!cp->val && !up)) {
-		ret = cmd_status(sk, MGMT_OP_SET_POWERED, EALREADY);
+		err = cmd_status(sk, MGMT_OP_SET_POWERED, EALREADY);
 		goto failed;
 	}
 
 	if (mgmt_pending_find(MGMT_OP_SET_POWERED, dev_id)) {
-		ret = cmd_status(sk, MGMT_OP_SET_POWERED, EBUSY);
+		err = cmd_status(sk, MGMT_OP_SET_POWERED, EBUSY);
 		goto failed;
 	}
 
-	ret = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, dev_id, data, len);
-	if (ret < 0)
+	cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, dev_id, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
 		goto failed;
+	}
 
 	if (cp->val)
 		queue_work(hdev->workqueue, &hdev->power_on);
 	else
 		queue_work(hdev->workqueue, &hdev->power_off);
 
-	ret = 0;
+	err = 0;
 
 failed:
 	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
-	return ret;
+	return err;
 }
 
 static int set_discoverable(struct sock *sk, unsigned char *data, u16 len)
 {
 	struct mgmt_mode *cp;
 	struct hci_dev *hdev;
+	struct pending_cmd *cmd;
 	u16 dev_id;
 	u8 scan;
 	int err;
@@ -383,9 +387,11 @@ static int set_discoverable(struct sock *sk, unsigned char *data, u16 len)
 		goto failed;
 	}
 
-	err = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, dev_id, data, len);
-	if (err < 0)
+	cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, dev_id, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
 		goto failed;
+	}
 
 	scan = SCAN_PAGE;
 
@@ -407,6 +413,7 @@ static int set_connectable(struct sock *sk, unsigned char *data, u16 len)
 {
 	struct mgmt_mode *cp;
 	struct hci_dev *hdev;
+	struct pending_cmd *cmd;
 	u16 dev_id;
 	u8 scan;
 	int err;
@@ -438,9 +445,11 @@ static int set_connectable(struct sock *sk, unsigned char *data, u16 len)
 		goto failed;
 	}
 
-	err = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, dev_id, data, len);
-	if (err < 0)
+	cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, dev_id, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
 		goto failed;
+	}
 
 	if (cp->val)
 		scan = SCAN_PAGE;
@@ -828,6 +837,7 @@ static int disconnect(struct sock *sk, unsigned char *data, u16 len)
 	struct hci_dev *hdev;
 	struct mgmt_cp_disconnect *cp;
 	struct hci_cp_disconnect dc;
+	struct pending_cmd *cmd;
 	struct hci_conn *conn;
 	u16 dev_id;
 	int err;
@@ -859,9 +869,11 @@ static int disconnect(struct sock *sk, unsigned char *data, u16 len)
 		goto failed;
 	}
 
-	err = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, dev_id, data, len);
-	if (err < 0)
+	cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, dev_id, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
 		goto failed;
+	}
 
 	put_unaligned_le16(conn->handle, &dc.handle);
 	dc.reason = 0x13; /* Remote User Terminated Connection */
@@ -938,6 +950,7 @@ static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len)
 	struct hci_dev *hdev;
 	struct mgmt_cp_pin_code_reply *cp;
 	struct hci_cp_pin_code_reply reply;
+	struct pending_cmd *cmd;
 	u16 dev_id;
 	int err;
 
@@ -957,9 +970,11 @@ static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len)
 		goto failed;
 	}
 
-	err = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, dev_id, data, len);
-	if (err < 0)
+	cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, dev_id, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
 		goto failed;
+	}
 
 	bacpy(&reply.bdaddr, &cp->bdaddr);
 	reply.pin_len = cp->pin_len;
@@ -980,6 +995,7 @@ static int pin_code_neg_reply(struct sock *sk, unsigned char *data, u16 len)
 {
 	struct hci_dev *hdev;
 	struct mgmt_cp_pin_code_neg_reply *cp;
+	struct pending_cmd *cmd;
 	u16 dev_id;
 	int err;
 
@@ -999,10 +1015,12 @@ static int pin_code_neg_reply(struct sock *sk, unsigned char *data, u16 len)
 		goto failed;
 	}
 
-	err = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, dev_id,
+	cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, dev_id,
 								data, len);
-	if (err < 0)
+	if (!cmd) {
+		err = -ENOMEM;
 		goto failed;
+	}
 
 	err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(bdaddr_t),
 								&cp->bdaddr);
-- 
1.7.4.1


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

* [PATCH 2/8] Bluetooth: Add mgmt_pair_device command
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
  2011-02-19 15:05 ` [PATCH 1/8] Bluetooth: Make pending_add return a pointer to the added entry johan.hedberg
@ 2011-02-19 15:05 ` johan.hedberg
  2011-02-19 15:05 ` [PATCH 3/8] Bluetooth: Add management support for user confirmation request johan.hedberg
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:05 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@nokia.com>

This patch adds a new mgmt_pair_device which can be used to initiate a
dedicated bonding procedure. Some extra callbacks are added to the
hci_conn struct so that the pairing code can get notified of the
completion of the procedure.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 include/net/bluetooth/hci_core.h |   16 +++++
 include/net/bluetooth/mgmt.h     |   12 ++++
 net/bluetooth/mgmt.c             |  133 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 161 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index d5d8454..506f250 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -248,6 +248,10 @@ struct hci_conn {
 	void		*priv;
 
 	struct hci_conn	*link;
+
+	void (*connect_cfm_cb)	(struct hci_conn *conn, u8 status);
+	void (*security_cfm_cb)	(struct hci_conn *conn, u8 status);
+	void (*disconn_cfm_cb)	(struct hci_conn *conn, u8 reason);
 };
 
 extern struct hci_proto *hci_proto[];
@@ -571,6 +575,9 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
 	hp = hci_proto[HCI_PROTO_SCO];
 	if (hp && hp->connect_cfm)
 		hp->connect_cfm(conn, status);
+
+	if (conn->connect_cfm_cb)
+		conn->connect_cfm_cb(conn, status);
 }
 
 static inline int hci_proto_disconn_ind(struct hci_conn *conn)
@@ -600,6 +607,9 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
 	hp = hci_proto[HCI_PROTO_SCO];
 	if (hp && hp->disconn_cfm)
 		hp->disconn_cfm(conn, reason);
+
+	if (conn->disconn_cfm_cb)
+		conn->disconn_cfm_cb(conn, reason);
 }
 
 static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
@@ -619,6 +629,9 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
 	hp = hci_proto[HCI_PROTO_SCO];
 	if (hp && hp->security_cfm)
 		hp->security_cfm(conn, status, encrypt);
+
+	if (conn->security_cfm_cb)
+		conn->security_cfm_cb(conn, status);
 }
 
 static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
@@ -632,6 +645,9 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u
 	hp = hci_proto[HCI_PROTO_SCO];
 	if (hp && hp->security_cfm)
 		hp->security_cfm(conn, status, encrypt);
+
+	if (conn->security_cfm_cb)
+		conn->security_cfm_cb(conn, status);
 }
 
 int hci_register_proto(struct hci_proto *hproto);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 44ac55c..1d25c59 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -160,6 +160,18 @@ struct mgmt_cp_set_io_capability {
 	__u8 io_capability;
 } __packed;
 
+#define MGMT_OP_PAIR_DEVICE		0x0014
+struct mgmt_cp_pair_device {
+	__le16 index;
+	bdaddr_t bdaddr;
+	__u8 io_cap;
+} __packed;
+struct mgmt_rp_pair_device {
+	__le16 index;
+	bdaddr_t bdaddr;
+	__u8 status;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 52e5f88..d7fc54d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -38,6 +38,7 @@ struct pending_cmd {
 	int index;
 	void *cmd;
 	struct sock *sk;
+	void *user_data;
 };
 
 LIST_HEAD(cmd_list);
@@ -1063,6 +1064,135 @@ static int set_io_capability(struct sock *sk, unsigned char *data, u16 len)
 						&dev_id, sizeof(dev_id));
 }
 
+static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct list_head *p;
+
+	list_for_each(p, &cmd_list) {
+		struct pending_cmd *cmd;
+
+		cmd = list_entry(p, struct pending_cmd, list);
+
+		if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
+			continue;
+
+		if (cmd->index != hdev->id)
+			continue;
+
+		if (cmd->user_data != conn)
+			continue;
+
+		return cmd;
+	}
+
+	return NULL;
+}
+
+static void pairing_complete(struct pending_cmd *cmd, u8 status)
+{
+	struct mgmt_rp_pair_device rp;
+	struct hci_conn *conn = cmd->user_data;
+
+	rp.index = cmd->index;
+	bacpy(&rp.bdaddr, &conn->dst);
+	rp.status = status;
+
+	cmd_complete(cmd->sk, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
+
+	/* So we don't get further callbacks for this connection */
+	conn->connect_cfm_cb = NULL;
+	conn->security_cfm_cb = NULL;
+	conn->disconn_cfm_cb = NULL;
+
+	hci_conn_put(conn);
+
+	list_del(&cmd->list);
+	mgmt_pending_free(cmd);
+}
+
+static void pairing_complete_cb(struct hci_conn *conn, u8 status)
+{
+	struct pending_cmd *cmd;
+
+	BT_DBG("status %u", status);
+
+	cmd = find_pairing(conn);
+	if (!cmd) {
+		BT_DBG("Unable to find a pending command");
+		return;
+	}
+
+	pairing_complete(cmd, status);
+}
+
+static int pair_device(struct sock *sk, unsigned char *data, u16 len)
+{
+	struct hci_dev *hdev;
+	struct mgmt_cp_pair_device *cp;
+	struct pending_cmd *cmd;
+	u8 sec_level, auth_type;
+	struct hci_conn *conn;
+	u16 dev_id;
+	int err;
+
+	BT_DBG("");
+
+	cp = (void *) data;
+	dev_id = get_unaligned_le16(&cp->index);
+
+	hdev = hci_dev_get(dev_id);
+	if (!hdev)
+		return cmd_status(sk, MGMT_OP_PAIR_DEVICE, ENODEV);
+
+	hci_dev_lock_bh(hdev);
+
+	if (cp->io_cap == 0x03) {
+		sec_level = BT_SECURITY_MEDIUM;
+		auth_type = HCI_AT_DEDICATED_BONDING;
+	} else {
+		sec_level = BT_SECURITY_HIGH;
+		auth_type = HCI_AT_DEDICATED_BONDING_MITM;
+	}
+
+	conn = hci_connect(hdev, ACL_LINK, &cp->bdaddr, sec_level, auth_type);
+	if (!conn) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	if (conn->connect_cfm_cb) {
+		hci_conn_put(conn);
+		err = cmd_status(sk, MGMT_OP_PAIR_DEVICE, EBUSY);
+		goto unlock;
+	}
+
+	cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, dev_id, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
+		hci_conn_put(conn);
+		goto unlock;
+	}
+
+	conn->connect_cfm_cb = pairing_complete_cb;
+	conn->security_cfm_cb = pairing_complete_cb;
+	conn->disconn_cfm_cb = pairing_complete_cb;
+	conn->io_capability = cp->io_cap;
+	cmd->user_data = conn;
+
+	if (conn->state == BT_CONNECTED &&
+				hci_conn_security(conn, sec_level, auth_type))
+		pairing_complete(cmd, 0);
+
+	err = 0;
+
+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;
@@ -1148,6 +1278,9 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 	case MGMT_OP_SET_IO_CAPABILITY:
 		err = set_io_capability(sk, buf + sizeof(*hdr), len);
 		break;
+	case MGMT_OP_PAIR_DEVICE:
+		err = pair_device(sk, buf + sizeof(*hdr), len);
+		break;
 	default:
 		BT_DBG("Unknown op %u", opcode);
 		err = cmd_status(sk, opcode, 0x01);
-- 
1.7.4.1


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

* [PATCH 3/8] Bluetooth: Add management support for user confirmation request
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
  2011-02-19 15:05 ` [PATCH 1/8] Bluetooth: Make pending_add return a pointer to the added entry johan.hedberg
  2011-02-19 15:05 ` [PATCH 2/8] Bluetooth: Add mgmt_pair_device command johan.hedberg
@ 2011-02-19 15:05 ` johan.hedberg
  2011-02-19 15:05 ` [PATCH 4/8] Bluetooth: Fix mgmt_pin_code_reply command status opcode johan.hedberg
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:05 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@nokia.com>

This patch adds support for the user confirmation (numeric comparison)
Secure Simple Pairing authentication method.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 include/net/bluetooth/hci.h      |   17 ++++++
 include/net/bluetooth/hci_core.h |    4 ++
 include/net/bluetooth/mgmt.h     |   20 +++++++
 net/bluetooth/hci_event.c        |   50 ++++++++++++++++++
 net/bluetooth/mgmt.c             |  103 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 194 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index a5f8c46..ec6acf2 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -415,6 +415,17 @@ struct hci_cp_io_capability_reply {
 	__u8     authentication;
 } __packed;
 
+#define HCI_OP_USER_CONFIRM_REPLY		0x042c
+struct hci_cp_user_confirm_reply {
+	bdaddr_t bdaddr;
+} __packed;
+struct hci_rp_user_confirm_reply {
+	__u8     status;
+	bdaddr_t bdaddr;
+} __packed;
+
+#define HCI_OP_USER_CONFIRM_NEG_REPLY	0x042d
+
 #define HCI_OP_IO_CAPABILITY_NEG_REPLY	0x0434
 struct hci_cp_io_capability_neg_reply {
 	bdaddr_t bdaddr;
@@ -936,6 +947,12 @@ struct hci_ev_io_capa_reply {
 	__u8     authentication;
 } __packed;
 
+#define HCI_EV_USER_CONFIRM_REQUEST	0x33
+struct hci_ev_user_confirm_req {
+	bdaddr_t	bdaddr;
+	__le32		passkey;
+} __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 506f250..05f4706 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -762,6 +762,10 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
 int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
+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);
 
 /* 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 1d25c59..52376a3 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -172,6 +172,19 @@ struct mgmt_rp_pair_device {
 	__u8 status;
 } __packed;
 
+#define MGMT_OP_USER_CONFIRM_REPLY	0x0015
+struct mgmt_cp_user_confirm_reply {
+	__le16 index;
+	bdaddr_t bdaddr;
+} __packed;
+struct mgmt_rp_user_confirm_reply {
+	__le16 index;
+	bdaddr_t bdaddr;
+	__u8 status;
+} __packed;
+
+#define MGMT_OP_USER_CONFIRM_NEG_REPLY	0x0016
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
@@ -239,3 +252,10 @@ struct mgmt_ev_pin_code_request {
 	__le16 index;
 	bdaddr_t bdaddr;
 } __packed;
+
+#define MGMT_EV_USER_CONFIRM_REQUEST	0x000F
+struct mgmt_ev_user_confirm_request {
+	__le16 index;
+	bdaddr_t bdaddr;
+	__le32 value;
+} __packed;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 98b5764..604c7b5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -796,6 +796,29 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
 	hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
 }
 
+static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (test_bit(HCI_MGMT, &hdev->flags))
+		mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr,
+								rp->status);
+}
+
+static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (test_bit(HCI_MGMT, &hdev->flags))
+		mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr,
+								rp->status);
+}
+
 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
 {
 	BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1728,6 +1751,14 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
 
+	case HCI_OP_USER_CONFIRM_REPLY:
+		hci_cc_user_confirm_reply(hdev, skb);
+		break;
+
+	case HCI_OP_USER_CONFIRM_NEG_REPLY:
+		hci_cc_user_confirm_neg_reply(hdev, skb);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 		break;
@@ -2362,6 +2393,21 @@ unlock:
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_ev_user_confirm_req *ev = (void *) skb->data;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	if (test_bit(HCI_MGMT, &hdev->flags))
+		mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
+
+	hci_dev_unlock(hdev);
+}
+
 static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
@@ -2580,6 +2626,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 		hci_io_capa_reply_evt(hdev, skb);
 		break;
 
+	case HCI_EV_USER_CONFIRM_REQUEST:
+		hci_user_confirm_request_evt(hdev, skb);
+		break;
+
 	case HCI_EV_SIMPLE_PAIR_COMPLETE:
 		hci_simple_pair_complete_evt(hdev, skb);
 		break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d7fc54d..fdcc974 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1193,6 +1193,55 @@ unlock:
 	return err;
 }
 
+static int user_confirm_reply(struct sock *sk, unsigned char *data, u16 len,
+								int success)
+{
+	struct mgmt_cp_user_confirm_reply *cp = (void *) data;
+	u16 dev_id, mgmt_op, hci_op;
+	struct pending_cmd *cmd;
+	struct hci_dev *hdev;
+	int err;
+
+	BT_DBG("");
+
+	dev_id = get_unaligned_le16(&cp->index);
+
+	if (success) {
+		mgmt_op = MGMT_OP_USER_CONFIRM_REPLY;
+		hci_op = HCI_OP_USER_CONFIRM_REPLY;
+	} else {
+		mgmt_op = MGMT_OP_USER_CONFIRM_NEG_REPLY;
+		hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY;
+	}
+
+	hdev = hci_dev_get(dev_id);
+	if (!hdev)
+		return cmd_status(sk, mgmt_op, ENODEV);
+
+	if (!test_bit(HCI_UP, &hdev->flags)) {
+		err = cmd_status(sk, mgmt_op, ENETDOWN);
+		goto failed;
+	}
+
+	cmd = mgmt_pending_add(sk, mgmt_op, dev_id, data, len);
+	if (!cmd) {
+		err = -ENOMEM;
+		goto failed;
+	}
+
+	err = hci_send_cmd(hdev, hci_op, sizeof(cp->bdaddr), &cp->bdaddr);
+	if (err < 0) {
+		list_del(&cmd->list);
+		mgmt_pending_free(cmd);
+	}
+
+failed:
+	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;
@@ -1281,6 +1330,12 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 	case MGMT_OP_PAIR_DEVICE:
 		err = pair_device(sk, buf + sizeof(*hdr), len);
 		break;
+	case MGMT_OP_USER_CONFIRM_REPLY:
+		err = user_confirm_reply(sk, buf + sizeof(*hdr), len, 1);
+		break;
+	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
+		err = user_confirm_reply(sk, buf + sizeof(*hdr), len, 0);
+		break;
 	default:
 		BT_DBG("Unknown op %u", opcode);
 		err = cmd_status(sk, opcode, 0x01);
@@ -1541,3 +1596,51 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 
 	return err;
 }
+
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
+{
+	struct mgmt_ev_user_confirm_request ev;
+
+	BT_DBG("hci%u", index);
+
+	put_unaligned_le16(index, &ev.index);
+	bacpy(&ev.bdaddr, bdaddr);
+	put_unaligned_le32(value, &ev.value);
+
+	return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, &ev, sizeof(ev), NULL);
+}
+
+static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status,
+								u8 opcode)
+{
+	struct pending_cmd *cmd;
+	struct mgmt_rp_user_confirm_reply rp;
+	int err;
+
+	cmd = mgmt_pending_find(opcode, index);
+	if (!cmd)
+		return -ENOENT;
+
+	put_unaligned_le16(index, &rp.index);
+	bacpy(&rp.bdaddr, bdaddr);
+	rp.status = status;
+	err = cmd_complete(cmd->sk, opcode, &rp, sizeof(rp));
+
+	list_del(&cmd->list);
+	mgmt_pending_free(cmd);
+
+	return err;
+}
+
+int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
+{
+	return confirm_reply_complete(index, bdaddr, status,
+						MGMT_OP_USER_CONFIRM_REPLY);
+}
+
+int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
+								u8 status)
+{
+	return confirm_reply_complete(index, bdaddr, status,
+					MGMT_OP_USER_CONFIRM_NEG_REPLY);
+}
-- 
1.7.4.1


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

* [PATCH 4/8] Bluetooth: Fix mgmt_pin_code_reply command status opcode
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
                   ` (2 preceding siblings ...)
  2011-02-19 15:05 ` [PATCH 3/8] Bluetooth: Add management support for user confirmation request johan.hedberg
@ 2011-02-19 15:05 ` johan.hedberg
  2011-02-19 15:05 ` [PATCH 5/8] Bluetooth: Fix mgmt_pin_code_reply return parameters johan.hedberg
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:05 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@nokia.com>

The opcode for the ENODEV case was wrong (probably copy-paste mistake).

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 net/bluetooth/mgmt.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index fdcc974..d1d9b8c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -962,7 +962,7 @@ static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len)
 
 	hdev = hci_dev_get(dev_id);
 	if (!hdev)
-		return cmd_status(sk, MGMT_OP_DISCONNECT, ENODEV);
+		return cmd_status(sk, MGMT_OP_PIN_CODE_REPLY, ENODEV);
 
 	hci_dev_lock_bh(hdev);
 
-- 
1.7.4.1


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

* [PATCH 5/8] Bluetooth: Fix mgmt_pin_code_reply return parameters
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
                   ` (3 preceding siblings ...)
  2011-02-19 15:05 ` [PATCH 4/8] Bluetooth: Fix mgmt_pin_code_reply command status opcode johan.hedberg
@ 2011-02-19 15:05 ` johan.hedberg
  2011-02-19 15:06 ` [PATCH 6/8] Bluetooth: Add mgmt_auth_failed event johan.hedberg
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:05 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@nokia.com>

The command complete event for mgmt_pin_code_reply &
mgmt_pin_code_neg_reply should have the adapter index, Bluetooth address
as well as the status.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 include/net/bluetooth/mgmt.h |    5 +++++
 net/bluetooth/mgmt.c         |   23 +++++++++++++----------
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 52376a3..5aee200 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -147,6 +147,11 @@ struct mgmt_cp_pin_code_reply {
 	__u8 pin_len;
 	__u8 pin_code[16];
 } __packed;
+struct mgmt_rp_pin_code_reply {
+	__le16 index;
+	bdaddr_t bdaddr;
+	uint8_t status;
+} __packed;
 
 #define MGMT_OP_PIN_CODE_NEG_REPLY	0x0012
 struct mgmt_cp_pin_code_neg_reply {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d1d9b8c..0d3d613 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1558,17 +1558,18 @@ int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
 int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 {
 	struct pending_cmd *cmd;
+	struct mgmt_rp_pin_code_reply rp;
 	int err;
 
 	cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index);
 	if (!cmd)
 		return -ENOENT;
 
-	if (status != 0)
-		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_REPLY, status);
-	else
-		err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY,
-						bdaddr, sizeof(*bdaddr));
+	put_unaligned_le16(index, &rp.index);
+	bacpy(&rp.bdaddr, bdaddr);
+	rp.status = status;
+
+	err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY, &rp, sizeof(rp));
 
 	list_del(&cmd->list);
 	mgmt_pending_free(cmd);
@@ -1579,17 +1580,19 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 {
 	struct pending_cmd *cmd;
+	struct mgmt_rp_pin_code_reply rp;
 	int err;
 
 	cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index);
 	if (!cmd)
 		return -ENOENT;
 
-	if (status != 0)
-		err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, status);
-	else
-		err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY,
-						bdaddr, sizeof(*bdaddr));
+	put_unaligned_le16(index, &rp.index);
+	bacpy(&rp.bdaddr, bdaddr);
+	rp.status = status;
+
+	err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY,
+							&rp, sizeof(rp));
 
 	list_del(&cmd->list);
 	mgmt_pending_free(cmd);
-- 
1.7.4.1


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

* [PATCH 6/8] Bluetooth: Add mgmt_auth_failed event
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
                   ` (4 preceding siblings ...)
  2011-02-19 15:05 ` [PATCH 5/8] Bluetooth: Fix mgmt_pin_code_reply return parameters johan.hedberg
@ 2011-02-19 15:06 ` johan.hedberg
  2011-02-19 15:06 ` [PATCH 7/8] Bluetooth: Fix inititial value for remote authentication requirements johan.hedberg
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:06 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@nokia.com>

To properly track bonding completion an event to indicate authentication
failure is needed. This event will be sent whenever an authentication
complete HCI event with a non-zero status comes. It will also be sent
when we're acting in acceptor role for SSP authentication in which case
the controller will send a Simple Pairing Complete event.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 include/net/bluetooth/hci_core.h |    1 +
 include/net/bluetooth/mgmt.h     |    7 +++++++
 net/bluetooth/hci_event.c        |   19 ++++++++++++++++---
 net/bluetooth/mgmt.c             |   11 +++++++++++
 4 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 05f4706..441dadb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -766,6 +766,7 @@ int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
 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);
 
 /* 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 5aee200..1e63c31 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -264,3 +264,10 @@ struct mgmt_ev_user_confirm_request {
 	bdaddr_t bdaddr;
 	__le32 value;
 } __packed;
+
+#define MGMT_EV_AUTH_FAILED		0x0010
+struct mgmt_ev_auth_failed {
+	__le16 index;
+	bdaddr_t bdaddr;
+	__u8 status;
+} __packed;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 604c7b5..3fbfa50 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1424,8 +1424,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 		if (!ev->status) {
 			conn->link_mode |= HCI_LM_AUTH;
 			conn->sec_level = conn->pending_sec_level;
-		} else
+		} else {
+			mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
 			conn->sec_level = BT_SECURITY_LOW;
+		}
 
 		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
 
@@ -2418,9 +2420,20 @@ static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_
 	hci_dev_lock(hdev);
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
-	if (conn)
-		hci_conn_put(conn);
+	if (!conn)
+		goto unlock;
+
+	/* To avoid duplicate auth_failed events to user space we check
+	 * the HCI_CONN_AUTH_PEND flag which will be set if we
+	 * initiated the authentication. A traditional auth_complete
+	 * event gets always produced as initiator and is also mapped to
+	 * the mgmt_auth_failed event */
+	if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
+		mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
 
+	hci_conn_put(conn);
+
+unlock:
 	hci_dev_unlock(hdev);
 }
 
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 0d3d613..46e2c39 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1647,3 +1647,14 @@ int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
 	return confirm_reply_complete(index, bdaddr, status,
 					MGMT_OP_USER_CONFIRM_NEG_REPLY);
 }
+
+int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
+{
+	struct mgmt_ev_auth_failed ev;
+
+	put_unaligned_le16(index, &ev.index);
+	bacpy(&ev.bdaddr, bdaddr);
+	ev.status = status;
+
+	return mgmt_event(MGMT_EV_AUTH_FAILED, &ev, sizeof(ev), NULL);
+}
-- 
1.7.4.1


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

* [PATCH 7/8] Bluetooth: Fix inititial value for remote authentication requirements
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
                   ` (5 preceding siblings ...)
  2011-02-19 15:06 ` [PATCH 6/8] Bluetooth: Add mgmt_auth_failed event johan.hedberg
@ 2011-02-19 15:06 ` johan.hedberg
  2011-02-19 15:06 ` [PATCH 8/8] Bluetooth: Fix unnecessary list traversal in mgmt_pending_remove johan.hedberg
  2011-02-21 20:53 ` [PATCH 0/8] More Management interface patches Gustavo F. Padovan
  8 siblings, 0 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:06 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@nokia.com>

The remote authentication requirements for conections need to be
initialized to 0xff (unknown) since it is possible that we receive a IO
Capability Request before we have received information about the remote
requirements.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 net/bluetooth/hci_conn.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index a050a69..6d8b988 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -286,6 +286,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 	conn->state = BT_OPEN;
 	conn->auth_type = HCI_AT_GENERAL_BONDING;
 	conn->io_capability = hdev->io_capability;
+	conn->remote_auth = 0xff;
 
 	conn->power_save = 1;
 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
-- 
1.7.4.1


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

* [PATCH 8/8] Bluetooth: Fix unnecessary list traversal in mgmt_pending_remove
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
                   ` (6 preceding siblings ...)
  2011-02-19 15:06 ` [PATCH 7/8] Bluetooth: Fix inititial value for remote authentication requirements johan.hedberg
@ 2011-02-19 15:06 ` johan.hedberg
  2011-02-21 20:53 ` [PATCH 0/8] More Management interface patches Gustavo F. Padovan
  8 siblings, 0 replies; 10+ messages in thread
From: johan.hedberg @ 2011-02-19 15:06 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@nokia.com>

All of the places that need to call mgmt_pending_remove already have a
pointer to the pending command, so searching for the command in the list
doesn't make sense. The added benefit is that many places that
previously had to call list_del + mgmt_pending_free can just call
mgmt_pending_remove now.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 net/bluetooth/mgmt.c |   42 ++++++++++++++----------------------------
 1 files changed, 14 insertions(+), 28 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 46e2c39..982becd 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -290,14 +290,8 @@ static struct pending_cmd *mgmt_pending_find(u16 opcode, int index)
 	return NULL;
 }
 
-static void mgmt_pending_remove(u16 opcode, int index)
+static void mgmt_pending_remove(struct pending_cmd *cmd)
 {
-	struct pending_cmd *cmd;
-
-	cmd = mgmt_pending_find(opcode, index);
-	if (cmd == NULL)
-		return;
-
 	list_del(&cmd->list);
 	mgmt_pending_free(cmd);
 }
@@ -401,7 +395,7 @@ static int set_discoverable(struct sock *sk, unsigned char *data, u16 len)
 
 	err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 	if (err < 0)
-		mgmt_pending_remove(MGMT_OP_SET_DISCOVERABLE, dev_id);
+		mgmt_pending_remove(cmd);
 
 failed:
 	hci_dev_unlock_bh(hdev);
@@ -459,7 +453,7 @@ static int set_connectable(struct sock *sk, unsigned char *data, u16 len)
 
 	err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 	if (err < 0)
-		mgmt_pending_remove(MGMT_OP_SET_CONNECTABLE, dev_id);
+		mgmt_pending_remove(cmd);
 
 failed:
 	hci_dev_unlock_bh(hdev);
@@ -881,7 +875,7 @@ static int disconnect(struct sock *sk, unsigned char *data, u16 len)
 
 	err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
 	if (err < 0)
-		mgmt_pending_remove(MGMT_OP_DISCONNECT, dev_id);
+		mgmt_pending_remove(cmd);
 
 failed:
 	hci_dev_unlock_bh(hdev);
@@ -983,7 +977,7 @@ static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len)
 
 	err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
 	if (err < 0)
-		mgmt_pending_remove(MGMT_OP_PIN_CODE_REPLY, dev_id);
+		mgmt_pending_remove(cmd);
 
 failed:
 	hci_dev_unlock_bh(hdev);
@@ -1026,7 +1020,7 @@ static int pin_code_neg_reply(struct sock *sk, unsigned char *data, u16 len)
 	err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(bdaddr_t),
 								&cp->bdaddr);
 	if (err < 0)
-		mgmt_pending_remove(MGMT_OP_PIN_CODE_NEG_REPLY, dev_id);
+		mgmt_pending_remove(cmd);
 
 failed:
 	hci_dev_unlock_bh(hdev);
@@ -1107,8 +1101,7 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
 
 	hci_conn_put(conn);
 
-	list_del(&cmd->list);
-	mgmt_pending_free(cmd);
+	mgmt_pending_remove(cmd);
 }
 
 static void pairing_complete_cb(struct hci_conn *conn, u8 status)
@@ -1230,10 +1223,8 @@ static int user_confirm_reply(struct sock *sk, unsigned char *data, u16 len,
 	}
 
 	err = hci_send_cmd(hdev, hci_op, sizeof(cp->bdaddr), &cp->bdaddr);
-	if (err < 0) {
-		list_del(&cmd->list);
-		mgmt_pending_free(cmd);
-	}
+	if (err < 0)
+		mgmt_pending_remove(cmd);
 
 failed:
 	hci_dev_unlock_bh(hdev);
@@ -1494,8 +1485,7 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
 	*sk = cmd->sk;
 	sock_hold(*sk);
 
-	list_del(&cmd->list);
-	mgmt_pending_free(cmd);
+	mgmt_pending_remove(cmd);
 }
 
 int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
@@ -1528,8 +1518,7 @@ int mgmt_disconnect_failed(u16 index)
 
 	err = cmd_status(cmd->sk, MGMT_OP_DISCONNECT, EIO);
 
-	list_del(&cmd->list);
-	mgmt_pending_free(cmd);
+	mgmt_pending_remove(cmd);
 
 	return err;
 }
@@ -1571,8 +1560,7 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 
 	err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY, &rp, sizeof(rp));
 
-	list_del(&cmd->list);
-	mgmt_pending_free(cmd);
+	mgmt_pending_remove(cmd);
 
 	return err;
 }
@@ -1594,8 +1582,7 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
 	err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY,
 							&rp, sizeof(rp));
 
-	list_del(&cmd->list);
-	mgmt_pending_free(cmd);
+	mgmt_pending_remove(cmd);
 
 	return err;
 }
@@ -1629,8 +1616,7 @@ static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status,
 	rp.status = status;
 	err = cmd_complete(cmd->sk, opcode, &rp, sizeof(rp));
 
-	list_del(&cmd->list);
-	mgmt_pending_free(cmd);
+	mgmt_pending_remove(cmd);
 
 	return err;
 }
-- 
1.7.4.1


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

* Re: [PATCH 0/8] More Management interface patches
  2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
                   ` (7 preceding siblings ...)
  2011-02-19 15:06 ` [PATCH 8/8] Bluetooth: Fix unnecessary list traversal in mgmt_pending_remove johan.hedberg
@ 2011-02-21 20:53 ` Gustavo F. Padovan
  8 siblings, 0 replies; 10+ messages in thread
From: Gustavo F. Padovan @ 2011-02-21 20:53 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth

Hi Johan,

* johan.hedberg@gmail.com <johan.hedberg@gmail.com> [2011-02-19 12:05:54 -0300]:

> Hi,
> 
> Here's a new set of patches for the Management interface. Combined with
> the latest user space git these patches enable both legacy and Secure
> Simple Pairing procedures. After these the only big missing feature in
> the management interface is device discovery which I'm just about to
> start working on.

All 8 patches are in my tree now, Thanks.

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

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

end of thread, other threads:[~2011-02-21 20:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-19 15:05 [PATCH 0/8] More Management interface patches johan.hedberg
2011-02-19 15:05 ` [PATCH 1/8] Bluetooth: Make pending_add return a pointer to the added entry johan.hedberg
2011-02-19 15:05 ` [PATCH 2/8] Bluetooth: Add mgmt_pair_device command johan.hedberg
2011-02-19 15:05 ` [PATCH 3/8] Bluetooth: Add management support for user confirmation request johan.hedberg
2011-02-19 15:05 ` [PATCH 4/8] Bluetooth: Fix mgmt_pin_code_reply command status opcode johan.hedberg
2011-02-19 15:05 ` [PATCH 5/8] Bluetooth: Fix mgmt_pin_code_reply return parameters johan.hedberg
2011-02-19 15:06 ` [PATCH 6/8] Bluetooth: Add mgmt_auth_failed event johan.hedberg
2011-02-19 15:06 ` [PATCH 7/8] Bluetooth: Fix inititial value for remote authentication requirements johan.hedberg
2011-02-19 15:06 ` [PATCH 8/8] Bluetooth: Fix unnecessary list traversal in mgmt_pending_remove johan.hedberg
2011-02-21 20:53 ` [PATCH 0/8] More Management interface patches 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