Fawkes API  Fawkes Development Version
avahi_thread.h
00001 
00002 /***************************************************************************
00003  *  avahi_thread.h - Avahi Thread
00004  *
00005  *  Created: Wed Nov 08 11:17:06 2006
00006  *  Copyright  2006  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #ifndef __NETCOMM_DNSSD_AVAHI_THREAD_H_
00025 #define __NETCOMM_DNSSD_AVAHI_THREAD_H_
00026 
00027 #include <core/threading/thread.h>
00028 #include <netcomm/service_discovery/service_publisher.h>
00029 #include <netcomm/service_discovery/service_browser.h>
00030 
00031 #include <core/utils/lock_map.h>
00032 #include <core/utils/lock_list.h>
00033 #include <core/utils/lock_queue.h>
00034 
00035 #include <avahi-client/client.h>
00036 #include <string>
00037 #include <utility>
00038 #include <netinet/in.h>
00039 
00040 struct AvahiEntryGroup;
00041 struct AvahiSimplePoll;
00042 struct AvahiServiceBrowser;
00043 struct AvahiServiceResolver;
00044 struct AvahiHostNameResolver;
00045 struct AvahiAddressResolver;
00046 struct sockaddr_in;
00047 
00048 namespace fawkes {
00049 
00050 class ServiceBrowseHandler;
00051 class NetworkService;
00052 class WaitCondition;
00053 class AvahiResolverHandler;
00054 
00055 class AvahiThread
00056 : public Thread,
00057   public ServicePublisher,
00058   public ServiceBrowser
00059 {
00060  public:
00061   AvahiThread();
00062   ~AvahiThread();
00063 
00064   void wait_initialized();
00065 
00066   virtual void loop();
00067 
00068   /* Service publisher entry methods */
00069   void publish_service(NetworkService *service);
00070   void unpublish_service(NetworkService *service);
00071 
00072   /* Service browser methods */
00073   void watch_service(const char *service_type, ServiceBrowseHandler *h);
00074   void unwatch_service(const char *service_type, ServiceBrowseHandler *h);
00075 
00076   /* Resolver methods */
00077   void resolve_name(const char *name, AvahiResolverHandler *handler);
00078   void resolve_address(struct sockaddr *addr, socklen_t addrlen,
00079                        AvahiResolverHandler *handler);
00080 
00081  /** Stub to see name in backtrace for easier debugging. @see Thread::run() */
00082  protected: virtual void run() { Thread::run(); }
00083 
00084  private:
00085   /* Callbacks */
00086   static void client_callback(AvahiClient *c, AvahiClientState state, void *instance);
00087 
00088   static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state,
00089                                    void *instance);
00090 
00091   static void browse_callback( AvahiServiceBrowser *b,
00092                                AvahiIfIndex interface,
00093                                AvahiProtocol protocol,
00094                                AvahiBrowserEvent event,
00095                                const char *name,
00096                                const char *type,
00097                                const char *domain,
00098                                AvahiLookupResultFlags flags,
00099                                void *instance);
00100 
00101   static void resolve_callback( AvahiServiceResolver *r,
00102                                 AVAHI_GCC_UNUSED AvahiIfIndex interface,
00103                                 AVAHI_GCC_UNUSED AvahiProtocol protocol,
00104                                 AvahiResolverEvent event,
00105                                 const char *name,
00106                                 const char *type,
00107                                 const char *domain,
00108                                 const char *host_name,
00109                                 const AvahiAddress *address,
00110                                 uint16_t port,
00111                                 AvahiStringList *txt,
00112                                 AvahiLookupResultFlags flags,
00113                                 void *instance);
00114 
00115   static void host_name_resolver_callback(AvahiHostNameResolver *r,
00116                                           AvahiIfIndex interface,
00117                                           AvahiProtocol protocol,
00118                                            AvahiResolverEvent event,
00119                                           const char *name,
00120                                           const AvahiAddress *a,
00121                                           AvahiLookupResultFlags flags,
00122                                           void *userdata);
00123   
00124   static void address_resolver_callback(AvahiAddressResolver *r,
00125                                         AvahiIfIndex interface,
00126                                         AvahiProtocol protocol,
00127                                         AvahiResolverEvent event,
00128                                         const AvahiAddress *a,
00129                                         const char *name,
00130                                         AvahiLookupResultFlags flags,
00131                                         void *userdata);
00132 
00133 
00134   void call_handler_service_removed( const char *name,
00135                                      const char *type,
00136                                      const char *domain);
00137   void call_handler_service_added( const char *name,
00138                                    const char *type,
00139                                    const char *domain,
00140                                    const char *host_name,
00141                                    const AvahiAddress *address,
00142                                    uint16_t port,
00143                                    std::list<std::string> &txt,
00144                                    AvahiLookupResultFlags flags);
00145   void call_handler_failed( const char *name,
00146                             const char *type,
00147                             const char *domain);
00148 
00149   void call_handler_all_for_now(const char *type);
00150   void call_handler_cache_exhausted(const char *type);
00151 
00152 
00153   void create_browser(const char *service_type);
00154   void create_browsers();
00155   void erase_browsers();
00156   void recreate_browsers();
00157   void create_pending_browsers();
00158   void remove_pending_browsers();
00159 
00160   /* general private methods */
00161   void init_done();
00162   void recover();
00163   void wake_poller();
00164 
00165   /* publisher private methods */
00166   AvahiEntryGroup * create_service(const NetworkService &service, AvahiEntryGroup *exgroup);
00167   void group_reset(AvahiEntryGroup *g);
00168   void group_erase(AvahiEntryGroup *g);
00169   void name_collision(AvahiEntryGroup *g);
00170   void erase_groups();
00171   void reset_groups();
00172   void create_pending_services();
00173   void remove_pending_services();
00174   void recreate_services();
00175 
00176   /* resolver */
00177   /** Internal type to pass data to callbacks for resolve methods */
00178   typedef std::pair<AvahiThread *, AvahiResolverHandler *> AvahiResolverCallbackData;
00179 
00180   void remove_hostname_resolver(AvahiHostNameResolver *r);
00181   void remove_address_resolver(AvahiAddressResolver *r);
00182   void start_address_resolvers();
00183   void start_hostname_resolvers();
00184   void start_hostname_resolver(const char *name, AvahiResolverCallbackData *data);
00185   void start_address_resolver(struct sockaddr_in *in_addr, AvahiResolverCallbackData *data);
00186 
00187 
00188   bool need_recover;
00189   bool do_erase_browsers;
00190   bool do_reset_groups;
00191 
00192   AvahiSimplePoll  *simple_poll;
00193   AvahiClient      *client;
00194   AvahiClientState  client_state;
00195 
00196   WaitCondition         *init_wc;
00197 
00198   LockMap<NetworkService, AvahiEntryGroup *>           __services;
00199   LockMap<NetworkService, AvahiEntryGroup *>::iterator __sit;
00200   LockQueue<NetworkService>            __pending_services;
00201   LockQueue<NetworkService>            __pending_remove_services;
00202 
00203   LockMap<std::string, std::list<ServiceBrowseHandler *> > __handlers;
00204   LockMap<std::string, AvahiServiceBrowser * >             __browsers;
00205   LockQueue<std::string> __pending_browsers;
00206   LockQueue<std::string> __pending_browser_removes;
00207 
00208   LockList<AvahiHostNameResolver *> __running_hostname_resolvers;
00209   LockList<AvahiAddressResolver *>  __running_address_resolvers;
00210 
00211   LockMap<std::string, AvahiResolverCallbackData * >      __pending_hostname_resolves;
00212   LockMap<std::string, AvahiResolverCallbackData * >::iterator __phrit;
00213   LockMap<struct sockaddr_in *, AvahiResolverCallbackData *>  __pending_address_resolves;
00214   LockMap<struct sockaddr_in *, AvahiResolverCallbackData *>::iterator  __parit;
00215 };
00216 
00217 } // end namespace fawkes
00218 
00219 #endif