Commit 4d9b9528 authored by Daniel Winkler's avatar Daniel Winkler Committed by Johan Hedberg

Bluetooth: Change MGMT security info CMD to be more generic

For advertising, we wish to know the LE tx power capabilities of the
controller in userspace, so this patch edits the Security Info MGMT
command to be more generic, such that other various controller
capabilities can be included in the EIR data. This change also includes
the LE min and max tx power into this newly-named command.

The change was tested by manually verifying that the MGMT command
returns the tx power range as expected in userspace.
Reviewed-by: default avatarSonny Sasaka <sonnysasaka@chromium.org>
Signed-off-by: default avatarDaniel Winkler <danielwinkler@google.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
parent 7c395ea5
...@@ -686,11 +686,16 @@ struct mgmt_cp_set_blocked_keys { ...@@ -686,11 +686,16 @@ struct mgmt_cp_set_blocked_keys {
#define MGMT_OP_SET_WIDEBAND_SPEECH 0x0047 #define MGMT_OP_SET_WIDEBAND_SPEECH 0x0047
#define MGMT_OP_READ_SECURITY_INFO 0x0048 #define MGMT_CAP_SEC_FLAGS 0x01
#define MGMT_READ_SECURITY_INFO_SIZE 0 #define MGMT_CAP_MAX_ENC_KEY_SIZE 0x02
struct mgmt_rp_read_security_info { #define MGMT_CAP_SMP_MAX_ENC_KEY_SIZE 0x03
__le16 sec_len; #define MGMT_CAP_LE_TX_PWR 0x04
__u8 sec[];
#define MGMT_OP_READ_CONTROLLER_CAP 0x0048
#define MGMT_READ_CONTROLLER_CAP_SIZE 0
struct mgmt_rp_read_controller_cap {
__le16 cap_len;
__u8 cap[0];
} __packed; } __packed;
#define MGMT_OP_READ_EXP_FEATURES_INFO 0x0049 #define MGMT_OP_READ_EXP_FEATURES_INFO 0x0049
......
...@@ -110,7 +110,7 @@ static const u16 mgmt_commands[] = { ...@@ -110,7 +110,7 @@ static const u16 mgmt_commands[] = {
MGMT_OP_SET_APPEARANCE, MGMT_OP_SET_APPEARANCE,
MGMT_OP_SET_BLOCKED_KEYS, MGMT_OP_SET_BLOCKED_KEYS,
MGMT_OP_SET_WIDEBAND_SPEECH, MGMT_OP_SET_WIDEBAND_SPEECH,
MGMT_OP_READ_SECURITY_INFO, MGMT_OP_READ_CONTROLLER_CAP,
MGMT_OP_READ_EXP_FEATURES_INFO, MGMT_OP_READ_EXP_FEATURES_INFO,
MGMT_OP_SET_EXP_FEATURE, MGMT_OP_SET_EXP_FEATURE,
MGMT_OP_READ_DEF_SYSTEM_CONFIG, MGMT_OP_READ_DEF_SYSTEM_CONFIG,
...@@ -176,7 +176,7 @@ static const u16 mgmt_untrusted_commands[] = { ...@@ -176,7 +176,7 @@ static const u16 mgmt_untrusted_commands[] = {
MGMT_OP_READ_CONFIG_INFO, MGMT_OP_READ_CONFIG_INFO,
MGMT_OP_READ_EXT_INDEX_LIST, MGMT_OP_READ_EXT_INDEX_LIST,
MGMT_OP_READ_EXT_INFO, MGMT_OP_READ_EXT_INFO,
MGMT_OP_READ_SECURITY_INFO, MGMT_OP_READ_CONTROLLER_CAP,
MGMT_OP_READ_EXP_FEATURES_INFO, MGMT_OP_READ_EXP_FEATURES_INFO,
MGMT_OP_READ_DEF_SYSTEM_CONFIG, MGMT_OP_READ_DEF_SYSTEM_CONFIG,
MGMT_OP_READ_DEF_RUNTIME_CONFIG, MGMT_OP_READ_DEF_RUNTIME_CONFIG,
...@@ -3710,13 +3710,14 @@ static int set_wideband_speech(struct sock *sk, struct hci_dev *hdev, ...@@ -3710,13 +3710,14 @@ static int set_wideband_speech(struct sock *sk, struct hci_dev *hdev,
return err; return err;
} }
static int read_security_info(struct sock *sk, struct hci_dev *hdev, static int read_controller_cap(struct sock *sk, struct hci_dev *hdev,
void *data, u16 data_len) void *data, u16 data_len)
{ {
char buf[16]; char buf[20];
struct mgmt_rp_read_security_info *rp = (void *)buf; struct mgmt_rp_read_controller_cap *rp = (void *)buf;
u16 sec_len = 0; u16 cap_len = 0;
u8 flags = 0; u8 flags = 0;
u8 tx_power_range[2];
bt_dev_dbg(hdev, "sock %p", sk); bt_dev_dbg(hdev, "sock %p", sk);
...@@ -3740,23 +3741,37 @@ static int read_security_info(struct sock *sk, struct hci_dev *hdev, ...@@ -3740,23 +3741,37 @@ static int read_security_info(struct sock *sk, struct hci_dev *hdev,
flags |= 0x08; /* Encryption key size enforcement (LE) */ flags |= 0x08; /* Encryption key size enforcement (LE) */
sec_len = eir_append_data(rp->sec, sec_len, 0x01, &flags, 1); cap_len = eir_append_data(rp->cap, cap_len, MGMT_CAP_SEC_FLAGS,
&flags, 1);
/* When the Read Simple Pairing Options command is supported, then /* When the Read Simple Pairing Options command is supported, then
* also max encryption key size information is provided. * also max encryption key size information is provided.
*/ */
if (hdev->commands[41] & 0x08) if (hdev->commands[41] & 0x08)
sec_len = eir_append_le16(rp->sec, sec_len, 0x02, cap_len = eir_append_le16(rp->cap, cap_len,
MGMT_CAP_MAX_ENC_KEY_SIZE,
hdev->max_enc_key_size); hdev->max_enc_key_size);
sec_len = eir_append_le16(rp->sec, sec_len, 0x03, SMP_MAX_ENC_KEY_SIZE); cap_len = eir_append_le16(rp->cap, cap_len,
MGMT_CAP_SMP_MAX_ENC_KEY_SIZE,
SMP_MAX_ENC_KEY_SIZE);
rp->sec_len = cpu_to_le16(sec_len); /* Append the min/max LE tx power parameters if we were able to fetch
* it from the controller
*/
if (hdev->commands[38] & 0x80) {
memcpy(&tx_power_range[0], &hdev->min_le_tx_power, 1);
memcpy(&tx_power_range[1], &hdev->max_le_tx_power, 1);
cap_len = eir_append_data(rp->cap, cap_len, MGMT_CAP_LE_TX_PWR,
tx_power_range, 2);
}
rp->cap_len = cpu_to_le16(cap_len);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_SECURITY_INFO, 0, return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_READ_CONTROLLER_CAP, 0,
rp, sizeof(*rp) + sec_len); rp, sizeof(*rp) + cap_len);
} }
#ifdef CONFIG_BT_FEATURE_DEBUG #ifdef CONFIG_BT_FEATURE_DEBUG
...@@ -8193,7 +8208,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = { ...@@ -8193,7 +8208,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
{ set_blocked_keys, MGMT_OP_SET_BLOCKED_KEYS_SIZE, { set_blocked_keys, MGMT_OP_SET_BLOCKED_KEYS_SIZE,
HCI_MGMT_VAR_LEN }, HCI_MGMT_VAR_LEN },
{ set_wideband_speech, MGMT_SETTING_SIZE }, { set_wideband_speech, MGMT_SETTING_SIZE },
{ read_security_info, MGMT_READ_SECURITY_INFO_SIZE, { read_controller_cap, MGMT_READ_CONTROLLER_CAP_SIZE,
HCI_MGMT_UNTRUSTED }, HCI_MGMT_UNTRUSTED },
{ read_exp_features_info, MGMT_READ_EXP_FEATURES_INFO_SIZE, { read_exp_features_info, MGMT_READ_EXP_FEATURES_INFO_SIZE,
HCI_MGMT_UNTRUSTED | HCI_MGMT_UNTRUSTED |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment