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;
	
}
Beispiel #2
0
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;
}