Wiselib
wiselib.testing/algorithms/cluster/modules/it/maxmind_it.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines