aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorMichał Narajowski <michal.narajowski@codecoup.pl>2016-10-19 04:20:27 -0400
committerMarcel Holtmann <marcel@holtmann.org>2016-10-19 12:42:37 -0400
commitf61851f64b171a684f5a1fa78325756dbbaadadc (patch)
treea6296b4aecf3903a33de96608eef7c27bcbd1663 /net/bluetooth/mgmt.c
parent5e2bd93b8fcac8c0cf83f189d996831fb21f2db3 (diff)
Bluetooth: Fix append max 11 bytes of name to scan rsp data
Append maximum of 10 + 1 bytes of name to scan response data. Complete name is appended only if exists and is <= 10 characters. Else append short name if exists or shorten complete name if not. This makes sure name is consistent across multiple advertising instances. Signed-off-by: Michał Narajowski <michal.narajowski@codecoup.pl> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 736038085feb..1fba2a03f8ae 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -6017,7 +6017,15 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
6017 return err; 6017 return err;
6018} 6018}
6019 6019
6020static u8 tlv_data_max_len(u32 adv_flags, bool is_adv_data) 6020static u8 calculate_name_len(struct hci_dev *hdev)
6021{
6022 u8 buf[HCI_MAX_SHORT_NAME_LENGTH + 3];
6023
6024 return append_local_name(hdev, buf, 0);
6025}
6026
6027static u8 tlv_data_max_len(struct hci_dev *hdev, u32 adv_flags,
6028 bool is_adv_data)
6021{ 6029{
6022 u8 max_len = HCI_MAX_AD_LENGTH; 6030 u8 max_len = HCI_MAX_AD_LENGTH;
6023 6031
@@ -6030,9 +6038,8 @@ static u8 tlv_data_max_len(u32 adv_flags, bool is_adv_data)
6030 if (adv_flags & MGMT_ADV_FLAG_TX_POWER) 6038 if (adv_flags & MGMT_ADV_FLAG_TX_POWER)
6031 max_len -= 3; 6039 max_len -= 3;
6032 } else { 6040 } else {
6033 /* at least 1 byte of name should fit in */
6034 if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME) 6041 if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
6035 max_len -= 3; 6042 max_len -= calculate_name_len(hdev);
6036 6043
6037 if (adv_flags & (MGMT_ADV_FLAG_APPEARANCE)) 6044 if (adv_flags & (MGMT_ADV_FLAG_APPEARANCE))
6038 max_len -= 4; 6045 max_len -= 4;
@@ -6063,12 +6070,13 @@ static bool appearance_managed(u32 adv_flags)
6063 return adv_flags & MGMT_ADV_FLAG_APPEARANCE; 6070 return adv_flags & MGMT_ADV_FLAG_APPEARANCE;
6064} 6071}
6065 6072
6066static bool tlv_data_is_valid(u32 adv_flags, u8 *data, u8 len, bool is_adv_data) 6073static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
6074 u8 len, bool is_adv_data)
6067{ 6075{
6068 int i, cur_len; 6076 int i, cur_len;
6069 u8 max_len; 6077 u8 max_len;
6070 6078
6071 max_len = tlv_data_max_len(adv_flags, is_adv_data); 6079 max_len = tlv_data_max_len(hdev, adv_flags, is_adv_data);
6072 6080
6073 if (len > max_len) 6081 if (len > max_len)
6074 return false; 6082 return false;
@@ -6215,8 +6223,8 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
6215 goto unlock; 6223 goto unlock;
6216 } 6224 }
6217 6225
6218 if (!tlv_data_is_valid(flags, cp->data, cp->adv_data_len, true) || 6226 if (!tlv_data_is_valid(hdev, flags, cp->data, cp->adv_data_len, true) ||
6219 !tlv_data_is_valid(flags, cp->data + cp->adv_data_len, 6227 !tlv_data_is_valid(hdev, flags, cp->data + cp->adv_data_len,
6220 cp->scan_rsp_len, false)) { 6228 cp->scan_rsp_len, false)) {
6221 err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, 6229 err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
6222 MGMT_STATUS_INVALID_PARAMS); 6230 MGMT_STATUS_INVALID_PARAMS);
@@ -6429,8 +6437,8 @@ static int get_adv_size_info(struct sock *sk, struct hci_dev *hdev,
6429 6437
6430 rp.instance = cp->instance; 6438 rp.instance = cp->instance;
6431 rp.flags = cp->flags; 6439 rp.flags = cp->flags;
6432 rp.max_adv_data_len = tlv_data_max_len(flags, true); 6440 rp.max_adv_data_len = tlv_data_max_len(hdev, flags, true);
6433 rp.max_scan_rsp_len = tlv_data_max_len(flags, false); 6441 rp.max_scan_rsp_len = tlv_data_max_len(hdev, flags, false);
6434 6442
6435 err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_ADV_SIZE_INFO, 6443 err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_ADV_SIZE_INFO,
6436 MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); 6444 MGMT_STATUS_SUCCESS, &rp, sizeof(rp));