All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/7] advertising: Rename AdvertisementInstaces to AdvertisingInstaces
@ 2017-08-04  9:16 Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 2/7] advertising: Add SupportedFeatures Luiz Augusto von Dentz
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2017-08-04  9:16 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This is consitent with tha name of the interface, also make it
experimental since AdvertisingManager.
---
 doc/advertising-api.txt | 2 +-
 src/advertising.c       | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
index 7a29b7095..26ec0ca37 100644
--- a/doc/advertising-api.txt
+++ b/doc/advertising-api.txt
@@ -113,6 +113,6 @@ Methods		RegisterAdvertisement(object advertisement, dict options)
 			Possible errors: org.bluez.Error.InvalidArguments
 					 org.bluez.Error.DoesNotExist
 
-Properties	byte AdvertisementInstaces
+Properties	byte AdvertisingInstaces
 
 			Number of available advertisement instances.
diff --git a/src/advertising.c b/src/advertising.c
index c2af3acb4..c628f0fd5 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -739,7 +739,8 @@ static gboolean get_instances(const GDBusPropertyTable *property,
 }
 
 static const GDBusPropertyTable properties[] = {
-	{ "AdvertisementInstances", "y", get_instances },
+	{ "AdvertisingInstances", "y", get_instances, NULL, NULL,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
 };
 
 static const GDBusMethodTable methods[] = {
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/7] advertising: Add SupportedFeatures
  2017-08-04  9:16 [PATCH v3 1/7] advertising: Rename AdvertisementInstaces to AdvertisingInstaces Luiz Augusto von Dentz
@ 2017-08-04  9:16 ` Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 3/7] advertising: Add IncludeName property Luiz Augusto von Dentz
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2017-08-04  9:16 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds SupportedFeatures so application can detect what features
are supported by the system.
---
 doc/advertising-api.txt |  8 ++++++++
 src/advertising.c       | 43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
index 26ec0ca37..a001fb668 100644
--- a/doc/advertising-api.txt
+++ b/doc/advertising-api.txt
@@ -116,3 +116,11 @@ Methods		RegisterAdvertisement(object advertisement, dict options)
 Properties	byte AdvertisingInstaces
 
 			Number of available advertisement instances.
+
+		array{string} SupportedFeatures
+
+			List of supported features.
+
+			Possible values: "Tx Power"
+					 "Appearance"
+					 "Local Name"
diff --git a/src/advertising.c b/src/advertising.c
index c628f0fd5..a1e497439 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -48,6 +48,7 @@ struct btd_adv_manager {
 	uint16_t mgmt_index;
 	uint8_t max_adv_len;
 	uint8_t max_ads;
+	uint32_t supported_flags;
 	unsigned int instance_bitmap;
 };
 
@@ -738,9 +739,50 @@ static gboolean get_instances(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static struct adv_feat {
+	uint8_t flag;
+	const char *name;
+} feats[] = {
+	{ MGMT_ADV_FLAG_TX_POWER, "tx-power" },
+	{ MGMT_ADV_FLAG_APPEARANCE, "appearance" },
+	{ MGMT_ADV_FLAG_LOCAL_NAME, "local-name" },
+	{ },
+};
+
+static void append_features(struct btd_adv_manager *manager,
+						DBusMessageIter *iter)
+{
+	struct adv_feat *feat;
+
+	for (feat = feats; feat && feat->name; feat++) {
+		if (manager->supported_flags & feat->flag)
+			dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
+								&feat->name);
+	}
+}
+
+static gboolean get_supported_features(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adv_manager *manager = data;
+	DBusMessageIter entry;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+					DBUS_TYPE_STRING_AS_STRING, &entry);
+
+	append_features(manager, &entry);
+
+	dbus_message_iter_close_container(iter, &entry);
+
+	return TRUE;
+}
+
 static const GDBusPropertyTable properties[] = {
 	{ "AdvertisingInstances", "y", get_instances, NULL, NULL,
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "SupportedFeatures", "as", get_supported_features, NULL, NULL,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ }
 };
 
 static const GDBusMethodTable methods[] = {
@@ -785,6 +827,7 @@ static void read_adv_features_callback(uint8_t status, uint16_t length,
 
 	manager->max_adv_len = feat->max_adv_data_len;
 	manager->max_ads = feat->max_instances;
+	manager->supported_flags = feat->supported_flags;
 
 	if (manager->max_ads == 0)
 		return;
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 3/7] advertising: Add IncludeName property
  2017-08-04  9:16 [PATCH v3 1/7] advertising: Rename AdvertisementInstaces to AdvertisingInstaces Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 2/7] advertising: Add SupportedFeatures Luiz Augusto von Dentz
@ 2017-08-04  9:16 ` Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 4/7] client: Add set-advertise-name command Luiz Augusto von Dentz
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2017-08-04  9:16 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds support to include adapter name, or alias, in the scan
response with use of IncludeName property.
---
 doc/advertising-api.txt |  5 +++++
 src/advertising.c       | 27 +++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
index a001fb668..59ec13363 100644
--- a/doc/advertising-api.txt
+++ b/doc/advertising-api.txt
@@ -66,6 +66,11 @@ Properties	string Type
 			Includes the Tx Power in the advertising packet.
 			If missing, the Tx Power is not included.
 
+		bool IncludeName
+
+			Include adapter Name, or Alias if set, as scan
+			response data.
+
 
 LE Advertising Manager hierarchy
 ================================
diff --git a/src/advertising.c b/src/advertising.c
index a1e497439..7a1b083bc 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -64,6 +64,7 @@ struct btd_adv_client {
 	DBusMessage *reg;
 	uint8_t type; /* Advertising type */
 	bool include_tx_power;
+	bool include_name;
 	struct bt_ad *data;
 	uint8_t instance;
 };
@@ -412,6 +413,24 @@ static bool parse_include_tx_power(GDBusProxy *proxy, bool *included)
 	return true;
 }
 
