Logo ROOT   6.16/01
Reference Guide
TBonjourBrowser.cxx
Go to the documentation of this file.
1// @(#)root/bonjour:$Id$
2// Author: Fons Rademakers 29/05/2009
3
4/*************************************************************************
5 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//////////////////////////////////////////////////////////////////////////
13// //
14// TBonjourBrowser //
15// //
16// This class consists of one main member function, //
17// BrowseForServiceType(), that looks for the service. //
18// The rest of the class wraps the various bits of Bonjour service //
19// browser. The static callback function is marked with the DNSSD_API //
20// macro to make sure that the callback has the correct calling //
21// convention on Windows. //
22// //
23// Bonjour works out-of-the-box on MacOS X. On Linux you have to //
24// install the Avahi package and run the avahi-daemon. To compile //
25// these classes and run Avahi on Linux you need to install the: //
26// avahi //
27// avahi-compat-libdns_sd-devel //
28// nss-mdns //
29// packages. After installation make sure the avahi-daemon is started. //
30// //
31//////////////////////////////////////////////////////////////////////////
32
33#include "TBonjourBrowser.h"
34#include "TBonjourRecord.h"
35#include "TSysEvtHandler.h"
36#include "TList.h"
37#include "TError.h"
38#include "TSystem.h"
39
40
42
43////////////////////////////////////////////////////////////////////////////////
44/// Default ctor.
45
46TBonjourBrowser::TBonjourBrowser() : fDNSRef(0), fBonjourSocketHandler(0)
47{
50
51 // silence Avahi about using Bonjour compat layer
52 gSystem->Setenv("AVAHI_COMPAT_NOWARN", "1");
53}
54
55////////////////////////////////////////////////////////////////////////////////
56/// Cleanup.
57
59{
60 delete fBonjourRecords;
62
63 if (fDNSRef) {
64 DNSServiceRefDeallocate(fDNSRef);
65 fDNSRef = 0;
66 }
67}
68
69////////////////////////////////////////////////////////////////////////////////
70/// Tell Bonjour to start browsing for a specific type of service.
71/// Returns -1 in case of error, 0 otherwise.
72
74{
75 DNSServiceErrorType err = DNSServiceBrowse(&fDNSRef, 0,
76 0, serviceType, 0,
77 (DNSServiceBrowseReply)BonjourBrowseReply,
78 this);
79 if (err != kDNSServiceErr_NoError) {
80 Error("BrowseForServiceType", "error in DNSServiceBrowse (%d)", err);
81 return -1;
82 }
83
84 Int_t sockfd = DNSServiceRefSockFD(fDNSRef);
85 if (sockfd == -1) {
86 Error("BrowseForServiceType", "invalid sockfd");
87 return -1;
88 }
89
91 fBonjourSocketHandler->Connect("Notified()", "TBonjourBrowser", this, "BonjourSocketReadyRead()");
93
94 return 0;
95}
96
97////////////////////////////////////////////////////////////////////////////////
98/// Emit CurrentBonjourRecordsChanged signal.
99
101{
102 Emit("CurrentBonjourRecordsChanged(TList*)", (Long_t)bonjourRecords);
103}
104
105////////////////////////////////////////////////////////////////////////////////
106/// The Bonjour socket is ready for reading. Tell Bonjour to process the
107/// information on the socket, this will invoke the BonjourBrowseReply
108/// callback. This is a private slot, used in BrowseForServiceType.
109
111{
112 // in case the browser has already been deleted
113 if (!fDNSRef) return;
114
115 DNSServiceErrorType err = DNSServiceProcessResult(fDNSRef);
116 if (err != kDNSServiceErr_NoError)
117 Error("BonjourSocketReadyRead", "error in DNSServiceProcessResult");
118}
119
120////////////////////////////////////////////////////////////////////////////////
121/// Static Bonjour browser callback function.
122
124 DNSServiceFlags flags, UInt_t,
125 DNSServiceErrorType errorCode,
126 const char *serviceName, const char *regType,
127 const char *replyDomain, void *context)
128{
129 TBonjourBrowser *browser = static_cast<TBonjourBrowser*>(context);
130 if (errorCode != kDNSServiceErr_NoError) {
131 ::Error("TBonjourBrowser::BonjourBrowseReply", "error in BonjourBrowseReply");
132 //browser->Error(errorCode);
133 } else {
134 TBonjourRecord *record = new TBonjourRecord(serviceName, regType, replyDomain);
135 if (flags & kDNSServiceFlagsAdd) {
136 if (!browser->fBonjourRecords->FindObject(record))
137 browser->fBonjourRecords->Add(record);
138 else
139 delete record;
140 } else {
142 delete r;
143 delete record;
144 }
145 if (!(flags & kDNSServiceFlagsMoreComing)) {
147 }
148 }
149}
ROOT::R::TRInterface & r
Definition: Object.C:4
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
long Long_t
Definition: RtypesCore.h:50
#define ClassImp(name)
Definition: Rtypes.h:363
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
TList * fBonjourRecords
static void DNSSD_API BonjourBrowseReply(DNSServiceRef, DNSServiceFlags, UInt_t, DNSServiceErrorType, const char *, const char *, const char *, void *)
Static Bonjour browser callback function.
void CurrentBonjourRecordsChanged(TList *bonjourRecords)
Emit CurrentBonjourRecordsChanged signal.
TFileHandler * fBonjourSocketHandler
DNSServiceRef fDNSRef
void BonjourSocketReadyRead()
The Bonjour socket is ready for reading.
Int_t BrowseForServiceType(const char *serviceType)
Tell Bonjour to start browsing for a specific type of service.
TBonjourBrowser()
Default ctor.
virtual ~TBonjourBrowser()
Cleanup.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void Add()
Add file event handler to system file handler list.
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition: TQObject.h:165
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot.
Definition: TQObject.cxx:867
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1636