diff --git a/client/browseAvahi.cpp b/client/browseAvahi.cpp index b1641240..70c46402 100644 --- a/client/browseAvahi.cpp +++ b/client/browseAvahi.cpp @@ -24,6 +24,7 @@ #include #include #include +#include "common/snapException.h" #include "common/log.h" @@ -36,15 +37,24 @@ BrowseAvahi::BrowseAvahi() : client_(NULL), sb_(NULL) BrowseAvahi::~BrowseAvahi() +{ + cleanUp(); +} + + +void BrowseAvahi::cleanUp() { if (sb_) avahi_service_browser_free(sb_); + sb_ = NULL; if (client_) avahi_client_free(client_); + client_ = NULL; if (simple_poll) avahi_simple_poll_free(simple_poll); + simple_poll = NULL; } @@ -88,7 +98,7 @@ void BrowseAvahi::resolve_callback( browseAvahi->result_.valid_ = true; t = avahi_string_list_to_string(txt); - logO << "\t" << host_name << ":" << port << "(" << a << ")\n"; + logO << "\t" << host_name << ":" << port << " (" << a << ")\n"; logD << "\tTXT=" << t << "\n"; logD << "\tProto=" << (int)protocol << "\n"; logD << "\tcookie is " << avahi_string_list_get_service_cookie(txt) << "\n"; @@ -114,7 +124,8 @@ void BrowseAvahi::browse_callback( const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, - void* userdata) { + void* userdata) +{ // AvahiClient* client = (AvahiClient*)userdata; BrowseAvahi* browseAvahi = static_cast(userdata); @@ -154,7 +165,8 @@ void BrowseAvahi::browse_callback( } -void BrowseAvahi::client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) { +void BrowseAvahi::client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) +{ assert(c); /* Called whenever the client or server state changes */ @@ -170,48 +182,42 @@ void BrowseAvahi::client_callback(AvahiClient *c, AvahiClientState state, AVAHI_ bool BrowseAvahi::browse(const std::string& serviceName, int proto, AvahiResult& result, int timeout) { - int error; - - /* Allocate main loop object */ - if (!(simple_poll = avahi_simple_poll_new())) + try { - logE << "Failed to create simple poll object.\n"; - goto fail; - } + /* Allocate main loop object */ + if (!(simple_poll = avahi_simple_poll_new())) + throw SnapException("BrowseAvahi - Failed to create simple poll object"); - /* Allocate a new client */ - client_ = avahi_client_new(avahi_simple_poll_get(simple_poll), (AvahiClientFlags)0, client_callback, this, &error); + /* Allocate a new client */ + int error; + if (!(client_ = avahi_client_new(avahi_simple_poll_get(simple_poll), (AvahiClientFlags)0, client_callback, this, &error))) + throw SnapException("BrowseAvahi - Failed to create client: " + std::string(avahi_strerror(error))); - /* Check wether creating the client object succeeded */ - if (!client_) - { - logE << "Failed to create client: " << avahi_strerror(error) << "\n"; - goto fail; - } + /* Create the service browser */ + if (!(sb_ = avahi_service_browser_new(client_, AVAHI_IF_UNSPEC, proto, serviceName.c_str(), NULL, (AvahiLookupFlags)0, browse_callback, this))) + throw SnapException("BrowseAvahi - Failed to create service browser: " + std::string(avahi_strerror(avahi_client_errno(client_)))); - /* Create the service browser */ - if (!(sb_ = avahi_service_browser_new(client_, AVAHI_IF_UNSPEC, proto, serviceName.c_str(), NULL, (AvahiLookupFlags)0, browse_callback, this))) - { - logE << "Failed to create service browser: " << avahi_strerror(avahi_client_errno(client_)) << "\n"; - goto fail; - } - - result_.valid_ = false; - while (timeout > 0) - { - avahi_simple_poll_iterate(simple_poll, 100); - timeout -= 100; - if (result_.valid_) + result_.valid_ = false; + while (timeout > 0) { - result = result_; - return true; + avahi_simple_poll_iterate(simple_poll, 100); + timeout -= 100; + if (result_.valid_) + { + result = result_; + cleanUp(); + return true; + } } - } -fail: - return false; + cleanUp(); + return false; + } + catch (...) + { + cleanUp(); + throw; + } } - - diff --git a/client/browseAvahi.h b/client/browseAvahi.h index d873f6af..cd334d0d 100644 --- a/client/browseAvahi.h +++ b/client/browseAvahi.h @@ -44,6 +44,7 @@ public: bool browse(const std::string& serviceName, int proto, AvahiResult& result, int timeout); private: + void cleanUp(); static void resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, AVAHI_GCC_UNUSED void* userdata); 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); static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata); diff --git a/client/snapClient.cpp b/client/snapClient.cpp index a7f43b62..32fd9467 100644 --- a/client/snapClient.cpp +++ b/client/snapClient.cpp @@ -145,13 +145,21 @@ int main (int argc, char *argv[]) AvahiResult avahiResult; while (!g_terminated) { - if (browseAvahi.browse("_snapcast._tcp", AVAHI_PROTO_INET, avahiResult, 5000)) + try { - ip = avahiResult.ip_; - port = avahiResult.port_; - std::cout << ip << ":" << port << "\n"; - break; + if (browseAvahi.browse("_snapcast._tcp", AVAHI_PROTO_INET, avahiResult, 5000)) + { + ip = avahiResult.ip_; + port = avahiResult.port_; + logO << "Found server " << ip << ":" << port << "\n"; + break; + } } + catch (const std::exception& e) + { + logS(kLogErr) << "Exception: " << e.what() << std::endl; + } + usleep(500*1000); } }