+static bool parse_include_name(GDBusProxy *proxy, bool *included)
+{
+	DBusMessageIter iter;
+	dbus_bool_t b;
+
+	if (!g_dbus_proxy_get_property(proxy, "IncludeName", &iter))
+		return true;
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
+		return false;
+
+	dbus_message_iter_get_basic(&iter, &b);
+
+	*included = b;
+
+	return true;
+}
+
 static void add_client_complete(struct btd_adv_client *client, uint8_t status)
 {
 	DBusMessage *reply;
@@ -498,6 +517,9 @@ static DBusMessage *refresh_advertisement(struct btd_adv_client *client)
 	if (client->include_tx_power)
 		flags |= MGMT_ADV_FLAG_TX_POWER;
 
+	if (client->include_name)
+		flags |= MGMT_ADV_FLAG_LOCAL_NAME;
+
 	adv_data = bt_ad_generate(client->data, &adv_data_len);
 
 	if (!adv_data || (adv_data_len > calc_max_adv_len(client, flags))) {
@@ -574,6 +596,11 @@ static DBusMessage *parse_advertisement(struct btd_adv_client *client)
 		goto fail;
 	}
 
+	if (!parse_include_name(client->proxy, &client->include_name)) {
+		error("Property \"IncludeName\" failed to parse");
+		goto fail;
+	}
+
 	return refresh_advertisement(client);
 
 fail:
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 4/7] client: Add set-advertise-name command
  2017-08-04  9:16 [PATCH v3 1/7] advertising: Rename AdvertisementInstaces to AdvertisingInstaces Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 2/7] advertising: Add SupportedFeatures Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 3/7] advertising: Add IncludeName property Luiz Augusto von Dentz
@ 2017-08-04  9:16 ` Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 5/7] advertising: Add IncludeAppearance property Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2017-08-04  9:16 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds set-advertise-name which enables the use of adapter
name/alias in the scan response:

[bluetooth]# set-advertise-name on
[bluetooth]# advertise on

@ MGMT Command: Add Advertising (0x003e) plen 11
        Instance: 1
        Flags: 0x00000043
          Switch into Connectable mode
          Advertise as Discoverable
          Add Local Name in Scan Response
        Duration: 0
        Timeout: 0
        Advertising data length: 0
        Scan response length: 0
---
 client/advertising.c | 21 +++++++++++++++++++++
 client/advertising.h |  1 +
 client/main.c        | 22 ++++++++++++++++++++++
 3 files changed, 44 insertions(+)

diff --git a/client/advertising.c b/client/advertising.c
index 81fa85118..67e87c7ca 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -49,6 +49,7 @@ static uint16_t ad_manufacturer_id;
 static uint8_t ad_manufacturer_data[25];
 static uint8_t ad_manufacturer_data_len = 0;
 static gboolean ad_tx_power = FALSE;
+static gboolean ad_name = FALSE;
 
 static void ad_release(DBusConnection *conn)
 {
@@ -252,6 +253,20 @@ static gboolean get_tx_power(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static gboolean include_name_exists(const GDBusPropertyTable *property,
+							void *data)
+{
+	return ad_name;
+}
+
+static gboolean get_include_name(const GDBusPropertyTable *property,
+				DBusMessageIter *iter, void *user_data)
+{
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &ad_name);
+
+	return TRUE;
+}
+
 static const GDBusPropertyTable ad_props[] = {
 	{ "Type", "s", get_type },
 	{ "ServiceUUIDs", "as", get_uuids, NULL, uuids_exists },
@@ -259,6 +274,7 @@ static const GDBusPropertyTable ad_props[] = {
 	{ "ManufacturerData", "a{qv}", get_manufacturer_data, NULL,
 						manufacturer_data_exists },
 	{ "IncludeTxPower", "b", get_tx_power, NULL, tx_power_exists },
+	{ "IncludeName", "b", get_include_name, NULL, include_name_exists },
 	{ }
 };
 
@@ -453,3 +469,8 @@ void ad_advertise_tx_power(gboolean value)
 {
 	ad_tx_power = value;
 }
+
+void ad_advertise_name(gboolean value)
+{
+	ad_name = value;
+}
diff --git a/client/advertising.h b/client/advertising.h
index 86384656c..a41a2742d 100644
--- a/client/advertising.h
+++ b/client/advertising.h
@@ -28,3 +28,4 @@ void ad_advertise_uuids(const char *arg);
 void ad_advertise_service(const char *arg);
 void ad_advertise_manufacturer(const char *arg);
 void ad_advertise_tx_power(gboolean value);
+void ad_advertise_name(gboolean value);
diff --git a/client/main.c b/client/main.c
index 17de7f81f..44de8c0a0 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2362,6 +2362,26 @@ static void cmd_set_advertise_tx_power(const char *arg)
 	rl_printf("Invalid argument\n");
 }
 
+static void cmd_set_advertise_name(const char *arg)
+{
+	if (arg == NULL || strlen(arg) == 0) {
+		rl_printf("Missing on/off argument\n");
+		return;
+	}
+
+	if (strcmp(arg, "on") == 0 || strcmp(arg, "yes") == 0) {
+		ad_advertise_name(TRUE);
+		return;
+	}
+
+	if (strcmp(arg, "off") == 0 || strcmp(arg, "no") == 0) {
+		ad_advertise_name(FALSE);
+		return;
+	}
+
+	rl_printf("Invalid argument\n");
+}
+
 static const struct {
 	const char *cmd;
 	const char *arg;
@@ -2406,6 +2426,8 @@ static const struct {
 	{ "set-advertise-tx-power", "<on/off>",
 			cmd_set_advertise_tx_power,
 			"Enable/disable TX power to be advertised" },
+	{ "set-advertise-name", "<on/off>", cmd_set_advertise_name,
+			"Enable/disable local name to be advertised" },
 	{ "set-scan-filter-uuids", "[uuid1 uuid2 ...]",
 			cmd_set_scan_filter_uuids, "Set scan filter uuids" },
 	{ "set-scan-filter-rssi", "[rssi]", cmd_set_scan_filter_rssi,
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 5/7] advertising: Add IncludeAppearance property
  2017-08-04  9:16 [PATCH v3 1/7] advertising: Rename AdvertisementInstaces to AdvertisingInstaces Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2017-08-04  9:16 ` [PATCH v3 4/7] client: Add set-advertise-name command Luiz Augusto von Dentz
