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 HWY_DEBUG 00047 //#define HWY_SEND_DEBUG 00048 //#define HIGHWAY_METHOD_DEBUG 00049 //#define HIGHWAY_MSG_RECV_DEBUG 00050 //#define VISOR_DEBUG 00051 #define CTI_VISOR 00052 //#define TRACK_SEND_MSG 00053 #ifdef ISENSE_APP 00054 #define SEND_OVERHEAD 9 00055 #else 00056 #define SEND_OVERHEAD 17 00057 #endif 00058 //#define STABLE 00059 00060 namespace wiselib{ 00061 00069 template<typename OsModel_P, 00070 typename RoutingTable_P, 00071 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> >, 00072 typename Neighbor_P = wiselib::Echo<OsModel_P, typename OsModel_P::TxRadio, typename OsModel_P::Timer, typename OsModel_P::Debug>, 00073 uint16_t MAX_CLUSTERS = 8> 00074 class HighwayCluster 00075 { 00076 public: 00077 00078 // OS modules. 00079 typedef OsModel_P OsModel; 00080 typedef typename OsModel::Rand Rand; 00081 typedef typename OsModel::TxRadio Radio; 00082 typedef typename OsModel::Timer Timer; 00083 typedef typename OsModel::Clock Clock; 00084 typedef typename OsModel::Debug Debug; 00085 typedef typename OsModel::TxRadio TxRadio; 00086 00087 // Type definitions. 00088 typedef wiselib::AtributeClusterHeadDecision<OsModel, TxRadio> CHD_t; 00089 typedef wiselib::BfsJoinDecision<OsModel, TxRadio> JD_t; 00090 typedef wiselib::FrontsIterator<OsModel, TxRadio> IT_t; 00091 00092 // Type definition of the used Templates. 00093 typedef RoutingTable_P RoutingTable; 00094 typedef Cluster_P Cluster; 00095 typedef Neighbor_P Neighbor; 00096 typedef typename RoutingTable::iterator routing_iterator; 00097 00098 typedef HighwayCluster<OsModel, RoutingTable, Cluster, Neighbor, MAX_CLUSTERS> self_type; 00099 typedef wiselib::Echo<OsModel, TxRadio, Timer, Debug> nb_t; 00100 typedef self_type* self_pointer_t; 00101 00102 // Basic types definition. 00103 typedef typename Radio::node_id_t node_id_t; 00104 typedef typename Radio::size_t size_t; 00105 typedef typename Radio::block_data_t block_data_t; 00106 typedef typename Timer::millis_t millis_t; 00107 00108 // Type definition for the receive callback. 00109 typedef delegate3<void, node_id_t, size_t, block_data_t*> highway_delegate_t; 00110 00111 // Type definition for the special data structures of the highway. 00112 typedef wiselib::pair<uint8_t, int8_t> hops_ack; 00113 typedef wiselib::pair<node_id_t, node_id_t> source_target; 00114 typedef wiselib::pair<source_target, hops_ack> entry; 00115 typedef wiselib::MapStaticVector<OsModel, node_id_t, entry, MAX_CLUSTERS> HighwayTable; 00116 typedef HighwayTable PortsQueue; 00117 typedef wiselib::vector_static<OsModel, node_id_t, MAX_CLUSTERS> Node_vect; 00118 00119 // Type definition for the special types iterators. 00120 typedef typename HighwayTable::iterator highway_iterator; 00121 00122 // Return types definition. 00123 enum ErrorCodes { 00124 SUCCESS = OsModel::SUCCESS, 00125 ERR_UNSPEC = OsModel::ERR_UNSPEC 00126 }; 00127 00128 // Possible highway message ids. 00129 enum msg_id { 00130 CANDIDACY = 30, 00131 PORT_REQ = 31, 00132 PORT_REQ2 = 32, 00133 PORT_ACK = 33, 00134 PORT_ACK2 = 34, 00135 PORT_NACK = 35, 00136 PORT_NACK2 = 36, 00137 SEND = 37, 00138 SEND2 = 38, 00139 ACK = 39, 00140 ACK2 = 40 00141 }; 00142 00143 // -------------------------------------------------------------------- 00144 // Public method declaration. | 00145 // -------------------------------------------------------------------- 00146 00149 HighwayCluster(): 00150 radio_ ( 0 ), 00151 timer_ ( 0 ), 00152 clock_ ( 0 ), 00153 debug_ ( 0 ), 00154 rand_ ( 0 ), 00155 cluster_ ( 0 ), 00156 discovery_time_ ( 5000 ), 00157 disc_timer_set_(false), 00158 cand_timer_set_(false), 00159 max_acks_(15), 00160 reg_callback_ ( false ), 00161 enabled_(false) 00162 { 00163 }; 00164 00167 ~HighwayCluster(){}; 00168 00169 00173 int init( TxRadio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Rand& rand, Cluster& cluster, Neighbor& neighbor ); 00174 00178 void enable( void ); 00179 00186 void send( node_id_t receiver, size_t len, block_data_t *data ); 00187 00192 //Node_vect cluster_neighbors(); 00193 void cluster_neighbors(Node_vect * neighbor); 00194 00198 template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)> 00199 uint8_t hwy_reg_recv_callback(T *obj_pnt) { 00200 hwy_recv_callback_ = highway_delegate_t::template from_method<T, TMethod > ( obj_pnt ); 00201 reg_callback_ = true; 00202 return 0; 00203 } 00204 00207 void unreg_hwy_recv_callback() { 00208 hwy_recv_callback_ = highway_delegate_t(); 00209 reg_callback_ = false; 00210 } 00211 00214 inline void disable(void) { 00215 // Unregister the callback 00216 radio().unreg_recv_callback(radio_callback_id_); 00217 cluster().disable(); 00218 enabled_ = false; 00219 #ifdef CTI_VISOR 00220 debug().debug( "HWY_SHUT" ); 00221 #endif 00222 } 00223 ; 00224 00225 // -------------------------------------------------------------------- 00226 // Setters | 00227 // -------------------------------------------------------------------- 00228 00232 inline void set_discovery_time( millis_t t ) { 00233 discovery_time_ = t; 00234 }; 00235 00239 inline void set_max_acks( uint8_t m ) { 00240 max_acks_ = m; 00241 }; 00242 00243 private: 00244 // Typenaming the underlying modules. 00245 typename Radio::self_pointer_t radio_; 00246 typename Timer::self_pointer_t timer_; 00247 typename Clock::self_pointer_t clock_; 00248 typename Debug::self_pointer_t debug_; 00249 typename Rand::self_pointer_t rand_; 00250 typename Cluster::self_type* cluster_; 00251 typename Neighbor::self_t* neighbor_; 00252 00253 // Highway control message. 00254 struct msg_highway { 00255 uint8_t msg_id, hops; 00256 node_id_t source, target, sid_source, sid_target; 00257 }; 00258 00259 enum msg_highway_size { 00260 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 ) 00261 }; 00262 00273 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 ); 00274 00280 void get_msg_highway( msg_highway * msg, uint8_t * data ); 00281 00282 // -------------------------------------------------------------------- 00283 // Private variables declaration. | 00284 // -------------------------------------------------------------------- 00285 00287 msg_highway msg_highway_; 00288 00290 millis_t discovery_time_; 00291 00293 bool disc_timer_set_; 00294 00296 bool cand_timer_set_; 00297 00299 highway_delegate_t hwy_recv_callback_; 00300 00301 00303 RoutingTable routing_table_; 00304 00306 HighwayTable highway_table_; 00307 00309 PortsQueue ports_queue_; 00310 00312 block_data_t buffer_[Radio::MAX_MESSAGE_LENGTH]; 00313 00315 int8_t max_acks_; 00316 int radio_callback_id_; 00317 bool reg_callback_; 00318 bool enabled_; 00319 node_id_t clus_head_; 00320 00321 00323 CHD_t CHD_; 00324 JD_t JD_; 00325 IT_t IT_; 00326 00327 00328 // -------------------------------------------------------------------- 00329 // Private method declaration. | 00330 // -------------------------------------------------------------------- 00331 00339 void send( bool send_ack, node_id_t receiver, size_t len, block_data_t *data ); 00340 00344 Radio& radio() { 00345 return *radio_; 00346 } 00347 00351 Timer& timer() { 00352 return *timer_; 00353 } 00354 00358 Clock& clock() { 00359 return *clock_; 00360 } 00361 00365 Debug& debug() { 00366 return *debug_; 00367 } 00368 00372 Cluster& cluster() { 00373 return *cluster_; 00374 } 00375 00379 Neighbor& neighbor() { 00380 return *neighbor_; 00381 } 00382 00387 void cluster_callback(int state); 00388 00389 void clean_highways( bool all, bool notify ); 00390 00394 void cluster_discovery( void ); 00395 00403 void neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data); 00404 00409 void discovery_timeout( void *userdata ); 00410 00415 void candidacies_timeout( void *userdata ); 00416 00423 void receive( node_id_t from, size_t len, block_data_t *data ); 00424 00431 void send_to_leader( node_id_t from, size_t len, block_data_t *data ); 00432 00439 void send_away( node_id_t from, size_t len, block_data_t *data ); 00440 00447 void process_send( node_id_t from, size_t len, block_data_t *data ); 00448 00455 void cluster_head_work( node_id_t from, size_t len, block_data_t *data ); 00456 00457 00458 }; // End of class declaration. 00459 00460 // -------------------------------------------------------------------- 00461 // Start of the method code: PUBLIC METHODS | 00462 // -------------------------------------------------------------------- 00463 template<typename OsModel_P, 00464 typename RoutingTable_P, 00465 typename Cluster_P, 00466 typename Neighbor_P, 00467 uint16_t MAX_CLUSTERS> 00468 inline int 00469 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00470 init( TxRadio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Rand& rand, Cluster& cluster, Neighbor& neighbor ) { 00471 radio_ = &tx_radio; 00472 timer_ = &timer; 00473 clock_ = &clock; 00474 debug_ = &debug; 00475 rand_ = &rand; 00476 cluster_ = &cluster; 00477 neighbor_ = &neighbor; 00478 00479 // Initialize the neighborhood discovery module. 00480 neighbor_->init( tx_radio, *clock_, *timer_, *debug_ ); 00481 if ( neighbor_->register_payload_space( HWY_N ) !=0 ) 00482 { 00483 #ifdef HIGHWAY_DEBUG 00484 debug().debug( "Error registering payload space" ); 00485 #endif 00486 } 00487 00488 clus_head_ = 0; 00489 00490 // Stabilizing cluster initialization. 00491 // set the HeadDecision Module 00492 cluster_->set_cluster_head_decision( CHD_ ); 00493 // set the JoinDecision Module 00494 cluster_->set_join_decision( JD_ ); 00495 // set the Iterator Module 00496 cluster_->set_iterator( IT_ ); 00497 cluster_->init( *radio_, *timer_, *debug_, *rand_, *neighbor_ ); 00498 00499 //cluster_->set_maxhops( 1 ); 00500 cluster_->set_maxhops( 2 ); 00501 00502 return SUCCESS; 00503 } 00504 00505 // -------------------------------------------------------------------- 00506 00507 template<typename OsModel_P, 00508 typename RoutingTable_P, 00509 typename Cluster_P, 00510 typename Neighbor_P, 00511 uint16_t MAX_CLUSTERS> 00512 void 00513 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00514 enable( void ) 00515 { 00516 #ifdef HIGHWAY_METHOD_DEBUG 00517 debug().debug( "@@ %x METHOD CALLED: enable()\n", radio().id() ); 00518 #endif 00519 enabled_ = true; 00520 // Enabling and registering radio 00521 radio().enable_radio(); 00522 radio_callback_id_ = radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00523 00524 // Enabling neighborhood and registering cluster 00525 cluster().enable(); 00526 cluster().template reg_state_changed_callback<self_type, &self_type::cluster_callback > ( this ); 00527 neighbor().enable(); 00528 00529 neighbor().template reg_event_callback<HighwayCluster,&HighwayCluster::neighbor_callback>( HWY_N, nb_t::NEW_PAYLOAD_BIDI, this ); 00530 00531 #ifdef HIGHWAY_METHOD_DEBUG 00532 debug().debug( "@@ %x METHOD ENDED: enable()\n", radio().id() ); 00533 #endif 00534 } 00535 00536 // -------------------------------------------------------------------- 00537 00538 template<typename OsModel_P, 00539 typename RoutingTable_P, 00540 typename Cluster_P, 00541 typename Neighbor_P, 00542 uint16_t MAX_CLUSTERS> 00543 void 00544 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00545 send( node_id_t destination, size_t len, block_data_t *data ) 00546 { 00547 if(!enabled_) 00548 return; 00549 #ifdef HIGHWAY_METHOD_DEBUG 00550 debug().debug( "@@ %x METHOD CALLED: send()\n", radio().id() ); 00551 #endif 00552 00553 send(true, destination, len, data); 00554 00555 #ifdef HIGHWAY_METHOD_DEBUG 00556 debug().debug( "@@ %x METHOD ENDED: send()\n", radio().id() ); 00557 #endif 00558 } 00559 00560 // ----------------------------------------------------------------------- 00561 00562 template<typename OsModel_P, 00563 typename RoutingTable_P, 00564 typename Cluster_P, 00565 typename Neighbor_P, 00566 uint16_t MAX_CLUSTERS> 00567 void 00568 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00569 cluster_neighbors( Node_vect * neighbors ) 00570 { 00571 if(!enabled_) 00572 return; 00573 #ifdef HIGHWAY_METHOD_DEBUG 00574 debug().debug( "@@ %x METHOD CALLED: cluster_neighbors()\n", radio().id() ); 00575 #endif 00576 00577 neighbors->clear(); 00578 if ( not cluster().is_cluster_head() ) 00579 return; 00580 00581 clean_highways( false, true ); 00582 00583 for ( highway_iterator it = highway_table_.begin(); it != highway_table_.end(); ++it ) 00584 neighbors->push_back( it->first ); 00585 00586 #ifdef HIGHWAY_METHOD_DEBUG 00587 debug().debug( "@@ %x METHOD ENDED: cluster_neighbors()\n", radio().id() ); 00588 #endif 00589 } 00590 00591 // ----------------------------------------------------------------------- 00592 // PRIVATE METHODS | 00593 // ----------------------------------------------------------------------- 00594 00595 template<typename OsModel_P, 00596 typename RoutingTable_P, 00597 typename Cluster_P, 00598 typename Neighbor_P, 00599 uint16_t MAX_CLUSTERS> 00600 void 00601 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00602 clean_highways( bool all, bool notify ) 00603 { 00604 if(!enabled_) 00605 return; 00606 highway_iterator it = highway_table_.begin(); 00607 while( it != highway_table_.end() ) 00608 { 00609 if( all || it->second.second.second > max_acks_ ) 00610 { 00611 if(notify) 00612 { 00613 #ifdef CTI_VISOR 00614 debug().debug( "HWY_DEL; %x; %x; %x; %x", it->second.first.second, it->second.first.first, it->first, clus_head_ ); 00615 #endif 00616 // Create a CANDIDACY highway message with: hops, port_source, port_target, cluster_id_own, cluster_id_target. 00617 set_msg_highway( buffer_, PORT_NACK, it->second.second.first, it->second.first.second, it->second.first.first, it->first, clus_head_ ); 00618 00619 if( radio().id() == it->second.first.first ) 00620 { 00621 radio().send(it->second.first.second, HWY_MSG_SIZE, buffer_); 00622 } 00623 else 00624 { 00625 routing_iterator rit = routing_table_.find( it->second.first.first ); 00626 if( rit != routing_table_.end() ) 00627 radio().send(rit->second, HWY_MSG_SIZE, buffer_); 00628 } 00629 } 00630 highway_table_.erase(it->first); 00631 it = highway_table_.begin(); 00632 } 00633 else 00634 { 00635 ++it; 00636 } 00637 } 00638 } 00639 00640 // ----------------------------------------------------------------------- 00641 00642 template<typename OsModel_P, 00643 typename RoutingTable_P, 00644 typename Cluster_P, 00645 typename Neighbor_P, 00646 uint16_t MAX_CLUSTERS> 00647 void 00648 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00649 cluster_callback( int state ) 00650 { 00651 if(!enabled_) 00652 return; 00653 #ifdef HIGHWAY_METHOD_DEBUG 00654 debug().debug( "@@ %x METHOD_CALLED: cluster_callback()\n", radio().id() ); 00655 #endif 00656 00657 #ifdef VISOR_DEBUG 00658 debug().debug( "+%d#%d#%d#1\n", radio().id(), cluster().cluster_id(), cluster().is_cluster_head() ); 00659 #endif 00660 00661 // Check if it is a real change. 00662 if( clus_head_ != cluster().cluster_id() ) 00663 { 00664 #ifdef CTI_VISOR 00665 debug().debug( "HWY_CLUS; %x; %x", cluster().cluster_id(), cluster().parent() ); 00666 #endif 00667 clean_highways( true, clus_head_ == radio().id() ); 00668 ports_queue_.clear(); 00669 routing_table_.clear(); 00670 clus_head_ = cluster().cluster_id(); 00671 cluster_discovery(); 00672 } 00673 00674 #ifdef HIGHWAY_METHOD_DEBUG 00675 debug().debug( "@@ %x METHOD_ENDED: clustering_callback()\n", radio().id() ); 00676 #endif 00677 } 00678 00679 // ----------------------------------------------------------------------- 00680 00681 template<typename OsModel_P, 00682 typename RoutingTable_P, 00683 typename Cluster_P, 00684 typename Neighbor_P, 00685 uint16_t MAX_CLUSTERS> 00686 void 00687 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00688 cluster_discovery( void ) 00689 { 00690 if(!enabled_) 00691 return; 00692 #ifdef HIGHWAY_METHOD_DEBUG 00693 debug().debug( "@@ %x METHOD CALLED: cluster_discovery()\n", radio().id() ); 00694 #endif 00695 00696 // Add the piggybacking information to the neighborhood discovery module. 00697 node_id_t id = cluster().cluster_id(); 00698 uint8_t length; 00699 00700 // Adapt cluster_id to the node_id_t size of the plattform. 00701 #ifdef ISENSE_APP 00702 uint8_t sid_buf[3]; 00703 sid_buf[0] = id & 0xFF; 00704 sid_buf[1] = id >> 8; 00705 sid_buf[2] = cluster().hops()+1; 00706 length = 3; 00707 #else 00708 uint8_t sid_buf[5]; 00709 sid_buf[0] = id & 0xFF; 00710 sid_buf[1] = ( id >> 8 ) & 0xFF; 00711 sid_buf[2] = ( id >> 16 ) & 0xFF; 00712 sid_buf[3] = ( id >> 24 ) & 0xFF; 00713 sid_buf[4] = cluster().hops()+1; 00714 length = 5; 00715 #endif 00716 00717 // Register and add the payload space to the neighborhood discovery module. 00718 00719 if(neighbor().set_payload( HWY_N, sid_buf, length )!=0 ) 00720 { 00721 #ifdef HWY_DEBUG 00722 debug().debug( "Error setting payload" ); 00723 #endif 00724 } 00725 else 00726 { 00727 #ifdef HWY_DEBUG 00728 debug().debug( "Registering neighborhood" ); 00729 #endif 00730 if( not disc_timer_set_ ) 00731 { 00732 disc_timer_set_ = true; 00733 timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ , this, (void *) 0 ); 00734 } 00735 } 00736 #ifdef HIGHWAY_METHOD_DEBUG 00737 debug().debug( "@@ %x METHOD ENDED: cluster_discovery()\n", radio().id() ); 00738 #endif 00739 } 00740 00741 // ----------------------------------------------------------------------- 00742 00743 template<typename OsModel_P, 00744 typename RoutingTable_P, 00745 typename Cluster_P, 00746 typename Neighbor_P, 00747 uint16_t MAX_CLUSTERS> 00748 void 00749 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00750 neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data) 00751 { 00752 if(!enabled_) 00753 return; 00754 #ifdef HIGHWAY_METHOD_DEBUG 00755 debug().debug("@@ %x METHOD CALLED: neighbor_callback()\n", radio().id()); 00756 #endif 00757 00758 memcpy( buffer_, data, len ); 00759 00760 node_id_t sid; 00761 uint8_t hops; 00762 00763 // On payload event, process the data according to the plattform 00764 if ( nb_t::NEW_PAYLOAD_BIDI == event ) { 00765 #ifdef ISENSE_APP 00766 sid = ( buffer_[1] << 8 ) | buffer_[0]; 00767 hops = buffer_[2]; 00768 #else 00769 sid = ( buffer_[3] << 24 ) | ( buffer_[2] << 16 ) | ( buffer_[1] << 8 ) | buffer_[0]; 00770 hops = buffer_[4]; 00771 #endif 00772 00773 // If the message is from another cluster add it to the ports queue. 00774 if ( cluster().cluster_id() != sid && sid != radio().id() && ( cluster().is_cluster_head() || cluster().hops() != 0 ) ) 00775 { 00776 #ifdef HIGHWAY_DEBUG 00777 debug().debug( "%d NB_disc <-%d+%d-%x(%x)", cluster().is_cluster_head(), cluster().hops(), hops, from, sid ); 00778 #endif 00779 //Check if it is new and that it is better than the current one 00780 highway_iterator it = ports_queue_.find( sid ); 00781 #ifdef STABLE 00782 if( it == ports_queue_.end() || it->second.second.first > hops ) 00783 #else 00784 if( true ) 00785 #endif 00786 { 00787 ports_queue_[sid] = entry( source_target( radio().id(), from ), hops_ack( hops+cluster().hops(), 0 )); 00788 } 00789 else 00790 { 00791 //debug().debug( "%d Refused NB_disc <-%d+%d-%x(%x)", cluster().is_cluster_head(), cluster().hops(), hops, from, sid ); 00792 return; 00793 } 00794 00795 if( cluster().is_cluster_head() ) 00796 { 00797 if( not cand_timer_set_ ) 00798 { 00799 cand_timer_set_ = true; 00800 timer().template set_timer<self_type, &self_type::candidacies_timeout>( discovery_time_ , this, (void *) 0 ); 00801 } 00802 } 00803 else 00804 { 00805 if( not disc_timer_set_ ) 00806 { 00807 disc_timer_set_ = true; 00808 timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ , this, (void *) 0 ); 00809 } 00810 } 00811 } 00812 00813 } 00814 #ifdef HIGHWAY_METHOD_DEBUG 00815 debug().debug("@@ %x METHOD ENDED: neighbor_callback()\n", radio().id()); 00816 #endif 00817 } 00818 00819 // ----------------------------------------------------------------------- 00820 00821 template<typename OsModel_P, 00822 typename RoutingTable_P, 00823 typename Cluster_P, 00824 typename Neighbor_P, 00825 uint16_t MAX_CLUSTERS> 00826 void 00827 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00828 discovery_timeout( void *userdata ) 00829 { 00830 if(!enabled_) 00831 return; 00832 #ifdef HIGHWAY_METHOD_DEBUG 00833 debug().debug( "@@ %x METHOD CALLED: discovery_timeout()\n", radio().id()); 00834 #endif 00835 00836 highway_iterator pit, hit; 00837 for ( pit = ports_queue_.begin(); pit != ports_queue_.end(); ++pit ) 00838 { 00839 //Check if the port candidate is already set as highway 00840 hit = highway_table_.find( pit->first ); 00841 if( hit != highway_table_.end() && hit->second.first.first == pit->second.first.first && hit->second.first.second == pit->second.first.second ) 00842 { 00843 //debug().debug( "There was already highway for %x", pit->first ); 00844 continue; 00845 } 00846 // Create a CANDIDACY highway message with: hops, port_source, port_target, cluster_id_own, cluster_id_target. 00847 set_msg_highway( buffer_, CANDIDACY, pit->second.second.first, radio().id(), pit->second.first.second, cluster().cluster_id(), pit->first ); 00848 00849 if( cluster().is_cluster_head() ) 00850 { 00851 cluster_head_work( radio().id(), HWY_MSG_SIZE, buffer_ ); 00852 } 00853 else 00854 { 00855 // Send it to the parent. 00856 radio().send( cluster().parent(), HWY_MSG_SIZE, buffer_ ); 00857 } 00858 } 00859 ports_queue_.clear(); 00860 disc_timer_set_ = false; 00861 #ifdef HIGHWAY_METHOD_DEBUG 00862 debug().debug( "@@ %x METHOD ENDED: discovery_timeout()\n", radio().id() ); 00863 #endif 00864 } 00865 00866 // ----------------------------------------------------------------------- 00867 00868 template<typename OsModel_P, 00869 typename RoutingTable_P, 00870 typename Cluster_P, 00871 typename Neighbor_P, 00872 uint16_t MAX_CLUSTERS> 00873 void 00874 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00875 candidacies_timeout( void *userdata ) 00876 { 00877 if(!enabled_) 00878 return; 00879 #ifdef HIGHWAY_METHOD_DEBUG 00880 debug().debug( "@@ %x METHOD STARTED: candidacies_timeout()\n", radio().id() ); 00881 #endif 00882 if( !cluster().is_cluster_head() ) 00883 return; 00884 00885 highway_iterator pit, hit; 00886 for ( pit = ports_queue_.begin(); pit != ports_queue_.end(); ++pit ) 00887 { 00888 // Check that it is not the same highway 00889 hit = highway_table_.find( pit->first ); 00890 if( hit != highway_table_.end() && ( hit->second.second.second <= max_acks_ || ( pit->second.first.first == hit->second.first.first && pit->second.first.second == hit->second.first.second ) ) ) 00891 continue; 00892 00893 // Create a PORT_REQ highway message with: hops, port_source, port_target, cluster_id_own, cluster_id_target. 00894 #ifdef HWY_DEBUG 00895 debug().debug( "Negotiating %x; %x; %x; %x; %d", pit->second.first.first, pit->second.first.second, cluster().cluster_id(), pit->first, pit->second.second.first ); 00896 #endif 00897 set_msg_highway( buffer_, PORT_REQ, pit->second.second.first, pit->second.first.first, pit->second.first.second, cluster().cluster_id(), pit->first ); 00898 send_away( radio().id(), HWY_MSG_SIZE, buffer_ ); 00899 } 00900 00901 //After processing all the ports, we flush the queue. 00902 ports_queue_.clear(); 00903 cand_timer_set_ = false; 00904 #ifdef HIGHWAY_METHOD_DEBUG 00905 debug().debug( "@@ %x METHOD ENDED: candidacies_timeout()\n", radio().id() ); 00906 #endif 00907 } 00908 00909 // ----------------------------------------------------------------------- 00910 00911 template<typename OsModel_P, 00912 typename RoutingTable_P, 00913 typename Cluster_P, 00914 typename Neighbor_P, 00915 uint16_t MAX_CLUSTERS> 00916 void 00917 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00918 receive( node_id_t from, size_t len, block_data_t *data ) 00919 { 00920 if(!enabled_) 00921 return; 00922 #ifdef HIGHWAY_METHOD_DEBUG 00923 // debug().debug("@@ %d METHOD_CALLED: receive()\n", radio().id()); 00924 #endif 00925 00926 // Ignore if heard oneself's message. 00927 if ( from == radio().id() ) 00928 return; 00929 00930 memcpy( &buffer_, data, len); 00931 00932 #ifdef HIGHWAY_MSG_RECV_DEBUG 00933 if ( buffer_[0] == CANDIDACY ) debug().debug( "@@ %x(%d)<- %x: MSG_RECEIVED: CANDIDACY\n", radio().id(), cluster().is_cluster_head(), from ); 00934 else if ( buffer_[0] == PORT_REQ ) debug().debug( "@@ %x(%d)<- %x: MSG_RECEIVED: PORT_REQ\n", radio().id(), cluster().is_cluster_head(), from ); 00935 else if ( buffer_[0] == PORT_REQ2 ) debug().debug( "@@ %x(%d)<- %x: MSG_RECEIVED: PORT_REQ2\n", radio().id(), cluster().is_cluster_head(), from ); 00936 else if ( buffer_[0] == PORT_ACK ) debug().debug( "@@ %x(%d)<- %x: MSG_RECEIVED: PORT_ACK\n", radio().id(), cluster().is_cluster_head(), from ); 00937 else if ( buffer_[0] == PORT_ACK2 ) debug().debug( "@@ %x(%d)<- %x: MSG_RECEIVED: PORT_ACK2\n", radio().id(), cluster().is_cluster_head(), from ); 00938 else if ( buffer_[0] == PORT_NACK ) debug().debug( "@@ %x(%d)<- %x: MSG_RECEIVED: PORT_NACK\n", radio().id(), cluster().is_cluster_head(), from ); 00939 else if ( buffer_[0] == PORT_NACK2 ) debug().debug( "@@ %x(%d)<- %x: MSG_RECEIVED: PORT_NACK2\n", radio().id(), cluster().is_cluster_head(), from ); 00940 else if ( buffer_[0] == SEND ) debug().debug( "@@ %x(%d)<- %x: MSG_RECEIVED: SEND\n", radio().id(), cluster().is_cluster_head(), from ); 00941 else if ( buffer_[0] == SEND2 ) debug().debug( "@@ %d(%d)<- %x: MSG_RECEIVED: SEND2\n", radio().id(), cluster().is_cluster_head(), from ); 00942 #endif 00943 00944 #ifdef CTI_VISOR 00945 /*if ( buffer_[0] == CANDIDACY ) debug().debug( "HWY_MSG; CAND; %x; %x", radio().id(), from ); 00946 else if ( buffer_[0] == PORT_REQ or buffer_[0] == PORT_REQ2 ) debug().debug( "HWY_MSG; RE; %x; %x, %d", radio().id(), from, cluster().is_cluster_head() ); 00947 else if ( buffer_[0] == PORT_ACK or buffer_[0] == PORT_ACK2 ) debug().debug( "HWY_MSG; PACK; %x; %x, %d", radio().id(), from, cluster().is_cluster_head() ); 00948 else if ( buffer_[0] == PORT_NACK or buffer_[0] == PORT_NACK2 ) debug().debug( "HWY_MSG; PNACK; %x; %x", radio().id(), from ); 00949 else */if ( buffer_[0] == SEND or buffer_[0] == SEND2 ) debug().debug( "HWY_MSG; SEND; %x; %x", radio().id(), from ); 00950 else if ( buffer_[0] == ACK or buffer_[0] == ACK2 ) debug().debug( "HWY_MSG; ACK; %x; %x", radio().id(), from ); 00951 #endif 00952 00953 // Messages travelling to the current node cluster leader are processed in send_to_leader 00954 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 ) 00955 { 00956 send_to_leader( from, len, buffer_ ); 00957 } 00958 else if ( buffer_[0] == PORT_REQ or buffer_[0] == PORT_ACK or buffer_[0] == PORT_NACK ) // Construction messages travelling outwards 00959 { 00960 send_away( from, len, buffer_ ); 00961 } 00962 else if ( buffer_[0] == SEND or buffer_[0] == ACK ) // Data messages travelling outwards. 00963 { 00964 process_send( from, len, buffer_ ); 00965 } 00966 } 00967 00968 // ----------------------------------------------------------------------- 00969 00970 template<typename OsModel_P, 00971 typename RoutingTable_P, 00972 typename Cluster_P, 00973 typename Neighbor_P, 00974 uint16_t MAX_CLUSTERS> 00975 void 00976 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00977 send_to_leader( node_id_t from, size_t len, block_data_t *data ) 00978 { 00979 if(!enabled_) 00980 return; 00981 #ifdef HIGHWAY_METHOD_DEBUG 00982 debug().debug( "@@ %x METHOD_CALLED: send_to_leader()\n", radio().id()) ; 00983 #endif 00984 uint8_t type = data[0]; 00985 00986 #ifdef HIGHWAY_MSG_RECV_DEBUG 00987 if( type == SEND2 ) 00988 { 00989 debug().debug( "---------------SENDRECV2--------------\n" ); 00990 for( int i = 0; i<len; ++i ) 00991 debug().debug( "Data[%d]: %d\n", i, data[i] ); 00992 debug().debug( "---------------/SENDRECV2--------------\n" ); 00993 } 00994 #endif 00995 00996 get_msg_highway( &msg_highway_, data ); 00997 routing_table_[msg_highway_.source] = from; 00998 00999 if( type == PORT_ACK2 ) 01000 { 01001 #ifdef VISOR_DEBUG 01002 debug().debug( "$%d->%d$h\n", from, radio_->id() ); 01003 #endif 01004 #ifdef CTI_VISOR 01005 //debug().debug( "HWY_EDGE; %x; %x; %x; %x; %x", from, msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01006 #endif 01007 } 01008 01009 if( cluster().is_cluster_head() ) 01010 { 01011 cluster_head_work( from, len, data ); 01012 } 01013 else 01014 { 01015 if(msg_highway_.sid_source != radio().id() ) 01016 radio().send( cluster().parent(), len, data ); 01017 } 01018 #ifdef HIGHWAY_METHOD_DEBUG 01019 debug().debug( "@@ %x METHOD_ENDED: send_to_leader()\n", radio().id()) ; 01020 #endif 01021 } 01022 01023 // ----------------------------------------------------------------------- 01024 01025 template<typename OsModel_P, 01026 typename RoutingTable_P, 01027 typename Cluster_P, 01028 typename Neighbor_P, 01029 uint16_t MAX_CLUSTERS> 01030 void 01031 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01032 send_away( node_id_t from, size_t len, block_data_t *data ) 01033 { 01034 if(!enabled_) 01035 return; 01036 #ifdef HIGHWAY_METHOD_DEBUG 01037 debug().debug("@@ %x METHOD_CALLED: send_away()\n", radio().id()); 01038 #endif 01039 node_id_t next; 01040 01041 get_msg_highway( &msg_highway_, data ); 01042 01043 // Check if we are still in the cluster that originated the request. 01044 if ( from == cluster().parent() || from == radio().id() ) 01045 { 01046 // If the current node is not the port, continue the way to the port. 01047 if( msg_highway_.source != radio().id() && msg_highway_.target != radio().id() ) 01048 { 01049 routing_iterator rit; 01050 if ( msg_highway_.msg_id == PORT_REQ ) 01051 rit = routing_table_.find( msg_highway_.source ); 01052 else if( msg_highway_.msg_id == PORT_ACK ) 01053 { 01054 #ifdef CTI_VISOR 01055 //debug().debug( "HWY_EDGE; %x; %x; %x; %x; %x", from, msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01056 #endif 01057 rit = routing_table_.find( msg_highway_.target ); 01058 } 01059 else 01060 rit = routing_table_.find( msg_highway_.target ); 01061 if( rit == routing_table_.end() ) 01062 { 01063 #ifdef HWY_DEBUG 01064 debug().debug( "PITFALL2" ); 01065 #endif 01066 return; 01067 } 01068 next = rit->second; 01069 #ifdef HWY_DEBUG 01070 debug().debug( "Still same cluster, not yet port, passing request to %x", next ); 01071 #endif 01072 } 01073 else // It is the port. Send the message to the other cluster port and set the port to highway status(if needed). 01074 { 01075 if( msg_highway_.msg_id == PORT_REQ ) 01076 { 01077 next = msg_highway_.target; 01078 if( next == radio().id() ) 01079 { 01080 #ifdef HWY_DEBUG 01081 debug().debug( "Error_1" ); 01082 #endif 01083 return; 01084 } 01085 } 01086 else 01087 { 01088 next = msg_highway_.source; 01089 if( next == radio().id() ) 01090 { 01091 #ifdef HWY_DEBUG 01092 debug().debug( "Error_2" ); 01093 #endif 01094 return; 01095 } 01096 if( msg_highway_.msg_id == PORT_ACK ) 01097 { 01098 if( not cluster().is_cluster_head() ) 01099 highway_table_[msg_highway_.sid_source] = entry( source_target( msg_highway_.target, msg_highway_.source ), hops_ack( msg_highway_.hops, 0 ) ); 01100 #ifdef CTI_VISOR 01101 //debug().debug( "HWY_EDGE; %x; %x; %x; %x; %x", from, msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01102 #endif 01103 #ifdef VISOR_DEBUG 01104 debug().debug("$%d->%d$h\n", from, radio_->id()); 01105 #endif 01106 } 01107 } 01108 #ifdef HWY_DEBUG 01109 debug().debug( "Still same cluster, already port, passing request to %x", msg_highway_.target ); 01110 #endif 01111 } 01112 radio().send( next, HWY_MSG_SIZE, data ); 01113 } 01114 else // Create a "2" message. 01115 { 01116 // Make it into a "2" message 01117 if ( msg_highway_.msg_id == PORT_ACK ) 01118 { 01119 #ifdef VISOR_DEBUG 01120 debug().debug( "+%d#%d#%d#1\n", radio().id(), cluster().cluster_id(), cluster().is_cluster_head() ); 01121 debug().debug( "+%d#%d#%d#1\n", from, msg_highway_.sid_target, cluster().is_cluster_head() ); 01122 #endif 01123 #ifdef CTI_VISOR 01124 // debug().debug( "HWY_EDGE; %x; %x; %x; %x; %x", from, msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01125 #endif 01126 #ifdef CTI_VISOR 01127 //debug().debug( "HWY_PORTS; %x; %x", radio().id(), from ); 01128 #endif 01129 if( not cluster().is_cluster_head() ) 01130 highway_table_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, from ), hops_ack( msg_highway_.hops, 0 ) ); 01131 } 01132 msg_highway_.msg_id++; 01133 01134 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 ); 01135 if( cluster().is_cluster_head() ) 01136 cluster_head_work( from, len, buffer_ ); 01137 else 01138 radio().send( cluster().parent(), HWY_MSG_SIZE, buffer_ ); 01139 } 01140 #ifdef HIGHWAY_METHOD_DEBUG 01141 debug().debug("@@ %x 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 if(!enabled_) 01157 return; 01158 #ifdef HIGHWAY_METHOD_DEBUG 01159 debug().debug("@@ %x METHOD_CALLED: send_process()\n", radio().id()); 01160 #endif 01161 node_id_t port, port_target, destination; 01162 01163 #ifdef HWY_SEND_DEBUGG 01164 debug().debug("---------------SENDRECV--------------\n"); 01165 for(int i = 0; i<len; ++i) 01166 debug().debug("Data[%d]: %d\n", i, data[i]); 01167 debug().debug("---------------/SENDRECV--------------\n"); 01168 #endif 01169 01170 // Check if we are still in the cluster that originated the request. 01171 if ( from == cluster().parent() || from == radio().id() ) 01172 { 01173 // If the current node is not the port, continue the way to the port. 01174 #ifdef ISENSE_APP 01175 port = ( data[4] << 8 ) | data[3]; 01176 port_target = ( data[8] << 8 ) | data[7]; 01177 destination = ( data[2] << 8 ) | data[1]; 01178 #else 01179 port = ( data[8] << 24 ) | ( data[7] << 16 ) | ( data[6] << 8 ) | data[5]; 01180 port_target = ( data[16] << 24 ) | ( data[15] << 16 ) | ( data[14] << 8 ) | data[13]; 01181 destination = ( data[4] << 24 ) | ( data[3] << 16 ) | ( data[2] << 8 ) | data[1]; 01182 #endif 01183 if( port_target == radio().id() ) 01184 { 01185 #ifdef HWY_DEBUG 01186 debug().debug( "MERDA!!! %x; %x", cluster().cluster_id(), destination ); 01187 #endif 01188 return; 01189 } 01190 01191 if ( port != radio().id() ) 01192 { 01193 routing_iterator rit = routing_table_.find( port ); 01194 if( rit == routing_table_.end() ) 01195 { 01196 #ifdef HWY_DEBUG 01197 debug().debug( "PITFALL3 Managed" ); 01198 #endif 01199 // As it wasn't in the routing table, We try to send it straight 01200 radio().send( port, len, data ); 01201 return; 01202 } 01203 #ifdef TRACK_SEND_MSG 01204 debug().debug( "(%d)Process_send sending to %x through %x",cluster().is_cluster_head(), destination, rit->second ); 01205 #endif 01206 radio().send( rit->second, len, data ); 01207 } 01208 else // Send the message to the other cluster port. 01209 { 01210 radio().send( port_target, len, data ); 01211 } 01212 } 01213 else 01214 { 01215 // Create a "2" message. 01216 *data += 1; 01217 01218 if( cluster().is_cluster_head() ) 01219 { 01220 #ifdef TRACK_SEND_MSG 01221 debug().debug( "Process_send port target and leader" ); 01222 #endif 01223 cluster_head_work( from, len, data ); 01224 } 01225 else 01226 { 01227 #ifdef TRACK_SEND_MSG 01228 debug().debug( "Process_send port target, sending to %x through %x", destination, cluster().parent() ); 01229 #endif 01230 radio().send( cluster().parent(), len, data ); 01231 } 01232 } 01233 #ifdef HIGHWAY_METHOD_DEBUG 01234 debug().debug("@@ %x METHOD_ENDED: send_process()\n", radio().id()); 01235 #endif 01236 } 01237 01238 // ----------------------------------------------------------------------- 01239 01240 template<typename OsModel_P, 01241 typename RoutingTable_P, 01242 typename Cluster_P, 01243 typename Neighbor_P, 01244 uint16_t MAX_CLUSTERS> 01245 void 01246 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01247 cluster_head_work( node_id_t from, size_t len, block_data_t *data ) 01248 { 01249 if(!enabled_) 01250 return; 01251 #ifdef HIGHWAY_METHOD_DEBUG 01252 debug().debug("@@ %x METHOD_CALLED: cluster_head_work()\n", radio().id() ); 01253 #endif 01254 node_id_t sender; 01255 01256 get_msg_highway( &msg_highway_, data ); 01257 01258 if ( msg_highway_.msg_id == CANDIDACY ) // Add the port candidate to the queue. 01259 { 01260 if( msg_highway_.sid_target == radio().id() ) 01261 return; 01262 // Check that the port candidate is better than the stored candidate 01263 highway_iterator it = ports_queue_.find( msg_highway_.sid_target ); 01264 #ifdef STABLE 01265 if( it == ports_queue_.end() || it->second.second.first > msg_highway_.hops ) 01266 #else 01267 if( true ) 01268 #endif 01269 { 01270 ports_queue_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, msg_highway_.target ), hops_ack( msg_highway_.hops, 0 )); 01271 #ifdef HWY_DEBUG 01272 debug().debug( "(%d)HWY received candidacy from %x; %x; %x; %x", cluster().is_cluster_head(), msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01273 #endif 01274 if( not cand_timer_set_ ) 01275 { 01276 cand_timer_set_ = true; 01277 timer().template set_timer<self_type, &self_type::candidacies_timeout>( discovery_time_ , this, (void *) 0 ); 01278 } 01279 } 01280 } 01281 else if ( msg_highway_.msg_id == PORT_REQ2 ) // Accept or reject the highway request. 01282 { 01283 #ifdef HWY_DEBUG 01284 debug().debug( "HWY received port request %x; %x; %x; %x", msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01285 #endif 01286 // iff there is no highway set or the ack of the current one are too high accept or is the same highway 01287 highway_iterator it = highway_table_.find( msg_highway_.sid_source ); 01288 if( it == highway_table_.end() || it->second.second.second > max_acks_ || ( it->second.first.first == msg_highway_.target && it->second.first.second == msg_highway_.source ) ) 01289 { 01290 #ifdef HWY_DEBUG 01291 debug().debug( "HWY acking %x; %x; %x; %x", msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01292 #endif 01293 highway_table_[msg_highway_.sid_source] = entry( source_target( msg_highway_.target, msg_highway_.source ), hops_ack( msg_highway_.hops, 0 ) ); 01294 msg_highway_.msg_id = PORT_ACK; 01295 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 ); 01296 radio().send( from, HWY_MSG_SIZE, buffer_ ); 01297 } 01298 } 01299 else if ( msg_highway_.msg_id == PORT_ACK2 ) // Establish the port. 01300 { 01301 #ifdef CTI_VISOR 01302 debug().debug( "HWY_ADDED; %x; %x; %x; %x; %d", msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target, msg_highway_.hops ); 01303 #endif 01304 highway_table_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, msg_highway_.target ), hops_ack( msg_highway_.hops, 0 ) ); 01305 } 01306 else if ( msg_highway_.msg_id == PORT_NACK2 ) // Remove the port or highway. 01307 { 01308 highway_iterator it = highway_table_.find( msg_highway_.sid_target ); 01309 if( it != highway_table_.end() && it->second.first.first == msg_highway_.sid_source || it->second.first.second == msg_highway_.sid_target ) 01310 { 01311 #ifdef CTI_VISOR 01312 debug().debug( "HWY_DEL; %x; %x; %x; %x", msg_highway_.source, msg_highway_.target, msg_highway_.sid_source, msg_highway_.sid_target ); 01313 #endif 01314 highway_table_.erase(msg_highway_.sid_target); 01315 } 01316 01317 // Try to renegotiate 01318 if( not cand_timer_set_ ) 01319 candidacies_timeout( (void *) 0 ); 01320 } 01321 else 01322 { 01323 if ( *data == SEND2 ) // Send the msg_ack and call the registered (if exists) receiving method. 01324 { 01325 #ifdef ISENSE_APP 01326 sender = (data[6] << 8) | data[5]; 01327 #else 01328 sender = ( data[12] << 24 ) | ( data[11] << 16 ) | ( data[10] << 8 ) | data[9]; 01329 #endif 01330 #ifdef HWY_SEND_DEBUG 01331 debug().debug( "---------------HEAD_WORK_RECV--------------\n" ); 01332 for( int i = 0; i<len; ++i ) 01333 debug().debug( "Data[%d]: %d\n", i, data[i] ); 01334 debug().debug( "---------------HEAD_WORK_RECV--------------\n" ); 01335 #endif 01336 #ifdef TRACK_SEND_MSG 01337 debug().debug( "Arrived to the leader" ); 01338 #endif 01339 send( false, sender, 0, data ); 01340 if( reg_callback_ ) hwy_recv_callback_(sender, len-SEND_OVERHEAD, &data[SEND_OVERHEAD]); 01341 else debug().debug( "No one registered the receive callback :O!" ); 01342 } 01343 else if ( *data == ACK2 ) //Count the received ACKs from the highway 01344 { 01345 highway_iterator it = highway_table_.find( sender ); 01346 if( it != highway_table_.end() && it->second.second.second > -100 ) 01347 it->second.second.second -= 4; 01348 } 01349 } 01350 #ifdef HIGHWAY_METHOD_DEBUG 01351 debug().debug("@@ %x METHOD_ENDED: cluster_head_work()\n", radio().id() ); 01352 #endif 01353 } 01354 01355 // ----------------------------------------------------------------------- 01356 01357 template<typename OsModel_P, 01358 typename RoutingTable_P, 01359 typename Cluster_P, 01360 typename Neighbor_P, 01361 uint16_t MAX_CLUSTERS> 01362 void 01363 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01364 send( bool send_ack, node_id_t destination, size_t len, block_data_t *data ) 01365 { 01366 if(!enabled_) 01367 return; 01368 #ifdef HIGHWAY_METHOD_DEBUG 01369 debug().debug( "@@ %x METHOD CALLED: send()\n", radio().id() ); 01370 #endif 01371 //Check if the highway is still valid. 01372 01373 highway_iterator it = highway_table_.find( destination ); 01374 if( it == highway_table_.end() || it->second.second.second > max_acks_ ) 01375 { 01376 highway_table_.erase(destination); 01377 return; 01378 } 01379 01380 node_id_t port = it->second.first.first; 01381 node_id_t port_target = it->second.first.second; 01382 #ifdef TRACK_SEND_MSG 01383 debug().debug( "TRACK: sending to %x through %x", destination, port ); 01384 #endif 01385 if(send_ack ) 01386 { 01387 buffer_[0] = SEND; 01388 if( it->second.second.second < 100 ) 01389 it->second.second.second += 3; 01390 } 01391 else 01392 { 01393 buffer_[0] = ACK; 01394 } 01395 #ifdef ISENSE_APP 01396 buffer_[1] = destination & 0xFF; 01397 buffer_[2] = ( destination >> 8 ) & 0xFF; 01398 buffer_[3] = port & 0xFF; 01399 buffer_[4] = ( port >> 8 ) & 0xFF; 01400 buffer_[5] = radio().id() & 0xFF; 01401 buffer_[6] = ( radio().id() >> 8 ) & 0xFF; 01402 buffer_[7] = port_target & 0xFF; 01403 buffer_[8] = ( port_target >> 8 ) & 0xFF; 01404 #else 01405 buffer_[1] = destination & 0xFF; 01406 buffer_[2] = ( destination >> 8 ) & 0xFF; 01407 buffer_[3] = ( destination >> 16 ) & 0xFF; 01408 buffer_[4] = ( destination >> 24 ) & 0xFF; 01409 buffer_[5] = port & 0xFF; 01410 buffer_[6] = ( port >> 8 ) & 0xFF; 01411 buffer_[7] = ( port >> 16 ) & 0xFF; 01412 buffer_[8] = ( port >> 24 ) & 0xFF; 01413 buffer_[9] = radio().id() & 0xFF; 01414 buffer_[10] = ( radio().id() >> 8 ) & 0xFF; 01415 buffer_[11] = ( radio().id() >> 16 ) & 0xFF; 01416 buffer_[12] = ( radio().id() >> 24 ) & 0xFF; 01417 buffer_[13] = port_target & 0xFF; 01418 buffer_[14] = ( port_target >> 8 ) & 0xFF; 01419 buffer_[15] = ( port_target >> 16 ) & 0xFF; 01420 buffer_[16] = ( port_target >> 24 ) & 0xFF; 01421 #endif 01422 01423 #ifdef HWY_SEND_DEBUG 01424 debug().debug( "---------------ENCAPSULATING----------------\n" ); 01425 #endif 01426 01427 for (int i = 0; i < len; ++i) 01428 { 01429 buffer_[i+SEND_OVERHEAD] = data[i]; 01430 #ifdef HWY_SEND_DEBUG 01431 debug().debug( "Data item %d: %d\n", i, data[i] ); 01432 #endif 01433 } 01434 01435 01436 #ifdef HWY_SEND_DEBUG 01437 for ( int i = 0; i < len+SEND_OVERHEAD; ++i ) 01438 { 01439 debug().debug( "Buffer item %d: %d\n", i, buffer_[i] ); 01440 } 01441 debug().debug( "---------------/ENCAPSULATING----------------\n" ); 01442 #endif 01443 01444 process_send( radio().id(), len+SEND_OVERHEAD, buffer_ ); 01445 #ifdef HIGHWAY_METHOD_DEBUG 01446 debug().debug( "@@ %x METHOD ENDED: send()\n", radio().id() ); 01447 #endif 01448 } 01449 01450 // ----------------------------------------------------------------------- 01451 01452 template<typename OsModel_P, 01453 typename RoutingTable_P, 01454 typename Cluster_P, 01455 typename Neighbor_P, 01456 uint16_t MAX_CLUSTERS> 01457 void 01458 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01459 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 ) 01460 { 01461 int idx = 0; 01462 write<OsModel, block_data_t, uint8_t>( data + idx, msg_id ); 01463 idx += sizeof( uint8_t ); 01464 write<OsModel, block_data_t, uint8_t>( data + idx, hops ); 01465 idx += sizeof( uint8_t ); 01466 write<OsModel, block_data_t, node_id_t>( data + idx, source ); 01467 idx += sizeof( node_id_t ); 01468 write<OsModel, block_data_t, node_id_t>( data + idx, target ); 01469 idx += sizeof( node_id_t ); 01470 write<OsModel, block_data_t, node_id_t>( data + idx, sid_source ); 01471 idx += sizeof( node_id_t ); 01472 write<OsModel, block_data_t, node_id_t>( data + idx, sid_target ); 01473 } 01474 01475 // ----------------------------------------------------------------------- 01476 01477 template<typename OsModel_P, 01478 typename RoutingTable_P, 01479 typename Cluster_P, 01480 typename Neighbor_P, 01481 uint16_t MAX_CLUSTERS> 01482 void 01483 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01484 get_msg_highway( msg_highway * msg, uint8_t * data ) 01485 { 01486 int idx = 0; 01487 msg->msg_id = read<OsModel, block_data_t, uint8_t>( data + idx ); 01488 idx += sizeof( uint8_t ); 01489 msg->hops = read<OsModel, block_data_t, uint8_t>( data + idx ); 01490 idx += sizeof( uint8_t ); 01491 msg->source = read<OsModel, block_data_t, node_id_t>( data + idx ); 01492 idx += sizeof( node_id_t ); 01493 msg->target = read<OsModel, block_data_t, node_id_t>( data + idx ); 01494 idx += sizeof( node_id_t ); 01495 msg->sid_source = read<OsModel, block_data_t, node_id_t>( data + idx ); 01496 idx += sizeof( node_id_t ); 01497 msg->sid_target = read<OsModel, block_data_t, node_id_t>( data + idx ); 01498 } 01499 01500 } 01501 #endif