Wiselib
wiselib.testing/algorithms/routing/aodv/aodv_routing.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines