Logo Search packages:      
Sourcecode: latd version File versions

services.h

/******************************************************************************
    (c) 2000-2004 Patrick Caulfield                 patrick@debian.org
    (c) 2003 Dmitri Popov

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    any later version.

    This program 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 General Public License for more details.
******************************************************************************/

class LATServices
{
 public:
    static LATServices *Instance()
      {
          if (!instance)
            return (instance = new LATServices());
          else
            return instance;
      }

    // Get the highest rated node for this service name.
    bool get_highest(const std::string &service,
                 std::string &node,
                 unsigned char *macaddr,
                 int *interface);

    bool get_node(const std::string &service,
              const std::string &node,
              unsigned char *macaddr, int *interface);

    // Add/update a service.
    bool add_service(const std::string &node, const std::string &service, const std::string &ident,
                 int rating, int interface, unsigned char *macaddr);

    bool remove_node(const std::string &node);
    bool list_services(bool verbose, std::ostrstream &output);
    void purge() {servicelist.clear(); }
    void expire_nodes();
    bool list_dummy_nodes(bool verbose, std::ostrstream &output);
    bool touch_dummy_node_respond_counter(const std::string &str_name);


 private:
    LATServices()
      {};                         // Private constructor to force singleton
    static LATServices *instance; // Singleton instance

    class serviceinfo
    {
    public:
      serviceinfo() {}
      serviceinfo(const std::string &node, const std::string &_ident,
              const unsigned char *macaddr, int rating, int interface)
        {
            ident = _ident;
            nodes[node] = nodeinfo(macaddr, rating, ident, interface);
        }

      void add_or_replace_node(const std::string &node, const std::string &_ident,
                         const unsigned char *macaddr, int rating,
                         int interface)
        {
            ident = _ident;
            nodes.erase(node); // Don't care if this fails
            nodes[node] = nodeinfo(macaddr, rating, ident, interface);
        }
      bool  get_highest(std::string &node, unsigned char *macaddr, int *interface);
      bool  get_node(const std::string &node, unsigned char *macaddr, int *interface);
      const std::string get_ident() { return ident; }
      bool  is_available();
      bool  remove_node(const std::string &node);
      void  serviceinfo::list_service(std::ostrstream &output);
      void  expire_nodes(time_t);
      void  list_nodes(std::ostrstream &output);
      bool  touch_dummy_node_respond_counter(const std::string &str_name);

    private:
      class nodeinfo
      {
      public:
        nodeinfo() {}
        nodeinfo(const unsigned char *_macaddr, int _rating, std::string _ident, int _interface):
            rating(_rating),
            interface(_interface),
            available(true),
            slave_reachable(5) // if it doesn't respond five times...
          {
            memcpy(macaddr, _macaddr, 6);
            ident = _ident;
            updated = time(NULL);
          }
        bool has_expired(time_t current_time)
            {
              return ( (current_time - updated) > 60);
            }

        int                  get_rating()          { return rating; }
        int                  get_interface()       { return interface; }
        const unsigned char *get_macaddr()         { return macaddr; }
        bool                 is_available()        { return available; }
        void                 set_available(bool a) { available = a; }
        std::string          get_ident()           { return ident; }

        int touch_respond_counter()
            {
              if (slave_reachable > 0)
              {
                  slave_reachable--;
              }
              debuglog(("touch_respond_counter() %d\n", slave_reachable));
              return slave_reachable;
            }

         bool check_respond_counter() { return slave_reachable > 0; }

      private:
        unsigned char macaddr[6];
        int           rating;
        int           interface;
        bool          available;
        std::string   ident;
        time_t        updated;

        // for slave nodes
        int slave_reachable;
      };// class LATServices::service::nodeinfo

      std::map<std::string, nodeinfo, std::less<std::string> > nodes;
      std::string ident;
    };// class LATServices::serviceinfo

    std::map<std::string, serviceinfo, std::less<std::string> > servicelist;
};

Generated by  Doxygen 1.6.0   Back to index