improved error handling

This commit is contained in:
badaix 2015-08-26 19:01:29 +02:00
parent 5cc5aa7f04
commit 635daabd8c
3 changed files with 58 additions and 43 deletions

View file

@ -24,6 +24,7 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <iostream> #include <iostream>
#include "common/snapException.h"
#include "common/log.h" #include "common/log.h"
@ -36,15 +37,24 @@ BrowseAvahi::BrowseAvahi() : client_(NULL), sb_(NULL)
BrowseAvahi::~BrowseAvahi() BrowseAvahi::~BrowseAvahi()
{
cleanUp();
}
void BrowseAvahi::cleanUp()
{ {
if (sb_) if (sb_)
avahi_service_browser_free(sb_); avahi_service_browser_free(sb_);
sb_ = NULL;
if (client_) if (client_)
avahi_client_free(client_); avahi_client_free(client_);
client_ = NULL;
if (simple_poll) if (simple_poll)
avahi_simple_poll_free(simple_poll); avahi_simple_poll_free(simple_poll);
simple_poll = NULL;
} }
@ -88,7 +98,7 @@ void BrowseAvahi::resolve_callback(
browseAvahi->result_.valid_ = true; browseAvahi->result_.valid_ = true;
t = avahi_string_list_to_string(txt); 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 << "\tTXT=" << t << "\n";
logD << "\tProto=" << (int)protocol << "\n"; logD << "\tProto=" << (int)protocol << "\n";
logD << "\tcookie is " << avahi_string_list_get_service_cookie(txt) << "\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 *type,
const char *domain, const char *domain,
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
void* userdata) { void* userdata)
{
// AvahiClient* client = (AvahiClient*)userdata; // AvahiClient* client = (AvahiClient*)userdata;
BrowseAvahi* browseAvahi = static_cast<BrowseAvahi*>(userdata); BrowseAvahi* browseAvahi = static_cast<BrowseAvahi*>(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); assert(c);
/* Called whenever the client or server state changes */ /* 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) bool BrowseAvahi::browse(const std::string& serviceName, int proto, AvahiResult& result, int timeout)
{ {
int error; try
/* Allocate main loop object */
if (!(simple_poll = avahi_simple_poll_new()))
{ {
logE << "Failed to create simple poll object.\n"; /* Allocate main loop object */
goto fail; if (!(simple_poll = avahi_simple_poll_new()))
} throw SnapException("BrowseAvahi - Failed to create simple poll object");
/* Allocate a new client */ /* Allocate a new client */
client_ = avahi_client_new(avahi_simple_poll_get(simple_poll), (AvahiClientFlags)0, client_callback, this, &error); 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 */ /* Create the service browser */
if (!client_) 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_))));
logE << "Failed to create client: " << avahi_strerror(error) << "\n";
goto fail;
}
/* Create the service browser */ result_.valid_ = false;
if (!(sb_ = avahi_service_browser_new(client_, AVAHI_IF_UNSPEC, proto, serviceName.c_str(), NULL, (AvahiLookupFlags)0, browse_callback, this))) while (timeout > 0)
{
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 = result_; avahi_simple_poll_iterate(simple_poll, 100);
return true; timeout -= 100;
if (result_.valid_)
{
result = result_;
cleanUp();
return true;
}
} }
}
fail: cleanUp();
return false; return false;
}
catch (...)
{
cleanUp();
throw;
}
} }

View file

@ -44,6 +44,7 @@ public:
bool browse(const std::string& serviceName, int proto, AvahiResult& result, int timeout); bool browse(const std::string& serviceName, int proto, AvahiResult& result, int timeout);
private: 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 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 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); static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata);

View file

@ -145,13 +145,21 @@ int main (int argc, char *argv[])
AvahiResult avahiResult; AvahiResult avahiResult;
while (!g_terminated) while (!g_terminated)
{ {
if (browseAvahi.browse("_snapcast._tcp", AVAHI_PROTO_INET, avahiResult, 5000)) try
{ {
ip = avahiResult.ip_; if (browseAvahi.browse("_snapcast._tcp", AVAHI_PROTO_INET, avahiResult, 5000))
port = avahiResult.port_; {
std::cout << ip << ":" << port << "\n"; ip = avahiResult.ip_;
break; 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);
} }
} }