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