Logo ROOT   6.12/07
Reference Guide
TBonjourResolver.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 // TBonjourResolver //
15 // //
16 // This class consists of one main member function, //
17 // ResolveBonjourRecord(), that resolves the service to an actual //
18 // IP address and port number. The rest of the class wraps the various //
19 // bits of Bonjour service resolver. The static callback function //
20 // is marked with the DNSSD_API macro to make sure that the callback //
21 // has the correct calling convention on Windows. //
22 // //
23 //////////////////////////////////////////////////////////////////////////
24 
25 #include "TBonjourResolver.h"
26 #include "TBonjourBrowser.h"
27 #include "TBonjourRecord.h"
28 #include "TSysEvtHandler.h"
29 #include "TSystem.h"
30 #include "TError.h"
31 
32 #include <arpa/inet.h>
33 
34 
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Default ctor.
39 
40 TBonjourResolver::TBonjourResolver() : fDNSRef(0), fBonjourSocketHandler(0), fPort(0)
41 {
42 }
43 
44 ////////////////////////////////////////////////////////////////////////////////
45 /// Cleanup.
46 
48 {
49  delete fBonjourSocketHandler;
50 
51  if (fDNSRef) {
52  DNSServiceRefDeallocate(fDNSRef);
53  fDNSRef = 0;
54  }
55 }
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 /// Resolve Bonjour service to IP address and port.
59 /// Returns -1 in case of error, 0 otherwise.
60 
62 {
63  if (fDNSRef) {
64  Warning("ResolveBonjourRecord", "resolve already in process");
65  return 0;
66  }
67 
68  DNSServiceErrorType err = DNSServiceResolve(&fDNSRef, 0, 0,
69  record.GetServiceName(),
70  record.GetRegisteredType(),
71  record.GetReplyDomain(),
72  (DNSServiceResolveReply)BonjourResolveReply,
73  this);
74  if (err != kDNSServiceErr_NoError) {
75  Error("ResolveBonjourRecord", "error in DNSServiceResolve (%d)", err);
76  return -1;
77  }
78 
79  Int_t sockfd = DNSServiceRefSockFD(fDNSRef);
80  if (sockfd == -1) {
81  Error("ResolveBonjourRecord", "invalide sockfd");
82  return -1;
83  }
84 
86  fBonjourSocketHandler->Connect("Notified()", "TBonjourResolver", this, "BonjourSocketReadyRead()");
88 
89  return 0;
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 /// Emit RecordResolved signal.
94 
96 {
97  Long_t args[2];
98  args[0] = (Long_t) hostInfo;
99  args[1] = port;
100 
101  Emit("RecordResolved(TInetAddress*,Int_t)", args);
102 }
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// The Bonjour socket is ready for reading. Tell Bonjour to process the
106 /// information on the socket, this will invoke the BonjourResolveReply
107 /// callback. This is a private slot, used in ResolveBonjourRecord.
108 
110 {
111  // in case the resolver has already been deleted
112  if (!fDNSRef) return;
113 
114  DNSServiceErrorType err = DNSServiceProcessResult(fDNSRef);
115  if (err != kDNSServiceErr_NoError)
116  Error("BonjourSocketReadyRead", "error in DNSServiceProcessResult");
117 }
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// Static Bonjour resolver callback function.
121 
123  DNSServiceFlags, UInt_t,
124  DNSServiceErrorType errorCode, const char *,
125  const char *hostTarget, UShort_t port,
126  UShort_t, const char *txtRecord,
127  void *context)
128 {
129  TBonjourResolver *resolver = static_cast<TBonjourResolver *>(context);
130  if (errorCode != kDNSServiceErr_NoError) {
131  ::Error("TBonjourResolver::BonjourResolveReply", "error in BonjourResolveReply");
132  //resolver->Error(errorCode);
133  } else {
134  resolver->fPort = ntohs(port);
135  resolver->fHostAddress = gSystem->GetHostByName(hostTarget);
136  resolver->fTXTRecord = txtRecord;
137  resolver->RecordResolved(&resolver->fHostAddress, resolver->fPort);
138  }
139 }
void BonjourSocketReadyRead()
The Bonjour socket is ready for reading.
Int_t ResolveBonjourRecord(const TBonjourRecord &record)
Resolve Bonjour service to IP address and port.
unsigned short UShort_t
Definition: RtypesCore.h:36
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:36
virtual void Add()
Add file event handler to system file handler list.
TBonjourResolver()
Default ctor.
int Int_t
Definition: RtypesCore.h:41
void RecordResolved(const TInetAddress *hostInfo, Int_t port)
Emit RecordResolved signal.
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2320
virtual ~TBonjourResolver()
Cleanup.
DNSServiceRef fDNSRef
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
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
long Long_t
Definition: RtypesCore.h:50
static void DNSSD_API BonjourResolveReply(DNSServiceRef, DNSServiceFlags, UInt_t, DNSServiceErrorType, const char *, const char *, UShort_t, UShort_t, const char *, void *)
Static Bonjour resolver callback function.
#define ClassImp(name)
Definition: Rtypes.h:359
TFileHandler * fBonjourSocketHandler
const char * GetReplyDomain() const
TInetAddress fHostAddress
const char * GetServiceName() const
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition: TQObject.h:165
const char * GetRegisteredType() const
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866