Diff between 3d9ff9d52edf0b2ad4f7c878b6197dc369240d04 and c0560248754912d70641a6181d07a22f8816ebaa

Changed Files

File Additions Deletions Status
lib/mgmt.h +1 -0 modified
src/advertising.c +23 -1 modified
src/shared/ad.c +17 -0 modified
src/shared/ad.h +2 -0 modified

Full Patch

diff --git a/lib/mgmt.h b/lib/mgmt.h
index c0021ab..81e54c4 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -509,6 +509,7 @@ struct mgmt_rp_add_advertising {
 #define MGMT_ADV_PARAM_TIMEOUT		(1 << 13)
 #define MGMT_ADV_PARAM_INTERVALS	(1 << 14)
 #define MGMT_ADV_PARAM_TX_POWER		(1 << 15)
+#define MGMT_ADV_PARAM_SCAN_RSP		(1 << 16)
 
 #define MGMT_OP_REMOVE_ADVERTISING	0x003F
 struct mgmt_cp_remove_advertising {
diff --git a/src/advertising.c b/src/advertising.c
index 4ab449c..70e6060 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -793,6 +793,22 @@ static uint8_t *generate_scan_rsp(struct btd_adv_client *client,
 	return bt_ad_generate(client->scan, len);
 }
 
+static bool adv_client_has_scan_response(struct btd_adv_client *client,
+						uint32_t flags)
+{
+	/* The local name isn't added into the bt_ad structure until
+	 * generate_scan_rsp is called, so we must check these conditions as
+	 * well.
+	 */
+	if (!(flags & MGMT_ADV_FLAG_LOCAL_NAME) &&
+			!client->name &&
+			bt_ad_is_empty(client->scan)) {
+		return false;
+	}
+
+	return true;
+}
+
 static int get_adv_flags(struct btd_adv_client *client)
 {
 	uint32_t flags = 0;
@@ -917,7 +933,13 @@ static int refresh_extended_adv(struct btd_adv_client *client,
 		flags |= MGMT_ADV_PARAM_TX_POWER;
 	}
 
-	cp.flags = htobl(flags);
+	/* Indicate that this instance will be configured as scannable */
+	if (adv_client_has_scan_response(client, flags) &&
+		client->manager->supported_flags & MGMT_ADV_PARAM_SCAN_RSP) {
+		flags |= MGMT_ADV_PARAM_SCAN_RSP;
+	}
+
+	cp.flags = cpu_to_le32(flags);
 
 	mgmt_ret = mgmt_send(client->manager->mgmt, MGMT_OP_ADD_EXT_ADV_PARAMS,
 			client->manager->mgmt_index, sizeof(cp), &cp,
diff --git a/src/shared/ad.c b/src/shared/ad.c
index 23c8c34..d40d153 100644
--- a/src/shared/ad.c
+++ b/src/shared/ad.c
@@ -552,6 +552,23 @@ uint8_t *bt_ad_generate(struct bt_ad *ad, size_t *length)
 	return adv_data;
 }
 
+bool bt_ad_is_empty(struct bt_ad *ad)
+{
+	/* If any of the bt_ad fields are non-empty or don't have the default
+	 * value, then bt_ad_generate will return a non-empty buffer
+	 */
+	if (!ad->name &&
+		ad->appearance == UINT16_MAX &&
+		queue_isempty(ad->service_uuids) &&
+		queue_isempty(ad->manufacturer_data) &&
+		queue_isempty(ad->solicit_uuids) &&
+		queue_isempty(ad->service_data) &&
+		queue_isempty(ad->data)) {
+		return true;
+	}
+	return false;
+}
+
 static bool queue_add_uuid(struct queue *queue, const bt_uuid_t *uuid)
 {
 	bt_uuid_t *new_uuid;
diff --git a/src/shared/ad.h b/src/shared/ad.h
index 13adcb4..84ef9de 100644
--- a/src/shared/ad.h
+++ b/src/shared/ad.h
@@ -105,6 +105,8 @@ void bt_ad_unref(struct bt_ad *ad);
 
 uint8_t *bt_ad_generate(struct bt_ad *ad, size_t *length);
 
+bool bt_ad_is_empty(struct bt_ad *ad);
+
 bool bt_ad_add_service_uuid(struct bt_ad *ad, const bt_uuid_t *uuid);
 
 bool bt_ad_remove_service_uuid(struct bt_ad *ad, bt_uuid_t *uuid);