blob: 2f544239f2f624f8a20050be5b03e76798f6252c [file] [log] [blame]
From d8570e28f2fcdcebd2fab49ff7652fa1785369e9 Mon Sep 17 00:00:00 2001
From: Alain Michaud <alainm@chromium.org>
Date: Fri, 24 Jul 2020 19:13:13 +0000
Subject: [PATCH] FROMLIST: Bluetooth: adding configurable eir_max_name_len
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This change adds support for a configurable eir_max_name_len for
platforms which requires a larger than 48 bytes complete name in EIR.
From bluetoothctl:
[bluetooth]# system-alias
012345678901234567890123456789012345678901234567890123456789
Changing 012345678901234567890123456789012345678901234567890123456789
succeeded
[CHG] Controller DC:71:96:69:02:89 Alias:
012345678901234567890123456789012345678901234567890123456789
From btmon:
< HCI Command: Write Local Name (0x03|0x0013) plen 248     #109
[hci0] 88.567990
        Name:
012345678901234567890123456789012345678901234567890123456789
> HCI Event: Command Complete (0x0e) plen 4  #110 [hci0] 88.663854
      Write Local Name (0x03|0x0013) ncmd 1
        Status: Success (0x00)
@ MGMT Event: Local Name Changed (0x0008) plen 260               
{0x0004} [hci0] 88.663948
        Name:
012345678901234567890123456789012345678901234567890123456789
        Short name:
< HCI Command: Write Extended Inquiry Response (0x03|0x0052) plen 241
#111 [hci0] 88.663977
        FEC: Not required (0x00)
        Name (complete):
012345678901234567890123456789012345678901234567890123456789
        TX power: 12 dBm
        Device ID: Bluetooth SIG assigned (0x0001)
          Vendor: Google (224)
          Product: 0xc405
          Version: 0.5.6 (0x0056)
        16-bit Service UUIDs (complete): 7 entries
          Generic Access Profile (0x1800)
          Generic Attribute Profile (0x1801)
          Device Information (0x180a)
          A/V Remote Control (0x110e)
          A/V Remote Control Target (0x110c)
          Handsfree Audio Gateway (0x111f)
          Audio Source (0x110a)
> HCI Event: Command Complete (0x0e) plen 4 #112 [hci0] 88.664874
      Write Extended Inquiry Response (0x03|0x0052) ncmd 1
        Status: Success (0x00)
