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_TOPOLOGY_CBTC_TOPOLOGY_NEIGHBOURS_H__ 00020 #define __ALGORITHMS_TOPOLOGY_CBTC_TOPOLOGY_NEIGHBOURS_H__ 00021 00022 #define DEBUG_CBTC_TOPOLOGY 00023 00024 #include "util/pstl/vector_static.h" 00025 00026 namespace wiselib 00027 { 00028 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00029 class CbtcTopologyNeighbours 00030 { 00031 public: 00032 typedef OsModel_P OsModel; 00033 typedef Radio_P Radio; 00034 #ifdef DEBUG_CBTC_TOPOLOGY 00035 typedef typename OsModel::Debug Debug; 00036 #endif 00037 00038 typedef typename OsModel_P::size_t size_type; 00039 00040 typedef typename Radio::node_id_t node_id_t; 00041 00042 typedef struct triplet_t{ 00043 double angle; 00044 node_id_t id; 00045 int power; 00046 bool asymmetric; 00047 } TIPA_t; 00048 00049 typedef struct ndp_struct{ 00050 node_id_t id; 00051 int power; 00052 bool first_time_seen; 00053 uint8_t ndp_counter; 00054 } ndp_t; 00055 00056 typedef vector_static<OsModel, TIPA_t, MAX_NODES> Nodes; 00057 Nodes N; 00058 typedef normal_iterator<OsModel, TIPA_t*, Nodes> Niter; 00059 00060 //Asymmetric Nodes to be removed 00061 vector_static<OsModel, node_id_t, MAX_NODES> ATR; 00062 vector_static<OsModel, ndp_t, MAX_NODES> NDP; 00063 00064 bool first_phase_done; 00065 00066 CbtcTopologyNeighbours(); 00067 00068 inline void set_id(node_id_t id) {id_ = id; } 00069 00070 inline size_type size(){ return N.size(); } 00071 inline TIPA_t& operator[](size_type n) { return N[n];} 00072 00073 void add_update_neighbour(node_id_t id, int p, double angle, bool asymmetric); 00074 inline void delete_by_id(node_id_t id); 00075 inline void delete_by_index(size_type index); 00076 bool add_update_ndp(node_id_t id, int p, double angle); 00077 bool ndp_update(); 00078 00079 inline void delete_by_power(int p){ 00080 size_type i; 00081 for ( i = 0; i < N.size(); ++i ){ 00082 if(N[i].power == p){ 00083 delete_by_index(i); 00084 i--; 00085 } 00086 } 00087 } 00088 00089 inline void add_asymmetric_to_remove(node_id_t from){ 00090 size_type i; 00091 for(i = 0; i < ATR.size(); i++) 00092 if(ATR[i] == from) 00093 break; 00094 00095 if(i == ATR.size()) 00096 ATR.push_back(from); 00097 } 00098 00099 inline void copy_to_NDP(); 00100 00101 #ifdef DEBUG_CBTC_TOPOLOGY 00102 inline void print_basic(); 00103 inline void print_optimization(const char *s); 00104 #endif 00105 00106 private: 00107 node_id_t id_; 00108 }; 00109 00110 // ----------------------------------------------------------------------- 00111 // ----------------------------------------------------------------------- 00112 // ----------------------------------------------------------------------- 00113 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00114 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00115 CbtcTopologyNeighbours() 00116 { 00117 first_phase_done = false; 00118 }; 00119 00120 00121 // ----------------------------------------------------------------------- 00122 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00123 void 00124 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00125 add_update_neighbour(node_id_t id, int p, double angle, bool asymmetric){ 00126 size_type i, j; 00127 00128 if(first_phase_done){ 00129 //Add it to NDP or update it if it's already there 00130 for ( i = 0; i < NDP.size(); ++i ){ 00131 if(NDP[i].id == id) { 00132 NDP[i].first_time_seen = true; 00133 if(NDP[i].power > p) NDP[i].power = p; 00134 } 00135 } 00136 if(i == NDP.size()){ 00137 ndp_t ndp; 00138 ndp.id = N[i].id; 00139 ndp.power = N[i].power; 00140 ndp.ndp_counter = 0; 00141 ndp.first_time_seen = true; 00142 NDP.push_back(ndp); 00143 } 00144 } 00145 00146 00147 //Remove from ATR if it's there and if now is symmetric 00148 if(!first_phase_done and !asymmetric){ 00149 for ( i = 0; i < ATR.size(); ++i ) 00150 if(ATR[i] == id) 00151 break; 00152 00153 if(i < ATR.size()){ 00154 for(; i < ATR.size() - 1; i++) 00155 ATR[i] = ATR[i+1]; 00156 00157 ATR.pop_back(); 00158 } 00159 } 00160 00161 //Update it in N 00162 //If we are in second phase just update don't add it to N if 00163 //it's not there 00164 for ( i = 0; i < N.size(); ++i ){ 00165 if (N[i].id == id) { 00166 if (N[i].power > p ) N[i].power = p; 00167 N[i].angle = angle; 00168 N[i].asymmetric = N[i].asymmetric && asymmetric; 00169 break; 00170 } 00171 } 00172 00173 if(first_phase_done or i < N.size()) 00174 return; 00175 00176 //Add it to N (just if we are in first phase) 00177 TIPA_t t; 00178 t.id = id; 00179 t.power = p; 00180 t.angle = angle; 00181 t.asymmetric = asymmetric; 00182 00183 for ( i = 0; i < N.size(); ++i ){ 00184 if (angle < N[i].angle) { 00185 N.push_back(t); 00186 00187 for(j = N.size() - 1; j > i; j--){ 00188 N[j] = N[j-1]; 00189 } 00190 N[i] = t; 00191 return; 00192 } 00193 } 00194 00195 N.push_back(t); 00196 } 00197 00198 00199 // ----------------------------------------------------------------------- 00200 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00201 inline void 00202 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00203 delete_by_id(node_id_t id){ 00204 size_type i; 00205 00206 for( i = 0; i < N.size(); i++) 00207 if(N[i].id == id) 00208 break; 00209 00210 for(; i < N.size() - 1; i++) 00211 N[i] = N[i+1]; 00212 00213 N.pop_back(); 00214 } 00215 00216 // ----------------------------------------------------------------------- 00217 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00218 inline void 00219 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00220 delete_by_index(size_type index){ 00221 size_type i; 00222 00223 for(i = index; i < N.size() - 1; i++) 00224 N[i] = N[i+1]; 00225 00226 N.pop_back(); 00227 } 00228 00229 // ----------------------------------------------------------------------- 00230 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00231 inline void 00232 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00233 copy_to_NDP(){ 00234 size_type i; 00235 ndp_t ndp; 00236 for(i = 0; i < N.size(); i++){ 00237 ndp.id = N[i].id; 00238 ndp.power = N[i].power; 00239 ndp.ndp_counter = 0; 00240 ndp.first_time_seen = true; 00241 NDP.push_back(ndp); 00242 } 00243 } 00244 00245 // ----------------------------------------------------------------------- 00246 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00247 bool 00248 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00249 add_update_ndp(node_id_t id, int p, double angle){ 00250 size_type i, j; 00251 ndp_t ndp; 00252 bool has_to_check_gap = false; 00253 00254 //Update it in NDP 00255 for(i = 0; i < NDP.size(); i++){ 00256 if(id == NDP[i].id){ 00257 NDP[i].ndp_counter += 1; 00258 break; 00259 } 00260 } 00261 00262 //If it's not in NDP add it 00263 if(i == NDP.size()){ 00264 ndp.id = id; 00265 ndp.power = p; 00266 ndp.ndp_counter = 0; 00267 ndp.first_time_seen = true; 00268 NDP.push_back(ndp); 00269 } 00270 00271 //Update it in N 00272 for(j = 0; j < N.size(); j++){ 00273 if(id == N[j].id){ 00274 if(N[j].angle != angle) 00275 has_to_check_gap = true; 00276 N[j].angle = angle; 00277 break; 00278 } 00279 } 00280 00281 //If it's not in N add it sorted 00282 if(j == N.size()){ 00283 TIPA_t t; 00284 t.id = id; 00285 t.power = NDP[i].power; 00286 t.angle = angle; 00287 t.asymmetric = false; 00288 00289 Niter it; 00290 00291 for(it = N.begin(); it != N.end(); it++){ 00292 if(angle < (*it).angle){ 00293 N.insert(it, t); 00294 break; 00295 } 00296 } 00297 if(it == N.end()){ 00298 N.push_back(t); 00299 } 00300 } 00301 00302 return has_to_check_gap; 00303 } 00304 00305 // ----------------------------------------------------------------------- 00306 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00307 bool 00308 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00309 ndp_update(){ 00310 size_type i, j; 00311 bool check_for_gap = false; 00312 node_id_t id; 00313 00314 for(i = 0; i < NDP.size(); i++){ 00315 if(NDP[i].first_time_seen){ 00316 NDP[i].first_time_seen = false; 00317 NDP[i].ndp_counter = 0; 00318 } else { 00319 if(NDP[i].ndp_counter) { 00320 NDP[i].ndp_counter = 0; 00321 } else { 00322 id = NDP[i].id; 00323 for(j = i; j < NDP.size() - 1; j++) { 00324 NDP[j] = NDP[j+1]; 00325 } 00326 NDP.pop_back(); 00327 for(j = 0; j < N.size(); j++){ 00328 if(N[j].id == id) { 00329 check_for_gap = true; 00330 delete_by_index(j); 00331 break; 00332 } 00333 } 00334 } 00335 } 00336 } 00337 00338 return check_for_gap; 00339 } 00340 00341 00342 #ifdef DEBUG_CBTC_TOPOLOGY 00343 // ----------------------------------------------------------------------- 00344 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00345 inline void 00346 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00347 print_basic(){ 00348 size_type i; 00349 char nodes[MAX_NODES*7+1]; 00350 int n = 0; 00351 00352 for ( i = 0; i < N.size(); ++i ) 00353 n += snprintf(nodes + n, 7, "%5i ", N[i].id ); 00354 //Debug::debug( os(), "%i: Nodes[Firstphase]: %s\n", id_, nodes ); 00355 00356 n = 0; 00357 for ( i = 0; i < N.size(); ++i ) 00358 n += sprintf(nodes + n, "%5.2f ", N[i].angle ); 00359 //Debug::debug( os(), "%i: Nodes[Angles]: %s\n", id_, nodes ); 00360 00361 n = 0; 00362 for ( i = 0; i < N.size(); ++i ) 00363 n += sprintf(nodes + n, "%5i ", N[i].power ); 00364 //Debug::debug( os(), "%i: Nodes[Powers]: %s\n", id_, nodes ); 00365 00366 n = 0; 00367 for ( i = 0; i < N.size(); ++i ) 00368 n += sprintf(nodes + n, "%s ", N[i].asymmetric? " yes": " no"); 00369 //Debug::debug( os(), "%i: Nodes[asymmetry]: %s\n", id_, nodes ); 00370 } 00371 00372 // ----------------------------------------------------------------------- 00373 template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES> 00374 inline void 00375 CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>:: 00376 print_optimization(const char *s){ 00377 size_type i; 00378 char nodes[MAX_NODES*7+1]; 00379 int n = 0; 00380 00381 for ( i = 0; i < N.size(); ++i ) 00382 n += snprintf(nodes + n, 7, "%5i ", N[i].id ); 00383 //Debug::debug( os(), "%i: %s %s\n", id_, s, nodes ); 00384 } 00385 #endif 00386 00387 } 00388 00389 #endif