policy-node: support target.object property

This commit is contained in:
Pauli Virtanen 2022-03-06 15:57:28 +02:00 committed by Wim Taymans
parent 6b03c11b70
commit f4ad06946b

View file

@ -575,14 +575,25 @@ static bool check_node_name(struct node *node, const char *name)
return false; return false;
} }
static struct node *find_node_by_id_name(struct impl *impl, uint32_t id, const char *name) static struct node *find_node_by_id_name(struct impl *impl, uint32_t id, const char *name, bool name_is_serial)
{ {
struct node *node; struct node *node;
uint32_t name_id = name ? (uint32_t)atoi(name) : SPA_ID_INVALID; uint32_t name_id = SPA_ID_INVALID;
uint64_t serial = SPA_ID_INVALID;
if (name_is_serial) {
if (spa_atou64(name, &serial, 0))
name = NULL;
} else {
if (spa_atou32(name, &name_id, 0))
name = NULL;
}
spa_list_for_each(node, &impl->node_list, link) { spa_list_for_each(node, &impl->node_list, link) {
if (node->id == id || node->id == name_id) if (node->id == id || node->id == name_id)
return node; return node;
if (node->obj->obj.serial == serial && serial != SPA_ID_INVALID)
return node;
if (check_node_name(node, name)) if (check_node_name(node, name))
return node; return node;
} }
@ -640,18 +651,29 @@ static const char *get_device_name(struct node *node)
return pw_properties_get(node->obj->obj.props, PW_KEY_NODE_NAME); return pw_properties_get(node->obj->obj.props, PW_KEY_NODE_NAME);
} }
static uint32_t find_device_for_name(struct impl *impl, const char *name) static uint32_t find_device_for_name(struct impl *impl, const char *name, bool is_serial, bool is_id)
{ {
struct node *node; struct node *node;
const char *str; const char *str;
uint32_t id = atoi(name); uint32_t id = SPA_ID_INVALID;
uint64_t serial = SPA_ID_INVALID;
if (is_serial) {
if (spa_atou64(name, &serial, 0))
name = NULL;
} else if (is_id) {
if (spa_atou32(name, &id, 0))
name = NULL;
}
spa_list_for_each(node, &impl->node_list, link) { spa_list_for_each(node, &impl->node_list, link) {
if (id == node->obj->obj.id) if (id == node->obj->obj.id)
return id; return id;
if (serial == node->obj->obj.serial && serial != SPA_ID_INVALID)
return node->obj->obj.id;
if ((str = get_device_name(node)) == NULL) if ((str = get_device_name(node)) == NULL)
continue; continue;
if (spa_streq(str, name)) if (name != NULL && spa_streq(str, name))
return node->obj->obj.id; return node->obj->obj.id;
} }
return SPA_ID_INVALID; return SPA_ID_INVALID;
@ -1100,15 +1122,22 @@ static int rescan_node(struct impl *impl, struct node *n)
/* honor target node set by user or asked for by the client */ /* honor target node set by user or asked for by the client */
path_id = SPA_ID_INVALID; path_id = SPA_ID_INVALID;
if (n->obj->target_node != NULL) if (n->obj->target_node != NULL)
path_id = find_device_for_name(impl, n->obj->target_node); path_id = find_device_for_name(impl, n->obj->target_node, false, false);
if (!n->obj->fixed_target && if (!n->obj->fixed_target) {
(str = spa_dict_lookup(props, PW_KEY_NODE_TARGET)) != NULL) { bool is_serial = true;
bool has_target = ((uint32_t)atoi(str) != SPA_ID_INVALID); str = spa_dict_lookup(props, PW_KEY_TARGET_OBJECT);
path_id = find_device_for_name(impl, str); if (str == NULL) {
if (!reconnect && has_target && path_id == SPA_ID_INVALID) { str = spa_dict_lookup(props, PW_KEY_NODE_TARGET);
/* don't use fallbacks for non-reconnecting nodes */ is_serial = false;
peer = NULL; }
goto do_link; if (str) {
bool has_target = ((uint32_t)atoi(str) != SPA_ID_INVALID);
path_id = find_device_for_name(impl, str, is_serial, !is_serial);
if (!reconnect && has_target && path_id == SPA_ID_INVALID) {
/* don't use fallbacks for non-reconnecting nodes */
peer = NULL;
goto do_link;
}
} }
} }
@ -1359,10 +1388,10 @@ static int metadata_property(void *object, uint32_t subject,
} }
if (changed) if (changed)
sm_media_session_schedule_rescan(impl->session); sm_media_session_schedule_rescan(impl->session);
} else if (key == NULL || spa_streq(key, "target.node")) { } else if (key == NULL || spa_streq(key, "target.node") || spa_streq(key, "target.object")) {
struct node *src_node; struct node *src_node;
src_node = find_node_by_id_name(impl, subject, NULL); src_node = find_node_by_id_name(impl, subject, NULL, false);
if (!src_node) if (!src_node)
return 0; return 0;
@ -1374,8 +1403,9 @@ static int metadata_property(void *object, uint32_t subject,
} else { } else {
const char *str; const char *str;
struct node *dst_node; struct node *dst_node;
bool is_serial = spa_streq(key, "target.object");
dst_node = find_node_by_id_name(impl, SPA_ID_INVALID, value); dst_node = find_node_by_id_name(impl, SPA_ID_INVALID, value, is_serial);
if (dst_node) { if (dst_node) {
str = get_device_name(dst_node); str = get_device_name(dst_node);
if (!str) if (!str)