00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 }
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
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
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
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
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
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
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 }
00403
00404 }
00405
00406 #endif // !QOLYESTER_DAEMON_SCH_EVENTS_HXX