]> git.meshlink.io Git - catta/blob - examples/core-browse-services.c
update examples to reflect recent API changes (wide area)
[catta] / examples / core-browse-services.c
1 /* $Id$ */
2
3 /* PLEASE NOTE *
4  * This file demonstrates how to use Avahi's core API, this is
5  * the embeddable mDNS stack for embedded applications.
6  *
7  * End user applications should *not* use this API and should use
8  * the DBUS or C APIs, please see
9  * client-browse-services.c and glib-integration.c
10  * 
11  * I repeat, you probably do *not* want to use this example.
12  */
13
14 /***
15   This file is part of avahi.
16  
17   avahi is free software; you can redistribute it and/or modify it
18   under the terms of the GNU Lesser General Public License as
19   published by the Free Software Foundation; either version 2.1 of the
20   License, or (at your option) any later version.
21  
22   avahi is distributed in the hope that it will be useful, but WITHOUT
23   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
25   Public License for more details.
26  
27   You should have received a copy of the GNU Lesser General Public
28   License along with avahi; if not, write to the Free Software
29   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30   USA.
31 ***/
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include <stdio.h>
38 #include <assert.h>
39 #include <stdlib.h>
40 #include <time.h>
41
42 #include <avahi-core/core.h>
43 #include <avahi-core/lookup.h>
44 #include <avahi-common/simple-watch.h>
45 #include <avahi-common/malloc.h>
46 #include <avahi-common/error.h>
47
48 static AvahiSimplePoll *simple_poll = NULL;
49 static AvahiServer *server = NULL;
50
51 static void resolve_callback(
52     AvahiSServiceResolver *r,
53     AvahiIfIndex interface,
54     AvahiProtocol protocol,
55     AvahiResolverEvent event,
56     const char *name,
57     const char *type,
58     const char *domain,
59     const char *host_name,
60     const AvahiAddress *address,
61     uint16_t port,
62     AvahiStringList *txt,
63     AvahiLookupResultFlags flags,
64     void* userdata) {
65     
66     assert(r);
67
68     /* Called whenever a service has been resolved successfully or timed out */
69
70     switch (event) {
71         case AVAHI_RESOLVER_TIMEOUT:
72         case AVAHI_RESOLVER_NOT_FOUND:
73         case AVAHI_RESOLVER_FAILURE:
74             fprintf(stderr, "Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain,
75                     event == AVAHI_RESOLVER_TIMEOUT ? "TIMEOUT" : (event == AVAHI_RESOLVER_NOT_FOUND ? "NOT_FOUND" : "FAILURE"));
76
77         case AVAHI_RESOLVER_FOUND: {
78             char a[128], *t;
79             
80             fprintf(stderr, "Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
81             
82             avahi_address_snprint(a, sizeof(a), address);
83             t = avahi_string_list_to_string(txt);
84             fprintf(stderr,
85                     "\t%s:%u (%s)\n"
86                     "\tTXT=%s\n"
87                     "\tcookie is %u\n"
88                     "\tis_local: %i\n"
89                     "\twide_area: %i\n"
90                     "\tmulticast: %i\n"
91                     "\tcached: %i\n",
92                     host_name, port, a,
93                     t,
94                     avahi_string_list_get_service_cookie(txt),
95                     avahi_server_is_service_local(server, interface, protocol, name, type, domain),
96                     !!(flags & AVAHI_LOOKUP_CALLBACK_WIDE_AREA),
97                     !!(flags & AVAHI_LOOKUP_CALLBACK_MULTICAST),
98                     !!(flags & AVAHI_LOOKUP_CALLBACK_CACHED));
99             avahi_free(t);
100         }
101     }
102     
103     avahi_s_service_resolver_free(r);
104 }
105
106 static void browse_callback(
107     AvahiSServiceBrowser *b,
108     AvahiIfIndex interface,
109     AvahiProtocol protocol,
110     AvahiBrowserEvent event,
111     const char *name,
112     const char *type,
113     const char *domain,
114     AvahiLookupResultFlags flags,
115     void* userdata) {
116     
117     AvahiServer *s = userdata;
118     assert(b);
119
120     /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
121
122     switch (event) {
123
124         case AVAHI_BROWSER_FAILURE:
125         case AVAHI_BROWSER_NOT_FOUND:
126             
127             fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_FAILURE ? "FAILURE" : "NOT_FOUND");
128             avahi_simple_poll_quit(simple_poll);
129             return;
130
131         case AVAHI_BROWSER_NEW:
132             fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
133
134             /* We ignore the returned resolver object. In the callback
135                function we free it. If the server is terminated before
136                the callback function is called the server will free
137                the resolver for us. */
138             
139             if (!(avahi_s_service_resolver_new(s, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, s)))
140                 fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(s)));
141             
142             break;
143
144         case AVAHI_BROWSER_REMOVE:
145             fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
146             break;
147
148         case AVAHI_BROWSER_ALL_FOR_NOW:
149         case AVAHI_BROWSER_CACHE_EXHAUSTED:
150             fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
151             break;
152     }
153 }
154
155 int main(int argc, char*argv[]) {
156     AvahiServerConfig config;
157     AvahiSServiceBrowser *sb;
158     int error;
159     int ret = 1;
160
161     /* Initialize the psuedo-RNG */
162     srand(time(NULL));
163
164     /* Allocate main loop object */
165     if (!(simple_poll = avahi_simple_poll_new())) {
166         fprintf(stderr, "Failed to create simple poll object.\n");
167         goto fail;
168     }
169
170     /* Do not publish any local records */
171     avahi_server_config_init(&config);
172     config.publish_hinfo = 0;
173     config.publish_addresses = 0;
174     config.publish_workstation = 0;
175     config.publish_domain = 0;
176
177     /* Set a unicast DNS server for wide area DNS-SD */
178     avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &config.wide_area_servers[0]);
179     config.n_wide_area_servers = 1;
180     config.enable_wide_area = 1;
181     
182     /* Allocate a new server */
183     server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, NULL, NULL, &error);
184
185     /* Free the configuration data */
186     avahi_server_config_free(&config);
187
188     /* Check wether creating the server object succeeded */
189     if (!server) {
190         fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error));
191         goto fail;
192     }
193     
194     /* Create the service browser */
195     if (!(sb = avahi_s_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, server))) {
196         fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_server_errno(server)));
197         goto fail;
198     }
199     
200     /* Run the main loop */
201     for (;;)
202         if (avahi_simple_poll_iterate(simple_poll, -1) != 0)
203             break;
204     
205     ret = 0;
206     
207 fail:
208     
209     /* Cleanup things */
210     if (sb)
211         avahi_s_service_browser_free(sb);
212     
213     if (server)
214         avahi_server_free(server);
215
216     if (simple_poll)
217         avahi_simple_poll_free(simple_poll);
218
219     return ret;
220 }