5 #include <avahi-client/client.h>
6 #include <avahi-client/lookup.h>
7 #include <avahi-common/simple-watch.h>
9 #include <avahi-common/alternative.h>
10 #include <avahi-common/simple-watch.h>
11 #include <avahi-common/malloc.h>
12 #include <avahi-common/error.h>
13 #include <avahi-common/timeval.h>
17 static void resolve_callback(
18 AvahiServiceResolver
*r
,
19 AVAHI_GCC_UNUSED AvahiIfIndex interface
,
20 AVAHI_GCC_UNUSED AvahiProtocol protocol
,
21 AvahiResolverEvent event
,
25 const char *host_name
,
26 const AvahiAddress
*address
,
29 AvahiLookupResultFlags flags
,
30 AVAHI_GCC_UNUSED
void* userdata
) {
34 /* Called whenever a service has been resolved successfully or timed out */
37 case AVAHI_RESOLVER_FAILURE
:
38 fprintf(stderr
, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name
, type
, domain
, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r
))));
41 case AVAHI_RESOLVER_FOUND
:
42 parse_tender(r
, name
, txt
);
46 avahi_service_resolver_free(r
);
49 static void modify_callback(AvahiTimeout
*e
, void *userdata
) {
50 AvahiClient
*client
= userdata
;
52 /* If the server is currently running, we need to remove our
53 * service and create it anew */
55 if (avahi_client_get_state(client
) != AVAHI_CLIENT_FAILURE
) {
56 /* And create them again with the new name */
59 create_services(client
);
61 avahi_simple_poll_get(simple_poll
)->timeout_update(e
, avahi_elapse_time(&tv
, 1000*POLL
, 0));
65 static void browse_callback(
66 AvahiServiceBrowser
*b
,
67 AvahiIfIndex interface
,
68 AvahiProtocol protocol
,
69 AvahiBrowserEvent event
,
73 AVAHI_GCC_UNUSED AvahiLookupResultFlags flags
,
74 AVAHI_GCC_UNUSED
void* userdata
) {
78 /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
81 case AVAHI_BROWSER_FAILURE
:
83 fprintf(stderr
, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b
))));
84 avahi_service_browser_free(b
);
87 case AVAHI_BROWSER_NEW
: {
88 AvahiClient
*c
= avahi_service_browser_get_client(b
);
89 fprintf(stderr
, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name
, type
, domain
);
91 /* We ignore the returned resolver object. In the callback
92 function we free it. If the server is terminated before
93 the callback function is called the server will free
94 the resolver for us. */
96 if (!(avahi_service_resolver_new(c
, interface
, protocol
, name
, type
, domain
, AVAHI_PROTO_UNSPEC
, 0, resolve_callback
, NULL
)))
97 fprintf(stderr
, "Failed to resolve service '%s': %s\n", name
, avahi_strerror(avahi_client_errno(c
)));
102 case AVAHI_BROWSER_REMOVE
:
104 fprintf(stderr
, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name
, type
, domain
);
107 case AVAHI_BROWSER_ALL_FOR_NOW
:
108 case AVAHI_BROWSER_CACHE_EXHAUSTED
:
109 fprintf(stderr
, "(Browser) %s\n", event
== AVAHI_BROWSER_CACHE_EXHAUSTED
? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
115 void client_callback(AvahiClient
*c
, AvahiClientState state
, AVAHI_GCC_UNUSED
void * userdata
) {
116 /* Called whenever the client or server state changes */
119 case AVAHI_CLIENT_S_RUNNING
: {
120 /* The server has startup successfully and registered its host
121 * name on the network, so it's time to create our services */
124 if (! (offerServiceBrowser
= avahi_service_browser_new(c
, AVAHI_IF_UNSPEC
, AVAHI_PROTO_UNSPEC
, "_offer._tcp", NULL
, 0, browse_callback
, NULL
))) {
125 fprintf(stderr
, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(c
)));
128 /* After 10s do some weird modification to the service */
129 avahi_simple_poll_get(simple_poll
)->timeout_new(
130 avahi_simple_poll_get(simple_poll
),
131 avahi_elapse_time(&tv
, 1000*POLL
, 0),
138 case AVAHI_CLIENT_FAILURE
: {
143 fprintf(stderr
, "Client failure: %s\n", avahi_strerror(avahi_client_errno(c
)));
144 avahi_client_free(c
);
149 /* Allocate a new client */
150 client
= avahi_client_new(avahi_simple_poll_get(simple_poll
), AVAHI_CLIENT_NO_FAIL
, client_callback
, NULL
, &error
);
154 case AVAHI_CLIENT_S_COLLISION
:
155 /* Let's drop our registered services. When the server is back
156 * in AVAHI_SERVER_RUNNING state we will register them
157 * again with the new host name. */
159 case AVAHI_CLIENT_S_REGISTERING
:
160 /* The server records are now being established. This
161 * might be caused by a host name change. We need to wait
162 * for our own records to register until the host name is
163 * properly esatblished. */
166 case AVAHI_CLIENT_CONNECTING
:
171 void entry_group_callback(AvahiEntryGroup
*g
, AvahiEntryGroupState state
, AVAHI_GCC_UNUSED
void *userdata
) {
173 case AVAHI_ENTRY_GROUP_ESTABLISHED
:
174 /* The entry group has been established successfully */
177 case AVAHI_ENTRY_GROUP_COLLISION
: {
178 /* A service name collision with a remote service
183 case AVAHI_ENTRY_GROUP_FAILURE
:
184 /* Some kind of failure happened while we were registering our services */
185 // avahi_simple_poll_quit(simple_poll);
188 case AVAHI_ENTRY_GROUP_UNCOMMITED
:
189 case AVAHI_ENTRY_GROUP_REGISTERING
: