Wiselib
|
00001 00019 #ifndef __ALGORITHMS_CLUSTER_HIGHWAY_CLUSTER_H__ 00020 #define __ALGORITHMS_CLUSTER_HIGHWAY_CLUSTER_H__ 00021 00022 00023 #include "algorithms/neighbor_discovery/echo.h" 00024 #include "algorithms/cluster/clustering_types.h" 00025 #include "util/pstl/vector_static.h" 00026 #include "util/pstl/pair.h" 00027 #include "util/pstl/map_static_vector.h" 00028 #include "internal_interface/routing_table/routing_table_static_array.h" 00029 #include "util/delegates/delegate.hpp" 00030 00031 #include "algorithms/cluster/fronts/fronts_core.h" 00032 #include "algorithms/cluster/modules/chd/attr_chd.h" 00033 #include "algorithms/cluster/modules/it/fronts_it.h" 00034 #include "algorithms/cluster/modules/jd/bfs_jd.h" 00035 00036 // Levels of debug info: 00037 // HIGHWAY_METHOD_DEBUG: Adds a Method called notice at the beginning of each 00038 // method. 00039 // HIGHWAY_MSG_RECV_DEBUG: Adds all sorts of debug messages for the tracking 00040 // of sending messages at Highway level. 00041 // VISOR_DEBUG: Adds debug messages that can be processed by the Python visor 00042 // application to generate a picture of the final status of the WSN. 00043 // HIGHWAY_DEBUG: Most general debug messages. 00044 00045 //#define HIGHWAY_DEBUG 00046 //#define HIGHWAY_METHOD_DEBUG 00047 //#define HIGHWAY_MSG_RECV_DEBUG 00048 //#define VISOR_DEBUG 00049 #define CTI_VISOR 00050 //#define HWY_METRICS 00051 #ifdef ISENSE_APP 00052 #define SEND_OVERHEAD 7 00053 #else 00054 #define SEND_OVERHEAD 13 00055 #endif 00056 00057 namespace wiselib{ 00058 template<typename OsModel_P, 00059 typename RoutingTable_P, 00060 typename Cluster_P = wiselib::FrontsCore<OsModel_P, typename OsModel_P::TxRadio, wiselib::AtributeClusterHeadDecision<OsModel_P, typename OsModel_P::TxRadio>, wiselib::BfsJoinDecision<OsModel_P, typename OsModel_P::TxRadio>, wiselib::FrontsIterator<OsModel_P, typename OsModel_P::TxRadio> >, 00061 typename Neighbor_P = wiselib::Echo<OsModel_P, typename OsModel_P::TxRadio, typename OsModel_P::Timer, typename OsModel_P::Debug>, 00062 uint16_t MAX_CLUSTERS = 8> 00063 class HighwayCluster 00064 { 00065 public: 00066 00067 // OS modules. 00068 typedef OsModel_P OsModel; 00069 typedef typename OsModel::Rand Rand; 00070 typedef typename OsModel::TxRadio Radio; 00071 typedef typename OsModel::Timer Timer; 00072 typedef typename OsModel::Clock Clock; 00073 typedef typename OsModel::Debug Debug; 00074 typedef typename OsModel::TxRadio TxRadio; 00075 00076 // Type definitions. 00077 typedef wiselib::AtributeClusterHeadDecision<OsModel, TxRadio> CHD_t; 00078 typedef wiselib::BfsJoinDecision<OsModel, TxRadio> JD_t; 00079 typedef wiselib::FrontsIterator<OsModel, TxRadio> IT_t; 00080 00081 // Type definition of the used Templates. 00082 typedef RoutingTable_P RoutingTable; 00083 typedef Cluster_P Cluster; 00084 typedef Neighbor_P Neighbor; 00085 00086 typedef HighwayCluster<OsModel, RoutingTable, Cluster, Neighbor, MAX_CLUSTERS> self_type; 00087 typedef wiselib::Echo<OsModel, TxRadio, Timer, Debug> nb_t; 00088 typedef self_type* self_pointer_t; 00089 00090 // Basic types definition. 00091 typedef typename Radio::node_id_t node_id_t; 00092 typedef typename Radio::size_t size_t; 00093 typedef typename Radio::block_data_t block_data_t; 00094 typedef typename Timer::millis_t millis_t; 00095 00096 // Type definition for the receive callback. 00097 typedef delegate3<void, node_id_t, size_t, block_data_t*> highway_delegate_t; 00098 00099 // Type definition for the special data structures of the highway. 00100 typedef wiselib::pair<uint8_t, uint8_t> hops_ack; 00101 typedef wiselib::pair<node_id_t, node_id_t> source_target; 00102 typedef wiselib::pair<source_target, hops_ack> entry; 00103 typedef wiselib::MapStaticVector<OsModel, node_id_t, entry, MAX_CLUSTERS> HighwayTable; 00104 typedef HighwayTable PortsQueue; 00105 typedef wiselib::vector_static<OsModel, node_id_t, MAX_CLUSTERS> Node_vect; 00106 00107 // Type definition for the special types iterators. 00108 typedef typename HighwayTable::iterator highway_iterator; 00109 00110 // Return types definition. 00111 enum ErrorCodes { 00112 SUCCESS = OsModel::SUCCESS, 00113 ERR_UNSPEC = OsModel::ERR_UNSPEC 00114 }; 00115 00116 // Possible highway message ids. 00117 enum msg_id { 00118 CANDIDACY = 200, 00119 PORT_REQ = 201, 00120 PORT_REQ2 = 202, 00121 PORT_ACK = 203, 00122 PORT_ACK2 = 204, 00123 PORT_NACK = 205, 00124 PORT_NACK2 = 206, 00125 SEND = 207, 00126 SEND2 = 208, 00127 ACK = 109, 00128 ACK2 = 110 00129 }; 00130 00131 // -------------------------------------------------------------------- 00132 // Public method declaration. | 00133 // -------------------------------------------------------------------- 00134 00137 HighwayCluster(): 00138 radio_ ( 0 ), 00139 timer_ ( 0 ), 00140 clock_ ( 0 ), 00141 debug_ ( 0 ), 00142 rand_ ( 0 ), 00143 cluster_ ( 0 ), 00144 discovery_time_ ( 5000 ), 00145 disc_timer_set_(0), 00146 cand_timer_set_(0), 00147 max_acks_(25) 00148 { 00149 }; 00150 00153 ~HighwayCluster(){}; 00154 00155 00159 int init( TxRadio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Rand& rand, Cluster& cluster, Neighbor& neighbor ); 00160 00164 void enable( void ); 00165 00172 void send( node_id_t receiver, size_t len, block_data_t *data ); 00173 00178 //Node_vect cluster_neighbors(); 00179 void cluster_neighbors(Node_vect * neighbor); 00180 00184 template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)> 00185 uint8_t hwy_reg_recv_callback(T *obj_pnt) { 00186 hwy_recv_callback_ = highway_delegate_t::template from_method<T, TMethod > ( obj_pnt ); 00187 return 0; 00188 } 00189 00192 void unreg_hwy_recv_callback() { 00193 hwy_recv_callback_ = highway_delegate_t(); 00194 } 00195 00196 // -------------------------------------------------------------------- 00197 // Setters | 00198 // -------------------------------------------------------------------- 00199 00203 inline void set_discovery_time( millis_t t ) { 00204 discovery_time_ = t; 00205 }; 00206 00210 inline void set_max_acks( uint8_t m ) { 00211 max_acks_ = m; 00212 }; 00213 00214 private: 00215 // Typenaming the underlying modules. 00216 typename Radio::self_pointer_t radio_; 00217 typename Timer::self_pointer_t timer_; 00218 typename Clock::self_pointer_t clock_; 00219 typename Debug::self_pointer_t debug_; 00220 typename Rand::self_pointer_t rand_; 00221 typename Cluster::self_type* cluster_; 00222 typename Neighbor::self_t* neighbor_; 00223 00224 // Highway control message. 00225 struct msg_highway { 00226 uint8_t msg_id, hops; 00227 node_id_t source, target, sid_source, sid_target; 00228 }; 00229 00230 enum msg_highway_size { 00231 HWY_MSG_SIZE = sizeof( uint8_t ) + sizeof( uint8_t ) + sizeof( node_id_t ) + sizeof( node_id_t ) + sizeof( node_id_t ) + sizeof( node_id_t ) 00232 }; 00233 00234 inline void set_msg_highway( uint8_t * data, uint8_t msg_id, uint8_t hops, node_id_t source, node_id_t target, node_id_t sid_source, node_id_t sid_target ) 00235 { 00236 int idx = 0; 00237 write<OsModel, block_data_t, uint8_t>( data + idx, msg_id ); 00238 idx += sizeof( uint8_t ); 00239 write<OsModel, block_data_t, uint8_t>( data + idx, hops ); 00240 idx += sizeof( uint8_t ); 00241 write<OsModel, block_data_t, node_id_t>( data + idx, source ); 00242 idx += sizeof( node_id_t ); 00243 write<OsModel, block_data_t, node_id_t>( data + idx, target ); 00244 idx += sizeof( node_id_t ); 00245 write<OsModel, block_data_t, node_id_t>( data + idx, sid_source ); 00246 idx += sizeof( node_id_t ); 00247 write<OsModel, block_data_t, node_id_t>( data + idx, sid_target ); 00248 } 00249 00250 inline void get_msg_highway( msg_highway * msg, uint8_t * data ) 00251 { 00252 int idx = 0; 00253 msg->msg_id = read<OsModel, block_data_t, uint8_t>( data + idx ); 00254 idx += sizeof( uint8_t ); 00255 msg->hops = read<OsModel, block_data_t, uint8_t>( data + idx ); 00256 idx += sizeof( uint8_t ); 00257 msg->source = read<OsModel, block_data_t, node_id_t>( data + idx ); 00258 idx += sizeof( node_id_t ); 00259 msg->target = read<OsModel, block_data_t, node_id_t>( data + idx ); 00260 idx += sizeof( node_id_t ); 00261 msg->sid_source = read<OsModel, block_data_t, node_id_t>( data + idx ); 00262 idx += sizeof( node_id_t ); 00263 msg->sid_target = read<OsModel, block_data_t, node_id_t>( data + idx ); 00264 } 00265 00266 // -------------------------------------------------------------------- 00267 // Private variables declaration. | 00268 // -------------------------------------------------------------------- 00269 00271 msg_highway msg_highway_; 00272 00274 millis_t discovery_time_; 00275 00277 uint8_t disc_timer_set_; 00278 00280 uint8_t cand_timer_set_; 00281 00283 highway_delegate_t hwy_recv_callback_; 00284 00286 RoutingTable routing_table_; 00287 00289 HighwayTable highway_table_; 00290 00292 PortsQueue ports_queue_; 00293 00295 block_data_t buffer_[Radio::MAX_MESSAGE_LENGTH]; 00296 00298 int8_t max_acks_; 00299 00307 void send( bool send_ack, node_id_t receiver, size_t len, block_data_t *data ); 00308 00310 CHD_t CHD_; 00311 JD_t JD_; 00312 IT_t IT_; 00313 00314 #ifdef HWY_METRICS 00315 00316 uint16_t r_cand, r_req, r_req2, r_pack, r_pack2, r_pnack, r_pnack2, r_send, r_send2, r_ack, r_ack2; 00317 uint16_t s_cand, s_req, s_req2, s_pack, s_pack2, s_pnack, s_pnack2, s_send, s_send2, s_ack, s_ack2; 00318 uint8_t n_hwy; 00319 uint8_t time; 00320 #endif 00321 00322 // -------------------------------------------------------------------- 00323 // Private method declaration. | 00324 // -------------------------------------------------------------------- 00325 00329 Radio& radio() { 00330 return *radio_; 00331 } 00332 00336 Timer& timer() { 00337 return *timer_; 00338 } 00339 00343 Clock& clock() { 00344 return *clock_; 00345 } 00346 00350 Debug& debug() { 00351 return *debug_; 00352 } 00353 00357 Cluster& cluster() { 00358 return *cluster_; 00359 } 00360 00364 Neighbor& neighbor() { 00365 return *neighbor_; 00366 } 00367 00372 void cluster_callback(int state); 00373 00377 void cluster_discovery( void ); 00378 00386 void neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data); 00387 00392 void discovery_timeout( void *userdata ); 00393 00398 void candidacies_timeout( void *userdata ); 00399 00406 void receive( node_id_t from, size_t len, block_data_t *data ); 00407 00414 void send_to_leader( node_id_t from, size_t len, block_data_t *data ); 00415 00422 void send_away( node_id_t from, size_t len, block_data_t *data ); 00423 00430 void process_send( node_id_t from, size_t len, block_data_t *data ); 00431 00438 void cluster_head_work( node_id_t from, size_t len, block_data_t *data ); 00439 00440 #ifdef HWY_METRICS 00441 00444 void graph_print( void * userdata ); 00445 #endif 00446 00447 }; // End of class. 00448 00449 // -------------------------------------------------------------------- 00450 // Start of the method code: PUBLIC METHODS | 00451 // -------------------------------------------------------------------- 00452 template<typename OsModel_P, 00453 typename RoutingTable_P, 00454 typename Cluster_P, 00455 typename Neighbor_P, 00456 uint16_t MAX_CLUSTERS> 00457 inline int 00458 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00459 init( TxRadio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Rand& rand, Cluster& cluster, Neighbor& neighbor ) { 00460 radio_ = &tx_radio; 00461 timer_ = &timer; 00462 clock_ = &clock; 00463 debug_ = &debug; 00464 rand_ = &rand; 00465 cluster_ = &cluster; 00466 neighbor_ = &neighbor; 00467 00468 // Initialize the neighborhood discovery module. 00469 neighbor_->init( tx_radio, *clock_, *timer_, *debug_ ); 00470 00471 // Stabilizing cluster initialization. 00472 // set the HeadDecision Module 00473 cluster_->set_cluster_head_decision( CHD_ ); 00474 // set the JoinDecision Module 00475 cluster_->set_join_decision( JD_ ); 00476 // set the Iterator Module 00477 cluster_->set_iterator( IT_ ); 00478 cluster_->init( *radio_, *timer_, *debug_, *rand_, *neighbor_ ); 00479 00480 //IMPROVE: Take the value upper as soon as more hops clustering is tested. 00481 //cluster_->set_maxhops( 1 ); 00482 cluster_->set_maxhops( 2 ); 00483 00484 #ifdef HWY_METRICS 00485 // Graph variables initialization 00486 r_cand = 0; 00487 s_cand = 0; 00488 r_req = 0; 00489 s_req = 0; 00490 r_req2 = 0; 00491 s_req2 = 0; 00492 r_pack = 0; 00493 s_pack = 0; 00494 r_pack2 = 0; 00495 s_pack2 = 0; 00496 r_pnack = 0; 00497 s_pnack = 0; 00498 r_pnack2 = 0; 00499 s_pnack2 = 0; 00500 r_send = 0; 00501 s_send = 0; 00502 r_send2 = 0; 00503 s_send2 = 0; 00504 r_ack = 0; 00505 s_ack = 0; 00506 r_ack2 = 0; 00507 s_ack2 = 0; 00508 n_hwy = 0; 00509 time = 0; 00510 #endif 00511 00512 return SUCCESS; 00513 } 00514 00515 // -------------------------------------------------------------------- 00516 00517 template<typename OsModel_P, 00518 typename RoutingTable_P, 00519 typename Cluster_P, 00520 typename Neighbor_P, 00521 uint16_t MAX_CLUSTERS> 00522 void 00523 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00524 enable( void ) 00525 { 00526 #ifdef HIGHWAY_METHOD_DEBUG 00527 debug().debug( "@@ %d METHOD CALLED: enable()\n", radio().id() ); 00528 #endif 00529 // Enabling and registering radio 00530 radio().enable_radio(); 00531 radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00532 00533 // Enabling neighborhood and registering cluster 00534 cluster().enable(); 00535 cluster().template reg_state_changed_callback<self_type, &self_type::cluster_callback > ( this ); 00536 neighbor().enable(); 00537 00538 #ifdef HWY_METRICS 00539 time = 0; 00540 graph_print( ( void * )0 ); 00541 #endif 00542 00543 #ifdef HIGHWAY_METHOD_DEBUG 00544 debug().debug( "@@ %d METHOD ENDED: enable()\n", radio().id() ); 00545 #endif 00546 } 00547 00548 // -------------------------------------------------------------------- 00549 00550 template<typename OsModel_P, 00551 typename RoutingTable_P, 00552 typename Cluster_P, 00553 typename Neighbor_P, 00554 uint16_t MAX_CLUSTERS> 00555 void 00556 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00557 send( node_id_t destination, size_t len, block_data_t *data ) 00558 { 00559 #ifdef HIGHWAY_METHOD_DEBUG 00560 debug().debug( "@@ %d METHOD CALLED: send()\n", radio().id() ); 00561 #endif 00562 00563 send(true, destination, len, data); 00564 00565 #ifdef HIGHWAY_METHOD_DEBUG 00566 debug().debug( "@@ %d METHOD ENDED: send()\n", radio().id() ); 00567 #endif 00568 } 00569 00570 // ----------------------------------------------------------------------- 00571 00572 template<typename OsModel_P, 00573 typename RoutingTable_P, 00574 typename Cluster_P, 00575 typename Neighbor_P, 00576 uint16_t MAX_CLUSTERS> 00577 void 00578 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00579 cluster_neighbors( Node_vect * neighbors ) 00580 { 00581 #ifdef HIGHWAY_METHOD_DEBUG 00582 debug().debug( "@@ %d METHOD CALLED: cluster_neighbors()\n", radio().id() ); 00583 #endif 00584 00585 neighbors->clear(); 00586 if ( not cluster().is_cluster_head() ) 00587 { 00588 return; 00589 } 00590 00591 highway_iterator it; 00592 for ( it = highway_table_.begin(); it != highway_table_.end(); ++it ) 00593 { 00594 neighbors->push_back( it->first ); 00595 } 00596 00597 #ifdef HIGHWAY_METHOD_DEBUG 00598 debug().debug( "@@ %d METHOD ENDED: cluster_neighbors()\n", radio().id() ); 00599 #endif 00600 } 00601 00602 // ----------------------------------------------------------------------- 00603 // PRIVATE METHODS | 00604 // ----------------------------------------------------------------------- 00605 00606 template<typename OsModel_P, 00607 typename RoutingTable_P, 00608 typename Cluster_P, 00609 typename Neighbor_P, 00610 uint16_t MAX_CLUSTERS> 00611 void 00612 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00613 cluster_callback( int state ) 00614 { 00615 #ifdef HIGHWAY_METHOD_DEBUG 00616 debug().debug( "@@ %d METHOD_CALLED: cluster_callback()\n", radio().id() ); 00617 #endif 00618 00619 #ifdef HIGHWAY_DEBUG 00620 if( state == CLUSTER_HEAD_CHANGED ) 00621 { 00622 debug().debug( "@@ %d CLUSTER_HEAD_CHANGED\n", radio().id() ); 00623 } 00624 else if( state == CLUSTER_FORMED ) 00625 { 00626 debug().debug( "@@ %d CLUSTER_FORMED\n", radio().id() ); 00627 } 00628 else if( state == NODE_JOINED ) 00629 { 00630 debug().debug( "@@ %d NODE_JOINED\n", radio().id() ); 00631 } 00632 #endif 00633 00634 // Otherwise flush routing and highway tables and start 00635 if ( state == CLUSTER_HEAD_CHANGED or state == NODE_JOINED ) 00636 { 00637 highway_table_.clear(); 00638 ports_queue_.clear(); 00639 routing_table_.clear(); 00640 #ifdef VISOR_DEBUG 00641 debug().debug( "+%d#%d#%d#1\n", radio().id(), cluster().cluster_id(), cluster().is_cluster_head() ); 00642 #endif 00643 00644 if ( state == CLUSTER_HEAD_CHANGED ) 00645 { 00646 neighbor().unreg_event_callback( HWY_N ); 00647 } 00648 else //is not cluster head. 00649 { 00650 #ifdef VISOR_DEBUG 00651 debug().debug( "$%d->%d$t\n", cluster().parent(), radio_->id() ); 00652 #endif 00653 cluster_discovery(); 00654 } 00655 } 00656 #ifdef HIGHWAY_METHOD_DEBUG 00657 debug().debug( "@@ %d METHOD_ENDED: start_wrapper()\n", radio().id() ); 00658 #endif 00659 } 00660 00661 // ----------------------------------------------------------------------- 00662 00663 template<typename OsModel_P, 00664 typename RoutingTable_P, 00665 typename Cluster_P, 00666 typename Neighbor_P, 00667 uint16_t MAX_CLUSTERS> 00668 void 00669 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00670 cluster_discovery( void ) 00671 { 00672 #ifdef HIGHWAY_METHOD_DEBUG 00673 debug().debug( "@@ %d METHOD CALLED: cluster_discovery()\n", radio().id() ); 00674 #endif 00675 00676 // Add the piggybacking information to the neighborhood discovery module. 00677 node_id_t id = cluster().cluster_id(); 00678 uint8_t length; 00679 00680 // Adapt cluster_id to the node_id_t size of the plattform. 00681 #ifdef ISENSE_APP 00682 uint8_t sid_buf[3]; 00683 sid_buf[0] = id & 0xFF; 00684 sid_buf[1] = id >> 8; 00685 sid_buf[2] = cluster().hops(); 00686 length = 3; 00687 #else 00688 uint8_t sid_buf[5]; 00689 sid_buf[0] = id & 0xFF; 00690 sid_buf[1] = ( id >> 8 ) & 0xFF; 00691 sid_buf[2] = ( id >> 16 ) & 0xFF; 00692 sid_buf[3] = ( id >> 24 ) & 0xFF; 00693 sid_buf[4] = cluster().hops(); 00694 length = 5; 00695 #endif 00696 00697 #ifdef HIGHWAY_DEBUG 00698 debug().debug( "@@ Node %d:%d cluster_disc hops: %d\n", id, radio().id(), cluster().hops() ); 00699 #endif 00700 00701 // Register and add the payload space to the neighborhood discovery module. 00702 if ( neighbor().register_payload_space( HWY_N ) !=0 ) 00703 { 00704 #ifdef HIGHWAY_DEBUG 00705 debug().debug( "Error registering payload space\n" ); 00706 #endif 00707 } 00708 else if(neighbor().set_payload( HWY_N, sid_buf, length )!=0) { 00709 #ifdef HIGHWAY_DEBUG 00710 debug().debug( "Error adding payload\n" ); 00711 #endif 00712 } 00713 else 00714 { 00715 #ifdef HIGHWAY_DEBUG 00716 debug().debug( "%d Registering neighborhood\n", radio().id() ); 00717 #endif 00718 uint8_t flags = nb_t::LOST_NB_BIDI | nb_t::NEW_PAYLOAD_BIDI; 00719 neighbor().template reg_event_callback<HighwayCluster,&HighwayCluster::neighbor_callback>( HWY_N, flags, this ); 00720 if( not disc_timer_set_ ) 00721 { 00722 disc_timer_set_ = 1; 00723 timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ , this, (void *) 0 ); 00724 } 00725 } 00726 #ifdef HIGHWAY_METHOD_DEBUG 00727 debug().debug( "@@ %d METHOD ENDED: cluster_discovery()\n", radio().id() ); 00728 #endif 00729 } 00730 00731 // ----------------------------------------------------------------------- 00732 00733 template<typename OsModel_P, 00734 typename RoutingTable_P, 00735 typename Cluster_P, 00736 typename Neighbor_P, 00737 uint16_t MAX_CLUSTERS> 00738 void 00739 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00740 neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data) 00741 { 00742 #ifdef HIGHWAY_METHOD_DEBUG 00743 debug().debug("@@ %d METHOD CALLED: neighbor_callback()\n", radio().id()); 00744 #endif 00745 00746 memcpy( buffer_, data, len ); 00747 00748 node_id_t sid; 00749 uint8_t hops; 00750 00751 // On payload event, process the data according to the plattform 00752 if ( nb_t::NEW_PAYLOAD_BIDI == event ) { 00753 #ifdef ISENSE_APP 00754 sid = ( buffer_[1] << 8 ) | buffer_[0]; 00755 hops = buffer_[2]; 00756 #else 00757 sid = ( buffer_[3] << 24 ) | ( buffer_[2] << 16 ) | ( buffer_[1] << 8 ) | buffer_[0]; 00758 hops = buffer_[4]; 00759 #endif 00760 00761 #ifdef HIGHWAY_DEBUG 00762 debug().debug( "@@Node: %d, cluster_id: %d, hops: %d\n", from, sid, hops ); 00763 #endif 00764 // If not cluster leader and the message is from another cluster add it to the highway table of the now to be port candidate. 00765 if ( !cluster().is_cluster_head() and cluster().cluster_id() != sid ) 00766 { 00767 //debug().debug( "PQ[%d].first=%d(%d) from=%d(%d)", sid, ports_queue_[sid].first, ports_queue_[sid].second.first, from, hops ); 00768 //Check if it is new and that it is better than the current one 00769 if( ports_queue_[sid].first.second != from && ( ( ports_queue_[sid].second.first == 0 ) || ( ports_queue_[sid].second.first > hops ) ) ) 00770 { 00771 ports_queue_[sid] = entry( source_target( radio().id(), from ), hops_ack( hops, 0 )); 00772 } 00773 else 00774 return; 00775 } 00776 if( not disc_timer_set_ ) 00777 { 00778 disc_timer_set_ = 1; 00779 timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ , this, (void *) 0 ); 00780 } 00781 } 00782 else if ( nb_t::LOST_NB_BIDI == event ) 00783 { 00784 //TODO: Work on fault tolerance here! 00785 // If the removed node is in the routing_table (it's path to a highway or a port itself) remove it from there and signal the cluster head of the loss. 00786 #ifdef HIGHWAY_DEBUG 00787 debug().debug( "NODE %d: event LOST_NB_BIDI %d \n",radio().id(), from); 00788 #endif 00789 } 00790 #ifdef HIGHWAY_METHOD_DEBUG 00791 debug().debug("@@ %d METHOD ENDED: neighbor_callback()\n", radio().id()); 00792 #endif 00793 } 00794 00795 // ----------------------------------------------------------------------- 00796 00797 template<typename OsModel_P, 00798 typename RoutingTable_P, 00799 typename Cluster_P, 00800 typename Neighbor_P, 00801 uint16_t MAX_CLUSTERS> 00802 void 00803 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00804 discovery_timeout( void *userdata ) 00805 { 00806 #ifdef HIGHWAY_METHOD_DEBUG 00807 debug().debug( "@@ %d METHOD CALLED: discovery_timeout()\n", radio().id()); 00808 #endif 00809 if( disc_timer_set_ ) 00810 { 00811 disc_timer_set_ = 0; 00812 } 00813 00814 highway_iterator it; 00815 for ( it = ports_queue_.begin(); it != ports_queue_.end(); ++it ) 00816 { 00817 //Check if the port candidate is already set as highway 00818 if(highway_table_[it->first].first.first == it->second.first.first and highway_table_[it->first].first.second == it->second.first.second ) 00819 return; 00820 // Create a CANDIDACY highway message with: hops, port_source, port_target, cluster_id_own, cluster_id_target. 00821 set_msg_highway( buffer_, CANDIDACY, it->second.second.first, radio().id(), it->second.first.second, cluster().cluster_id(), it->first ); 00822 00823 // Send it to the parent. 00824 radio().send( cluster().parent(), HWY_MSG_SIZE, buffer_ ); 00825 #ifdef HWY_METRICS 00826 s_cand++; 00827 #endif 00828 } 00829 #ifdef HIGHWAY_METHOD_DEBUG 00830 debug().debug( "@@ %d METHOD ENDED: discovery_timeout()\n", radio().id() ); 00831 #endif 00832 } 00833 00834 // ----------------------------------------------------------------------- 00835 00836 template<typename OsModel_P, 00837 typename RoutingTable_P, 00838 typename Cluster_P, 00839 typename Neighbor_P, 00840 uint16_t MAX_CLUSTERS> 00841 void 00842 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00843 candidacies_timeout( void *userdata ) 00844 { 00845 #ifdef HIGHWAY_METHOD_DEBUG 00846 debug().debug( "@@ %d METHOD STARTED: candidacies_timeout()\n", radio().id() ); 00847 #endif 00848 if( cand_timer_set_ ) 00849 { 00850 cand_timer_set_ = 0; 00851 } 00852 00853 if ( !ports_queue_.empty() ) // If no candidacies were presented we will call the same method after a work period. 00854 { 00855 #ifdef HIGHWAY_DEBUG 00856 debug().debug( "%d Cand_timeout leader with ports to start\n", radio().id() ); 00857 #endif 00858 highway_iterator it; 00859 for ( it = ports_queue_.begin(); it != ports_queue_.end(); ++it ) 00860 { 00861 // Check that it is not the same highway 00862 if( it->second.second.first == 0 || ( it->second.first.first == highway_table_[it->first].first.first && it->second.first.second == highway_table_[it->first].first.second )) 00863 continue; 00864 //Check that there's a current highway and that it is still working properly 00865 if( highway_table_[it->first].second.first == 0 || highway_table_[it->first].second.second > max_acks_ ) 00866 { 00867 #ifdef HIGHWAY_DEBUG 00868 debug().debug( "%d Sent port request to %d through %d\n", radio().id(), it->first, routing_table_[it->second.first.first] ); 00869 #endif 00870 // Create a CANDIDACY highway message with: hops, port_source, port_target, cluster_id_own, cluster_id_target. 00871 set_msg_highway( buffer_, PORT_REQ, it->second.second.first, it->second.first.first, it->second.first.second, cluster().cluster_id(), it->first ); 00872 radio().send( routing_table_[it->second.first.first], HWY_MSG_SIZE, buffer_ ); 00873 #ifdef HWY_METRICS 00874 s_req++; 00875 #endif 00876 } 00877 } 00878 00879 //After processing all the ports, we flush the queue. 00880 //IMPROVE: Check if it isn't better to save an extra port for when the ACKs are not arriving. 00881 ports_queue_.clear(); 00882 } 00883 #ifdef HIGHWAY_METHOD_DEBUG 00884 debug().debug( "@@ %d METHOD ENDED: candidacies_timeout()\n", radio().id() ); 00885 #endif 00886 } 00887 00888 // ----------------------------------------------------------------------- 00889 00890 template<typename OsModel_P, 00891 typename RoutingTable_P, 00892 typename Cluster_P, 00893 typename Neighbor_P, 00894 uint16_t MAX_CLUSTERS> 00895 void 00896 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00897 receive( node_id_t from, size_t len, block_data_t *data ) 00898 { 00899 #ifdef HIGHWAY_METHOD_DEBUG 00900 // debug().debug("@@ %d METHOD_CALLED: receive()\n", radio().id()); 00901 #endif 00902 00903 // Ignore if heard oneself's message. 00904 if ( from == radio().id() ) 00905 { 00906 return; 00907 } 00908 memcpy( &buffer_, data, len); 00909 00910 #ifdef HIGHWAY_MSG_RECV_DEBUG 00911 if ( buffer_[0] == CANDIDACY ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: CANDIDACY\n", radio().id(), from ); 00912 else if ( buffer_[0] == PORT_REQ ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_REQ\n", radio().id(), from ); 00913 else if ( buffer_[0] == PORT_REQ2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_REQ2\n", radio().id(), from ); 00914 else if ( buffer_[0] == PORT_ACK ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_ACK\n", radio().id(), from ); 00915 else if ( buffer_[0] == PORT_ACK2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_ACK2\n", radio().id(), from ); 00916 else if ( buffer_[0] == PORT_NACK ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_NACK\n", radio().id(), from ); 00917 else if ( buffer_[0] == PORT_NACK2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_NACK2\n", radio().id(), from ); 00918 else if ( buffer_[0] == SEND ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: SEND\n", radio().id(), from ); 00919 else if ( buffer_[0] == SEND2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: SEND2\n", radio().id(), from ); 00920 #endif 00921 00922 #ifdef CTI_VISOR 00923 if ( buffer_[0] == CANDIDACY ) debug().debug( "HWY_MSG; CAND; %d; %d", radio().id(), from ); 00924 else if ( buffer_[0] == PORT_REQ or buffer_[0] == PORT_REQ2 ) debug().debug( "HWY_MSG; REQ; %d; %d", radio().id(), from ); 00925 else if ( buffer_[0] == PORT_ACK or buffer_[0] == PORT_ACK2 ) debug().debug( "HWY_MSG; PACK; %d; %d", radio().id(), from ); 00926 else if ( buffer_[0] == PORT_NACK or buffer_[0] == PORT_NACK2 ) debug().debug( "HWY_MSG; PNACK; %d; %d", radio().id(), from ); 00927 else if ( buffer_[0] == SEND or buffer_[0] == SEND2 ) debug().debug( "HWY_MSG; SEND; %d; %d", radio().id(), from ); 00928 else if ( buffer_[0] == ACK or buffer_[0] == ACK2 ) debug().debug( "HWY_MSG; ACK; %d; %d", radio().id(), from ); 00929 #endif 00930 00931 #ifdef HWY_METRICS 00932 if ( buffer_[0] == CANDIDACY ) r_cand++; 00933 else if ( buffer_[0] == PORT_REQ ) r_req++; 00934 else if ( buffer_[0] == PORT_REQ2 ) r_req2++; 00935 else if ( buffer_[0] == PORT_ACK ) r_pack++; 00936 else if ( buffer_[0] == PORT_ACK2 ) r_pack2++; 00937 else if ( buffer_[0] == PORT_NACK ) r_pnack++; 00938 else if ( buffer_[0] == PORT_NACK2 ) r_pnack2++; 00939 else if ( buffer_[0] == SEND ) r_send++; 00940 else if ( buffer_[0] == SEND2 ) r_send2++; 00941 else if ( buffer_[0] == ACK ) r_ack++; 00942 else if ( buffer_[0] == ACK2 ) r_ack2++; 00943 #endif 00944 00945 00946 // Messages travelling to the current node cluster leader are processed in send_to_leader 00947 if ( buffer_[0] == CANDIDACY or buffer_[0] == PORT_REQ2 or buffer_[0] == PORT_ACK2 or buffer_[0] == PORT_NACK2 or buffer_[0] == SEND2 or buffer_[0] == ACK2 ) 00948 { 00949 send_to_leader( from, len, buffer_ ); 00950 } 00951 else if ( buffer_[0] == PORT_REQ or buffer_[0] == PORT_ACK or buffer_[0] == PORT_NACK ) // Construction messages travelling outwards 00952 { 00953 send_away( from, len, buffer_ ); 00954 } 00955 else if ( buffer_[0] == SEND or buffer_[0] == ACK ) // Data messages travelling outwards. 00956 { 00957 process_send( from, len, buffer_ ); 00958 } 00959 } 00960 00961 // ----------------------------------------------------------------------- 00962 00963 template<typename OsModel_P, 00964 typename RoutingTable_P, 00965 typename Cluster_P, 00966 typename Neighbor_P, 00967 uint16_t MAX_CLUSTERS> 00968 void 00969 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00970 send_to_leader( node_id_t from, size_t len, block_data_t *data ) 00971 { 00972 #ifdef HIGHWAY_METHOD_DEBUG 00973 debug().debug( "@@ %d METHOD_CALLED: send_to_leader()\n", radio().id()) ; 00974 #endif 00975 uint8_t type = data[0]; 00976 00977 #ifdef HIGHWAY_MSG_RECV_DEBUG 00978 if( type == SEND2 ) 00979 { 00980 debug().debug( "---------------SENDRECV2--------------\n" ); 00981 for( int i = 0; i<len; ++i ) 00982 debug().debug( "Data[%d]: %d\n", i, data[i] ); 00983 debug().debug( "---------------/SENDRECV2--------------\n" ); 00984 } 00985 #endif 00986 00987 get_msg_highway( &msg_highway_, data ); 00988 00989 if( type == CANDIDACY ) 00990 { 00991 routing_table_[msg_highway_.source] = from; 00992 } 00993 else if( type == PORT_REQ2 ) 00994 { 00995 routing_table_[msg_highway_.target] = from; 00996 } 00997 else if( type == PORT_ACK2 ) 00998 { 00999 // Improve: put it on the highway_table for fault tolerance 01000 #ifdef VISOR_DEBUG 01001 debug().debug( "$%d->%d$h\n", from, radio_->id() ); 01002 #endif 01003 #ifdef CTI_VISOR 01004 debug().debug( "HWY_EDGE; %d; %d", from, radio_->id() ); 01005 #endif 01006 } 01007 01008 if( cluster().is_cluster_head() ) 01009 { 01010 cluster_head_work( from, len, data ); 01011 } 01012 else 01013 { 01014 radio().send( cluster().parent(), len, data ); 01015 } 01016 #ifdef HIGHWAY_METHOD_DEBUG 01017 debug().debug( "@@ %d METHOD_ENDED: send_to_leader()\n", radio().id()) ; 01018 #endif 01019 } 01020 01021 // ----------------------------------------------------------------------- 01022 01023 template<typename OsModel_P, 01024 typename RoutingTable_P, 01025 typename Cluster_P, 01026 typename Neighbor_P, 01027 uint16_t MAX_CLUSTERS> 01028 void 01029 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01030 send_away( node_id_t from, size_t len, block_data_t *data ) 01031 { 01032 #ifdef HIGHWAY_METHOD_DEBUG 01033 debug().debug("@@ %d METHOD_CALLED: send_away()\n", radio().id()); 01034 #endif 01035 01036 #ifdef VISOR_DEBUG 01037 if( *data == PORT_ACK ) 01038 debug().debug("$%d->%d$h\n", from, radio_->id()); 01039 #endif 01040 #ifdef CTI_VISOR 01041 debug().debug( "HWY_EDGE; %d; %d", from, radio_->id()); 01042 #endif 01043 01044 //msg_highway_ = * ((msg_highway * ) data); 01045 get_msg_highway( &msg_highway_, data ); 01046 01047 // Check if we are still in the cluster that originated the request. 01048 if ( from == cluster().parent() ) 01049 { 01050 // If the current node is not the port, continue the way to the port. 01051 if ( msg_highway_.msg_id == PORT_REQ && msg_highway_.source != radio().id() ) 01052 { 01053 radio().send( routing_table_[msg_highway_.source], HWY_MSG_SIZE, data ); 01054 #ifdef HIGHWAY_DEBUG 01055 debug().debug( "Still same cluster, not yet port, sending PORT_REQ through %d", msg_highway_.source ); 01056 #endif 01057 } 01058 else if ( msg_highway_.msg_id == PORT_ACK && msg_highway_.target != radio().id() ) 01059 { 01060 radio().send( routing_table_[msg_highway_.target], HWY_MSG_SIZE, data ); 01061 #ifdef HIGHWAY_DEBUG 01062 debug().debug( "Still same cluster, not yet port, sending PORT_REQ through %d", msg_highway_.target ); 01063 #endif 01064 } 01065 else // It is the port. Send the message to the other cluster port and set the port to highway status(if needed). 01066 { 01067 if ( msg_highway_.msg_id == PORT_REQ ) 01068 { 01069 radio().send( msg_highway_.target, HWY_MSG_SIZE, data ); 01070 #ifdef HIGHWAY_DEBUG 01071 debug().debug( "Still same cluster, already port, passing request to %d", msg_highway_.target ); 01072 #endif 01073 #ifdef HWY_METRICS 01074 s_req++; 01075 #endif 01076 } 01077 else if ( msg_highway_.msg_id == PORT_ACK ) { 01078 #ifdef HIGHWAY_DEBUG 01079 debug().debug( "Still same cluster, already port, passing pack to %d", msg_highway_.target ); 01080 #endif 01081 highway_table_[msg_highway_.sid_source] = entry( source_target( msg_highway_.target, msg_highway_.source ), hops_ack( msg_highway_.hops, 0 ) ); 01082 radio().send( msg_highway_.source, HWY_MSG_SIZE, data ); 01083 #ifdef HWY_METRICS 01084 s_pack++; 01085 #endif 01086 } 01087 else //NACK 01088 { 01089 #ifdef HIGHWAY_DEBUG 01090 debug().debug( "Still same cluster, already port, passing pnack to %d", msg_highway_.target ); 01091 #endif 01092 radio().send( msg_highway_.source, HWY_MSG_SIZE, data ); 01093 #ifdef HWY_METRICS 01094 s_pnack++; 01095 #endif 01096 } 01097 } 01098 } 01099 else // Create a "2" message. 01100 { 01101 #ifdef HIGHWAY_DEBUG 01102 debug().debug( "Passed to new cluster cluster" ); 01103 #endif 01104 if ( msg_highway_.msg_id == PORT_REQ ) 01105 { 01106 #ifdef HIGHWAY_DEBUG 01107 debug().debug( "^^%d transforming to PORT_REQ2 and sending to %d", cluster().is_cluster_head(), cluster().parent() ); 01108 #endif 01109 msg_highway_.msg_id = PORT_REQ2; 01110 #ifdef HWY_METRICS 01111 s_req2++; 01112 #endif 01113 } 01114 else if ( msg_highway_.msg_id == PORT_ACK ) { 01115 #ifdef VISOR_DEBUG 01116 debug().debug( "+%d#%d#%d#1\n", radio().id(), cluster().cluster_id(), cluster().is_cluster_head() ); 01117 debug().debug( "+%d#%d#%d#1\n", from, msg_highway_.sid_target, cluster().is_cluster_head() ); 01118 #endif 01119 #ifdef CTI_VISOR 01120 debug().debug( "HWY_PORTS; %d; %d", radio().id(), from ); 01121 #endif 01122 msg_highway_.msg_id = PORT_ACK2; 01123 highway_table_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, from ), hops_ack( msg_highway_.hops, 0 ) ); 01124 #ifdef HWY_METRICS 01125 s_pack2++; 01126 #endif 01127 01128 } 01129 else //NACK 01130 { 01131 msg_highway_.msg_id = PORT_NACK2; 01132 #ifdef HWY_METRICS 01133 s_pnack2++; 01134 #endif 01135 } 01136 01137 set_msg_highway( buffer_, msg_highway_.msg_id, msg_highway_.hops, msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01138 radio().send( cluster().parent(), HWY_MSG_SIZE, buffer_ ); 01139 } 01140 #ifdef HIGHWAY_METHOD_DEBUG 01141 debug().debug("@@ %d METHOD_ENDED: send_away()\n", radio().id()); 01142 #endif 01143 } 01144 01145 // ----------------------------------------------------------------------- 01146 01147 template<typename OsModel_P, 01148 typename RoutingTable_P, 01149 typename Cluster_P, 01150 typename Neighbor_P, 01151 uint16_t MAX_CLUSTERS> 01152 void 01153 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01154 process_send( node_id_t from, size_t len, block_data_t *data ) 01155 { 01156 #ifdef HIGHWAY_METHOD_DEBUG 01157 debug().debug("@@ %d METHOD_CALLED: send_process()\n", radio().id()); 01158 #endif 01159 node_id_t port, destination; 01160 01161 #ifdef HIGHWAY_MSG_RECV_DEBUG 01162 debug().debug("---------------SENDRECV--------------\n"); 01163 for(int i = 0; i<len; ++i) 01164 debug().debug("Data[%d]: %d\n", i, data[i]); 01165 debug().debug("---------------/SENDRECV--------------\n"); 01166 #endif 01167 01168 // Check if we are still in the cluster that originated the request. 01169 if ( from == cluster().parent() ) 01170 { 01171 // If the current node is not the port, continue the way to the port. 01172 #ifdef ISENSE_APP 01173 port = ( data[4] << 8 ) | data[3]; 01174 destination = ( data[2] << 8 ) | data[1]; 01175 #else 01176 port = ( data[8] << 24 ) | ( data[7] << 16 ) | ( data[6] << 8 ) | data[5]; 01177 destination = ( data[4] << 24 ) | ( data[3] << 16 ) | ( data[2] << 8 ) | data[1]; 01178 #endif 01179 01180 if ( port != radio().id() ) 01181 { 01182 radio().send( routing_table_[port], len, data ); 01183 } 01184 else // Send the message to the other cluster port. 01185 { 01186 radio().send( highway_table_[destination].first.second, len, data ); 01187 #ifdef HWY_METRICS 01188 s_send++; 01189 #endif 01190 } 01191 } 01192 else // Create a "2" message. 01193 { 01194 if(*data == SEND) 01195 { 01196 *data = SEND2; 01197 #ifdef HWY_METRICS 01198 s_send2++; 01199 #endif 01200 } 01201 else 01202 { 01203 *data = ACK2; 01204 #ifdef HWY_METRICS 01205 s_ack2++; 01206 #endif 01207 } 01208 radio().send( cluster().parent(), len, data ); 01209 } 01210 #ifdef HIGHWAY_METHOD_DEBUG 01211 debug().debug("@@ %d METHOD_ENDED: send_process()\n", radio().id()); 01212 #endif 01213 } 01214 01215 // ----------------------------------------------------------------------- 01216 01217 template<typename OsModel_P, 01218 typename RoutingTable_P, 01219 typename Cluster_P, 01220 typename Neighbor_P, 01221 uint16_t MAX_CLUSTERS> 01222 void 01223 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01224 cluster_head_work( node_id_t from, size_t len, block_data_t *data ) 01225 { 01226 #ifdef HIGHWAY_METHOD_DEBUG 01227 debug().debug("@@ %d METHOD_CALLED: cluster_head_work()\n", radio().id() ); 01228 #endif 01229 node_id_t sender; 01230 01231 get_msg_highway( &msg_highway_, data ); 01232 01233 if ( msg_highway_.msg_id == CANDIDACY ) // Add the port candidate to the queue. 01234 { 01235 #ifdef HIGHWAY_DEBUG 01236 debug().debug( "Putting an entry to ports_queue on %d\n", radio().id() ); 01237 #endif 01238 // Check that the port candidate is better than the stored candidate 01239 if( ( ports_queue_[msg_highway_.sid_target].first.first != msg_highway_.source || ports_queue_[msg_highway_.sid_target].first.second != msg_highway_.target ) && ( ( ports_queue_[msg_highway_.sid_target].second.first == 0 ) || ( ports_queue_[msg_highway_.sid_target].second.first > msg_highway_.hops ) ) ) 01240 { 01241 ports_queue_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, msg_highway_.target ), hops_ack( msg_highway_.hops, 0 )); 01242 if( not cand_timer_set_ ) 01243 { 01244 cand_timer_set_ = 1; 01245 timer().template set_timer<self_type, &self_type::candidacies_timeout>( discovery_time_ , this, (void *) 0 ); 01246 } 01247 } 01248 } 01249 else if ( msg_highway_.msg_id == PORT_REQ2 ) // Accept or reject the highway request. 01250 { 01251 // iff there is no highway set or the ack of the current one are too high accept 01252 if( highway_table_[msg_highway_.sid_source].second.first == 0 || highway_table_[msg_highway_.sid_source].second.second > max_acks_ ) 01253 { 01254 highway_table_[msg_highway_.sid_source] = entry( source_target( msg_highway_.target, msg_highway_.source ), hops_ack( msg_highway_.hops, 0 ) ); 01255 msg_highway_.msg_id = PORT_ACK; 01256 #ifdef HWY_METRICS 01257 n_hwy++; 01258 s_pack++; 01259 #endif 01260 } 01261 else 01262 { 01263 msg_highway_.msg_id = PORT_NACK; 01264 #ifdef HWY_METRICS 01265 s_pack++; 01266 #endif 01267 } 01268 set_msg_highway( buffer_, msg_highway_.msg_id, msg_highway_.hops, msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01269 radio().send( from, HWY_MSG_SIZE, buffer_ ); 01270 } 01271 else if ( msg_highway_.msg_id == PORT_ACK2 ) // Establish the port. 01272 { 01273 highway_table_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, msg_highway_.target ), hops_ack( msg_highway_.hops, 0 ) ); 01274 #ifdef HWY_METRICS 01275 n_hwy += 1; 01276 #endif 01277 } 01278 else if ( msg_highway_.msg_id == PORT_NACK2 ) // Remove the port candidate. 01279 { 01280 //IMPROVE: Check if it is worth it to start a new negotiation if there's a new port in the queue 01281 /*if( ports_queue_[msg_highway_.sid_target].first.first != msg_highway_.source || ports_queue_[msg_highway_.sid_target].first.second != msg_highway_.target ) 01282 { 01283 if( ports_queue_[msg_highway_.sid_target].second.first != 0 && highway_table_[it->first].second.second > max_acks_ ) 01284 { 01285 set_msg_highway( buffer_, PORT_REQ, ports_queue_[msg_highway_.sid_target].second.first, ports_queue_[msg_highway_.sid_target].first.first, ports_queue_[msg_highway_.sid_target].first.second, cluster().cluster_id(), msg_highway_sid_target ); 01286 radio().send( routing_table_[ports_queue_[msg_highway_.sid_target].first.first], HWY_MSG_SIZE, buffer_ ); 01287 } 01288 ports_queue_.erase( it->first ); 01289 }*/ 01290 // Try to renegotiate 01291 candidacies_timeout( (void *) 0 ); 01292 } 01293 else 01294 { 01295 if ( *data == SEND2 ) // Send the msg_ack andi call the registered (if exists) receiving method. 01296 { 01297 #ifdef ISENSE_APP 01298 sender = (data[6] << 8) | data[5]; 01299 #else 01300 sender = ( data[12] << 24 ) | ( data[11] << 16 ) | ( data[10] << 8 ) | data[9]; 01301 #endif 01302 #ifdef HIGHWAY_MSG_RECV_DEBUG 01303 debug().debug( "---------------HEAD_WORK_RECV--------------\n" ); 01304 for( int i = 0; i<len; ++i ) 01305 debug().debug( "Data[%d]: %d\n", i, data[i] ); 01306 debug().debug( "---------------HEAD_WORK_RECV--------------\n" ); 01307 #endif 01308 send( false, sender, 0, data ); 01309 if( hwy_recv_callback_ ) hwy_recv_callback_(sender, len-SEND_OVERHEAD, &data[SEND_OVERHEAD]); 01310 } 01311 else if ( *data == ACK2 ) //Count the received ACKs from the highway 01312 { 01313 highway_table_[sender].second.second -= 1; 01314 } 01315 } 01316 #ifdef HIGHWAY_METHOD_DEBUG 01317 debug().debug("@@ %d METHOD_ENDED: cluster_head_work()\n", radio().id() ); 01318 #endif 01319 } 01320 01321 // ----------------------------------------------------------------------- 01322 01323 template<typename OsModel_P, 01324 typename RoutingTable_P, 01325 typename Cluster_P, 01326 typename Neighbor_P, 01327 uint16_t MAX_CLUSTERS> 01328 void 01329 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01330 send( bool send_ack, node_id_t destination, size_t len, block_data_t *data ) 01331 { 01332 #ifdef HIGHWAY_METHOD_DEBUG 01333 debug().debug( "@@ %d METHOD CALLED: send()\n", radio().id() ); 01334 #endif 01335 01336 node_id_t port = highway_table_[destination].first.first; 01337 if(send_ack) 01338 { 01339 buffer_[0] = SEND; 01340 highway_table_[destination].second.second += 1; 01341 #ifdef HWY_METRICS 01342 s_send++; 01343 #endif 01344 } 01345 else 01346 { 01347 buffer_[0] = ACK; 01348 #ifdef HWY_METRICS 01349 s_ack++; 01350 #endif 01351 } 01352 #ifdef ISENSE_APP 01353 buffer_[1] = destination & 0xFF; 01354 buffer_[2] = ( destination >> 8 ) & 0xFF; 01355 buffer_[3] = port & 0xFF; 01356 buffer_[4] = ( port >> 8 ) & 0xFF; 01357 buffer_[5] = radio().id() & 0xFF; 01358 buffer_[6] = ( radio().id() >> 8 ) & 0xFF; 01359 #else 01360 buffer_[1] = destination & 0xFF; 01361 buffer_[2] = ( destination >> 8 ) & 0xFF; 01362 buffer_[3] = ( destination >> 16 ) & 0xFF; 01363 buffer_[4] = ( destination >> 24 ) & 0xFF; 01364 buffer_[5] = port & 0xFF; 01365 buffer_[6] = ( port >> 8 ) & 0xFF; 01366 buffer_[7] = ( port >> 16 ) & 0xFF; 01367 buffer_[8] = ( port >> 24 ) & 0xFF; 01368 buffer_[9] = radio().id() & 0xFF; 01369 buffer_[10] = ( radio().id() >> 8 ) & 0xFF; 01370 buffer_[11] = ( radio().id() >> 16 ) & 0xFF; 01371 buffer_[12] = ( radio().id() >> 24 ) & 0xFF; 01372 #endif 01373 01374 #ifdef HIGHWAY_MSG_RECV_DEBUG 01375 debug().debug( "---------------ENCAPSULATING----------------\n" ); 01376 #endif 01377 01378 for (int i = SEND_OVERHEAD; i < ( len+SEND_OVERHEAD ); ++i) 01379 { 01380 buffer_[i] = data[i-SEND_OVERHEAD]; 01381 #ifdef HIGHWAY_MSG_RECV_DEBUG 01382 debug().debug( "Data item %d: %d\n", i-SEND_OVERHEAD, data[i-SEND_OVERHEAD] ); 01383 #endif 01384 } 01385 01386 01387 #ifdef HIGHWAY_MSG_RECV_DEBUG 01388 for (int i = 0; i < len+SEND_OVERHEAD; ++i) 01389 { 01390 debug().debug( "Buffer item %d: %d\n", i, buffer_[i] ); 01391 } 01392 #endif 01393 01394 #ifdef HIGHWAY_MSG_RECV_DEBUG 01395 debug().debug( "---------------/ENCAPSULATING----------------\n" ); 01396 #endif 01397 01398 radio().send( routing_table_[port], len+SEND_OVERHEAD, buffer_ ); 01399 #ifdef HIGHWAY_METHOD_DEBUG 01400 debug().debug( "@@ %d METHOD ENDED: send()\n", radio().id() ); 01401 #endif 01402 } 01403 01404 01405 // ----------------------------------------------------------------------- 01406 // Helper methods. | 01407 // ----------------------------------------------------------------------- 01408 01409 #ifdef HWY_METRICS 01410 template<typename OsModel_P, 01411 typename RoutingTable_P, 01412 typename Cluster_P, 01413 typename Neighbor_P, 01414 uint16_t MAX_CLUSTERS> 01415 void 01416 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01417 graph_print( void * userdata ) 01418 { 01419 #ifdef HIGHWAY_METHOD_DEBUG 01420 debug().debug( "@@ %d METHOD_CALLED: graph_print()\n", radio().id() ); 01421 #endif 01422 timer().template set_timer<self_type, &self_type::graph_print>( (millis_t)1000 , this, (void *) 0 ); 01423 time++; 01424 if(cluster().is_cluster_head()) 01425 debug().debug( "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", time, n_hwy, r_cand, r_req, r_req2, r_pack, r_pack2, r_pnack, r_pnack2, r_send, r_send2, r_ack, r_ack2, s_cand, s_req, s_req2, s_pack, s_pack2, s_pnack, s_pnack2, s_send, s_send2, s_ack, s_ack2 ); 01426 #ifdef HIGHWAY_METHOD_DEBUG 01427 debug().debug( "@@ %d METHOD_ENDED: graph_print()\n", radio().id() ); 01428 #endif 01429 } 01430 #endif 01431 01432 } 01433 #endif