TBonjourRegistrar.cxx

Go to the documentation of this file.
00001 // @(#)root/bonjour:$Id: TBonjourRegistrar.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 // TBonjourRegistrar                                                    //
00015 //                                                                      //
00016 // This class consists of one main member function, RegisterService(),  //
00017 // that registers the service. As long as the object is alive, the      //
00018 // service stays registered. The rest of the class wraps the various    //
00019 // bits of Bonjour service registration. 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 // Bonjour works out-of-the-box on MacOS X. On Linux you have to        //
00024 // install the Avahi package and run the avahi-daemon. To compile       //
00025 // these classes and run Avahi on Linux you need to install the:        //
00026 //    avahi                                                             //
00027 //    avahi-compat-libdns_sd-devel                                      //
00028 //    nss-mdns                                                          //
00029 // packages. After installation make sure the avahi-daemon is started.  //
00030 //                                                                      //
00031 //////////////////////////////////////////////////////////////////////////
00032 
00033 #include "TBonjourRegistrar.h"
00034 #include "TSysEvtHandler.h"
00035 #include "TError.h"
00036 #include "TSystem.h"
00037 
00038 #include <arpa/inet.h>
00039 
00040 
00041 ClassImp(TBonjourRegistrar)
00042 
00043 //______________________________________________________________________________
00044 TBonjourRegistrar::TBonjourRegistrar() : fDNSRef(0), fBonjourSocketHandler(0)
00045 {
00046    // Default ctor.
00047 
00048    // silence Avahi about using Bonjour compat layer
00049    gSystem->Setenv("AVAHI_COMPAT_NOWARN", "1");
00050 }
00051 
00052 //______________________________________________________________________________
00053 TBonjourRegistrar::~TBonjourRegistrar()
00054 {
00055    // Cleanup.
00056 
00057    delete fBonjourSocketHandler;
00058 
00059    if (fDNSRef) {
00060       DNSServiceRefDeallocate(fDNSRef);
00061       fDNSRef = 0;
00062    }
00063 }
00064 
00065 //______________________________________________________________________________
00066 Int_t TBonjourRegistrar::RegisterService(const TBonjourRecord &record, UShort_t servicePort)
00067 {
00068    // Register Bonjour service.
00069    // Return -1 in case or error, 0 otherwise.
00070 
00071    if (fDNSRef) {
00072       Warning("RegisterService", "already registered a service");
00073       return 0;
00074    }
00075 
00076    UShort_t sport = htons(servicePort);
00077 
00078    // register our service and callback
00079    DNSServiceErrorType err = DNSServiceRegister(&fDNSRef, 0, kDNSServiceInterfaceIndexAny,
00080                                                 !strlen(record.GetServiceName()) ? 0
00081                                                 : record.GetServiceName(),
00082                                                 record.GetRegisteredType(),
00083                                                 !strlen(record.GetReplyDomain()) ? 0
00084                                                 : record.GetReplyDomain(),
00085                                                 0, sport,
00086                                                 record.GetTXTRecordsLength(),
00087                                                 !strlen(record.GetTXTRecords()) ? 0
00088                                                 : record.GetTXTRecords(),
00089                                                 (DNSServiceRegisterReply)BonjourRegisterService,
00090                                                 this);
00091    if (err != kDNSServiceErr_NoError) {
00092       Error("RegisterService", "error in DNSServiceRegister (%d)", err);
00093       return -1;
00094    }
00095 
00096    Int_t sockfd = DNSServiceRefSockFD(fDNSRef);
00097    if (sockfd == -1) {
00098       Error("RegisterService", "invalid sockfd");
00099       return -1;
00100    }
00101 
00102    fBonjourSocketHandler = new TFileHandler(sockfd, TFileHandler::kRead);
00103    fBonjourSocketHandler->Connect("Notified()", "TBonjourRegistrar", this, "BonjourSocketReadyRead()");
00104    fBonjourSocketHandler->Add();
00105 
00106    return 0;
00107 }
00108 
00109 //______________________________________________________________________________
00110 void TBonjourRegistrar::ServiceRegistered(TBonjourRecord *record)
00111 {
00112    // Emit ServiceRegistered signal.
00113 
00114    Emit("ServiceRegistered(TBonjourRecord*)", (Long_t)record);
00115 }
00116 
00117 //______________________________________________________________________________
00118 void TBonjourRegistrar::BonjourSocketReadyRead()
00119 {
00120    // The Bonjour socket is ready for reading. Tell Bonjour to process the
00121    // information on the socket, this will invoke the BonjourRegisterService
00122    // callback. This is a private slot, used in RegisterService.
00123 
00124    DNSServiceErrorType err = DNSServiceProcessResult(fDNSRef);
00125    if (err != kDNSServiceErr_NoError)
00126       Error("BonjourSocketReadyRead", "error in DNSServiceProcessResult");
00127 }
00128 
00129 //______________________________________________________________________________
00130 void TBonjourRegistrar::BonjourRegisterService(DNSServiceRef, DNSServiceFlags,
00131                                                DNSServiceErrorType errCode,
00132                                                const char *name, const char *regType,
00133                                                const char *domain, void *context)
00134 {
00135    // Static Bonjour register callback function.
00136 
00137    TBonjourRegistrar *registrar = static_cast<TBonjourRegistrar*>(context);
00138    if (errCode != kDNSServiceErr_NoError) {
00139       ::Error("TBonjourRegistrar::BonjourRegisterService", "error in BonjourRegisterService");
00140       //registrar->Error(errorCode);
00141    } else {
00142       registrar->fFinalRecord = TBonjourRecord(name, regType, domain);
00143       registrar->ServiceRegistered(&registrar->fFinalRecord);
00144    }
00145 }

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