summaryrefslogtreecommitdiffstats
path: root/lassi-avahi.c
diff options
context:
space:
mode:
Diffstat (limited to 'lassi-avahi.c')
-rw-r--r--lassi-avahi.c88
1 files changed, 53 insertions, 35 deletions
diff --git a/lassi-avahi.c b/lassi-avahi.c
index a247070..258c199 100644
--- a/lassi-avahi.c
+++ b/lassi-avahi.c
@@ -23,14 +23,14 @@ static void resolve_cb(
AvahiStringList *txt,
AvahiLookupResultFlags flags,
void* userdata) {
-
+
LassiAvahiInfo *i = userdata;
-
+
g_assert(r);
g_assert(i);
-
+
/* Called whenever a service has been resolved successfully or timed out */
-
+
switch (event) {
case AVAHI_RESOLVER_FOUND: {
char a[AVAHI_ADDRESS_STR_MAX], *t;
@@ -45,9 +45,9 @@ static void resolve_cb(
case AVAHI_RESOLVER_FAILURE:
g_message("Failed to resolve service '%s' of type '%s' in domain '%s': %s", name, type, domain, avahi_strerror(avahi_client_errno(i->client)));
break;
-
+
}
-
+
avahi_service_resolver_free(r);
}
@@ -63,7 +63,7 @@ static void browse_cb(
void* userdata) {
LassiAvahiInfo *i = userdata;
-
+
g_assert(b);
g_assert(i);
@@ -73,11 +73,11 @@ static void browse_cb(
if (!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN) &&
!lassi_server_is_connected(i->server, name) &&
lassi_server_is_known(i->server, name))
-
+
if (!(avahi_service_resolver_new(i->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_cb, i)))
g_message("Failed to resolve service '%s': %s", name, avahi_strerror(avahi_client_errno(i->client)));
break;
-
+
case AVAHI_BROWSER_REMOVE:
case AVAHI_BROWSER_ALL_FOR_NOW:
case AVAHI_BROWSER_CACHE_EXHAUSTED:
@@ -95,36 +95,36 @@ static void create_service(LassiAvahiInfo *i);
static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) {
LassiAvahiInfo *i = userdata;
-
+
g_assert(g);
g_assert(i);
i->group = g;
-
+
switch (state) {
case AVAHI_ENTRY_GROUP_ESTABLISHED :
g_message("Service '%s' successfully established.", i->service_name);
break;
-
+
case AVAHI_ENTRY_GROUP_COLLISION : {
char *n;
-
+
n = avahi_alternative_service_name(i->service_name);
avahi_free(i->service_name);
i->service_name = n;
-
+
g_message("Service name collision, renaming service to '%s'", n);
-
+
/* And recreate the services */
create_service(i);
break;
}
-
- case AVAHI_ENTRY_GROUP_FAILURE :
+
+ case AVAHI_ENTRY_GROUP_FAILURE :
g_message("Entry group failure: %s", avahi_strerror(avahi_client_errno(i->client)));
gtk_main_quit();
break;
-
+
case AVAHI_ENTRY_GROUP_UNCOMMITED:
case AVAHI_ENTRY_GROUP_REGISTERING:
;
@@ -144,13 +144,31 @@ static void create_service(LassiAvahiInfo *i) {
if (avahi_entry_group_is_empty(i->group)) {
int ret;
- if (!i->service_name)
- i->service_name = g_strdup(i->server->id);
-
- if ((ret = avahi_entry_group_add_service(i->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, i->service_name, LASSI_SERVICE_TYPE, NULL, NULL, i->server->port, NULL)) < 0) {
- g_message("Failed to add service: %s", avahi_strerror(ret));
- gtk_main_quit();
- return;
+ for (;;) {
+
+ if (!i->service_name)
+ i->service_name = g_strdup(i->server->id);
+
+ if ((ret = avahi_entry_group_add_service(i->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, i->service_name, LASSI_SERVICE_TYPE, NULL, NULL, i->server->port, NULL)) < 0) {
+
+ if (ret == AVAHI_ERR_COLLISION) {
+ char *n = avahi_alternative_service_name(i->service_name);
+ avahi_free(i->service_name);
+ i->service_name = n;
+ continue;
+ }
+
+ g_message("Failed to add service: %s", avahi_strerror(ret));
+ gtk_main_quit();
+ return;
+ }
+
+ break;
+ }
+
+ if (strcmp(i->service_name, i->server->id)) {
+ g_free(i->server->id);
+ i->server->id = g_strdup(i->service_name);
}
if ((ret = avahi_entry_group_commit(i->group)) < 0) {
@@ -171,27 +189,27 @@ static void client_cb(AvahiClient *client, AvahiClientState state, void *userdat
if (!i->group)
create_service(i);
break;
-
+
case AVAHI_CLIENT_FAILURE:
g_message("Client failure: %s", avahi_strerror(avahi_client_errno(client)));
gtk_main_quit();
break;
-
+
case AVAHI_CLIENT_S_COLLISION:
case AVAHI_CLIENT_S_REGISTERING:
if (i->group)
avahi_entry_group_reset(i->group);
-
+
break;
-
+
case AVAHI_CLIENT_CONNECTING:
;
}
}
-
+
int lassi_avahi_init(LassiAvahiInfo *i, LassiServer *server) {
int error;
-
+
g_assert(i);
g_assert(server);
@@ -204,7 +222,7 @@ int lassi_avahi_init(LassiAvahiInfo *i, LassiServer *server) {
g_message("avahi_glib_poll_new() failed.");
goto fail;
}
-
+
if (!(i->client = avahi_client_new(avahi_glib_poll_get(i->poll), 0, client_cb, i, &error))) {
g_message("avahi_client_new() failed: %s", avahi_strerror(error));
goto fail;
@@ -214,7 +232,7 @@ int lassi_avahi_init(LassiAvahiInfo *i, LassiServer *server) {
g_message("avahi_service_browser_new(): %s", avahi_strerror(avahi_client_errno(i->client)));
goto fail;
}
-
+
return 0;
fail:
@@ -224,7 +242,7 @@ fail:
void lassi_avahi_done(LassiAvahiInfo *i) {
g_assert(i);
-
+
if (i->client)
avahi_client_free(i->client);
@@ -232,6 +250,6 @@ void lassi_avahi_done(LassiAvahiInfo *i) {
avahi_glib_poll_free(i->poll);
g_free(i->service_name);
-
+
memset(i, 0, sizeof(*i));
}