Wiselib
|
00001 /* 00002 * File: maxmind_chd.h 00003 * Author: Amaxilatis 00004 */ 00005 00006 #ifndef __MAXMIND_CLUSTER_HEAD_DECISION_H_ 00007 #define __MAXMIND_CLUSTER_HEAD_DECISION_H_ 00008 00009 #include "util/delegates/delegate.hpp" 00010 00011 00012 namespace wiselib { 00018 template< typename OsModel_P > 00019 class MaxmindClusterHeadDecision { 00020 public: 00021 00022 00023 //TYPEDEFS 00024 typedef OsModel_P OsModel; 00025 typedef typename OsModel::Radio Radio; 00026 typedef typename OsModel::Debug Debug; 00027 00028 //DATA TYPES 00029 typedef int cluster_id_t; 00030 typedef typename Radio::node_id_t node_id_t; 00031 00032 00033 //delegate 00034 typedef delegate1<void, node_id_t*> chd_delegate_t; 00035 00036 /* 00037 * Constructor 00038 * */ 00039 MaxmindClusterHeadDecision() : 00040 d_(0), // Maxmind Parameter 00041 id_(-1), 00042 cluster_id_(-1), 00043 parent_(-1), 00044 cluster_head_(false) { 00045 00046 }; 00047 00048 /* 00049 * Destructor 00050 * */ 00051 ~MaxmindClusterHeadDecision() { 00052 }; 00053 00054 /* 00055 * INIT 00056 * initializes the values of radio timer and debug 00057 */ 00058 void init(Radio& radio, Debug & debug) { 00059 radio_ = &radio; 00060 debug_ = &debug; 00061 }; 00062 00063 00064 /* 00065 * Calculates if node is a Cluster Head 00066 * Returns True: if a cluster_head 00067 * False: if not cluster_head 00068 * */ 00069 bool calculate_head() { 00070 00071 // winner and sender arrays 00072 00073 node_id_t local_winner_[2 * d_]; 00074 winner_ = local_winner_; 00075 node_id_t local_sender_[2 * d_]; 00076 sender_ = local_sender_; 00077 00078 bool decided = false; 00079 00080 // get the winner adn sender arrays from join decision 00081 winner_callback_(winner_); 00082 sender_callback_(sender_); 00083 00084 #ifdef DEBUG 00085 // print the arrays for debuging 00086 debug().debug("CHD(%x) is now deciding\n winner[", id_); 00087 // print the winner array 00088 for (int i = 0; i < 2 * d_; i++) { 00089 if (i == d_) debug().debug("|"); 00090 debug().debug("%x ", winner_[i]); 00091 } 00092 debug().debug("]\n sender["); 00093 // print the sender array 00094 for (int i = 0; i < 2 * d_; i++) { 00095 if (i == d_) debug().debug("|"); 00096 debug().debug("%x ", sender_[i]); 00097 } 00098 debug().debug("]\n"); 00099 #endif 00100 // RULE_1 of MAXMIND 00101 // check if received own id in the second d rounds of flooding (RULE_1) 00102 if (!decided) { 00103 // check all the second d values of the winner list for my id_ 00104 // [ - - - - - - | C C C C C C ] 00105 for (int i = d_; i < 2 * d_; i++) { 00106 // if you find your id then you are cluster_head (RULE_1) 00107 if (winner_[i] == id_) { 00108 // set myself as cluster_head_ 00109 cluster_head_ = true; 00110 // set my cluster_id_to my id 00111 cluster_id_ = id_; 00112 // set my parent_ to -1 , as i am cluster_head 00113 parent_ = id_; 00114 // set as decided 00115 decided = true; 00116 #ifdef DEBUG 00117 debug().debug("%x now is head (Rule1)\n", id_); 00118 debug().debug("checking rule 2\n"); 00119 #endif 00120 00121 00122 00123 00124 break; 00125 } 00126 } 00127 } 00128 // RULE_2 of MAXMIND 00129 // check if a node pair exists in the winner list (RULE_2) 00130 if (!decided) { 00131 00132 // check all the first d values of the winner list for a pair with the second d values 00133 // [ A - B - C - D - E | a - b - c - d - e ] 00134 // if node pairs were found : true else false 00135 bool found = false; 00136 // contains the pair id and the node currently checked 00137 int pair = -1, node; 00138 // contains my parent_if a pair was found 00139 int parent_node = sender_[0]; 00140 // check all nodes of the first d rounds for their possible pair 00141 for (int i = 0; i < d_; i++) { 00142 node = winner_[i]; 00143 00144 // for each node in the first d rounds check second d rounds for pair 00145 for (int j = d_; j < 2 * d_; j++) { 00146 // if a pair exists 00147 00148 if (node == winner_[j]) { 00149 // if not the first pair 00150 if (found) { 00151 // keep only the minimum pair 00152 if (node < pair) { 00153 // if the minimum pair so far 00154 pair = node; 00155 // find the sender closer to my pair 00156 // the first node i received the pair id from is my parent 00157 for (int l = 0; l < 2 * d_; l++) { 00158 if (winner_[l] == node) { 00159 parent_node = sender_[l]; 00160 break; 00161 } 00162 00163 } 00164 00165 00166 } 00167 }// if the first pair keep it imediately 00168 else { 00169 pair = node; 00170 // find the sender closer to my pair 00171 // the first node i received the pair id from is my parent 00172 for (int l = 0; l < 2 * d_; l++) { 00173 if (winner_[l] == node) { 00174 parent_node = sender_[l]; 00175 break; 00176 } 00177 00178 } 00179 00180 00181 00182 // now i have a pair value , avoid nulls- memory faults 00183 found = true; 00184 } 00185 } 00186 } 00187 } 00188 // if found any pairs elect its node id as cluster_head 00189 if (found) { 00190 // set as decided for cluster_head 00191 decided = true; 00192 // set as not cluster_head 00193 cluster_head_ = false; 00194 // save the cluster_id 00195 cluster_id_ = pair; 00196 // set my parent_as the parent_node calculated above 00197 parent_ = parent_node; 00198 #ifdef DEBUG 00199 debug().debug("%x has now head %x and parent %x (Rule2)\n", id_, cluster_id_, parent_); 00200 #endif 00201 } 00202 } 00203 // RULE_3 of MAXMIND 00204 // check and find the max value of the first d rounds as cluster_head (RULE_3) 00205 if (!decided) { 00206 // check all the first d values of the winner list for the maximum node_id 00207 // [ C C C C C | - - - - - ] 00208 cluster_id_ = winner_[0]; 00209 parent_ = sender_[0]; 00210 for (int i = 0; i < d_; i++) { 00211 // find the max of the winner list 00212 if (winner_[i] > cluster_id_) { 00213 cluster_id_ = winner_[i]; 00214 for (int l = 0; l < 2 * d_; l++) { 00215 // find the sender closer to my pair 00216 // the first node i received the pair id from is my parent 00217 if (winner_[l] == cluster_id_) { 00218 parent_ = sender_[l]; 00219 break; 00220 } 00221 } 00222 } 00223 } 00224 // set as decided for cluster_head 00225 decided = true; 00226 // set the cluster_head (not sure if head here) 00227 if (cluster_id_ != id_) { 00228 #ifdef DEBUG 00229 debug().debug("%x has now head %x and parent %x (Rule3)\n", id_, cluster_id_, parent_); 00230 #endif 00231 cluster_head_ = false; 00232 } else { 00233 #ifdef DEBUG 00234 debug().debug("%x now is head (Rule3)", id_); 00235 #endif 00236 cluster_head_ = true; 00237 } 00238 } 00239 00240 #ifdef DEBUG 00241 debug().debug("%x cluster head decided\n", id_); 00242 #endif 00243 00244 return cluster_head_; 00245 }; 00246 00247 00248 // Returns if Cluster Head 00249 00250 bool is_cluster_head(void) { 00251 return cluster_head_; 00252 }; 00253 00254 cluster_id_t cluster_id() { 00255 return cluster_id_; 00256 } 00257 00258 node_id_t parent() { 00259 return parent_; 00260 } 00261 00262 // Set the theta value 00263 00264 void set_theta(int theta) { 00265 d_ = theta; 00266 00267 }; 00268 00269 // Set my id 00270 00271 void set_id(node_id_t id) { 00272 id_ = id; 00273 }; 00274 00275 // winner callback 00276 00277 template<class T, void (T::*TMethod)(node_id_t*) > 00278 inline int reg_winner_callback(T * obj_pnt) { 00279 winner_callback_ = chd_delegate_t::template from_method<T, TMethod > (obj_pnt); 00280 return winner_callback_; 00281 }; 00282 00283 void unreg_winner_callback(int idx) { 00284 winner_callback_ = chd_delegate_t(); 00285 }; 00286 00287 // winner callback 00288 00289 template<class T, void (T::*TMethod)(node_id_t*) > 00290 inline int reg_sender_callback(T * obj_pnt) { 00291 sender_callback_ = chd_delegate_t::template from_method<T, TMethod > (obj_pnt); 00292 return sender_callback_; 00293 }; 00294 00295 void unreg_sender_callback(int idx) { 00296 sender_callback_ = chd_delegate_t(); 00297 }; 00298 00299 void enable() { 00300 d_ = 0; 00301 id_ = -1; 00302 cluster_id_ = -1; 00303 parent_ = -1; 00304 cluster_head_ = false; 00305 } 00306 00307 00308 00309 private: 00310 // winner list 00311 node_id_t * winner_; 00312 // sender list 00313 node_id_t * sender_; 00314 // d range 00315 int d_; 00316 // node id 00317 node_id_t id_; 00318 cluster_id_t cluster_id_; 00319 node_id_t parent_; 00320 // is cluster head? 00321 bool cluster_head_; 00322 00323 // delegate for callbacks 00324 chd_delegate_t winner_callback_; 00325 chd_delegate_t sender_callback_; 00326 00327 00328 Radio * radio_; 00329 00330 Radio & radio() { 00331 return *radio_; 00332 } 00333 Debug * debug_; 00334 00335 Debug & debug() { 00336 return *debug_; 00337 } 00338 }; 00339 00340 } 00341 00342 #endif