neighbors.hh

Go to the documentation of this file.
00001 // Copyright (C) 2003-2006 Laboratoire de Recherche en Informatique
00002 
00003 // This file is part of Qolyester.
00004 
00005 // Qolyester is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 // Qolyester is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018 // Boston, MA  02110-1301, USA.
00019 
00027 
00028 # include "msg/message.hh"
00029 
00030 #ifndef QOLYESTER_DAEMON_SET_NEIGHBORS_HH
00031 # define QOLYESTER_DAEMON_SET_NEIGHBORS_HH 1
00032 
00033 # include "config.hh"
00034 
00035 # include "cst/constants.hh"
00036 # include "net/ipaddress.hh"
00037 # include "sch/scheduler.hh"
00038 # include "utl/set.hh"
00039 # include "utl/seqnum.hh"
00040 # include "utl/stampable.hh"
00041 # include "utl/timeval.hh"
00042 
00043 namespace olsr {
00044 
00045   namespace sch {
00046 
00047     class StatePrinter;
00048 
00049   }
00050 
00051   namespace set {
00052 
00053     //************************************
00054     //*  The Link class
00055     //*
00056 
00057     class Link : public utl::MultiStampable<1, address_t> {
00058       typedef Link                              This;
00059       typedef utl::MultiStampable<1, address_t> Super;
00060 
00061       explicit Link();
00062 
00063 # ifdef QOLYESTER_ENABLE_LINKHYS
00064       class LinkQuality {
00065         typedef LinkQuality     This;
00066       public:
00067         inline LinkQuality(Link& i, float v = cst::hyst_scaling);
00068         virtual ~LinkQuality() {}
00069         operator float() const {
00070           return value_;
00071         }
00072         inline This&    operator++();
00073         This    operator++(int) {
00074           This  tmp(*this);
00075           ++*this;
00076           return tmp;
00077         }
00078         inline This&    operator--();
00079         This    operator--(int) {
00080           This  tmp(*this);
00081           --*this;
00082           return tmp;
00083         }
00084         void    expire() {
00085           ++expired_;
00086         }
00087         void    lost(unsigned n) {
00088           if (n > expired_ || n == 0)
00089             blocked_ = false;
00090           else
00091             blocked_ = true;
00092           expired_ = 0;
00093         }
00094       private:
00095         inline void     update();
00096 
00097         float           value_;
00098         Link&           instance_;
00099         unsigned        expired_;
00100         bool            blocked_;
00101       };
00102     public:
00103       inline Link(const address_t& l, const address_t& r, const address_t& m,
00104                   const timeval_t& v, const seqnum_t& s, const timeval_t& ht);
00105 # else // !QOLYESTER_ENABLE_LINKHYS
00106     public:
00107       inline Link(const address_t& l, const address_t& r, const address_t& m,
00108                   const timeval_t& v);
00109 # endif
00110 
00111       inline Link(const This& other);
00112 
00113       virtual ~Link() {}
00114       // Modifiers
00115       void      set_asymtime(const timeval_t& t) { asymtime_ = t; }
00116       void      set_symtime (const timeval_t& t) { symtime_  = t; }
00117       void      set_time    (const timeval_t& t) { time_     = t; }
00118 # ifdef QOLYESTER_ENABLE_LINKHYS
00119       void      set_losttime(const timeval_t& t) { losttime_ = t; }
00120       void      set_nexttime(const timeval_t& t) { nexttime_ = t; }
00121       void      set_htime   (const timeval_t& t) { htime_    = t; }
00122       void      set_pending (const bool p)       { pending_  = p; }
00123 
00124       inline void       set_last_seqnum(const seqnum_t& s);
00125 # endif // !QOLYESTER_ENABLE_LINKHYS
00126 
00127       // Accessors
00128       const address_t&  local_addr()    const { return l_addr_; }
00129       const address_t&  remote_addr()   const { return r_addr_; }
00130       const address_t&  main_addr()     const { return m_addr_; }
00131       const timeval_t&  asymtime()      const { return asymtime_; }
00132       const timeval_t&  symtime()       const { return symtime_; }
00133       const timeval_t&  time()          const { return time_; }
00134 # ifdef QOLYESTER_ENABLE_LINKHYS
00135       const timeval_t&  losttime()      const { return losttime_; }
00136       const timeval_t&  nexttime()      const { return nexttime_; }
00137       const timeval_t&  htime()         const { return htime_; }
00138       const bool        pending()       const { return pending_; }
00139 
00140       const LinkQuality&        quality() const { return quality_; }
00141       LinkQuality&              quality() { return quality_; }
00142 # endif // !QOLYESTER_ENABLE_LINKHYS
00143 
00144       // Simple validity checker
00145       inline bool       is_valid() const;
00146       inline bool       is_sym() const;
00147 
00148       bool      was_sym()     const { return was_sym_; }
00149       void      set_was_sym(bool ws) { was_sym_ = ws; }
00150 
00151       // Plain comparison operator
00152       inline bool       operator<(const This& rhs) const;
00153 
00154       // Utility static method for the creation of dummy objects to search sets
00155       static inline const This& make_key(const address_t& local,
00156                                          const address_t& remote);
00157       static inline const This& make_key_local(const address_t& local);
00158     private:
00159       const address_t   l_addr_;
00160       const address_t   r_addr_;
00161       const address_t   m_addr_;
00162       timeval_t         asymtime_;
00163       timeval_t         symtime_;
00164       timeval_t         time_;
00165       bool              was_sym_;
00166 # ifdef QOLYESTER_ENABLE_LINKHYS
00167       timeval_t         losttime_;
00168       timeval_t         nexttime_;
00169       timeval_t         htime_;
00170       bool              pending_;
00171       LinkQuality       quality_;
00172       seqnum_t          last_seqnum_;
00173 # endif // !QOLYESTER_ENABLE_LINKHYS
00174 
00175       // This is used for dummy objects used in set searching
00176       static This       dummy_for_find_;
00177 
00178       friend class sch::StatePrinter;
00179     };
00180 
00181     //********************************
00182     //*  The Neighbor class
00183     //*
00184 
00185     // The following block of declarations is only to provide Neighbor
00186     // with nested type definitions that are to occur in
00187     // CoherenceProxy later in the code.  This is mainly to avoid
00188     // having to declare Neighbor after CoherenceProxy and is
00189     // obviously the best way to deal with type interdependance.
00190 
00191     class CoherenceProxy;
00192 
00193     namespace upd {
00194 
00195       class LinkUpdater {
00196         typedef LinkUpdater                     This;
00197         typedef CoherenceProxy                  Set;
00198         typedef sch::Updatable<Link>            elem_t;
00199         typedef std::set<elem_t>::iterator      Iter;
00200         typedef sch::UpdateEvent<This>          updater_t;
00201       public:
00202         LinkUpdater(Set& s, const Iter& i)
00203           : set_(s),
00204             iter_(i)
00205         {}
00206         inline void     operator()();
00207         static timeval_t        min_time(const Link& l) {
00208           timeval_t     min_time(0);
00209           if (!l.time().is_past())
00210             min_time = l.time();
00211           if (!l.asymtime().is_past() &&
00212               (min_time == 0 ||
00213                l.asymtime() < min_time))
00214             min_time = l.asymtime();
00215           if (!l.symtime().is_past() &&
00216               (min_time == 0 ||
00217                l.symtime() < min_time))
00218             min_time = l.symtime();
00219 # ifdef QOLYESTER_ENABLE_LINKHYS
00220           if (!l.losttime().is_past() &&
00221               (min_time == 0 ||
00222                l.losttime() < min_time))
00223             min_time = l.losttime();
00224           if (!l.nexttime().is_past() &&
00225               (min_time == 0 ||
00226                l.nexttime() < min_time))
00227             min_time = l.nexttime();
00228 # endif // !QOLYESTER_ENABLE_LINKHYS
00229           return min_time;
00230         }
00231       private:
00232         Set&    set_;
00233         Iter    iter_;
00234       };
00235 
00236     } // namespace upd
00237 
00238     class Neighbor : public utl::MultiStampable<1, address_t> {
00239       typedef Neighbor                          This;
00240       typedef utl::MultiStampable<1, address_t> Super;
00241 
00242       typedef sch::Updatable<Link>              ulink_t;
00243 
00244       struct ilinkless {
00245         typedef std::set<ulink_t>::iterator     iter_t;
00246         bool    operator()(const iter_t& a, const iter_t& b) const {
00247           return a->local_addr() < b->local_addr();
00248         }
00249       };
00250 
00251       typedef utl::Index<std::multiset,
00252                          std::set<ulink_t>,
00253                          ilinkless>             lset_t;
00254 
00255       struct lset_valid {
00256         bool operator()(This&, const lset_t::iterator& pos) const {
00257           return pos->is_valid();
00258         }
00259       };
00260 
00261       typedef utl::Subset<utl::MultiAdapt<lset_t>,
00262                           utl::NoAction<This, lset_t::iterator>,
00263                           lset_valid,
00264                           This>                 val_lset_t;
00265 
00266       explicit inline Neighbor();
00267     public:
00268       typedef val_lset_t                        linkset_t;
00269 
00270       inline Neighbor(const address_t& maddr,
00271                       const std::set<ulink_t>::iterator& i,
00272                       unsigned w);
00273 
00274       inline Neighbor(const This&);
00275 
00276       virtual ~Neighbor() {}
00277 
00278       const address_t&  main_addr()   const { return m_addr_;      }
00279       unsigned          willingness() const { return willingness_; }
00280       const timeval_t&  mprsel_time() const { return mprsel_time_; }
00281 
00282       inline void       set_willingness(unsigned w);
00283 
00284       bool              is_sym() const { return sym_; }
00285       bool              is_mpr() const { return mpr_; }
00286       inline bool       is_mprsel() const;
00287       inline bool       was_mprsel();
00288 
00289       void              set_sym(bool state) { sym_ = state; }
00290 
00291       void              set_mpr(bool state) { mpr_ = state; }
00292 
00293       inline void       set_mprsel(const timeval_t& validity);
00294 
00295       inline void       unset_mprsel();
00296 
00297       inline std::pair<linkset_t::const_iterator, linkset_t::const_iterator>
00298                         find_lifaces(const address_t& laddr) const;
00299 
00300 //       bool           is_liface(const address_t& iaddr) const;
00301 
00302       linkset_t&        linkset() { return val_lset_; }
00303 
00304       inline void       insert(const std::set<ulink_t>::iterator& pos);
00305 
00306       inline void       erase(const lset_t::iterator& pos);
00307       inline void       erase(const std::set<ulink_t>::iterator& pos);
00308 
00309       inline bool       operator<(const This& rhs) const;
00310 
00311       static inline const This& make_key(const address_t& m);
00312 
00313     private:
00314       const address_t   m_addr_;
00315       lset_t            lset_;
00316       val_lset_t        val_lset_;
00317       bool              sym_;
00318       bool              mpr_;
00319       timeval_t         mprsel_time_;
00320       bool              was_mprsel_;
00321       unsigned          willingness_;
00322 
00323       static Neighbor   dummy_for_find_;
00324 
00325       friend class sch::StatePrinter;
00326     };
00327 
00328     namespace upd {
00329 
00330       class NeighborUpdater {
00331         typedef NeighborUpdater                 This;
00332         typedef CoherenceProxy                  Set;
00333         typedef sch::Updatable<Neighbor>        elem_t;
00334         typedef std::set<elem_t>::iterator      Iter;
00335         typedef sch::UpdateEvent<This>          updater_t;
00336       public:
00337         NeighborUpdater(Set& s, const Iter& i)
00338           : set_(s),
00339             iter_(i)
00340         {}
00341         inline void     operator()();
00342       private:
00343         Set&    set_;
00344         Iter    iter_;
00345       };
00346 
00347     } // namespace upd
00348 
00350     //  The coherence management proxy
00351     //
00352 
00353     class CoherenceProxy {
00354       typedef CoherenceProxy    This;
00355 
00356 //       typedef internal::nested_type_traits<This>     ntt_t;
00357 
00358       typedef sch::Updatable<Link>                      ulink_t;
00359       typedef sch::UpdateEvent<upd::LinkUpdater>        link_updater_t;
00360       typedef std::set<ulink_t>                         lset_t;
00361 
00362       typedef sch::Updatable<Neighbor>                  uneighbor_t;
00363       typedef sch::UpdateEvent<upd::NeighborUpdater>    neighbor_updater_t;
00364 
00365       struct stampable_nset_ : public std::set<uneighbor_t>,
00366                                public utl::Stampable {};
00367 
00368       typedef stampable_nset_   nset_t;
00369 
00370       // Some functors
00371       template <class Set, class Iter>
00372       struct nset_valid {
00373         bool operator()(Set& explicit_this, const Iter& pos) const {
00374           return explicit_this.is_valid(pos);
00375         }
00376       };
00377 
00378       // Valid Link set
00379       typedef utl::Subset<lset_t>       val_lset_t;
00380 
00381       // Valid Neighbor set
00382       typedef utl::Subset<nset_t,
00383                           utl::NoAction<This, nset_t::iterator>,
00384                           nset_valid<This, nset_t::iterator>,
00385                           This>         val_nset_t;
00386 
00387       template <class Set>
00388       struct nset_sym {
00389         bool operator()(Set&, const typename Set::iterator& pos) const {
00390           return pos->is_sym();
00391         }
00392       };
00393 
00394       // Symmetric Neighbor set
00395       typedef utl::Subset<val_nset_t,
00396                           utl::NoAction<val_nset_t>,
00397                           nset_sym<val_nset_t> >        sym_val_nset_t;
00398 
00399       typedef utl::MSIndex<lset_t, 0, address_t>        idx_lset_t;
00400 
00401       // First multistamped index on Neighbors
00402       typedef utl::MSIndex<nset_t, 0, address_t>        idx_nset_t;
00403 
00404 //       // Second multistamped index on Neighbors
00405 //       typedef utl::MSIndex<nset_t, 1, address_t>     idx1_nset_t;
00406 
00407       typedef utl::Subset<utl::MSAdapt<idx_lset_t>,
00408                           utl::NoAction<idx_lset_t>,
00409                           utl::DefaultPredicate<idx_lset_t>,
00410                           idx_lset_t>                   val_idx_lset_t;
00411 
00412       // First valid multistamped index on Neighbors
00413       typedef utl::Subset<utl::MSAdapt<idx_nset_t>,
00414                           utl::NoAction<This, idx_nset_t::iterator>,
00415                           nset_valid<This, idx_nset_t::iterator>,
00416                           This>                         val_idx_nset_t;
00417 
00418 //       // Second valid multistamped index on Neighbors
00419 //       typedef utl::Subset<utl::MSAdapt<idx1_nset_t>,
00420 //                        utl::NoAction<This, idx1_nset_t::iterator>,
00421 //                        nset_valid<This, idx1_nset_t::iterator>,
00422 //                        This>         val_idx1_nset_t;
00423 
00424       struct val_idx_nset_stamper {
00425         void operator()(val_idx_nset_t& set_ref,
00426                         val_idx_nset_t::iterator pos) const {
00427           set_ref.set_stamp(pos);
00428         }
00429       };
00430 
00431       typedef utl::Subset<utl::MSAdapt<val_idx_nset_t>,
00432                           val_idx_nset_stamper,
00433                           nset_sym<val_idx_nset_t>,
00434                           val_idx_nset_t>               sym_val_idx_nset_t;
00435     public:
00436       inline CoherenceProxy();
00437 
00438       virtual inline ~CoherenceProxy();
00439 
00440       typedef val_lset_t                linkset_t;
00441       typedef val_idx_lset_t            hello_linkset_t;
00442 
00443       typedef val_nset_t                neighborset_t;
00444       typedef sym_val_nset_t            sym_neighborset_t;
00445       typedef sym_val_idx_nset_t        tc_neighborset_t;
00446 
00462 # ifdef QOLYESTER_ENABLE_LINKHYS
00463       inline std::pair<neighborset_t::iterator, bool>
00464       insert_link(const msg::Message::header& mh,
00465                   const int linktype,
00466                   const int will,
00467                   const timeval_t& htime);
00468 # else // !QOLYESTER_ENABLE_LINKHYS
00469       inline std::pair<neighborset_t::iterator, bool>
00470       insert_link(const msg::Message::header& mh,
00471                   const int linktype,
00472                   const int will);
00473 # endif
00486       inline void       set_willingness(const nset_t::iterator& pos,
00487                                         unsigned w);
00488 
00493       inline void       update_graph(const nset_t::iterator& pos);
00494 
00500       inline bool       update_state(const nset_t::iterator& pos);
00501 
00502       inline void       update_state(const address_t& maddr);
00503 
00508       inline void       set_sym(const nset_t::iterator& pos);
00509 
00514       inline void       unset_sym(const nset_t::iterator& pos);
00515 
00516       inline void       set_mpr(const nset_t::iterator& pos);
00517       inline void       set_mpr(const sym_neighborset_t::iterator& pos);
00518 
00519       inline void       unset_mpr(const nset_t::iterator& pos);
00520       inline void       unset_mpr(const sym_neighborset_t::iterator& pos);
00521 
00522       inline void       set_mprsel(const nset_t::iterator& pos,
00523                                    const timeval_t& v);
00524 
00525       inline void       unset_mprsel(const nset_t::iterator& pos);
00526 
00527       inline bool       is_advset_empty();
00528 
00529       bool      is_hold_expired() const {
00530         return nset_.expired(cst::top_hold_time);
00531       }
00532 
00533       void      stamp_hold() {
00534         nset_.set_stamp();
00535       }
00536 
00537       inline bool       is_valid(const nset_t::iterator& pos);
00538       inline bool       is_valid(const idx_nset_t::iterator& pos);
00539 //    inline bool       is_valid(const idx1_nset_t::iterator& pos);
00540 
00541       inline void       erase(lset_t::iterator pos);
00542     private:
00543       inline void       erase_from_all(nset_t::iterator pos);
00544     public:
00545       // Subsets accessors
00546 
00547       linkset_t&                linkset() {
00548         return linkset_;
00549       }
00550 
00551       hello_linkset_t&          hello_linkset() {
00552         return hello_linkset_;
00553       }
00554 
00555       neighborset_t&            neighborset() {
00556         return neighborset_;
00557       }
00558 
00559       sym_neighborset_t&        sym_neighborset() {
00560         return sym_neighborset_;
00561       }
00562 
00563       tc_neighborset_t&         tc_neighborset() {
00564         return tc_neighborset_;
00565       }
00566 
00567       const utl::Seqnum<u_int16_t>&     advset_seqnum() {
00568         if (advset_changed_) {
00569           ++advset_seqnum_;
00570           advset_changed_ = false;
00571         }
00572         return advset_seqnum_;
00573       }
00574 
00575       // Interface addition for multistamped indexes
00576       inline void       add_interface(const address_t& a);
00577       // Interface removal for multistamped indexes
00578       inline void       remove_interface(const address_t& a);
00579 
00580     private:
00581       lset_t                    lset_;
00582       nset_t                    nset_;
00583 
00584       linkset_t                 linkset_;
00585 
00586       idx_lset_t                idx_lset_;
00587       hello_linkset_t           hello_linkset_;
00588 
00589       neighborset_t             neighborset_;
00590 
00591       sym_neighborset_t         sym_neighborset_;
00592 
00593       idx_nset_t                idx_nset_;
00594       val_idx_nset_t            val_idx_nset_;
00595       tc_neighborset_t          tc_neighborset_;
00596 
00597       utl::Seqnum<u_int16_t>    advset_seqnum_;
00598       bool                      advset_changed_;
00599 
00600       unsigned                  sym_count_;
00601       unsigned                  mpr_count_;
00602       bool                      mprsel_empty_;
00603 
00604       friend class sch::StatePrinter;
00605 
00606     };
00607 
00608     class TwoHopNeighbor {
00609       typedef TwoHopNeighbor            This;
00610 
00611       inline TwoHopNeighbor();
00612     public:
00613       inline TwoHopNeighbor(const address_t& a,
00614                             const address_t& tha,
00615                             const timeval_t&   validity);
00616 
00617       virtual ~TwoHopNeighbor() {}
00618 
00619       // Accessors
00620       const address_t&  main_addr()   const { return mainaddr_;   }
00621       const address_t&  twohop_addr() const { return twohopaddr_; }
00622       const timeval_t&  time()        const { return time_;       }
00623 
00624       // Modifiers
00625       void      set_time(const timeval_t& t) { time_ = t; }
00626 
00627       bool      is_valid() const { return !time_.is_past(); }
00628 
00629       inline bool       operator<(const This& rhs) const;
00630 
00631       inline This&      operator=(const This& other);
00632 
00633       static inline const This& make_key(const address_t& ma,
00634                                          const address_t& tha);
00635     private:
00636       const address_t   mainaddr_;
00637       const address_t   twohopaddr_;
00638       timeval_t         time_;
00639 
00640       static This       dummy_for_find_;
00641 
00642       friend class sch::StatePrinter;
00643     };
00644 
00645     class TwoHopNeighborSet {
00646       typedef TwoHopNeighborSet                                 This;
00647       typedef sch::Updatable<TwoHopNeighbor>                    elem_t;
00648       typedef std::set<elem_t>                                  tset_t;
00649       typedef sch::upd::SetEraser<This, tset_t::iterator>       eraser_t;
00650       typedef sch::UpdateEvent<eraser_t>                        updater_t;
00651 
00652       typedef utl::Subset<tset_t,
00653                           utl::NoAction<This, tset_t::iterator>,
00654                           utl::DefaultPredicate<This, tset_t::iterator>,
00655                           This>         val_tset_t;
00656     public:
00657       typedef val_tset_t                thnset_t;
00658 
00659       thnset_t& thnset() { return thnset_; }
00660 
00661       inline TwoHopNeighborSet();
00662       virtual ~TwoHopNeighborSet() {}
00663 
00664       inline void       insert(const TwoHopNeighbor& x);
00665       inline void       erase(const tset_t::iterator& pos);
00666       inline void       erase(const tset_t::value_type& x);
00667 
00668     private:
00669       tset_t    tset_;
00670       thnset_t  thnset_;
00671 
00672       friend class sch::StatePrinter;
00673     };
00674 
00675   } // namespace set
00676 
00677   typedef set::CoherenceProxy           cproxy_t;
00678   typedef set::TwoHopNeighborSet        thnset_t;
00679 
00680 } // namespace olsr
00681 
00682 # include "neighbors.hxx"
00683 
00684 #endif // ! QOLYESTER_DAEMON_SET_NEIGHBORS_HH

Generated on Mon Sep 10 17:02:12 2007 for Qolyester daemon by  doxygen 1.5.1