media-session: sanitize name and nick

Replace unwanted chars in the name with _. This makes it compatible
with pulseaudio names and avoids problems with regex.
Replace unwanred chars in the nick with ' '. This ensures JACK
clients don't receive ':' in the device names, which cause it to
fail when parsing the ports.

See #714 and #130
This commit is contained in:
Wim Taymans 2021-02-12 20:47:41 +01:00
parent ac910c7c1c
commit 062911640c
5 changed files with 55 additions and 10 deletions

View file

@ -210,6 +210,7 @@ static struct node *alsa_create_node(struct device *device, uint32_t id,
struct impl *impl = device->impl;
int res;
const char *dev, *subdev, *stream, *profile, *profile_desc, *rules;
char name[1024];
int i, priority;
pw_log_debug("new node %u", id);
@ -282,12 +283,16 @@ static struct node *alsa_create_node(struct device *device, uint32_t id,
}
if (pw_properties_get(node->props, PW_KEY_NODE_NICK) == NULL) {
const char *s;
s = pw_properties_get(device->props, PW_KEY_DEVICE_NICK);
if (s == NULL)
s = pw_properties_get(device->props, SPA_KEY_API_ALSA_CARD_NAME);
if (s == NULL)
s = pw_properties_get(device->props, "alsa.card_name");
pw_properties_set(node->props, PW_KEY_NODE_NICK, s);
pw_properties_set(node->props, PW_KEY_NODE_NICK,
sm_media_session_sanitize_name(name, sizeof(name),
' ', "%s", s));
}
if (pw_properties_get(node->props, SPA_KEY_NODE_NAME) == NULL) {
@ -297,9 +302,12 @@ static struct node *alsa_create_node(struct device *device, uint32_t id,
devname = "unnamed-device";
if (strstr(devname, "alsa_card.") == devname)
devname += 10;
pw_properties_setf(node->props, SPA_KEY_NODE_NAME, "%s.%s.%s",
pw_properties_set(node->props, SPA_KEY_NODE_NAME,
sm_media_session_sanitize_name(name, sizeof(name),
'_', "%s.%s.%s",
node->direction == PW_DIRECTION_OUTPUT ?
"alsa_input" : "alsa_output", devname, profile);
"alsa_input" : "alsa_output", devname, profile));
for (i = 2; i <= 99; i++) {
if ((d = pw_properties_get(node->props, PW_KEY_NODE_NAME)) == NULL)
@ -308,9 +316,11 @@ static struct node *alsa_create_node(struct device *device, uint32_t id,
if (alsa_find_node(device, SPA_ID_INVALID, d) == NULL)
break;
pw_properties_setf(node->props, SPA_KEY_NODE_NAME, "%s.%s.%s.%d",
pw_properties_set(node->props, SPA_KEY_NODE_NAME,
sm_media_session_sanitize_name(name, sizeof(name),
'_', "%s.%s.%s.%d",
node->direction == PW_DIRECTION_OUTPUT ?
"alsa_input" : "alsa_output", devname, profile, i);
"alsa_input" : "alsa_output", devname, profile, i));
}
}
if (pw_properties_get(node->props, PW_KEY_NODE_DESCRIPTION) == NULL) {

View file

@ -133,6 +133,7 @@ static struct node *bluez5_create_node(struct device *device, uint32_t id,
int res;
const char *prefix, *str, *profile, *rules;
int priority;
char name[1024];
pw_log_debug("new node %u", id);
@ -175,7 +176,10 @@ static struct node *bluez5_create_node(struct device *device, uint32_t id,
else
prefix = info->factory_name;
pw_properties_setf(node->props, PW_KEY_NODE_NAME, "%s.%s.%s", prefix, str, profile);
pw_properties_set(node->props, PW_KEY_NODE_NAME,
sm_media_session_sanitize_name(name, sizeof(name),
'_', "%s.%s.%s", prefix, str, profile));
pw_properties_set(node->props, PW_KEY_FACTORY_NAME, info->factory_name);
if (pw_properties_get(node->props, PW_KEY_PRIORITY_DRIVER) == NULL) {

View file

@ -1798,6 +1798,31 @@ int sm_media_session_save_state(struct sm_media_session *sess,
return pw_conf_save_state(SESSION_PREFIX, name, props);
}
char *sm_media_session_sanitize_name(char *name, int size, char sub, const char *fmt, ...)
{
char *p;
va_list varargs;
va_start(varargs, fmt);
if (vsnprintf(name, size, fmt, varargs) < 0)
return NULL;
va_end(varargs);
for (p = name; *p; p++) {
switch(*p) {
case '0' ... '9':
case 'a' ... 'z':
case 'A' ... 'Z':
case '.': case '-': case '_':
break;
default:
*p = sub;
break;
}
}
return name;
}
static void monitor_core_done(void *data, uint32_t id, int seq)
{
struct impl *impl = data;

View file

@ -300,6 +300,9 @@ int sm_media_session_save_state(struct sm_media_session *sess,
int sm_media_session_match_rules(const char *rules, size_t size,
struct pw_properties *props);
char *sm_media_session_sanitize_name(char *name, int size, char sub,
const char *fmt, ...) SPA_PRINTF_FUNC(4, 5);
#ifdef __cplusplus
}
#endif

View file

@ -128,6 +128,7 @@ static struct node *v4l2_create_node(struct device *dev, uint32_t id,
struct impl *impl = dev->impl;
int i, res;
const char *prefix, *str, *d, *rules;
char name[1024];
pw_log_debug("new node %u", id);
@ -162,8 +163,9 @@ static struct node *v4l2_create_node(struct device *dev, uint32_t id,
else
prefix = info->factory_name;
pw_properties_setf(node->props, PW_KEY_NODE_NAME, "%s.%s", prefix, str);
pw_properties_set(node->props, PW_KEY_NODE_NAME,
sm_media_session_sanitize_name(name, sizeof(name),
'_', "%s.%s", prefix, str));
for (i = 2; i <= 99; i++) {
if ((d = pw_properties_get(node->props, PW_KEY_NODE_NAME)) == NULL)
break;
@ -171,8 +173,9 @@ static struct node *v4l2_create_node(struct device *dev, uint32_t id,
if (v4l2_find_node(dev, SPA_ID_INVALID, d) == NULL)
break;
pw_properties_setf(node->props, PW_KEY_NODE_NAME, "%s.%s.%d",
prefix, str, i);
pw_properties_set(node->props, PW_KEY_NODE_NAME,
sm_media_session_sanitize_name(name, sizeof(name),
'_', "%s.%s.%d", prefix, str, i));
}
str = pw_properties_get(dev->props, SPA_KEY_DEVICE_DESCRIPTION);