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