bool CZeroconfBrowserAvahi::doAddServiceType ( const std::string& fcr_service_type ) { ScopedEventLoopBlock lock ( mp_poll ); tBrowserMap::iterator it = m_browsers.find ( fcr_service_type ); if ( it != m_browsers.end() ) return false; else it = m_browsers.insert ( std::make_pair ( fcr_service_type, ( AvahiServiceBrowser* ) 0 ) ).first; //if the client is running, we directly create a browser for the service here if ( mp_client && avahi_client_get_state ( mp_client ) == AVAHI_CLIENT_S_RUNNING ) { AvahiServiceBrowser* browser = createServiceBrowser ( fcr_service_type, mp_client, this); if ( !browser ) { m_browsers.erase ( it ); return false; } else { it->second = browser; return true; } } else { CLog::Log ( LOGINFO, "CZeroconfBrowserAvahi::doAddServiceType client not available. service browsing queued" ); return true; } }
/** * epc_shell_watch_avahi_client_state: * @callback: a callback function * @user_data: data to pass to @callback * @destroy_data: a function for freeing @user_data when removing the watch * @error: return location for a #GError, or %NULL * * Registers a function to watch state changes of the library's #AvahiClient. * On success the identifier of the newly created watch is returned. Pass it * to epc_shell_watch_remove() to remove the watch. On failure it returns 0 and * sets @error. The error domain is #EPC_AVAHI_ERROR. Possible error codes are * those of the <citetitle>Avahi</citetitle> library. * * <note><para> * Usually there is no need in handling the #AVAHI_CLIENT_FAILURE state * for @callback, as the callback dispatcher takes care already. This * state is dispatched mostly for notification purposes. * </para></note> * * Returns: The identifier of the newly created watch, or 0 on error. */ guint epc_shell_watch_avahi_client_state (AvahiClientCallback callback, gpointer user_data, GDestroyNotify destroy_data, GError **error) { AvahiClient *client = epc_shell_get_avahi_client (error); guint id = 0; g_return_val_if_fail (NULL != callback, 0); if (NULL != client) { id = epc_shell_watch_add (G_CALLBACK (callback), user_data, destroy_data); callback (client, avahi_client_get_state (client), user_data); } return id; }
static void modify_callback(AVAHI_GCC_UNUSED AvahiTimeout *e, void *userdata) { AvahiClient *client = userdata; fprintf(stderr, "Doing some weird modification\n"); avahi_free(name); name = avahi_strdup("Modified MegaPrinter"); /* If the server is currently running, we need to remove our * service and create it anew */ if (avahi_client_get_state(client) == AVAHI_CLIENT_S_RUNNING) { /* Remove the old services */ if (group) avahi_entry_group_reset(group); /* And create them again with the new name */ create_services(client); } }
static void avahi_browser_try_register(AvahiBrowserEntry *entry) { if (entry->browser) return; /* Already registered */ if ((!avahi_client) || (avahi_client_get_state(avahi_client) != AVAHI_CLIENT_S_RUNNING)) { eDebug("[Avahi] Not running yet, cannot browse for type %s.", entry->service_type); return; } entry->browser = avahi_service_browser_new(avahi_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, entry->service_type, NULL, (AvahiLookupFlags)0, avahi_browser_callback, entry); if (!entry->browser) { eDebug("[Avahi] avahi_service_browser_new failed: %s", avahi_strerror(avahi_client_errno(avahi_client))); } }
bool CZeroconfAvahi::doPublishService(const std::string& fcr_identifier, const std::string& fcr_type, const std::string& fcr_name, unsigned int f_port, std::map<std::string, std::string> txt) { CLog::Log(LOGDEBUG, "CZeroconfAvahi::doPublishService identifier: %s type: %s name:%s port:%i", fcr_identifier.c_str(), fcr_type.c_str(), fcr_name.c_str(), f_port); ScopedEventLoopBlock l_block(mp_poll); tServiceMap::iterator it = m_services.find(fcr_identifier); if (it != m_services.end()) { //fcr_identifier exists, no update functionality yet, so exit return false; } //txt records to AvahiStringList AvahiStringList *txtList = NULL; for(std::map<std::string, std::string>::iterator it=txt.begin(); it!=txt.end(); it++) { txtList = avahi_string_list_add_pair(txtList, it->first.c_str(), it->second.c_str()); } //create service info and add it to service map tServiceMap::mapped_type p_service_info(new CZeroconfAvahi::ServiceInfo(fcr_type, fcr_name, f_port, txtList)); it = m_services.insert(it, std::make_pair(fcr_identifier, p_service_info)); //if client is already running, directly try to add the new service if ( mp_client && avahi_client_get_state(mp_client) == AVAHI_CLIENT_S_RUNNING ) { //client's already running, add this new service addService(p_service_info, mp_client); } else { CLog::Log(LOGDEBUG, "CZeroconfAvahi::doPublishService: client not running, queued for publishing"); } return true; }
static void avahi_service_try_register(AvahiServiceEntry *entry) { if (entry->group) return; /* Already registered */ if ((!avahi_client) || (avahi_client_get_state(avahi_client) != AVAHI_CLIENT_S_RUNNING)) { eDebug("[Avahi] Not running yet, cannot register type %s.", entry->service_type); return; } entry->group = avahi_entry_group_new(avahi_client, avahi_group_callback, NULL); if (!entry->group) { eDebug("[Avahi] avahi_entry_group_new failed, cannot register %s %s.", entry->service_type, entry->service_name); return; } const char *service_name = entry->service_name; /* Blank or NULL service name, use our host name as service name, * this appears to be what other services do. */ if ((!service_name) || (!*service_name)) service_name = avahi_client_get_host_name(avahi_client); if (!avahi_entry_group_add_service(entry->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0, service_name, entry->service_type, NULL, NULL, entry->port_num, NULL)) { avahi_entry_group_commit(entry->group); eDebug("[Avahi] Registered %s (%s) on %s:%u", service_name, entry->service_type, avahi_client_get_host_name(avahi_client), entry->port_num); } /* NOTE: group is freed by avahi_client_free */ }
AvahiClientState Client::getAvahiClientState() { UniqueClientLock lock; return avahi_client_get_state(msAvahiClient); }
int main(int argc, char *argv[]) { int ret = 1, error; Config config; const char *argv0; if ((argv0 = strrchr(argv[0], '/'))) argv0++; else argv0 = argv[0]; if (parse_command_line(&config, argv0, argc, argv) < 0) goto fail; switch (config.command) { case COMMAND_UNSPEC: ret = 1; fprintf(stderr, "No command specified.\n"); break; case COMMAND_HELP: help(stdout, argv0); ret = 0; break; case COMMAND_VERSION: printf("%s "PACKAGE_VERSION"\n", argv0); ret = 0; break; case COMMAND_PUBLISH_SERVICE: case COMMAND_PUBLISH_ADDRESS: if (!(simple_poll = avahi_simple_poll_new())) { fprintf(stderr, "Failed to create simple poll object.\n"); goto fail; } if (sigint_install(simple_poll) < 0) goto fail; if (!(client = avahi_client_new(avahi_simple_poll_get(simple_poll), config.no_fail ? AVAHI_CLIENT_NO_FAIL : 0, client_callback, &config, &error))) { fprintf(stderr, "Failed to create client object: %s\n", avahi_strerror(error)); goto fail; } if (avahi_client_get_state(client) != AVAHI_CLIENT_CONNECTING && config.verbose) { const char *version, *hn; if (!(version = avahi_client_get_version_string(client))) { fprintf(stderr, "Failed to query version string: %s\n", avahi_strerror(avahi_client_errno(client))); goto fail; } if (!(hn = avahi_client_get_host_name_fqdn(client))) { fprintf(stderr, "Failed to query host name: %s\n", avahi_strerror(avahi_client_errno(client))); goto fail; } fprintf(stderr, "Server version: %s; Host name: %s\n", version, hn); } avahi_simple_poll_loop(simple_poll); ret = 0; break; } fail: if (client) avahi_client_free(client); sigint_uninstall(); if (simple_poll) avahi_simple_poll_free(simple_poll); avahi_free(config.host); avahi_free(config.name); avahi_free(config.stype); avahi_free(config.domain); avahi_string_list_free(config.subtypes); avahi_string_list_free(config.txt); return ret; }
void AvahiSession::modify_cb(AVAHI_GCC_UNUSED AvahiTimeout* e, void* data) { AvahiSession* self = (AvahiSession*)data; if (avahi_client_get_state(self->mClient) == AVAHI_CLIENT_S_RUNNING) self->CreateServices(); }
static int publish_service(struct service *s) { int r = -1; AvahiStringList *txt = NULL; const char *name = NULL, *t; pa_proplist *proplist = NULL; pa_sample_spec ss; pa_channel_map map; char cm[PA_CHANNEL_MAP_SNPRINT_MAX]; enum service_subtype subtype; const char * const subtype_text[] = { [SUBTYPE_HARDWARE] = "hardware", [SUBTYPE_VIRTUAL] = "virtual", [SUBTYPE_MONITOR] = "monitor" }; pa_assert(s); if (!s->userdata->client || avahi_client_get_state(s->userdata->client) != AVAHI_CLIENT_S_RUNNING) return 0; if (!s->entry_group) { if (!(s->entry_group = avahi_entry_group_new(s->userdata->client, service_entry_group_callback, s))) { pa_log("avahi_entry_group_new(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } } else avahi_entry_group_reset(s->entry_group); txt = txt_record_server_data(s->userdata->core, txt); get_service_data(s, &ss, &map, &name, &proplist, &subtype); txt = avahi_string_list_add_pair(txt, "device", name); txt = avahi_string_list_add_printf(txt, "rate=%u", ss.rate); txt = avahi_string_list_add_printf(txt, "channels=%u", ss.channels); txt = avahi_string_list_add_pair(txt, "format", pa_sample_format_to_string(ss.format)); txt = avahi_string_list_add_pair(txt, "channel_map", pa_channel_map_snprint(cm, sizeof(cm), &map)); txt = avahi_string_list_add_pair(txt, "subtype", subtype_text[subtype]); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_DESCRIPTION))) txt = avahi_string_list_add_pair(txt, "description", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_ICON_NAME))) txt = avahi_string_list_add_pair(txt, "icon-name", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_VENDOR_NAME))) txt = avahi_string_list_add_pair(txt, "vendor-name", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_PRODUCT_NAME))) txt = avahi_string_list_add_pair(txt, "product-name", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_CLASS))) txt = avahi_string_list_add_pair(txt, "class", t); if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_FORM_FACTOR))) txt = avahi_string_list_add_pair(txt, "form-factor", t); 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) { 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( 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, pa_sink_isinstance(s->device) ? (subtype == SUBTYPE_HARDWARE ? SERVICE_SUBTYPE_SINK_HARDWARE : SERVICE_SUBTYPE_SINK_VIRTUAL) : (subtype == SUBTYPE_HARDWARE ? SERVICE_SUBTYPE_SOURCE_HARDWARE : (subtype == SUBTYPE_VIRTUAL ? SERVICE_SUBTYPE_SOURCE_VIRTUAL : SERVICE_SUBTYPE_SOURCE_MONITOR))) < 0) { pa_log("avahi_entry_group_add_service_subtype(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } if (pa_source_isinstance(s->device) && subtype != SUBTYPE_MONITOR) { if (avahi_entry_group_add_service_subtype( s->entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, s->service_name, SERVICE_TYPE_SOURCE, NULL, SERVICE_SUBTYPE_SOURCE_NON_MONITOR) < 0) { pa_log("avahi_entry_group_add_service_subtype(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } } if (avahi_entry_group_commit(s->entry_group) < 0) { pa_log("avahi_entry_group_commit(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); goto finish; } r = 0; pa_log_debug("Successfully created entry group for %s.", s->service_name); finish: /* Remove this service */ if (r < 0) service_free(s); avahi_string_list_free(txt); return r; }