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 ** Author: Juan Farré, jafarre@lsi.upc.edu ** 00020 ***************************************************************************/ 00021 #ifndef __ALGORITHMS_TOPOLOGY_XTC_TOPOLOGY_CONTROL_H__ 00022 #define __ALGORITHMS_TOPOLOGY_XTC_TOPOLOGY_CONTROL_H__ 00023 00024 #include "algorithms/topology/topology_control_base.h" 00025 #include "algorithms/topology/xtc/xtc_broadcast_message.h" 00026 #include "algorithms/topology/xtc/xtc_order_message.h" 00027 #include "algorithms/topology/xtc/xtc_types.h" 00028 #include "util/pstl/algorithm.h" 00029 #include "util/pstl/pair.h" 00030 #include "util/pstl/vector_static.h" 00031 00032 namespace wiselib { 00033 00034 #define DELTA_DEF 60000 00035 00041 template<class OsModel_P, typename OsModel_P::size_t MAX_NODES = 32, 00042 class Radio_P = typename OsModel_P::Radio, 00043 class Timer_P = typename OsModel_P::Timer> 00044 class XTCProtocol: 00045 public TopologyBase<OsModel_P> 00046 { 00047 public: 00048 typedef OsModel_P OsModel; 00049 typedef Radio_P Radio; 00050 typedef Timer_P Timer; 00051 #ifdef DEBUG 00052 typedef typename OsModel_P::Debug Debug; 00053 #endif 00054 00055 typedef XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P> self_type; 00056 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::ExtendedData ExtendedData; 00061 00062 typedef typename Timer::millis_t millis_t; 00063 struct Neighbor; 00064 typedef vector_static<OsModel,Neighbor,MAX_NODES> Order; 00065 typedef vector_static<OsModel,node_id_t,MAX_NODES> Neighbors; 00066 typedef Neighbors VOrders[MAX_NODES]; 00067 00070 XTCProtocol(); 00072 00075 void enable(); 00076 void disable(); 00078 00079 Neighbors &topology(); 00080 00083 void timer0( void * const userdata ); 00084 void timer1( void * const userdata ); 00085 void timer2( void * const userdata ); 00086 void timer3( void * const userdata ); 00088 00091 void receive( node_id_t from, size_t len, block_data_t *data, ExtendedData const &ext ); 00093 00094 void set_delta(millis_t const delta=s_delta_def) { 00095 if(!d_enabled) 00096 d_delta=delta; 00097 } 00098 00099 millis_t delta() const { 00100 return d_delta; 00101 } 00102 00103 static void set_default_delta(millis_t const delta=DELTA_DEF) { 00104 s_delta_def=delta; 00105 } 00106 00107 static millis_t default_delta() { 00108 return s_delta_def; 00109 } 00110 00111 #ifdef DEBUG 00112 void init( Radio& radio, Timer& timer, Debug& debug ) { 00113 radio_ = &radio; 00114 timer_ = &timer; 00115 debug_ = &debug; 00116 } 00117 #else 00118 void init( Radio& radio, Timer& timer) { 00119 radio_ = &radio; 00120 timer_ = &timer; 00121 } 00122 #endif 00123 00124 void destruct() { 00125 } 00126 00127 private: 00128 Radio& radio() 00129 { return *radio_;} 00130 00131 Timer& timer() 00132 { return *timer_;} 00133 00134 #ifdef DEBUG 00135 Debug& debug() 00136 { return *debug_;} 00137 #endif 00138 00139 Radio * radio_; 00140 Timer * timer_; 00141 #ifdef DEBUG 00142 Debug * debug_; 00143 #endif 00144 00145 static millis_t s_delta_def; 00146 bool d_enabled; 00147 millis_t d_delta; 00148 00149 Order order; 00150 Neighbors neighbors; 00151 VOrders vorders; 00152 XTCOrderMessage<OsModel,MAX_NODES,Radio> msg; 00153 XTCBroadcastMessage<OsModel,Radio> broadcast; 00154 }; 00155 // ----------------------------------------------------------------------- 00156 template<class OsModel_P, 00157 typename OsModel_P::size_t MAX_NODES, 00158 class Radio_P, 00159 class Timer_P> 00160 typename Timer_P::millis_t XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::s_delta_def=DELTA_DEF; 00161 // ----------------------------------------------------------------------- 00162 template<class OsModel_P, 00163 typename OsModel_P::size_t MAX_NODES, 00164 class Radio_P, 00165 class Timer_P> 00166 struct XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::Neighbor { 00167 node_id_t id; 00168 uint16_t lqi; 00169 00170 Neighbor(): 00171 id(Radio::NULL_NODE_ID) 00172 ,lqi(0xffff) {} 00173 00174 Neighbor(node_id_t n,uint16_t q): 00175 id(n) 00176 ,lqi(q) {} 00177 00178 bool operator< (Neighbor const &n) const { 00179 return lqi<n.lqi; 00180 } 00181 }; 00182 // ----------------------------------------------------------------------- 00183 template<class OsModel_P, 00184 typename OsModel_P::size_t MAX_NODES, 00185 class Radio_P, 00186 class Timer_P> 00187 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>:: 00188 XTCProtocol() 00189 : d_enabled(false), 00190 d_delta(s_delta_def) 00191 { 00192 } 00193 // ----------------------------------------------------------------------- 00194 template<class OsModel_P, 00195 typename OsModel_P::size_t MAX_NODES, 00196 class Radio_P, 00197 class Timer_P> 00198 void 00199 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>:: 00200 enable( void ) 00201 { 00202 order.clear(); 00203 neighbors.clear(); 00204 for(size_t i=0;i<MAX_NODES;i++) 00205 vorders[i].clear(); 00206 d_enabled=true; 00207 radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00208 timer().template set_timer<self_type, &self_type::timer0>( 00209 delta(), this, 0 ); 00210 #ifdef DEBUG 00211 debug().debug( "XTCProtocol Boots for %i\n", radio().id() ); 00212 #endif 00213 } 00214 // ----------------------------------------------------------------------- 00215 template<class OsModel_P, 00216 typename OsModel_P::size_t MAX_NODES, 00217 class Radio_P, 00218 class Timer_P> 00219 void 00220 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>:: 00221 disable( void ) 00222 { 00223 d_enabled=false; 00224 #ifdef DEBUG 00225 debug().debug( "Called XTCProtocol::disable\n" ); 00226 #endif 00227 } 00228 // ----------------------------------------------------------------------- 00229 template<class OsModel_P, 00230 typename OsModel_P::size_t MAX_NODES, 00231 class Radio_P, 00232 class Timer_P> 00233 typename XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::Neighbors & 00234 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::topology() 00235 { 00236 return neighbors; 00237 } 00238 // ----------------------------------------------------------------------- 00239 template<class OsModel_P, 00240 typename OsModel_P::size_t MAX_NODES, 00241 class Radio_P, 00242 class Timer_P> 00243 void 00244 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>:: 00245 timer0( void* userdata ) 00246 { 00247 #ifdef DEBUG 00248 debug().debug( "Timer0 elapsed\n"); 00249 #endif 00250 if(!d_enabled) 00251 return; 00252 broadcast.set_msg_id(XTCBroadcastMsgId); 00253 radio().send( radio().BROADCAST_ADDRESS, broadcast.buffer_size(), broadcast.buf() ); 00254 timer().template set_timer<self_type, &self_type::timer1>( 00255 delta(), this, 0 ); 00256 #ifdef DEBUG 00257 debug().debug( "Broadcast message sent\n"); 00258 #endif 00259 } 00260 00261 template<class OsModel_P, 00262 typename OsModel_P::size_t MAX_NODES, 00263 class Radio_P, 00264 class Timer_P> 00265 void 00266 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>:: 00267 timer1( void* userdata ) 00268 { 00269 #ifdef DEBUG 00270 debug().debug( "Timer1 elapsed\n"); 00271 #endif 00272 if(!d_enabled) 00273 return; 00274 insertion_sort(order.begin(),order.end()); 00275 timer().template set_timer<self_type, &self_type::timer2>( 00276 delta(), this, 0 ); 00277 #ifdef DEBUG 00278 debug().debug( "Neighbor order generated\n"); 00279 #endif 00280 } 00281 00282 template<class OsModel_P, 00283 typename OsModel_P::size_t MAX_NODES, 00284 class Radio_P, 00285 class Timer_P> 00286 void 00287 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>:: 00288 timer2( void* userdata ) 00289 { 00290 #ifdef DEBUG 00291 debug().debug( "Timer2 elapsed\n"); 00292 #endif 00293 if(!d_enabled) 00294 return; 00295 msg.set_msg_id(XTCOrderMsgId); 00296 for(size_t i=0;i<order.size();i++) 00297 msg.set_neighbor(i,order[i].id); 00298 msg.set_neighbor_number(order.size()); 00299 radio().send( radio().BROADCAST_ADDRESS, msg.buffer_size(), msg.buf() ); 00300 timer().template set_timer<self_type, &self_type::timer3>( 00301 delta(), this, 0 ); 00302 #ifdef DEBUG 00303 debug().debug( "Order message sent\n"); 00304 #endif 00305 } 00306 00307 template<class OsModel_P, 00308 typename OsModel_P::size_t MAX_NODES, 00309 class Radio_P, 00310 class Timer_P> 00311 void 00312 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>:: 00313 timer3( void* userdata ) 00314 { 00315 typedef typename Order::iterator NeighIterator; 00316 typedef typename Neighbors::iterator NodeIterator; 00317 #ifdef DEBUG 00318 debug().debug( "Timer3 elapsed\n"); 00319 #endif 00320 if(!d_enabled) 00321 return; 00322 for(size_t i=0;i<order.size();i++) { 00323 NodeIterator const iu=find(vorders[i].begin(), vorders[i].end(),radio().id()); 00324 if(iu==vorders[i].end()) 00325 continue; 00326 bool insert=true; 00327 for(size_t j=0;j<i;j++) { 00328 NodeIterator const k=find(vorders[i].begin(),iu,order[j].id); 00329 if(k!=iu) { 00330 insert=false; 00331 break; 00332 } 00333 } 00334 if(insert) 00335 neighbors.push_back(order[i].id); 00336 } 00337 #ifdef DEBUG 00338 debug().debug( "Topology generated\n"); 00339 #endif 00340 TopologyBase<OsModel>::notify_listeners(); 00341 } 00342 // ----------------------------------------------------------------------- 00343 template<class OsModel_P, 00344 typename OsModel_P::size_t MAX_NODES, 00345 class Radio_P, 00346 class Timer_P> 00347 void 00348 XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>:: 00349 receive( node_id_t from, size_t len, block_data_t *data, ExtendedData const &ext ) 00350 { 00351 if(!d_enabled) 00352 return; 00353 switch(*data) { 00354 case XTCBroadcastMsgId: 00355 order.push_back(Neighbor(from,ext.link_metric())); 00356 #ifdef DEBUG 00357 debug().debug( "Broadcast message received\n"); 00358 #endif 00359 break; 00360 case XTCOrderMsgId: { 00361 size_t i; 00362 for(i=0;i<order.size()&&order[i].id!=from;i++); 00363 if(i<order.size()) { 00364 XTCOrderMessage<OsModel,MAX_NODES,Radio> *const m=reinterpret_cast<XTCOrderMessage<OsModel,MAX_NODES,Radio> *>(data); 00365 for(size_t j=0;j<m->neighbor_number();j++) 00366 vorders[i].push_back(m->neighbor(j)); 00367 } 00368 } 00369 #ifdef DEBUG 00370 debug().debug( "Order message received\n"); 00371 #endif 00372 break; 00373 } 00374 } 00375 00376 } 00377 #endif