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 __STATIC_ROUTING_ALGORITHM_H__ 00020 #define __STATIC_ROUTING_ALGORITHM_H__ 00021 00022 #include "util/base_classes/routing_base.h" 00023 #include "static_routing_message.h" 00024 00025 00026 namespace wiselib 00027 { 00028 00036 template<typename OsModel_P, 00037 typename RoutingTable_P, 00038 typename Radio_P = typename OsModel_P::Radio, 00039 typename Debug_P = typename OsModel_P::Debug> 00040 class StaticRoutingAlgorithm 00041 : public RoutingBase<OsModel_P, Radio_P> 00042 { 00043 public: 00044 typedef OsModel_P OsModel; 00045 typedef Radio_P Radio; 00046 typedef Debug_P Debug; 00047 00048 typedef RoutingTable_P MapType; 00049 typedef typename MapType::iterator MapTypeIterator; 00050 00051 typedef StaticRoutingAlgorithm<OsModel, MapType, Radio, Debug> self_type; 00052 typedef self_type* self_pointer_t; 00053 00054 typedef typename Radio::node_id_t node_id_t; 00055 typedef typename Radio::size_t size_t; 00056 typedef typename Radio::block_data_t block_data_t; 00057 typedef typename Radio::message_id_t message_id_t; 00058 00059 typedef StaticRoutingMessage<OsModel, Radio> Message; 00060 // -------------------------------------------------------------------- 00061 enum ErrorCodes 00062 { 00063 SUCCESS = OsModel::SUCCESS, 00064 ERR_UNSPEC = OsModel::ERR_UNSPEC 00065 }; 00066 // -------------------------------------------------------------------- 00067 enum SpecialNodeIds 00068 { 00069 BROADCAST_ADDRESS = Radio_P::BROADCAST_ADDRESS, 00070 NULL_NODE_ID = Radio_P::NULL_NODE_ID 00071 }; 00072 // -------------------------------------------------------------------- 00073 enum Restrictions 00074 { 00075 MAX_MESSAGE_LENGTH = Radio_P::MAX_MESSAGE_LENGTH - Message::PAYLOAD_POS 00076 }; 00077 // -------------------------------------------------------------------- 00080 StaticRoutingAlgorithm(); 00081 ~StaticRoutingAlgorithm(); 00083 00084 int init( Radio& radio, Debug& debug ) 00085 { 00086 radio_ = &radio; 00087 debug_ = &debug; 00088 return SUCCESS; 00089 } 00090 00091 int init(); 00092 int destruct(); 00093 00096 int enable_radio( void ); 00097 int disable_radio( void ); 00099 00102 00104 int send( node_id_t receiver, size_t len, block_data_t *data ); 00107 void receive( node_id_t from, size_t len, block_data_t *data ); 00110 void add_hop(node_id_t from, node_id_t to); 00113 void remove_hop(node_id_t from); 00116 void set_route(node_id_t start, node_id_t end); 00119 typename Radio::node_id_t id() 00120 { return radio_->id(); } 00122 00123 private: 00124 Radio& radio() 00125 { return *radio_; } 00126 00127 Debug& debug() 00128 { return *debug_; } 00129 00130 typename Radio::self_pointer_t radio_; 00131 typename Debug::self_pointer_t debug_; 00132 00133 node_id_t route_start_; 00134 node_id_t route_end_; 00135 00136 enum MessageIds 00137 { 00138 STATIC_ROUTING_ID = 222 00139 }; 00140 00141 int callback_id_; 00142 00143 MapType hop_map_; 00144 }; 00145 // ----------------------------------------------------------------------- 00146 // ----------------------------------------------------------------------- 00147 // ----------------------------------------------------------------------- 00148 template<typename OsModel_P, 00149 typename RoutingTable_P, 00150 typename Radio_P, 00151 typename Debug_P> 00152 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00153 StaticRoutingAlgorithm() 00154 : callback_id_ ( 0 ) 00155 {} 00156 // ----------------------------------------------------------------------- 00157 template<typename OsModel_P, 00158 typename RoutingTable_P, 00159 typename Radio_P, 00160 typename Debug_P> 00161 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00162 ~StaticRoutingAlgorithm() 00163 { 00164 #ifdef ROUTING_STATIC_DEBUG 00165 debug().debug( "StaticRoutingAlgorithm:dtor\n" ); 00166 #endif 00167 } 00168 // ----------------------------------------------------------------------- 00169 template<typename OsModel_P, 00170 typename RoutingTable_P, 00171 typename Radio_P, 00172 typename Debug_P> 00173 int 00174 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00175 init( void ) 00176 { 00177 hop_map_.clear(); 00178 enable_radio(); 00179 return SUCCESS; 00180 } 00181 // ----------------------------------------------------------------------- 00182 template<typename OsModel_P, 00183 typename RoutingTable_P, 00184 typename Radio_P, 00185 typename Debug_P> 00186 int 00187 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00188 destruct( void ) 00189 { 00190 return disable_radio(); 00191 } 00192 // ----------------------------------------------------------------------- 00193 template<typename OsModel_P, 00194 typename RoutingTable_P, 00195 typename Radio_P, 00196 typename Debug_P> 00197 int 00198 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00199 enable_radio( void ) 00200 { 00201 #ifdef ROUTING_STATIC_DEBUG 00202 debug().debug( "StaticRoutingAlgorithm: Boot for %i\n", radio().id() ); 00203 #endif 00204 00205 radio().enable_radio(); 00206 callback_id_ = radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00207 return SUCCESS; 00208 } 00209 // ----------------------------------------------------------------------- 00210 template<typename OsModel_P, 00211 typename RoutingTable_P, 00212 typename Radio_P, 00213 typename Debug_P> 00214 int 00215 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00216 disable_radio( void ) 00217 { 00218 #ifdef ROUTING_STATIC_DEBUG 00219 debug().debug( "StaticRoutingAlgorithm: Disable\n" ); 00220 #endif 00221 00222 radio().unreg_recv_callback( callback_id_ ); 00223 radio().disable(); 00224 return SUCCESS; 00225 } 00226 // ----------------------------------------------------------------------- 00227 template<typename OsModel_P, 00228 typename RoutingTable_P, 00229 typename Radio_P, 00230 typename Debug_P> 00231 int 00232 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00233 send( node_id_t destination, size_t len, block_data_t *data ) 00234 { 00235 Message message; 00236 message.set_msg_id( STATIC_ROUTING_ID ); 00237 message.set_source_id( radio().id() ); 00238 message.set_destination( destination ); 00239 message.set_payload( len, data ); 00240 00241 if(destination == route_end_ && route_start_ != radio_->id() ) 00242 { 00243 #ifdef ROUTING_STATIC_DEBUG 00244 debug().debug( "StaticRoutingAlgorithm: node %d Send to %d over %d\n", radio().id(), destination, route_start_ ); 00245 #endif 00246 radio().send( route_start_, message.buffer_size(), (block_data_t*)&message ); 00247 } 00248 else if(destination == route_end_ && route_start_ == radio_->id() ) 00249 { 00250 if ( hop_map_.find( radio().id()) == hop_map_.end() ) 00251 { 00252 debug().debug( "FATAL send: no entry for %d\n", radio().id() ); 00253 return ERR_UNSPEC; 00254 } 00255 radio().send( hop_map_[radio().id()], message.buffer_size(), (block_data_t*)&message ); 00256 } 00257 else 00258 { 00259 #ifdef ROUTING_STATIC_DEBUG 00260 debug().debug( "StaticRoutingAlgorithm: node %d Send to %d\n", radio().id(), destination ); 00261 #endif 00262 radio().send( destination, message.buffer_size(), (block_data_t*)&message ); 00263 } 00264 00265 return SUCCESS; 00266 } 00267 // ----------------------------------------------------------------------- 00268 template<typename OsModel_P, 00269 typename RoutingTable_P, 00270 typename Radio_P, 00271 typename Debug_P> 00272 void 00273 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00274 add_hop( node_id_t from, node_id_t to ) 00275 { 00276 hop_map_[from] = to; 00277 } 00278 // ----------------------------------------------------------------------- 00279 template<typename OsModel_P, 00280 typename RoutingTable_P, 00281 typename Radio_P, 00282 typename Debug_P> 00283 void 00284 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00285 remove_hop( node_id_t from ) 00286 { 00287 hop_map_.erase(from); 00288 } 00289 // ----------------------------------------------------------------------- 00290 template<typename OsModel_P, 00291 typename RoutingTable_P, 00292 typename Radio_P, 00293 typename Debug_P> 00294 void 00295 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00296 set_route( node_id_t start, node_id_t end ) 00297 { 00298 route_start_ = start; 00299 route_end_ = end; 00300 } 00301 // ----------------------------------------------------------------------- 00302 template<typename OsModel_P, 00303 typename RoutingTable_P, 00304 typename Radio_P, 00305 typename Debug_P> 00306 void 00307 StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>:: 00308 receive( node_id_t from, size_t len, block_data_t *data ) 00309 { 00310 if ( from == radio().id() ) 00311 return; 00312 00313 message_id_t msg_id = read<OsModel, block_data_t, message_id_t>( data ); 00314 if ( msg_id == STATIC_ROUTING_ID ) 00315 { 00316 #ifdef ROUTING_STATIC_DEBUG 00317 debug().debug( "StaticRoutingAlgorithm: got Message from %d on %d size: %d\n", from,radio().id(),len); 00318 #endif 00319 00320 Message *message = (Message *)data; 00321 if ( message->destination() != radio().id() ) 00322 { 00323 #ifdef ROUTING_STATIC_DEBUG 00324 debug().debug( "StaticRoutingAlgorithm: forward from node %d to node %d\n", 00325 radio().id(),hop_map_[radio().id()] ); 00326 #endif 00327 if ( hop_map_.find( radio().id()) == hop_map_.end() ) 00328 { 00329 debug().debug( "FATAL fwd: no entry for %d\n", radio().id() ); 00330 return; 00331 } 00332 radio().send( hop_map_[radio().id()], len, data ); 00333 return; 00334 } 00335 else 00336 { 00337 #ifdef ROUTING_STATIC_DEBUG 00338 debug().debug( "StaticRoutingAlgorithm: receive\n" ); 00339 #endif 00340 notify_receivers( message->source_id(), message->payload_size(), message->payload() ); 00341 return; 00342 } 00343 00344 } 00345 } 00346 00347 } 00348 #endif