Hey,
I have written a small patch that allows the module-zeroconf-publish module
to export the service for both cards, even though they originally had the
same name. In the get_service() I have extracted the content that dealt with
naming the service to a separate function, get_service_name(). Then, if the
registration of the service fails, a loop is entered, trying to add ".%d" to
the name until it succeeds (or a limit of 100 is reached), basically the
same strategy used in pa_namereg_register().
Without this patch, PA refuses to export the second card over the network.
Would be nice if this patch (or something similar) is added to the PA
system.
Thanks,
-Ivar!
diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c
index d72d264..ecca4cc 100644
--- a/src/modules/module-zeroconf-publish.c
+++ b/src/modules/module-zeroconf-publish.c
@@ -66,6 +66,7 @@ PA_MODULE_LOAD_ONCE(TRUE);
#define SERVICE_SUBTYPE_SOURCE_VIRTUAL "_virtual._sub."SERVICE_TYPE_SOURCE
#define SERVICE_SUBTYPE_SOURCE_MONITOR "_monitor._sub."SERVICE_TYPE_SOURCE
#define SERVICE_SUBTYPE_SOURCE_NON_MONITOR "_non-monitor._sub."SERVICE_TYPE_SOURCE
+#define MAX_NUM_LEN 16
static const char* const valid_modargs[] = {
NULL
@@ -222,6 +223,46 @@ static uint16_t compute_port(struct userdata *u) {
return PA_NATIVE_DEFAULT_PORT;
}
+static char *get_service_name(pa_object *device, int service_number) {
+ char *service_name, *hn, *un;
+ const char *n;
+
+ pa_object_assert_ref(device);
+
+ if (pa_sink_isinstance(device)) {
+ if (!(n = pa_proplist_gets(PA_SINK(device)->proplist, PA_PROP_DEVICE_DESCRIPTION)))
+ n = PA_SINK(device)->name;
+ } else {
+ if (!(n = pa_proplist_gets(PA_SOURCE(device)->proplist, PA_PROP_DEVICE_DESCRIPTION)))
+ n = PA_SOURCE(device)->name;
+ }
+
+ hn = pa_get_host_name_malloc();
+ un = pa_get_user_name_malloc();
+
+ if (service_number) {
+ char label[AVAHI_LABEL_MAX];
+ char number_label[MAX_NUM_LEN];
+ char * number_label_write_to;
+ pa_snprintf(label, AVAHI_LABEL_MAX, "%...@%s: %s", un, hn, n);
+ pa_snprintf(number_label, MAX_NUM_LEN, ".%d", service_number);
+ if(strlen(label) + strlen(number_label) > AVAHI_LABEL_MAX-1) {
+ number_label_write_to = label + AVAHI_LABEL_MAX-1 - strlen(number_label);
+ } else {
+ number_label_write_to = label + strlen(label);
+ }
+ pa_snprintf(number_label_write_to, MAX_NUM_LEN, "%s", number_label);
+ service_name = pa_truncate_utf8(pa_sprintf_malloc("%s", label), AVAHI_LABEL_MAX);
+ } else {
+ service_name = pa_truncate_utf8(pa_sprintf_malloc("%...@%s: %s", un, hn, n), AVAHI_LABEL_MAX);
+ }
+
+ pa_xfree(un);
+ pa_xfree(hn);
+
+ return service_name;
+}
+
static int publish_service(struct service *s) {
int r = -1;
AvahiStringList *txt = NULL;
@@ -231,6 +272,7 @@ static int publish_service(struct service *s) {
pa_channel_map map;
char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
enum service_subtype subtype;
+ pa_bool_t found_service_name = TRUE;
const char * const subtype_text[] = {
[SUBTYPE_HARDWARE] = "hardware",
@@ -284,9 +326,31 @@ static int publish_service(struct service *s) {
NULL,
compute_port(s->userdata),
txt) < 0) {
-
- pa_log("avahi_entry_group_add_service_strlst(): %s", avahi_strerror(avahi_client_errno(s->userdata->client)));
- goto finish;
+ found_service_name = FALSE;
+ }
+ if(!found_service_name) {
+ int i;
+ for(i=2; i<100; ++i) {
+ pa_xfree(s->service_name);
+ s->service_name = get_service_name(s->device, i);
+ if (avahi_entry_group_add_service_strlst(
+ s->entry_group,
+ AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
+ 0,
+ s->service_name,
+ pa_sink_isinstance(s->device) ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE,
+ NULL,
+ NULL,
+ compute_port(s->userdata),
+ txt) >= 0) {
+ found_service_name = TRUE;
+ break;
+ }
+ }
+ if(!found_service_name) {
+ pa_log("avahi_entry_group_add_service_strlst(): %s", avahi_strerror(avahi_client_errno(s->userdata->client)));
+ goto finish;
+ }
}
if (avahi_entry_group_add_service_subtype(
@@ -339,8 +403,6 @@ finish:
static struct service *get_service(struct userdata *u, pa_object *device) {
struct service *s;
- char *hn, *un;
- const char *n;
pa_assert(u);
pa_object_assert_ref(device);
@@ -353,21 +415,7 @@ static struct service *get_service(struct userdata *u, pa_object *device) {
s->entry_group = NULL;
s->device = device;
- if (pa_sink_isinstance(device)) {
- if (!(n = pa_proplist_gets(PA_SINK(device)->proplist, PA_PROP_DEVICE_DESCRIPTION)))
- n = PA_SINK(device)->name;
- } else {
- if (!(n = pa_proplist_gets(PA_SOURCE(device)->proplist, PA_PROP_DEVICE_DESCRIPTION)))
- n = PA_SOURCE(device)->name;
- }
-
- hn = pa_get_host_name_malloc();
- un = pa_get_user_name_malloc();
-
- s->service_name = pa_truncate_utf8(pa_sprintf_malloc("%...@%s: %s", un, hn, n), AVAHI_LABEL_MAX-1);
-
- pa_xfree(un);
- pa_xfree(hn);
+ s->service_name = get_service_name(device, 0);
pa_hashmap_put(u->services, s->device, s);
_______________________________________________
pulseaudio-discuss mailing list
[email protected]
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss