Wiselib
|
00001 /* 00002 * File: fronts_core.h 00003 * Author: Amaxilatis 00004 * 00005 */ 00006 00007 #ifndef __FRONTS_CORE_H_ 00008 #define __FRONTS_CORE_H_ 00009 00010 #include "util/delegates/delegate.hpp" 00011 #include "algorithms/cluster/clustering_types.h" 00012 #include "util/base_classes/clustering_base.h" 00013 #include "algorithms/neighbor_discovery/echo.h" 00014 #include "algorithms/neighbor_discovery/pgb_payloads_ids.h" 00015 00016 //Enable This to Initiate Fixed Cluster Roles for Nodes 00017 //#define FIXED_ROLES 00018 #ifdef FIXED_ROLES 00019 #define TOTAL_NODES 2 00020 #endif 00021 #define MAINTENANCE 00022 00023 #undef DEBUG 00024 // Uncomment to enable Debug 00025 //#define DEBUG 00026 #ifdef DEBUG 00027 //#define DEBUG_PAYLOADS 00028 //#define DEBUG_RECEIVED 00029 //#define DEBUG_CLUSTERING 00030 #endif 00031 00032 00033 namespace wiselib { 00034 00042 template<typename OsModel_P, typename Radio_P, typename HeadDecision_P, 00043 typename JoinDecision_P, typename Iterator_P> 00044 class FrontsCore : public ClusteringBase<OsModel_P> { 00045 public: 00046 //TYPEDEFS 00047 typedef OsModel_P OsModel; 00048 // os modules 00049 typedef Radio_P Radio; 00050 typedef typename OsModel::Timer Timer; 00051 typedef typename OsModel::Debug Debug; 00052 typedef typename OsModel::Rand Rand; 00053 00054 //algorithm modules 00055 typedef HeadDecision_P HeadDecision_t; 00056 typedef JoinDecision_P JoinDecision_t; 00057 typedef Iterator_P Iterator_t; 00058 00059 // self type 00060 typedef FrontsCore<OsModel_P, Radio_P, HeadDecision_P, JoinDecision_P, 00061 Iterator_P> self_type; 00062 typedef wiselib::Echo<OsModel, Radio, Timer, Debug> nb_t; 00063 00064 // data types 00065 typedef typename Radio::node_id_t node_id_t; 00066 typedef node_id_t cluster_id_t; 00067 typedef typename Radio::size_t size_t; 00068 typedef typename Radio::block_data_t block_data_t; 00069 typedef uint16_t cluster_level_t; //quite useless within current scheme, supported for compatibility issues 00070 00071 00072 #ifdef FIXED_ROLES 00073 typedef wiselib::pair<node_id_t, node_id_t> node_role_t; 00074 #endif 00075 00076 // delegate 00077 //typedef delegate1<void, uint32_t> cluster_delegate_t; 00078 00079 typedef delegate3<void, uint8_t, cluster_id_t, node_id_t> cradio_delegate_t; 00080 00081 00082 /* 00083 * Constructor 00084 * */ 00085 FrontsCore() : 00086 enabled_(false), status_(0), maxhops_(1), auto_reform_(0), reform_( 00087 false), head_lost_(false) { 00088 } 00089 00090 /* 00091 * Destructor 00092 * */ 00093 ~FrontsCore() { 00094 } 00095 00096 /* 00097 * INIT 00098 * initializes the values of radio timer and debug 00099 */ 00100 void init(Radio& radiot, Timer& timert, Debug& debugt, Rand& randt, 00101 nb_t& neighbor_discovery) { 00102 radio_ = &radiot; 00103 timer_ = &timert; 00104 debug_ = &debugt; 00105 rand_ = &randt; 00106 00107 00108 neighbor_discovery_ = &neighbor_discovery; 00109 00110 uint8_t flags = nb_t::DROPPED_NB | nb_t::LOST_NB_BIDI 00111 | nb_t::NEW_PAYLOAD_BIDI ;//| nb_t::NB_READY; 00112 00113 neighbor_discovery_->template reg_event_callback<self_type, 00114 &self_type::ND_callback > (CLUSTERING, flags, this); 00115 neighbor_discovery_->register_payload_space((uint8_t) CLUSTERING); 00116 00117 cradio_delegate_=cradio_delegate_t(); 00118 00119 //initialize the clustering modules 00120 chd().init(radio(), debug()); 00121 jd().init(radio(), debug()); 00122 it().init(radio(), timer(), debug()); 00123 00124 rand().srand(radio().id()); 00125 00126 00127 } 00128 00129 /* 00130 * Set Clustering modules 00131 * it,jd,chd 00132 */ 00133 inline void set_iterator(Iterator_t &it) { 00134 it_ = ⁢ 00135 } 00136 inline void set_join_decision(JoinDecision_t &jd) { 00137 jd_ = &jd; 00138 } 00139 inline void set_cluster_head_decision(HeadDecision_t &chd) { 00140 chd_ = &chd; 00141 } 00142 00143 /* Set Clustering Parameters 00144 * maxhops 00145 */ 00146 inline void set_maxhops(uint8_t maxhops) { 00147 maxhops_ = maxhops; 00148 jd().set_maxhops(maxhops); 00149 if (hops()>maxhops){ 00150 node_lost(parent()); 00151 } 00152 } 00153 00154 /* Get Clustering Values 00155 * cluster_id 00156 * parent 00157 * hops (from parent) 00158 * node_type 00159 * childs_count 00160 * childs 00161 * node_count (like childs) 00162 * is_gateway 00163 * is_cluster_head 00164 */ 00165 inline cluster_id_t cluster_id(void) { 00166 if (enabled_) 00167 return it().cluster_id(); 00168 else return 0; 00169 } 00170 inline node_id_t parent(void) { 00171 return it().parent(); 00172 } 00173 inline uint8_t hops(void) { 00174 return it().hops(); 00175 } 00176 inline int node_type(void) { 00177 return it().node_type(); 00178 } 00179 inline int childs_count() { 00180 return it().childs_count(); 00181 } 00182 inline void childs(node_id_t * list) { 00183 it().childs(list); 00184 } 00185 inline size_t node_count(int type){ 00186 return it().node_count(type); 00187 } 00188 inline bool is_gateway(){ 00189 return it().is_gateway(); 00190 } 00191 inline bool is_cluster_head() { 00192 if (node_type() != UNCLUSTERED) { 00193 return it().cluster_id() == radio().id(); 00194 } else { 00195 return false; 00196 } 00197 } 00198 00199 00200 /* 00201 * Register a callback that prints specific debug information 00202 * upon any generated event 00203 */ 00204 void register_debug_callback() { 00205 // enable_debug_ = true; 00206 } 00207 00208 /* 00209 * The status Of the Clustering Algorithm 00210 * 1 means a cluster is being formed 00211 * 0 means cluster is formed 00212 */ 00213 inline uint8_t status() { 00214 //1 - forming , 0 - formed 00215 if (enabled_) { 00216 return status_; 00217 } else { 00218 return 2; 00219 } 00220 } 00221 00222 00223 00224 /* 00225 * Size of the payload to the ND module beacon 00226 */ 00227 inline size_t beacon_size() { 00228 JoinClusterMsg<OsModel, Radio> msg; 00229 // send a join payload 00230 return msg.length(); 00231 } 00232 00233 /* 00234 * Receive a beacon payload 00235 * check for new head if needed 00236 * check if in need to reform 00237 */ 00238 void receive_beacon(node_id_t node_from, size_t len, uint8_t * data) { 00239 //receive the beacon data 00240 JoinClusterMsg<OsModel, Radio> *msg; 00241 msg = (JoinClusterMsg<OsModel, Radio> *)data; 00242 //DOWN memcpy(&msg, data, len); 00243 node_id_t cluster = msg->cluster_id(); 00244 int hops = msg->hops(); 00245 #ifndef SHAWN 00246 if (cluster == 0 ) return; 00247 #endif 00248 00249 if (cluster == UNKNOWN_CLUSTER_HEAD) return; 00250 00251 //if the connection to the cluster head was lost 00252 if (head_lost_) { 00253 //if the beacon came from a cluster head 00254 if ((hops < maxhops_) && (cluster < radio().id()) && (neighbor_discovery_->is_neighbor_bidi(node_from))) { 00255 // join him 00256 // inform iterator about the new cluster 00257 it().set_parent(node_from); 00258 it().set_cluster_id(cluster); 00259 jd().set_cluster_id(cluster); 00260 it().set_hops(hops+1); 00261 jd().set_hops(hops+1); 00262 it().set_node_type(SIMPLE); 00263 it().node_joined(node_from); 00264 00265 //mark that the head_lost_ situation was resolved 00266 head_lost_ = false; 00267 00268 JoinClusterMsg<OsModel, Radio> join_msg = jd().get_join_request_payload(); 00269 // Forward message from previous node 00270 radio().send(Radio::BROADCAST_ADDRESS, join_msg.length(), (block_data_t *) & join_msg); 00271 #ifdef DEBUG_CLUSTERING 00272 debug().debug("Send::%x::%d::%x::%d::", radio().id(), 00273 join_msg.msg_id(), Radio::BROADCAST_ADDRESS, 00274 join_msg.hops()); 00275 #ifdef SHAWN 00276 debug().debug("\n"); 00277 #endif 00278 #endif 00279 // if (enable_debug_){ 00280 debug().debug("CLS;%x;%d;%x", radio().id(), 00281 join_msg.msg_id(), Radio::BROADCAST_ADDRESS); 00282 // } 00283 //set the timer to check for clustering end 00284 timer().template set_timer 00285 <self_type, &self_type::wait2form_cluster > 00286 (time_slice_, this, (void*) 0); 00287 } 00288 } 00289 else{ 00290 receive(node_from,len,data); 00291 } 00292 //debug().debug("Node %x(%x) from %x(%x)\n",radio().id(),it().cluster_id(),node_from,cluster); 00293 //if Beacon from cluster neighbor 00294 if (cluster == it().cluster_id() ) { 00295 it().node_joined(node_from); 00296 }//if Beacon from non cluster neighbor 00297 else { 00298 it().node_not_joined(node_from, cluster); 00299 notify_cradio(RESUME, cluster, node_from); 00300 } 00301 00302 //if the sender was my cluster head but is no more a cluster head (possible reform was lost) 00303 if ((node_from == parent()) && (cluster != it().cluster_id())) { 00304 node_lost(node_from); 00305 } 00306 if ((node_from == parent()) && (it().hops() != hops+1 )) { 00307 node_lost(node_from); 00308 } 00309 } 00310 00311 /* 00312 * Get a payload 00313 * to save on a beacon message 00314 */ 00315 void get_beacon(uint8_t * mess) { 00316 JoinClusterMsg<OsModel, Radio> msg = jd().get_join_request_payload(); 00317 memcpy(mess, &msg, msg.length()); 00318 } 00319 00320 void present_neighbors(void) { 00321 if (status() != 2) { 00322 it().present_neighbors(); 00323 } 00324 } 00325 00326 /* 00327 * Enable 00328 * enables the clustering module 00329 * enable chd it and jd modules 00330 * calls find head to start clustering 00331 */ 00332 inline void enable() { 00333 #ifdef SHAWN 00334 enable(6); 00335 #else 00336 enable(40); 00337 #endif 00338 } 00339 00340 void enable(int start_in) { 00341 if (enabled_) return; 00342 00343 //set as enabled 00344 enabled_ = true; 00345 head_lost_ = false; 00346 00347 #ifdef DEBUG_CLUSTERING 00348 debug().debug("Enable::%x::%d::", radio().id(), maxhops_); 00349 #ifdef SHAWN 00350 debug().debug("\n"); 00351 #endif 00352 #endif 00353 00354 #ifdef FIXED_ROLES 00355 //HERE Define the roles For Each node in the network 00356 debug().debug("SettingRoles"); 00357 //Vector Containing The NodeId - ClusterId To set the node to the network 00358 node_role_t roles_vector_[TOTAL_NODES]; 00359 00360 //All node Ids Have to be defined here as .first element of the pair 00361 roles_vector_[0].first = 0x96fc; 00362 roles_vector_[1].first = 0x96f4; 00363 00364 //For Each Node Id defined Above A ClusterId has to be defined 00365 //If the NodeId is the same as the ClusterId then the node is ClusterHead 00366 //If Different then the Node Joins Cluster with Cluster Id and sets its parent to Cluster-Id (cluster head, simulate 1 hop cluster) 00367 roles_vector_[0].second = 0x96fc; 00368 roles_vector_[1].second = 0x96fc; 00369 00370 //Run again for all Nodes in vector to set Iterator Lists 00371 for (int i = 0; i < 2; i++) { 00372 //Run once for all Nodes in vector to set Roles 00373 for (int i = 0; i < TOTAL_NODES; i++) { 00374 set_role(roles_vector_[i].first, roles_vector_[i].second); 00375 } 00376 } 00377 #endif 00378 // receive receive callback 00379 callback_id_ = radio().template reg_recv_callback<self_type, 00380 &self_type::receive > (this); 00381 // set variables of other modules 00382 chd().set_attribute(radio().id()); 00383 jd().set_maxhops(maxhops_); 00384 00385 #ifndef FIXED_ROLES 00386 #ifdef SHAWN 00387 timer().template set_timer<self_type, &self_type::form_cluster > ( 00388 6000, this, (void *) maxhops_); 00389 #else 00390 timer().template set_timer<self_type, &self_type::form_cluster > ( 00391 start_in * 1000, this, (void *) maxhops_); 00392 #endif 00393 #endif 00394 } 00395 00396 // Call with a timer to start a reform procedure from the cluster head 00397 00398 inline void reform_cluster(void * parameter) { 00399 reform_ = true; 00400 } 00401 00402 // Start the procedure needed to form a cluster 00403 00404 void form_cluster(void * parameter) { 00405 if (!enabled_) 00406 return; 00407 status_ = 1; 00408 //enabling 00409 chd().reset(); 00410 chd().set_attribute(radio().id()); 00411 jd().reset(); 00412 it().reset(); 00413 00414 uint8_t buf[beacon_size()]; 00415 get_beacon(buf); 00416 00417 neighbor_discovery_->set_payload((uint8_t) CLUSTERING, buf, 00418 beacon_size()); 00419 00420 // start the procedure to find new head 00421 timer().template set_timer<self_type, &self_type::find_head > ( 00422 rand()() % 300 + time_slice_, this, (void *) 0); 00423 00424 // reform is false as cluster is not yet formed 00425 reform_ = false; 00426 } 00427 00428 /* 00429 * Disable 00430 * disables the bfsclustering module 00431 * unregisters callbacks 00432 */ 00433 inline void disable(void) { 00434 // Unregister the callback 00435 radio().unreg_recv_callback(callback_id_); 00436 enabled_ = false; 00437 } 00438 ; 00439 00440 /* 00441 * wait2form_cluster 00442 * if wait2form_cluster is called and no 00443 * accept messages were received 00444 * there are no nodes under this one and 00445 * node has to respond to head with a resume message 00446 */ 00447 void wait2form_cluster(void * timer_value) { 00448 // if none joind under the node 00449 if (!it().any_joined()) { 00450 // if not a cluster head 00451 if (it().node_type() != HEAD) { 00452 // create a resume message 00453 ResumeClusterMsg<OsModel, Radio> msg = 00454 it().get_resume_payload(); 00455 //do send the message 00456 radio().send(it().parent(), msg.length(), (block_data_t *) & msg); 00457 #ifdef DEBUG_CLUSTERING 00458 debug().debug("CL::Send::from%x::type%d::to%x::", radio().id(), msg.msg_id(), 00459 it().parent()); 00460 #ifdef SHAWN 00461 debug().debug("\n"); 00462 #endif 00463 #else 00464 // if (enable_debug_) { 00465 debug().debug("CLS;%x;%d;%x", radio().id(), msg.msg_id(), 00466 it().parent()); 00467 // } 00468 #endif 00469 00470 00471 // if a cluster head end the clustering under this branch 00472 } else { 00473 cluster_state_changed(CLUSTER_FORMED); 00474 this->state_changed(CLUSTER_FORMED); 00475 reset_beacon_payload(); 00476 } 00477 status_ = 0; 00478 } else { 00479 00480 } 00481 } 00482 00483 /* 00484 * FIND_HEAD 00485 * starts clustering 00486 * decides a head and then start clustering 00487 * from the head of each cluster 00488 * */ 00489 void find_head(void * value) { 00490 00491 long round = (long) value; 00492 00493 if (round < maxhops_) { 00494 //SEND my Attribute to my neighbors (Broadcast the ID) 00495 00496 AttributeClusterMsg<OsModel, Radio> msg = 00497 chd().get_attribute_payload(); 00498 radio().send(Radio::BROADCAST_ADDRESS, msg.length(), 00499 (block_data_t *) & msg); 00500 #ifdef DEBUG_CLUSTERING 00501 debug().debug("CL::Send::from%x::type%d::to%x::%d::%x::", radio().id(), ATTRIBUTE, 00502 Radio::BROADCAST_ADDRESS, round, msg.attribute()); 00503 #ifdef SHAWN 00504 debug().debug("\n"); 00505 #endif 00506 #else 00507 // if (enable_debug_) { 00508 debug().debug("CLS;%x;%d;%x", radio().id(), ATTRIBUTE, 00509 Radio::BROADCAST_ADDRESS); 00510 // } 00511 #endif 00512 00513 00514 round++; 00515 00516 //Recall find_head funtion to resend attribute messages if round<maxhops or elect cluster heads 00517 timer().template set_timer<self_type, &self_type::find_head > ( 00518 time_slice_, this, (void *) round); 00519 00520 } else { 00521 // if Cluster Head 00522 if (chd().calculate_head() == true) { 00523 00524 00525 // set values for iterator and join_decision 00526 it().set_parent(radio().id()); 00527 it().set_cluster_id(radio().id()); 00528 jd().set_cluster_id(radio().id()); 00529 it().set_hops(0); 00530 jd().set_hops(0); 00531 00532 00533 00534 // inform : node is a cluster head 00535 cluster_state_changed(CLUSTER_HEAD_CHANGED); 00536 this->state_changed(CLUSTER_HEAD_CHANGED); 00537 reset_beacon_payload(); 00538 00539 if (auto_reform_ > 0) { 00540 timer().template set_timer<self_type, 00541 &self_type::reform_cluster > (auto_reform_ 00542 * time_slice_, this, (void *) maxhops_); 00543 } 00544 00545 status_ = 0; 00546 00547 JoinClusterMsg<OsModel, Radio> join_msg = 00548 jd().get_join_request_payload(); 00549 // send JOIN 00550 radio().send(Radio::BROADCAST_ADDRESS, join_msg.length(), 00551 (block_data_t *) & join_msg); 00552 #ifdef DEBUG_CLUSTERING 00553 debug().debug("CL::Send::from%x::type%d::to%x::", radio().id(), 00554 join_msg.msg_id(), Radio::BROADCAST_ADDRESS); 00555 #ifdef SHAWN 00556 debug().debug("\n"); 00557 #endif 00558 #else 00559 // if (enable_debug_) { 00560 debug().debug("CLS;%x;%d;%x", radio().id(), 00561 join_msg.msg_id(), Radio::BROADCAST_ADDRESS); 00562 // } 00563 #endif 00564 00565 //Check after some time if any accept messages were received 00566 //2*time_slice for messages to be sent and received 00567 timer().template set_timer<self_type, &self_type::wait2form_cluster > ( 00568 4 * maxhops_ * time_slice_, this, 0); 00569 } else { 00570 timer().template set_timer<self_type, &self_type::wait_for_joins > (time_slice_ / 2, this, (void *) 1); 00571 } 00572 } 00573 } 00574 00575 #ifdef FIXED_ROLES 00576 00577 void set_role(node_id_t node, node_id_t cluster) { 00578 if (node == radio().id()) { 00579 debug().debug("Node %x is in %x", node, cluster); 00580 it().set_parent(cluster); 00581 it().set_cluster_id(cluster); 00582 jd().set_cluster_id(cluster); 00583 if (cluster == radio().id()) { 00584 it().set_hops(0); 00585 } else { 00586 it().set_hops(1); 00587 } 00588 } else { 00589 if (cluster == it().cluster_id()) { 00590 it().node_joined(node); 00591 } else { 00592 it().node_not_joined(node); 00593 } 00594 } 00595 } 00596 #endif 00597 00598 template<class T, void(T::*TMethod)(uint8_t, node_id_t, node_id_t) > 00599 uint8_t reg_notify_cradio(T * obj_pnt) { 00600 cradio_delegate_ = cradio_delegate_t::template from_method<T, TMethod > (obj_pnt); 00601 return 0; 00602 } 00603 00604 node_id_t get_next_node_to_child(node_id_t dest) { 00605 return it().get_child(dest); 00606 } 00607 00608 protected: 00609 00610 /* 00611 * Called when ND lost contact with a node 00612 * If the node was cluster head 00613 * - start searching for new head 00614 * else 00615 * - remove node from known nodes 00616 */ 00617 void node_lost(node_id_t node) { 00618 00619 if (status_ == 0) { 00620 //If the node was my route to CH 00621 if (node == parent()) { 00622 //Reset Iterator 00623 it().reset(); 00624 //Mark as headless 00625 head_lost_ = true; 00626 //Timeout for new CH beacons 00627 timer().template set_timer <self_type, &self_type::wait_for_joins > (1000, this, (void*) 0); 00628 } else { 00629 //if not my CH 00630 //Remove from Iterator 00631 it().drop_node(node); 00632 } 00633 } 00634 } 00635 00636 void cluster_state_changed(int event) throw () { 00637 debug().debug("CLP;%x;%d;%x", radio().id(), it().node_type(), it().cluster_id()); 00638 /*CDOWN 00639 // if (enable_debug_) { 00640 if (event == wiselib::NODE_JOINED) { 00641 // debug().debug("Present::%x::%d::%x::%d::%x::", radio().id(), it().node_type(), it().cluster_id(), it().hops(), it().parent()); 00642 debug().debug("Present::%x::%d::%x::", radio().id(), it().node_type(), it().cluster_id()); 00643 #ifdef SHAWN 00644 debug().debug("\n"); 00645 #endif 00646 } else if (event == wiselib::CLUSTER_HEAD_CHANGED) { 00647 // debug().debug("Present::%x::%d::%d::%d::", radio().id(), it().node_type(), it().childs_count(), 0); 00648 debug().debug("Present::%x::%d::", radio().id(), it().node_type(), it().childs_count(), 0); 00649 #ifdef SHAWN 00650 debug().debug("\n"); 00651 #endif 00652 } 00653 // } 00654 */ 00655 } 00656 00657 /* 00658 * RECEIVE 00659 * respond to the new messages received 00660 * callback from the radio 00661 * */ 00662 void receive(node_id_t from, size_t len, block_data_t * recvm) { 00663 00664 if (radio().id() == from) 00665 return; 00666 if (!neighbor_discovery_->is_neighbor_bidi(from)) 00667 return; 00668 00669 //CDOWN uint8_t type = *recvm; 00670 00671 if (*recvm == ATTRIBUTE) { 00672 #ifdef DEBUG_RECEIVED 00673 debug().debug("Received::%x::%d::%x::%d::", radio().id(), *recvm, from, len); 00674 #endif 00675 chd().receive(from, len, recvm); 00676 } 00677 00678 if (*recvm == JOIN) { 00679 // if ((!status()) || (it().node_type() == HEAD)) return; 00680 00681 #ifdef DEBUG_RECEIVED 00682 debug().debug("Received::%x::%d::%x::%d::", radio().id(), *recvm, from, len); 00683 #endif 00684 00685 // check if the node Joins 00686 if (jd().join(recvm, len)) { 00687 00688 // set values for iterator and join_decision 00689 it().set_parent(from); 00690 it().set_cluster_id(jd().cluster_id()); 00691 it().set_node_type(SIMPLE); 00692 it().node_joined(from); 00693 it().set_hops(jd().hops()); 00694 00695 cluster_state_changed(NODE_JOINED); 00696 this->state_changed(NODE_JOINED); 00697 00698 ResumeClusterMsg<OsModel, Radio> msg = 00699 it().get_resume_payload(); 00700 //do send the message 00701 radio().send(it().parent(), msg.length(), (block_data_t *) & msg); 00702 #ifdef DEBUG_CLUSTERING 00703 debug().debug("CL::Send::from%x::type%d::to%x::", radio().id(), msg.msg_id(), 00704 it().parent()); 00705 #ifdef SHAWN 00706 debug().debug("\n"); 00707 #endif 00708 #else 00709 // if (enable_debug_) { 00710 debug().debug("CLS;%x;%d;%x", radio().id(), msg.msg_id(), 00711 it().parent()); 00712 // } 00713 #endif 00714 00715 00716 } 00717 } else if (*recvm == RESUME) { 00718 if (from == parent()) return; 00719 00720 //CDOWN ResumeClusterMsg<OsModel, Radio> msg; 00721 ResumeClusterMsg<OsModel, Radio> *msg; 00722 msg = (ResumeClusterMsg<OsModel, Radio> *)recvm; 00723 //CDOWN memcpy(&msg, recvm, len); 00724 #ifdef DEBUG_RECEIVED 00725 debug().debug("Received::%x::%d::%x::%d::", radio().id(), msg->mess_id(), from, len); 00726 #endif 00727 // if not a cluster head forward the message to head 00728 if (it().node_type() != HEAD) { 00729 00730 //cluster is formed 00731 status_ = 0; 00732 00733 //do send the message 00734 radio().send(it().parent(), len, (block_data_t *) msg); 00735 it().add_resume(from, msg->node_id()); 00736 00737 #ifdef DEBUG_CLUSTERING 00738 debug().debug("CL::Send::from%x::type%d::to%x::forw::", radio().id(), 00739 msg->msg_id(), it().parent()); //old4 00740 #ifdef SHAWN 00741 debug().debug("\n"); 00742 #endif 00743 #else 00744 // if (enable_debug_) { 00745 debug().debug("CLS;%x;%d;%x", radio().id(), 00746 msg->msg_id(), it().parent()); //old4 00747 // } 00748 #endif 00749 00750 } else { 00751 //if a cluster head add node to cluster nodes 00752 it().node_joined(msg->node_id()); 00753 it().add_resume(from, msg->node_id()); 00754 } 00755 00756 notify_cradio(RESUME, msg->node_id(), from); 00757 } 00758 } 00759 00760 void notify_cradio(uint8_t event, cluster_id_t from, node_id_t to) { 00761 if (cradio_delegate_ != 0) { 00762 cradio_delegate_(event, from, to); 00763 } 00764 } 00765 00766 // -------------------------------------------------------------------- 00767 00768 void wait_for_joins(void * data) { 00769 00770 long wait_round = (long) data; 00771 if (it().node_type() == UNCLUSTERED) { 00772 00773 if (wait_round < maxhops_) { 00774 #ifdef DEBUG_CLUSTERING_EXTRA 00775 debug().debug("Waiting::%x::%d::", radio().id(), wait_round); 00776 #endif 00777 //reset the timer and wait for wait_round+1 hop cluster heads 00778 timer().template set_timer 00779 <self_type, &self_type::wait_for_joins > 00780 (time_slice_ / 2, this, (void *) (wait_round + 1)); 00781 } else { 00782 00783 head_lost_ = false; 00784 //no cluster head in maxhops 00785 00786 // set values for iterator and join_decision 00787 it().set_parent(radio().id()); 00788 it().set_cluster_id(radio().id()); 00789 jd().set_cluster_id(radio().id()); 00790 it().set_hops(0); 00791 jd().set_hops(0); 00792 00793 #ifdef DEBUG_CLUSTERING 00794 debug().debug("ForcedCH::%x::", radio().id()); 00795 #ifdef SHAWN 00796 debug().debug("\n"); 00797 #endif 00798 #endif 00799 //INFORM I AM A CLUSTER HEAD 00800 cluster_state_changed(CLUSTER_HEAD_CHANGED); 00801 this->state_changed(CLUSTER_HEAD_CHANGED); 00802 reset_beacon_payload(); 00803 00804 if (auto_reform_ > 0) { 00805 // set timer to periodically reform the cluster 00806 timer().template set_timer 00807 <self_type, &self_type::reform_cluster > 00808 ((auto_reform_ - maxhops_) * time_slice_, this, (void *) maxhops_); 00809 } 00810 00811 // the cluster was formed 00812 status_ = 0; 00813 00814 JoinClusterMsg<OsModel, Radio> join_msg = jd().get_join_request_payload(); 00815 // Forward message from previous node 00816 radio().send(Radio::BROADCAST_ADDRESS, join_msg.length(), (block_data_t *) & join_msg); 00817 #ifdef DEBUG_CLUSTERING 00818 debug().debug("Send::%x::%d::%x::%d::", radio().id(), 00819 join_msg.msg_id(), Radio::BROADCAST_ADDRESS, 00820 join_msg.hops()); 00821 #ifdef SHAWN 00822 debug().debug("\n"); 00823 #endif 00824 #endif 00825 00826 00827 //Check after some time if Any accept messages were received 00828 //2*time_slice for messages to be sent and received 00829 //timer().template set_timer<self_type, &self_type::wait2form_cluster > (2 * time_slice_, this, 0); 00830 00831 //call timer expired to finallize cluster formation 00832 wait2form_cluster(0); 00833 } 00834 } else { 00835 head_lost_ = false; 00836 if (hops() < maxhops_) { 00837 JoinClusterMsg<OsModel, Radio> join_msg = 00838 jd().get_join_request_payload(); 00839 // Forward message from previous node 00840 radio().send(Radio::BROADCAST_ADDRESS, join_msg.length(), 00841 (block_data_t *) & join_msg); 00842 #ifdef DEBUG_CLUSTERING 00843 debug().debug("CL::Send::from%x::type%d::to%x::%d::", radio().id(), 00844 join_msg.msg_id(), Radio::BROADCAST_ADDRESS, 00845 join_msg.hops()); 00846 #ifdef SHAWN 00847 debug().debug("\n"); 00848 #endif 00849 #else 00850 // if (enable_debug_) { 00851 debug().debug("CLS;%x;%d;%x", radio().id(), 00852 join_msg.msg_id(), Radio::BROADCAST_ADDRESS); 00853 // } 00854 #endif 00855 00856 //set the timer to check for clustering end 00857 timer().template set_timer 00858 <self_type, &self_type::wait2form_cluster > 00859 (2 * (maxhops_ - hops()) * time_slice_, this, (void*) 0); 00860 } else { 00861 // if no more hops to propagate the join message finalize cluster formation 00862 wait2form_cluster(0); 00863 } 00864 //notify for join 00865 cluster_state_changed(NODE_JOINED); 00866 this->state_changed(NODE_JOINED); 00867 reset_beacon_payload(); 00868 } 00869 } 00870 00871 // -------------------------------------------------------------------- 00872 00873 void reset_beacon_payload() { 00874 //reset my beacon according to the new status 00875 uint8_t buf[beacon_size()]; 00876 get_beacon(buf); 00877 if (neighbor_discovery_->set_payload((uint8_t) CLUSTERING, buf, 00878 it().cluster_id() != UNKNOWN_CLUSTER_HEAD ? beacon_size() : 0) != 0) { 00879 #ifdef DEBUG_CLUSTERING 00880 debug_->debug("Error::%x::", radio_->id()); 00881 #endif 00882 } 00883 } 00884 // -------------------------------------------------------------------- 00885 00886 void ND_callback(uint8_t event, node_id_t from, uint8_t len, uint8_t * data) { 00887 if (nb_t::NEW_PAYLOAD_BIDI == event) { 00888 receive_beacon(from, len, data); 00889 //reset my beacon according to the new status 00890 reset_beacon_payload(); 00891 } else if ((nb_t::LOST_NB_BIDI == event) || (nb_t::DROPPED_NB == event)) { 00892 #ifndef FIXED_ROLES 00893 #ifdef MAINTENANCE 00894 node_lost(from); 00895 #endif 00896 #endif 00897 } 00898 } 00899 00900 private: 00901 nb_t * neighbor_discovery_; 00902 bool enabled_; 00903 // bool enable_debug_; 00904 uint8_t status_; // the status of the clustering algorithm 00905 int callback_id_; // receive message callback 00906 int maxhops_; // clustering parameter 00907 static const uint32_t time_slice_ = 2000; // time to wait for cluster accept replies 00908 int auto_reform_; //time to autoreform the clusters 00909 bool reform_; // flag to start reforming 00910 bool head_lost_; // flag when the head was lost 00911 00912 cradio_delegate_t cradio_delegate_; 00913 00914 00915 00916 /* CLustering algorithm modules */ 00917 HeadDecision_t * chd_; 00918 00919 inline HeadDecision_t & chd() { 00920 return *chd_; 00921 } 00922 JoinDecision_t * jd_; 00923 00924 inline JoinDecision_t & jd() { 00925 return *jd_; 00926 } 00927 Iterator_t * it_; 00928 00929 inline Iterator_t & it() { 00930 return *it_; 00931 } 00932 00933 Radio * radio_; // radio module 00934 Timer * timer_; // timer module 00935 Debug * debug_; // debug module 00936 00937 Rand * rand_; 00938 00939 Radio & radio() { 00940 return *radio_; 00941 } 00942 00943 Timer & timer() { 00944 return *timer_; 00945 } 00946 00947 Debug & debug() { 00948 #ifdef SHAWN 00949 debug_->debug("\n"); 00950 #endif 00951 return *debug_; 00952 } 00953 00954 Rand & rand() { 00955 return *rand_; 00956 } 00957 }; 00958 } 00959 #endif