From 0edc2c1447a7c71f04445660daa73f00596d112a Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 5 Aug 2020 15:10:44 +0200 Subject: enforce unique values for node keys starting with "+" --- src/pipewire/impl-node.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- src/pipewire/keys.h | 2 +- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index bf52d636..9ec3c4ad 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -41,6 +41,8 @@ #define DEFAULT_SYNC_TIMEOUT ((uint64_t)(5 * SPA_NSEC_PER_SEC)) +static int update_properties(struct pw_impl_node *node, const struct spa_dict *dict); + /** \cond */ struct impl { struct pw_impl_node this; @@ -654,7 +656,8 @@ int pw_impl_node_register(struct pw_impl_node *this, pw_properties_setf(this->properties, PW_KEY_OBJECT_ID, "%d", this->info.id); this->info.props = &this->properties->dict; - pw_global_update_keys(this->global, &this->properties->dict, keys); + update_properties(this, this->info.props); + pw_global_update_keys(this->global, this->info.props, keys); pw_impl_node_initialized(this); @@ -1169,11 +1172,52 @@ const struct pw_properties *pw_impl_node_get_properties(struct pw_impl_node *nod return node->properties; } +static int pw_properties_update_unique(struct pw_properties *props, + const struct spa_dict *dict, uint32_t unique, + int (*unique_check) (void *data, const char *key, const char *val), + void *data) +{ + int changed; + const struct spa_dict_item *it; + struct pw_properties *new = pw_properties_new(NULL, NULL); + + spa_dict_for_each(it, dict) { + if (it->key[0] != '+') { + pw_properties_set(new, it->key, it->value); + } else if (!unique_check(data, it->key, it->value)) { + pw_properties_setf(new, it->key, + "%s-%d", it->value, unique); + } else { + pw_properties_set(new, it->key, it->value); + } + } + changed = pw_properties_update(props, &new->dict); + pw_properties_free(new); + return changed; +} + +static int node_unique_check(void *data, const char *key, const char *value) +{ + struct pw_impl_node *this = data, *n; + struct pw_context *context = this->context; + const char *str; + + spa_list_for_each(n, &context->node_list, link) { + if (n == this) + continue; + if ((str = pw_properties_get(n->properties, key)) != NULL && + strcmp(str, value) == 0) + return 0; + } + return 1; +} + static int update_properties(struct pw_impl_node *node, const struct spa_dict *dict) { int changed; - changed = pw_properties_update(node->properties, dict); + changed = pw_properties_update_unique(node->properties, dict, node->info.id, + node_unique_check, node); node->info.props = &node->properties->dict; pw_log_debug(NAME" %p: updated %d properties", node, changed); diff --git a/src/pipewire/keys.h b/src/pipewire/keys.h index 9925eeca..d27e03d5 100644 --- a/src/pipewire/keys.h +++ b/src/pipewire/keys.h @@ -119,7 +119,7 @@ extern "C" { /** Node keys */ #define PW_KEY_NODE_ID "node.id" /**< node id */ -#define PW_KEY_NODE_NAME "node.name" /**< node name */ +#define PW_KEY_NODE_NAME "+node.name" /**< node name */ #define PW_KEY_NODE_NICK "node.nick" /**< short node name */ #define PW_KEY_NODE_DESCRIPTION "node.description" /**< localized human readable node one-line * description. Ex. "Foobar USB Headset" */ -- cgit v1.2.3