[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / network / ZeroconfBrowser.h
1 #pragma once
2
3 /*
4  *      Copyright (C) 2005-2013 Team XBMC
5  *      http://www.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 <set>
25 #include <vector>
26 #include <map>
27
28 #include "utils/StdString.h"
29
30 #ifdef _WIN32
31 #undef SetPort // WIN32INCLUDES this is defined as SetPortA in WinSpool.h which is being included _somewhere_
32 #endif
33
34 //forwards
35 class CCriticalSection;
36
37 /// this class provides support for zeroconf browsing
38 class CZeroconfBrowser
39 {
40 public:
41   class ZeroconfService
42   {
43     public:
44       typedef std::map<std::string, std::string> tTxtRecordMap;
45
46       ZeroconfService();
47       ZeroconfService(const CStdString& fcr_name, const CStdString& fcr_type, const CStdString& fcr_domain);
48
49       /// easy conversion to string and back (used in czeronfdiretory to store this service)
50       ///@{
51       static CStdString toPath(const ZeroconfService& fcr_service);
52       static ZeroconfService fromPath(const CStdString& fcr_path); //throws std::runtime_error on failure
53       ///@}
54
55       /// general access methods
56       ///@{
57       void SetName(const CStdString& fcr_name);
58       const CStdString& GetName() const {return m_name;}
59
60       void SetType(const CStdString& fcr_type);
61       const CStdString& GetType() const {return m_type;}
62
63       void SetDomain(const CStdString& fcr_domain);
64       const CStdString& GetDomain() const {return m_domain;}
65       ///@}
66
67       /// access methods needed during resolve
68       ///@{
69       void SetIP(const CStdString& fcr_ip);
70       const CStdString& GetIP() const {return m_ip;}
71
72       void SetPort(int f_port);
73       int GetPort() const {return m_port;}
74     
75       void SetTxtRecords(const tTxtRecordMap& txt_records);
76       const tTxtRecordMap& GetTxtRecords() const { return m_txtrecords_map;}
77       ///@}
78     private:
79       //3 entries below identify a service
80       CStdString m_name;
81       CStdString m_type;
82       CStdString m_domain;
83
84       //2 entries below store 1 ip:port pair for this service
85       CStdString m_ip;
86       int        m_port;
87       
88       //1 entry below stores the txt-record as a key value map for this service
89       tTxtRecordMap m_txtrecords_map;    
90   };
91
92   // starts browsing
93   void Start();
94
95   // stops browsing
96   void Stop();
97
98   ///returns the list of found services
99   /// if this is updated, the following message with "zeroconf://" as path is sent:
100   /// CGUIMessage message(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_PATH);
101   std::vector<ZeroconfService> GetFoundServices();
102   ///@}
103
104   // resolves a ZeroconfService to ip + port
105   // @param fcr_service the service to resolve
106   // @param f_timeout timeout in seconds for resolving
107   //   the protocol part of CURL is the raw zeroconf service type
108   //   added with AddServiceType (== needs further processing! e.g. _smb._tcp -> smb)
109   // @return true if it was successfully resolved (or scheduled), false if resolve
110   //         failed (async or not)
111   bool ResolveService(ZeroconfService& fr_service, double f_timeout = 1.0);
112
113   // class methods
114   // access to singleton; singleton gets created on call if not existent
115   // if zeroconf is disabled (!HAS_ZEROCONF), this will return a dummy implementation that
116   // just does nothings, otherwise the platform specific one
117   static CZeroconfBrowser* GetInstance();
118   // release the singleton; (save to call multiple times)
119   static void ReleaseInstance();
120   // returns false if ReleaseInstance() was called befores
121   static bool IsInstantiated() { return  smp_instance != 0; }
122
123   virtual void ProcessResults() {}
124
125 protected:
126   // pure virtual methods to implement for OS specific implementations
127   virtual bool doAddServiceType(const CStdString& fcr_service_type) = 0;
128   virtual bool doRemoveServiceType(const CStdString& fcr_service_type) = 0;
129   virtual std::vector<ZeroconfService> doGetFoundServices() = 0;
130   virtual bool doResolveService(ZeroconfService& fr_service, double f_timeout) = 0;
131
132 protected:
133   //singleton: we don't want to get instantiated nor copied or deleted from outside
134   CZeroconfBrowser();
135   CZeroconfBrowser(const CZeroconfBrowser&);
136   virtual ~CZeroconfBrowser();
137
138 private:
139   /// methods for browsing and getting results of it
140   ///@{
141   /// adds a service type for browsing
142   /// @param fcr_service_type the service type as string, e.g. _smb._tcp.
143   /// @return false if it was already there
144   bool AddServiceType(const CStdString& fcr_service_type);
145
146   /// remove the specified service from discovery
147   /// @param fcr_service_type the service type as string, e.g. _smb._tcp.
148   /// @return if it was not found
149   bool RemoveServiceType(const CStdString& fcr_service_type);
150
151   struct ServiceInfo
152   {
153     CStdString type;
154   };
155
156   //protects data
157   CCriticalSection* mp_crit_sec;
158   typedef std::set<CStdString> tServices;
159   tServices m_services;
160   bool m_started;
161
162   //protects singleton creation/destruction
163   static long sm_singleton_guard;
164   static CZeroconfBrowser* smp_instance;
165 };
166 #include <iostream>
167
168 //debugging helper
169 inline std::ostream& operator<<(std::ostream& o, const CZeroconfBrowser::ZeroconfService& service){
170   o << "(" << service.GetName() << "|" << service.GetType() << "|" << service.GetDomain() << ")";
171   return o;
172 }
173
174 //inline methods
175 inline bool operator<(CZeroconfBrowser::ZeroconfService const& fcr_lhs, CZeroconfBrowser::ZeroconfService const& fcr_rhs)
176 {
177   return (fcr_lhs.GetName() +  fcr_lhs.GetType() + fcr_lhs.GetDomain() < fcr_rhs.GetName() + fcr_rhs.GetType() + fcr_rhs.GetDomain());
178 }
179
180 inline bool operator==(CZeroconfBrowser::ZeroconfService const& fcr_lhs, CZeroconfBrowser::ZeroconfService const& fcr_rhs)
181 {
182   return (fcr_lhs.GetName() == fcr_rhs.GetName() && fcr_lhs.GetType() == fcr_rhs.GetType() && fcr_lhs.GetDomain() == fcr_rhs.GetDomain() );
183 }