diff options
Diffstat (limited to 'backend/epsonds-net.c')
| -rw-r--r-- | backend/epsonds-net.c | 234 | 
1 files changed, 234 insertions, 0 deletions
| diff --git a/backend/epsonds-net.c b/backend/epsonds-net.c index 3c8be29..4f4c1e2 100644 --- a/backend/epsonds-net.c +++ b/backend/epsonds-net.c @@ -32,10 +32,19 @@  #include "sane/sanei_debug.h" +  static ssize_t  epsonds_net_read_raw(epsonds_scanner *s, unsigned char *buf, ssize_t wanted,  		       SANE_Status *status)  { +	DBG(15, "%s: wanted: %ld\n", __func__, wanted); + +	if (wanted == 0) +	{ +	    *status = SANE_STATUS_GOOD; +		return 0; +	} +  	int ready;  	ssize_t read = -1;  	fd_set readable; @@ -284,3 +293,228 @@ epsonds_net_unlock(struct epsonds_scanner *s)  /*	epsonds_net_read(s, buf, 1, &status); */  	return status;  } +#if WITH_AVAHI + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <avahi-client/lookup.h> +#include <avahi-common/error.h> +#include <avahi-common/simple-watch.h> +#include <sys/time.h> +#include <errno.h> + +static AvahiSimplePoll *simple_poll = NULL; + +static struct timeval borowseEndTime; + +static int resolvedCount = 0; +static int browsedCount = 0; +static int waitResolver = 0; + +typedef struct { +    AvahiClient* client; +    Device_Found_CallBack callBack; +}EDSAvahiUserData; + +static int my_avahi_simple_poll_loop(AvahiSimplePoll *s) { +    struct timeval currentTime; + +    for (;;) +    { +         int r = avahi_simple_poll_iterate(s, 1); +		if (r != 0) +		{ +			if (r >= 0 || errno != EINTR) +			{ +					DBG(10, "my_avahi_simple_poll_loop end\n"); +					return r; +			} +		} + +		if (waitResolver) { +			gettimeofday(¤tTime, NULL); + +			if ((currentTime.tv_sec - borowseEndTime.tv_sec) >= 3) +			{ +				avahi_simple_poll_quit(simple_poll); +				DBG(10, "resolve timeout\n"); +				return 0; +			} +		} +    } +} + +static void +epsonds_resolve_callback(AvahiServiceResolver *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, +                            void  *userdata) +{ +	// unused parameter +	(void)r; +	(void)type; +	(void)domain; +	(void)host_name; +	(void)port; +	(void)flags; +    EDSAvahiUserData* data = userdata; +    char ipAddr[AVAHI_ADDRESS_STR_MAX]; + +	DBG(10, "epsonds_searchDevices resolve_callback\n"); + + +    resolvedCount++; + +    switch (event) { +    case AVAHI_RESOLVER_FAILURE: +        break; +    case AVAHI_RESOLVER_FOUND: +        avahi_address_snprint(ipAddr, sizeof(ipAddr), address); +	   DBG(10, "epsonds_searchDevices name = %s \n", name); +        if (strlen(name) > 7) +        { +            if (strncmp(name, "EPSON", 5) == 0) +            { +				while(txt != NULL) +				{ +					char* text = (char*)avahi_string_list_get_text(txt); +					DBG(10, "avahi string = %s\n", text); + +					if (strlen(text) > 4 && strncmp(text, "mdl=", 4) == 0) +					{ +						if (data->callBack) +                		{ +							data->callBack(&text[4], ipAddr); +							break; +                		} +					} +					txt = avahi_string_list_get_next(txt); +				} + +            } +        } +		break; +    } +} + +static void +browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, +                            AvahiProtocol protocol, AvahiBrowserEvent event, +                            const char *name, const char *type, +                            const char *domain, +                            AvahiLookupResultFlags flags, +                            void* userdata) +{ +    DBG(10, "browse_callback event = %d\n", event); + +	//unused parameter +	(void)b; +	(void)flags; + +    EDSAvahiUserData *data = userdata; +    switch (event) { +    case AVAHI_BROWSER_FAILURE: +        avahi_simple_poll_quit(simple_poll); +        return; +    case AVAHI_BROWSER_NEW: +	    DBG(10, "browse_callback name = %s\n", name); +		browsedCount++; +        if (!(avahi_service_resolver_new(data->client, interface, protocol, name, +                                                               type, domain, +                                                               AVAHI_PROTO_UNSPEC, 0, +                                                               epsonds_resolve_callback, data))) +		{ +			DBG(10, "avahi_service_resolver_new fails\n"); +		    break; +		} +    case AVAHI_BROWSER_REMOVE: +        break; +    case AVAHI_BROWSER_ALL_FOR_NOW: +		DBG(10, "AVAHI_BROWSER_ALL_FOR_NOW\n"); +        gettimeofday(&borowseEndTime, NULL); + +        if (browsedCount > resolvedCount) +        { +			  DBG(10, "WAIT RESOLVER\n"); +               waitResolver = 1; +         }else{ +			 DBG(10, "QUIT POLL\n"); +             avahi_simple_poll_quit(simple_poll); +         } +		break; +    case AVAHI_BROWSER_CACHE_EXHAUSTED: +		 DBG(10, "AVAHI_BROWSER_CACHE_EXHAUSTED\n"); +        break; +    } +} + +static void +client_callback(AvahiClient *c, AvahiClientState state, +                         AVAHI_GCC_UNUSED void *userdata) +{ +    assert(c); +    if (state == AVAHI_CLIENT_FAILURE) +        avahi_simple_poll_quit(simple_poll); +} + +SANE_Status epsonds_searchDevices(Device_Found_CallBack deviceFoundCallBack) +{ +	int result = SANE_STATUS_GOOD; + +    AvahiClient *client = NULL; +    AvahiServiceBrowser *sb = NULL; + +    EDSAvahiUserData data; + +    resolvedCount = 0; +	browsedCount = 0; +	waitResolver = 0; + + +	int error = 0; +    DBG(10, "epsonds_searchDevices\n"); + +    if (!(simple_poll = avahi_simple_poll_new())) { +        DBG(10, "avahi_simple_poll_new failed\n"); +		result = SANE_STATUS_INVAL; +        goto fail; +    } +    client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, +                                               client_callback, NULL, &error); +    if (!client) { +        DBG(10, "avahi_client_new failed %s\n", avahi_strerror(error)); +		result = SANE_STATUS_INVAL; +        goto fail; +    } +    data.client = client; +    data.callBack = deviceFoundCallBack; + +    if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, +                                                                   AVAHI_PROTO_UNSPEC, "_scanner._tcp", +                                                                   NULL, 0, browse_callback, &data))) { +        DBG(10, "avahi_service_browser_new failed: %s\n", +                              avahi_strerror(avahi_client_errno(client))); +		result = SANE_STATUS_INVAL; +        goto fail; +    } +    my_avahi_simple_poll_loop(simple_poll); +fail: +    if (sb) +        avahi_service_browser_free(sb); +    if (client) +        avahi_client_free(client); +    if (simple_poll) +        avahi_simple_poll_free(simple_poll); + +	DBG(10, "epsonds_searchDevices fin\n"); + +    return result; +} +#endif | 
