]> git.meshlink.io Git - catta/blob - examples/core-browse-services.c
* remove AVAHI_PUBLISH_IS_PROXY, it was a bad idea
[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_FAILURE:
72             fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_server_errno(server)));
73             break;
74
75         case AVAHI_RESOLVER_FOUND: {
76             char a[AVAHI_ADDRESS_STR_MAX], *t;
77             
78             fprintf(stderr, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
79             
80             avahi_address_snprint(a, sizeof(a), address);
81             t = avahi_string_list_to_string(txt);
82             fprintf(stderr,
83                     "\t%s:%u (%s)\n"
84                     "\tTXT=%s\n"
85                     "\tcookie is %u\n"
86                     "\tis_local: %i\n"
87                     "\twide_area: %i\n"
88                     "\tmulticast: %i\n"
89                     "\tcached: %i\n",
90                     host_name, port, a,
91                     t,
92                     avahi_string_list_get_service_cookie(txt),
93                     !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
94                     !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
95                     !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
96                     !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
97             avahi_free(t);
98         }
99     }
100     
101     avahi_s_service_resolver_free(r);
102 }
103
104 static void browse_callback(
105     AvahiSServiceBrowser *b,
106     AvahiIfIndex interface,
107     AvahiProtocol protocol,
108     AvahiBrowserEvent event,
109     const char *name,
110     const char *type,
111     const char *domain,
112     AvahiLookupResultFlags flags,
113     void* userdata) {
114     
115     AvahiServer *s = userdata;
116     assert(b);
117
118     /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
119
120     switch (event) {
121
122         case AVAHI_BROWSER_FAILURE:
123             
124             fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_server_errno(server)));
125             avahi_simple_poll_quit(simple_poll);
126             return;
127
128         case AVAHI_BROWSER_NEW:
129             fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
130
131             /* We ignore the returned resolver object. In the callback
132                function we free it. If the server is terminated before
133                the callback function is called the server will free
134                the resolver for us. */
135             
136             if (!(avahi_s_service_resolver_new(s, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, s)))
137                 fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(s)));
138             
139             break;
140
141         case AVAHI_BROWSER_REMOVE:
142             fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
143             break;
144
145         case AVAHI_BROWSER_ALL_FOR_NOW:
146         case AVAHI_BROWSER_CACHE_EXHAUSTED:
147             fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
148             break;
149     }
150 }
151
152 int main(int argc, char*argv[]) {
153     AvahiServerConfig config;
154     AvahiSServiceBrowser *sb = NULL;
155     int error;
156     int ret = 1;
157
158     /* Initialize the psuedo-RNG */
159     srand(time(NULL));
160
161     /* Allocate main loop object */
162     if (!(simple_poll = avahi_simple_poll_new())) {
163         fprintf(stderr, "Failed to create simple poll object.\n");
164         goto fail;
165     }
166
167     /* Do not publish any local records */
168     avahi_server_config_init(&config);
169     config.publish_hinfo = 0;
170     config.publish_addresses = 0;
171     config.publish_workstation = 0;
172     config.publish_domain = 0;
173
174     /* Set a unicast DNS server for wide area DNS-SD */
175     avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &config.wide_area_servers[0]);
176     config.n_wide_area_servers = 1;
177     config.enable_wide_area = 1;
178     
179     /* Allocate a new server */
180     server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, NULL, NULL, &error);
181
182     /* Free the configuration data */
183     avahi_server_config_free(&config);
184
185     /* Check wether creating the server object succeeded */
186     if (!server) {
187         fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error));
188         goto fail;
189     }
190     
191     /* Create the service browser */
192     if (!(sb = avahi_s_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, server))) {
193         fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_server_errno(server)));
194         goto fail;
195     }
196     
197     /* Run the main loop */
198     avahi_simple_poll_loop(simple_poll);
199     
200     ret = 0;
201     
202 fail:
203     
204     /* Cleanup things */
205     if (sb)
206         avahi_s_service_browser_free(sb);
207     
208     if (server)
209         avahi_server_free(server);
210
211     if (simple_poll)
212         avahi_simple_poll_free(simple_poll);
213
214     return ret;
215 }