Merge pull request #4857 from t-nelson/Gotham_13.2_backports
[vuplus_xbmc] / xbmc / network / Zeroconf.h
1 #pragma once
2
3 /*
4  *      Copyright (C) 2005-2013 Team XBMC
5  *      http://xbmc.org
6  *
7  *  This Program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2, or (at your option)
10  *  any later version.
11  *
12  *  This Program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with XBMC; see the file COPYING.  If not, see
19  *  <http://www.gnu.org/licenses/>.
20  *
21  */
22
23 #include <string>
24 #include <map>
25 #include <vector>
26 #include "utils/Job.h"
27
28 class CCriticalSection;
29 /// this class provides support for zeroconf
30 /// while the different zeroconf implementations have asynchronous APIs
31 /// this class hides it and provides only few ways to interact
32 /// with the services. If more control is needed, feel
33 /// free to add it. The main purpose currently is to provide an easy
34 /// way to publish services in the different StartXXX/StopXXX methods
35 /// in CApplication
36 /// TODO: Make me safe for use in static initialization. CritSec is a static member :/
37 ///       use e.g. loki's singleton implementation to make do it properly
38 class CZeroconf
39 {
40 public:
41
42   //tries to publish this service via zeroconf
43   //fcr_identifier can be used to stop or reannounce this service later
44   //fcr_type is the zeroconf service type to publish (e.g. _http._tcp for webserver)
45   //fcr_name is the name of the service to publish. The hostname is currently automatically appended
46   //         and used for name collisions. e.g. XBMC would get published as fcr_name@Martn or, after collision fcr_name@Martn-2
47   //f_port port of the service to publish
48   // returns false if fcr_identifier was already present
49   bool PublishService(const std::string& fcr_identifier,
50                       const std::string& fcr_type,
51                       const std::string& fcr_name,
52                       unsigned int f_port,
53                       std::vector<std::pair<std::string, std::string> > txt /*= std::vector<std::pair<std::string, std::string> >()*/);
54   
55   //tries to rebroadcast that service on the network without removing/readding
56   //this can be achieved by changing a fake txt record. Implementations should
57   //implement it by doing so.
58   //
59   //fcr_identifier - the identifier of the already published service which should be reannounced
60   // returns true on successfull reannonuce - false if this service isn't published yet
61   bool ForceReAnnounceService(const std::string& fcr_identifier);
62
63   ///removes the specified service
64   ///returns false if fcr_identifier does not exist
65   bool RemoveService(const std::string& fcr_identifier);
66
67   ///returns true if fcr_identifier exists
68   bool HasService(const std::string& fcr_identifier) const;
69
70   //starts publishing
71   //services that were added with PublishService(...) while Zeroconf wasn't
72   //started, get published now.
73   bool Start();
74
75   // unpublishs all services (but keeps them stored in this class)
76   // a call to Start() will republish them
77   void Stop();
78
79   // class methods
80   // access to singleton; singleton gets created on call if not existent
81   // if zeroconf is disabled (!HAS_ZEROCONF), this will return a dummy implementation that
82   // just does nothings, otherwise the platform specific one
83   static CZeroconf* GetInstance();
84   // release the singleton; (save to call multiple times)
85   static void   ReleaseInstance();
86   // returns false if ReleaseInstance() was called befores
87   static bool   IsInstantiated() { return  smp_instance != 0; }
88   // win32: process results from the bonjour daemon
89   virtual void  ProcessResults() {}
90   // returns if the service is started and services are announced
91   bool IsStarted() { return m_started; }
92
93 protected:
94   //methods to implement for concrete implementations
95   //publishs this service
96   virtual bool doPublishService(const std::string& fcr_identifier,
97                                 const std::string& fcr_type,
98                                 const std::string& fcr_name,
99                                 unsigned int f_port,
100                                 const std::vector<std::pair<std::string, std::string> >& txt) = 0;
101
102   //methods to implement for concrete implementations
103   //update this service
104   virtual bool doForceReAnnounceService(const std::string& fcr_identifier) = 0;
105   
106   //removes the service if published
107   virtual bool doRemoveService(const std::string& fcr_ident) = 0;
108
109   //removes all services (short hand for "for i in m_service_map doRemoveService(i)")
110   virtual void doStop() = 0;
111
112   // return true if the zeroconf daemon is running
113   virtual bool IsZCdaemonRunning() { return  true; }
114
115 protected:
116   //singleton: we don't want to get instantiated nor copied or deleted from outside
117   CZeroconf();
118   CZeroconf(const CZeroconf&);
119   virtual ~CZeroconf();
120
121 private:
122   struct PublishInfo{
123     std::string type;
124     std::string name;
125     unsigned int port;
126     std::vector<std::pair<std::string, std::string> > txt;
127   };
128
129   //protects data
130   CCriticalSection* mp_crit_sec;
131   typedef std::map<std::string, PublishInfo> tServiceMap;
132   tServiceMap m_service_map;
133   bool m_started;
134
135   //protects singleton creation/destruction
136   static long sm_singleton_guard;
137   static CZeroconf* smp_instance;
138
139   class CPublish : public CJob
140   {
141   public:
142     CPublish(const std::string& fcr_identifier, const PublishInfo& pubinfo);
143     CPublish(const tServiceMap& servmap);
144
145     bool DoWork();
146
147   private:
148     tServiceMap m_servmap;
149   };
150 };