Diff between ef14e6eaa7e698d0f62feed3eecd0cae74484d7b and 0da5c68413d6ed3ff8afb3638e0a88914bae7153

Changed Files

File Additions Deletions Status
lib/mgmt.h +3 -0 modified
src/advertising.c +32 -7 modified

Full Patch

diff --git a/lib/mgmt.h b/lib/mgmt.h
index 922a243..430bd0e 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -511,6 +511,9 @@ struct mgmt_rp_add_advertising {
 #define MGMT_ADV_PARAM_TX_POWER		(1 << 15)
 #define MGMT_ADV_PARAM_SCAN_RSP		(1 << 16)
 
+#define MGMT_ADV_FLAG_SEC_MASK	(MGMT_ADV_FLAG_SEC_1M | MGMT_ADV_FLAG_SEC_2M | \
+				 MGMT_ADV_FLAG_SEC_CODED)
+
 #define MGMT_OP_REMOVE_ADVERTISING	0x003F
 struct mgmt_cp_remove_advertising {
 	uint8_t instance;
diff --git a/src/advertising.c b/src/advertising.c
index ca23774..1fe371a 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -776,6 +776,18 @@ static uint8_t *generate_adv_data(struct btd_adv_client *client,
 		bt_ad_add_appearance(client->data, appearance);
 	}
 
+	/* Scan response shall not be used when connectable and setting a
+	 * secondary PHY since that would end up using EA types instead of
+	 * legacy which doesn't support being connectable and scannable
+	 * simultaneously.
+	 */
+	if ((*flags & MGMT_ADV_FLAG_CONNECTABLE) &&
+				(*flags & MGMT_ADV_FLAG_SEC_MASK) &&
+				client->name) {
+		*flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;
+		bt_ad_add_name(client->data, client->name);
+	}
+
 	return bt_ad_generate(client->data, len);
 }
 
@@ -807,6 +819,15 @@ static bool adv_client_has_scan_response(struct btd_adv_client *client,
 		return false;
 	}
 
+	/* Scan response shall not be used when connectable and setting a
+	 * secondary PHY since that would end up using EA types instead of
+	 * legacy which doesn't support being connectable and scannable
+	 * simultaneously.
+	 */
+	if (flags & MGMT_ADV_FLAG_CONNECTABLE &&
+				flags & MGMT_ADV_FLAG_SEC_MASK)
+		return false;
+
 	return true;
 }
 
@@ -1250,7 +1271,7 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
 	uint8_t *adv_data = NULL;
 	size_t adv_data_len;
 	uint8_t *scan_rsp = NULL;
-	size_t scan_rsp_len = -1;
+	size_t scan_rsp_len = 0;
 	uint32_t flags = 0;
 	unsigned int mgmt_ret;
 	dbus_int16_t tx_power;
@@ -1281,11 +1302,13 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
 		goto fail;
 	}
 
-	scan_rsp = generate_scan_rsp(client, &flags, &scan_rsp_len);
-	if ((!scan_rsp && scan_rsp_len) ||
-			scan_rsp_len > rp->max_scan_rsp_len) {
-		error("Scan data couldn't be generated.");
-		goto fail;
+	if (adv_client_has_scan_response(client, flags)) {
+		scan_rsp = generate_scan_rsp(client, &flags, &scan_rsp_len);
+		if ((!scan_rsp && scan_rsp_len) ||
+				scan_rsp_len > rp->max_scan_rsp_len) {
+			error("Scan data couldn't be generated.");
+			goto fail;
+		}
 	}
 
 	param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len +
@@ -1301,7 +1324,9 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
 	cp->adv_data_len = adv_data_len;
 	cp->scan_rsp_len = scan_rsp_len;
 	memcpy(cp->data, adv_data, adv_data_len);
-	memcpy(cp->data + adv_data_len, scan_rsp, scan_rsp_len);
+
+	if (scan_rsp)
+		memcpy(cp->data + adv_data_len, scan_rsp, scan_rsp_len);
 
 	free(adv_data);
 	free(scan_rsp);