* [PATCH v2 1/7] Bluetooth: Fix doing some useless casts when receiving MGMT commands
2012-02-03 0:07 [PATCH v2 0/7] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
@ 2012-02-03 0:07 ` Vinicius Costa Gomes
2012-02-03 0:20 ` Marcel Holtmann
2012-02-03 0:08 ` [PATCH v2 2/7] Bluetooth: Add new structures for handling SMP Long Term Keys Vinicius Costa Gomes
` (6 subsequent siblings)
7 siblings, 1 reply; 12+ messages in thread
From: Vinicius Costa Gomes @ 2012-02-03 0:07 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
Every command handler of mgmt does a cast to the command structure
so it can properly interpreted. So we can avoid that cast if we
make those functions receive a void * directly.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
net/bluetooth/mgmt.c | 210 +++++++++++++++++++++-----------------------------
1 files changed, 88 insertions(+), 122 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 00ab083..f8720de 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -611,15 +611,13 @@ static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
return cmd_complete(sk, hdev->id, opcode, &settings, sizeof(settings));
}
-static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
+static int set_powered(struct sock *sk, u16 index, void *cp_data, u16 len)
{
- struct mgmt_mode *cp;
+ struct mgmt_mode *cp = cp_data;
struct hci_dev *hdev;
struct pending_cmd *cmd;
int err, up;
- cp = (void *) data;
-
BT_DBG("request for hci%u", index);
if (len != sizeof(*cp))
@@ -645,7 +643,7 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, cp_data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -664,17 +662,14 @@ failed:
return err;
}
-static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
- u16 len)
+static int set_discoverable(struct sock *sk, u16 index, void *cp_data, u16 len)
{
- struct mgmt_cp_set_discoverable *cp;
+ struct mgmt_cp_set_discoverable *cp = cp_data;
struct hci_dev *hdev;
struct pending_cmd *cmd;
u8 scan;
int err;
- cp = (void *) data;
-
BT_DBG("request for hci%u", index);
if (len != sizeof(*cp))
@@ -707,7 +702,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, cp_data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -734,17 +729,14 @@ failed:
return err;
}
-static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
- u16 len)
+static int set_connectable(struct sock *sk, u16 index, void *cp_data, u16 len)
{
- struct mgmt_mode *cp;
+ struct mgmt_mode *cp = cp_data;
struct hci_dev *hdev;
struct pending_cmd *cmd;
u8 scan;
int err;
- cp = (void *) data;
-
BT_DBG("request for hci%u", index);
if (len != sizeof(*cp))
@@ -776,7 +768,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, cp_data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -827,16 +819,13 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data,
return 0;
}
-static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
- u16 len)
+static int set_pairable(struct sock *sk, u16 index, void *cp_data, u16 len)
{
- struct mgmt_mode *cp;
+ struct mgmt_mode *cp = cp_data;
struct hci_dev *hdev;
__le32 ev;
int err;
- cp = (void *) data;
-
BT_DBG("request for hci%u", index);
if (len != sizeof(*cp))
@@ -870,15 +859,13 @@ failed:
return err;
}
-static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
+static int add_uuid(struct sock *sk, u16 index, void *cp_data, u16 len)
{
- struct mgmt_cp_add_uuid *cp;
+ struct mgmt_cp_add_uuid *cp = cp_data;
struct hci_dev *hdev;
struct bt_uuid *uuid;
int err;
- cp = (void *) data;
-
BT_DBG("request for hci%u", index);
if (len != sizeof(*cp))
@@ -920,16 +907,14 @@ failed:
return err;
}
-static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
+static int remove_uuid(struct sock *sk, u16 index, void *cp_data, u16 len)
{
+ struct mgmt_cp_remove_uuid *cp = cp_data;
struct list_head *p, *n;
- struct mgmt_cp_remove_uuid *cp;
struct hci_dev *hdev;
u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int err, found;
- cp = (void *) data;
-
BT_DBG("request for hci%u", index);
if (len != sizeof(*cp))
@@ -983,15 +968,12 @@ unlock:
return err;
}
-static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
- u16 len)
+static int set_dev_class(struct sock *sk, u16 index, void *cp_data, u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_set_dev_class *cp;
+ struct mgmt_cp_set_dev_class *cp = cp_data;
int err;
- cp = (void *) data;
-
BT_DBG("request for hci%u", index);
if (len != sizeof(*cp))
@@ -1026,16 +1008,13 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
return err;
}
-static int load_link_keys(struct sock *sk, u16 index, unsigned char *data,
- u16 len)
+static int load_link_keys(struct sock *sk, u16 index, void *cp_data, u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_load_link_keys *cp;
+ struct mgmt_cp_load_link_keys *cp = cp_data;
u16 key_count, expected_len;
int i;
- cp = (void *) data;
-
if (len < sizeof(*cp))
return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS,
MGMT_STATUS_INVALID_PARAMS);
@@ -1085,19 +1064,16 @@ static int load_link_keys(struct sock *sk, u16 index, unsigned char *data,
return 0;
}
-static int remove_keys(struct sock *sk, u16 index, unsigned char *data,
- u16 len)
+static int remove_keys(struct sock *sk, u16 index, void *cp_data, u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_remove_keys *cp;
+ struct mgmt_cp_remove_keys *cp = cp_data;
struct mgmt_rp_remove_keys rp;
struct hci_cp_disconnect dc;
struct pending_cmd *cmd;
struct hci_conn *conn;
int err;
- cp = (void *) data;
-
if (len != sizeof(*cp))
return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS,
MGMT_STATUS_INVALID_PARAMS);
@@ -1154,10 +1130,10 @@ unlock:
return err;
}
-static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
+static int disconnect(struct sock *sk, u16 index, void *cp_data, u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_disconnect *cp;
+ struct mgmt_cp_disconnect *cp = cp_data;
struct hci_cp_disconnect dc;
struct pending_cmd *cmd;
struct hci_conn *conn;
@@ -1165,8 +1141,6 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
BT_DBG("");
- cp = (void *) data;
-
if (len != sizeof(*cp))
return cmd_status(sk, index, MGMT_OP_DISCONNECT,
MGMT_STATUS_INVALID_PARAMS);
@@ -1200,7 +1174,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, cp_data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -1314,12 +1288,12 @@ static int send_pin_code_neg_reply(struct sock *sk, u16 index,
return err;
}
-static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
+static int pin_code_reply(struct sock *sk, u16 index, void *cp_data,
u16 len)
{
struct hci_dev *hdev;
struct hci_conn *conn;
- struct mgmt_cp_pin_code_reply *cp;
+ struct mgmt_cp_pin_code_reply *cp = cp_data;
struct mgmt_cp_pin_code_neg_reply ncp;
struct hci_cp_pin_code_reply reply;
struct pending_cmd *cmd;
@@ -1327,8 +1301,6 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
BT_DBG("");
- cp = (void *) data;
-
if (len != sizeof(*cp))
return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
MGMT_STATUS_INVALID_PARAMS);
@@ -1366,7 +1338,8 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, cp_data,
+ len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -1387,17 +1360,15 @@ failed:
return err;
}
-static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
+static int pin_code_neg_reply(struct sock *sk, u16 index, void *cp_data,
u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_pin_code_neg_reply *cp;
+ struct mgmt_cp_pin_code_neg_reply *cp = cp_data;
int err;
BT_DBG("");
- cp = (void *) data;
-
if (len != sizeof(*cp))
return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
MGMT_STATUS_INVALID_PARAMS);
@@ -1424,16 +1395,14 @@ failed:
return err;
}
-static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
+static int set_io_capability(struct sock *sk, u16 index, void *cp_data,
u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_set_io_capability *cp;
+ struct mgmt_cp_set_io_capability *cp = cp_data;
BT_DBG("");
- cp = (void *) data;
-
if (len != sizeof(*cp))
return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
MGMT_STATUS_INVALID_PARAMS);
@@ -1508,10 +1477,10 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
pairing_complete(cmd, status);
}
-static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
+static int pair_device(struct sock *sk, u16 index, void *cp_data, u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_pair_device *cp;
+ struct mgmt_cp_pair_device *cp = cp_data;
struct mgmt_rp_pair_device rp;
struct pending_cmd *cmd;
u8 sec_level, auth_type;
@@ -1520,8 +1489,6 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
BT_DBG("");
- cp = (void *) data;
-
if (len != sizeof(*cp))
return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
MGMT_STATUS_INVALID_PARAMS);
@@ -1565,7 +1532,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
goto unlock;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, cp_data, len);
if (!cmd) {
err = -ENOMEM;
hci_conn_put(conn);
@@ -1721,7 +1688,7 @@ done:
static int user_confirm_reply(struct sock *sk, u16 index, void *data, u16 len)
{
- struct mgmt_cp_user_confirm_reply *cp = (void *) data;
+ struct mgmt_cp_user_confirm_reply *cp = data;
BT_DBG("");
@@ -1752,7 +1719,7 @@ static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data,
static int user_passkey_reply(struct sock *sk, u16 index, void *data, u16 len)
{
- struct mgmt_cp_user_passkey_reply *cp = (void *) data;
+ struct mgmt_cp_user_passkey_reply *cp = data;
BT_DBG("");
@@ -1768,7 +1735,7 @@ static int user_passkey_reply(struct sock *sk, u16 index, void *data, u16 len)
static int user_passkey_neg_reply(struct sock *sk, u16 index, void *data,
u16 len)
{
- struct mgmt_cp_user_passkey_neg_reply *cp = (void *) data;
+ struct mgmt_cp_user_passkey_neg_reply *cp = data;
BT_DBG("");
@@ -1781,10 +1748,10 @@ static int user_passkey_neg_reply(struct sock *sk, u16 index, void *data,
HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
}
-static int set_local_name(struct sock *sk, u16 index, unsigned char *data,
+static int set_local_name(struct sock *sk, u16 index, void *cp_data,
u16 len)
{
- struct mgmt_cp_set_local_name *mgmt_cp = (void *) data;
+ struct mgmt_cp_set_local_name *mgmt_cp = cp_data;
struct hci_cp_write_local_name hci_cp;
struct hci_dev *hdev;
struct pending_cmd *cmd;
@@ -1803,7 +1770,8 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data,
hci_dev_lock(hdev);
- cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, cp_data,
+ len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -1872,11 +1840,11 @@ unlock:
return err;
}
-static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data,
- u16 len)
+static int add_remote_oob_data(struct sock *sk, u16 index, void *cp_data,
+ u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_add_remote_oob_data *cp = (void *) data;
+ struct mgmt_cp_add_remote_oob_data *cp = cp_data;
int err;
BT_DBG("hci%u ", index);
@@ -1908,10 +1876,10 @@ static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data,
}
static int remove_remote_oob_data(struct sock *sk, u16 index,
- unsigned char *data, u16 len)
+ void *cp_data, u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_remove_remote_oob_data *cp = (void *) data;
+ struct mgmt_cp_remove_remote_oob_data *cp = cp_data;
int err;
BT_DBG("hci%u ", index);
@@ -1942,9 +1910,9 @@ static int remove_remote_oob_data(struct sock *sk, u16 index,
}
static int start_discovery(struct sock *sk, u16 index,
- unsigned char *data, u16 len)
+ void *cp_data, u16 len)
{
- struct mgmt_cp_start_discovery *cp = (void *) data;
+ struct mgmt_cp_start_discovery *cp = cp_data;
struct pending_cmd *cmd;
struct hci_dev *hdev;
int err;
@@ -2054,10 +2022,10 @@ unlock:
return err;
}
-static int confirm_name(struct sock *sk, u16 index, unsigned char *data,
+static int confirm_name(struct sock *sk, u16 index, void *cp_data,
u16 len)
{
- struct mgmt_cp_confirm_name *cp = (void *) data;
+ struct mgmt_cp_confirm_name *cp = cp_data;
struct inquiry_entry *e;
struct hci_dev *hdev;
int err;
@@ -2104,11 +2072,11 @@ failed:
return err;
}
-static int block_device(struct sock *sk, u16 index, unsigned char *data,
+static int block_device(struct sock *sk, u16 index, void *cp_data,
u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_block_device *cp = (void *) data;
+ struct mgmt_cp_block_device *cp = cp_data;
int err;
BT_DBG("hci%u", index);
@@ -2138,11 +2106,10 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data,
return err;
}
-static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
- u16 len)
+static int unblock_device(struct sock *sk, u16 index, void *cp_data, u16 len)
{
struct hci_dev *hdev;
- struct mgmt_cp_unblock_device *cp = (void *) data;
+ struct mgmt_cp_unblock_device *cp = cp_data;
int err;
BT_DBG("hci%u", index);
@@ -2174,10 +2141,10 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
}
static int set_fast_connectable(struct sock *sk, u16 index,
- unsigned char *data, u16 len)
+ void *cp_data, u16 len)
{
struct hci_dev *hdev;
- struct mgmt_mode *cp = (void *) data;
+ struct mgmt_mode *cp = cp_data;
struct hci_cp_write_page_scan_activity acp;
u8 type;
int err;
@@ -2231,7 +2198,8 @@ done:
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
- unsigned char *buf;
+ void *buf;
+ u8 *cp;
struct mgmt_hdr *hdr;
u16 opcode, index, len;
int err;
@@ -2250,7 +2218,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
goto done;
}
- hdr = (struct mgmt_hdr *) buf;
+ hdr = buf;
opcode = get_unaligned_le16(&hdr->opcode);
index = get_unaligned_le16(&hdr->index);
len = get_unaligned_le16(&hdr->len);
@@ -2260,6 +2228,8 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
goto done;
}
+ cp = buf + sizeof(*hdr);
+
switch (opcode) {
case MGMT_OP_READ_VERSION:
err = read_version(sk);
@@ -2271,98 +2241,94 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
err = read_controller_info(sk, index);
break;
case MGMT_OP_SET_POWERED:
- err = set_powered(sk, index, buf + sizeof(*hdr), len);
+ err = set_powered(sk, index, cp, len);
break;
case MGMT_OP_SET_DISCOVERABLE:
- err = set_discoverable(sk, index, buf + sizeof(*hdr), len);
+ err = set_discoverable(sk, index, cp, len);
break;
case MGMT_OP_SET_CONNECTABLE:
- err = set_connectable(sk, index, buf + sizeof(*hdr), len);
+ err = set_connectable(sk, index, cp, len);
break;
case MGMT_OP_SET_FAST_CONNECTABLE:
- err = set_fast_connectable(sk, index, buf + sizeof(*hdr),
- len);
+ err = set_fast_connectable(sk, index, cp, len);
break;
case MGMT_OP_SET_PAIRABLE:
- err = set_pairable(sk, index, buf + sizeof(*hdr), len);
+ err = set_pairable(sk, index, cp, len);
break;
case MGMT_OP_ADD_UUID:
- err = add_uuid(sk, index, buf + sizeof(*hdr), len);
+ err = add_uuid(sk, index, cp, len);
break;
case MGMT_OP_REMOVE_UUID:
- err = remove_uuid(sk, index, buf + sizeof(*hdr), len);
+ err = remove_uuid(sk, index, cp, len);
break;
case MGMT_OP_SET_DEV_CLASS:
- err = set_dev_class(sk, index, buf + sizeof(*hdr), len);
+ err = set_dev_class(sk, index, cp, len);
break;
case MGMT_OP_LOAD_LINK_KEYS:
- err = load_link_keys(sk, index, buf + sizeof(*hdr), len);
+ err = load_link_keys(sk, index, cp, len);
break;
case MGMT_OP_REMOVE_KEYS:
- err = remove_keys(sk, index, buf + sizeof(*hdr), len);
+ err = remove_keys(sk, index, cp, len);
break;
case MGMT_OP_DISCONNECT:
- err = disconnect(sk, index, buf + sizeof(*hdr), len);
+ err = disconnect(sk, index, cp, len);
break;
case MGMT_OP_GET_CONNECTIONS:
err = get_connections(sk, index);
break;
case MGMT_OP_PIN_CODE_REPLY:
- err = pin_code_reply(sk, index, buf + sizeof(*hdr), len);
+ err = pin_code_reply(sk, index, cp, len);
break;
case MGMT_OP_PIN_CODE_NEG_REPLY:
- err = pin_code_neg_reply(sk, index, buf + sizeof(*hdr), len);
+ err = pin_code_neg_reply(sk, index, cp, len);
break;
case MGMT_OP_SET_IO_CAPABILITY:
- err = set_io_capability(sk, index, buf + sizeof(*hdr), len);
+ err = set_io_capability(sk, index, cp, len);
break;
case MGMT_OP_PAIR_DEVICE:
- err = pair_device(sk, index, buf + sizeof(*hdr), len);
+ err = pair_device(sk, index, cp, len);
break;
case MGMT_OP_CANCEL_PAIR_DEVICE:
err = cancel_pair_device(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_USER_CONFIRM_REPLY:
- err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len);
+ err = user_confirm_reply(sk, index, cp, len);
break;
case MGMT_OP_USER_CONFIRM_NEG_REPLY:
- err = user_confirm_neg_reply(sk, index, buf + sizeof(*hdr),
- len);
+ err = user_confirm_neg_reply(sk, index, cp, len);
break;
case MGMT_OP_USER_PASSKEY_REPLY:
- err = user_passkey_reply(sk, index, buf + sizeof(*hdr), len);
+ err = user_passkey_reply(sk, index, cp, len);
break;
case MGMT_OP_USER_PASSKEY_NEG_REPLY:
- err = user_passkey_neg_reply(sk, index, buf + sizeof(*hdr),
- len);
+ err = user_passkey_neg_reply(sk, index, cp, len);
break;
case MGMT_OP_SET_LOCAL_NAME:
- err = set_local_name(sk, index, buf + sizeof(*hdr), len);
+ err = set_local_name(sk, index, cp, len);
break;
case MGMT_OP_READ_LOCAL_OOB_DATA:
err = read_local_oob_data(sk, index);
break;
case MGMT_OP_ADD_REMOTE_OOB_DATA:
- err = add_remote_oob_data(sk, index, buf + sizeof(*hdr), len);
+ err = add_remote_oob_data(sk, index, cp, len);
break;
case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
- err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
- len);
+ err = remove_remote_oob_data(sk, index, cp, len);
break;
case MGMT_OP_START_DISCOVERY:
- err = start_discovery(sk, index, buf + sizeof(*hdr), len);
+ err = start_discovery(sk, index, cp, len);
break;
case MGMT_OP_STOP_DISCOVERY:
err = stop_discovery(sk, index);
break;
case MGMT_OP_CONFIRM_NAME:
- err = confirm_name(sk, index, buf + sizeof(*hdr), len);
+ err = confirm_name(sk, index, cp, len);
break;
case MGMT_OP_BLOCK_DEVICE:
- err = block_device(sk, index, buf + sizeof(*hdr), len);
+ err = block_device(sk, index, cp, len);
break;
case MGMT_OP_UNBLOCK_DEVICE:
- err = unblock_device(sk, index, buf + sizeof(*hdr), len);
+ err = unblock_device(sk, index, cp, len);
break;
default:
BT_DBG("Unknown op %u", opcode);
--
1.7.8.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH v2 3/7] Bluetooth: Use the updated key structures for handling LTKs
2012-02-03 0:07 [PATCH v2 0/7] New MGMT messages for SMP Long Term Keys Vinicius Costa Gomes
2012-02-03 0:07 ` [PATCH v2 1/7] Bluetooth: Fix doing some useless casts when receiving MGMT commands Vinicius Costa Gomes
2012-02-03 0:08 ` [PATCH v2 2/7] Bluetooth: Add new structures for handling SMP Long Term Keys Vinicius Costa Gomes
@ 2012-02-03 0:08 ` Vinicius Costa Gomes
2012-02-03 0:23 ` Marcel Holtmann
2012-02-03 0:08 ` [PATCH v2 4/7] Bluetooth: Add MGMT handlers for dealing with SMP LTK's Vinicius Costa Gomes
` (4 subsequent siblings)
7 siblings, 1 reply; 12+ messages in thread
From: Vinicius Costa Gomes @ 2012-02-03 0:08 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
This updates all the users of the older way, that was using the
link_keys list to store the SMP keys, to use the new way.
This includes defining new types for the keys, we have a type for each
combination of STK/LTK and Master/Slave.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 11 +++--
net/bluetooth/hci_core.c | 76 ++++++++++++++++---------------------
net/bluetooth/hci_event.c | 11 ++++-
net/bluetooth/smp.c | 38 +++++++++++-------
4 files changed, 71 insertions(+), 65 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c998176..3f22f03 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -658,12 +658,13 @@ int hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type);
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+ int new_key, u8 authenticated, u8 tk[16],
+ u8 enc_size, u16 ediv, u8 rand[8]);
+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 addr_type);
int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
int hci_smp_ltks_clear(struct hci_dev *hdev);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a28e637..ff519b5 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1222,41 +1222,35 @@ static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
return 0;
}
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
{
- struct link_key *k;
-
- list_for_each_entry(k, &hdev->link_keys, list) {
- struct key_master_id *id;
+ struct smp_ltk *k;
- if (k->type != HCI_LK_SMP_LTK)
+ list_for_each_entry(k, &hdev->long_term_keys, list) {
+ if (k->ediv != ediv ||
+ memcmp(rand, k->rand, sizeof(k->rand)))
continue;
- if (k->dlen != sizeof(*id))
- continue;
-
- id = (void *) &k->data;
- if (id->ediv == ediv &&
- (memcmp(rand, id->rand, sizeof(id->rand)) == 0))
- return k;
+ return k;
}
return NULL;
}
EXPORT_SYMBOL(hci_find_ltk);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type)
+struct smp_ltk *hci_find_ltk_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 addr_type)
{
- struct link_key *k;
+ struct smp_ltk *k;
- list_for_each_entry(k, &hdev->link_keys, list)
- if (k->type == type && bacmp(bdaddr, &k->bdaddr) == 0)
+ list_for_each_entry(k, &hdev->long_term_keys, list)
+ if (addr_type == k->bdaddr_type &&
+ bacmp(bdaddr, &k->bdaddr) == 0)
return k;
return NULL;
}
-EXPORT_SYMBOL(hci_find_link_key_type);
+EXPORT_SYMBOL(hci_find_ltk_addr);
int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
@@ -1313,40 +1307,36 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
return 0;
}
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16])
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+ int new_key, u8 authenticated, u8 tk[16],
+ u8 enc_size, u16 ediv, u8 rand[8])
{
- struct link_key *key, *old_key;
- struct key_master_id *id;
- u8 old_key_type;
+ struct smp_ltk *key, *old_key;
- BT_DBG("%s addr %s", hdev->name, batostr(bdaddr));
+ if (!(type & HCI_SMP_STK) && !(type & HCI_SMP_LTK))
+ return 0;
- old_key = hci_find_link_key_type(hdev, bdaddr, HCI_LK_SMP_LTK);
- if (old_key) {
+ old_key = hci_find_ltk_addr(hdev, bdaddr, addr_type);
+ if (old_key)
key = old_key;
- old_key_type = old_key->type;
- } else {
- key = kzalloc(sizeof(*key) + sizeof(*id), GFP_ATOMIC);
+ else {
+ key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
- list_add(&key->list, &hdev->link_keys);
- old_key_type = 0xff;
+ list_add(&key->list, &hdev->long_term_keys);
}
- key->dlen = sizeof(*id);
-
bacpy(&key->bdaddr, bdaddr);
- memcpy(key->val, ltk, sizeof(key->val));
- key->type = HCI_LK_SMP_LTK;
- key->pin_len = key_size;
-
- id = (void *) &key->data;
- id->ediv = ediv;
- memcpy(id->rand, rand, sizeof(id->rand));
+ key->bdaddr_type = addr_type;
+ memcpy(key->val, tk, sizeof(key->val));
+ key->authenticated = authenticated;
+ key->ediv = ediv;
+ key->enc_size = enc_size;
+ key->type = type;
+ memcpy(key->rand, rand, sizeof(key->rand));
- if (new_key)
- mgmt_new_link_key(hdev, key, old_key_type);
+ if (!new_key)
+ return 0;
return 0;
}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index a86f82b..23dbb31 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3256,7 +3256,7 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
struct hci_cp_le_ltk_reply cp;
struct hci_cp_le_ltk_neg_reply neg;
struct hci_conn *conn;
- struct link_key *ltk;
+ struct smp_ltk *ltk;
BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
@@ -3272,10 +3272,17 @@ static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
cp.handle = cpu_to_le16(conn->handle);
- conn->pin_length = ltk->pin_len;
+
+ if (ltk->authenticated)
+ conn->sec_level = BT_SECURITY_HIGH;
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
+ if (ltk->type & HCI_SMP_STK) {
+ list_del(<k->list);
+ kfree(ltk);
+ }
+
hci_dev_unlock(hdev);
return;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 9ff56e1..19d1371 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -475,8 +475,9 @@ static void random_work(struct work_struct *work)
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
- hci_add_ltk(hcon->hdev, 0, conn->dst, smp->enc_key_size,
- ediv, rand, stk);
+ hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_STK_SLAVE, 0, 0, stk,
+ smp->enc_key_size, ediv, rand);
}
return;
@@ -701,22 +702,18 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
static u8 smp_ltk_encrypt(struct l2cap_conn *conn)
{
- struct link_key *key;
- struct key_master_id *master;
+ struct smp_ltk *key;
struct hci_conn *hcon = conn->hcon;
- key = hci_find_link_key_type(hcon->hdev, conn->dst,
- HCI_LK_SMP_LTK);
+ key = hci_find_ltk_addr(hcon->hdev, conn->dst, hcon->dst_type);
if (!key)
return 0;
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags))
return 1;
- master = (void *) key->data;
- hci_le_start_enc(hcon, master->ediv, master->rand,
- key->val);
- hcon->enc_key_size = key->pin_len;
+ hci_le_start_enc(hcon, key->ediv, key->rand, key->val);
+ hcon->enc_key_size = key->enc_size;
return 1;
@@ -819,13 +816,19 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_master_ident *rp = (void *) skb->data;
struct smp_chan *smp = conn->smp_chan;
+ struct hci_dev *hdev = conn->hcon->hdev;
+ struct hci_conn *hcon = conn->hcon;
+ u8 authenticated;
skb_pull(skb, sizeof(*rp));
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
- rp->ediv, rp->rand, smp->tk);
-
+ hci_dev_lock(hdev);
+ authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH);
+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_LTK, 1, authenticated, smp->tk,
+ smp->enc_key_size, rp->ediv, rp->rand);
smp_distribute_keys(conn, 1);
+ hci_dev_unlock(hdev);
return 0;
}
@@ -935,6 +938,8 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
if (*keydist & SMP_DIST_ENC_KEY) {
struct smp_cmd_encrypt_info enc;
struct smp_cmd_master_ident ident;
+ struct hci_conn *hcon = conn->hcon;
+ u8 authenticated;
__le16 ediv;
get_random_bytes(enc.ltk, sizeof(enc.ltk));
@@ -943,8 +948,11 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);
- hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->enc_key_size,
- ediv, ident.rand, enc.ltk);
+ authenticated = hcon->sec_level == BT_SECURITY_HIGH;
+ hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type,
+ HCI_SMP_LTK_SLAVE, 1, authenticated,
+ enc.ltk, smp->enc_key_size,
+ ediv, ident.rand);
ident.ediv = cpu_to_le16(ediv);
--
1.7.8.1
^ permalink raw reply related [flat|nested] 12+ messages in thread