1 /*
2  * Copyright 2007-2021 CM4all GmbH
3  * All rights reserved.
4  *
5  * author: Max Kellermann <mk@cm4all.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * - Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * - Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
23  * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30  * OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #pragma once
34 
35 #include "EntryGroup.hxx"
36 #include "ConnectionListener.hxx"
37 
38 #include <avahi-client/publish.h>
39 
40 #include <string>
41 #include <forward_list>
42 
43 class SocketAddress;
44 
45 namespace Avahi {
46 
47 struct Service;
48 class ErrorHandler;
49 class Client;
50 
51 /**
52  * A helper class which manages a list of services to be published via
53  * Avahi/Zeroconf.
54  */
55 class Publisher final : ConnectionListener {
56 	ErrorHandler &error_handler;
57 
58 	std::string name;
59 
60 	Client &client;
61 
62 	EntryGroupPtr group;
63 
64 	const std::forward_list<Service> services;
65 
66 	/**
67 	 * Shall the published services be visible?  This is controlled by
68 	 * HideServices() and ShowServices().
69 	 */
70 	bool visible = true;
71 
72 public:
73 	Publisher(Client &client, const char *_name,
74 		  std::forward_list<Service> _services,
75 		  ErrorHandler &_error_handler) noexcept;
76 	~Publisher() noexcept;
77 
78 	Publisher(const Publisher &) = delete;
79 	Publisher &operator=(const Publisher &) = delete;
80 
81 	/**
82 	 * Temporarily hide all registered services.  You can undo this
83 	 * with ShowServices().
84 	 */
85 	void HideServices() noexcept;
86 
87 	/**
88 	 * Undo HideServices().
89 	 */
90 	void ShowServices() noexcept;
91 
92 private:
93 	void GroupCallback(AvahiEntryGroup *g,
94 			   AvahiEntryGroupState state) noexcept;
95 	static void GroupCallback(AvahiEntryGroup *g,
96 				  AvahiEntryGroupState state,
97 				  void *userdata) noexcept;
98 
99 	void RegisterServices(AvahiClient *c) noexcept;
100 
101 	/* virtual methods from class AvahiConnectionListener */
102 	void OnAvahiConnect(AvahiClient *client) noexcept override;
103 	void OnAvahiDisconnect() noexcept override;
104 	void OnAvahiChanged() noexcept override;
105 };
106 
107 } // namespace Avahi
108