[PATCH v6 5/7] advertising: Add IncludeAppearance property

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

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 bcf415c1c..3dbc2270f 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

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux