bool CZeroconfBrowserAvahi::doResolveService ( CZeroconfBrowser::ZeroconfService& fr_service, double f_timeout ) { { //wait for lock on event-loop to schedule resolving ScopedEventLoopBlock lock ( mp_poll ); //avahi can only resolve already discovered services, as it needs info from there tDiscoveredServices::const_iterator it = m_discovered_services.find( fr_service ); if ( it == m_discovered_services.end() ) { CLog::Log ( LOGERROR, "CZeroconfBrowserAvahi::doResolveService called with undiscovered service, resolving is NOT possible" ); return false; } //start resolving m_resolving_service = fr_service; m_resolved_event.Reset(); if ( !avahi_service_resolver_new ( mp_client, it->second.interface, it->second.protocol, it->first.GetName().c_str(), it->first.GetType().c_str(), it->first.GetDomain().c_str(), AVAHI_PROTO_UNSPEC, AvahiLookupFlags ( 0 ), resolveCallback, this ) ) { CLog::Log ( LOGERROR, "CZeroconfBrowserAvahi::doResolveService Failed to resolve service '%s': %s\n", it->first.GetName().c_str(), avahi_strerror ( avahi_client_errno ( mp_client ) ) ); return false; } } // end of this block releases lock of eventloop //wait for resolve to return or timeout m_resolved_event.WaitMSec(f_timeout*1000); { ScopedEventLoopBlock lock ( mp_poll ); fr_service = m_resolving_service; return (!fr_service.GetIP().empty()); } }
static void avahi_browser_callback(AvahiServiceBrowser *browser, AvahiIfIndex iface, AvahiProtocol proto, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *d) { AvahiBrowserEntry *entry = (AvahiBrowserEntry*)d; struct AvahiClient *client = avahi_service_browser_get_client(browser); switch (event) { case AVAHI_BROWSER_NEW: eDebug("[Avahi] Resolving service '%s' of type '%s'", name, type); avahi_service_resolver_new(client, iface, proto, name, type, domain, AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0, avahi_resolver_callback, d); break; case AVAHI_BROWSER_REMOVE: eDebug("[Avahi] REMOVE service '%s' of type '%s' in domain '%s'", name, type, domain); entry->callback(entry->userdata, E2AVAHI_EVENT_REMOVE, name, type, NULL, 0); break; case AVAHI_BROWSER_ALL_FOR_NOW: /* Useless information... */ break; case AVAHI_BROWSER_FAILURE: eDebug("[Avahi] AVAHI_BROWSER_FAILURE"); /* We'll probably need to restart everything? */ entry->browser = NULL; break; case AVAHI_BROWSER_CACHE_EXHAUSTED: /* Useless information... */ break; } }
static void browse_callback (AVAHI_GCC_UNUSED AvahiServiceBrowser * b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void *userdata) { SnraClient *client = userdata; switch (event) { case AVAHI_BROWSER_FAILURE: /* Respawn browser on a timer? */ avahi_service_browser_free (client->avahi_sb); client->timeout = g_timeout_add_seconds (1, (GSourceFunc) try_reconnect, client); return; case AVAHI_BROWSER_NEW:{ avahi_service_resolver_new (client->avahi_client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, avahi_resolve_callback, client); break; } case AVAHI_BROWSER_REMOVE: case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: break; } }
static gboolean dmap_mdns_browser_resolve (DMAPMdnsBrowser * browser, const gchar * name, const gchar * domain) { AvahiServiceResolver *service_resolver; service_resolver = avahi_service_resolver_new (browser->priv->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, name, service_type_name [browser-> priv->service_type], domain, AVAHI_PROTO_UNSPEC, #ifdef HAVE_AVAHI_0_6 0, #endif (AvahiServiceResolverCallback) resolve_cb, browser); if (service_resolver == NULL) { g_debug ("Error starting mDNS resolving using AvahiServiceResolver"); return FALSE; } browser->priv->resolvers = g_slist_prepend (browser->priv->resolvers, service_resolver); return TRUE; }
static void __avahi_browser_cb(AvahiServiceBrowser *browser, AvahiIfIndex iface, AvahiProtocol proto, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, __notused AvahiLookupResultFlags flags, void *d) { struct avahi_discovery_data *ddata = (struct avahi_discovery_data *) d; struct AvahiClient *client = avahi_service_browser_get_client(browser); switch (event) { default: case AVAHI_BROWSER_NEW: ddata->found = !!avahi_service_resolver_new(client, iface, proto, name, type, domain, AVAHI_PROTO_UNSPEC, 0, __avahi_resolver_cb, d); break; case AVAHI_BROWSER_ALL_FOR_NOW: if (ddata->found) { while (!ddata->resolved) { struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 4000000; nanosleep(&ts, NULL); } } case AVAHI_BROWSER_FAILURE: /* fall-through */ avahi_simple_poll_quit(ddata->poll); case AVAHI_BROWSER_CACHE_EXHAUSTED: /* fall-through */ break; } }
static ServiceInfo *add_service(Config *c, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain) { ServiceInfo *i; i = avahi_new(ServiceInfo, 1); if (c->resolve) { if (!(i->resolver = avahi_service_resolver_new(client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, service_resolver_callback, i))) { avahi_free(i); fprintf(stderr, ("Failed to resolve service '%s' of type '%s' in domain '%s': %s\n"), name, type, domain, avahi_strerror(avahi_client_errno(client))); return NULL; } n_resolving++; } else i->resolver = NULL; i->interface = interface; i->protocol = protocol; i->name = avahi_strdup(name); i->type = avahi_strdup(type); i->domain = avahi_strdup(domain); i->config = c; AVAHI_LLIST_PREPEND(ServiceInfo, info, services, i); return i; }
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) { AvahiSimplePoll *simple_poll; const AvahiPoll *poll_api; AvahiClient *client; AvahiServiceResolver *r; simple_poll = avahi_simple_poll_new(); assert(simple_poll); poll_api = avahi_simple_poll_get(simple_poll); assert(poll_api); client = avahi_client_new(poll_api, 0, NULL, NULL, NULL); assert(client); r = avahi_service_resolver_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, "_domain._udp", "0pointer.de", AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_TXT, callback, simple_poll); assert(r); avahi_simple_poll_loop(simple_poll); avahi_client_free(client); avahi_simple_poll_free(simple_poll); return 0; }
static gboolean start_avahi_resolver (gpointer user_data) { GVfsDnsSdResolver *resolver = G_VFS_DNS_SD_RESOLVER (user_data); AvahiClient *avahi_client; avahi_client = get_global_avahi_client (NULL); if (avahi_client == NULL) goto out; resolver->avahi_resolver = avahi_service_resolver_new (avahi_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, resolver->service_name, resolver->service_type, resolver->domain, AVAHI_PROTO_UNSPEC, 0, /* AvahiLookupFlags */ service_resolver_cb, resolver); out: g_object_unref (resolver); return FALSE; }
/** Called when a new service appears or is removed from the * netwhor. */ static void sBrowseCallback( AvahiServiceBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) { Implementation *impl = (Implementation*)userdata; AvahiClient *client = avahi_service_browser_get_client(browser); switch (event) { case AVAHI_BROWSER_FAILURE: throw dub::Exception("mdns.Browser browser failure (%s).\n", avahi_strerror( avahi_client_errno(client))); return; case AVAHI_BROWSER_NEW: { // New service available. AvahiServiceResolver *resolver = avahi_service_resolver_new( client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0, sResolveCallback, impl); /** We do not have to save the resolver object: we free it in * the callback. If the server quits before the callback is * called, the server will free the resolver for us. */ if (!resolver) { throw dub::Exception("Failed to resolve service '%s' (%s).\n", name, avahi_strerror(avahi_client_errno(client))); } } break; case AVAHI_BROWSER_REMOVE: impl->pushService(new Service( impl->master_->service_type_, name, interface, type, domain, false)); break; case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: // Done: nothing more. break; } }
void RemoteService::resolveAsync() { if (d->m_running) return; d->m_resolved = false; // FIXME: first protocol should be set? #ifdef HAVE_DNSSD #ifdef AVAHI_API_0_6 d->m_resolver = avahi_service_resolver_new(Responder::self().client(),AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, m_serviceName.utf8(), m_type.ascii(), domainToDNS(m_domain), AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_ADDRESS, resolve_callback, this); #else d->m_resolver = avahi_service_resolver_new(Responder::self().client(),AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, m_serviceName.utf8(), m_type.ascii(), m_domain.utf8(), AVAHI_PROTO_UNSPEC, resolve_callback, this); #endif if (d->m_resolver) d->m_running=true; else emit resolved(false); #endif }
static void daap_mdns_browse_cb (AvahiServiceBrowser *browser, AvahiIfIndex iface, AvahiProtocol proto, AvahiBrowserEvent event, const gchar *name, const gchar *type, const gchar *domain, AvahiLookupResultFlags flags, void *userdata) { AvahiClient *client = ((browse_callback_userdata_t *) userdata)->client; if (!browser) { return; } switch (event) { case AVAHI_BROWSER_NEW: avahi_service_resolver_new (client, iface, proto, name, type, domain, AVAHI_PROTO_UNSPEC, 0, daap_mdns_resolve_browser_new_cb, NULL); break; case AVAHI_BROWSER_REMOVE: avahi_service_resolver_new (client, iface, proto, name, type, domain, AVAHI_PROTO_UNSPEC, 0, daap_mdns_resolve_browser_remove_cb, NULL); break; case AVAHI_BROWSER_CACHE_EXHAUSTED: break; case AVAHI_BROWSER_ALL_FOR_NOW: break; default: break; } }
static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void *userdata) { rtsp_conn_info *conn = (rtsp_conn_info *)userdata; dacp_browser_struct *dbs = (dacp_browser_struct *)conn->mdns_private_pointer; assert(b); /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ switch (event) { case AVAHI_BROWSER_FAILURE: warn("avahi: browser failure.", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); avahi_threaded_poll_quit(tpoll); break; case AVAHI_BROWSER_NEW: debug(3, "(Browser) NEW: service '%s' of type '%s' in domain '%s'.", name, type, domain); /* We ignore the returned resolver object. In the callback function we free it. If the server is terminated before the callback function is called the server will free the resolver for us. */ if (!(avahi_service_resolver_new(dbs->service_client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, userdata))) debug(1, "Failed to resolve service '%s': %s.", name, avahi_strerror(avahi_client_errno(dbs->service_client))); break; case AVAHI_BROWSER_REMOVE: debug(3, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'.", name, type, domain); char *dacpid = strstr(name, "iTunes_Ctrl_"); if (dacpid) { dacpid += strlen("iTunes_Ctrl_"); if (strcmp(dacpid, conn->dacp_id) == 0) { if (conn->dacp_id != 0) { debug(1, "Client's DACP status withdrawn."); conn->dacp_port = 0; #if defined(HAVE_DBUS) || defined(HAVE_MPRIS) set_dacp_server_information(conn); // this will have the effect of telling the scanner that the DACP server is no longer working #endif } } } else { debug(1, "Browse callback: Can't see a DACP string in a DACP Record!"); } break; case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: // debug(1, "(Browser) %s.", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : // "ALL_FOR_NOW"); break; } }
static void browse_callback( AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) { AvahiClient *c = userdata; assert(b); /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ switch (event) { case AVAHI_BROWSER_FAILURE: fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); avahi_simple_poll_quit(simple_poll); return; case AVAHI_BROWSER_NEW: fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); /* We ignore the returned resolver object. In the callback function we free it. If the server is terminated before the callback function is called the server will free the resolver for us. */ if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, c))) fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); break; case AVAHI_BROWSER_REMOVE: fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain); break; case AVAHI_BROWSER_ALL_FOR_NOW: fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); avahi_simple_poll_quit(simple_poll); break; case AVAHI_BROWSER_CACHE_EXHAUSTED: fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); break; } }
/** * browser: The avahi browser * iface: the interface * proto: the protocol * event: the event that happened while browsing (failure, new, remove) * name: name of the service * type: HKP_SERVICE_TYPE is expected * domain: domain of the service * flags: ignored * data: userdata, type BastileServiceDiscovery * * Called when a service is discovered while browsing. * It is a AvahiServiceBrowserCallback * **/ static void browse_callback(AvahiServiceBrowser *browser, AvahiIfIndex iface, AvahiProtocol proto, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* data) { BastileServiceDiscovery *ssd = BASTILE_SERVICE_DISCOVERY (data); const gchar *uri; g_assert (BASTILE_IS_SERVICE_DISCOVERY (ssd)); g_assert (browser == ssd->priv->browser); /* XXX Is the service always guaranteed to be ascii? */ if (g_ascii_strcasecmp (HKP_SERVICE_TYPE, type) != 0) return; switch (event) { case AVAHI_BROWSER_FAILURE: g_warning ("failure browsing for services: %s", avahi_strerror (avahi_client_errno (ssd->priv->client))); disconnect (ssd); break; case AVAHI_BROWSER_NEW: if (!avahi_service_resolver_new (ssd->priv->client, iface, proto, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, ssd)) g_warning ("couldn't start resolver for service '%s': %s\n", name, avahi_strerror (avahi_client_errno (ssd->priv->client))); break; case AVAHI_BROWSER_REMOVE: uri = g_hash_table_lookup (ssd->services, name); if (uri != NULL) { /* Remove it from the main context */ BastileSource *sksrc = bastile_context_remote_source (SCTX_APP(), uri); bastile_context_remove_source (SCTX_APP(), sksrc); } /* And remove it from our tables */ g_hash_table_remove (ssd->services, name); g_signal_emit (ssd, signals[REMOVED], 0, name); DEBUG_DNSSD (("DNS-SD removed: %s\n", name)); break; default: break; } }
void BrowseAvahi::browse_callback( AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) { // AvahiClient* client = (AvahiClient*)userdata; BrowseAvahi* browseAvahi = static_cast<BrowseAvahi*>(userdata); assert(b); /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ switch (event) { case AVAHI_BROWSER_FAILURE: logE << "(Browser) " << avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))) << "\n"; avahi_simple_poll_quit(simple_poll); return; case AVAHI_BROWSER_NEW: logO << "(Browser) NEW: service '" << name << "' of type '" << type << "' in domain '" << domain << "'\n"; /* We ignore the returned resolver object. In the callback function we free it. If the server is terminated before the callback function is called the server will free the resolver for us. */ if (!(avahi_service_resolver_new(browseAvahi->client_, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0, resolve_callback, userdata))) logE << "Failed to resolve service '" << name << "': " << avahi_strerror(avahi_client_errno(browseAvahi->client_)) << "\n"; break; case AVAHI_BROWSER_REMOVE: logO << "(Browser) REMOVE: service '" << name << "' of type '" << type << "' in domain '" << domain << "'\n"; break; case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: logO << "(Browser) " << (event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW") << "\n"; break; } }
void Browser::browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags, void* data) { assert(b); AvahiClient *client = avahi_service_browser_get_client(b); assert(data); Browser *browser = static_cast<Browser *>(data); switch (event) { case AVAHI_BROWSER_FAILURE: cerr << "[Browser] " << avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))) << endl; throw BrowserError(avahi_client_errno(client)); //a->Stop(); return; case AVAHI_BROWSER_NEW: //cerr << "[Browser] New service '" << name << "' of type '" << type << "' in domain '" << domain << "'" << endl; if (!(avahi_service_resolver_new(client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0, resolve_callback, browser))) cerr << "Failed to resolve service '" << name << "': " << avahi_strerror(avahi_client_errno(client)) << endl; break; case AVAHI_BROWSER_REMOVE: //cerr << "[Browser] Removed service " << name << " of type " << type << " in domain " << domain << endl; // XXX Remove cached service, broadcast browser->remove_service(name); break; case AVAHI_BROWSER_ALL_FOR_NOW: //cerr << "[Browser] All for now." << endl; break; case AVAHI_BROWSER_CACHE_EXHAUSTED: //cerr << "[Browser] Cache exhausted." << endl; break; } }
static void _browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { PurpleAccount *account = userdata; PurpleBuddy *gb = NULL; switch (event) { case AVAHI_BROWSER_FAILURE: purple_debug_error("bonjour", "_browser_callback - Failure: %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); /* TODO: This is an error that should be handled. */ break; case AVAHI_BROWSER_NEW: /* A new peer has joined the network and uses iChat bonjour */ purple_debug_info("bonjour", "_browser_callback - new service\n"); /* Make sure it isn't us */ if (g_ascii_strcasecmp(name, account->username) != 0) { if (!avahi_service_resolver_new(avahi_service_browser_get_client(b), interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, _resolver_callback, account)) { purple_debug_warning("bonjour", "_browser_callback -- Error initiating resolver: %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); } } break; case AVAHI_BROWSER_REMOVE: purple_debug_info("bonjour", "_browser_callback - Remove service\n"); gb = purple_find_buddy(account, name); if (gb != NULL) { bonjour_buddy_delete(gb->proto_data); purple_blist_remove_buddy(gb); } break; case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: purple_debug_warning("bonjour", "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); break; default: purple_debug_info("bonjour", "Unrecognized Service browser event: %d.\n", event); } }
/***************************************************************************** * browser_callback *****************************************************************************/ static void browse_callback( AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* userdata ) { VLC_UNUSED(b); VLC_UNUSED(flags); services_discovery_t *p_sd = ( services_discovery_t* )userdata; services_discovery_sys_t *p_sys = p_sd->p_sys; if( event == AVAHI_BROWSER_NEW ) { if( avahi_service_resolver_new( p_sys->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, userdata ) == NULL ) { msg_Err( p_sd, "failed to resolve service '%s': %s", name, avahi_strerror( avahi_client_errno( p_sys->client ) ) ); } } else if( name ) { /** \todo Store the input id and search it, rather than searching the items */ input_item_t *p_item; p_item = vlc_dictionary_value_for_key( &p_sys->services_name_to_input_item, name ); if( !p_item ) msg_Err( p_sd, "failed to find service '%s' in playlist", name ); else { services_discovery_RemoveItem( p_sd, p_item ); vlc_dictionary_remove_value_for_key( &p_sys->services_name_to_input_item, name, NULL, NULL ); } } }
ServiceInfo* NetworkServicesProviderAvahi::addServiceInfo( AvahiIfIndex interface, AvahiProtocol protocol, const char* name, const char* type, const char* domain) { ServiceInfo* i; m_currentService = i = avahi_new(ServiceInfo, 1); if (!(i->resolver = avahi_service_resolver_new( m_avahiClient, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0, &serviceResolverCallback, static_cast<void*>(i)))) { avahi_free(i); LOG_ERROR("Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(m_avahiClient))); return 0; } m_resolving++; i->interface = interface; i->protocol = protocol; i->name = avahi_strdup(name); i->type = avahi_strdup(type); i->domain = avahi_strdup(domain); i->provider = this; i->notify = false; AVAHI_LLIST_PREPEND(ServiceInfo, info, m_services, i); return i; }
static void browser(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { service_aux_t *sa = userdata; service_instance_t *si; char fullname[256]; snprintf(fullname, sizeof(fullname), "%s.%s.%s.%d.%d", name, type, domain, interface, protocol); switch(event) { case AVAHI_BROWSER_NEW: si = calloc(1, sizeof(service_instance_t)); si->si_opaque = sa; si->si_id = strdup(fullname); LIST_INSERT_HEAD(&services, si, si_link); if(!(avahi_service_resolver_new(sa->sa_c, interface, protocol, name, type, domain, AVAHI_PROTO_INET, 0, resolve_callback, si))) { si_destroy(si); TRACE(TRACE_ERROR, "AVAHI", "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(sa->sa_c))); } break; case AVAHI_BROWSER_REMOVE: si = si_find(&services, fullname); if(si != NULL) si_destroy(si); break; default: break; } }
static void browser_cb( AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { struct userdata *u = userdata; struct tunnel *t; pa_assert(u); if (flags & AVAHI_LOOKUP_RESULT_LOCAL) return; t = tunnel_new(interface, protocol, name, type, domain); if (event == AVAHI_BROWSER_NEW) { if (!pa_hashmap_get(u->tunnels, t)) if (!(avahi_service_resolver_new(u->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolver_cb, u))) pa_log("avahi_service_resolver_new() failed: %s", avahi_strerror(avahi_client_errno(u->client))); /* We ignore the returned resolver object here, since the we don't * need to attach any special data to it, and we can still destroy * it from the callback */ } else if (event == AVAHI_BROWSER_REMOVE) { struct tunnel *t2; if ((t2 = pa_hashmap_get(u->tunnels, t))) { pa_module_unload_request_by_index(u->core, t2->module_index, TRUE); pa_hashmap_remove(u->tunnels, t2); tunnel_free(t2); } } tunnel_free(t); }
static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex intf, AvahiProtocol proto, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { struct mdns_browser *mb; struct mdns_resolver *r; int family; mb = (struct mdns_browser *)userdata; switch (event) { case AVAHI_BROWSER_FAILURE: DPRINTF(E_LOG, L_MDNS, "Avahi Browser failure: %s\n", MDNSERR); avahi_service_browser_free(b); b = avahi_service_browser_new(mdns_client, AVAHI_IF_UNSPEC, mb->protocol, mb->type, NULL, 0, browse_callback, mb); if (!b) { DPRINTF(E_LOG, L_MDNS, "Failed to recreate service browser (service type %s): %s\n", mb->type, MDNSERR); return; } break; case AVAHI_BROWSER_NEW: DPRINTF(E_DBG, L_MDNS, "Avahi Browser: NEW service '%s' type '%s' proto %d\n", name, type, proto); CHECK_NULL(L_MDNS, r = calloc(1, sizeof(struct mdns_resolver))); r->resolver = avahi_service_resolver_new(mdns_client, intf, proto, name, type, domain, proto, 0, browse_resolve_callback, mb); if (!r->resolver) { DPRINTF(E_LOG, L_MDNS, "Failed to create service resolver: %s\n", MDNSERR); free(r); return; } r->name = strdup(name); r->proto = proto; r->next = resolver_list; resolver_list = r; break; case AVAHI_BROWSER_REMOVE: DPRINTF(E_DBG, L_MDNS, "Avahi Browser: REMOVE service '%s' type '%s' proto %d\n", name, type, proto); family = avahi_proto_to_af(proto); if (family != AF_UNSPEC) mb->cb(name, type, domain, NULL, family, NULL, -1, NULL); resolvers_cleanup(name, proto); break; case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: DPRINTF(E_DBG, L_MDNS, "Avahi Browser (%s): no more results (%s)\n", mb->type, (event == AVAHI_BROWSER_CACHE_EXHAUSTED) ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); break; } }
/* Called whenever a new service is found or removed */ static void browse_reply( AvahiServiceBrowser *UNUSED(b), AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags UNUSED(flags), void *userdata) { struct daemon_data *d = userdata; assert(d); switch (event) { case AVAHI_BROWSER_NEW: { struct host *h; h = malloc(sizeof(struct host)); assert(h); rs_log_info("new service: %s\n", name); if (!(h->resolver = avahi_service_resolver_new(d->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_reply, h))) { rs_log_warning("Failed to create service resolver for '%s': %s\n", name, avahi_strerror(avahi_client_errno(d->client))); free(h); } else { /* Fill in missing data */ h->service = strdup(name); assert(h->service); h->domain = strdup(domain); assert(h->domain); h->daemon_data = d; h->interface = interface; h->protocol = protocol; h->next = d->hosts; h->n_cpus = 1; d->hosts = h; } break; } case AVAHI_BROWSER_REMOVE: rs_log_info("Removed service: %s\n", name); remove_service(d, interface, protocol, name, domain); write_hosts(d); break; case AVAHI_BROWSER_FAILURE: rs_log_crit("Service Browser failure '%s': %s\n", name, avahi_strerror(avahi_client_errno(d->client))); avahi_simple_poll_quit(d->simple_poll); break; case AVAHI_BROWSER_CACHE_EXHAUSTED: case AVAHI_BROWSER_ALL_FOR_NOW: ; } }
void Avahi::Heap::BrowserCallback (AvahiServiceBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags /*flags*/) { switch (event) { case AVAHI_BROWSER_NEW: /* this may not be the final valid resolver pointer... * we'll take what our callback gets */ if (resolver) avahi_service_resolver_free (resolver); resolver = avahi_service_resolver_new (client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, (AvahiLookupFlags)0, avahi_resolver_callback, this); #if DEBUG std::cout << __PRETTY_FUNCTION__ << " AVAHI_BROWSER_NEW" << std::endl; #endif if (resolver == NULL) std::cout << "resolver is NULL!" << std::endl; break; case AVAHI_BROWSER_REMOVE: #if DEBUG std::cout << __PRETTY_FUNCTION__ << " AVAHI_BROWSER_REMOVE" << std::endl; #endif for (iterator iter = begin (); iter != end (); ++iter) if ((*iter)->get_name () == name) { (*iter)->removed (*iter); break; } break; case AVAHI_BROWSER_CACHE_EXHAUSTED: // FIXME: do I care? #if DEBUG std::cout << __PRETTY_FUNCTION__ << " AVAHI_BROWSER_CACHE_EXHAUSTED" << std::endl; #endif break; case AVAHI_BROWSER_ALL_FOR_NOW: // FIXME: do I care? #if DEBUG std::cout << __PRETTY_FUNCTION__ << " AVAHI_BROWSER_ALL_FOR_NOW" << std::endl; #endif break; case AVAHI_BROWSER_FAILURE: #if DEBUG std::cout << __PRETTY_FUNCTION__ << " AVAHI_BROWSER_FAILURE" << std::endl; #endif avahi_service_browser_free (browser); browser = NULL; break; default: /* shouldn't happen */ #if DEBUG std::cout << __PRETTY_FUNCTION__ << " SHOULDN'T HAPPEN" << std::endl; #endif break; } }
static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex intf, AvahiProtocol proto, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { struct mdns_browser *mb; AvahiServiceResolver *res; int family; mb = (struct mdns_browser *)userdata; switch (event) { case AVAHI_BROWSER_FAILURE: DPRINTF(E_LOG, L_MDNS, "Avahi Browser failure: %s\n", avahi_strerror(avahi_client_errno(mdns_client))); avahi_service_browser_free(b); b = avahi_service_browser_new(mdns_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, mb->type, NULL, 0, browse_callback, mb); if (!b) { DPRINTF(E_LOG, L_MDNS, "Failed to recreate service browser (service type %s): %s\n", mb->type, avahi_strerror(avahi_client_errno(mdns_client))); } return; case AVAHI_BROWSER_NEW: DPRINTF(E_DBG, L_MDNS, "Avahi Browser: NEW service '%s' type '%s' proto %d\n", name, type, proto); res = avahi_service_resolver_new(mdns_client, intf, proto, name, type, domain, proto, 0, browse_resolve_callback, mb); if (!res) DPRINTF(E_LOG, L_MDNS, "Failed to create service resolver: %s\n", avahi_strerror(avahi_client_errno(mdns_client))); break; case AVAHI_BROWSER_REMOVE: DPRINTF(E_DBG, L_MDNS, "Avahi Browser: REMOVE service '%s' type '%s' proto %d\n", name, type, proto); switch (proto) { case AVAHI_PROTO_INET: family = AF_INET; break; case AVAHI_PROTO_INET6: family = AF_INET6; break; default: DPRINTF(E_INFO, L_MDNS, "Avahi Browser: unknown protocol %d\n", proto); family = AF_UNSPEC; break; } if (family != AF_UNSPEC) mb->cb(name, type, domain, NULL, family, NULL, -1, NULL); break; case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: DPRINTF(E_DBG, L_MDNS, "Avahi Browser (%s): no more results (%s)\n", mb->type, (event == AVAHI_BROWSER_CACHE_EXHAUSTED) ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); break; } }
static void _browser_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { PurpleAccount *account = userdata; PurpleBuddy *pb = NULL; switch (event) { case AVAHI_BROWSER_FAILURE: purple_debug_error("bonjour", "_browser_callback - Failure: %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); /* TODO: This is an error that should be handled. */ break; case AVAHI_BROWSER_NEW: /* A new peer has joined the network and uses iChat bonjour */ purple_debug_info("bonjour", "_browser_callback - new service\n"); /* Make sure it isn't us */ if (purple_utf8_strcasecmp(name, bonjour_get_jid(account)) != 0) { if (!avahi_service_resolver_new(avahi_service_browser_get_client(b), interface, protocol, name, type, domain, protocol, 0, _resolver_callback, account)) { purple_debug_warning("bonjour", "_browser_callback -- Error initiating resolver: %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); } } break; case AVAHI_BROWSER_REMOVE: purple_debug_info("bonjour", "_browser_callback - Remove service\n"); pb = purple_find_buddy(account, name); if (pb != NULL) { BonjourBuddy *bb = purple_buddy_get_protocol_data(pb); AvahiBuddyImplData *b_impl; GSList *l; AvahiSvcResolverData *rd_search; g_return_if_fail(bb != NULL); b_impl = bb->mdns_impl_data; /* There may be multiple presences, we should only get rid of this one */ rd_search = g_new0(AvahiSvcResolverData, 1); rd_search->interface = interface; rd_search->protocol = protocol; rd_search->name = (gchar *) name; rd_search->type = (gchar *) type; rd_search->domain = (gchar *) domain; l = g_slist_find_custom(b_impl->resolvers, rd_search, _find_resolver_data); g_free(rd_search); if (l != NULL) { AvahiSvcResolverData *rd = l->data; b_impl->resolvers = g_slist_remove(b_impl->resolvers, rd); /* This IP is no longer available */ if (rd->ip != NULL) { bb->ips = g_slist_remove(bb->ips, rd->ip); g_free((gchar *) rd->ip); } _cleanup_resolver_data(rd); /* If this was the last resolver, remove the buddy */ if (b_impl->resolvers == NULL) bonjour_buddy_signed_off(pb); } } break; case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_CACHE_EXHAUSTED: break; default: purple_debug_info("bonjour", "Unrecognized Service browser event: %d.\n", event); } }
static void browseCallback( AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata ) { AvahiClient *c = userdata; TiVoUnit *tivo, *prev, *next; /* Called whenever a new tivo becomes available on the LAN or is removed from the LAN */ switch (event) { case AVAHI_BROWSER_NEW: /* detected a new TiVo on the LAN */ tivo = rememberTiVo( name ); /* We don't save the resolver object returned by avahi_service_resolver_new(). Instead, when the resolver calls the callback function with the results, the new TiVoUnit is added, then the resolver is freed. If the server terminates before the callback function is called, the server will free the resolver for us. */ if ( !avahi_service_resolver_new( c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolveCallback, tivo) ) { logerror( "Failed to resolve service '%s': %s", name, avahi_strerror(avahi_client_errno(c)) ); } break; case AVAHI_BROWSER_REMOVE: /* a TiVo disappeared from the LAN */ loginfo( "TiVo '%s' disappeared from network", name ); /*-- begin critical section --*/ prev = NULL; tivo = tivoUnits; while ( tivo != NULL ) { next = tivo->next; if ( !strcmp( tivo->name, name ) ) { /* found it, so unlink it */ if ( prev == NULL ) tivoUnits = next; else prev->next = next; /* prev itself stays put */ forgetTiVo( tivo ); } else prev = tivo; tivo = next; } /*-- end critical section --*/ break; case AVAHI_BROWSER_CACHE_EXHAUSTED: loginfo( "(Browser) cache exhausted" ); break; case AVAHI_BROWSER_ALL_FOR_NOW: loginfo( "(Browser) all for now" ); break; case AVAHI_BROWSER_FAILURE: logerror( "(Browser) %s", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))) ); avahi_threaded_poll_quit( bonjourThread ); return; } }
static void browse_callback( AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) { AvahiClient *c = userdata; const AvahiPoll *api = avahi_simple_poll_get (simple_poll); struct timeval *tv; assert(b); /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ switch (event) { case AVAHI_BROWSER_FAILURE: fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); avahi_simple_poll_quit(simple_poll); return; case AVAHI_BROWSER_NEW: /* Count the pending resolvers so we know when we can quit. */ n_pending_resolvers++; /* We ignore the returned resolver object. In the callback function we free it. If the server is terminated before the callback function is called the server will free the resolver for us. */ if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, c))) fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); break; case AVAHI_BROWSER_REMOVE: break; case AVAHI_BROWSER_ALL_FOR_NOW: /* The all for now event is emitted when each published service was announced by the new event (handled above). But there still might be some pending resolvers, so we have to wait for the resolvers to be finished, before quitting the main loop. */ tv = avahi_malloc0 (sizeof (struct timeval)); avahi_elapse_time (tv, 200, 0); api->timeout_new (api, tv, timeout_callback, tv); break; case AVAHI_BROWSER_CACHE_EXHAUSTED: break; } }