Wiselib
wiselib.testing/algorithms/cluster/highway/highway_stabilizing_new.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines