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_BASIC_TOPOLOGY_H__ 00022 #define __ALGORITHMS_TOPOLOGY_BASIC_TOPOLOGY_H__ 00023 00024 #include "util/pstl/algorithm.h" 00025 #include "util/pstl/pair.h" 00026 #include "external_interface/external_interface.h" 00027 #include "algorithms/topology/topology_control_base.h" 00028 #include "algorithms/topology/basic_topology_broadcast_message.h" 00029 #include "algorithms/topology/basic_topology_types.h" 00030 00031 namespace wiselib { 00032 00033 #define PING_PERIOD_DEF 1000 00034 00040 template<class OsModel_P, class Neigh_P, 00041 class Radio_P = typename OsModel_P::Radio, 00042 class Timer_P = typename OsModel_P::Timer> 00043 class BasicTopology: public TopologyBase<OsModel_P> { 00044 public: 00045 typedef OsModel_P OsModel; 00046 typedef Neigh_P Neighbors; 00047 typedef Radio_P Radio; 00048 typedef Timer_P Timer; 00049 #ifdef DEBUG 00050 typedef typename OsModel_P::Debug Debug; 00051 #endif 00052 00053 typedef BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P> self_type; 00054 00055 typedef typename OsModel::Os Os; 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 00061 typedef typename Timer::millis_t millis_t; 00062 00065 BasicTopology(); 00067 00070 void enable(); 00071 void disable(); 00073 00074 Neighbors &topology(); 00075 00076 #ifdef DEBUG 00077 void init(Radio &r, Timer &t, Debug &d) { 00078 radio = &r; 00079 timer = &t; 00080 debug=&d; 00081 } 00082 #else 00083 void init(Radio &r, Timer &t) { 00084 radio = &r; 00085 timer = &t; 00086 } 00087 #endif 00088 00089 void set_ping_period(register millis_t const period = s_period_def) { 00090 if (!d_enabled) 00091 d_period = period; 00092 } 00093 00094 millis_t ping_period() const { 00095 return d_period; 00096 } 00097 00098 static void set_default_ping_period(millis_t const period = PING_PERIOD_DEF) { 00099 s_period_def = period; 00100 } 00101 00102 static millis_t default_ping_period() { 00103 return s_period_def; 00104 } 00105 00106 private: 00109 void timer_callback(void * const userdata); 00111 00114 void receive(node_id_t from, size_t len, block_data_t *data); 00116 00117 00118 bool d_enabled; 00119 millis_t d_period; 00120 00121 Neighbors neigh; 00122 Radio *radio; 00123 Timer *timer; 00124 #ifdef DEBUG 00125 Debug *debug; 00126 #endif 00127 00128 BasicTopologyBroadcastMessage<OsModel, Radio> broadcast_msg; 00129 00130 static millis_t s_period_def; 00131 }; 00132 // ----------------------------------------------------------------------- 00133 // ----------------------------------------------------------------------- 00134 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P> 00135 typename Timer_P::millis_t 00136 BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::s_period_def = 00137 PING_PERIOD_DEF; 00138 // ----------------------------------------------------------------------- 00139 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P> 00140 BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::BasicTopology() : 00141 d_enabled(false), d_period(s_period_def) { 00142 } 00143 ; 00144 // ----------------------------------------------------------------------- 00145 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P> 00146 void BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::enable(void) { 00147 #ifdef DEBUG 00148 debug->debug("Enabling BasicTopology\n"); 00149 #endif 00150 d_enabled = true; 00151 radio->template reg_recv_callback<self_type, &self_type::receive> (this); 00152 timer->template set_timer<self_type, &self_type::timer_callback> ( 00153 ping_period(), this, 0); 00154 neigh.clear(); 00155 #ifdef DEBUG 00156 debug->debug("BasicTopology Boots for %i\n", radio->id()); 00157 #endif 00158 } 00159 // ----------------------------------------------------------------------- 00160 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P> 00161 void BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::disable(void) { 00162 #ifdef DEBUG 00163 debug->debug("Called BasicTopology::disable\n"); 00164 #endif 00165 d_enabled = false; 00166 } 00167 // ----------------------------------------------------------------------- 00168 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P> 00169 typename BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::Neighbors & 00170 BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::topology() { 00171 return neigh; 00172 } 00173 // ----------------------------------------------------------------------- 00174 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P> 00175 void BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::timer_callback( 00176 void* userdata) { 00177 if (!d_enabled) 00178 return; 00179 #ifdef DEBUG 00180 debug->debug("Timer elapsed\n"); 00181 #endif 00182 broadcast_msg.set_msg_id(BasicTopologyBroadcastMsgId); 00183 radio->send(Radio::BROADCAST_ADDRESS, broadcast_msg.buffer_size(), 00184 broadcast_msg.buf()); 00185 timer->template set_timer<self_type, &self_type::timer_callback> ( 00186 ping_period(), this, 0); 00187 #ifdef DEBUG 00188 debug->debug("Broadcast message sent\n"); 00189 #endif 00190 } 00191 // ----------------------------------------------------------------------- 00192 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P> 00193 void BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::receive( 00194 node_id_t from, size_t len, block_data_t *data) { 00195 if (len == 0) 00196 return; 00197 switch (*data) { 00198 case BasicTopologyBroadcastMsgId: 00199 #ifdef DEBUG 00200 debug->debug("Broadcast message received\n"); 00201 #endif 00202 if (find(neigh.begin(), neigh.end(), from) == neigh.end()) { 00203 neigh.push_back(from); 00204 TopologyBase<OsModel>::notify_listeners(); 00205 } 00206 break; 00207 } 00208 } 00209 00210 } 00211 #endif