int InitializeZeroconf() { int error; //int ret = 1; int timeout = 50; //500ms const char *avahiVersion; CThread_mutex_lock(&zeroconfInitLock); if(Dns_sdInitialized) { CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_OK; } #ifdef ZEROCONF_RUNTIME_LINKING avahiLibHandle = dlopen("libavahi-client.so",RTLD_LAZY); if(!avahiLibHandle) { avahiLibHandle = dlopen("libavahi-client.so.3",RTLD_LAZY); } if(!avahiLibHandle) { LOG(PHIDGET_LOG_WARNING, "dlopen failed with error: %s", dlerror()); LOG(PHIDGET_LOG_WARNING, "Assuming that zeroconf is not supported on this machine."); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNSUPPORTED; } //These are always in Avahi if(!(avahi_client_get_version_string_ptr = (avahi_client_get_version_string_type)dlsym(avahiLibHandle, "avahi_client_get_version_string"))) goto dlsym_err; if(!(avahi_service_browser_new_ptr = (avahi_service_browser_new_type)dlsym(avahiLibHandle, "avahi_service_browser_new"))) goto dlsym_err; if(!(avahi_service_resolver_new_ptr = (avahi_service_resolver_new_type)dlsym(avahiLibHandle, "avahi_service_resolver_new"))) goto dlsym_err; if(!(avahi_service_resolver_free_ptr = (avahi_service_resolver_free_type)dlsym(avahiLibHandle, "avahi_service_resolver_free"))) goto dlsym_err; if(!(avahi_record_browser_new_ptr = (avahi_record_browser_new_type)dlsym(avahiLibHandle, "avahi_record_browser_new"))) goto dlsym_err; if(!(avahi_record_browser_free_ptr = (avahi_record_browser_free_type)dlsym(avahiLibHandle, "avahi_record_browser_free"))) goto dlsym_err; if(!(avahi_service_name_join_ptr = (avahi_service_name_join_type)dlsym(avahiLibHandle, "avahi_service_name_join"))) goto dlsym_err; if(!(avahi_client_new_ptr = (avahi_client_new_type)dlsym(avahiLibHandle, "avahi_client_new"))) goto dlsym_err; if(!(avahi_client_free_ptr = (avahi_client_free_type)dlsym(avahiLibHandle, "avahi_client_free"))) goto dlsym_err; if(!(avahi_strerror_ptr = (avahi_strerror_type)dlsym(avahiLibHandle, "avahi_strerror"))) goto dlsym_err; if(!(avahi_client_errno_ptr = (avahi_client_errno_type)dlsym(avahiLibHandle, "avahi_client_errno"))) goto dlsym_err; //These are in Avahi > 0.6.4 if(!(avahi_threaded_poll_new_ptr = (avahi_threaded_poll_new_type)dlsym(avahiLibHandle, "avahi_threaded_poll_new"))) goto dlsym_err2; if(!(avahi_threaded_poll_free_ptr = (avahi_threaded_poll_free_type)dlsym(avahiLibHandle, "avahi_threaded_poll_free"))) goto dlsym_err2; if(!(avahi_threaded_poll_get_ptr = (avahi_threaded_poll_get_type)dlsym(avahiLibHandle, "avahi_threaded_poll_get"))) goto dlsym_err2; if(!(avahi_threaded_poll_start_ptr = (avahi_threaded_poll_start_type)dlsym(avahiLibHandle, "avahi_threaded_poll_start"))) goto dlsym_err2; if(!(avahi_threaded_poll_stop_ptr = (avahi_threaded_poll_stop_type)dlsym(avahiLibHandle, "avahi_threaded_poll_stop"))) goto dlsym_err2; if(!(avahi_threaded_poll_quit_ptr = (avahi_threaded_poll_quit_type)dlsym(avahiLibHandle, "avahi_threaded_poll_quit"))) goto dlsym_err2; if(!(avahi_threaded_poll_lock_ptr = (avahi_threaded_poll_lock_type)dlsym(avahiLibHandle, "avahi_threaded_poll_lock"))) goto dlsym_err2; if(!(avahi_threaded_poll_unlock_ptr = (avahi_threaded_poll_unlock_type)dlsym(avahiLibHandle, "avahi_threaded_poll_unlock"))) goto dlsym_err2; goto dlsym_good; dlsym_err: LOG(PHIDGET_LOG_WARNING, "dlsym failed with error: %s", dlerror()); LOG(PHIDGET_LOG_WARNING, "Assuming that zeroconf is not supported on this machine."); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNSUPPORTED; //Old avahi didn't have the thread functions dlsym_err2: LOG(PHIDGET_LOG_WARNING, "dlsym failed with error: %s", dlerror()); LOG(PHIDGET_LOG_WARNING, "Avahi is too old, upgrade to at least version 0.6.4."); LOG(PHIDGET_LOG_WARNING, "Zeroconf will not be used on this machine."); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNSUPPORTED; dlsym_good: #endif /* Allocate main loop object */ if (!(threaded_poll = avahi_threaded_poll_new_ptr())) { LOG(PHIDGET_LOG_ERROR, "Failed to create threaded poll object."); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNEXPECTED; } /* Allocate a new client */ client = avahi_client_new_ptr(avahi_threaded_poll_get_ptr(threaded_poll), 0, client_callback, NULL, &error); /* Check wether creating the client object succeeded */ if (!client) { LOG(PHIDGET_LOG_ERROR, "Failed to create client: %s", avahi_strerror_ptr(error)); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNEXPECTED; } //get version avahiVersion = avahi_client_get_version_string_ptr(client); /* Create the service browsers */ if (!(zeroconf_browse_ws_ref = avahi_service_browser_new_ptr(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_phidget_ws._tcp", NULL, 0, DNSServiceBrowse_ws_CallBack, client))) { LOG(PHIDGET_LOG_ERROR, "Failed to create service browser: %s", avahi_strerror_ptr(avahi_client_errno_ptr(client))); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNEXPECTED; } if (!(zeroconf_browse_phidget_ref = avahi_service_browser_new_ptr(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_phidget._tcp", NULL, 0, DNSServiceBrowse_Phidget_CallBack, client))) { LOG(PHIDGET_LOG_ERROR, "Failed to create service browser: %s", avahi_strerror_ptr(avahi_client_errno_ptr(client))); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNEXPECTED; } if (!(zeroconf_browse_sbc_ref = avahi_service_browser_new_ptr(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_phidget_sbc._tcp", NULL, 0, DNSServiceBrowse_SBC_CallBack, client))) { LOG(PHIDGET_LOG_ERROR, "Failed to create service browser: %s", avahi_strerror_ptr(avahi_client_errno_ptr(client))); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNEXPECTED; } if(avahi_threaded_poll_start_ptr(threaded_poll)) { LOG(PHIDGET_LOG_ERROR, "avahi_threaded_poll_start_ptr failed"); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNEXPECTED; } //Thread is started successfully else { //There is a bug in at least Avahi 0.6.16 (Debian Etch default) where thread_running is not set, so quit doesn't work!!!???!?!?!?!?!?! //This is fixed in 0.6.24 //So I'll set it myself here if(strcmp(avahiVersion, "avahi 0.6.24") < 0) { LOG(PHIDGET_LOG_INFO, "Fixing thread_running bug in avahi < 0.6.24"); threaded_poll->thread_running = 1; } } while(!Dns_sdInitialized) { usleep(10000); timeout--; if(!timeout) { UninitializeZeroconf(); LOG(PHIDGET_LOG_ERROR, "InitializeZeroconf Seems bad... Dns_sdInitialized wasn't set to true."); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_UNEXPECTED; } } LOG(PHIDGET_LOG_INFO, "InitializeZeroconf Seems good... (%s)",avahiVersion); CThread_mutex_unlock(&zeroconfInitLock); return EPHIDGET_OK; }
int InitializeZeroconf() { int error; //int ret = 1; int timeout = 50; //500ms if(Dns_sdInitialized) return EPHIDGET_OK; #ifdef ZEROCONF_RUNTIME_LINKING avahiLibHandle = dlopen("libavahi-client.so",RTLD_LAZY); if(!avahiLibHandle) { LOG(PHIDGET_LOG_WARNING, "dlopen failed with error: %s", dlerror()); LOG(PHIDGET_LOG_WARNING, "Assuming that zeroconf is not supported on this machine."); return EPHIDGET_UNSUPPORTED; } if(!(avahi_service_browser_new_ptr = (avahi_service_browser_new_type)dlsym(avahiLibHandle, "avahi_service_browser_new"))) goto dlsym_err; if(!(avahi_service_resolver_new_ptr = (avahi_service_resolver_new_type)dlsym(avahiLibHandle, "avahi_service_resolver_new"))) goto dlsym_err; if(!(avahi_service_resolver_free_ptr = (avahi_service_resolver_free_type)dlsym(avahiLibHandle, "avahi_service_resolver_free"))) goto dlsym_err; if(!(avahi_record_browser_new_ptr = (avahi_record_browser_new_type)dlsym(avahiLibHandle, "avahi_record_browser_new"))) goto dlsym_err; if(!(avahi_record_browser_free_ptr = (avahi_record_browser_free_type)dlsym(avahiLibHandle, "avahi_record_browser_free"))) goto dlsym_err; if(!(avahi_service_name_join_ptr = (avahi_service_name_join_type)dlsym(avahiLibHandle, "avahi_service_name_join"))) goto dlsym_err; if(!(avahi_client_new_ptr = (avahi_client_new_type)dlsym(avahiLibHandle, "avahi_client_new"))) goto dlsym_err; if(!(avahi_client_free_ptr = (avahi_client_free_type)dlsym(avahiLibHandle, "avahi_client_free"))) goto dlsym_err; if(!(avahi_strerror_ptr = (avahi_strerror_type)dlsym(avahiLibHandle, "avahi_strerror"))) goto dlsym_err; if(!(avahi_client_errno_ptr = (avahi_client_errno_type)dlsym(avahiLibHandle, "avahi_client_errno"))) goto dlsym_err; if(!(avahi_threaded_poll_new_ptr = (avahi_threaded_poll_new_type)dlsym(avahiLibHandle, "avahi_threaded_poll_new"))) goto dlsym_err; if(!(avahi_threaded_poll_free_ptr = (avahi_threaded_poll_free_type)dlsym(avahiLibHandle, "avahi_threaded_poll_free"))) goto dlsym_err; if(!(avahi_threaded_poll_get_ptr = (avahi_threaded_poll_get_type)dlsym(avahiLibHandle, "avahi_threaded_poll_get"))) goto dlsym_err; if(!(avahi_threaded_poll_start_ptr = (avahi_threaded_poll_start_type)dlsym(avahiLibHandle, "avahi_threaded_poll_start"))) goto dlsym_err; if(!(avahi_threaded_poll_stop_ptr = (avahi_threaded_poll_stop_type)dlsym(avahiLibHandle, "avahi_threaded_poll_stop"))) goto dlsym_err; if(!(avahi_threaded_poll_quit_ptr = (avahi_threaded_poll_quit_type)dlsym(avahiLibHandle, "avahi_threaded_poll_quit"))) goto dlsym_err; if(!(avahi_threaded_poll_lock_ptr = (avahi_threaded_poll_lock_type)dlsym(avahiLibHandle, "avahi_threaded_poll_lock"))) goto dlsym_err; if(!(avahi_threaded_poll_unlock_ptr = (avahi_threaded_poll_unlock_type)dlsym(avahiLibHandle, "avahi_threaded_poll_unlock"))) goto dlsym_err; goto dlsym_good; dlsym_err: LOG(PHIDGET_LOG_WARNING, "dlsym failed with error: %s", dlerror()); LOG(PHIDGET_LOG_WARNING, "Assuming that zeroconf is not supported on this machine."); return EPHIDGET_UNSUPPORTED; dlsym_good: #endif /* Allocate main loop object */ if (!(threaded_poll = avahi_threaded_poll_new_ptr())) { LOG(PHIDGET_LOG_ERROR, "Failed to create threaded poll object."); return EPHIDGET_UNEXPECTED; } /* Allocate a new client */ client = avahi_client_new_ptr(avahi_threaded_poll_get_ptr(threaded_poll), 0, client_callback, NULL, &error); /* Check wether creating the client object succeeded */ if (!client) { LOG(PHIDGET_LOG_ERROR, "Failed to create client: %s", avahi_strerror_ptr(error)); return EPHIDGET_UNEXPECTED; } /* Create the service browsers */ if (!(zeroconf_browse_ws_ref = avahi_service_browser_new_ptr(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_phidget_ws._tcp", NULL, 0, DNSServiceBrowse_ws_CallBack, client))) { LOG(PHIDGET_LOG_ERROR, "Failed to create service browser: %s", avahi_strerror_ptr(avahi_client_errno_ptr(client))); return EPHIDGET_UNEXPECTED; } if (!(zeroconf_browse_phidget_ref = avahi_service_browser_new_ptr(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_phidget._tcp", NULL, 0, DNSServiceBrowse_Phidget_CallBack, client))) { LOG(PHIDGET_LOG_ERROR, "Failed to create service browser: %s", avahi_strerror_ptr(avahi_client_errno_ptr(client))); return EPHIDGET_UNEXPECTED; } if(avahi_threaded_poll_start_ptr(threaded_poll)) { LOG(PHIDGET_LOG_ERROR, "avahi_threaded_poll_start_ptr failed"); return EPHIDGET_UNEXPECTED; } while(!Dns_sdInitialized) { usleep(10000); timeout--; if(!timeout) { UninitializeZeroconf(); LOG(PHIDGET_LOG_ERROR, "InitializeZeroconf Seems bad... Dns_sdInitialized wasn't set to true."); return EPHIDGET_UNEXPECTED; } } LOG(PHIDGET_LOG_INFO, "InitializeZeroconf Seems good..."); return EPHIDGET_OK; }