@ 2017-08-04  9:16 ` Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 6/7] client: Add set-advertise-name command Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 7/7] advertising: Consolidate Include* into a single property Luiz Augusto von Dentz
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2017-08-04  9:16 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds support to include appearance in the advertisement data
with use of IncludeAppearance property.
---
 doc/advertising-api.txt |   6 ++
 src/advertising.c       | 189 ++++++++++++++++++++++++------------------------
 2 files changed, 100 insertions(+), 95 deletions(-)

diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
index 59ec13363..f4e7826b6 100644
--- a/doc/advertising-api.txt
+++ b/doc/advertising-api.txt
@@ -66,6 +66,12 @@ Properties	string Type
 			Includes the Tx Power in the advertising packet.
 			If missing, the Tx Power is not included.
 
+		uint16 IncludeAppearance
+
+			Includes Appearance in the advertising packet.
+
+			Possible values: as found on Device.Appearance
+
 		bool IncludeName
 
 			Include adapter Name, or Alias if set, as scan
diff --git a/src/advertising.c b/src/advertising.c
index 7a1b083bc..a39b82774 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -65,6 +65,7 @@ struct btd_adv_client {
 	uint8_t type; /* Advertising type */
 	bool include_tx_power;
 	bool include_name;
+	bool include_appearance;
 	struct bt_ad *data;
 	uint8_t instance;
 };
@@ -176,45 +177,39 @@ static void client_disconnect_cb(DBusConnection *conn, void *user_data)
 	client_remove(user_data);
 }
 
-static bool parse_type(GDBusProxy *proxy, uint8_t *type)
+static bool parse_type(DBusMessageIter *iter, struct btd_adv_client *client)
 {
-	DBusMessageIter iter;
 	const char *msg_type;
 
-	if (!g_dbus_proxy_get_property(proxy, "Type", &iter))
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
 		return false;
 
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
-		return false;
-
-	dbus_message_iter_get_basic(&iter, &msg_type);
+	dbus_message_iter_get_basic(iter, &msg_type);
 
 	if (!g_strcmp0(msg_type, "broadcast")) {
-		*type = AD_TYPE_BROADCAST;
+		client->type = AD_TYPE_BROADCAST;
 		return true;
 	}
 
 	if (!g_strcmp0(msg_type, "peripheral")) {
-		*type = AD_TYPE_PERIPHERAL;
+		client->type = AD_TYPE_PERIPHERAL;
 		return true;
 	}
 
 	return false;
 }
 
-static bool parse_service_uuids(GDBusProxy *proxy, struct bt_ad *data)
+static bool parse_service_uuids(DBusMessageIter *iter,
+					struct btd_adv_client *client)
 {
-	DBusMessageIter iter, ariter;
-
-	if (!g_dbus_proxy_get_property(proxy, "ServiceUUIDs", &iter))
-		return true;
+	DBusMessageIter ariter;
 
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
 		return false;
 
-	dbus_message_iter_recurse(&iter, &ariter);
+	dbus_message_iter_recurse(iter, &ariter);
 
-	bt_ad_clear_service_uuid(data);
+	bt_ad_clear_service_uuid(client->data);
 
 	while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
 		const char *uuid_str;
@@ -227,7 +222,7 @@ static bool parse_service_uuids(GDBusProxy *proxy, struct bt_ad *data)
 		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
 			goto fail;
 
-		if (!bt_ad_add_service_uuid(data, &uuid))
+		if (!bt_ad_add_service_uuid(client->data, &uuid))
 			goto fail;
 
 		dbus_message_iter_next(&ariter);
@@ -236,23 +231,21 @@ static bool parse_service_uuids(GDBusProxy *proxy, struct bt_ad *data)
 	return true;
 
 fail:
-	bt_ad_clear_service_uuid(data);
+	bt_ad_clear_service_uuid(client->data);
 	return false;
 }
 
-static bool parse_solicit_uuids(GDBusProxy *proxy, struct bt_ad *data)
+static bool parse_solicit_uuids(DBusMessageIter *iter,
+					struct btd_adv_client *client)
 {
-	DBusMessageIter iter, ariter;
-
-	if (!g_dbus_proxy_get_property(proxy, "SolicitUUIDs", &iter))
-		return true;
+	DBusMessageIter ariter;
 
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
 		return false;
 
-	dbus_message_iter_recurse(&iter, &ariter);
+	dbus_message_iter_recurse(iter, &ariter);
 
-	bt_ad_clear_solicit_uuid(data);
+	bt_ad_clear_solicit_uuid(client->data);
 
 	while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
 		const char *uuid_str;
@@ -265,7 +258,7 @@ static bool parse_solicit_uuids(GDBusProxy *proxy, struct bt_ad *data)
 		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
 			goto fail;
 
-		if (!bt_ad_add_solicit_uuid(data, &uuid))
+		if (!bt_ad_add_solicit_uuid(client->data, &uuid))
 			goto fail;
 
 		dbus_message_iter_next(&ariter);
@@ -274,23 +267,21 @@ static bool parse_solicit_uuids(GDBusProxy *proxy, struct bt_ad *data)
 	return true;
 
 fail:
-	bt_ad_clear_solicit_uuid(data);
+	bt_ad_clear_solicit_uuid(client->data);
 	return false;
 }
 
-static bool parse_manufacturer_data(GDBusProxy *proxy, struct bt_ad *data)
+static bool parse_manufacturer_data(DBusMessageIter *iter,
+					struct btd_adv_client *client)
 {
-	DBusMessageIter iter, entries;
+	DBusMessageIter entries;
 
-	if (!g_dbus_proxy_get_property(proxy, "ManufacturerData", &iter))
-		return true;
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
 		return false;
 
-	dbus_message_iter_recurse(&iter, &entries);
+	dbus_message_iter_recurse(iter, &entries);
 
-	bt_ad_clear_manufacturer_data(data);
+	bt_ad_clear_manufacturer_data(client->data);
 
 	while (dbus_message_iter_get_arg_type(&entries)
 						== DBUS_TYPE_DICT_ENTRY) {
@@ -321,8 +312,8 @@ static bool parse_manufacturer_data(GDBusProxy *proxy, struct bt_ad *data)
 
 		DBG("Adding ManufacturerData for %04x", manuf_id);
 
-		if (!bt_ad_add_manufacturer_data(data, manuf_id, manuf_data,
-									len))
+		if (!bt_ad_add_manufacturer_data(client->data, manuf_id,
+							manuf_data, len))
 			goto fail;
 
 		dbus_message_iter_next(&entries);
@@ -331,23 +322,21 @@ static bool parse_manufacturer_data(GDBusProxy *proxy, struct bt_ad *data)
 	return true;
 
 fail:
-	bt_ad_clear_manufacturer_data(data);
+	bt_ad_clear_manufacturer_data(client->data);
 	return false;
 }
 
-static bool parse_service_data(GDBusProxy *proxy, struct bt_ad *data)
+static bool parse_service_data(DBusMessageIter *iter,
+					struct btd_adv_client *client)
 {
-	DBusMessageIter iter, entries;
+	DBusMessageIter entries;
 
-	if (!g_dbus_proxy_get_property(proxy, "ServiceData", &iter))
-		return true;
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
 		return false;
 
-	dbus_message_iter_recurse(&iter, &entries);
+	dbus_message_iter_recurse(iter, &entries);
 
-	bt_ad_clear_service_data(data);
+	bt_ad_clear_service_data(client->data);
 
 	while (dbus_message_iter_get_arg_type(&entries)
 						== DBUS_TYPE_DICT_ENTRY) {
@@ -382,7 +371,8 @@ static bool parse_service_data(GDBusProxy *proxy, struct bt_ad *data)
 
 		DBG("Adding ServiceData for %s", uuid_str);
 
-		if (!bt_ad_add_service_data(data, &uuid, service_data, len))
+		if (!bt_ad_add_service_data(client->data, &uuid, service_data,
+									len))
 			goto fail;
 
 		dbus_message_iter_next(&entries);
@@ -391,46 +381,72 @@ static bool parse_service_data(GDBusProxy *proxy, struct bt_ad *data)
 	return true;
 
 fail:
-	bt_ad_clear_service_data(data);
+	bt_ad_clear_service_data(client->data);
 	return false;
 }
 
-static bool parse_include_tx_power(GDBusProxy *proxy, bool *included)
+static bool parse_include_tx_power(DBusMessageIter *iter,
+					struct btd_adv_client *client)
 {
-	DBusMessageIter iter;
 	dbus_bool_t b;
 
-	if (!g_dbus_proxy_get_property(proxy, "IncludeTxPower", &iter))
-		return true;
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
 		return false;
 
-	dbus_message_iter_get_basic(&iter, &b);
+	dbus_message_iter_get_basic(iter, &b);
 
-	*included = b;
+	client->include_tx_power = b;
 
 	return true;
 }
 
-static bool parse_include_name(GDBusProxy *proxy, bool *included)
+static bool parse_include_name(DBusMessageIter *iter,
+					struct btd_adv_client *client)
 {
-	DBusMessageIter iter;
 	dbus_bool_t b;
 
-	if (!g_dbus_proxy_get_property(proxy, "IncludeName", &iter))
-		return true;
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
+		return false;
+
+	dbus_message_iter_get_basic(iter, &b);
+
+	if (client->manager->supported_flags & MGMT_ADV_FLAG_LOCAL_NAME)
+		client->include_name = b;
+
+	return true;
+}
+
+static bool parse_include_appearance(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	dbus_bool_t b;
 
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
 		return false;
 
-	dbus_message_iter_get_basic(&iter, &b);
+	dbus_message_iter_get_basic(iter, &b);
 
-	*included = b;
+	if (client->manager->supported_flags & MGMT_ADV_FLAG_APPEARANCE)
+		client->include_appearance = b;
 
 	return true;
 }
 
+static struct adv_parser {
+	const char *name;
+	bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
+} parsers[] = {
+	{ "Type", parse_type },
+	{ "UUIDs", parse_service_uuids },
+	{ "SolicitUUIDs", parse_solicit_uuids },
+	{ "ManufacturerData", parse_manufacturer_data },
+	{ "ServiceData", parse_service_data },
+	{ "IncludeTxPower", parse_include_tx_power },
+	{ "IncludeName", parse_include_name },
+	{ "IncludeAppearance", parse_include_appearance },
+	{ },
+};
+
 static void add_client_complete(struct btd_adv_client *client, uint8_t status)
 {
 	DBusMessage *reply;
@@ -520,6 +536,9 @@ static DBusMessage *refresh_advertisement(struct btd_adv_client *client)
 	if (client->include_name)
 		flags |= MGMT_ADV_FLAG_LOCAL_NAME;
 
+	if (client->include_appearance)
+		flags |= MGMT_ADV_FLAG_APPEARANCE;
+
 	adv_data = bt_ad_generate(client->data, &adv_data_len);
 
 	if (!adv_data || (adv_data_len > calc_max_adv_len(client, flags))) {
@@ -566,39 +585,19 @@ static DBusMessage *refresh_advertisement(struct btd_adv_client *client)
 
 static DBusMessage *parse_advertisement(struct btd_adv_client *client)
 {
-	if (!parse_type(client->proxy, &client->type)) {
-		error("Failed to read \"Type\" property of advertisement");
-		goto fail;
-	}
+	struct adv_parser *parser;
 
-	if (!parse_service_uuids(client->proxy, client->data)) {
-		error("Property \"ServiceUUIDs\" failed to parse");
-		goto fail;
-	}
+	for (parser = parsers; parser && parser->name; parser++) {
+		DBusMessageIter iter;
 
-	if (!parse_solicit_uuids(client->proxy, client->data)) {
-		error("Property \"SolicitUUIDs\" failed to parse");
-		goto fail;
-	}
+		if (!g_dbus_proxy_get_property(client->proxy, parser->name,
+								&iter))
+			continue;
 
-	if (!parse_manufacturer_data(client->proxy, client->data)) {
-		error("Property \"ManufacturerData\" failed to parse");
-		goto fail;
-	}
-
-	if (!parse_service_data(client->proxy, client->data)) {
-		error("Property \"ServiceData\" failed to parse");
-		goto fail;
-	}
-
-	if (!parse_include_tx_power(client->proxy, &client->include_tx_power)) {
-		error("Property \"IncludeTxPower\" failed to parse");
-		goto fail;
-	}
-
-	if (!parse_include_name(client->proxy, &client->include_name)) {
-		error("Property \"IncludeName\" failed to parse");
-		goto fail;
+		if (!parser->func(&iter, client)) {
+			error("Error parsing %s property", parser->name);
+			goto fail;
+		}
 	}
 
 	return refresh_advertisement(client);
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 6/7] client: Add set-advertise-name command
  2017-08-04  9:16 [PATCH v3 1/7] advertising: Rename AdvertisementInstaces to AdvertisingInstaces Luiz Augusto von Dentz
                   ` (3 preceding siblings ...)
  2017-08-04  9:16 ` [PATCH v3 5/7] advertising: Add IncludeAppearance property Luiz Augusto von Dentz
@ 2017-08-04  9:16 ` Luiz Augusto von Dentz
  2017-08-04  9:16 ` [PATCH v3 7/7] advertising: Consolidate Include* into a single property Luiz Augusto von Dentz
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2017-08-04  9:16 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds set-advertise-name which enables the use of adapter
name/alias in the scan response:

[bluetooth]# set-advertise-appearance on
[bluetooth]# advertise on

@ MGMT Command: Add Advertising (0x003e) plen 11
        Instance: 1
        Flags: 0x00000023
          Switch into Connectable mode
          Advertise as Discoverable
          Add Appearance field to Scan Response
        Duration: 0
        Timeout: 0
        Advertising data length: 0
        Scan response length: 0
---
 client/advertising.c | 163 ++++++++++++++++++++++++++++++++-------------------
 client/advertising.h |   5 +-
 client/main.c        |  30 ++++++++--
 3 files changed, 131 insertions(+), 67 deletions(-)

diff --git a/client/advertising.c b/client/advertising.c
index 67e87c7ca..a90127b9c 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <readline/readline.h>
 #include <wordexp.h>
 
@@ -38,22 +39,36 @@
 #define AD_PATH "/org/bluez/advertising"
 #define AD_IFACE "org.bluez.LEAdvertisement1"
 
-static gboolean registered = FALSE;
-static char *ad_type = NULL;
-static char **ad_uuids = NULL;
-static size_t ad_uuids_len = 0;
-static char *ad_service_uuid = NULL;
-static uint8_t ad_service_data[25];
-static uint8_t ad_service_data_len = 0;
-static uint16_t ad_manufacturer_id;
-static uint8_t ad_manufacturer_data[25];
-static uint8_t ad_manufacturer_data_len = 0;
-static gboolean ad_tx_power = FALSE;
-static gboolean ad_name = FALSE;
+struct ad_data {
+	uint8_t data[25];
+	uint8_t len;
+};
+
+struct service_data {
+	char *uuid;
+	struct ad_data data;
+};
+
+struct manufacturer_data {
+	uint16_t id;
+	struct ad_data data;
+};
+
+static struct ad {
+	bool registered;
+	char *type;
+	char **uuids;
+	size_t uuids_len;
+	struct service_data service;
+	struct manufacturer_data manufacturer;
+	bool tx_power;
+	bool name;
+	bool appearance;
+} ad;
 
 static void ad_release(DBusConnection *conn)
 {
-	registered = FALSE;
+	ad.registered = false;
 
 	g_dbus_unregister_interface(conn, AD_PATH, AD_IFACE);
 }
@@ -95,7 +110,7 @@ static void register_reply(DBusMessage *message, void *user_data)
 	dbus_error_init(&error);
 
 	if (dbus_set_error_from_message(&error, message) == FALSE) {
-		registered = TRUE;
+		ad.registered = true;
 		rl_printf("Advertising object registered\n");
 	} else {
 		rl_printf("Failed to register advertisement: %s\n", error.name);
@@ -112,8 +127,8 @@ static gboolean get_type(const GDBusPropertyTable *property,
 {
 	const char *type = "peripheral";
 
-	if (!ad_type || strlen(ad_type) > 0)
-		type = ad_type;
+	if (!ad.type || strlen(ad.type) > 0)
+		type = ad.type;
 
 	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &type);
 
@@ -122,7 +137,7 @@ static gboolean get_type(const GDBusPropertyTable *property,
 
 static gboolean uuids_exists(const GDBusPropertyTable *property, void *data)
 {
-	return ad_uuids_len != 0;
+	return ad.uuids_len != 0;
 }
 
 static gboolean get_uuids(const GDBusPropertyTable *property,
@@ -133,9 +148,9 @@ static gboolean get_uuids(const GDBusPropertyTable *property,
 
 	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "as", &array);
 
-	for (i = 0; i < ad_uuids_len; i++)
+	for (i = 0; i < ad.uuids_len; i++)
 		dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING,
-							&ad_uuids[i]);
+							&ad.uuids[i]);
 
 	dbus_message_iter_close_container(iter, &array);
 
@@ -198,19 +213,19 @@ static void dict_append_array(DBusMessageIter *dict, const char *key, int type,
 static gboolean service_data_exists(const GDBusPropertyTable *property,
 								void *data)
 {
-	return ad_service_uuid != NULL;
+	return ad.service.uuid != NULL;
 }
 
 static gboolean get_service_data(const GDBusPropertyTable *property,
 				DBusMessageIter *iter, void *user_data)
 {
 	DBusMessageIter dict;
-	const uint8_t *data = ad_service_data;
+	struct ad_data *data = &ad.service.data;
 
 	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
 
-	dict_append_array(&dict, ad_service_uuid, DBUS_TYPE_BYTE, &data,
-							ad_service_data_len);
+	dict_append_array(&dict, ad.service.uuid, DBUS_TYPE_BYTE, &data->data,
+								data->len);
 
 	dbus_message_iter_close_container(iter, &dict);
 
@@ -220,20 +235,19 @@ static gboolean get_service_data(const GDBusPropertyTable *property,
 static gboolean manufacturer_data_exists(const GDBusPropertyTable *property,
 								void *data)
 {
-	return ad_manufacturer_id != 0;
+	return ad.manufacturer.id != 0;
 }
 
 static gboolean get_manufacturer_data(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *user_data)
 {
 	DBusMessageIter dict;
-	const uint8_t *data = ad_manufacturer_data;
+	struct ad_data *data = &ad.manufacturer.data;
 
 	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{qv}", &dict);
 
-	dict_append_basic_array(&dict, DBUS_TYPE_UINT16, &ad_manufacturer_id,
-					DBUS_TYPE_BYTE, &data,
-					ad_manufacturer_data_len);
+	dict_append_basic_array(&dict, DBUS_TYPE_UINT16, &ad.manufacturer.id,
+					DBUS_TYPE_BYTE, &data->data, data->len);
 
 	dbus_message_iter_close_container(iter, &dict);
 
@@ -242,13 +256,15 @@ static gboolean get_manufacturer_data(const GDBusPropertyTable *property,
 
 static gboolean tx_power_exists(const GDBusPropertyTable *property, void *data)
 {
-	return ad_tx_power;
+	return ad.tx_power;
 }
 
 static gboolean get_tx_power(const GDBusPropertyTable *property,
 				DBusMessageIter *iter, void *user_data)
 {
-	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &ad_tx_power);
+	dbus_bool_t b = ad.tx_power;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &b);
 
 	return TRUE;
 }
@@ -256,13 +272,31 @@ static gboolean get_tx_power(const GDBusPropertyTable *property,
 static gboolean include_name_exists(const GDBusPropertyTable *property,
 							void *data)
 {
-	return ad_name;
+	return ad.name;
 }
 
 static gboolean get_include_name(const GDBusPropertyTable *property,
 				DBusMessageIter *iter, void *user_data)
 {
-	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &ad_name);
+	dbus_bool_t b = ad.name;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &b);
+
+	return TRUE;
+}
+
+static gboolean include_appearance_exists(const GDBusPropertyTable *property,
+							void *data)
+{
+	return ad.appearance;
+}
+
+static gboolean get_include_appearance(const GDBusPropertyTable *property,
+				DBusMessageIter *iter, void *user_data)
+{
+	dbus_bool_t b = ad.appearance;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &b);
 
 	return TRUE;
 }
@@ -275,17 +309,19 @@ static const GDBusPropertyTable ad_props[] = {
 						manufacturer_data_exists },
 	{ "IncludeTxPower", "b", get_tx_power, NULL, tx_power_exists },
 	{ "IncludeName", "b", get_include_name, NULL, include_name_exists },
+	{ "IncludeAppearance", "b", get_include_appearance, NULL,
+						include_appearance_exists },
 	{ }
 };
 
 void ad_register(DBusConnection *conn, GDBusProxy *manager, const char *type)
 {
-	if (registered == TRUE) {
+	if (ad.registered) {
 		rl_printf("Advertisement is already registered\n");
 		return;
 	}
 
-	ad_type = g_strdup(type);
+	ad.type = g_strdup(type);
 
 	if (g_dbus_register_interface(conn, AD_PATH, AD_IFACE, ad_methods,
 					NULL, ad_props, NULL, NULL) == FALSE) {
@@ -316,7 +352,7 @@ static void unregister_reply(DBusMessage *message, void *user_data)
 	dbus_error_init(&error);
 
 	if (dbus_set_error_from_message(&error, message) == FALSE) {
-		registered = FALSE;
+		ad.registered = false;
 		rl_printf("Advertising object unregistered\n");
 		if (g_dbus_unregister_interface(conn, AD_PATH,
 							AD_IFACE) == FALSE)
@@ -333,7 +369,7 @@ void ad_unregister(DBusConnection *conn, GDBusProxy *manager)
 	if (!manager)
 		ad_release(conn);
 
-	if (!registered)
+	if (!ad.registered)
 		return;
 
 	if (g_dbus_proxy_method_call(manager, "UnregisterAdvertisement",
@@ -346,34 +382,33 @@ void ad_unregister(DBusConnection *conn, GDBusProxy *manager)
 
 void ad_advertise_uuids(const char *arg)
 {
-	g_strfreev(ad_uuids);
-	ad_uuids = NULL;
-	ad_uuids_len = 0;
+	g_strfreev(ad.uuids);
+	ad.uuids = NULL;
+	ad.uuids_len = 0;
 
 	if (!arg || !strlen(arg))
 		return;
 
-	ad_uuids = g_strsplit(arg, " ", -1);
-	if (!ad_uuids) {
+	ad.uuids = g_strsplit(arg, " ", -1);
+	if (!ad.uuids) {
 		rl_printf("Failed to parse input\n");
 		return;
 	}
 
-	ad_uuids_len = g_strv_length(ad_uuids);
+	ad.uuids_len = g_strv_length(ad.uuids);
 }
 
 static void ad_clear_service(void)
 {
-	g_free(ad_service_uuid);
-	ad_service_uuid = NULL;
-	memset(ad_service_data, 0, sizeof(ad_service_data));
-	ad_service_data_len = 0;
+	g_free(ad.service.uuid);
+	memset(&ad.service, 0, sizeof(ad.service));
 }
 
 void ad_advertise_service(const char *arg)
 {
 	wordexp_t w;
 	unsigned int i;
+	struct ad_data *data;
 
 	if (wordexp(arg, &w, WRDE_NOCMD)) {
 		rl_printf("Invalid argument\n");
@@ -385,13 +420,14 @@ void ad_advertise_service(const char *arg)
 	if (w.we_wordc == 0)
 		goto done;
 
-	ad_service_uuid = g_strdup(w.we_wordv[0]);
+	ad.service.uuid = g_strdup(w.we_wordv[0]);
+	data = &ad.service.data;
 
 	for (i = 1; i < w.we_wordc; i++) {
 		long int val;
 		char *endptr = NULL;
 
-		if (i >= G_N_ELEMENTS(ad_service_data)) {
+		if (i >= G_N_ELEMENTS(data->data)) {
 			rl_printf("Too much data\n");
 			goto done;
 		}
@@ -403,8 +439,8 @@ void ad_advertise_service(const char *arg)
 			goto done;
 		}
 
-		ad_service_data[ad_service_data_len] = val;
-		ad_service_data_len++;
+		data->data[data->len] = val;
+		data->len++;
 	}
 
 done:
@@ -413,9 +449,7 @@ done:
 
 static void ad_clear_manufacturer(void)
 {
-	ad_manufacturer_id = 0;
-	memset(ad_manufacturer_data, 0, sizeof(ad_manufacturer_data));
-	ad_manufacturer_data_len = 0;
+	memset(&ad.manufacturer, 0, sizeof(ad.manufacturer));
 }
 
 void ad_advertise_manufacturer(const char *arg)
@@ -424,6 +458,7 @@ void ad_advertise_manufacturer(const char *arg)
 	unsigned int i;
 	char *endptr = NULL;
 	long int val;
+	struct ad_data *data;
 
 	if (wordexp(arg, &w, WRDE_NOCMD)) {
 		rl_printf("Invalid argument\n");
@@ -441,10 +476,11 @@ void ad_advertise_manufacturer(const char *arg)
 		goto done;
 	}
 
-	ad_manufacturer_id = val;
+	ad.manufacturer.id = val;
+	data = &ad.manufacturer.data;
 
 	for (i = 1; i < w.we_wordc; i++) {
-		if (i >= G_N_ELEMENTS(ad_service_data)) {
+		if (i >= G_N_ELEMENTS(data->data)) {
 			rl_printf("Too much data\n");
 			goto done;
 		}
@@ -456,8 +492,8 @@ void ad_advertise_manufacturer(const char *arg)
 			goto done;
 		}
 
-		ad_manufacturer_data[ad_manufacturer_data_len] = val;
-		ad_manufacturer_data_len++;
+		data->data[data->len] = val;
+		data->len++;
 	}
 
 done:
@@ -465,12 +501,17 @@ done:
 }
 
 
-void ad_advertise_tx_power(gboolean value)
+void ad_advertise_tx_power(bool value)
+{
+	ad.tx_power = value;
+}
+
+void ad_advertise_name(bool value)
 {
-	ad_tx_power = value;
+	ad.name = value;
 }
 
-void ad_advertise_name(gboolean value)
+void ad_advertise_appearance(bool value)
 {
-	ad_name = value;
+	ad.appearance = value;
 }
diff --git a/client/advertising.h b/client/advertising.h
index a41a2742d..77fc1cca5 100644
--- a/client/advertising.h
+++ b/client/advertising.h
@@ -27,5 +27,6 @@ void ad_unregister(DBusConnection *conn, GDBusProxy *manager);
 void ad_advertise_uuids(const char *arg);
 void ad_advertise_service(const char *arg);
 void ad_advertise_manufacturer(const char *arg);
-void ad_advertise_tx_power(gboolean value);
-void ad_advertise_name(gboolean value);
+void ad_advertise_tx_power(bool value);
+void ad_advertise_name(bool value);
+void ad_advertise_appearance(bool value);
diff --git a/client/main.c b/client/main.c
index 44de8c0a0..0bc2a8896 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2350,12 +2350,12 @@ static void cmd_set_advertise_tx_power(const char *arg)
 	}
 
 	if (strcmp(arg, "on") == 0 || strcmp(arg, "yes") == 0) {
-		ad_advertise_tx_power(TRUE);
+		ad_advertise_tx_power(true);
 		return;
 	}
 
 	if (strcmp(arg, "off") == 0 || strcmp(arg, "no") == 0) {
-		ad_advertise_tx_power(FALSE);
+		ad_advertise_tx_power(false);
 		return;
 	}
 
@@ -2370,12 +2370,32 @@ static void cmd_set_advertise_name(const char *arg)
 	}
 
 	if (strcmp(arg, "on") == 0 || strcmp(arg, "yes") == 0) {
-		ad_advertise_name(TRUE);
+		ad_advertise_name(true);
 		return;
 	}
 
 	if (strcmp(arg, "off") == 0 || strcmp(arg, "no") == 0) {
-		ad_advertise_name(FALSE);
+		ad_advertise_name(false);
+		return;
+	}
+
+	rl_printf("Invalid argument\n");
+}
+
+static void cmd_set_advertise_appearance(const char *arg)
+{
+	if (arg == NULL || strlen(arg) == 0) {
+		rl_printf("Missing value argument\n");
+		return;
+	}
+
+	if (strcmp(arg, "on") == 0 || strcmp(arg, "yes") == 0) {
+		ad_advertise_appearance(true);
+		return;
+	}
+
+	if (strcmp(arg, "off") == 0 || strcmp(arg, "no") == 0) {
+		ad_advertise_appearance(false);
 		return;
 	}
 
@@ -2428,6 +2448,8 @@ static const struct {
 			"Enable/disable TX power to be advertised" },
 	{ "set-advertise-name", "<on/off>", cmd_set_advertise_name,
 			"Enable/disable local name to be advertised" },
+	{ "set-advertise-appearance", "<value>", cmd_set_advertise_appearance,
+			"Set custom appearance to be advertised" },
 	{ "set-scan-filter-uuids", "[uuid1 uuid2 ...]",
 			cmd_set_scan_filter_uuids, "Set scan filter uuids" },
 	{ "set-scan-filter-rssi", "[rssi]", cmd_set_scan_filter_rssi,
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 7/7] advertising: Consolidate Include* into a single property
  2017-08-04  9:16 [PATCH v3 1/7] advertising: Rename AdvertisementInstaces to AdvertisingInstaces Luiz Augusto von Dentz
                   ` (4 preceding siblings ...)
  2017-08-04  9:16 ` [PATCH v3 6/7] client: Add set-advertise-name command Luiz Augusto von Dentz
@ 2017-08-04  9:16 ` Luiz Augusto von Dentz
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2017-08-04  9:16 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This makes it easier to add new features and makes the code a lot
cleaner as well.

