From 062911640c795f5eaffc0221a2060920807ceb01 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 12 Feb 2021 20:47:41 +0100 Subject: [PATCH] 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 --- src/examples/media-session/alsa-monitor.c | 20 ++++++++++++----- src/examples/media-session/bluez-monitor.c | 6 +++++- src/examples/media-session/media-session.c | 25 ++++++++++++++++++++++ src/examples/media-session/media-session.h | 3 +++ src/examples/media-session/v4l2-monitor.c | 11 ++++++---- 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/examples/media-session/alsa-monitor.c b/src/examples/media-session/alsa-monitor.c index d40e3a4bc..993e7122f 100644 --- a/src/examples/media-session/alsa-monitor.c +++ b/src/examples/media-session/alsa-monitor.c @@ -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) { diff --git a/src/examples/media-session/bluez-monitor.c b/src/examples/media-session/bluez-monitor.c index 3e2ff12d6..f4be1af65 100644 --- a/src/examples/media-session/bluez-monitor.c +++ b/src/examples/media-session/bluez-monitor.c @@ -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) { diff --git a/src/examples/media-session/media-session.c b/src/examples/media-session/media-session.c index d0ca6596b..5dac20d41 100644 --- a/src/examples/media-session/media-session.c +++ b/src/examples/media-session/media-session.c @@ -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; diff --git a/src/examples/media-session/media-session.h b/src/examples/media-session/media-session.h index 154a1f57f..f3b85697d 100644 --- a/src/examples/media-session/media-session.h +++ b/src/examples/media-session/media-session.h @@ -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 diff --git a/src/examples/media-session/v4l2-monitor.c b/src/examples/media-session/v4l2-monitor.c index da84e8c6b..66faea709 100644 --- a/src/examples/media-session/v4l2-monitor.c +++ b/src/examples/media-session/v4l2-monitor.c @@ -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);