Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

events.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2003, 2004, 2005 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, Boston, MA  02110-1301, USA.
00018 
00019 #ifndef QOLYESTER_DAEMON_SCH_EVENTS_HXX
00020 # define QOLYESTER_DAEMON_SCH_EVENTS_HXX 1
00021 
00022 # include "alg/routingtable.hh"
00023 # include "alg/mprselection.hh"
00024 # include "set/duplicate.hh"
00025 # include "set/hna.hh"
00026 # include "set/interfaces.hh"
00027 # include "set/mid.hh"
00028 # include "set/routes.hh"
00029 # include "set/topology.hh"
00030 # include "set/neighbors.hh"
00031 # include "sys/routing.hh"
00032 
00033 # include "events.hh"
00034 
00035 namespace olsr {
00036 
00037   extern utl::Mark      mprset_recomp;
00038   extern utl::Mark      advset_changed;
00039 
00040   extern sch::TimedEvent*       tc_sender;
00041   extern dupset_t       dup_set;
00042   extern hnaset_t       hna_set;
00043   extern midset_t       mid_set;
00044   extern lrouteset_t    lroute_set;
00045   extern rrouteset_t    rroute_set;
00046   extern toposet_t      topo_set;
00047   extern ifaceset_t     iface_set;
00048   extern thnset_t       thn_set;
00049 
00050   extern std::ostream   dump_state;
00051 
00052   namespace sch {
00053 
00054     namespace internal {
00055 
00056 # define SENDER_TRAITS(Msg, Id) \
00057       const timeval_t& sender_traits<msg::Msg ## Message>::interval = \
00058         cst::Id ## _interval; \
00059       const timeval_t sender_traits<msg::Msg ## Message>::in_jitter(1000); \
00060       const timeval_t& sender_traits<msg::Msg ## Message>::maxjitter = \
00061         cst::maxjitter; \
00062       const std::string sender_traits<msg::Msg ## Message>::name = #Msg ;
00063 
00064       SENDER_TRAITS(HELLO, hello);
00065       SENDER_TRAITS(TC, tc);
00066       SENDER_TRAITS(MID, mid);
00067       SENDER_TRAITS(HNA, hna);
00068 
00069 #undef SENDER_TRAITS
00070 
00071     } // namespace internal
00072 
00073 # ifdef DEBUG
00074     template <class M>
00075     MessageSender<M>::MessageSender()
00076       : Super(timeval_t::in_jitter(internal::sender_traits<M>::in_jitter),
00077               internal::sender_traits<M>::interval,
00078               internal::sender_traits<M>::maxjitter,
00079               std::string("MessageSender(") +
00080               internal::sender_traits<M>::name + ")")
00081     {}
00082 # else // !DEBUG
00083     template <class M>
00084     MessageSender<M>::MessageSender()
00085       : Super(timeval_t::in_jitter(internal::sender_traits<M>::in_jitter),
00086               internal::sender_traits<M>::interval,
00087               internal::sender_traits<M>::maxjitter)
00088     {}
00089 # endif
00090 
00091     template <class M>
00092     void
00093     MessageSender<M>::handle() {
00094       Super::handle();
00095       pending_messages.push_back(new M());
00096     }
00097 
00098 # ifdef DEBUG
00099     MessageSender<msg::TCMessage>::MessageSender()
00100       : Super(timeval_t::in_jitter(internal::sender_traits<msg::TCMessage>::in_jitter),
00101               internal::sender_traits<msg::TCMessage>::interval,
00102               internal::sender_traits<msg::TCMessage>::maxjitter,
00103               "MessageSender(TC)")
00104     {}
00105 # else // !DEBUG
00106     MessageSender<msg::TCMessage>::MessageSender()
00107       : Super(timeval_t::in_jitter(internal::sender_traits<msg::TCMessage>::in_jitter),
00108               internal::sender_traits<msg::TCMessage>::interval,
00109               internal::sender_traits<msg::TCMessage>::maxjitter)
00110     {}
00111 # endif
00112 
00113     void
00114     MessageSender<msg::TCMessage>::handle() {
00115       Super::handle();
00116       if (!cproxy.is_advset_empty() || !cproxy.is_hold_expired())
00117         pending_messages.push_back(new msg::TCMessage());
00118     }
00119 
00120 # ifdef DEBUG
00121     MessageForwarder::MessageForwarder(const timeval_t& n,
00122                                        const msg::UnknownMessage& m)
00123       : Super(n, "MessageForwarder"),
00124         message_(new msg::UnknownMessage(m))
00125     {}
00126 # else // !DEBUG
00127     MessageForwarder::MessageForwarder(const timeval_t& n,
00128                                        const msg::UnknownMessage& m)
00129       : Super(n),
00130         message_(new msg::UnknownMessage(m))
00131     {}
00132 # endif
00133 
00134     MessageForwarder::~MessageForwarder() {
00135       if (message_ != 0)
00136         delete message_;
00137     }
00138 
00139     void
00140     MessageForwarder::handle() {
00141       if (message_ != 0) {
00142         pending_messages.push_back(message_);
00143         message_ = 0;
00144       }
00145       scheduler.destroy(this);
00146     }
00147 
00148 # ifdef DEBUG
00149     StatePrinter::StatePrinter()
00150       : Super(timeval_t::now(), cst::dump_interval, "StatePrinter")
00151     {}
00152 # else // !DEBUG
00153     StatePrinter::StatePrinter()
00154       : Super(timeval_t::now(), cst::dump_interval)
00155     {}
00156 # endif
00157 
00158     // The state printer handler
00159     void
00160     StatePrinter::handle() {
00161       Super::handle();
00162 
00163       dump_state << "STATE {\n"
00164                  << indent;
00165       if (cproxy.nset_.empty())
00166         dump_state << "Neighbors {}\n";
00167       else {
00168         dump_state << "Neighbors {\n"
00169                    << indent;
00170         for (cproxy_t::nset_t::const_iterator i = cproxy.nset_.begin();
00171              i != cproxy.nset_.end(); ++i)
00172           dump_state << (i->is_sym()    ? "S " : "A ")
00173                      << (i->is_mpr()    ? "M " : "_ ")
00174                      << (i->is_mprsel() ? "s " : "_ ")
00175                      << i->main_addr() << " (" << i->lset_.size()
00176                      << " link(s)) "
00177                      << "s:" << of(i->mprsel_time().diff()) << " "
00178                      << "w: " << i->willingness() << "\n";
00179         dump_state << deindent
00180                    << "}\n";
00181       }
00182       if (cproxy.lset_.empty())
00183         dump_state << "Links {}\n";
00184       else {
00185         dump_state << "Links {\n"
00186                    << indent;
00187         for (cproxy_t::lset_t::const_iterator i = cproxy.lset_.begin();
00188              i != cproxy.lset_.end(); ++i) {
00189           dump_state << (i->is_sym() ? "S " :
00190                          (i->asymtime() > timeval_t::now() ?
00191                           "A " : "L "))
00192                      << i->local_addr() << " <- " << i->remote_addr() << " ("
00193                      << i->main_addr() << ")\n        "
00194                      << "t:" << of(i->time_.diff()) << " "
00195                      << "A:" << of(i->asymtime_.diff()) << " "
00196                      << "S:" << of(i->symtime_.diff()) << " "
00197 # ifdef QOLYESTER_ENABLE_LINKHYS
00198                      << "L:" << of(i->losttime_.diff()) << (i->pending_ ?
00199                                                             " P " : "   ")
00200                      << "n:" << of(i->nexttime_.diff()) << " "
00201                      << "Q:" << of(i->quality_)
00202 # endif // !QOLYESTER_ENABLE_LINKHYS
00203                      << "\n";
00204         }
00205         dump_state << deindent
00206                    << "}\n";
00207       }
00208       if (thn_set.tset_.empty())
00209         dump_state << "2-Hop neighbors {}\n";
00210       else {
00211         dump_state << "2-Hop neighbors {\n"
00212                    << indent;
00213         for (thnset_t::tset_t::const_iterator i = thn_set.tset_.begin();
00214              i != thn_set.tset_.end(); ++i)
00215           dump_state << i->main_addr() << " -> " << i->twohop_addr()
00216                      << " " << "t:" << of(i->time_.diff()) << "\n";
00217         dump_state << deindent
00218                    << "}\n";
00219       }
00220       if (topo_set.tset_.empty())
00221         dump_state << "Topology {}\n";
00222       else {
00223         dump_state << "Topology {\n"
00224                    << indent;
00225         for (toposet_t::tset_t::const_iterator i = topo_set.tset_.begin();
00226              i != topo_set.tset_.end(); ++i)
00227           dump_state << i->last_addr() << " -> " << i->dest_addr()
00228                      << " " << "t:" << of(i->time_.diff()) << "\n";
00229         dump_state << deindent
00230                    << "}" << std::endl;
00231       }
00232 # ifdef QOLYESTER_ENABLE_MID
00233       if (mid_set.mset_.empty())
00234         dump_state << "MID set {}\n";
00235       else {
00236         dump_state << "MID set {\n"
00237                    << indent;
00238         for (midset_t::mset_t::const_iterator i = mid_set.mset_.begin();
00239              i != mid_set.mset_.end(); ++i)
00240           dump_state << i->iface_addr() << " (" << i->main_addr()
00241                      << ") " << "t:" << of(i->time_.diff()) << "\n";
00242         dump_state << deindent
00243                    << "}\n";
00244       }
00245 # endif // !QOLYESTER_ENABLE_MID
00246 # ifdef QOLYESTER_ENABLE_HNA
00247       if (hna_set.hset_.empty())
00248         dump_state << "HNA set {}\n";
00249       else {
00250         dump_state << "HNA set {\n"
00251                    << indent;
00252         for (hnaset_t::hset_t::const_iterator i = hna_set.hset_.begin();
00253              i != hna_set.hset_.end(); ++i)
00254           dump_state << i->gw_addr() << " -> "
00255                << i->net_addr() << "/" << i->prefix() << " "
00256                << "t:" << of(i->time_.diff()) << "\n";
00257         dump_state << deindent
00258                    << "}\n";
00259       }
00260 # endif // !QOLYESTER_ENABLE_HNA
00261       if (dup_set.dset_.empty())
00262         dump_state << up << "Duplicate set {}\n" << down;
00263       else {
00264         dump_state << up << "Duplicate set {\n"
00265                    << indent;
00266         for (dupset_t::dset_t::const_iterator i = dup_set.dset_.begin();
00267              i != dup_set.dset_.end(); ++i) {
00268           dump_state << i->addr_ << " " << i->seqnum_
00269                      << (i->retransmitted_ ? " R" : " _") << " "
00270                      << i->time_.diff() << " { ";
00271           for (set::DuplicateEntry::ifaces_t::const_iterator j =
00272                  i->ifaces_.begin();
00273                j != i->ifaces_.end(); ++j)
00274             dump_state << *j << " ";
00275           dump_state << "}\n";
00276         }
00277         dump_state << deindent
00278                    << "}\n" << down;
00279       }
00280       if (lroute_set.set_.empty() && rroute_set.set_.empty())
00281         dump_state << "Route set {}\n";
00282       else {
00283         dump_state << "Route set {\n"
00284                    << indent;
00285         for (lrouteset_t::set_t::const_iterator i = lroute_set.set_.begin();
00286              i != lroute_set.set_.end(); ++i)
00287           dump_state << i->dest_addr() << "/" << i->prefix() << " : "
00288                      << i->interface_info().name() << "\n";
00289         for (rrouteset_t::set_t::const_iterator i = rroute_set.set_.begin();
00290              i != rroute_set.set_.end(); ++i)
00291           dump_state << i->dest_addr() << "/" << i->prefix() << " : "
00292                      << i->next_addr() << "\n";
00293         dump_state << deindent
00294                    << "}" << std::endl;
00295       }
00296 # ifdef DEBUG
00297       sys::RoutingActions().print_kernel_routes();
00298 # endif
00299       dump_state << up << path_net << "\n" << down;
00300       dump_state << deindent
00301                  << "}" << std::endl;
00302     }
00303 
00304 # ifdef DEBUG
00305     PacketSender::PacketSender(iface_t* i, const pkt::Packet& p)
00306       : Super(i->send_p(), "PacketSender"),
00307         iface_(i),
00308         packet_(p) {
00309       i->insert_event(this);
00310     }
00311 # else // !DEBUG
00312     PacketSender::PacketSender(iface_t* i, const pkt::Packet& p)
00313       : Super(i->send_p()),
00314         iface_(i),
00315         packet_(p) {
00316       i->insert_event(this);
00317     }
00318 # endif
00319 
00320     void
00321     PacketSender::handle() {
00322       p().pfd.revents = 0;
00323       try {
00324         iface_->send(packet_);
00325       } catch (errnoexcept_t& e) {
00326         warning << "PacketSender: " << e.what() << std::endl;
00327       }
00328       iface_->erase_event(this);
00329       scheduler.destroy(this);
00330     }
00331 
00332 # ifdef DEBUG
00333     PacketReceiver::PacketReceiver(iface_t* i)
00334       : Super(i->recv_p(), "PacketReceiver"),
00335         iface_(i) {
00336       i->insert_event(this);
00337     }
00338 # else // !DEBUG
00339     PacketReceiver::PacketReceiver(iface_t* i)
00340       : Super(i->recv_p()),
00341         iface_(i) {
00342       i->insert_event(this);
00343     }
00344 # endif
00345 
00346     void
00347     PacketReceiver::handle() {
00348       p().pfd.revents = 0;
00349       scheduler.insert(this);
00350       try {
00351         pkt::Packet     p = iface_->receive();
00352         pkt::Packet::parse(p.data(), p.sender(), iface_->addr());
00353       } catch (std::runtime_error& e) {
00354         warning << "PacketReceiver: " << e.what() << std::endl;
00355       }
00356     }
00357 
00358     bool
00359     QolyesterLoopHandler::operator()() const {
00360 
00361       // Here, we process the pending messages.
00362       if (!pending_messages.empty())
00363         iface_set.send_messages();
00364 
00365       if (mprset_recomp.mark()) {
00366         mprset_recomp.reset();
00367         alg::mprselection();
00368       }
00369 
00370       // Shift the sending of the next TC message if needed.
00371       if (advset_changed.mark()) {
00372         advset_changed.reset();
00373         assert(tc_sender != 0);
00374         scheduler.erase(tc_sender);
00375         tc_sender->set_next(timeval_t::in(timeval_t::jitter(cst::maxjitter)));
00376         scheduler.insert(tc_sender);
00377       }
00378 
00379       // Recalculate routes if needed.
00380       if (routes_recomp.mark()) {
00381         routes_recomp.reset();
00382         try {
00383           alg::compute_routes();
00384         } catch (errnoexcept_t& e) {
00385           warning << e.what() << std::endl;
00386         }
00387       }
00388 
00389       // Cleanly terminate if needed.
00390       if (terminate_now.mark())
00391         remove_routes();
00392 
00393       return Super::operator()();
00394     }
00395 
00396     void remove_routes()
00397     {
00398       debug << "Removing all routes" << std::endl;
00399       alg::flush_routes(lrouteset_t(), rrouteset_t());
00400     }
00401 
00402   } // namespace sch
00403 
00404 } // namespace olsr
00405 
00406 #endif // !QOLYESTER_DAEMON_SCH_EVENTS_HXX

Generated on Thu Jul 28 21:21:47 2005 for Qolyester daemon by  doxygen 1.4.1