Note: Advertising related APIs are still experimental so it still possible
to make changes like this.
---
 client/advertising.c    | 54 ++++++++++++-------------------
 doc/advertising-api.txt | 12 +++----
 src/advertising.c       | 86 ++++++++++++++++++-------------------------------
 3 files changed, 56 insertions(+), 96 deletions(-)

diff --git a/client/advertising.c b/client/advertising.c
index a90127b9c..53e2c4bc0 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -254,49 +254,39 @@ static gboolean get_manufacturer_data(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
-static gboolean tx_power_exists(const GDBusPropertyTable *property, void *data)
+static gboolean include_features_exists(const GDBusPropertyTable *property,
+								void *data)
 {
-	return ad.tx_power;
+	return ad.tx_power || ad.name || ad.appearance;
 }
 
-static gboolean get_tx_power(const GDBusPropertyTable *property,
+static gboolean get_include_features(const GDBusPropertyTable *property,
 				DBusMessageIter *iter, void *user_data)
 {
-	dbus_bool_t b = ad.tx_power;
+	DBusMessageIter array;
 
-	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &b);
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "as", &array);
 
-	return TRUE;
-}
+	if (ad.tx_power) {
+		const char *str = "tx-power";
 
-static gboolean include_name_exists(const GDBusPropertyTable *property,
-							void *data)
-{
-	return ad.name;
-}
+		dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &str);
+	}
 
