#include "TBonjourBrowser.h"
#include "TBonjourRecord.h"
#include "TSysEvtHandler.h"
#include "TList.h"
#include "TError.h"
#include "TSystem.h"
ClassImp(TBonjourBrowser)
TBonjourBrowser::TBonjourBrowser() : fDNSRef(0), fBonjourSocketHandler(0)
{
fBonjourRecords = new TList;
fBonjourRecords->SetOwner();
gSystem->Setenv("AVAHI_COMPAT_NOWARN", "1");
}
TBonjourBrowser::~TBonjourBrowser()
{
delete fBonjourRecords;
delete fBonjourSocketHandler;
if (fDNSRef) {
DNSServiceRefDeallocate(fDNSRef);
fDNSRef = 0;
}
}
Int_t TBonjourBrowser::BrowseForServiceType(const char *serviceType)
{
DNSServiceErrorType err = DNSServiceBrowse(&fDNSRef, 0,
0, serviceType, 0,
(DNSServiceBrowseReply)BonjourBrowseReply,
this);
if (err != kDNSServiceErr_NoError) {
Error("BrowseForServiceType", "error in DNSServiceBrowse (%d)", err);
return -1;
}
Int_t sockfd = DNSServiceRefSockFD(fDNSRef);
if (sockfd == -1) {
Error("BrowseForServiceType", "invalid sockfd");
return -1;
}
fBonjourSocketHandler = new TFileHandler(sockfd, TFileHandler::kRead);
fBonjourSocketHandler->Connect("Notified()", "TBonjourBrowser", this, "BonjourSocketReadyRead()");
fBonjourSocketHandler->Add();
return 0;
}
void TBonjourBrowser::CurrentBonjourRecordsChanged(TList *bonjourRecords)
{
Emit("CurrentBonjourRecordsChanged(TList*)", (Long_t)bonjourRecords);
}
void TBonjourBrowser::BonjourSocketReadyRead()
{
if (!fDNSRef) return;
DNSServiceErrorType err = DNSServiceProcessResult(fDNSRef);
if (err != kDNSServiceErr_NoError)
Error("BonjourSocketReadyRead", "error in DNSServiceProcessResult");
}
void TBonjourBrowser::BonjourBrowseReply(DNSServiceRef,
DNSServiceFlags flags, UInt_t,
DNSServiceErrorType errorCode,
const char *serviceName, const char *regType,
const char *replyDomain, void *context)
{
TBonjourBrowser *browser = static_cast<TBonjourBrowser*>(context);
if (errorCode != kDNSServiceErr_NoError) {
::Error("TBonjourBrowser::BonjourBrowseReply", "error in BonjourBrowseReply");
} else {
TBonjourRecord *record = new TBonjourRecord(serviceName, regType, replyDomain);
if (flags & kDNSServiceFlagsAdd) {
if (!browser->fBonjourRecords->FindObject(record))
browser->fBonjourRecords->Add(record);
else
delete record;
} else {
TBonjourRecord *r = (TBonjourRecord*)browser->fBonjourRecords->Remove(record);
delete r;
delete record;
}
if (!(flags & kDNSServiceFlagsMoreComing)) {
browser->CurrentBonjourRecordsChanged(browser->fBonjourRecords);
}
}
}