Wiselib
|
00001 /* 00002 * File: maxmind_it.h 00003 * Author: Amaxilatis 00004 */ 00005 00006 #ifndef __MAXMIND_ITERATOR_H_ 00007 #define __MAXMIND_ITERATOR_H_ 00008 00009 00010 #include "util/pstl/vector_static.h" 00011 #include "util/delegates/delegate.hpp" 00012 00013 namespace wiselib { 00014 00020 template<typename OsModel_P> 00021 class MaxmindIterator { 00022 public: 00023 //TYPEDEFS 00024 typedef OsModel_P OsModel; 00025 typedef typename OsModel::Radio Radio; 00026 typedef typename OsModel::Timer Timer; 00027 typedef typename OsModel::Debug Debug; 00028 typedef MaxmindIterator<OsModel_P> self_t; 00029 00030 // data types 00031 typedef int cluster_id_t; 00032 typedef typename Radio::node_id_t node_id_t; 00033 typedef typename Radio::block_data_t block_data_t; 00034 typedef typename Radio::size_t size_t; 00035 typedef wiselib::vector_static<OsModel, node_id_t, 250 > vector_t; 00036 00037 00038 //delegates 00039 typedef delegate1<void, int> iterator_delegate_t; 00040 00041 /* 00042 * Constructor 00043 * */ 00044 MaxmindIterator() : 00045 parent_(-1), // parent_id 00046 cluster_id_(-1), // my cluster_id 00047 node_type_(UNCLUSTERED) { // node type indicator 00048 }; 00049 00050 /* 00051 * Destructor 00052 * */ 00053 ~MaxmindIterator() { 00054 }; 00055 00056 /* 00057 * INIT 00058 * initializes the values of radio timer and debug 00059 */ 00060 void init(Radio& radio, Timer& timer, Debug& debug) { 00061 radio_ = &radio; 00062 timer_ = &timer; 00063 debug_ = &debug; 00064 }; 00065 00066 // set node parent_id 00067 00068 void set_parent(node_id_t parent) { 00069 parent_ = parent; 00070 }; 00071 // get the parent_id 00072 00073 node_id_t parent(void) { 00074 return parent_; 00075 }; 00076 00077 // set the cluster_id_ 00078 00079 void set_cluster_id(cluster_id_t cluster_id) { 00080 cluster_id_ = cluster_id; 00081 }; 00082 // get the cluster_id_ 00083 00084 cluster_id_t cluster_id(void) { 00085 return cluster_id_; 00086 }; 00087 00088 //UNUSED 00089 // called if timer has expired 00090 void timer_expired(void* data); 00091 00092 //UNUSED 00093 void node_joined(node_id_t node); 00094 00095 //UNUSED 00096 00097 bool is_empty(void) { 00098 return cluster_neighbors_.empty(); 00099 }; 00100 00101 void set_theta(int theta) { 00102 theta_ = theta; 00103 } 00104 00105 /* 00106 * Change the nodes type 00107 * clusterheads are not allowed 00108 * at the moment to change their type 00109 * */ 00110 void set_node_type(int node_type) { 00111 if (node_type_ != HEAD) { 00112 node_type_ = node_type; 00113 } 00114 }; 00115 00116 // get the node type 00117 00118 int node_type() { 00119 return node_type_; 00120 }; 00121 00122 // set the node_id 00123 00124 void set_id(node_id_t id) { 00125 id_ = id; 00126 }; 00127 00128 // add a node id to the cluster_neibhors 00129 00130 bool add_to_cluster(node_id_t node) { 00131 //check if the node is already declared 00132 bool exists = false; 00133 for (size_t i = 0; i < cluster_neighbors_.size(); i++) { 00134 if (node == cluster_neighbors_.at(i)) { 00135 exists = true; 00136 break; 00137 } 00138 } 00139 if (!exists) { 00140 cluster_neighbors_.push_back(node); 00141 } 00142 return !exists; 00143 }; 00144 00145 bool remove_from_cluster(node_id_t node) { 00146 //check if the node is already declared 00147 bool exists = false; 00148 for (size_t i = 0; i < cluster_neighbors_.size(); i++) { 00149 if (node == cluster_neighbors_.at(i)) { 00150 exists = true; 00151 for (int j = i; j < cluster_neighbors_.size() - 1; j++) { 00152 cluster_neighbors_.at(j) = cluster_neighbors_.at(j + 1); 00153 00154 } 00155 00156 cluster_neighbors_.pop_back(); 00157 break; 00158 } 00159 } 00160 return exists; 00161 00162 } 00163 00164 00165 // add a node id to the non cluster neibhors 00166 00167 bool add_to_non_cluster(node_id_t node) { 00168 //check if the node is already declared 00169 bool exists = false; 00170 for (size_t i = 0; i < non_cluster_neighbors_.size(); i++) { 00171 if (node == non_cluster_neighbors_.at(i)) { 00172 exists = true; 00173 break; 00174 } 00175 } 00176 if (!exists) { 00177 non_cluster_neighbors_.push_back(node); 00178 } 00179 return !exists; 00180 }; 00181 00182 bool remove_from_non_cluster(node_id_t node) { 00183 //check if the node is already declared 00184 bool exists = false; 00185 for (size_t i = 0; i < non_cluster_neighbors_.size(); i++) { 00186 if (node == non_cluster_neighbors_.at(i)) { 00187 exists = true; 00188 for (size_t j = i; j < non_cluster_neighbors_.size() - 1; j++) { 00189 non_cluster_neighbors_.at(j) = non_cluster_neighbors_.at(j + 1); 00190 00191 } 00192 00193 non_cluster_neighbors_.pop_back(); 00194 break; 00195 } 00196 } 00197 return exists; 00198 00199 } 00200 00201 void present_neibhors() { 00202 #ifdef DEBUG 00203 debug().debug("Neibhors(%x)[(%d) ", radio().id(), cluster_neighbors_.size()); 00204 for (size_t i = 0; i < cluster_neighbors_.size(); i++) { 00205 debug().debug("%x ", cluster_neighbors_.at(i)); 00206 } 00207 debug().debug("] , "); 00208 debug().debug("[(%d) ", non_cluster_neighbors_.size()); 00209 for (size_t i = 0; i < non_cluster_neighbors_.size(); i++) { 00210 debug().debug("%x ", non_cluster_neighbors_.at(i)); 00211 } 00212 debug().debug("]\n"); 00213 #endif 00214 }; 00215 00216 void eat_convergecast(uint8_t *payload, size_t len) { 00217 00218 size_t non_cluster_count; 00219 memcpy(&non_cluster_count, payload + 1 + sizeof (node_id_t) + sizeof (node_id_t) + sizeof (cluster_id_t), sizeof (size_t)); 00220 size_t new_non_cluster = 0; 00221 for (size_t i = 0; i < non_cluster_count; i++) { 00222 if ((1 + sizeof (node_id_t)*2 + sizeof (cluster_id_t) + sizeof (size_t) + sizeof (node_id_t)*(i + 1)) > Radio::MAX_MESSAGE_LENGTH) break; 00223 node_id_t non_cluster_node; 00224 memcpy(&non_cluster_node, payload + 1 + sizeof (node_id_t)*2 + sizeof (cluster_id_t) + sizeof (size_t) + sizeof (node_id_t)*(i + 1), sizeof (node_id_t)); 00225 if (add_to_non_cluster(non_cluster_node)) { 00226 new_non_cluster++; 00227 } 00228 } 00229 00230 #ifdef DEBUG 00231 debug().debug("Added %d to non_cluster\n", new_non_cluster); 00232 #endif 00233 }; 00234 00235 /* 00236 * Process an inform message 00237 * Get the node that sent it and add him to my neibhors 00238 * check for errors in clustering (parent circles) 00239 * find my node type (gateway vs simple) 00240 * */ 00241 bool inform(uint8_t *mess, uint8_t length) { 00242 00243 // sender of the message 00244 node_id_t node_from; 00245 memcpy(&node_from, mess + 1, sizeof (node_id_t)); 00246 // sender cluster 00247 node_id_t node_cluster; 00248 memcpy(&node_cluster, mess + 1 + sizeof (node_id_t), sizeof (cluster_id_t)); 00249 // sender parent node 00250 node_id_t node_parent; 00251 memcpy(&node_parent, mess + 1 + sizeof (node_id_t) + sizeof (cluster_id_t), sizeof (node_id_t)); 00252 00253 // set if the nodes i candidate for a cluster error 00254 bool cluster_error = false; 00255 00256 #ifdef DEBUG 00257 debug().debug("Inform Node %x from : %x cluster head is %x and parent is %x -- I have cluster_head %x and parent %x\n", radio().id(), node_from, node_cluster, node_parent, cluster_id(), parent_); 00258 #endif 00259 /* 00260 * If i was contacted form a node of 00261 * another cluster i am a gateway 00262 * */ 00263 if (node_cluster != cluster_id()) { 00264 if (node_from != parent_) { 00265 set_node_type(GATEWAY); 00266 #ifdef DEBUG 00267 debug().debug("%x Becomes gateway because of neighbor \n", radio().id()); 00268 #endif 00269 00270 cluster_error = false; 00271 add_to_non_cluster(node_from); 00272 } else { 00273 // the node is a candidate for clusterin error 00274 cluster_error = true; 00275 add_to_cluster(node_from); 00276 } 00277 } else { 00278 add_to_cluster(node_from); 00279 00280 } 00281 00282 //if i am the nodes parent 00283 if (node_parent == radio().id()) { 00284 00285 // if in the same cluster i am not a gateway so i am a simple 00286 if (!cluster_error) { 00287 00288 if (node_type() != GATEWAY) { 00289 set_node_type(SIMPLE); 00290 #ifdef DEBUG 00291 debug().debug("%x Becomes simple node \n", radio().id()); 00292 #endif 00293 } else { 00294 #ifdef DEBUG 00295 debug().debug("Is gateway %x\n", radio().id()); 00296 #endif 00297 } 00298 } 00299 00300 00301 00302 #ifdef DEBUG 00303 debug().debug("%x is parent of node %x \n", radio().id(), node_from); 00304 #endif 00305 // if the node is my parent and i am his parent then i chose annother parent to break a circle 00306 if (node_from == parent_) { 00307 #ifdef DEBUG 00308 debug().debug("%x has parent the node %x \n", radio().id(), node_from); 00309 #endif 00310 // find annother parent 00311 size_t i = 0; 00312 for (i = 0; i <= cluster_neighbors_.size(); i++) { 00313 if (cluster_neighbors_.at(i) != parent_) { 00314 parent_ = cluster_neighbors_.at(i); 00315 break; 00316 } 00317 } 00318 // if i cant find annother parent report it (the other node will break the circle) 00319 if (parent_ == node_from) { 00320 #ifdef DEBUG 00321 debug().debug("Node %d cannot find new parent \n", radio().id()); 00322 #endif 00323 } else { 00324 #ifdef DEBUG 00325 debug().debug("Node %d changed parent to node %d \n", radio().id(), parent_); 00326 #endif 00327 } 00328 } 00329 00330 } else { 00331 // if i was not a simple node i am a gateway (simple nodes have a child already so they cannot become cluster heads) 00332 if (node_type() != SIMPLE) { 00333 00334 set_node_type(GATEWAY); 00335 } 00336 } 00337 return true; 00338 }; 00339 00340 // set the hops from my cluster_head_ 00341 // UNUSED 00342 00343 void set_hops(int hops) { 00344 hops_ = hops; 00345 } 00346 00347 // get the hops from my cluster_head_ 00348 // UNUSED 00349 00350 int hops() { 00351 return hops_; 00352 } 00353 00354 /* controls vector neighbor with all nearby nodes */ 00355 void add_neighbor(node_id_t node_id) { 00356 for (size_t i = 0; i < neighbors_.size(); i++) { 00357 if (neighbors_.at(i) == node_id) return; 00358 } 00359 neighbors_.push_back(node_id); 00360 } 00361 00362 node_id_t next_neighbor() { 00363 if (neighbors_.size() == 0) { 00364 return Radio::NULL_NODE_ID; 00365 } else { 00366 node_id_t ret_val = neighbors_.back(); 00367 neighbors_.pop_back(); 00368 00369 return ret_val; 00370 } 00371 } 00372 00373 void get_inform_payload(block_data_t * mess) { 00374 00375 //size_t mess_size = get_payload_length(INFORM); 00376 //block_data_t ret[mess_size]; 00377 00378 uint8_t type = INFORM; 00379 memcpy(mess, &type, 1); 00380 00381 //ret[0] = INFORM; 00382 //ret[1] = id_ % 256; 00383 //ret[2] = id_ / 256; 00384 memcpy(mess + 1, &id_, sizeof (node_id_t)); 00385 //ret[3] = cluster_id_ % 256; 00386 //ret[4] = cluster_id_ / 256; 00387 memcpy(mess + 1 + sizeof (node_id_t), &cluster_id_, sizeof (cluster_id_t)); 00388 //ret[5] = parent_ % 256; 00389 //ret[6] = parent_ / 256; 00390 memcpy(mess + 1 + sizeof (node_id_t) + sizeof (cluster_id_t), &parent_, sizeof (node_id_t)); 00391 00392 //memcpy(mess, ret, mess_size); 00393 00394 #ifdef DEBUG 00395 debug().debug("[%x|%x|%x]\n", id_, cluster_id_, parent_); 00396 #endif 00397 } 00398 00399 void get_convergecast_payload(block_data_t * mess) { 00400 size_t outer_cluster = non_cluster_neighbors_.size(); 00401 00402 //size_t mess_size = get_payload_length(CONVERGECAST); 00403 //block_data_t ret[mess_size]; 00404 00405 uint8_t type = CONVERGECAST; 00406 00407 //ret[0] = CONVERGECAST; 00408 memcpy(mess, &type, 1); 00409 //ret[1] = parent_ % 256; 00410 //ret[2] = parent_ / 256; 00411 memcpy(mess + 1, &parent_, sizeof (node_id_t)); 00412 //ret[3] = id_ % 256; 00413 //ret[4] = id_ / 256; 00414 memcpy(mess + 1 + sizeof (node_id_t), &id_, sizeof (node_id_t)); 00415 //ret[5] = cluster_id_ % 256; 00416 //ret[6] = cluster_id_ / 256; 00417 memcpy(mess + 1 + sizeof (node_id_t) + sizeof (node_id_t), &cluster_id_, sizeof (cluster_id_t)); 00418 //ret[7] = outer_cluster % 256; 00419 //ret[8] = outer_cluster / 256; 00420 memcpy(mess + 1 + sizeof (node_id_t) + sizeof (node_id_t) + sizeof (cluster_id_t), &outer_cluster, sizeof (size_t)); 00421 #ifdef DEBUG 00422 debug().debug("[%d|%x|%x|%x|%d", type, parent_, id_, cluster_id_, outer_cluster); 00423 #endif 00424 for (int i = 0; i < outer_cluster; i++) { 00425 if (1 + sizeof (node_id_t)*2 + sizeof (cluster_id_t) + sizeof (size_t) + sizeof (node_id_t)*(i + 1) > Radio::MAX_MESSAGE_LENGTH) break; 00426 //ret[8 + 2 * i + 1] = non_cluster_neighbors_.at(i) % 256; 00427 //ret[8 + 2 * i + 2] = non_cluster_neighbors_.at(i) / 256; 00428 memcpy(mess + 1 + sizeof (node_id_t) + sizeof (node_id_t) + sizeof (cluster_id_t) + sizeof (size_t) + i * sizeof (node_id_t), &non_cluster_neighbors_.at(i), sizeof (node_id_t)); 00429 #ifdef DEBUG 00430 debug().debug("|%x", non_cluster_neighbors_.at(i)); 00431 #endif 00432 } 00433 #ifdef DEBUG 00434 debug().debug("]\n"); 00435 #endif 00436 }; 00437 00438 void get_rejoin_payload(block_data_t * mess, node_id_t destination) { 00439 //size_t mess_size = get_payload_length(REJOIN); 00440 //block_data_t ret[mess_size]; 00441 00442 uint8_t type = REJOIN; 00443 memcpy(mess, &type, 1); 00444 //ret[1] = destination % 256; 00445 //ret[2] = destination / 256; 00446 memcpy(mess + 1, &destination, sizeof (node_id_t)); 00447 //ret[3] = cluster_id_ % 256; 00448 //ret[4] = cluster_id_ / 256; 00449 memcpy(mess + 1 + sizeof (node_id_t), &cluster_id_, sizeof (cluster_id_t)); 00450 //ret[5] = theta_; 00451 memcpy(mess + 1 + sizeof (node_id_t) + sizeof (cluster_id_t), &theta_, sizeof (size_t)); 00452 #ifdef DEBUG 00453 debug().debug("[%d|%x|%x|%d]\n", type, destination, cluster_id_, theta_); 00454 #endif 00455 //memcpy(mess, ret, mess_size); 00456 } 00457 00458 size_t get_payload_length(int type) { 00459 00460 if (type == INFORM) 00461 return 1 + sizeof (node_id_t) + sizeof (cluster_id_t) + sizeof (node_id_t); 00462 else if (type == CONVERGECAST) { 00463 size_t size = 1 + sizeof (node_id_t) + sizeof (node_id_t) + sizeof (cluster_id_t) + sizeof (size_t) + sizeof (node_id_t) * non_cluster_neighbors_.size(); 00464 return size > Radio::MAX_MESSAGE_LENGTH ? Radio::MAX_MESSAGE_LENGTH : size; 00465 //return size; 00466 } else if (type == REJOIN) 00467 return 1 + sizeof (node_id_t) + sizeof (cluster_id_t) + sizeof (size_t); 00468 else 00469 return 0; 00470 }; 00471 00472 template<typename T, void (T::*TMethod)(int) > 00473 inline int reg_next_callback(T * obj) { 00474 get_next_callback_ = iterator_delegate_t::template from_method<T, TMethod > (obj); 00475 return get_next_callback_; 00476 } 00477 00478 inline void unreg_next_callback(uint8_t idx) { 00479 get_next_callback_ = iterator_delegate_t(); 00480 } 00481 00482 void enable(void) { 00483 parent_ = -1; 00484 cluster_id_ = -1; 00485 node_type_ = UNCLUSTERED; 00486 cluster_neighbors_.clear(); 00487 non_cluster_neighbors_.clear(); 00488 neighbors_.clear(); 00489 id_ = -1; 00490 }; 00491 00492 void disable(void) { 00493 00494 00495 }; 00496 00497 private: 00498 // 00499 vector_t cluster_neighbors_; 00500 vector_t non_cluster_neighbors_; 00501 vector_t neighbors_; 00502 // my parent_ 00503 node_id_t parent_; 00504 node_id_t id_; 00505 00506 // id of the cluster 00507 cluster_id_t cluster_id_; 00508 // callback delegate 00509 iterator_delegate_t get_next_callback_; 00510 // timeslice 00511 static const int time_slice_ = 1500; 00512 int node_type_; 00513 int hops_; 00514 size_t theta_; 00515 00516 00517 Radio * radio_; 00518 Timer * timer_; 00519 Debug * debug_; 00520 00521 Radio & radio() { 00522 return *radio_; 00523 } 00524 00525 Timer & timer() { 00526 return *timer_; 00527 } 00528 00529 Debug & debug() { 00530 return *debug_; 00531 } 00532 00533 00534 }; 00535 00536 // UNUSED 00537 00538 template<typename OsModel_P> 00539 void MaxmindIterator<OsModel_P>::node_joined(node_id_t node) { 00540 00541 cluster_neighbors_.push_back(node); 00542 00543 } 00544 00545 00546 00547 } 00548 00549 #endif