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