[avahi] [PATCH 1/2] avahi-daemon: extend simple protocol to browse services
Thomas Petazzoni
thomas.petazzoni at free-electrons.com
Fri May 18 06:08:06 PDT 2012
The Avahi simple protocol provides a way of accessing some of the
Avahi services over an Unix socket. Currently used by the nss-mdns
plugin for the glibc name resolution services, it provides a
lightweight and convenient way to access Avahi services.
This patch extends this simple protocol to support service
browsing. It is useful for embedded devices in which D-Bus is not
present and would be a too big addition: this simple protocol
extension extends the avahi-daemon binary size by 740 bytes, which is
several order of magnitudes smaller than adding D-Bus.
The new command added is BROWSE-SERVICE-TYPE, which takes as argument
the service type to browse.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
---
avahi-daemon/simple-protocol.c | 92 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 91 insertions(+), 1 deletion(-)
diff --git a/avahi-daemon/simple-protocol.c b/avahi-daemon/simple-protocol.c
index 3e0ebb1..3efb99a 100644
--- a/avahi-daemon/simple-protocol.c
+++ b/avahi-daemon/simple-protocol.c
@@ -67,6 +67,7 @@ typedef enum {
CLIENT_RESOLVE_HOSTNAME,
CLIENT_RESOLVE_ADDRESS,
CLIENT_BROWSE_DNS_SERVERS,
+ CLIENT_BROWSE_SERVICE_TYPE,
CLIENT_DEAD
} ClientState;
@@ -84,6 +85,7 @@ struct Client {
AvahiSHostNameResolver *host_name_resolver;
AvahiSAddressResolver *address_resolver;
AvahiSDNSServerBrowser *dns_server_browser;
+ AvahiSServiceBrowser *service_browser;
AvahiProtocol afquery;
@@ -119,6 +121,9 @@ static void client_free(Client *c) {
if (c->dns_server_browser)
avahi_s_dns_server_browser_free(c->dns_server_browser);
+ if (c->service_browser)
+ avahi_s_service_browser_free(c->service_browser);
+
c->server->poll_api->watch_free(c->watch);
close(c->fd);
@@ -263,6 +268,87 @@ static void dns_server_browser_callback(
}
}
+static void service_resolver_callback(
+ AVAHI_GCC_UNUSED 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 *a,
+ uint16_t port,
+ AVAHI_GCC_UNUSED AvahiStringList *txt,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ void *userdata)
+{
+ char astr[AVAHI_ADDRESS_STR_MAX];
+ Client *c = userdata;
+
+ assert(c);
+
+ switch(event) {
+ case AVAHI_RESOLVER_FOUND:
+ avahi_address_snprint(astr, sizeof(astr), a);
+ client_output_printf(c, "> %s,%s,%s,%s,%s,%d\n",
+ name, type, domain, host_name, astr, port);
+ break;
+ case AVAHI_RESOLVER_FAILURE:
+ client_output_printf(c, "%+i %s\n", avahi_server_errno(avahi_server), avahi_strerror(avahi_server_errno(avahi_server)));
+ c->state = CLIENT_DEAD;
+ break;
+ }
+
+ avahi_s_service_resolver_free(r);
+}
+
+static void service_browser_callback(
+ AVAHI_GCC_UNUSED AvahiSServiceBrowser *b,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
+ void *userdata) {
+
+ Client *c = userdata;
+ AvahiSServiceResolver *r;
+
+ assert(c);
+
+ switch (event) {
+ case AVAHI_BROWSER_FAILURE:
+ client_output_printf(c, "%+i %s\n", avahi_server_errno(avahi_server), avahi_strerror(avahi_server_errno(avahi_server)));
+ c->state = CLIENT_DEAD;
+ break;
+
+ case AVAHI_BROWSER_ALL_FOR_NOW:
+ client_output_printf(c, "+ End\n");
+ c->state = CLIENT_DEAD;
+ break;
+
+ case AVAHI_BROWSER_CACHE_EXHAUSTED:
+ break;
+
+ case AVAHI_BROWSER_NEW:
+ r = avahi_s_service_resolver_new(avahi_server, interface, protocol, name,
+ type, domain, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_USE_MULTICAST,
+ service_resolver_callback, c);
+ if (! r) {
+ c->state = CLIENT_DEAD;
+ break;
+ }
+
+ break;
+
+ case AVAHI_BROWSER_REMOVE:
+ break;
+ }
+}
+
static void handle_line(Client *c, const char *s) {
char cmd[64], arg[64];
int n_args;
@@ -348,7 +434,11 @@ static void handle_line(Client *c, const char *s) {
client_output_printf(c, "+ Browsing ...\n");
avahi_log_debug(__FILE__": Got %s request.", cmd);
-
+ } else if (strcmp(cmd, "BROWSE-SERVICE-TYPE") == 0 && n_args == 2) {
+ c->state = CLIENT_BROWSE_SERVICE_TYPE;
+ if (!(c->service_browser = avahi_s_service_browser_new(avahi_server, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, arg, NULL, AVAHI_LOOKUP_USE_MULTICAST, service_browser_callback, c)))
+ goto fail;
+ client_output_printf(c, "+ Browsing ...\n");
} else {
client_output_printf(c, "%+i Invalid command \"%s\", try \"HELP\".\n", AVAHI_ERR_INVALID_OPERATION, cmd);
c->state = CLIENT_DEAD;
--
1.7.9.5
More information about the avahi
mailing list