Commit bb5c27c1 authored by Fawzi Mohamed's avatar Fawzi Mohamed
Browse files

zeroconf: native avahi, and working fallbacks



* supports avahi through its native interface
* starts embedded deamon if found
* tested all fallbacks on ubuntu
* Service is a normal object now
* several smaller improvements
Change-Id: I36288ec6fcefb64a60b6284e4d86d4b589ba37b5
Reviewed-by: default avatarChristian Kandeler <christian.kandeler@nokia.com>
parent a0e0a125
#ifndef fooclienthfoo
#define fooclienthfoo
/***
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.
***/
#include <inttypes.h>
#include <avahi-common/cdecl.h>
#include <avahi-common/address.h>
#include <avahi-common/strlst.h>
#include <avahi-common/defs.h>
#include <avahi-common/watch.h>
#include <avahi-common/gccmacro.h>
/** \file client.h Definitions and functions for the client API over D-Bus */
AVAHI_C_DECL_BEGIN
/** A connection context */
typedef struct AvahiClient AvahiClient;
/** States of a client object, a superset of AvahiServerState */
typedef enum {
AVAHI_CLIENT_S_REGISTERING = AVAHI_SERVER_REGISTERING, /**< Server state: REGISTERING */
AVAHI_CLIENT_S_RUNNING = AVAHI_SERVER_RUNNING, /**< Server state: RUNNING */
AVAHI_CLIENT_S_COLLISION = AVAHI_SERVER_COLLISION, /**< Server state: COLLISION */
AVAHI_CLIENT_FAILURE = 100, /**< Some kind of error happened on the client side */
AVAHI_CLIENT_CONNECTING = 101 /**< We're still connecting. This state is only entered when AVAHI_CLIENT_NO_FAIL has been passed to avahi_client_new() and the daemon is not yet available. */
} AvahiClientState;
typedef enum {
AVAHI_CLIENT_IGNORE_USER_CONFIG = 1, /**< Don't read user configuration */
AVAHI_CLIENT_NO_FAIL = 2 /**< Don't fail if the daemon is not available when avahi_client_new() is called, instead enter AVAHI_CLIENT_CONNECTING state and wait for the daemon to appear */
} AvahiClientFlags;
/** The function prototype for the callback of an AvahiClient */
typedef void (*AvahiClientCallback) (
AvahiClient *s,
AvahiClientState state /**< The new state of the client */,
void* userdata /**< The user data that was passed to avahi_client_new() */);
/** @{ \name Construction and destruction */
/** Creates a new client instance */
AvahiClient* avahi_client_new (
const AvahiPoll *poll_api /**< The abstract event loop API to use */,
AvahiClientFlags flags /**< Some flags to modify the behaviour of the client library */,
AvahiClientCallback callback /**< A callback that is called whenever the state of the client changes. This may be NULL. Please note that this function is called for the first time from within the avahi_client_new() context! Thus, in the callback you should not make use of global variables that are initialized only after your call to avahi_client_new(). A common mistake is to store the AvahiClient pointer returned by avahi_client_new() in a global variable and assume that this global variable already contains the valid pointer when the callback is called for the first time. A work-around for this is to always use the AvahiClient pointer passed to the callback function instead of the global pointer. */,
void *userdata /**< Some arbitrary user data pointer that will be passed to the callback function */,
int *error /**< If creation of the client fails, this integer will contain the error cause. May be NULL if you aren't interested in the reason why avahi_client_new() failed. */);
/** Free a client instance. This will automatically free all
* associated browser, resolve and entry group objects. All pointers
* to such objects become invalid! */
void avahi_client_free(AvahiClient *client);
/** @} */
/** @{ \name Properties */
/** Get the version of the server */
const char* avahi_client_get_version_string (AvahiClient*);
/** Get host name */
const char* avahi_client_get_host_name (AvahiClient*);
/** Set host name. \since 0.6.13 */
int avahi_client_set_host_name(AvahiClient*, const char *name);
/** Get domain name */
const char* avahi_client_get_domain_name (AvahiClient*);
/** Get FQDN domain name */
const char* avahi_client_get_host_name_fqdn (AvahiClient*);
/** Get state */
AvahiClientState avahi_client_get_state(AvahiClient *client);
/** @{ \name Error Handling */
/** Get the last error number. See avahi_strerror() for converting this error code into a human readable string. */
int avahi_client_errno (AvahiClient*);
/** @} */
/** \cond fulldocs */
/** Return the local service cookie. returns AVAHI_SERVICE_COOKIE_INVALID on failure. */
uint32_t avahi_client_get_local_service_cookie(AvahiClient *client);
/** \endcond */
/** @{ \name Libc NSS Support */
/** Return 1 if gethostbyname() supports mDNS lookups, 0 otherwise. \since 0.6.5 */
int avahi_nss_support(void);
/** @} */
AVAHI_C_DECL_END
#endif
#ifndef fooclientlookuphfoo
#define fooclientlookuphfoo
/***
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.
***/
#include <inttypes.h>
#include <avahi-common/cdecl.h>
#include <avahi-common/address.h>
#include <avahi-common/strlst.h>
#include <avahi-common/defs.h>
#include <avahi-common/watch.h>
#include <avahi-common/gccmacro.h>
#include <avahi-client/client.h>
/** \file avahi-client/lookup.h Lookup Client API */
/** \example client-browse-services.c Example how to browse for DNS-SD
* services using the client interface to avahi-daemon. */
AVAHI_C_DECL_BEGIN
/** @{ \name Domain Browser */
/** A domain browser object */
typedef struct AvahiDomainBrowser AvahiDomainBrowser;
/** The function prototype for the callback of an AvahiDomainBrowser */
typedef void (*AvahiDomainBrowserCallback) (
AvahiDomainBrowser *b,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiBrowserEvent event,
const char *domain,
AvahiLookupResultFlags flags,
void *userdata);
/** Browse for domains on the local network */
AvahiDomainBrowser* avahi_domain_browser_new (
AvahiClient *client,
AvahiIfIndex interface,
AvahiProtocol protocol,
const char *domain,
AvahiDomainBrowserType btype,
AvahiLookupFlags flags,
AvahiDomainBrowserCallback callback,
void *userdata);
/** Get the parent client of an AvahiDomainBrowser object */
AvahiClient* avahi_domain_browser_get_client (AvahiDomainBrowser *);
/** Cleans up and frees an AvahiDomainBrowser object */
int avahi_domain_browser_free (AvahiDomainBrowser *);
/** @} */
/** @{ \name Service Browser */
/** A service browser object */
typedef struct AvahiServiceBrowser AvahiServiceBrowser;
/** The function prototype for the callback of an AvahiServiceBrowser */
typedef void (*AvahiServiceBrowserCallback) (
AvahiServiceBrowser *b,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiBrowserEvent event,
const char *name,
const char *type,
const char *domain,
AvahiLookupResultFlags flags,
void *userdata);
/** Browse for services of a type on the network. In most cases you
* probably want to pass AVAHI_IF_UNSPEC and AVAHI_PROTO_UNSPED in
* interface, resp. protocol to browse on all local networks. The
* specified callback will be called whenever a new service appears
* or is removed from the network. Please note that events may be
* collapsed to minimize traffic (i.e. a REMOVED followed by a NEW for
* the same service data is dropped because redundant). If you want to
* subscribe to service data changes, you should use
* avahi_service_resolver_new() and keep it open, in which case you
* will be notified via AVAHI_RESOLVE_FOUND everytime the service data
* changes. */
AvahiServiceBrowser* avahi_service_browser_new (
AvahiClient *client,
AvahiIfIndex interface, /**< In most cases pass AVAHI_IF_UNSPEC here */
AvahiProtocol protocol, /**< In most cases pass AVAHI_PROTO_UNSPEC here */
const char *type, /**< A service type such as "_http._tcp" */
const char *domain, /**< A domain to browse in. In most cases you want to pass NULL here for the default domain (usually ".local") */
AvahiLookupFlags flags,
AvahiServiceBrowserCallback callback,
void *userdata);
/** Get the parent client of an AvahiServiceBrowser object */
AvahiClient* avahi_service_browser_get_client (AvahiServiceBrowser *);
/** Cleans up and frees an AvahiServiceBrowser object */
int avahi_service_browser_free (AvahiServiceBrowser *);
/** @} */
/** \cond fulldocs */
/** A service type browser object */
typedef struct AvahiServiceTypeBrowser AvahiServiceTypeBrowser;
/** The function prototype for the callback of an AvahiServiceTypeBrowser */
typedef void (*AvahiServiceTypeBrowserCallback) (
AvahiServiceTypeBrowser *b,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiBrowserEvent event,
const char *type,
const char *domain,
AvahiLookupResultFlags flags,
void *userdata);
/** Browse for service types on the local network */
AvahiServiceTypeBrowser* avahi_service_type_browser_new (
AvahiClient *client,
AvahiIfIndex interface,
AvahiProtocol protocol,
const char *domain,
AvahiLookupFlags flags,
AvahiServiceTypeBrowserCallback callback,
void *userdata);
/** Get the parent client of an AvahiServiceTypeBrowser object */
AvahiClient* avahi_service_type_browser_get_client (AvahiServiceTypeBrowser *);
/** Cleans up and frees an AvahiServiceTypeBrowser object */
int avahi_service_type_browser_free (AvahiServiceTypeBrowser *);
/** \endcond */
/** @{ \name Service Resolver */
/** A service resolver object */
typedef struct AvahiServiceResolver AvahiServiceResolver;
/** The function prototype for the callback of an AvahiServiceResolver */
typedef void (*AvahiServiceResolverCallback) (
AvahiServiceResolver *r,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiResolverEvent event,
const char *name,
const char *type,
const char *domain,
const char *host_name,
const AvahiAddress *a,
uint16_t port,
AvahiStringList *txt,
AvahiLookupResultFlags flags,
void *userdata);
/** Create a new service resolver object. Please make sure to pass all
* the service data you received via avahi_service_browser_new()'s
* callback function, especially interface and protocol. The protocol
* argument specifies the protocol (IPv4 or IPv6) to use as transport
* for the queries which are sent out by this resolver. The
* aprotocol argument specifies the adress family (IPv4 or IPv6) of
* the address of the service we are looking for. Generally, on
* "protocol" you should only pass what was supplied to you as
* parameter to your AvahiServiceBrowserCallback. In "aprotocol" you
* should pass what your application code can deal with when
* connecting to the service. Or, more technically speaking: protocol
* specifies if the mDNS queries should be sent as UDP/IPv4
* resp. UDP/IPv6 packets. aprotocol specifies whether the query is for a A
* resp. AAAA resource record. */
AvahiServiceResolver * avahi_service_resolver_new(
AvahiClient *client,
AvahiIfIndex interface, /**< Pass the interface argument you received in AvahiServiceBrowserCallback here. */
AvahiProtocol protocol, /**< Pass the protocol argument you received in AvahiServiceBrowserCallback here. */
const char *name, /**< Pass the name argument you received in AvahiServiceBrowserCallback here. */
const char *type, /**< Pass the type argument you received in AvahiServiceBrowserCallback here. */
const char *domain, /**< Pass the domain argument you received in AvahiServiceBrowserCallback here. */
AvahiProtocol aprotocol, /**< The desired address family of the service address to resolve. AVAHI_PROTO_UNSPEC if your application can deal with both IPv4 and IPv6 */
AvahiLookupFlags flags,
AvahiServiceResolverCallback callback,
void *userdata);
/** Get the parent client of an AvahiServiceResolver object */
AvahiClient* avahi_service_resolver_get_client (AvahiServiceResolver *);
/** Free a service resolver object */
int avahi_service_resolver_free(AvahiServiceResolver *r);
/** @} */
/** \cond fulldocs */
/** A service resolver object */
typedef struct AvahiHostNameResolver AvahiHostNameResolver;
/** The function prototype for the callback of an AvahiHostNameResolver */
typedef void (*AvahiHostNameResolverCallback) (
AvahiHostNameResolver *r,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiResolverEvent event,
const char *name,
const AvahiAddress *a,
AvahiLookupResultFlags flags,
void *userdata);
/** Create a new hostname resolver object */
AvahiHostNameResolver * avahi_host_name_resolver_new(
AvahiClient *client,
AvahiIfIndex interface,
AvahiProtocol protocol,
const char *name,
AvahiProtocol aprotocol,
AvahiLookupFlags flags,
AvahiHostNameResolverCallback callback,
void *userdata);
/** Get the parent client of an AvahiHostNameResolver object */
AvahiClient* avahi_host_name_resolver_get_client (AvahiHostNameResolver *);
/** Free a hostname resolver object */
int avahi_host_name_resolver_free(AvahiHostNameResolver *r);
/** An address resolver object */
typedef struct AvahiAddressResolver AvahiAddressResolver;
/** The function prototype for the callback of an AvahiAddressResolver */
typedef void (*AvahiAddressResolverCallback) (
AvahiAddressResolver *r,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiResolverEvent event,
const AvahiAddress *a,
const char *name,
AvahiLookupResultFlags flags,
void *userdata);
/** Create a new address resolver object from an AvahiAddress object */
AvahiAddressResolver* avahi_address_resolver_new(
AvahiClient *client,
AvahiIfIndex interface,
AvahiProtocol protocol,
const AvahiAddress *a,
AvahiLookupFlags flags,
AvahiAddressResolverCallback callback,
void *userdata);
/** Get the parent client of an AvahiAddressResolver object */
AvahiClient* avahi_address_resolver_get_client (AvahiAddressResolver *);
/** Free a AvahiAddressResolver resolver object */
int avahi_address_resolver_free(AvahiAddressResolver *r);
/** \endcond */
/** @{ \name Record Browser */
/** A record browser object */
typedef struct AvahiRecordBrowser AvahiRecordBrowser;
/** The function prototype for the callback of an AvahiRecordBrowser */
typedef void (*AvahiRecordBrowserCallback) (
AvahiRecordBrowser *b,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiBrowserEvent event,
const char *name,
uint16_t clazz,
uint16_t type,
const void *rdata,
size_t size,
AvahiLookupResultFlags flags,
void *userdata);
/** Browse for records of a type on the local network */
AvahiRecordBrowser* avahi_record_browser_new(
AvahiClient *client,
AvahiIfIndex interface,
AvahiProtocol protocol,
const char *name,
uint16_t clazz,
uint16_t type,
AvahiLookupFlags flags,
AvahiRecordBrowserCallback callback,
void *userdata);
/** Get the parent client of an AvahiRecordBrowser object */
AvahiClient* avahi_record_browser_get_client(AvahiRecordBrowser *);
/** Cleans up and frees an AvahiRecordBrowser object */
int avahi_record_browser_free(AvahiRecordBrowser *);
/** @} */
AVAHI_C_DECL_END
#endif
#ifndef fooaddresshfoo
#define fooaddresshfoo
/***
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.
***/
/** \file address.h Definitions and functions to manipulate IP addresses. */
#include <inttypes.h>
#include <sys/types.h>
#include <avahi-common/cdecl.h>
AVAHI_C_DECL_BEGIN
/** Protocol family specification, takes the values AVAHI_PROTO_INET, AVAHI_PROTO_INET6, AVAHI_PROTO_UNSPEC */
typedef int AvahiProtocol;
/** Numeric network interface index. Takes OS dependent values and the special constant AVAHI_IF_UNSPEC */
typedef int AvahiIfIndex;
/** Values for AvahiProtocol */
enum {
AVAHI_PROTO_INET = 0, /**< IPv4 */
AVAHI_PROTO_INET6 = 1, /**< IPv6 */
AVAHI_PROTO_UNSPEC = -1 /**< Unspecified/all protocol(s) */
};
/** Special values for AvahiIfIndex */
enum {
AVAHI_IF_UNSPEC = -1 /**< Unspecified/all interface(s) */
};
/** Maximum size of an address in string form */
#define AVAHI_ADDRESS_STR_MAX 40 /* IPv6 Max = 4*8 + 7 + 1 for NUL */
/** Return TRUE if the specified interface index is valid */
#define AVAHI_IF_VALID(ifindex) (((ifindex) >= 0) || ((ifindex) == AVAHI_IF_UNSPEC))
/** Return TRUE if the specified protocol is valid */
#define AVAHI_PROTO_VALID(protocol) (((protocol) == AVAHI_PROTO_INET) || ((protocol) == AVAHI_PROTO_INET6) || ((protocol) == AVAHI_PROTO_UNSPEC))
/** An IPv4 address */
typedef struct AvahiIPv4Address {
uint32_t address; /**< Address data in network byte order. */
} AvahiIPv4Address;
/** An IPv6 address */
typedef struct AvahiIPv6Address {
uint8_t address[16]; /**< Address data */
} AvahiIPv6Address;
/** Protocol (address family) independent address structure */
typedef struct AvahiAddress {
AvahiProtocol proto; /**< Address family */
union {
AvahiIPv6Address ipv6; /**< Address when IPv6 */
AvahiIPv4Address ipv4; /**< Address when IPv4 */
uint8_t data[1]; /**< Type-independent data field */
} data;
} AvahiAddress;
/** @{ \name Comparison */
/** Compare two addresses. Returns 0 when equal, a negative value when a < b, a positive value when a > b. */
int avahi_address_cmp(const AvahiAddress *a, const AvahiAddress *b);
/** @} */
/** @{ \name String conversion */
/** Convert the specified address *a to a human readable character string, use AVAHI_ADDRESS_STR_MAX to allocate an array of the right size */
char *avahi_address_snprint(char *ret_s, size_t length, const AvahiAddress *a);
/** Convert the specified human readable character string to an
* address structure. Set af to AVAHI_UNSPEC for automatic address
* family detection. */
AvahiAddress *avahi_address_parse(const char *s, AvahiProtocol af, AvahiAddress *ret_addr);
/** @} */
/** \cond fulldocs */
/** Generate the DNS reverse lookup name for an IPv4 or IPv6 address. */
char* avahi_reverse_lookup_name(const AvahiAddress *a, char *ret_s, size_t length);
/** \endcond */
/** @{ \name Protocol/address family handling */
/** Map AVAHI_PROTO_xxx constants to Unix AF_xxx constants */
int avahi_proto_to_af(AvahiProtocol proto);
/** Map Unix AF_xxx constants to AVAHI_PROTO_xxx constants */
AvahiProtocol avahi_af_to_proto(int af);
/** Return a textual representation of the specified protocol number. i.e. "IPv4", "IPv6" or "UNSPEC" */
const char* avahi_proto_to_string(AvahiProtocol proto);
/** @} */
AVAHI_C_DECL_END
#endif
#ifndef foocdeclhfoo
#define foocdeclhfoo
/***
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.
***/
/** \file cdecl.h C++ compatibility */
#ifdef __cplusplus
/** If using C++ this macro enables C mode, otherwise does nothing */
#define AVAHI_C_DECL_BEGIN extern "C" {
/** If using C++ this macro switches back to C++ mode, otherwise does nothing */
#define AVAHI_C_DECL_END }
#else
/** If using C++ this macro enables C mode, otherwise does nothing */
#define AVAHI_C_DECL_BEGIN
/** If using C++ this macro switches back to C++ mode, otherwise does nothing */
#define AVAHI_C_DECL_END
#endif
#endif
</
#ifndef foodefshfoo
#define foodefshfoo
/***
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.
***/