-static gboolean get_include_name(const GDBusPropertyTable *property,
-				DBusMessageIter *iter, void *user_data)
-{
-	dbus_bool_t b = ad.name;
+	if (ad.name) {
+		const char *str = "local-name";
 
-	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &b);
+		dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &str);
+	}
 
-	return TRUE;
-}
+	if (ad.appearance) {
+		const char *str = "appearance";
 
-static gboolean include_appearance_exists(const GDBusPropertyTable *property,
-							void *data)
-{
-	return ad.appearance;
-}
+		dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &str);
+	}
 
-static gboolean get_include_appearance(const GDBusPropertyTable *property,
-				DBusMessageIter *iter, void *user_data)
-{
-	dbus_bool_t b = ad.appearance;
+	dbus_message_iter_close_container(iter, &array);
 
-	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &b);
 
 	return TRUE;
 }
@@ -307,10 +297,8 @@ static const GDBusPropertyTable ad_props[] = {
 	{ "ServiceData", "a{sv}", get_service_data, NULL, service_data_exists },
 	{ "ManufacturerData", "a{qv}", get_manufacturer_data, NULL,
 						manufacturer_data_exists },
-	{ "IncludeTxPower", "b", get_tx_power, NULL, tx_power_exists },
-	{ "IncludeName", "b", get_include_name, NULL, include_name_exists },
-	{ "IncludeAppearance", "b", get_include_appearance, NULL,
-						include_appearance_exists },
+	{ "IncludeFeatures", "as", get_include_features, NULL,
+						include_features_exists },
 	{ }
 };
 
diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt
index f4e7826b6..494edf27c 100644
--- a/doc/advertising-api.txt
+++ b/doc/advertising-api.txt
@@ -61,16 +61,12 @@ Properties	string Type
 			Service Data elements to include. The keys are the
 			UUID to associate with the data.
 
-		bool IncludeTxPower
+		array{string} IncludeFeatures
 
-			Includes the Tx Power in the advertising packet.
-			If missing, the Tx Power is not included.
+			Includes selected features in the advertising packet.
 
-		uint16 IncludeAppearance
-
-			Includes Appearance in the advertising packet.
-
-			Possible values: as found on Device.Appearance
+			Possible values: as found on
+					LEAdvertisingManager.SupportedFeatures
 
 		bool IncludeName
 
diff --git a/src/advertising.c b/src/advertising.c
index a39b82774..aaf9a0149 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -63,9 +63,7 @@ struct btd_adv_client {
 	GDBusProxy *proxy;
 	DBusMessage *reg;
 	uint8_t type; /* Advertising type */
-	bool include_tx_power;
-	bool include_name;
-	bool include_appearance;
+	uint32_t flags;
 	struct bt_ad *data;
 	uint8_t instance;
 };
@@ -385,49 +383,46 @@ fail:
 	return false;
 }
 
-static bool parse_include_tx_power(DBusMessageIter *iter,
-					struct btd_adv_client *client)
-{
-	dbus_bool_t b;
-
-	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
-		return false;
-
-	dbus_message_iter_get_basic(iter, &b);
-
-	client->include_tx_power = b;
-
-	return true;
-}
+static struct adv_feat {
+	uint8_t flag;
+	const char *name;
+} feats[] = {
+	{ MGMT_ADV_FLAG_TX_POWER, "tx-power",  },
+	{ MGMT_ADV_FLAG_APPEARANCE, "appearance" },
+	{ MGMT_ADV_FLAG_LOCAL_NAME, "local-name" },
+	{ },
+};
 
