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