Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib 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 Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ***************************************************************************/ 00019 #ifndef __ALGORITHMS_ROUTING_AODV_ROUTING_H__ 00020 #define __ALGORITHMS_ROUTING_AODV_ROUTING_H__ 00021 00022 #include "algorithms/routing/aodv/aodv_routing_types.h" 00023 #include "algorithms/routing/aodv/aodv_route_discovery_msg.h" 00024 #include "algorithms/routing/aodv/aodv_routing_msg.h" 00025 #include "util/base_classes/routing_base.h" 00026 #include <string.h> 00027 #include "config.h" 00028 #include <map> 00029 #include <list> 00030 00031 #undef DEBUG 00032 //#define DEBUG 00033 00034 #define NET_DIAM 10 00035 #define ROUTE_TIMEOUT 2 *NET_DIAM 00036 00037 #define ECHO_INTERVAL 2 00038 #define ALLOWED_LOSS ECHO_INTERVAL * 2 00039 00040 00041 #define RETRY_INTERVAL NET_DIAM * 2 00042 #define MAX_RETRIES 1 00043 using namespace std; 00044 namespace wiselib { 00045 00054 template<typename OsModel_P, 00055 typename RoutingTable_P, 00056 typename Radio_P = typename OsModel_P::Radio, 00057 typename Debug_P = typename OsModel_P::Debug> 00058 class AODVRouting 00059 : public RoutingBase<OsModel_P, Radio_P> { 00060 public: 00061 typedef OsModel_P OsModel; 00062 typedef Radio_P Radio; 00063 typedef Debug_P Debug; 00064 00065 typedef typename OsModel_P::Timer Timer; 00066 00067 typedef RoutingTable_P RoutingTable; 00068 typedef typename RoutingTable::iterator RoutingTableIterator; 00069 typedef typename RoutingTable::mapped_type RoutingTableValue; 00070 typedef typename RoutingTable::value_type RoutingTableEntry; 00071 typedef typename RoutingTableValue::Path Path; 00072 00073 enum { 00074 MAX_PATH_LENGTH = RoutingTableValue::MAX_PATH_LENGTH 00075 }; 00076 00077 typedef AODVRouting<OsModel, RoutingTable, Radio, Debug> self_type; 00078 00079 typedef typename Radio::node_id_t node_id_t; 00080 typedef typename Radio::size_t size_t; 00081 typedef typename Radio::block_data_t block_data_t; 00082 00083 typedef typename Timer::millis_t millis_t; 00084 00085 //typedef DsrRouteDiscoveryMessage<OsModel, Radio, Path> RouteDiscoveryMessage; 00086 typedef AODVRouteDiscoveryMessage<OsModel, Radio, Path> RouteDiscoveryMessage; 00087 typedef map<uint8_t, RouteDiscoveryMessage> pending_msgs_t; 00088 00089 //typedef DsrRoutingMessage<OsModel, Radio, Path> RoutingMessage; 00090 00091 //typedef AODVRo 00092 // -------------------------------------------------------------------- 00093 enum SpecialNodeIds { 00094 BROADCAST_ADDRESS = Radio_P::BROADCAST_ADDRESS, 00095 NULL_NODE_ID = Radio_P::NULL_NODE_ID 00096 }; 00097 // -------------------------------------------------------------------- 00098 enum Restrictions { 00099 MAX_MESSAGE_LENGTH = Radio_P::MAX_MESSAGE_LENGTH - RouteDiscoveryMessage::PAYLOAD_POS 00100 }; 00101 // -------------------------------------------------------------------- 00104 AODVRouting(); 00105 ~AODVRouting(); 00107 00110 void enable_radio(void); 00111 void disable_radio(void); 00113 00116 void timer_elapsed(void *userdata); 00118 00121 00123 void send( node_id_t receiver, size_t len, block_data_t *data ); 00126 void receive( node_id_t from, size_t len, block_data_t *data ); 00129 typename Radio::node_id_t id() 00130 { 00131 return radio_->id(); 00132 }; 00134 00135 void proc_rreq(node_id_t from, RouteDiscoveryMessage& message); 00136 void proc_rrep(node_id_t from, RouteDiscoveryMessage& message); 00137 void proc_err(node_id_t from, RouteDiscoveryMessage& message); 00138 void proc_data(node_id_t from, RouteDiscoveryMessage& message); 00139 bool route_exists(node_id_t destination); 00140 void check_pending_messages(uint16_t destination); 00141 void table_cleanup(); 00142 void init_path_disc(); 00143 void resend_rreq(uint16_t dest); 00144 00145 00146 void pend_dest_cleanup(); 00147 00148 void broadcaster(); 00149 void neighbors_cleanup(); 00150 00151 void init( Radio& radio, Timer& timer, Debug& debug ) { 00152 radio_ = &radio; 00153 timer_ = &timer; 00154 debug_ = &debug; 00155 } 00156 00157 void destruct() { 00158 } 00159 00160 private: 00161 Radio& radio() 00162 { return *radio_; } 00163 00164 Timer& timer() 00165 { return *timer_; } 00166 00167 Debug& debug() 00168 { return *debug_; } 00169 00170 Radio * radio_; 00171 Timer * timer_; 00172 Debug * debug_; 00173 00174 uint16_t my_seq_nr_; 00175 uint16_t my_bcast_id_; 00176 map<uint16_t, uint16_t> seq_numbers_; 00177 00178 pending_msgs_t pending_msgs_; 00179 00180 struct rreq_info { 00181 uint8_t source; 00182 uint8_t bcast_id; 00183 }; 00184 00185 bool route_found; 00186 00187 list<struct rreq_info> received_rreq_; 00188 typename list<struct rreq_info>::iterator rreq_iter_; 00189 00190 typename pending_msgs_t::iterator pend_iter_; 00191 00192 map<uint16_t, uint8_t> neighbors_; 00193 00194 typedef typename map<uint16_t, uint8_t>::iterator neighbors_iter_; 00195 00196 struct retry_info { 00197 uint8_t retries; 00198 uint8_t time; 00199 00200 }; 00201 00202 map<uint16_t, struct retry_info> pend_dests_; 00203 typedef typename map<uint16_t, struct retry_info>::iterator pend_dests_iter_; 00204 00205 00206 short seconds; 00207 int rounds; 00208 00209 RoutingTable routing_table_; 00210 }; 00211 // ----------------------------------------------------------------------- 00212 // ----------------------------------------------------------------------- 00213 // ----------------------------------------------------------------------- 00214 // ----------------------------------------------------------------------- 00215 // ----------------------------------------------------------------------- 00216 00217 00218 // ********************* LOCAL CONNECTIVITY ************************** 00219 template<typename OsModel_P, 00220 typename RoutingTable_P, 00221 typename Radio_P, 00222 typename Debug_P> 00223 void 00224 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00225 broadcaster(){ 00226 RouteDiscoveryMessage hello_message( 00227 HELO, /*msg type*/ 00228 0, /*bcast id*/ 00229 0, /*hop count*/ 00230 0, /*source seq*/ 00231 0,/*destination seq*/ 00232 radio().id(), /*source*/ 00233 0, /*destination*/ 00234 0/*next hop*/); 00235 00236 radio().send(radio().BROADCAST_ADDRESS, hello_message.buffer_size(), (uint8_t*) & hello_message); 00237 00238 } 00239 00240 00241 template<typename OsModel_P, 00242 typename RoutingTable_P, 00243 typename Radio_P, 00244 typename Debug_P> 00245 void 00246 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00247 neighbors_cleanup(){ 00248 00249 //debug().debug(" %i is cleaning up tables\n",radio().id() ); 00250 neighbors_iter_ n_it; 00251 //neighbors_iter_ n_it; 00252 n_it = neighbors_.begin(); 00253 //it =routing_table_.end(); 00254 //entries = 0; 00255 while(n_it != neighbors_.end()){ 00256 //entries++; 00257 // decrease entry's lifetime and check if is stale 00258 00259 00260 if(n_it->second == 0){ 00261 //debug().debug(" %i no longer neighbor with %i \n",radio().id(), n_it->first); 00262 00263 neighbors_.erase(n_it); 00264 00265 if (n_it != neighbors_.end()){ 00266 break; 00267 } 00268 00269 00270 } 00271 else{ 00272 n_it->second -= 1; 00273 00274 } 00275 n_it++; 00276 } 00277 //debug().debug(" %i has %i entries \n",radio().id(),entries); 00278 00279 } 00280 00281 00282 00283 00284 template<typename OsModel_P, 00285 typename RoutingTable_P, 00286 typename Radio_P, 00287 typename Debug_P> 00288 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00289 AODVRouting() 00290 : my_seq_nr_(0), 00291 my_bcast_id_(0) 00292 {}; 00293 00294 00295 // ----------------------------------------------------------------------- 00296 00297 template<typename OsModel_P, 00298 typename RoutingTable_P, 00299 typename Radio_P, 00300 typename Debug_P> 00301 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00302 ~AODVRouting() { 00303 #ifdef DEBUG 00304 debug().debug("AODVRouting Destroyed\n"); 00305 #endif 00306 }; 00307 // ----------------------------------------------------------------------- 00308 00309 template<typename OsModel_P, 00310 typename RoutingTable_P, 00311 typename Radio_P, 00312 typename Debug_P> 00313 void 00314 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00315 enable_radio(void) { 00316 #ifdef DEBUG 00317 debug().debug("AODVRouting Boots for %i\n", radio().id()); 00318 #endif 00319 my_seq_nr_ = 0; 00320 my_bcast_id_ = 0; 00321 seconds = 0; 00322 00323 rounds = 0; 00324 00325 radio().enable_radio(); 00326 radio().template reg_recv_callback<self_type, &self_type::receive > (this); 00327 00328 timer().template set_timer<self_type, &self_type::timer_elapsed > ( 00329 1000, this, 0); 00330 } 00331 00332 00333 // ----------------------------------------------------------------------- 00334 00335 template<typename OsModel_P, 00336 typename RoutingTable_P, 00337 typename Radio_P, 00338 typename Debug_P> 00339 void 00340 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00341 disable_radio(void) { 00342 #ifdef DEBUG 00343 debug().debug("Called AODVRouting::disable\n"); 00344 #endif 00345 } 00346 00347 00348 // ----------------------------------------------------------------------- 00349 00350 template<typename OsModel_P, 00351 typename RoutingTable_P, 00352 typename Radio_P, 00353 typename Debug_P> 00354 void 00355 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00356 timer_elapsed(void *userdata) { 00357 00358 // debug().debug(" %i setting\n ",radio().id()); 00359 seconds++; 00360 // debug().debug(" %i resetting 1\n %i",radio().id(), seconds); 00361 if( seconds == ECHO_INTERVAL ){ 00362 // debug().debug(" %i resetting2\n ",radio().id()); 00363 broadcaster(); 00364 // debug().debug(" %iresetting3\n ",radio().id()); 00365 seconds = 0; 00366 // debug().debug(" %i resetting4\n ",radio().id()); 00367 } 00368 // clean up routing table 00369 // debug().debug(" %i table clean up ",radio().id()); 00370 table_cleanup(); 00371 // debug().debug(" done\n "); 00372 // clean up neighbors 00373 // debug().debug("%i neighbors ",radio().id()); 00374 neighbors_cleanup(); 00375 // debug().debug(" done\n "); 00376 // clean up pending destinations 00377 // debug().debug(" %i dest clean up ",radio().id()); 00378 pend_dest_cleanup(); 00379 // debug().debug(" done\n "); 00380 00381 //re-setting timer 00382 timer().template set_timer<self_type, &self_type::timer_elapsed > ( 00383 1000, this, 0); 00384 // debug().debug(" resetting\n "); 00385 } 00386 00387 00388 // ----------------------------------------------------------------------- 00389 00390 template<typename OsModel_P, 00391 typename RoutingTable_P, 00392 typename Radio_P, 00393 typename Debug_P> 00394 bool 00395 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00396 route_exists(node_id_t destination) { 00397 RoutingTableIterator it = routing_table_.find(destination); 00398 if (it != routing_table_.end()) { 00399 return true; 00400 } else 00401 return false; 00402 00403 }; 00404 00405 00406 // ----------------------------------------------------------------------- 00407 00408 template<typename OsModel_P, 00409 typename RoutingTable_P, 00410 typename Radio_P, 00411 typename Debug_P> 00412 void 00413 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00414 check_pending_messages(uint16_t destination) { 00415 pend_iter_ = pending_msgs_.find(destination); 00416 if (pend_iter_ != pending_msgs_.end()) { 00417 // debug().debug("%i has pending msg for %i \n", radio().id(), destination); 00418 00419 uint16_t next_hop = routing_table_[destination].next_hop; 00420 radio().send(next_hop, pend_iter_->second.buffer_size(), (uint8_t*) & pend_iter_->second); 00421 00422 // debug().debug("%i sent stored msg to %i.next hop[%i] \n", radio().id(), destination, next_hop); 00423 routing_table_[destination].lifetime = ROUTE_TIMEOUT; 00424 00425 00426 //remove saved msg 00427 } else { 00428 // debug().debug("%i no msg for %i \n", radio().id(), destination); 00429 00430 } 00431 00432 } 00433 00434 template<typename OsModel_P, 00435 typename RoutingTable_P, 00436 typename Radio_P, 00437 typename Debug_P> 00438 void 00439 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00440 resend_rreq(uint16_t dest){ 00441 if(pend_dests_[dest].retries > MAX_RETRIES){ 00442 debug().debug(" %i was unable to find route for %i \n",radio().id(), dest ); 00443 // TODO delete f 00444 00445 pend_dests_.erase(dest); 00446 00447 pending_msgs_.erase(dest); 00448 00449 00450 } 00451 else{ 00452 pend_dests_[dest].retries+=1; 00453 pend_dests_[dest].time = RETRY_INTERVAL; 00454 00455 00456 00457 RouteDiscoveryMessage message( 00458 RREQ, /*msg type*/ 00459 ++my_bcast_id_, /*bcast id*/ 00460 0, /*hop count*/ 00461 ++my_seq_nr_, /*source seq*/ 00462 seq_numbers_[dest]/*destination seq*/, 00463 radio().id(), /*source*/ 00464 dest, /*destination*/ 00465 0/*next hop*/); 00466 00467 00468 radio().send(radio().BROADCAST_ADDRESS, message.buffer_size(), (uint8_t*) & message); 00469 00470 // add my own rreq to received rreq's 00471 struct rreq_info own_rreq; 00472 own_rreq.source = radio().id(); 00473 own_rreq.bcast_id = my_bcast_id_; 00474 received_rreq_.push_back(own_rreq); 00475 00476 debug().debug("%i REsent RREQ for %i \n", radio().id(), dest); 00477 00478 } 00479 00480 00481 } 00482 00483 00484 template<typename OsModel_P, 00485 typename RoutingTable_P, 00486 typename Radio_P, 00487 typename Debug_P> 00488 void 00489 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00490 pend_dest_cleanup(){ 00491 00492 //debug().debug(" %i is cleaning up tables\n",radio().id() ); 00493 pend_dests_iter_ p_it; 00494 //neighbors_iter_ n_it; 00495 p_it = pend_dests_.begin(); 00496 //it =routing_table_.end(); 00497 int entries = 0; 00498 while(p_it != pend_dests_.end()){ 00499 00500 if( p_it->second.time > 0){ 00501 p_it->second.time -= 1; 00502 } 00503 00504 //if(p_it->second.time == 0 && p_it->second.retries > 3) 00505 else if (p_it->second.time == 0) { 00506 00507 pend_dests_.erase(p_it); 00508 00509 00510 pending_msgs_.erase(p_it->first); 00511 00512 if(p_it == pend_dests_.end()){ 00513 break; 00514 } 00515 00516 // resend_rreq(p_it->first); 00517 //debug().debug(" %i found no route for %i \n",radio().id(), p_it->first ); 00518 // TODO also remove from pending messages 00519 } 00520 00521 00522 else if(p_it->second.time == 0 && p_it->second.retries <= MAX_RETRIES){ 00523 resend_rreq(p_it->first); 00524 00525 } 00526 00527 // debug().debug(" %i : %i,%i \n",radio().id(), p_it->second.time ,p_it->second.retries ); 00528 00529 p_it++; 00530 } 00531 00532 00533 00534 00535 00536 } 00537 00538 00539 00540 // ----------------------------------------------------------------------- 00541 template<typename OsModel_P, 00542 typename RoutingTable_P, 00543 typename Radio_P, 00544 typename Debug_P> 00545 void 00546 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00547 table_cleanup(){ 00548 int entries=0; 00549 //debug().debug(" %i is cleaning up tables\n",radio().id() ); 00550 RoutingTableIterator it; 00551 it = routing_table_.begin(); 00552 //it =routing_table_.end(); 00553 entries = 0; 00554 while(it != routing_table_.end()){ 00555 entries++; 00556 // decrease entry's lifetime and check if is stale 00557 00558 00559 if(it->second.lifetime == 0){ 00560 //debug().debug(" %i delete's entry for %i lifetime:%i \n",radio().id(), it->second.destination,it->second.lifetime ); 00561 routing_table_.erase(it); 00562 if (it != routing_table_.end()){ 00563 break; 00564 } 00565 } 00566 else{ 00567 it->second.lifetime -= 1; 00568 00569 } 00570 it++; 00571 } 00572 //debug().debug(" %i has %i entries \n",radio().id(),entries); 00573 } 00574 00575 00576 // ----------------------------------------------------------------------- 00577 00578 template<typename OsModel_P, 00579 typename RoutingTable_P, 00580 typename Radio_P, 00581 typename Debug_P> 00582 void 00583 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00584 send(node_id_t destination, size_t len, block_data_t *data) { 00585 // check for path 00586 if (route_exists(destination)) { 00587 00588 // update ttl 00589 routing_table_[destination].lifetime = ROUTE_TIMEOUT; 00590 00591 // get next hop 00592 uint8_t next_hop = routing_table_[destination].next_hop; 00593 debug().debug("%i found route for %i. next hop:[%i] %i hops away\n", radio().id(), destination, next_hop,routing_table_[destination].hop_cnt); 00594 00595 RouteDiscoveryMessage encap_message( 00596 DATA, /*msg type*/ 00597 0, /*bcast id*/ 00598 0, /*hop count*/ 00599 0, /*source seq*/ 00600 seq_numbers_[destination]/*destination seq*/, 00601 radio().id(), /*source*/ 00602 destination, /*destination*/ 00603 0/*next hop*/); 00604 // TODO do actual encapsulation :) 00605 00606 // forward data msg to next hop 00607 radio().send(next_hop, encap_message.buffer_size(), (uint8_t*) & encap_message); 00608 //update lifetime 00609 routing_table_[destination].lifetime = ROUTE_TIMEOUT; 00610 return; 00611 } else if (false/*destination is neighbor*/) { 00612 00613 RouteDiscoveryMessage encap_message( 00614 DATA, /*msg type*/ 00615 0, /*bcast id*/ 00616 0, /*hop count*/ 00617 0, /*source seq*/ 00618 seq_numbers_[destination]/*destination seq*/, 00619 radio().id(), /*source*/ 00620 destination, /*destination*/ 00621 0/*next hop*/); 00622 // TODO do actual encapsulation :) 00623 00624 // forward data msg to next hop 00625 radio().send(destination, encap_message.buffer_size(), (uint8_t*) & encap_message); 00626 ; 00627 }// init path disc 00628 else { 00629 debug().debug("%i Starting path discovery \n", radio().id()); 00630 //block_data_t tmp[len]; 00631 //memcpy(tmp, data, len); 00632 00633 RouteDiscoveryMessage stored_message( 00634 DATA, /*msg type*/ 00635 0, /*bcast id*/ 00636 0, /*hop count*/ 00637 0, /*source seq*/ 00638 seq_numbers_[destination]/*destination seq*/, 00639 radio().id(), /*source*/ 00640 destination, /*destination*/ 00641 0/*next hop*/); 00642 //TODO add actual data and timeout to this message 00643 00644 pending_msgs_[destination] = stored_message; 00645 // debug().debug("%i stored message %i to buffer \n", radio().id(), stored_message.msg_type()); 00646 00647 //TODO add new entry to pending_dest 00648 struct retry_info retry_entry; 00649 retry_entry.retries = 1; 00650 retry_entry.time = RETRY_INTERVAL; 00651 pend_dests_[destination] = retry_entry; 00652 00653 00654 RouteDiscoveryMessage message( 00655 RREQ, /*msg type*/ 00656 ++my_bcast_id_, /*bcast id*/ 00657 0, /*hop count*/ 00658 ++my_seq_nr_, /*source seq*/ 00659 seq_numbers_[destination]/*destination seq*/, 00660 radio().id(), /*source*/ 00661 destination, /*destination*/ 00662 0/*next hop*/); 00663 00664 00665 radio().send(radio().BROADCAST_ADDRESS, message.buffer_size(), (uint8_t*) & message); 00666 00667 // add my own rreq to received rreq's 00668 struct rreq_info own_rreq; 00669 own_rreq.source = radio().id(); 00670 own_rreq.bcast_id = my_bcast_id_; 00671 received_rreq_.push_back(own_rreq); 00672 00673 debug().debug("%i sent RREQ for %i \n", radio().id(), destination); 00674 00675 } 00676 } 00677 00678 //--------------------------------------------------------------------- 00679 00680 template<typename OsModel_P, 00681 typename RoutingTable_P, 00682 typename Radio_P, 00683 typename Debug_P> 00684 void 00685 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00686 proc_data(node_id_t from, RouteDiscoveryMessage& message) { 00687 debug().debug("%i received DATA message from %i \n", radio().id(), message.source()); 00688 // msg for me 00689 if (message.destination() == radio().id()) { 00690 debug().debug("%i got his DATA message msg from %i \n", radio().id(), message.source()); 00691 00692 } // destination is my neighbor 00693 else if (false) { 00694 ; 00695 00696 } // i have route to destination 00697 else if (route_exists(message.destination())) { 00698 debug().debug("%i forwards DATA message for %i. next hop [%i] %i hops away \n", radio().id(), message.destination(), routing_table_[message.destination()].next_hop, routing_table_[message.destination()].hop_cnt); 00699 //TODO update lifetime 00700 00701 00702 //forward message to next hop 00703 radio().send(routing_table_[message.destination()].next_hop, message.buffer_size(), (uint8_t*) & message); 00704 routing_table_[message.destination()].lifetime = ROUTE_TIMEOUT; 00705 } else { 00706 debug().debug("%i ERROR: no route for \n", radio().id(), message.destination()); 00707 00708 } 00709 00710 } 00711 00712 00713 // ----------------------------------------------------------------------- 00714 00715 template<typename OsModel_P, 00716 typename RoutingTable_P, 00717 typename Radio_P, 00718 typename Debug_P> 00719 void 00720 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00721 proc_rreq(node_id_t from, RouteDiscoveryMessage& message) { 00722 //debug().debug("%i received RREQ from: %i. src:%i dst:%i bcast:%i hops:%i\n", radio().id(), from, message.source(), message.destination(), message.bcast_id(),message.hop_cnt()); 00723 00724 // drop any reduntant messages 00725 for (rreq_iter_ = received_rreq_.begin(); rreq_iter_ != received_rreq_.end(); ++rreq_iter_) { 00726 if ((*rreq_iter_).source == message.source() 00727 && (*rreq_iter_).bcast_id == message.bcast_id()) { 00728 //cout << "\t\t\tDROPPED\n"; 00729 return; 00730 } 00731 } 00732 00733 // Continue with rreq processing 00734 // Record highest seq num for destination 00735 if (message.source_sequence_nr() - seq_numbers_[message.source()] > 0) { 00736 seq_numbers_[message.source()] = message.source_sequence_nr(); 00737 } 00738 00739 // add rreq to received rreq's 00740 struct rreq_info tmp_info; 00741 tmp_info.source = message.source(); 00742 tmp_info.bcast_id = message.bcast_id(); 00743 //tmp_info.lifetime = INT_MAX; 00744 received_rreq_.push_back(tmp_info); 00745 00746 00747 // add REVERSE path entry 00748 RoutingTableValue value; 00749 00750 value.destination = message.source(); 00751 value.next_hop = from; 00752 value.hop_cnt = message.hop_cnt() + 1; 00753 value.dest_seq = message.destination_sequence_nr(); 00754 value.lifetime = ROUTE_TIMEOUT; 00755 routing_table_[message.source()] = value; 00756 00757 /* debug().debug("%i added route entry %i:%i:%i:%i \n", radio().id(), 00758 routing_table_[message.source()].destination, 00759 routing_table_[message.source()].next_hop, 00760 routing_table_[message.source()].hop_cnt, 00761 routing_table_[message.source()].lifetime);*/ 00762 00763 // check if there are any pending messages for newly added entry 00764 check_pending_messages(message.source()); 00765 00766 //check if i have route for this destination 00767 RoutingTableIterator it = routing_table_.find(message.destination()); 00768 if (it != routing_table_.end()) { 00769 debug().debug("%i found route for %i via %i, %i hops away\n", radio().id(), message.destination(), it->second.next_hop, it->second.hop_cnt); 00770 //debug().debug("%i route found.\n replying with RREP to %i \n", radio().id(), message.source()); 00771 //send a route reply 00772 RouteDiscoveryMessage rrep_message( 00773 RREP, /*msg type*/ 00774 0, /*bcast id*/ 00775 it->second.hop_cnt, /*hop cnt*/ 00776 seq_numbers_[message.source()], /* source seq nr*/ 00777 0/* dest seq nr*/, 00778 radio().id(), /*source */ 00779 message.source(), /*destination*/ 00780 from/*next hop*/); 00781 radio().send(from, rrep_message.buffer_size(), (uint8_t*) & rrep_message); 00782 00783 return; 00784 } 00785 00786 // i am the destination 00787 if (message.destination() == radio().id()) { 00788 //debug().debug("%i replying with RREP to %i \n", radio().id(), message.source()); 00789 // create a rrep message 00790 RouteDiscoveryMessage rrep_message( 00791 RREP, /*msg type*/ 00792 0, /*bcast id*/ 00793 0, /*hop cnt*/ 00794 //TODO increase? 00795 ++my_seq_nr_, /* source seq nr*/ 00796 seq_numbers_[message.source()]/* dest seq nr*/, 00797 radio().id(), /*source */ 00798 message.source(), /*destination*/ 00799 from/*next hop*/); 00800 00801 // send rrep 00802 radio().send(from, rrep_message.buffer_size(), (uint8_t*) & rrep_message); 00803 00804 } // no route. re-broadcast 00805 else { 00806 debug().debug("%i forwarding RREQ from %i\n", radio().id(), message.source()); 00807 RouteDiscoveryMessage rreq_message( 00808 RREQ, /*msg type*/ 00809 message.bcast_id(), /*bcast id*/ 00810 message.hop_cnt() + 1, /*hop cnt*/ 00811 my_seq_nr_, /* source seq nr*/ 00812 seq_numbers_[message.source()]/* dest seq nr*/, 00813 message.source(), /*source */ 00814 message.destination(), /*destination*/ 00815 0/*bcast*/); 00816 radio().send(radio().BROADCAST_ADDRESS, message.buffer_size(), (uint8_t*) & rreq_message); 00817 00818 } 00819 return; 00820 } 00821 00822 00823 // ----------------------------------------------------------------------- 00824 00825 template<typename OsModel_P, 00826 typename RoutingTable_P, 00827 typename Radio_P, 00828 typename Debug_P> 00829 void 00830 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00831 proc_rrep(node_id_t from, RouteDiscoveryMessage& message) { 00832 debug().debug("%i received RREP from %i via %i\n", radio().id(), message.source(), from, message.hop_cnt()); 00833 00834 // Record highest seq number 00835 if (message.source_sequence_nr() - seq_numbers_[message.source()] > 0) { 00836 seq_numbers_[message.source()] = message.source_sequence_nr(); 00837 } 00838 00839 // add to route entry only if this is the first entry OR rrep proposes a better path 00840 // or rrep is fresher 00841 if (!route_exists(message.source()) 00842 || routing_table_[message.destination()].dest_seq < message.destination_sequence_nr() 00843 || (routing_table_[message.destination()].hop_cnt > message.hop_cnt() 00844 && routing_table_[message.destination()].dest_seq < message.destination_sequence_nr())) { 00845 00846 RoutingTableValue value; 00847 00848 value.destination = message.source(); 00849 value.next_hop = from; 00850 value.hop_cnt = message.hop_cnt() + 1; 00851 value.dest_seq = seq_numbers_[message.destination()]; 00852 value.lifetime = ROUTE_TIMEOUT; 00853 routing_table_[message.source()] = value; 00854 /* debug().debug("%i added route entry %i:%i:%i:%i \n", radio().id(), 00855 routing_table_[message.source()].destination, 00856 routing_table_[message.source()].next_hop, 00857 routing_table_[message.source()].hop_cnt, 00858 routing_table_[message.source()].lifetime);*/ 00859 00860 00861 // check if there are any pending messages for this target 00862 check_pending_messages(message.source()); 00863 00864 } 00865 // this rrep is not for me 00866 if (message.destination() != radio().id()) { 00867 // unicast using reverse path 00868 RouteDiscoveryMessage rrep_message( 00869 RREP, /*msg type*/ 00870 message.bcast_id(), /*bcast id*/ 00871 message.hop_cnt() + 1, /*hop cnt*/ 00872 my_seq_nr_, /* source seq nr*/ 00873 seq_numbers_[message.source()]/* dest seq nr*/, 00874 message.source(), /*source */ 00875 message.destination(), /*destination*/ 00876 0/*bcast*/); 00877 00878 radio().send(routing_table_[message.destination()].next_hop, rrep_message.buffer_size(), (uint8_t*) & rrep_message); 00879 } 00880 00881 return; 00882 } 00883 00884 00885 // ----------------------------------------------------------------------- 00886 00887 template<typename OsModel_P, 00888 typename RoutingTable_P, 00889 typename Radio_P, 00890 typename Debug_P> 00891 void 00892 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00893 proc_err(node_id_t from, RouteDiscoveryMessage& message) { 00894 debug().debug("%i received ERROR from %i\n", radio().id(), from); 00895 return; 00896 } 00897 00898 00899 // ----------------------------------------------------------------------- 00900 00901 template<typename OsModel_P, 00902 typename RoutingTable_P, 00903 typename Radio_P, 00904 typename Debug_P> 00905 void 00906 AODVRouting<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00907 receive(node_id_t from, size_t len, block_data_t *data) { 00908 if (from != radio().id()) { 00909 uint8_t msg_type = *data; 00910 //debug().debug("%i received msg %i \n", radio().id(), msg_type); 00911 switch (msg_type) { 00912 case HELO: 00913 { 00914 // update sender's TTL 00915 neighbors_[from] = ALLOWED_LOSS; 00916 //debug().debug("%i received beacon from %i\n", radio().id(), from); 00917 break; 00918 } 00919 00920 case RREQ: 00921 { 00922 RouteDiscoveryMessage *message = reinterpret_cast<RouteDiscoveryMessage*> (data); 00923 proc_rreq(from, *message); 00924 break; 00925 } 00926 case RREP: 00927 { 00928 RouteDiscoveryMessage *message = reinterpret_cast<RouteDiscoveryMessage*> (data); 00929 proc_rrep(from, *message); 00930 break; 00931 } 00932 case ERR: 00933 { 00934 //proc_err(from, *data); 00935 break; 00936 } 00937 case DATA: 00938 { 00939 RouteDiscoveryMessage *message = reinterpret_cast<RouteDiscoveryMessage*> (data); 00940 proc_data(from, *message); 00941 break; 00942 } 00943 default: 00944 { 00945 debug().debug("%i received UNRECOGNIZED message type [%i]\n", radio().id(), msg_type); 00946 00947 } 00948 00949 00950 } 00951 00952 } 00953 00954 } 00955 00956 00957 } 00958 #endif