libshevek
src/avahi.hh
00001 /* avahi.hh - publish and browse network ports with avahi
00002  * Copyright 2009 Bas Wijnen <wijnen@debian.org>
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation, either version 3 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #ifndef SHEVEK_AVAHI_HH
00019 #define SHEVEK_AVAHI_HH
00020 
00021 #include <map>
00022 #include <set>
00023 #include <glibmm.h>
00024 #include "refbase.hh"
00025 
00026 #include <avahi-client/client.h>
00027 #include <avahi-client/lookup.h>
00028 #include <avahi-client/publish.h>
00029 #include <avahi-common/alternative.h>
00030 #include <avahi-common/error.h>
00031 #include <avahi-common/simple-watch.h>
00032 #include <avahi-glib/glib-watch.h>
00033 
00034 namespace shevek
00035 {
00037 
00040         class avahi : public refbase
00041         {
00042         public:
00044 
00046                 void publish (Glib::ustring const &protocol, int port);
00048                 class browser;
00050 
00052                 inline Glib::RefPtr <browser> create_browser (Glib::ustring const &protocol);
00054                 static Glib::RefPtr <avahi> create (Glib::ustring const &name = Glib::ustring ()) { return Glib::RefPtr <avahi> (new avahi (name)); }
00056                 ~avahi ();
00057         private:
00058                 avahi (Glib::ustring const &name, bool allow_restart = true, bool blocking_poller = false);
00059                 std::map <Glib::ustring, int> m_ports;
00060                 char *m_name;
00061                 bool m_allow_restart;
00062                 AvahiPoll const *m_poll_api;
00063                 AvahiGLibPoll *m_glib_poll;
00064                 AvahiEntryGroup *m_group;
00065                 AvahiClient *m_client;
00066                 AvahiSimplePoll *m_poller;
00067                 void create_services (AvahiClient *client);
00068                 void create_client ();
00069                 void name_change (AvahiClient *client);
00070                 static void group_callback (AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata);
00071                 static void callback (AvahiClient *client, AvahiClientState state, void *userdata);
00072         };
00073 
00075         class avahi::browser : public refbase
00076         {
00077         public:
00079                 struct details
00080                 {
00082                         AvahiIfIndex interface;
00084                         AvahiProtocol protocol;
00086                         Glib::ustring address;
00088                         AvahiLookupResultFlags flags;
00090                         details (AvahiIfIndex i, AvahiProtocol p) : interface (i), protocol (p) {}
00092                         details (AvahiIfIndex i, AvahiProtocol p, Glib::ustring a, AvahiLookupResultFlags f) : interface (i), protocol (p), address (a), flags (f) {}
00094                         details () {}
00096                         bool operator< (details const &that) const { return interface == that.interface ? protocol < that.protocol : interface < that.interface; }
00097                 };
00099                 typedef std::set <details> details_list;
00101                 struct owner
00102                 {
00104                         Glib::ustring host;
00106                         int port;
00108                         owner (Glib::ustring const &h, int p) : host (h), port (p) {}
00110                         owner () : port (-1) {}
00112                         bool operator< (owner const &that) const { return host == that.host ? port < that.port : host < that.host; }
00114                         details_list details;
00115                 };
00117                 typedef std::map <Glib::ustring, owner> list;
00119                 list const &get_list () { return m_list; }
00121                 sigc::signal1 <void, Glib::ustring const &> signal_changed () { return m_changed; }
00123                 ~browser ();
00125                 static Glib::RefPtr <browser> create (Glib::ustring const &protocol) { return Glib::RefPtr <browser> (new browser (avahi::create (), protocol)); }
00127                 static list get_list_block (Glib::ustring const &protocol, Glib::ustring const &name = Glib::ustring ());
00128         private:
00129                 Glib::RefPtr <avahi> m_parent;
00130                 list m_list;
00131                 AvahiServiceBrowser *m_sb;
00132                 sigc::signal1 <void, Glib::ustring const &> m_changed;
00133                 Glib::ustring m_filter;
00134                 friend class avahi;
00135                 browser (Glib::RefPtr <avahi> parent, Glib::ustring const &protocol);
00136                 static void resolve_callback (AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, char const *name, char const *type, char const *domain, char const *host_name, AvahiAddress const *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void * userdata);
00137                 static void browse_callback (AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, char const *name, char const *type, char const *domain, AvahiLookupResultFlags flags, void *userdata);
00138         };
00139 
00140         Glib::RefPtr <avahi::browser> avahi::create_browser (Glib::ustring const &protocol)
00141         {
00142                 return Glib::RefPtr <browser> (new browser (refptr_this <avahi> (), protocol));
00143         }
00144 }
00145 
00146 #endif