summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/mgmt.h8
-rw-r--r--net/bluetooth/mgmt.c107
2 files changed, 56 insertions, 59 deletions
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 36e68b4551af..7e3d38bfaec3 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -184,7 +184,6 @@ struct mgmt_cp_disconnect {
} __packed;
struct mgmt_rp_disconnect {
struct mgmt_addr_info addr;
- __u8 status;
} __packed;
#define MGMT_OP_GET_CONNECTIONS 0x0015
@@ -201,7 +200,6 @@ struct mgmt_cp_pin_code_reply {
} __packed;
struct mgmt_rp_pin_code_reply {
struct mgmt_addr_info addr;
- uint8_t status;
} __packed;
#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0017
@@ -221,7 +219,6 @@ struct mgmt_cp_pair_device {
} __packed;
struct mgmt_rp_pair_device {
struct mgmt_addr_info addr;
- __u8 status;
} __packed;
#define MGMT_OP_CANCEL_PAIR_DEVICE 0x001A
@@ -233,7 +230,6 @@ struct mgmt_cp_unpair_device {
} __packed;
struct mgmt_rp_unpair_device {
struct mgmt_addr_info addr;
- __u8 status;
};
#define MGMT_OP_USER_CONFIRM_REPLY 0x001C
@@ -242,7 +238,6 @@ struct mgmt_cp_user_confirm_reply {
} __packed;
struct mgmt_rp_user_confirm_reply {
struct mgmt_addr_info addr;
- __u8 status;
} __packed;
#define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x001D
@@ -257,7 +252,6 @@ struct mgmt_cp_user_passkey_reply {
} __packed;
struct mgmt_rp_user_passkey_reply {
struct mgmt_addr_info addr;
- __u8 status;
} __packed;
#define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x001F
@@ -297,7 +291,6 @@ struct mgmt_cp_confirm_name {
} __packed;
struct mgmt_rp_confirm_name {
struct mgmt_addr_info addr;
- __u8 status;
} __packed;
#define MGMT_OP_BLOCK_DEVICE 0x0026
@@ -313,6 +306,7 @@ struct mgmt_cp_unblock_device {
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
+ __u8 status;
__u8 data[0];
} __packed;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 89754bbcd02b..61d0250bd77e 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -227,8 +227,8 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
return err;
}
-static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp,
- size_t rp_len)
+static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
+ void *rp, size_t rp_len)
{
struct sk_buff *skb;
struct mgmt_hdr *hdr;
@@ -249,6 +249,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp,
ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
put_unaligned_le16(cmd, &ev->opcode);
+ ev->status = status;
if (rp)
memcpy(ev->data, rp, rp_len);
@@ -269,7 +270,7 @@ static int read_version(struct sock *sk)
rp.version = MGMT_VERSION;
put_unaligned_le16(MGMT_REVISION, &rp.revision);
- return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, &rp,
+ return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, &rp,
sizeof(rp));
}
@@ -299,7 +300,7 @@ static int read_commands(struct sock *sk)
for (i = 0; i < num_events; i++, opcode++)
put_unaligned_le16(mgmt_events[i], opcode);
- err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, rp,
+ err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, 0, rp,
rp_size);
kfree(rp);
@@ -347,7 +348,7 @@ static int read_index_list(struct sock *sk)
read_unlock(&hci_dev_list_lock);
- err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, rp,
+ err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,
rp_len);
kfree(rp);
@@ -637,7 +638,7 @@ static int read_controller_info(struct sock *sk, u16 index)
hci_dev_unlock(hdev);
hci_dev_put(hdev);
- return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp));
+ return cmd_complete(sk, index, MGMT_OP_READ_INFO, 0, &rp, sizeof(rp));
}
static void mgmt_pending_free(struct pending_cmd *cmd)
@@ -717,7 +718,8 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
{
__le32 settings = cpu_to_le32(get_current_settings(hdev));
- return cmd_complete(sk, hdev->id, opcode, &settings, sizeof(settings));
+ return cmd_complete(sk, hdev->id, opcode, 0, &settings,
+ sizeof(settings));
}
static int set_powered(struct sock *sk, u16 index, void *data, u16 len)
@@ -1124,7 +1126,7 @@ static int add_uuid(struct sock *sk, u16 index, void *data, u16 len)
if (err < 0)
goto failed;
- err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0);
+ err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, 0, NULL, 0);
failed:
hci_dev_unlock(hdev);
@@ -1185,7 +1187,7 @@ static int remove_uuid(struct sock *sk, u16 index, void *data, u16 len)
if (err < 0)
goto unlock;
- err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
+ err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, 0, NULL, 0);
unlock:
hci_dev_unlock(hdev);
@@ -1226,7 +1228,8 @@ static int set_dev_class(struct sock *sk, u16 index, void *data, u16 len)
err = update_class(hdev);
if (err == 0)
- err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0);
+ err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, 0,
+ NULL, 0);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
@@ -1282,7 +1285,7 @@ static int load_link_keys(struct sock *sk, u16 index, void *data, u16 len)
key->type, key->pin_len);
}
- cmd_complete(sk, index, MGMT_OP_LOAD_LINK_KEYS, NULL, 0);
+ cmd_complete(sk, index, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
@@ -1310,6 +1313,7 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len)
struct hci_cp_disconnect dc;
struct pending_cmd *cmd;
struct hci_conn *conn;
+ u8 status = 0;
int err;
if (len != sizeof(*cp))
@@ -1333,13 +1337,13 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len)
err = hci_remove_ltk(hdev, &cp->addr.bdaddr);
if (err < 0) {
- rp.status = MGMT_STATUS_NOT_PAIRED;
+ status = MGMT_STATUS_NOT_PAIRED;
goto unlock;
}
if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect) {
- err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, &rp,
- sizeof(rp));
+ err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, status,
+ &rp, sizeof(rp));
device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk);
goto unlock;
}
@@ -1352,8 +1356,8 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len)
&cp->addr.bdaddr);
if (!conn) {
- err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, &rp,
- sizeof(rp));
+ err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, status,
+ &rp, sizeof(rp));
device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk);
goto unlock;
}
@@ -1373,8 +1377,8 @@ static int unpair_device(struct sock *sk, u16 index, void *data, u16 len)
unlock:
if (err < 0)
- err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, &rp,
- sizeof(rp));
+ err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, status,
+ &rp, sizeof(rp));
hci_dev_unlock(hdev);
hci_dev_put(hdev);
@@ -1512,7 +1516,7 @@ static int get_connections(struct sock *sk, u16 index)
/* Recalculate length in case of filtered SCO connections, etc */
rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
- err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
+ err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, 0, rp, rp_len);
unlock:
kfree(rp);
@@ -1672,7 +1676,7 @@ static int set_io_capability(struct sock *sk, u16 index, void *data, u16 len)
hci_dev_unlock(hdev);
hci_dev_put(hdev);
- return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
+ return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, 0, NULL, 0);
}
static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
@@ -1700,9 +1704,9 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
bacpy(&rp.addr.bdaddr, &conn->dst);
rp.addr.type = link_to_mgmt(conn->type, conn->dst_type);
- rp.status = status;
- cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
+ cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status,
+ &rp, sizeof(rp));
/* So we don't get further callbacks for this connection */
conn->connect_cfm_cb = NULL;
@@ -1735,6 +1739,7 @@ static int pair_device(struct sock *sk, u16 index, void *data, u16 len)
struct pending_cmd *cmd;
u8 sec_level, auth_type;
struct hci_conn *conn;
+ u8 status = 0;
int err;
BT_DBG("");
@@ -1768,16 +1773,16 @@ static int pair_device(struct sock *sk, u16 index, void *data, u16 len)
rp.addr.type = cp->addr.type;
if (IS_ERR(conn)) {
- rp.status = -PTR_ERR(conn);
- err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
+ status = -PTR_ERR(conn);
+ err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE, status,
&rp, sizeof(rp));
goto unlock;
}
if (conn->connect_cfm_cb) {
hci_conn_put(conn);
- rp.status = EBUSY;
- err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
+ status = EBUSY;
+ err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE, status,
&rp, sizeof(rp));
goto unlock;
}
@@ -1850,7 +1855,7 @@ static int cancel_pair_device(struct sock *sk, u16 index,
pairing_complete(cmd, MGMT_STATUS_CANCELLED);
- err = cmd_complete(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, addr,
+ err = cmd_complete(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, 0, addr,
sizeof(*addr));
unlock:
hci_dev_unlock(hdev);
@@ -2112,8 +2117,8 @@ static int add_remote_oob_data(struct sock *sk, u16 index, void *data,
err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
MGMT_STATUS_FAILED);
else
- err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
- 0);
+ err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, 0,
+ NULL, 0);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
@@ -2147,7 +2152,7 @@ static int remove_remote_oob_data(struct sock *sk, u16 index,
MGMT_STATUS_INVALID_PARAMS);
else
err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
- NULL, 0);
+ 0, NULL, 0);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
@@ -2307,7 +2312,8 @@ static int stop_discovery(struct sock *sk, u16 index)
e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_PENDING);
if (!e) {
mgmt_pending_remove(cmd);
- err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, NULL, 0);
+ err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, 0,
+ NULL, 0);
hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
goto unlock;
}
@@ -2400,8 +2406,8 @@ static int block_device(struct sock *sk, u16 index, void *data, u16 len)
err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
MGMT_STATUS_FAILED);
else
- err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
- NULL, 0);
+ err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, 0,
+ NULL, 0);
hci_dev_unlock(hdev);
hci_dev_put(hdev);
@@ -2434,7 +2440,7 @@ static int unblock_device(struct sock *sk, u16 index, void *data, u16 len)
err = cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
MGMT_STATUS_INVALID_PARAMS);
else
- err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
+ err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, 0,
NULL, 0);
hci_dev_unlock(hdev);
@@ -2490,8 +2496,8 @@ static int set_fast_connectable(struct sock *sk, u16 index,
goto done;
}
- err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
- NULL, 0);
+ err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, 0,
+ NULL, 0);
done:
hci_dev_unlock(hdev);
hci_dev_put(hdev);
@@ -2908,9 +2914,9 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
rp.addr.type = cp->addr.type;
- rp.status = 0;
- cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
+ cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, 0, &rp,
+ sizeof(rp));
*sk = cmd->sk;
sock_hold(*sk);
@@ -2930,7 +2936,7 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
- cmd_complete(cmd->sk, cmd->index, cmd->opcode, &rp, sizeof(rp));
+ cmd_complete(cmd->sk, cmd->index, cmd->opcode, 0, &rp, sizeof(rp));
mgmt_pending_remove(cmd);
}
@@ -2972,10 +2978,9 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
bacpy(&rp.addr.bdaddr, bdaddr);
rp.addr.type = link_to_mgmt(link_type, addr_type);
- rp.status = mgmt_status(status);
err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
- &rp, sizeof(rp));
+ mgmt_status(status), &rp, sizeof(rp));
mgmt_pending_remove(cmd);
@@ -3021,10 +3026,9 @@ int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
bacpy(&rp.addr.bdaddr, bdaddr);
rp.addr.type = MGMT_ADDR_BREDR;
- rp.status = mgmt_status(status);
- err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, &rp,
- sizeof(rp));
+ err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
+ mgmt_status(status), &rp, sizeof(rp));
mgmt_pending_remove(cmd);
@@ -3044,10 +3048,9 @@ int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
bacpy(&rp.addr.bdaddr, bdaddr);
rp.addr.type = MGMT_ADDR_BREDR;
- rp.status = mgmt_status(status);
- err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, &rp,
- sizeof(rp));
+ err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY,
+ mgmt_status(status), &rp, sizeof(rp));
mgmt_pending_remove(cmd);
@@ -3099,8 +3102,8 @@ static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
bacpy(&rp.addr.bdaddr, bdaddr);
rp.addr.type = link_to_mgmt(link_type, addr_type);
- rp.status = mgmt_status(status);
- err = cmd_complete(cmd->sk, hdev->id, opcode, &rp, sizeof(rp));
+ err = cmd_complete(cmd->sk, hdev->id, opcode, mgmt_status(status),
+ &rp, sizeof(rp));
mgmt_pending_remove(cmd);
@@ -3217,7 +3220,7 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
update_eir(hdev);
- err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev,
+ err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, &ev,
sizeof(ev));
if (err < 0)
goto failed;
@@ -3256,7 +3259,7 @@ int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
err = cmd_complete(cmd->sk, hdev->id,
MGMT_OP_READ_LOCAL_OOB_DATA,
- &rp, sizeof(rp));
+ 0, &rp, sizeof(rp));
}
mgmt_pending_remove(cmd);
@@ -3365,7 +3368,7 @@ int mgmt_discovering(struct hci_dev *hdev, u8 discovering)
cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
if (cmd != NULL) {
- cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0);
+ cmd_complete(cmd->sk, hdev->id, cmd->opcode, 0, NULL, 0);
mgmt_pending_remove(cmd);
}