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_DSR_ROUTING_H__ 00020 #define __ALGORITHMS_ROUTING_DSR_ROUTING_H__ 00021 00022 #include "algorithms/routing/dsr/dsr_routing_types.h" 00023 #include "algorithms/routing/dsr/dsr_route_discovery_msg.h" 00024 #include "algorithms/routing/dsr/dsr_routing_msg.h" 00025 #include "util/base_classes/routing_base.h" 00026 #include "config.h" 00027 #include <string.h> 00028 00029 00030 namespace wiselib 00031 { 00032 00043 template<typename OsModel_P, 00044 typename RoutingTable_P, 00045 typename Radio_P = typename OsModel_P::Radio> 00046 // typename Timer_P = typename OsModel_P::Timer, 00047 // typename Debug_P = typename OsModel_P::Debug> 00048 class DsrRouting 00049 : public RoutingBase<OsModel_P, Radio_P> 00050 { 00051 public: 00052 typedef OsModel_P OsModel; 00053 typedef Radio_P Radio; 00054 typedef typename OsModel::Timer Timer; 00055 typedef typename OsModel::Debug Debug; 00056 00057 typedef RoutingTable_P RoutingTable; 00058 typedef typename RoutingTable::iterator RoutingTableIterator; 00059 typedef typename RoutingTable::mapped_type RoutingTableValue; 00060 typedef typename RoutingTable::value_type RoutingTableEntry; 00061 00062 typedef typename RoutingTableValue::Path Path; 00063 typedef typename Path::iterator PathIterator; 00064 00065 typedef DsrRouting<OsModel, RoutingTable, Radio> self_type; 00066 typedef self_type* self_pointer_t; 00067 00068 typedef typename Radio::node_id_t node_id_t; 00069 typedef typename Radio::size_t size_t; 00070 typedef typename Radio::block_data_t block_data_t; 00071 typedef typename Radio::message_id_t message_id_t; 00072 00073 typedef typename Timer::millis_t millis_t; 00074 00075 typedef DsrRouteDiscoveryMessage<OsModel, Radio, Path> RouteDiscoveryMessage; 00076 typedef DsrRoutingMessage<OsModel, Radio, Path> RoutingMessage; 00077 // -------------------------------------------------------------------- 00078 enum ErrorCodes 00079 { 00080 SUCCESS = OsModel::SUCCESS, 00081 ERR_UNSPEC = OsModel::ERR_UNSPEC, 00082 ERR_NOTIMPL = OsModel::ERR_NOTIMPL, 00083 ERR_BUSY = OsModel::ERR_BUSY 00084 }; 00085 // -------------------------------------------------------------------- 00086 enum SpecialNodeIds { 00087 BROADCAST_ADDRESS = Radio_P::BROADCAST_ADDRESS, 00088 NULL_NODE_ID = Radio_P::NULL_NODE_ID 00089 }; 00090 // -------------------------------------------------------------------- 00091 enum Restrictions { 00092 MAX_MESSAGE_LENGTH = Radio_P::MAX_MESSAGE_LENGTH 00093 }; 00094 // -------------------------------------------------------------------- 00097 DsrRouting(); 00098 ~DsrRouting(); 00100 00101 int init( Radio& radio, Timer& timer, Debug& debug ) 00102 { 00103 radio_ = &radio; 00104 timer_ = &timer; 00105 debug_ = &debug; 00106 return SUCCESS; 00107 } 00108 00109 inline int init(); 00110 inline int destruct(); 00111 00114 int enable_radio( void ); 00115 int disable_radio( void ); 00117 00120 void timer_elapsed( void *userdata ); 00122 00125 00127 int send( node_id_t receiver, size_t len, block_data_t *data ); 00130 void receive( node_id_t from, size_t len, block_data_t *data ); 00133 typename Radio::node_id_t id() 00134 { return radio_->id(); } 00136 00137 private: 00138 00139 Radio& radio() 00140 { return *radio_; } 00141 00142 Timer& timer() 00143 { return *timer_; } 00144 00145 Debug& debug() 00146 { return *debug_; } 00147 00148 typename Radio::self_pointer_t radio_; 00149 typename Timer::self_pointer_t timer_; 00150 typename Debug::self_pointer_t debug_; 00151 00152 uint16_t seq_nr_; 00153 00154 bool send_in_progress_; 00155 00156 RoutingTable routing_table_; 00157 RoutingMessage routing_message_; 00158 00159 void handle_route_request( node_id_t from, RouteDiscoveryMessage& message ); 00160 void handle_route_reply( node_id_t from, RouteDiscoveryMessage& message ); 00161 void handle_routing_message( node_id_t from, size_t len, RoutingMessage& message ); 00162 00163 void update_seq_nr( node_id_t node, uint16_t seq_nr ); 00164 uint16_t get_seq_nr( node_id_t node ); 00165 00166 void print_path( Path& path ); 00167 }; 00168 // ----------------------------------------------------------------------- 00169 // ----------------------------------------------------------------------- 00170 // ----------------------------------------------------------------------- 00171 template<typename OsModel_P, 00172 typename RoutingTable_P, 00173 typename Radio_P> 00174 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00175 DsrRouting() 00176 : seq_nr_ ( 1 ), 00177 send_in_progress_ ( false ) 00178 {} 00179 // ----------------------------------------------------------------------- 00180 template<typename OsModel_P, 00181 typename RoutingTable_P, 00182 typename Radio_P> 00183 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00184 ~DsrRouting() 00185 { 00186 #ifdef ROUTING_DSR_DEBUG 00187 debug().debug( "DsrRouting: Destroyed\n" ); 00188 #endif 00189 } 00190 // ----------------------------------------------------------------------- 00191 template<typename OsModel_P, 00192 typename RoutingTable_P, 00193 typename Radio_P> 00194 int 00195 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00196 init( void ) 00197 { 00198 routing_table_.clear(); 00199 routing_message_ = RoutingMessage(); 00200 seq_nr_ = 1; 00201 send_in_progress_ = false; 00202 00203 enable_radio(); 00204 00205 return SUCCESS; 00206 } 00207 // ----------------------------------------------------------------------- 00208 template<typename OsModel_P, 00209 typename RoutingTable_P, 00210 typename Radio_P> 00211 int 00212 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00213 destruct( void ) 00214 { 00215 return disable_radio(); 00216 } 00217 // ----------------------------------------------------------------------- 00218 template<typename OsModel_P, 00219 typename RoutingTable_P, 00220 typename Radio_P> 00221 int 00222 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00223 enable_radio( void ) 00224 { 00225 #ifdef ROUTING_DSR_DEBUG 00226 debug().debug( "DsrRouting: Boot for %d\n", radio().id() ); 00227 #endif 00228 00229 radio().enable_radio(); 00230 radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00231 00232 timer().template set_timer<self_type, &self_type::timer_elapsed>( 00233 15000, this, 0 ); 00234 00235 return SUCCESS; 00236 } 00237 // ----------------------------------------------------------------------- 00238 template<typename OsModel_P, 00239 typename RoutingTable_P, 00240 typename Radio_P> 00241 int 00242 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00243 disable_radio( void ) 00244 { 00245 #ifdef ROUTING_DSR_DEBUG 00246 debug().debug( "DsrRouting: Disable\n" ); 00247 #endif 00248 return ERR_NOTIMPL; 00249 } 00250 // ----------------------------------------------------------------------- 00251 template<typename OsModel_P, 00252 typename RoutingTable_P, 00253 typename Radio_P> 00254 void 00255 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00256 timer_elapsed( void *userdata ) 00257 { 00258 timer().template set_timer<self_type, &self_type::timer_elapsed>( 00259 15000, this, 0 ); 00260 } 00261 // ----------------------------------------------------------------------- 00262 template<typename OsModel_P, 00263 typename RoutingTable_P, 00264 typename Radio_P> 00265 int 00266 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00267 send( node_id_t destination, size_t len, block_data_t *data ) 00268 { 00269 // waiting for route reply - cannot store another routing message 00270 if ( send_in_progress_ ) 00271 return ERR_BUSY; 00272 00273 routing_message_ = RoutingMessage( DsrRoutingMsgId, radio().id(), destination, 1, len, data ); 00274 00275 RoutingTableIterator it = routing_table_.find( destination ); 00276 if ( it != routing_table_.end() ) 00277 { 00278 routing_message_.set_path( it->second.path ); 00279 radio().send( it->second.path[1], routing_message_.buffer_size(), (uint8_t*)&routing_message_ ); 00280 #ifdef ROUTING_DSR_DEBUG 00281 debug().debug( "DsrRouting: Existing path in Cache with size %d hops %d idx %d\n", 00282 it->second.path.size(), it->second.hops, routing_message_.path_idx() ); 00283 print_path( it->second.path ); 00284 #endif 00285 } 00286 else 00287 { 00288 send_in_progress_ = true; 00289 RouteDiscoveryMessage message( DsrRouteRequestMsgId, 00290 0, // hops 00291 seq_nr_++, 00292 radio().id(), 00293 destination, 00294 0 ); // path idx - not needed when sending request 00295 Path path; 00296 path.push_back( radio().id() ); 00297 message.set_path( path ); 00298 00299 radio().send( Radio::BROADCAST_ADDRESS, message.buffer_size(), (uint8_t*)&message ); 00300 #ifdef ROUTING_DSR_DEBUG 00301 debug().debug( "DsrRouting: Start Route Request from %d to %d.\n", message.source(), message.destination() ); 00302 #endif 00303 } 00304 00305 return SUCCESS; 00306 } 00307 // ----------------------------------------------------------------------- 00308 template<typename OsModel_P, 00309 typename RoutingTable_P, 00310 typename Radio_P> 00311 void 00312 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00313 receive( node_id_t from, size_t len, block_data_t *data ) 00314 { 00315 message_id_t msg_id = read<OsModel, block_data_t, message_id_t>( data ); 00316 if ( msg_id == DsrRouteRequestMsgId ) 00317 { 00318 RouteDiscoveryMessage *message = reinterpret_cast<RouteDiscoveryMessage*>(data); 00319 handle_route_request( from, *message ); 00320 } 00321 else if ( msg_id == DsrRouteReplyMsgId ) 00322 { 00323 RouteDiscoveryMessage *message = reinterpret_cast<RouteDiscoveryMessage*>(data); 00324 handle_route_reply( from, *message ); 00325 } 00326 else if ( msg_id == DsrRoutingMsgId ) 00327 { 00328 RoutingMessage *message = reinterpret_cast<RoutingMessage*>(data); 00329 handle_routing_message( from, len, *message ); 00330 } 00331 } 00332 // ----------------------------------------------------------------------- 00333 template<typename OsModel_P, 00334 typename RoutingTable_P, 00335 typename Radio_P> 00336 void 00337 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00338 handle_route_request( node_id_t from, RouteDiscoveryMessage& message ) 00339 { 00340 if ( get_seq_nr(message.source()) >= message.sequence_nr() ) 00341 { 00342 #ifdef ROUTING_DSR_DEBUG 00343 // debug().debug( "DsrRouting: Seq nr %d in RReq at %d from %d (to %d) is known.\n", 00344 // message.sequence_nr(), radio().id(), 00345 // message.source(), message.destination() ); 00346 #endif 00347 return; 00348 } 00349 update_seq_nr( message.source(), message.sequence_nr() ); 00350 00351 if ( message.destination() == radio().id() ) 00352 { 00353 RouteDiscoveryMessage msg(message); 00354 msg.set_msg_id( DsrRouteReplyMsgId ); 00355 msg.set_hops( msg.hops() + 1 ); 00356 00357 Path path; 00358 msg.path( path ); 00359 path.push_back( radio().id() ); 00360 msg.set_path( path ); 00361 00362 radio().send( path[msg.path_idx()], msg.buffer_size(), (uint8_t*)&msg ); 00363 #ifdef ROUTING_DSR_DEBUG 00364 debug().debug( "DsrRouting: Reply to RREQ with size %d, hops %d; idx %d\n", path.size(), msg.hops(), msg.path_idx() ); 00365 print_path(path); 00366 debug().debug( "DsrRouting: Route Request from %d at destination %d, send back route reply over %d\n", 00367 msg.source(), 00368 msg.destination(), 00369 path[msg.path_idx()] ); 00370 #endif 00371 } 00372 else 00373 { 00374 RouteDiscoveryMessage msg(message); 00375 Path path; 00376 msg.path( path ); 00377 path.push_back( radio().id() ); 00378 msg.inc_path_idx(); 00379 msg.set_hops( msg.hops() + 1 ); 00380 msg.set_path( path ); 00381 radio().send( Radio::BROADCAST_ADDRESS, msg.buffer_size(), (uint8_t*)&msg ); 00382 #ifdef ROUTING_DSR_DEBUG 00383 // debug().debug( "DsrRouting: Forward RREQ at %d (from %d to %d) with idx %d (size %d).\n", 00384 // radio().id(), message.source(), message.destination(), message.path_idx(), path.size() ); 00385 // print_path( path ); 00386 #endif 00387 } 00388 } 00389 // ----------------------------------------------------------------------- 00390 template<typename OsModel_P, 00391 typename RoutingTable_P, 00392 typename Radio_P> 00393 void 00394 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00395 handle_route_reply( node_id_t from, RouteDiscoveryMessage& message ) 00396 { 00397 if ( message.source() == radio().id() ) 00398 { 00399 #ifdef ROUTING_DSR_DEBUG 00400 debug().debug( "DsrRouting: RREP -> HOME at %d from %d\n", 00401 message.source(), message.destination() ); 00402 #endif 00403 routing_message_.set_path_idx( 1 ); 00404 Path path; 00405 message.path( path ); 00406 routing_message_.set_path( path ); 00407 00408 RoutingTableValue value; 00409 value.path = path; 00410 value.hops = message.hops(); 00411 value.seq_nr = message.sequence_nr(); 00412 routing_table_[message.destination()] = value; 00413 00414 radio().send( path[routing_message_.path_idx()], 00415 routing_message_.buffer_size(), 00416 (uint8_t*)&routing_message_ ); 00417 send_in_progress_ = false; 00418 #ifdef ROUTING_DSR_DEBUG 00419 debug().debug( "DsrRouting: Routing message with size %d hops %d idx %d (next hop %d)\n", 00420 path.size(), message.hops(), routing_message_.path_idx(), path[routing_message_.path_idx()] ); 00421 print_path(path); 00422 #endif 00423 } 00424 else 00425 { 00426 message.dec_path_idx(); 00427 Path path; 00428 message.path( path ); 00429 radio().send( path[message.path_idx()], message.buffer_size(), (uint8_t*)(&message) ); 00430 #ifdef ROUTING_DSR_DEBUG 00431 debug().debug( "DsrRouting: Forward RREP at %d to %d (from %d to %d).\n", 00432 radio().id(), 00433 path[message.path_idx()], 00434 message.source(), 00435 message.destination() ); 00436 print_path(path); 00437 #endif 00438 } 00439 } 00440 // ----------------------------------------------------------------------- 00441 template<typename OsModel_P, 00442 typename RoutingTable_P, 00443 typename Radio_P> 00444 void 00445 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00446 handle_routing_message( node_id_t from, size_t len, RoutingMessage& message ) 00447 { 00448 if ( message.destination() == radio().id() ) 00449 { 00450 #ifdef ROUTING_DSR_DEBUG 00451 debug().debug( "DsrRouting: DELIVERED Dsr-Routing-Message at %d from %d\n", 00452 radio().id(), message.source() ); 00453 #endif 00454 notify_receivers( message.source(), message.payload_size(), message.payload() ); 00455 } 00456 else 00457 { 00458 RoutingMessage msg( message ); 00459 Path path; 00460 message.path( path ); 00461 msg.inc_path_idx(); 00462 00463 radio().send( path[msg.path_idx()], len, (uint8_t*)&msg ); 00464 #ifdef ROUTING_DSR_DEBUG 00465 debug().debug( "DsrRouting: Forward RoutingMsg at %d to %d with path idx %d (from %d to %d).\n", 00466 radio().id(), 00467 path[msg.path_idx()], msg.path_idx(), 00468 msg.source(), msg.destination() ); 00469 #endif 00470 } 00471 } 00472 // ----------------------------------------------------------------------- 00473 template<typename OsModel_P, 00474 typename RoutingTable_P, 00475 typename Radio_P> 00476 void 00477 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00478 update_seq_nr( node_id_t node, uint16_t seq_nr ) 00479 { 00480 RoutingTableIterator it = routing_table_.find( node ); 00481 if ( it != routing_table_.end() ) 00482 { 00483 it->second.seq_nr = seq_nr; 00484 } 00485 else 00486 { 00487 RoutingTableValue entry; 00488 entry.hops = 0; 00489 entry.seq_nr = seq_nr; 00490 routing_table_[node] = entry; 00491 } 00492 } 00493 // ----------------------------------------------------------------------- 00494 template<typename OsModel_P, 00495 typename RoutingTable_P, 00496 typename Radio_P> 00497 uint16_t 00498 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00499 get_seq_nr( node_id_t node ) 00500 { 00501 RoutingTableIterator it = routing_table_.find( node ); 00502 if ( it != routing_table_.end() ) 00503 return it->second.seq_nr; 00504 00505 return 0; 00506 } 00507 // ----------------------------------------------------------------------- 00508 template<typename OsModel_P, 00509 typename RoutingTable_P, 00510 typename Radio_P> 00511 void 00512 DsrRouting<OsModel_P, RoutingTable_P, Radio_P>:: 00513 print_path( Path& path ) 00514 { 00515 #ifdef ROUTING_DSR_DEBUG 00516 debug().debug( " Path" ); 00517 for ( PathIterator it = path.begin(); it != path.end(); ++it ) 00518 { 00519 debug().debug( " -> %d", *it ); 00520 } 00521 debug().debug( "\n" ); 00522 #endif 00523 } 00524 00525 } 00526 #endif