(am from https://patchwork.kernel.org/patch/11687367/)
BUG=b:161448079
TEST=See bluetoothctl steps and validated outcome above
Signed-off-by: Alain Michaud <alainm@chromium.org>
Change-Id: Ic2cb84fb029a345c9e3901378717d1ab4e9246ab
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2324283
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Sonny Sasaka <sonnysasaka@chromium.org>
Tested-by: Alain Michaud <alainm@chromium.org>
Commit-Queue: Alain Michaud <alainm@chromium.org>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/eir.c | 26 +++++++++++++++++++-------
net/bluetooth/hci_core.c | 1 +
net/bluetooth/mgmt_config.c | 6 ++++++
4 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -332,6 +332,7 @@ struct hci_dev {
__u8 dev_name[HCI_MAX_NAME_LENGTH];
__u8 short_name[HCI_MAX_SHORT_NAME_LENGTH];
__u8 eir[HCI_MAX_EIR_LENGTH];
+ __u16 eir_max_name_len;
__u16 appearance;
__u8 dev_class[3];
__u8 major_class;
diff --git a/net/bluetooth/eir.c b/net/bluetooth/eir.c
--- a/net/bluetooth/eir.c
+++ b/net/bluetooth/eir.c
@@ -166,14 +166,17 @@ static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
void eir_create(struct hci_dev *hdev, u8 *data)
{
u8 *ptr = data;
+ u8 size_remaining = HCI_MAX_EIR_LENGTH;
size_t name_len;
name_len = strlen(hdev->dev_name);
if (name_len > 0) {
/* EIR Data type */
- if (name_len > 48) {
- name_len = 48;
+ if (name_len > min_t(u16, (HCI_MAX_EIR_LENGTH - 2),
+ hdev->eir_max_name_len)) {
+ name_len = min_t(u16, (HCI_MAX_EIR_LENGTH - 2),
+ hdev->eir_max_name_len);
ptr[1] = EIR_NAME_SHORT;
} else {
ptr[1] = EIR_NAME_COMPLETE;
@@ -185,17 +188,21 @@ void eir_create(struct hci_dev *hdev, u8 *data)
memcpy(ptr + 2, hdev->dev_name, name_len);
ptr += (name_len + 2);
+ size_remaining -= (name_len + 2);
}
- if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) {
+ if (hdev->inq_tx_power != HCI_TX_POWER_INVALID &&
+ size_remaining >= 3) {
ptr[0] = 2;
ptr[1] = EIR_TX_POWER;
ptr[2] = (u8)hdev->inq_tx_power;
ptr += 3;
+ size_remaining -= 3;
}
- if (hdev->devid_source > 0) {
+ if (hdev->devid_source > 0 &&
+ size_remaining >= 10) {
ptr[0] = 9;
ptr[1] = EIR_DEVICE_ID;
@@ -205,11 +212,16 @@ void eir_create(struct hci_dev *hdev, u8 *data)
put_unaligned_le16(hdev->devid_version, ptr + 8);
ptr += 10;
+ size_remaining -= 10;
}
- ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
- ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
- ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
+ ptr = create_uuid16_list(hdev, ptr, size_remaining);
+ size_remaining = HCI_MAX_EIR_LENGTH - (ptr - data);
+
+ ptr = create_uuid32_list(hdev, ptr, size_remaining);
+ size_remaining = HCI_MAX_EIR_LENGTH - (ptr - data);
+
+ ptr = create_uuid128_list(hdev, ptr, size_remaining);
}
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3670,6 +3670,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
hdev->adv_instance_cnt = 0;
hdev->cur_adv_instance = 0x00;
hdev->adv_instance_timeout = 0;
+ hdev->eir_max_name_len = 48;
hdev->advmon_allowlist_duration = 300;
hdev->advmon_no_filter_duration = 500;
diff --git a/net/bluetooth/mgmt_config.c b/net/bluetooth/mgmt_config.c
--- a/net/bluetooth/mgmt_config.c
+++ b/net/bluetooth/mgmt_config.c
@@ -75,6 +75,7 @@ int read_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
HDEV_PARAM_U16(le_conn_latency);
HDEV_PARAM_U16(le_supv_timeout);
HDEV_PARAM_U16(def_le_autoconnect_timeout);
+ HDEV_PARAM_U16(eir_max_name_len);
HDEV_PARAM_U16(advmon_allowlist_duration);
HDEV_PARAM_U16(advmon_no_filter_duration);
HDEV_PARAM_U8(enable_advmon_interleave_scan);
@@ -108,6 +109,7 @@ int read_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
TLV_SET_U16(0x001a, le_supv_timeout),
TLV_SET_U16_JIFFIES_TO_MSECS(0x001b,
def_le_autoconnect_timeout),
+ TLV_SET_U16(0x001c, eir_max_name_len),
TLV_SET_U16(0x001d, advmon_allowlist_duration),
TLV_SET_U16(0x001e, advmon_no_filter_duration),
TLV_SET_U8(0x001f, enable_advmon_interleave_scan),
@@ -184,6 +186,7 @@ int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
case 0x0019:
case 0x001a:
case 0x001b:
+ case 0x001c:
case 0x001d:
case 0x001e:
exp_type_len = sizeof(u16);
@@ -305,6 +308,9 @@ int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
hdev->def_le_autoconnect_timeout =
msecs_to_jiffies(TLV_GET_LE16(buffer));
break;
+ case 0x0001c:
+ hdev->eir_max_name_len = TLV_GET_LE16(buffer);
+ break;
case 0x0001d:
hdev->advmon_allowlist_duration = TLV_GET_LE16(buffer);
break;
--
2.34.0.rc2.393.gf8c9666880-goog