Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib is distributed in the hope that it will be useful, ** 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 00013 ** GNU Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ***************************************************************************/ 00019 00020 #ifndef __ALGORITHMS_CLUSTER_HIGHWAY_CLUSTER_H__ 00021 #define __ALGORITHMS_CLUSTER_HIGHWAY_CLUSTER_H__ 00022 00023 00024 #include "algorithms/neighbor_discovery/echo.h" 00025 #include "algorithms/cluster/clustering_types.h" 00026 #include "util/pstl/vector_static.h" 00027 #include "util/pstl/priority_queue.h" 00028 #include "util/pstl/pair.h" 00029 #include "util/pstl/map_static_vector.h" 00030 #include "internal_interface/routing_table/routing_table_static_array.h" 00031 #include "util/delegates/delegate.hpp" 00032 00033 00034 #include "algorithms/cluster/fronts/fronts_core.h" 00035 #include "algorithms/cluster/modules/chd/attr_chd.h" 00036 #include "algorithms/cluster/modules/it/fronts_it.h" 00037 #include "algorithms/cluster/modules/jd/fronts_jd.h" 00038 00039 #include "radio/reliable/reliableradio.h" 00040 00041 // Levels of debug info: 00042 // HIGHWAY_METHOD_DEBUG: Adds a Method called notice at the beginning of each 00043 // method. 00044 // HIGHWAY_MSG_RECV_DEBUG: Adds all sorts of debug messages for the tracking 00045 // of sending messages at Highway level. 00046 // VISOR_DEBUG: Adds debug messages that can be processed by the Python visor 00047 // application to generate a picture of the final status of the WSN. 00048 // HIGHWAY_DEBUG: Most general debug messages. 00049 00050 #define HIGHWAY_DEBUG 00051 #define HIGHWAY_METHOD_DEBUG 00052 #define HIGHWAY_MSG_RECV_DEBUG 00053 //#define VISOR_DEBUG 00054 #ifdef ISENSE_APP 00055 #define SEND_OVERHEAD 7 00056 #else 00057 #define SEND_OVERHEAD 13 00058 #endif 00059 00060 namespace wiselib{ 00061 template<typename OsModel_P, 00062 typename RoutingTable_P, 00063 typename Cluster_P = wiselib::FrontsCore<OsModel_P, typename OsModel_P::TxRadio, wiselib::AtributeClusterHeadDecision<OsModel_P, typename OsModel_P::TxRadio>, wiselib::FrontsJoinDecision<OsModel_P, typename OsModel_P::TxRadio>, wiselib::FrontsIterator<OsModel_P, typename OsModel_P::TxRadio> >, 00064 typename Neighbor_P = wiselib::Echo<OsModel_P, typename OsModel_P::TxRadio, typename OsModel_P::Timer, typename OsModel_P::Debug>, 00065 uint16_t MAX_CLUSTERS = 8> 00066 class HighwayCluster 00067 { 00068 public: 00069 00070 // OS modules. 00071 typedef OsModel_P OsModel; 00072 typedef typename OsModel::TxRadio Radio; 00073 typedef typename OsModel::Timer Timer; 00074 typedef typename OsModel::Clock Clock; 00075 typedef typename OsModel::Debug Debug; 00076 typedef typename OsModel::TxRadio TxRadio; 00077 00078 // Type definitions. 00079 typedef wiselib::AtributeClusterHeadDecision<OsModel, TxRadio> CHD_t; 00080 typedef wiselib::FrontsJoinDecision<OsModel, TxRadio> JD_t; 00081 typedef wiselib::FrontsIterator<OsModel, TxRadio> IT_t; 00082 00083 // Type definition of the used Templates. 00084 typedef RoutingTable_P RoutingTable; 00085 typedef Cluster_P Cluster; 00086 typedef Neighbor_P Neighbor; 00087 00088 typedef HighwayCluster<OsModel, RoutingTable, Cluster, Neighbor, MAX_CLUSTERS> self_type; 00089 typedef wiselib::Echo<OsModel, TxRadio, Timer, Debug> nb_t; 00090 typedef self_type* self_pointer_t; 00091 00092 // Basic types definition. 00093 typedef typename Radio::node_id_t node_id_t; 00094 typedef typename Radio::size_t size_t; 00095 typedef typename Radio::block_data_t block_data_t; 00096 typedef typename Timer::millis_t millis_t; 00097 00098 // Type definition for the receive callback. 00099 typedef delegate3<void, node_id_t, size_t, block_data_t*> highway_delegate_t; 00100 00101 enum Sizes { 00102 MAX_CLUSTER_PORTS = 4 00103 }; 00104 00105 // Type definition for the special data structures of the highway. 00106 typedef wiselib::pair<int16_t, node_id_t> Hops_Node_id; 00107 typedef wiselib::priority_queue<OsModel, Hops_Node_id, MAX_CLUSTER_PORTS> PQ; 00108 typedef wiselib::pair<PQ, int16_t> PQ_Ack; 00109 typedef wiselib::MapStaticVector<OsModel, node_id_t, PQ_Ack, MAX_CLUSTERS> HighwayTable; 00110 typedef wiselib::MapStaticVector<OsModel, node_id_t, PQ_Ack, MAX_CLUSTERS> PortsQueue; 00111 typedef wiselib::vector_static<OsModel, node_id_t, MAX_CLUSTERS> Node_vect; 00112 typedef wiselib::vector_static<OsModel, Hops_Node_id, MAX_CLUSTER_PORTS> Ports_vect; 00113 00114 // Type definition for the special types iterators. 00115 typedef typename HighwayTable::iterator highway_iterator; 00116 typedef typename PQ::pointer pq_iterator; 00117 00118 // Return types definition. 00119 enum ErrorCodes { 00120 SUCCESS = OsModel::SUCCESS, 00121 ERR_UNSPEC = OsModel::ERR_UNSPEC 00122 }; 00123 00124 // Possible highway message ids. 00125 enum msg_id { 00126 CANDIDACY = 200, 00127 PORT_REQ = 201, 00128 PORT_REQ2 = 202, 00129 PORT_ACK = 203, 00130 PORT_ACK2 = 204, 00131 PORT_NACK = 205, 00132 PORT_NACK2 = 206, 00133 SEND = 207, 00134 SEND2 = 208 00135 }; 00136 00137 // -------------------------------------------------------------------- 00138 // Public method declaration. | 00139 // -------------------------------------------------------------------- 00140 00143 HighwayCluster(): 00144 radio_ ( 0 ), 00145 timer_ ( 0 ), 00146 debug_ ( 0 ), 00147 cluster_ ( 0 ), 00148 discovery_time_ ( 5000 ), 00149 disc_timer_set_(0), 00150 cand_timer_set_(0) 00151 { 00152 }; 00153 00156 ~HighwayCluster(){}; 00157 00158 00162 int init( TxRadio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Cluster& cluster, Neighbor& neighbor ); 00163 00167 void enable( void ); 00168 00175 void send( node_id_t receiver, size_t len, block_data_t *data ); 00176 00184 void send( node_id_t receiver, node_id_t port, size_t len, block_data_t *data ); 00185 00190 Node_vect cluster_neighbors(); 00191 00196 Ports_vect ports(node_id_t sid); 00197 00201 template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)> 00202 uint8_t hwy_reg_recv_callback(T *obj_pnt) { 00203 hwy_recv_callback_ = highway_delegate_t::template from_method<T, TMethod > ( obj_pnt ); 00204 return 0; 00205 } 00206 00209 void unreg_hwy_recv_callback() { 00210 hwy_recv_callback_ = highway_delegate_t(); 00211 } 00212 00213 // -------------------------------------------------------------------- 00214 // Setters | 00215 // -------------------------------------------------------------------- 00216 00220 inline void set_discovery_time( millis_t t ) { 00221 discovery_time_ = t; 00222 }; 00223 00224 00225 private: 00226 // Typenaming the underlying modules. 00227 typename Radio::self_pointer_t radio_; 00228 typename Timer::self_pointer_t timer_; 00229 typename Clock::self_pointer_t clock_; 00230 typename Debug::self_pointer_t debug_; 00231 typename Cluster::self_type* cluster_; 00232 typename Neighbor::self_t* neighbor_; 00233 00234 // Highway control message. 00235 struct msg_highway { 00236 uint8_t msg_id, hops; 00237 node_id_t candidate_id, sid_source, sid_target; 00238 }; 00239 00240 inline uint8_t msg_highway_size() { 00241 return sizeof( uint8_t ) + sizeof( uint8_t ) + sizeof( node_id_t ) + sizeof( node_id_t ) + sizeof( node_id_t ); 00242 } 00243 00244 inline void set_msg_highway( uint8_t * data, uint8_t msg_id, uint8_t hops, node_id_t candidate_id, node_id_t sid_source, node_id_t sid_target ) { 00245 memcpy( data, &msg_id, sizeof( uint8_t ) ); 00246 data += sizeof( uint8_t ); 00247 memcpy( data, &hops, sizeof( uint8_t ) ); 00248 data += sizeof( uint8_t ); 00249 memcpy( data, &candidate_id, sizeof( node_id_t ) ); 00250 data += sizeof( node_id_t ); 00251 memcpy( data, &sid_source, sizeof( node_id_t ) ); 00252 data += sizeof( node_id_t ); 00253 memcpy( data, &sid_target, sizeof( node_id_t ) ); 00254 data += sizeof( node_id_t ); 00255 } 00256 00257 inline void get_msg_highway( msg_highway * msg, uint8_t * data ) { 00258 memcpy( &( msg->msg_id ), data, sizeof( uint8_t ) ); 00259 data += sizeof( uint8_t ); 00260 memcpy( &( msg->hops ), data, sizeof( uint8_t ) ); 00261 data += sizeof( uint8_t ); 00262 memcpy( &( msg->candidate_id ), data, sizeof( node_id_t ) ); 00263 data += sizeof( node_id_t ); 00264 memcpy( &( msg->sid_source ), data, sizeof( node_id_t ) ); 00265 data += sizeof( node_id_t ); 00266 memcpy( &( msg->sid_target ), data, sizeof( node_id_t ) ); 00267 data += sizeof( node_id_t ); 00268 } 00269 00270 // -------------------------------------------------------------------- 00271 // Private variables declaration. | 00272 // -------------------------------------------------------------------- 00273 00275 msg_highway msg_highway_; 00276 00278 millis_t discovery_time_; 00279 00280 //TODO: Check the possibility of removal. 00282 //int clustering_callback_; 00283 00285 uint8_t disc_timer_set_; 00286 00288 uint8_t cand_timer_set_; 00289 00290 00292 highway_delegate_t hwy_recv_callback_; 00293 00295 node_id_t connected_to; 00296 00298 RoutingTable routing_table_; 00299 00301 HighwayTable highway_table_; 00302 00304 PortsQueue ports_queue_; 00305 00306 //TODO: Check if this three can be moved inside their respective methods. 00308 vector_static<OsModel, Hops_Node_id, MAX_CLUSTER_PORTS -1 > aux; 00309 00311 Node_vect neighbors_; 00312 00314 Ports_vect ports_; 00315 00317 block_data_t buffer_[Radio::MAX_MESSAGE_LENGTH]; 00318 00320 CHD_t CHD_; 00321 JD_t JD_; 00322 IT_t IT_; 00323 00324 // -------------------------------------------------------------------- 00325 // Private method declaration. | 00326 // -------------------------------------------------------------------- 00327 00331 Radio& radio() { 00332 return *radio_; 00333 } 00334 00338 Timer& timer() { 00339 return *timer_; 00340 } 00341 00345 Clock& clock() { 00346 return *clock_; 00347 } 00348 00352 Debug& debug() { 00353 return *debug_; 00354 } 00355 00359 Cluster& cluster() { 00360 return *cluster_; 00361 } 00362 00366 Neighbor& neighbor() { 00367 return *neighbor_; 00368 } 00369 00374 void start_wrapper(int state); 00375 00379 void cluster_discovery( void ); 00380 00388 void neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data); 00389 00394 void discovery_timeout( void *userdata ); 00395 00400 void candidacies_timeout( void *userdata ); 00401 00402 00408 void start_port_negotiation( highway_iterator it, uint8_t n ); 00409 00415 void port_negotiation( node_id_t sid, node_id_t candidate ); 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 00462 void displacing_push(PQ& pq, Hops_Node_id pin); 00463 00469 Hops_Node_id pop_port(PQ& pq, node_id_t port); 00470 00471 00472 }; // End of class. 00473 00474 // -------------------------------------------------------------------- 00475 // Start of the method code: PUBLIC METHODS | 00476 // -------------------------------------------------------------------- 00477 template<typename OsModel_P, 00478 typename RoutingTable_P, 00479 typename Cluster_P, 00480 typename Neighbor_P, 00481 uint16_t MAX_CLUSTERS> 00482 inline int 00483 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00484 init( TxRadio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Cluster& cluster, Neighbor& neighbor ) { 00485 radio_ = &tx_radio; 00486 timer_ = &timer; 00487 clock_ = &clock; 00488 debug_ = &debug; 00489 cluster_ = &cluster; 00490 neighbor_ = &neighbor; 00491 00492 // Initialize the neighborhood discovery module. 00493 neighbor_->init( tx_radio, *clock_, *timer_, *debug_ ); 00494 00495 // Stabilizing cluster initialization. 00496 // set the HeadDecision Module 00497 cluster_->set_cluster_head_decision( CHD_ ); 00498 // set the JoinDecision Module 00499 cluster_->set_join_decision( JD_ ); 00500 // set the Iterator Module 00501 cluster_->set_iterator( IT_ ); 00502 cluster_->init( *radio_, *timer_, *debug_, *neighbor_ ); 00503 00504 //IMPROVE: Take the value upper as soon as more hops clustering is tested. 00505 cluster_->set_maxhops( 1 ); 00506 00507 return SUCCESS; 00508 } 00509 00510 // -------------------------------------------------------------------- 00511 00512 template<typename OsModel_P, 00513 typename RoutingTable_P, 00514 typename Cluster_P, 00515 typename Neighbor_P, 00516 uint16_t MAX_CLUSTERS> 00517 void 00518 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00519 enable( void ) 00520 { 00521 #ifdef HIGHWAY_METHOD_DEBUG 00522 debug().debug( "@@ %d METHOD CALLED: enable()\n", radio().id() ); 00523 #endif 00524 // Enabling and registering radio 00525 radio().enable_radio(); 00526 radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00527 00528 // Enabling neighborhood and registering cluster 00529 //clustering_callback_ = cluster().template reg_state_changed_callback<self_type, &self_type::start_wrapper > ( this ); 00530 cluster().enable(); 00531 cluster().template reg_state_changed_callback<self_type, &self_type::start_wrapper > ( this ); 00532 neighbor().enable(); 00533 00534 #ifdef HIGHWAY_METHOD_DEBUG 00535 debug().debug( "@@ %d METHOD ENDED: enable()\n", radio().id() ); 00536 #endif 00537 } 00538 00539 // -------------------------------------------------------------------- 00540 00541 template<typename OsModel_P, 00542 typename RoutingTable_P, 00543 typename Cluster_P, 00544 typename Neighbor_P, 00545 uint16_t MAX_CLUSTERS> 00546 void 00547 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00548 send( node_id_t destination, size_t len, block_data_t *data ) 00549 { 00550 #ifdef HIGHWAY_METHOD_DEBUG 00551 debug().debug( "@@ %d METHOD CALLED: send1()\n", radio().id() ); 00552 #endif 00553 #ifdef HIGHWAY_MSG_RECV_DEBUG 00554 debug().debug( "!! data: %d %d\n", data[0], data[1] ); 00555 #endif 00556 send( destination, highway_table_[destination].first.top().second, len, data ); 00557 #ifdef HIGHWAY_METHOD_DEBUG 00558 debug().debug( "@@ %d METHOD ENDED: send1()\n", radio().id() ); 00559 #endif 00560 } 00561 00562 // ----------------------------------------------------------------------- 00563 00564 template<typename OsModel_P, 00565 typename RoutingTable_P, 00566 typename Cluster_P, 00567 typename Neighbor_P, 00568 uint16_t MAX_CLUSTERS> 00569 void 00570 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00571 send( node_id_t destination, node_id_t port, size_t len, block_data_t *data ) 00572 { 00573 #ifdef HIGHWAY_METHOD_DEBUG 00574 debug().debug( "@@ %d METHOD CALLED: send_spec()\n", radio().id() ); 00575 #endif 00576 if (len >= Radio::MAX_MESSAGE_LENGTH-3) 00577 { 00578 debug().debug( "@@ %d: ERROR: message too long\n", radio().id() ); 00579 } 00580 00581 buffer_[0] = SEND; 00582 #ifdef ISENSE_APP 00583 buffer_[1] = destination & 0xFF; 00584 buffer_[2] = ( destination >> 8 ) & 0xFF; 00585 buffer_[3] = port & 0xFF; 00586 buffer_[4] = ( port >> 8 ) & 0xFF; 00587 buffer_[5] = radio().id() & 0xFF; 00588 buffer_[6] = ( radio().id() >> 8 ) & 0xFF; 00589 #else 00590 buffer_[1] = destination & 0xFF; 00591 buffer_[2] = ( destination >> 8 ) & 0xFF; 00592 buffer_[3] = ( destination >> 16 ) & 0xFF; 00593 buffer_[4] = ( destination >> 24 ) & 0xFF; 00594 buffer_[5] = port & 0xFF; 00595 buffer_[6] = ( port >> 8 ) & 0xFF; 00596 buffer_[7] = ( port >> 16 ) & 0xFF; 00597 buffer_[8] = ( port >> 24 ) & 0xFF; 00598 buffer_[9] = radio().id() & 0xFF; 00599 buffer_[10] = ( radio().id() >> 8 ) & 0xFF; 00600 buffer_[11] = ( radio().id() >> 16 ) & 0xFF; 00601 buffer_[12] = ( radio().id() >> 24 ) & 0xFF; 00602 #endif 00603 00604 #ifdef HIGHWAY_MSG_RECV_DEBUG 00605 debug().debug( "---------------ENCAPSULATING----------------\n" ); 00606 #endif 00607 00608 for (int i = SEND_OVERHEAD; i < ( len+SEND_OVERHEAD ); ++i) 00609 { 00610 buffer_[i] = data[i-SEND_OVERHEAD]; 00611 #ifdef HIGHWAY_MSG_RECV_DEBUG 00612 debug().debug( "Data item %d: %d\n", i-SEND_OVERHEAD, data[i-SEND_OVERHEAD] ); 00613 #endif 00614 } 00615 00616 00617 #ifdef HIGHWAY_MSG_RECV_DEBUG 00618 for (int i = 0; i < len+SEND_OVERHEAD; ++i) 00619 { 00620 debug().debug( "Buffer item %d: %d\n", i, buffer_[i] ); 00621 } 00622 #endif 00623 00624 #ifdef HIGHWAY_MSG_RECV_DEBUG 00625 debug().debug( "---------------/ENCAPSULATING----------------\n" ); 00626 #endif 00627 radio().send( routing_table_[port], len+SEND_OVERHEAD, buffer_ ); 00628 #ifdef HIGHWAY_METHOD_DEBUG 00629 debug().debug( "@@ %d METHOD ENDED: send_spec()\n", radio().id() ); 00630 #endif 00631 } 00632 00633 // ----------------------------------------------------------------------- 00634 00635 template<typename OsModel_P, 00636 typename RoutingTable_P, 00637 typename Cluster_P, 00638 typename Neighbor_P, 00639 uint16_t MAX_CLUSTERS> 00640 typename HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::Node_vect 00641 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00642 cluster_neighbors( void ) 00643 { 00644 #ifdef HIGHWAY_METHOD_DEBUG 00645 debug().debug( "@@ %d METHOD CALLED: cluster_neighbors()\n", radio().id() ); 00646 #endif 00647 00648 neighbors_.clear(); 00649 if ( not cluster().is_cluster_head() ) 00650 { 00651 return neighbors_; 00652 } 00653 00654 highway_iterator it; 00655 for ( it = highway_table_.begin(); it != highway_table_.end(); ++it ) 00656 { 00657 neighbors_.push_back( it->first ); 00658 } 00659 00660 #ifdef HIGHWAY_METHOD_DEBUG 00661 debug().debug( "@@ %d METHOD ENDED: cluster_neighbors()\n", radio().id() ); 00662 #endif 00663 00664 return neighbors_; 00665 } 00666 00667 // ----------------------------------------------------------------------- 00668 00669 template<typename OsModel_P, 00670 typename RoutingTable_P, 00671 typename Cluster_P, 00672 typename Neighbor_P, 00673 uint16_t MAX_CLUSTERS> 00674 typename HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::Ports_vect 00675 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00676 ports( node_id_t sid ) 00677 { 00678 #ifdef HIGHWAY_METHOD_DEBUG 00679 debug().debug( "@@ %d METHOD CALLED: ports()\n", radio().id() ); 00680 #endif 00681 ports_.clear(); 00682 pq_iterator p = highway_table_[sid].first.data(); 00683 for ( int i = 0; i < highway_table_[sid].first.size(); ++i ) 00684 { 00685 ports_.push_back( *p ); 00686 p++; 00687 } 00688 00689 #ifdef HIGHWAY_METHOD_DEBUG 00690 debug().debug( "@@ %d METHOD ENDED: ports()\n", radio().id() ); 00691 #endif 00692 00693 return ports_; 00694 } 00695 00696 // ----------------------------------------------------------------------- 00697 // PRIVATE METHODS | 00698 // ----------------------------------------------------------------------- 00699 00700 template<typename OsModel_P, 00701 typename RoutingTable_P, 00702 typename Cluster_P, 00703 typename Neighbor_P, 00704 uint16_t MAX_CLUSTERS> 00705 void 00706 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00707 start_wrapper( int state ) 00708 { 00709 #ifdef HIGHWAY_METHOD_DEBUG 00710 debug().debug( "@@ %d METHOD_CALLED: start_wrapper()\n", radio().id() ); 00711 #endif 00712 00713 #ifdef HIGHWAY_DEBUG 00714 if( state == CLUSTER_HEAD_CHANGED ) 00715 { 00716 debug().debug( "@@ %d CLUSTER_HEAD_CHANGED\n", radio().id() ); 00717 } 00718 else if( state == CLUSTER_FORMED ) 00719 { 00720 debug().debug( "@@ %d CLUSTER_FORMED\n", radio().id() ); 00721 } 00722 else if( state == NODE_JOINED ) 00723 { 00724 debug().debug( "@@ %d NODE_JOINED\n", radio().id() ); 00725 } 00726 #endif 00727 00728 // Otherwise flush routing and highway tables and start 00729 if ( state == CLUSTER_HEAD_CHANGED or state == NODE_JOINED ) 00730 { 00731 highway_table_.clear(); 00732 ports_queue_.clear(); 00733 routing_table_.clear(); 00734 ports_.clear(); 00735 neighbors_.clear(); 00736 #ifdef VISOR_DEBUG 00737 debug().debug( "+%d#%d#%d#1\n", radio().id(), cluster().cluster_id(), cluster().is_cluster_head() ); 00738 #endif 00739 00740 if ( state == CLUSTER_HEAD_CHANGED ) 00741 { 00742 neighbor().unreg_event_callback( HWY_N ); 00743 } 00744 else //is not cluster head. 00745 { 00746 #ifdef VISOR_DEBUG 00747 debug().debug( "$%d->%d$t\n", cluster().parent(), radio_->id() ); 00748 #endif 00749 cluster_discovery(); 00750 } 00751 } 00752 #ifdef HIGHWAY_METHOD_DEBUG 00753 debug().debug( "@@ %d METHOD_ENDED: start_wrapper()\n", radio().id() ); 00754 #endif 00755 } 00756 00757 // ----------------------------------------------------------------------- 00758 00759 template<typename OsModel_P, 00760 typename RoutingTable_P, 00761 typename Cluster_P, 00762 typename Neighbor_P, 00763 uint16_t MAX_CLUSTERS> 00764 void 00765 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00766 cluster_discovery( void ) 00767 { 00768 #ifdef HIGHWAY_METHOD_DEBUG 00769 debug().debug( "@@ %d METHOD CALLED: cluster_discovery()\n", radio().id() ); 00770 #endif 00771 00772 // Add the piggybacking information to the neighborhood discovery module. 00773 node_id_t id = cluster().cluster_id(); 00774 uint8_t length; 00775 00776 // Adapt cluster_id to the node_id_t size of the plattform. 00777 #ifdef ISENSE_APP 00778 uint8_t sid_buf[3]; 00779 sid_buf[0] = id & 0xFF; 00780 sid_buf[1] = id >> 8; 00781 sid_buf[2] = cluster().hops(); 00782 length = 3; 00783 #else 00784 uint8_t sid_buf[5]; 00785 sid_buf[0] = id & 0xFF; 00786 sid_buf[1] = ( id >> 8 ) & 0xFF; 00787 sid_buf[2] = ( id >> 16 ) & 0xFF; 00788 sid_buf[3] = ( id >> 24 ) & 0xFF; 00789 sid_buf[4] = cluster().hops(); 00790 length = 5; 00791 #endif 00792 00793 #ifdef HIGHWAY_DEBUG 00794 debug().debug( "@@ Node %d cluster_disc hops: %d\n", radio().id(), cluster().hops() ); 00795 #endif 00796 00797 // Register and add the payload space to the neighborhood discovery module. 00798 if ( neighbor().register_payload_space( HWY_N ) !=0 ) 00799 { 00800 debug().debug( "Error registering payload space\n" ); 00801 } 00802 else if(neighbor().set_payload( HWY_N, sid_buf, length )!=0) { 00803 debug().debug( "Error adding payload\n" ); 00804 } 00805 else 00806 { 00807 debug().debug( "%d Registering neighborhood\n", radio().id() ); 00808 uint8_t flags = nb_t::DROPPED_NB | nb_t::NEW_PAYLOAD_BIDI; 00809 neighbor().template reg_event_callback<HighwayCluster,&HighwayCluster::neighbor_callback>( HWY_N, flags, this ); 00810 if( not disc_timer_set_ ) 00811 { 00812 disc_timer_set_ = 1; 00813 timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ , this, (void *) 0 ); 00814 } 00815 } 00816 #ifdef HIGHWAY_METHOD_DEBUG 00817 debug().debug( "@@ %d METHOD ENDED: cluster_discovery()\n", radio().id() ); 00818 #endif 00819 } 00820 00821 // ----------------------------------------------------------------------- 00822 00823 template<typename OsModel_P, 00824 typename RoutingTable_P, 00825 typename Cluster_P, 00826 typename Neighbor_P, 00827 uint16_t MAX_CLUSTERS> 00828 void 00829 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00830 neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data) 00831 { 00832 #ifdef HIGHWAY_METHOD_DEBUG 00833 debug().debug("@@ %d METHOD CALLED: neighbor_callback(): cluster_head %d\n", radio().id(), cluster().is_cluster_head()); 00834 #endif 00835 00836 memcpy( buffer_, data, len ); 00837 00838 node_id_t sid; 00839 uint8_t hops; 00840 00841 // On payload event, process the data according to the plattform 00842 if ( nb_t::NEW_PAYLOAD_BIDI == event ) { 00843 #ifdef ISENSE_APP 00844 sid = ( buffer_[1] << 8 ) | buffer_[0]; 00845 hops = buffer_[2]; 00846 #else 00847 sid = ( buffer_[3] << 24 ) | ( buffer_[2] << 16 ) | ( buffer_[1] << 8 ) | buffer_[0]; 00848 hops = buffer_[4]; 00849 #endif 00850 00851 #ifdef NEIGHBOR_DEBUG 00852 debug().debug( "@@Node: %d, cluster_id: %d, hops: %d\n", from, sid, hops ); 00853 #endif 00854 // TODO: Check that the -1 commenting doesn't break it. 00855 // If not cluster leader and the message is from another cluster add it to the highway table of the now to be port candidate. 00856 if ( !cluster().is_cluster_head() and cluster().cluster_id() != sid /*and cluster().cluster_id() != -1 */) 00857 { 00858 debug().debug( "Pushing a %d, from %d into the highway table\n", from, sid ); 00859 displacing_push(highway_table_[sid].first, Hops_Node_id(hops + cluster().hops(), from)); 00860 } 00861 if( not disc_timer_set_ ) 00862 { 00863 disc_timer_set_ = 1; 00864 timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ , this, (void *) 0 ); 00865 } 00866 } 00867 else if ( nb_t::DROPPED_NB == event ) 00868 { 00869 //TODO: Work on fault tolerance here! 00870 // 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. 00871 debug().debug( "NODE %d: event DROPPED_NB %d \n",radio().id(), from); 00872 } 00873 #ifdef HIGHWAY_METHOD_DEBUG 00874 debug().debug("@@ %d METHOD ENDED: neighbor_callback()\n", radio().id()); 00875 #endif 00876 } 00877 00878 // ----------------------------------------------------------------------- 00879 00880 template<typename OsModel_P, 00881 typename RoutingTable_P, 00882 typename Cluster_P, 00883 typename Neighbor_P, 00884 uint16_t MAX_CLUSTERS> 00885 void 00886 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00887 discovery_timeout( void *userdata ) 00888 { 00889 #ifdef HIGHWAY_METHOD_DEBUG 00890 debug().debug( "@@ %d METHOD CALLED: discovery_timeout()\n", radio().id()); 00891 #endif 00892 if( disc_timer_set_ ) 00893 { 00894 disc_timer_set_ = 0; 00895 } 00896 00897 #ifdef HIGHWAY_DEBUG 00898 debug().debug( "Mida de la highway_table: %d\n", highway_table_.size() ); 00899 #endif 00900 00901 highway_iterator it; 00902 for ( it = highway_table_.begin(); it != highway_table_.end(); ++it ) 00903 { 00904 // Create a CANDIDACY highway message with: hops, id->candidate, cluster_id_own, cluster_id_target. 00905 set_msg_highway( buffer_, CANDIDACY, it->second.first.top().first, radio().id(), cluster().cluster_id(), it->first ); 00906 00907 // Send it to the parent. 00908 radio().send( cluster().parent(), msg_highway_size(), buffer_ ); 00909 } 00910 #ifdef HIGHWAY_METHOD_DEBUG 00911 debug().debug( "@@ %d METHOD ENDED: discovery_timeout()\n", radio().id() ); 00912 #endif 00913 } 00914 00915 // ----------------------------------------------------------------------- 00916 00917 template<typename OsModel_P, 00918 typename RoutingTable_P, 00919 typename Cluster_P, 00920 typename Neighbor_P, 00921 uint16_t MAX_CLUSTERS> 00922 void 00923 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00924 candidacies_timeout( void *userdata ) 00925 { 00926 #ifdef HIGHWAY_METHOD_DEBUG 00927 debug().debug( "@@ %d METHOD STARTED: candidacies_timeout()\n", radio().id() ); 00928 #endif 00929 if( cand_timer_set_ ) 00930 { 00931 cand_timer_set_ = 0; 00932 } 00933 if ( !ports_queue_.empty() ) // If no candidacies were presented we will call the same method after a work period. 00934 { 00935 #ifdef HIGHWAY_DEBUG 00936 debug().debug( "%d Disc_timeout leader with ports to start\n", radio().id() ); 00937 #endif 00938 highway_iterator it; 00939 for ( it = ports_queue_.begin(); it != ports_queue_.end(); ++it ) 00940 { 00941 start_port_negotiation( it, 4 ); // The four sets the amount of connectivity. 00942 } 00943 } 00944 #ifdef HIGHWAY_METHOD_DEBUG 00945 debug().debug( "@@ %d METHOD ENDED: candidacies_timeout()\n", radio().id() ); 00946 #endif 00947 } 00948 00949 00950 // ----------------------------------------------------------------------- 00951 00952 template<typename OsModel_P, 00953 typename RoutingTable_P, 00954 typename Cluster_P, 00955 typename Neighbor_P, 00956 uint16_t MAX_CLUSTERS> 00957 void 00958 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 00959 start_port_negotiation( highway_iterator it, uint8_t n ) 00960 { 00961 #ifdef HIGHWAY_METHOD_DEBUG 00962 debug().debug("@@ %d METHOD CALLED: start_port_negotiation()\n", radio().id()); 00963 #endif 00964 00965 aux.clear(); 00966 // If there are less candidates than desired connectivity put the available as ceiling. 00967 if ( n > it->second.first.size() ) 00968 { 00969 n = it->second.first.size(); 00970 } 00971 // Put max(n, size) elements into the aux vector. 00972 for ( int i = 0; i < n; ++i ) 00973 { 00974 aux.push_back( it->second.first.pop() ); 00975 } 00976 // Negotiate all the port candidates in aux. 00977 for ( int i = 0; i < n; ++i ) 00978 { 00979 port_negotiation( it->first, aux[i].second ); 00980 } 00981 // Put back the the port candidates. 00982 for ( int i = 0; i < n; ++i ) 00983 { 00984 it->second.first.push( aux[i] ); 00985 } 00986 aux.clear(); 00987 #ifdef HIGHWAY_METHOD_DEBUG 00988 debug().debug("@@ %d METHOD ENDED: start_port_negotiation()\n", radio().id()); 00989 #endif 00990 } 00991 00992 // ----------------------------------------------------------------------- 00993 00994 template<typename OsModel_P, 00995 typename RoutingTable_P, 00996 typename Cluster_P, 00997 typename Neighbor_P, 00998 uint16_t MAX_CLUSTERS> 00999 void 01000 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01001 port_negotiation( node_id_t sid, node_id_t candidate ) 01002 { 01003 #ifdef HIGHWAY_METHOD_DEBUG 01004 debug().debug( "@@ %d METHOD_CALLED: port_negotiation()\n", radio().id() ); 01005 #endif 01006 01007 // Create the highway_msg to request the other cluster a new connection. 01008 set_msg_highway( buffer_, PORT_REQ, msg_highway_.hops, candidate, cluster().cluster_id(), sid ); 01009 01010 // Send the highway_msg to the first node in the path to candidate. 01011 radio().send( routing_table_[candidate], msg_highway_size(), buffer_ ); 01012 01013 #ifdef HIGHWAY_METHOD_DEBUG 01014 debug().debug( "@@ %d METHOD_ENDED: port_negotiation()\n", radio().id() ); 01015 #endif 01016 } 01017 01018 // ----------------------------------------------------------------------- 01019 01020 template<typename OsModel_P, 01021 typename RoutingTable_P, 01022 typename Cluster_P, 01023 typename Neighbor_P, 01024 uint16_t MAX_CLUSTERS> 01025 void 01026 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01027 receive( node_id_t from, size_t len, block_data_t *data ) 01028 { 01029 #ifdef HIGHWAY_METHOD_DEBUG 01030 //debug().debug("@@ %d METHOD_CALLED: receive()\n", radio().id()); 01031 #endif 01032 01033 // Ignore if heard oneself's message. 01034 if ( from == radio().id() ) 01035 { 01036 return; 01037 } 01038 memcpy( &buffer_, data, len); 01039 01040 #ifdef HIGHWAY_MSG_RECV_DEBUG 01041 if ( buffer_[0] == CANDIDACY ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: CANDIDACY\n", radio().id(), from ); 01042 else if ( buffer_[0] == PORT_REQ ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_REQ\n", radio().id(), from ); 01043 else if ( buffer_[0] == PORT_REQ2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_REQ2\n", radio().id(), from ); 01044 else if ( buffer_[0] == PORT_ACK ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_ACK\n", radio().id(), from ); 01045 else if ( buffer_[0] == PORT_ACK2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_ACK2\n", radio().id(), from ); 01046 else if ( buffer_[0] == PORT_NACK ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_NACK\n", radio().id(), from ); 01047 else if ( buffer_[0] == PORT_NACK2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_NACK2\n", radio().id(), from ); 01048 else if ( buffer_[0] == SEND ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: SEND\n", radio().id(), from ); 01049 else if ( buffer_[0] == SEND2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: SEND2\n", radio().id(), from ); 01050 #endif 01051 01052 // Messages travelling to the current node cluster leader are processed in send_to_leader 01053 if ( buffer_[0] == CANDIDACY or buffer_[0] == PORT_REQ2 or buffer_[0] == PORT_ACK2 or buffer_[0] == PORT_NACK2 or buffer_[0] == SEND2 ) 01054 { 01055 send_to_leader( from, len, buffer_ ); 01056 } 01057 else if ( buffer_[0] == PORT_REQ or buffer_[0] == PORT_ACK or buffer_[0] == PORT_NACK ) // Construction messages travelling outwards 01058 { 01059 send_away( from, len, buffer_ ); 01060 } 01061 else if ( buffer_[0] == SEND) // Data messages travelling outwards. 01062 { 01063 process_send( from, len, buffer_ ); 01064 } 01065 } 01066 01067 // ----------------------------------------------------------------------- 01068 01069 template<typename OsModel_P, 01070 typename RoutingTable_P, 01071 typename Cluster_P, 01072 typename Neighbor_P, 01073 uint16_t MAX_CLUSTERS> 01074 void 01075 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01076 send_to_leader( node_id_t from, size_t len, block_data_t *data ) 01077 { 01078 #ifdef HIGHWAY_METHOD_DEBUG 01079 debug().debug( "@@ %d METHOD_CALLED: send_to_leader()\n", radio().id()) ; 01080 #endif 01081 uint8_t type = data[0]; 01082 01083 #ifdef HIGHWAY_MSG_RECV_DEBUG 01084 if( type == SEND2 ) 01085 { 01086 debug().debug( "---------------SENDRECV2--------------\n" ); 01087 for( int i = 0; i<len; ++i ) 01088 debug().debug( "Data[%d]: %d\n", i, data[i] ); 01089 debug().debug( "---------------/SENDRECV2--------------\n" ); 01090 } 01091 #endif 01092 01093 get_msg_highway( &msg_highway_, data ); 01094 01095 if ( type == CANDIDACY or type == PORT_REQ2 ) 01096 { 01097 routing_table_[msg_highway_.candidate_id] = from; 01098 } 01099 else if ( type == PORT_ACK2 ) 01100 { 01101 #ifdef VISOR_DEBUG 01102 debug().debug( "$%d->%d$h\n", from, radio_->id() ); 01103 #endif 01104 } 01105 01106 if ( cluster().is_cluster_head() ) 01107 { 01108 cluster_head_work( from, len, data ); 01109 } 01110 else 01111 { 01112 radio().send( cluster().parent(), len, data ); 01113 } 01114 #ifdef HIGHWAY_METHOD_DEBUG 01115 debug().debug( "@@ %d METHOD_ENDED: send_to_leader()\n", radio().id()) ; 01116 #endif 01117 } 01118 01119 // ----------------------------------------------------------------------- 01120 01121 template<typename OsModel_P, 01122 typename RoutingTable_P, 01123 typename Cluster_P, 01124 typename Neighbor_P, 01125 uint16_t MAX_CLUSTERS> 01126 void 01127 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01128 send_away( node_id_t from, size_t len, block_data_t *data ) 01129 { 01130 #ifdef HIGHWAY_METHOD_DEBUGG 01131 debug().debug("@@ %d METHOD_CALLED: send_away()\n", radio().id()); 01132 #endif 01133 01134 #ifdef VISOR_DEBUG 01135 if( *data == PORT_ACK ) 01136 debug().debug("$%d->%d$h\n", from, radio_->id()); 01137 #endif 01138 01139 //msg_highway_ = * ((msg_highway * ) data); 01140 get_msg_highway( &msg_highway_, data ); 01141 01142 // Check if we are still in the cluster that originated the request. 01143 if ( from == cluster().parent() ) 01144 { 01145 // If the current node is not the port, continue the way to the port. 01146 if ( msg_highway_.candidate_id != radio().id() ) 01147 { 01148 radio().send( routing_table_[msg_highway_.candidate_id], msg_highway_size(), data ); 01149 } 01150 else // Send the message o the other cluster port and set connected_to. 01151 { 01152 if ( msg_highway_.msg_id == PORT_REQ ) 01153 { 01154 radio().send( highway_table_[msg_highway_.sid_target].first.top().second, sizeof( msg_highway ), data ); 01155 } 01156 else if ( msg_highway_.msg_id == PORT_ACK ) { 01157 connected_to = routing_table_[msg_highway_.sid_source]; 01158 radio().send( connected_to, msg_highway_size(), data ); 01159 } 01160 else //NACK 01161 { 01162 radio().send( routing_table_[msg_highway_.sid_source], msg_highway_size(), data ); 01163 routing_table_.erase( routing_table_.find(msg_highway_.sid_source) ); 01164 } 01165 } 01166 } 01167 else // Create a "2" message. 01168 { 01169 if ( msg_highway_.msg_id == PORT_REQ ) 01170 { 01171 msg_highway_.msg_id = PORT_REQ2; 01172 routing_table_[msg_highway_.sid_source] = from; 01173 msg_highway_.candidate_id = radio().id(); 01174 } 01175 else if ( msg_highway_.msg_id == PORT_ACK ) { 01176 #ifdef VISOR_DEBUG 01177 debug().debug( "+%d#%d#%d#1\n", radio().id(), cluster().cluster_id(), cluster().is_cluster_head() ); 01178 debug().debug( "+%d#%d#%d#1\n", from, msg_highway_.sid_target, cluster().is_cluster_head() ); 01179 #endif 01180 msg_highway_.msg_id = PORT_ACK2; 01181 connected_to = from; 01182 01183 } 01184 else //NACK 01185 { 01186 msg_highway_.msg_id = PORT_NACK2; 01187 msg_highway_.candidate_id = radio().id(); 01188 } 01189 01190 msg_highway_.candidate_id = radio().id(); 01191 set_msg_highway( buffer_, msg_highway_.msg_id, msg_highway_.hops, msg_highway_.candidate_id, msg_highway_.sid_source, msg_highway_.sid_target ); 01192 radio().send( cluster().parent(), msg_highway_size(), buffer_ ); 01193 } 01194 #ifdef HIGHWAY_METHOD_DEBUGG 01195 debug().debug("@@ %d METHOD_ENDED: send_away()\n", radio().id()); 01196 #endif 01197 } 01198 01199 // ----------------------------------------------------------------------- 01200 01201 template<typename OsModel_P, 01202 typename RoutingTable_P, 01203 typename Cluster_P, 01204 typename Neighbor_P, 01205 uint16_t MAX_CLUSTERS> 01206 void 01207 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01208 process_send( node_id_t from, size_t len, block_data_t *data ) 01209 { 01210 #ifdef HIGHWAY_METHOD_DEBUGG 01211 debug().debug("@@ %d METHOD_CALLED: send_process()\n", radio().id()); 01212 #endif 01213 node_id_t port; 01214 01215 #ifdef HIGHWAY_MSG_RECV_DEBUG 01216 debug().debug("---------------SENDRECV--------------\n"); 01217 for(int i = 0; i<len; ++i) 01218 debug().debug("Data[%d]: %d\n", i, data[i]); 01219 debug().debug("---------------/SENDRECV--------------\n"); 01220 #endif 01221 01222 // Check if we are still in the cluster that originated the request. 01223 if ( from == cluster().parent() ) 01224 { 01225 // If the current node is not the port, continue the way to the port. 01226 #ifdef ISENSE_APP 01227 port = ( data[4] << 8 ) | data[3]; 01228 #else 01229 port = ( data[8] << 24 ) | ( data[7] << 16 ) | ( data[6] << 8 ) | data[5]; 01230 #endif 01231 01232 if ( port != radio().id() ) 01233 { 01234 radio().send( routing_table_[port], len, data ); 01235 } 01236 else // Send the message o the other cluster port and set connected_to. 01237 { 01238 radio().send( connected_to, len, data ); 01239 } 01240 } 01241 else // Create a SEND2 message. 01242 { 01243 *data = SEND2; 01244 radio().send( cluster().parent(), len, data ); 01245 } 01246 #ifdef HIGHWAY_METHOD_DEBUGG 01247 debug().debug("@@ %d METHOD_ENDED: send_process()\n", radio().id()); 01248 #endif 01249 } 01250 01251 // ----------------------------------------------------------------------- 01252 01253 template<typename OsModel_P, 01254 typename RoutingTable_P, 01255 typename Cluster_P, 01256 typename Neighbor_P, 01257 uint16_t MAX_CLUSTERS> 01258 void 01259 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01260 cluster_head_work( node_id_t from, size_t len, block_data_t *data ) 01261 { 01262 #ifdef HIGHWAY_METHOD_DEBUG 01263 debug().debug("@@ %d METHOD_CALLED: cluster_head_work()\n", radio().id() ); 01264 #endif 01265 node_id_t sender; 01266 //msg_highway_ = *((msg_highway * ) data); 01267 get_msg_highway( &msg_highway_, data ); 01268 01269 if ( msg_highway_.msg_id == CANDIDACY ) // Add the port candidate to the queue. 01270 { 01271 debug().debug( "Putting an entry to ports_queue on %d\n", radio().id() ); 01272 displacing_push( ports_queue_[msg_highway_.sid_target].first, Hops_Node_id( msg_highway_.hops, msg_highway_.candidate_id ) ); 01273 if( not cand_timer_set_ ) 01274 { 01275 cand_timer_set_ = 1; 01276 timer().template set_timer<self_type, &self_type::candidacies_timeout>( discovery_time_ , this, (void *) 0 ); 01277 } 01278 } 01279 else if ( msg_highway_.msg_id == PORT_REQ2 ) // Accept or reject the highway request. 01280 { 01281 if (highway_table_[msg_highway_.sid_source].first.size() < 4) 01282 { 01283 displacing_push( highway_table_[msg_highway_.sid_source].first, Hops_Node_id( msg_highway_.hops, msg_highway_.candidate_id ) ); 01284 highway_table_[msg_highway_.sid_source].second = 0; 01285 msg_highway_.msg_id = PORT_ACK; 01286 } 01287 else //IMPROVE: extra NACK conditions. 01288 { 01289 msg_highway_.msg_id = PORT_NACK; 01290 } 01291 set_msg_highway( buffer_, msg_highway_.msg_id, msg_highway_.hops, msg_highway_.candidate_id, msg_highway_.sid_source, msg_highway_.sid_target ); 01292 radio().send( from, msg_highway_size(), buffer_ ); 01293 } 01294 else if ( msg_highway_.msg_id == PORT_ACK2 ) // Establish the port. 01295 { 01296 displacing_push( highway_table_[msg_highway_.sid_target].first, pop_port( ports_queue_[msg_highway_.sid_target].first, msg_highway_.candidate_id ) ); 01297 highway_table_[msg_highway_.sid_target].second = 0; 01298 } 01299 else if ( msg_highway_.msg_id == PORT_NACK2 ) // Remove the port candidate. 01300 { 01301 pop_port( ports_queue_[msg_highway_.sid_target].first, msg_highway_.candidate_id ); 01302 } 01303 else if ( msg_highway_.msg_id == SEND2 ) // Call the registered (if exists) receiving method. 01304 { 01305 #ifdef ISENSE_APP 01306 sender = (data[6] << 8) | data[5]; 01307 #else 01308 sender = ( data[12] << 24 ) | ( data[11] << 16 ) | ( data[10] << 8 ) | data[9]; 01309 #endif 01310 #ifdef HIGHWAY_MSG_RECV_DEBUG 01311 debug().debug( "---------------HEAD_WORK_RECV--------------\n" ); 01312 for( int i = 0; i<len; ++i ) 01313 debug().debug( "Data[%d]: %d\n", i, data[i] ); 01314 debug().debug( "---------------HEAD_WORK_RECV--------------\n" ); 01315 #endif 01316 01317 if( hwy_recv_callback_ ) hwy_recv_callback_(sender, len-SEND_OVERHEAD, &data[SEND_OVERHEAD]); 01318 } 01319 #ifdef HIGHWAY_METHOD_DEBUG 01320 debug().debug("@@ %d METHOD_ENDED: cluster_head_work()\n", radio().id() ); 01321 #endif 01322 } 01323 01324 // ----------------------------------------------------------------------- 01325 // Queue and other helper methods. | 01326 // ----------------------------------------------------------------------- 01327 01328 template<typename OsModel_P, 01329 typename RoutingTable_P, 01330 typename Cluster_P, 01331 typename Neighbor_P, 01332 uint16_t MAX_CLUSTERS> 01333 void 01334 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01335 displacing_push( PQ& pq, Hops_Node_id pin ) 01336 { 01337 #ifdef HIGHWAY_METHOD_DEBUG 01338 debug().debug("@@ %d METHOD_CALLED: displacing_push()\n", radio().id()); 01339 #endif 01340 debug().debug(" Disc foo %d\n", radio().id() ); 01341 if ( pq.size() < MAX_CLUSTER_PORTS ) 01342 { 01343 pq.push( pin ); 01344 debug().debug(" Disc bar %d\n", radio().id() ); 01345 return; 01346 } 01347 01348 aux.clear(); 01349 01350 for ( int i = 0; i < MAX_CLUSTER_PORTS-1; ++i ) 01351 { 01352 aux.push_back( pq.pop() ); 01353 } 01354 01355 if ( pin < pq.top() ) 01356 { 01357 pq.pop(); 01358 pq.push( pin ); 01359 } 01360 01361 for ( int i = 0; i < MAX_CLUSTER_PORTS-1; ++i ) 01362 { 01363 pq.push( aux[aux.size()-1] ); 01364 aux.pop_back(); 01365 } 01366 debug().debug(" Disc bar2 %d\n", radio().id() ); 01367 } 01368 01369 // ----------------------------------------------------------------------- 01370 01371 template<typename OsModel_P, 01372 typename RoutingTable_P, 01373 typename Cluster_P, 01374 typename Neighbor_P, 01375 uint16_t MAX_CLUSTERS> 01376 typename HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::Hops_Node_id 01377 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>:: 01378 pop_port( PQ& pq, node_id_t port ) 01379 { 01380 #ifdef HIGHWAY_METHOD_DEBUG 01381 debug().debug( "@@ %d METHOD_CALLED: pop_port()\n", radio().id() ); 01382 #endif 01383 aux.clear(); 01384 Hops_Node_id ret; 01385 for ( uint16_t i = 0; i < pq.size(); ++i ) 01386 { 01387 if ( pq.top().second != port ) 01388 { 01389 aux.push_back( pq.pop() ); 01390 } 01391 else 01392 { 01393 ret = pq.top(); 01394 } 01395 } 01396 01397 for ( uint16_t i = 0; i < aux.size(); ++i ) 01398 { 01399 pq.push(aux[i]); 01400 } 01401 #ifdef HIGHWAY_METHOD_DEBUG 01402 debug().debug( "@@ %d METHOD_ENDED: pop_port()\n", radio().id() ); 01403 #endif 01404 return ret; 01405 } 01406 } 01407 #endif