-static bool parse_include_name(DBusMessageIter *iter,
+static bool parse_include_features(DBusMessageIter *iter,
 					struct btd_adv_client *client)
 {
-	dbus_bool_t b;
+	DBusMessageIter entries;
 
-	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
 		return false;
 
-	dbus_message_iter_get_basic(iter, &b);
+	dbus_message_iter_recurse(iter, &entries);
+
+	while (dbus_message_iter_get_arg_type(&entries) == DBUS_TYPE_STRING) {
+		const char *str;
+		struct adv_feat *feat;
 
-	if (client->manager->supported_flags & MGMT_ADV_FLAG_LOCAL_NAME)
-		client->include_name = b;
+		dbus_message_iter_get_basic(&entries, &str);
 
-	return true;
-}
+		for (feat = feats; feat && feat->name; feat++) {
+			if (strcmp(str, feat->name))
+				continue;
 
-static bool parse_include_appearance(DBusMessageIter *iter,
-					struct btd_adv_client *client)
-{
-	dbus_bool_t b;
+			if (!(client->manager->supported_flags & feat->flag))
+				continue;
 
-	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
-		return false;
+			DBG("Including Feature: %s", str);
 
-	dbus_message_iter_get_basic(iter, &b);
+			client->flags |= feat->flag;
+		}
 
-	if (client->manager->supported_flags & MGMT_ADV_FLAG_APPEARANCE)
-		client->include_appearance = b;
+		dbus_message_iter_next(&entries);
+	}
 
 	return true;
 }
@@ -441,9 +436,7 @@ static struct adv_parser {
 	{ "SolicitUUIDs", parse_solicit_uuids },
 	{ "ManufacturerData", parse_manufacturer_data },
 	{ "ServiceData", parse_service_data },
-	{ "IncludeTxPower", parse_include_tx_power },
-	{ "IncludeName", parse_include_name },
-	{ "IncludeAppearance", parse_include_appearance },
+	{ "IncludeFeatures", parse_include_features },
 	{ },
 };
 
@@ -530,14 +523,7 @@ static DBusMessage *refresh_advertisement(struct btd_adv_client *client)
 	if (client->type == AD_TYPE_PERIPHERAL)
 		flags = MGMT_ADV_FLAG_CONNECTABLE | MGMT_ADV_FLAG_DISCOV;
 
-	if (client->include_tx_power)
-		flags |= MGMT_ADV_FLAG_TX_POWER;
-
-	if (client->include_name)
-		flags |= MGMT_ADV_FLAG_LOCAL_NAME;
-
-	if (client->include_appearance)
-		flags |= MGMT_ADV_FLAG_APPEARANCE;
+	flags |= client->flags;
 
 	adv_data = bt_ad_generate(client->data, &adv_data_len);
 
@@ -765,16 +751,6 @@ static gboolean get_instances(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
-static struct adv_feat {
-	uint8_t flag;
-	const char *name;
-} feats[] = {
-	{ MGMT_ADV_FLAG_TX_POWER, "tx-power" },
-	{ MGMT_ADV_FLAG_APPEARANCE, "appearance" },
-	{ MGMT_ADV_FLAG_LOCAL_NAME, "local-name" },
-	{ },
-};
-
 static void append_features(struct btd_adv_manager *manager,
 						DBusMessageIter *iter)
 {
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-08-04  9:16 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-04  9:16 [PATCH v3 1/7] advertising: Rename AdvertisementInstaces to AdvertisingInstaces Luiz Augusto von Dentz
2017-08-04  9:16 ` [PATCH v3 2/7] advertising: Add SupportedFeatures Luiz Augusto von Dentz
2017-08-04  9:16 ` [PATCH v3 3/7] advertising: Add IncludeName property Luiz Augusto von Dentz
2017-08-04  9:16 ` [PATCH v3 4/7] client: Add set-advertise-name command Luiz Augusto von Dentz
2017-08-04  9:16 ` [PATCH v3 5/7] advertising: Add IncludeAppearance property Luiz Augusto von Dentz
2017-08-04  9:16 ` [PATCH v3 6/7] client: Add set-advertise-name command Luiz Augusto von Dentz
2017-08-04  9:16 ` [PATCH v3 7/7] advertising: Consolidate Include* into a single property Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.