00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
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
00152 inline bool operator<(const This& rhs) const;
00153
00154
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
00176 static This dummy_for_find_;
00177
00178 friend class sch::StatePrinter;
00179 };
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
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 }
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
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 }
00348
00350
00351
00352
00353 class CoherenceProxy {
00354 typedef CoherenceProxy This;
00355
00356
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
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
00379 typedef utl::Subset<lset_t> val_lset_t;
00380
00381
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
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
00402 typedef utl::MSIndex<nset_t, 0, address_t> idx_nset_t;
00403
00404
00405
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
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
00419
00420
00421
00422
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
00540
00541 inline void erase(lset_t::iterator pos);
00542 private:
00543 inline void erase_from_all(nset_t::iterator pos);
00544 public:
00545
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
00576 inline void add_interface(const address_t& a);
00577
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
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
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 }
00676
00677 typedef set::CoherenceProxy cproxy_t;
00678 typedef set::TwoHopNeighborSet thnset_t;
00679
00680 }
00681
00682 # include "neighbors.hxx"
00683
00684 #endif // ! QOLYESTER_DAEMON_SET_NEIGHBORS_HH