| /* PLEASE NOTE * |
| * This file demonstrates how to use Avahi's core API, this is |
| * the embeddable mDNS stack for embedded applications. |
| * |
| * End user applications should *not* use this API and should use |
| * the D-Bus or C APIs, please see |
| * client-browse-services.c and glib-integration.c |
| * |
| * I repeat, you probably do *not* want to use this example. |
| */ |
| |
| /*** |
| This file is part of avahi. |
| |
| avahi is free software; you can redistribute it and/or modify it |
| under the terms of the GNU Lesser General Public License as |
| published by the Free Software Foundation; either version 2.1 of the |
| License, or (at your option) any later version. |
| |
| avahi is distributed in the hope that it will be useful, but WITHOUT |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
| or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General |
| Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with avahi; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
| USA. |
| ***/ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| #include <stdio.h> |
| #include <assert.h> |
| #include <stdlib.h> |
| #include <time.h> |
| |
| #include <avahi-core/core.h> |
| #include <avahi-core/lookup.h> |
| #include <avahi-common/simple-watch.h> |
| #include <avahi-common/malloc.h> |
| #include <avahi-common/error.h> |
| |
| static AvahiSimplePoll *simple_poll = NULL; |
| static AvahiServer *server = NULL; |
| |
| static void resolve_callback( |
| AvahiSServiceResolver *r, |
| AVAHI_GCC_UNUSED AvahiIfIndex interface, |
| AVAHI_GCC_UNUSED AvahiProtocol protocol, |
| AvahiResolverEvent event, |
| const char *name, |
| const char *type, |
| const char *domain, |
| const char *host_name, |
| const AvahiAddress *address, |
| uint16_t port, |
| AvahiStringList *txt, |
| AvahiLookupResultFlags flags, |
| AVAHI_GCC_UNUSED void* userdata) { |
| |
| assert(r); |
| |
| /* Called whenever a service has been resolved successfully or timed out */ |
| |
| switch (event) { |
| case AVAHI_RESOLVER_FAILURE: |
| 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))); |
| break; |
| |
| case AVAHI_RESOLVER_FOUND: { |
| char a[AVAHI_ADDRESS_STR_MAX], *t; |
| |
| fprintf(stderr, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain); |
| |
| avahi_address_snprint(a, sizeof(a), address); |
| t = avahi_string_list_to_string(txt); |
| fprintf(stderr, |
| "\t%s:%u (%s)\n" |
| "\tTXT=%s\n" |
| "\tcookie is %u\n" |
| "\tis_local: %i\n" |
| "\twide_area: %i\n" |
| "\tmulticast: %i\n" |
| "\tcached: %i\n", |
| host_name, port, a, |
| t, |
| avahi_string_list_get_service_cookie(txt), |
| !!(flags & AVAHI_LOOKUP_RESULT_LOCAL), |
| !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA), |
| !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST), |
| !!(flags & AVAHI_LOOKUP_RESULT_CACHED)); |
| avahi_free(t); |
| } |
| } |
| |
| avahi_s_service_resolver_free(r); |
| } |
| |
| static void browse_callback( |
| AvahiSServiceBrowser *b, |
| AvahiIfIndex interface, |
| AvahiProtocol protocol, |
| AvahiBrowserEvent event, |
| const char *name, |
| const char *type, |
| const char *domain, |
| AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, |
| void* userdata) { |
| |
| AvahiServer *s = userdata; |
| assert(b); |
| |
| /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ |
| |
| switch (event) { |
| |
| case AVAHI_BROWSER_FAILURE: |
| |
| fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_server_errno(server))); |
| avahi_simple_poll_quit(simple_poll); |
| return; |
| |
| case AVAHI_BROWSER_NEW: |
| fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); |
| |
| /* We ignore the returned resolver object. In the callback |
| function we free it. If the server is terminated before |
| the callback function is called the server will free |
| the resolver for us. */ |
| |
| if (!(avahi_s_service_resolver_new(s, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, s))) |
| fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_server_errno(s))); |
| |
| break; |
| |
| case AVAHI_BROWSER_REMOVE: |
| fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain); |
| break; |
| |
| case AVAHI_BROWSER_ALL_FOR_NOW: |
| case AVAHI_BROWSER_CACHE_EXHAUSTED: |
| fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); |
| break; |
| } |
| } |
| |
| int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) { |
| AvahiServerConfig config; |
| AvahiSServiceBrowser *sb = NULL; |
| int error; |
| int ret = 1; |
| |
| /* Initialize the psuedo-RNG */ |
| srand(time(NULL)); |
| |
| /* Allocate main loop object */ |
| if (!(simple_poll = avahi_simple_poll_new())) { |
| fprintf(stderr, "Failed to create simple poll object.\n"); |
| goto fail; |
| } |
| |
| /* Do not publish any local records */ |
| avahi_server_config_init(&config); |
| config.publish_hinfo = 0; |
| config.publish_addresses = 0; |
| config.publish_workstation = 0; |
| config.publish_domain = 0; |
| |
| /* Set a unicast DNS server for wide area DNS-SD */ |
| avahi_address_parse("192.168.50.1", AVAHI_PROTO_UNSPEC, &config.wide_area_servers[0]); |
| config.n_wide_area_servers = 1; |
| config.enable_wide_area = 1; |
| |
| /* Allocate a new server */ |
| server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, NULL, NULL, &error); |
| |
| /* Free the configuration data */ |
| avahi_server_config_free(&config); |
| |
| /* Check wether creating the server object succeeded */ |
| if (!server) { |
| fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error)); |
| goto fail; |
| } |
| |
| /* Create the service browser */ |
| if (!(sb = avahi_s_service_browser_new(server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_http._tcp", NULL, 0, browse_callback, server))) { |
| fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_server_errno(server))); |
| goto fail; |
| } |
| |
| /* Run the main loop */ |
| avahi_simple_poll_loop(simple_poll); |
| |
| ret = 0; |
| |
| fail: |
| |
| /* Cleanup things */ |
| if (sb) |
| avahi_s_service_browser_free(sb); |
| |
| if (server) |
| avahi_server_free(server); |
| |
| if (simple_poll) |
| avahi_simple_poll_free(simple_poll); |
| |
| return ret; |
| } |