Line data Source code
1 : /* Copyright (c) 2012-2017, Human Brain Project
2 : * Stefan.Eilemann@epfl.ch
3 : *
4 : * This file is part of Servus <https://github.com/HBPVIS/Servus>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 3.0 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #ifndef SERVUS_SERVUS_H
21 : #define SERVUS_SERVUS_H
22 :
23 : #include <servus/api.h>
24 : #include <servus/result.h> // nested base class
25 : #include <servus/types.h>
26 :
27 : #include <map>
28 : #include <memory>
29 :
30 : namespace servus
31 : {
32 : /** Service name to be used by unit tests. All Servus instances with this name
33 : * "communicate" through global data, that is, announced key-value pairs are
34 : * communicated to all browsing instances in the same process. */
35 17 : static const std::string TEST_DRIVER{"_servus._test"};
36 :
37 : /**
38 : * Simple wrapper for ZeroConf key/value pairs.
39 : *
40 : * The servus class allows simple announcement and discovery of key/value pairs
41 : * using ZeroConf networking. The same instance can be used to announce and/or
42 : * to browse a ZeroConf service. If the Servus library is compiled without
43 : * zeroconf support (@sa isAvailable()), this class does not do anything useful.
44 : *
45 : * Example: @include tests/servus.cpp
46 : */
47 : class Servus
48 : {
49 : public:
50 : enum Interface
51 : {
52 : IF_ALL = 0, //!< use all interfaces
53 : // (uint32_t) -1 == kDNSServiceInterfaceIndexLocalOnly
54 : IF_LOCAL = (unsigned)(-1) //!< only local interfaces
55 : };
56 :
57 : /**
58 : * The ZeroConf operation result code.
59 : *
60 : * The result code is either one of kDNSServiceErr_ or one of static
61 : * constants defined by this class
62 : */
63 : class Result : public servus::Result
64 : {
65 : public:
66 53 : explicit Result(const int32_t code)
67 53 : : servus::Result(code)
68 : {
69 53 : }
70 53 : virtual ~Result() {}
71 : SERVUS_API std::string getString() const override;
72 :
73 : /** operation did not complete. */
74 : static const int32_t PENDING = -1;
75 : /** Servus compiled without ZeroConf support. */
76 : static const int32_t NOT_SUPPORTED = -2;
77 : /** Error during polling for event. */
78 : static const int32_t POLL_ERROR = -3;
79 : };
80 :
81 : /** @return true if a usable implementation is available. */
82 : SERVUS_API static bool isAvailable();
83 :
84 : /**
85 : * Create a new service handle.
86 : *
87 : * @param name the service descriptor, e.g., "_hwsd._tcp"
88 : * @version 1.1
89 : */
90 : SERVUS_API explicit Servus(const std::string& name);
91 :
92 : /** Destruct this service. @version 1.1 */
93 : SERVUS_API virtual ~Servus();
94 :
95 : /** @return the service name. @version 1.1 */
96 : SERVUS_API const std::string& getName() const;
97 :
98 : /**
99 : * Set a key/value pair to be announced.
100 : *
101 : * Keys should be at most eight characters, and values are truncated to 255
102 : * characters. The total length of all keys and values cannot exceed 65535
103 : * characters. Setting a value on an announced service causes an update
104 : * which needs some time to propagate after this function returns, that is,
105 : * calling discover() immediately afterwards will very likely not contain
106 : * the new key/value pair.
107 : *
108 : * @version 1.1
109 : */
110 : SERVUS_API void set(const std::string& key, const std::string& value);
111 :
112 : /** @return all (to be) announced keys. @version 1.1 */
113 : SERVUS_API Strings getKeys() const;
114 :
115 : /** @return the value to the given (to be) announced key. @version 1.1 */
116 : SERVUS_API const std::string& get(const std::string& key) const;
117 :
118 : /**
119 : * Start announcing the registered key/value pairs.
120 : *
121 : * @param port the service IP port in host byte order.
122 : * @param instance a host-unique instance name, hostname is used if empty.
123 : * @return the success status of the operation.
124 : * @version 1.1
125 : */
126 : SERVUS_API Result announce(const unsigned short port,
127 : const std::string& instance);
128 :
129 : /** Stop announcing the registered key/value pairs. @version 1.1 */
130 : SERVUS_API void withdraw();
131 :
132 : /** @return true if the local data is announced. @version 1.1 */
133 : SERVUS_API bool isAnnounced() const;
134 :
135 : /**
136 : * Discover all announced key/value pairs.
137 : *
138 : * @param addr the scope of the discovery
139 : * @param browseTime the browse time, in milliseconds, to wait for new
140 : * records.
141 : * @return all instance names found during discovery.
142 : * @sa beginBrowsing(), browse(), endBrowsing()
143 : * @version 1.1
144 : */
145 : SERVUS_API Strings discover(const Interface addr,
146 : const unsigned browseTime);
147 :
148 : /**
149 : * Begin the discovery of announced key/value pairs.
150 : *
151 : * @param addr the scope of the discovery
152 : * @return the success status of the operation.
153 : * @version 1.1
154 : */
155 : SERVUS_API Result beginBrowsing(const servus::Servus::Interface addr);
156 :
157 : /**
158 : * Browse and process discovered key/value pairs.
159 : *
160 : * @param timeout The time to spend browsing.
161 : * @return the success status of the operation.
162 : * @version 1.1
163 : */
164 : SERVUS_API Result browse(int32_t timeout = -1);
165 :
166 : /** Stop a discovery process and return all results. @version 1.1 */
167 : SERVUS_API void endBrowsing();
168 :
169 : /** @return true if the local data is browsing. @version 1.1 */
170 : SERVUS_API bool isBrowsing() const;
171 :
172 : /** @return all instances found during the last discovery. @version 1.1 */
173 : SERVUS_API Strings getInstances() const;
174 :
175 : /** @return all keys discovered on the given instance. @version 1.1 */
176 : SERVUS_API Strings getKeys(const std::string& instance) const;
177 :
178 : /** @return the host corresponding to the given instance. @version 1.3 */
179 : SERVUS_API const std::string& getHost(const std::string& instance) const;
180 :
181 : /** @return true if the given key was discovered. @version 1.1 */
182 : SERVUS_API bool containsKey(const std::string& instance,
183 : const std::string& key) const;
184 :
185 : /** @return the value of the given key and instance. @version 1.1 */
186 : SERVUS_API const std::string& get(const std::string& instance,
187 : const std::string& key) const;
188 :
189 : /**
190 : * Add a listener which is invoked according to its supported callbacks.
191 : *
192 : * @param listener the listener to be added, must not be nullptr
193 : * @version 1.2
194 : */
195 : SERVUS_API void addListener(Listener* listener);
196 :
197 : /**
198 : * Remove a listener to stop invokation on its supported callbacks.
199 : *
200 : * @param listener the listener to be removed, must not be nullptr
201 : * @version 1.2
202 : */
203 : SERVUS_API void removeListener(Listener* listener);
204 :
205 : /** @internal */
206 : typedef std::map<std::string, std::map<std::string, std::string> > Data;
207 :
208 : /** @internal */
209 : SERVUS_API void getData(Data& data);
210 :
211 : class Impl; //!< @internal
212 :
213 : private:
214 : Servus(const Servus&) = delete;
215 : Servus& operator=(const Servus&) = delete;
216 :
217 : std::unique_ptr<Impl> _impl;
218 :
219 : friend SERVUS_API std::ostream& operator<<(std::ostream&, const Servus&);
220 : };
221 :
222 : /** @return the local hostname. */
223 : SERVUS_API std::string getHostname();
224 :
225 : /** Output the servus instance in human-readable format. */
226 : SERVUS_API std::ostream& operator<<(std::ostream&, const Servus&);
227 :
228 : /** Output the servus interface in human-readable format. */
229 : SERVUS_API std::ostream& operator<<(std::ostream&, const Servus::Interface&);
230 : }
231 :
232 : #endif // SERVUS_SERVUS_H
|