* [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