TBonjourResolver.cxx

Go to the documentation of this file.
00001 // @(#)root/bonjour:$Id: TBonjourResolver.cxx 34481 2010-07-19 14:51:45Z rdm $
00002 // Author: Fons Rademakers   29/05/2009
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TBonjourResolver                                                     //
00015 //                                                                      //
00016 // This class consists of one main member function,                     //
00017 // ResolveBonjourRecord(), that resolves the service to an actual       //
00018 // IP address and port number. The rest of the class wraps the various  //
00019 // bits of Bonjour service resolver. The static callback function       //
00020 // is marked with the DNSSD_API macro to make sure that the callback    //
00021 // has the correct calling convention on Windows.                       //
00022 //                                                                      //
00023 //////////////////////////////////////////////////////////////////////////
00024 
00025 #include "TBonjourResolver.h"
00026 #include "TBonjourRecord.h"
00027 #include "TSysEvtHandler.h"
00028 #include "TSystem.h"
00029 #include "TError.h"
00030 
00031 #include <arpa/inet.h>
00032 
00033 
00034 ClassImp(TBonjourResolver)
00035 
00036 //______________________________________________________________________________
00037 TBonjourResolver::TBonjourResolver() : fDNSRef(0), fBonjourSocketHandler(0)
00038 {
00039    // Default ctor.
00040 }
00041 
00042 //______________________________________________________________________________
00043 TBonjourResolver::~TBonjourResolver()
00044 {
00045    // Cleanup.
00046 
00047    delete fBonjourSocketHandler;
00048 
00049    if (fDNSRef) {
00050       DNSServiceRefDeallocate(fDNSRef);
00051       fDNSRef = 0;
00052    }
00053 }
00054 
00055 //______________________________________________________________________________
00056 Int_t TBonjourResolver::ResolveBonjourRecord(const TBonjourRecord &record)
00057 {
00058    // Resolve Bonjour service to IP address and port.
00059    // Returns -1 in case of error, 0 otherwise.
00060 
00061    if (fDNSRef) {
00062       Warning("ResolveBonjourRecord", "resolve already in process");
00063       return 0;
00064    }
00065 
00066    DNSServiceErrorType err = DNSServiceResolve(&fDNSRef, 0, 0,
00067                                                record.GetServiceName(),
00068                                                record.GetRegisteredType(),
00069                                                record.GetReplyDomain(),
00070                                                (DNSServiceResolveReply)BonjourResolveReply,
00071                                                this);
00072    if (err != kDNSServiceErr_NoError) {
00073       Error("ResolveBonjourRecord", "error in DNSServiceResolve (%d)", err);
00074       return -1;
00075    }
00076 
00077    Int_t sockfd = DNSServiceRefSockFD(fDNSRef);
00078    if (sockfd == -1) {
00079       Error("ResolveBonjourRecord", "invalide sockfd");
00080       return -1;
00081    }
00082 
00083    fBonjourSocketHandler = new TFileHandler(sockfd, TFileHandler::kRead);
00084    fBonjourSocketHandler->Connect("Notified()", "TBonjourResolver", this, "BonjourSocketReadyRead()");
00085    fBonjourSocketHandler->Add();
00086 
00087    return 0;
00088 }
00089 
00090 //______________________________________________________________________________
00091 void TBonjourResolver::RecordResolved(const TInetAddress *hostInfo, Int_t port)
00092 {
00093    // Emit RecordResolved signal.
00094 
00095    Long_t args[2];
00096    args[0] = (Long_t) hostInfo;
00097    args[1] = port;
00098 
00099    Emit("RecordResolved(TInetAddress*,Int_t)", args);
00100 }
00101 
00102 //______________________________________________________________________________
00103 void TBonjourResolver::BonjourSocketReadyRead()
00104 {
00105    // The Bonjour socket is ready for reading. Tell Bonjour to process the
00106    // information on the socket, this will invoke the BonjourResolveReply
00107    // callback. This is a private slot, used in ResolveBonjourRecord.
00108 
00109    // in case the resolver has already been deleted
00110    if (!fDNSRef) return;
00111 
00112    DNSServiceErrorType err = DNSServiceProcessResult(fDNSRef);
00113    if (err != kDNSServiceErr_NoError)
00114       Error("BonjourSocketReadyRead", "error in DNSServiceProcessResult");
00115 }
00116 
00117 //______________________________________________________________________________
00118 void TBonjourResolver::BonjourResolveReply(DNSServiceRef,
00119                                            DNSServiceFlags, UInt_t,
00120                                            DNSServiceErrorType errorCode, const char *,
00121                                            const char *hostTarget, UShort_t port,
00122                                            UShort_t, const char *txtRecord,
00123                                            void *context)
00124 {
00125    // Static Bonjour resolver callback function.
00126 
00127    TBonjourResolver *resolver = static_cast<TBonjourResolver *>(context);
00128    if (errorCode != kDNSServiceErr_NoError) {
00129       ::Error("TBonjourResolver::BonjourResolveReply", "error in BonjourResolveReply");
00130       //resolver->Error(errorCode);
00131    } else {
00132       resolver->fPort = ntohs(port);
00133       resolver->fHostAddress = gSystem->GetHostByName(hostTarget);
00134       resolver->fTXTRecord = txtRecord;
00135       resolver->RecordResolved(&resolver->fHostAddress, resolver->fPort);
00136    }
00137 }

Generated on Tue Jul 5 14:45:39 2011 for ROOT_528-00b_version by  doxygen 1.5.1