diff mbox series

[v2,2/2] Bluetooth: hci_sync: Fix using Legacy PDUs with certain advertising

Message ID 20230707224318.677205-2-luiz.dentz@gmail.com (mailing list archive)
State Handled Elsewhere
Headers show
Series [v2,1/2] Bluetooth: MGMT: Fix always using HCI_MAX_AD_LENGTH | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/SubjectPrefix success Gitlint PASS
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Luiz Augusto von Dentz July 7, 2023, 10:43 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

If the advertising instance is bigger than HCI_MAX_AD_LENGTH than it
cannot use LE_LEGACY_ADV_IND:

BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
page 2449:

 'If legacy advertising PDU types are being used, then the parameter
 value shall be one of those specified in Table 7.2. If the advertising
 set already contains data, the type shall be one that supports
 advertising data and the amount of data shall not exceed 31 octets.'

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/eir.c      | 31 ++++++++++++++++++++-----------
 net/bluetooth/hci_sync.c | 16 ++++++++++++++++
 2 files changed, 36 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/net/bluetooth/eir.c b/net/bluetooth/eir.c
index 8a85f6cdfbc1..2fc375ddf787 100644
--- a/net/bluetooth/eir.c
+++ b/net/bluetooth/eir.c
@@ -302,20 +302,25 @@  u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
 		 * include the "Flags" AD field".
 		 */
 		if (flags) {
-			ptr[0] = 0x02;
-			ptr[1] = EIR_FLAGS;
-			ptr[2] = flags;
+			if (ptr) {
+				ptr[0] = 0x02;
+				ptr[1] = EIR_FLAGS;
+				ptr[2] = flags;
+				ptr += 3;
+			}
 
 			ad_len += 3;
-			ptr += 3;
 		}
 	}
 
 skip_flags:
 	if (adv) {
-		memcpy(ptr, adv->adv_data, adv->adv_data_len);
+		if (ptr) {
+			memcpy(ptr, adv->adv_data, adv->adv_data_len);
+			ptr += adv->adv_data_len;
+		}
+
 		ad_len += adv->adv_data_len;
-		ptr += adv->adv_data_len;
 	}
 
 	if (instance_flags & MGMT_ADV_FLAG_TX_POWER) {
@@ -330,14 +335,18 @@  u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
 			adv_tx_power = hdev->adv_tx_power;
 		}
 
-		/* Provide Tx Power only if we can provide a valid value for it */
+		/* Provide Tx Power only if we can provide a valid value for
+		 * it.
+		 */
 		if (adv_tx_power != HCI_TX_POWER_INVALID) {
-			ptr[0] = 0x02;
-			ptr[1] = EIR_TX_POWER;
-			ptr[2] = (u8)adv_tx_power;
+			if (ptr) {
+				ptr[0] = 0x02;
+				ptr[1] = EIR_TX_POWER;
+				ptr[2] = (u8)adv_tx_power;
+				ptr += 3;
+			}
 
 			ad_len += 3;
-			ptr += 3;
 		}
 	}
 
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 3348a1b0e3f7..f57bf554155e 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -1113,6 +1113,22 @@  int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
 
 	secondary_adv = (flags & MGMT_ADV_FLAG_SEC_MASK);
 
+	/* Force use of EA if advertising data is bigger than maximum allowed
+	 * over Legacy PDUS:
+	 *
+	 * BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
+	 * page 2449:
+	 *
+	 * 'If legacy advertising PDU types are being used, then the parameter
+	 * value shall be one of those specified in Table 7.2. If the
+	 * advertising set already contains data, the type shall be one that
+	 * supports advertising data and the amount of data shall not exceed
+	 * 31 octets.'
+	 */
+	if (!secondary_adv &&
+	    eir_create_adv_data(hdev, instance, NULL) > HCI_MAX_AD_LENGTH)
+		secondary_adv = true;
+
 	if (connectable) {
 		if (secondary_adv)
 			cp.evt_properties = cpu_to_le16(LE_EXT_ADV_CONN_IND);