From 4e3372a754ee05121029dde22ebee7a4988f9a46 Mon Sep 17 00:00:00 2001 From: Alain Michaud Date: Mon, 27 Jul 2020 17:47:05 +0000 Subject: [PATCH] BACKPORT: 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/) Reviewed-by: Sonny Sasaka Reviewed-by: Abhishek Pandit-Subedi Signed-off-by: Alain Michaud Backport notes: HDEV_PARAM_U16 is changed from two parameters to one parameter. BUG=none TEST=build Signed-off-by: Zhengping Jiang --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/eir.c | 29 ++++++++++++++++++++--------- net/bluetooth/hci_core.c | 1 + net/bluetooth/mgmt_config.c | 6 ++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 450a068e1c501e..2dbd97c634007b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -355,6 +355,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 index 1bc51e2b05a347..e6b2d9dc1c38ae 100644 --- a/net/bluetooth/eir.c +++ b/net/bluetooth/eir.c @@ -175,18 +175,20 @@ 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 = strnlen(hdev->dev_name, sizeof(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 { + } else ptr[1] = EIR_NAME_COMPLETE; - } /* EIR Data length */ ptr[0] = name_len + 1; @@ -194,17 +196,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; @@ -214,11 +220,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_per_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 0ac354db817794..d712b5ab51bd98 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -2452,6 +2452,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 index 6ef701c27da48d..6e56a67e309489 100644 --- 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;