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 __GREEDY_H__ 00020 #define __GREEDY_H__ 00021 00022 #include "util/base_classes/routing_base.h" 00023 #include "greedy_message.h" 00024 00025 #include <string.h> 00026 00027 00028 namespace wiselib 00029 { 00039 template<typename OsModel_P, 00040 typename Node_P, 00041 typename NodeList_P, 00042 typename Timer_P = typename OsModel_P::Timer, 00043 typename Radio_P = typename OsModel_P::Radio, 00044 typename Debug_P = typename OsModel_P::Debug> 00045 class Greedy 00046 : public RoutingBase<OsModel_P, Radio_P> 00047 { 00048 public: 00049 typedef OsModel_P OsModel; 00050 typedef Radio_P Radio; 00051 typedef Debug_P Debug; 00052 typedef Node_P Node; 00053 typedef NodeList_P NodeList; 00054 typedef typename Node::NodePosition::Float Float; 00055 typedef Timer_P Timer; 00056 typedef Greedy<OsModel, Node, NodeList, Timer, Radio, Debug> self_type; 00057 typedef typename Radio::node_id_t node_id_t; 00058 typedef typename Radio::size_t size_t; 00059 typedef typename Radio::block_data_t block_data_t; 00060 typedef typename Radio::message_id_t message_id_t; 00061 typedef typename NodeList::iterator NodeList_Iterator; 00062 typedef typename Node::NodePosition Position; 00063 typedef Greedy_Message<OsModel, Node, Radio> Message; 00064 00065 // -------------------------------------------------------------------- 00066 enum SpecialNodeIds { 00067 BROADCAST_ADDRESS = Radio_P::BROADCAST_ADDRESS, 00068 NULL_NODE_ID = Radio_P::NULL_NODE_ID 00069 }; 00070 // -------------------------------------------------------------------- 00071 enum Restrictions { 00072 MAX_MESSAGE_LENGTH = Radio_P::MAX_MESSAGE_LENGTH - Message::PAYLOAD_POS 00073 }; 00074 // -------------------------------------------------------------------- 00075 00076 Greedy( node_id_t sid); 00077 ~Greedy(); 00078 00079 void enable_radio( void ); 00080 void disable_radio( void ); 00081 00082 void send( node_id_t receiver, size_t len, block_data_t *data, message_id_t msg_id, Node n ); 00083 00084 void receive( node_id_t from, size_t len, block_data_t *data ); 00085 00086 void send_neighbor_discovery( void* userdata ); 00087 00088 void send_greedily( void* userdata); 00089 00090 node_id_t greedy_recipient() 00091 { 00092 Node current_greedy_recipient = self; 00093 Node prospective_greedy_recipient; 00094 00095 double current_closest_distance = distsq( destination, current_greedy_recipient.position ); 00096 double prospective_closest_distance; 00097 00098 for ( NodeList_Iterator neighbors_iterator = neighbors.begin(); neighbors_iterator != neighbors.end(); ++neighbors_iterator ) 00099 { 00100 prospective_greedy_recipient = *neighbors_iterator; 00101 prospective_closest_distance = distsq( destination, prospective_greedy_recipient.position ); 00102 00103 if ( prospective_closest_distance < current_closest_distance ) 00104 { 00105 current_closest_distance = prospective_closest_distance; 00106 current_greedy_recipient = prospective_greedy_recipient; 00107 } 00108 } 00109 return current_greedy_recipient.id; 00110 }; 00111 00112 void print_neighbors( void* userdata); 00113 00114 NodeList neighbors; 00115 Node self; 00116 node_id_t sender_id; 00117 Position destination; 00118 00119 void init( Radio& radio, Timer& timer, Debug& debug ) { 00120 radio_ = &radio; 00121 timer_ = &timer; 00122 debug_ = &debug; 00123 } 00124 00125 void destruct() { 00126 } 00127 00128 typename Radio::node_id_t id() 00129 { 00130 return radio_->id(); 00131 }; 00132 00133 private: 00134 Radio& radio() 00135 { return *radio_; } 00136 00137 Timer& timer() 00138 { return *timer_; } 00139 00140 Debug& debug() 00141 { return *debug_; } 00142 00143 Radio * radio_; 00144 Timer * timer_; 00145 Debug * debug_; 00146 00147 00148 enum MessageIds 00149 { 00150 NEIGHBOR_DISCOVERY_MSG_ID, 00151 GREEDY_MSG_ID 00152 }; 00153 00154 int callback_id_; 00155 00156 }; 00157 template<typename OsModel_P, 00158 typename Node_P, 00159 typename NodeList_P, 00160 typename Timer_P, 00161 typename Radio_P, 00162 typename Debug_P> 00163 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00164 Greedy( node_id_t sid) 00165 : callback_id_ ( 0 ) 00166 { 00167 sender_id = sid; 00168 } 00169 // ----------------------------------------------------------------------- 00170 template<typename OsModel_P, 00171 typename Node_P, 00172 typename NodeList_P, 00173 typename Timer_P, 00174 typename Radio_P, 00175 typename Debug_P> 00176 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00177 ~Greedy() 00178 {} 00179 // ----------------------------------------------------------------------- 00180 template<typename OsModel_P, 00181 typename Node_P, 00182 typename NodeList_P, 00183 typename Timer_P, 00184 typename Radio_P, 00185 typename Debug_P> 00186 void 00187 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00188 enable_radio( void ) 00189 { 00190 radio().enable; 00191 self.id = radio().id; 00192 //debug().debug( "Greedy %i: Boot \n", self.id ); 00193 callback_id_ = radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00194 timer().template set_timer<self_type, &self_type::send_neighbor_discovery>( 10000, this, 0 ); 00195 if ( sender_id == self.id ) 00196 { 00197 timer().template set_timer<self_type, &self_type::send_greedily>( 15000, this, 0 ); 00198 } 00199 } 00200 // ----------------------------------------------------------------------- 00201 template<typename OsModel_P, 00202 typename Node_P, 00203 typename NodeList_P, 00204 typename Timer_P, 00205 typename Radio_P, 00206 typename Debug_P> 00207 void 00208 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00209 disable_radio( void ) 00210 { 00211 //debug().debug( "Greedy %i: Disable \n", self.id ); 00212 radio().unreg_recv_callback( callback_id_ ); 00213 radio().disable; 00214 } 00215 // ----------------------------------------------------------------------- 00216 template<typename OsModel_P, 00217 typename Node_P, 00218 typename NodeList_P, 00219 typename Timer_P, 00220 typename Radio_P, 00221 typename Debug_P> 00222 void 00223 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00224 send( node_id_t destination, size_t len, block_data_t *data, message_id_t msg_id, Node n ) 00225 { 00226 //debug().debug( "Greedy %i : Send \n", self.id ); 00227 Message message; 00228 message.set_msg_id( msg_id ); 00229 message.set_node( n ); 00230 message.set_payload( len, data ); 00231 radio().send( destination, message.buffer_size(), (block_data_t*)&message ); 00232 } 00233 // ----------------------------------------------------------------------- 00234 template<typename OsModel_P, 00235 typename Node_P, 00236 typename NodeList_P, 00237 typename Timer_P, 00238 typename Radio_P, 00239 typename Debug_P> 00240 void 00241 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00242 receive( node_id_t from, size_t len, block_data_t *data ) 00243 { 00244 //debug().debug( "Greedy %i : Receive \n", self.id ); 00245 Message* message = (Message*)data; 00246 if ( message->msg_id() == NEIGHBOR_DISCOVERY_MSG_ID ) 00247 { 00248 NodeList_Iterator neighbors_iterator = neighbors.begin(); 00249 uint8_t found = 0; 00250 while ( neighbors_iterator!=neighbors.end() && found == 0 ) 00251 { 00252 if ( neighbors_iterator->id == message->node().id ) 00253 { 00254 found = 1; 00255 } 00256 if ( found == 0 ){ ++neighbors_iterator; } 00257 } 00258 if ( found == 1 ) 00259 { 00260 neighbors.erase( neighbors_iterator ); 00261 } 00262 neighbors.push_back( message->node() ); 00263 } 00264 else if ( message->msg_id() == GREEDY_MSG_ID ) 00265 { 00266 debug().debug( "Greedy %i : Receive Greedy from %i \n", self.id, from, message->node().position.x , message->node().position.y ); 00267 destination = message->node().position; 00268 send_greedily(NULL); 00269 } 00270 notify_receivers( from, message->payload_size(), message->payload() ); 00271 } 00272 // ----------------------------------------------------------------------- 00273 template<typename OsModel_P, 00274 typename Node_P, 00275 typename NodeList_P, 00276 typename Timer_P, 00277 typename Radio_P, 00278 typename Debug_P> 00279 void 00280 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00281 send_neighbor_discovery( void* userdata) 00282 { 00283 //debug().debug( "Greedy %i : Send neighbor discovery message \n", self.id ); 00284 block_data_t bd[1]; 00285 bd[0] = 'n'; 00286 send( radio().BROADCAST_ADDRESS,1, bd, NEIGHBOR_DISCOVERY_MSG_ID, self ); 00287 } 00288 // ----------------------------------------------------------------------- 00289 template<typename OsModel_P, 00290 typename Node_P, 00291 typename NodeList_P, 00292 typename Timer_P, 00293 typename Radio_P, 00294 typename Debug_P> 00295 void 00296 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00297 send_greedily( void* userdata) 00298 { 00299 node_id_t rec_id = greedy_recipient(); 00300 if (rec_id != self.id) 00301 { 00302 debug().debug( "Greedy %i : Send greedily to %i \n", self.id, rec_id ); 00303 Node dest; 00304 dest.position = destination; 00305 block_data_t bd[1]; 00306 bd[0] = 'g'; 00307 send( greedy_recipient(), 1, bd, GREEDY_MSG_ID, dest ); 00308 } 00309 } 00310 00311 // ----------------------------------------------------------------------- 00312 template<typename OsModel_P, 00313 typename Node_P, 00314 typename NodeList_P, 00315 typename Timer_P, 00316 typename Radio_P, 00317 typename Debug_P> 00318 void 00319 Greedy<OsModel_P, Node_P, NodeList_P, Timer_P, Radio_P, Debug_P>:: 00320 print_neighbors( void* userdata) 00321 { 00322 debug().debug( "Greedy %i : Begin Neighbor printout \n", self.id ); 00323 for ( NodeList_Iterator neighbors_iterator = neighbors.begin(); neighbors_iterator != neighbors.end(); ++neighbors_iterator ) 00324 { 00325 debug().debug( "--- neighbor: id = %i, position = ( %i, %i, %i ) \n", neighbors_iterator->id, neighbors_iterator->position.x, neighbors_iterator->position.y, neighbors_iterator->position.z ); 00326 } 00327 debug().debug( "Greedy %i : End Neighbor printout \n", self.id ); 00328 } 00329 00330 } 00331 #endif