Wiselib
wiselib.testing/algorithms/cluster/highway/highway_dumber.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 HIGHWAY_METHOD_DEBUG
00047 //#define HIGHWAY_MSG_RECV_DEBUG
00048 //#define VISOR_DEBUG
00049 #define CTI_VISOR
00050 //#define HWY_METRICS
00051 #ifdef ISENSE_APP
00052 #define SEND_OVERHEAD 7
00053 #else
00054 #define SEND_OVERHEAD 13 
00055 #endif
00056 
00057 namespace wiselib{
00058 template<typename OsModel_P,
00059      typename RoutingTable_P,
00060      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> >,
00061      typename Neighbor_P = wiselib::Echo<OsModel_P, typename OsModel_P::TxRadio, typename OsModel_P::Timer, typename OsModel_P::Debug>,
00062      uint16_t MAX_CLUSTERS = 8>
00063 class HighwayCluster
00064 {
00065 public:
00066       
00067       // OS modules.
00068      typedef OsModel_P OsModel;
00069      typedef typename OsModel::Rand Rand;
00070      typedef typename OsModel::TxRadio Radio;
00071      typedef typename OsModel::Timer Timer;
00072      typedef typename OsModel::Clock Clock;
00073      typedef typename OsModel::Debug Debug;
00074      typedef typename OsModel::TxRadio TxRadio;
00075 
00076      // Type definitions.
00077      typedef wiselib::AtributeClusterHeadDecision<OsModel, TxRadio> CHD_t;
00078      typedef wiselib::BfsJoinDecision<OsModel, TxRadio> JD_t;
00079      typedef wiselib::FrontsIterator<OsModel, TxRadio> IT_t;
00080      
00081      // Type definition of the used Templates.
00082      typedef RoutingTable_P RoutingTable;
00083      typedef Cluster_P Cluster;
00084      typedef Neighbor_P Neighbor;
00085      
00086      typedef HighwayCluster<OsModel, RoutingTable, Cluster, Neighbor, MAX_CLUSTERS> self_type;
00087      typedef wiselib::Echo<OsModel, TxRadio, Timer, Debug> nb_t;
00088      typedef self_type* self_pointer_t;
00089 
00090      // Basic types definition.
00091      typedef typename Radio::node_id_t node_id_t;
00092      typedef typename Radio::size_t size_t;
00093      typedef typename Radio::block_data_t block_data_t;
00094      typedef typename Timer::millis_t millis_t;
00095      
00096      // Type definition for the receive callback.
00097      typedef delegate3<void, node_id_t, size_t, block_data_t*> highway_delegate_t;
00098      
00099      // Type definition for the special data structures of the highway.
00100      typedef wiselib::pair<uint8_t, uint8_t> hops_ack;
00101      typedef wiselib::pair<node_id_t, node_id_t> source_target;
00102      typedef wiselib::pair<source_target, hops_ack> entry;
00103      typedef wiselib::MapStaticVector<OsModel, node_id_t, entry, MAX_CLUSTERS> HighwayTable;
00104      typedef HighwayTable PortsQueue;
00105      typedef wiselib::vector_static<OsModel, node_id_t, MAX_CLUSTERS> Node_vect;
00106      
00107      // Type definition for the special types iterators.
00108      typedef typename HighwayTable::iterator highway_iterator;
00109 
00110      // Return types definition.
00111      enum ErrorCodes {
00112           SUCCESS = OsModel::SUCCESS,
00113           ERR_UNSPEC = OsModel::ERR_UNSPEC
00114      };
00115      
00116      // Possible highway message ids.
00117      enum msg_id {
00118           CANDIDACY = 200,
00119           PORT_REQ = 201,
00120           PORT_REQ2 = 202,
00121           PORT_ACK = 203,
00122           PORT_ACK2 = 204,
00123           PORT_NACK = 205,
00124           PORT_NACK2 = 206,
00125           SEND = 207,
00126           SEND2 = 208,
00127           ACK = 109,
00128           ACK2 = 110
00129      };
00130      
00131      // --------------------------------------------------------------------
00132      // Public method declaration.                                         |
00133      // --------------------------------------------------------------------
00134      
00137      HighwayCluster():
00138      radio_ ( 0 ),
00139      timer_ ( 0 ),
00140      clock_ ( 0 ),
00141      debug_ ( 0 ),
00142      rand_ ( 0 ),
00143      cluster_ ( 0 ),
00144      discovery_time_ ( 5000 ),
00145      disc_timer_set_(0),
00146      cand_timer_set_(0),
00147      max_acks_(25)
00148      {
00149      };
00150      
00153      ~HighwayCluster(){};
00154      
00155      
00159      int init( TxRadio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Rand& rand, Cluster& cluster, Neighbor& neighbor );
00160      
00164      void enable( void );
00165 
00172      void send( node_id_t receiver, size_t len, block_data_t *data );
00173      
00178      //Node_vect cluster_neighbors();
00179      void cluster_neighbors(Node_vect * neighbor);
00180 
00184      template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)>
00185      uint8_t hwy_reg_recv_callback(T *obj_pnt) {
00186           hwy_recv_callback_ = highway_delegate_t::template from_method<T, TMethod > ( obj_pnt );
00187           return 0;
00188      }
00189      
00192      void unreg_hwy_recv_callback() {
00193           hwy_recv_callback_ = highway_delegate_t();
00194      }
00195      
00196      // --------------------------------------------------------------------
00197      // Setters                                                            |
00198      // --------------------------------------------------------------------
00199      
00203      inline void set_discovery_time( millis_t t ) {
00204           discovery_time_ = t;
00205      };
00206      
00210      inline void set_max_acks( uint8_t m ) {
00211           max_acks_ = m;
00212      };
00213      
00214 private:
00215      // Typenaming the underlying modules.
00216      typename Radio::self_pointer_t radio_;
00217      typename Timer::self_pointer_t timer_;
00218      typename Clock::self_pointer_t clock_;
00219      typename Debug::self_pointer_t debug_;
00220      typename Rand::self_pointer_t rand_; 
00221      typename Cluster::self_type* cluster_;
00222      typename Neighbor::self_t* neighbor_;
00223      
00224      // Highway control message.
00225      struct msg_highway {
00226           uint8_t msg_id, hops;
00227           node_id_t source, target, sid_source, sid_target;
00228      };
00229     
00230      enum msg_highway_size {
00231           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 )
00232      };
00233 
00234      inline 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 ) 
00235      {
00236           int idx = 0;
00237           write<OsModel, block_data_t, uint8_t>( data + idx, msg_id );
00238           idx += sizeof( uint8_t );
00239           write<OsModel, block_data_t, uint8_t>( data + idx, hops );
00240           idx += sizeof( uint8_t );
00241           write<OsModel, block_data_t, node_id_t>( data + idx, source );
00242           idx += sizeof( node_id_t );
00243           write<OsModel, block_data_t, node_id_t>( data + idx, target );
00244           idx += sizeof( node_id_t ); 
00245           write<OsModel, block_data_t, node_id_t>( data + idx, sid_source );
00246           idx += sizeof( node_id_t );
00247           write<OsModel, block_data_t, node_id_t>( data + idx, sid_target ); 
00248      }
00249 
00250      inline void get_msg_highway( msg_highway * msg, uint8_t * data )
00251      {
00252           int idx = 0;
00253           msg->msg_id = read<OsModel, block_data_t, uint8_t>( data + idx );
00254           idx += sizeof( uint8_t );
00255           msg->hops = read<OsModel, block_data_t, uint8_t>( data + idx );
00256           idx += sizeof( uint8_t );
00257           msg->source = read<OsModel, block_data_t, node_id_t>( data + idx );
00258           idx += sizeof( node_id_t );
00259           msg->target = read<OsModel, block_data_t, node_id_t>( data + idx );
00260           idx += sizeof( node_id_t ); 
00261           msg->sid_source = read<OsModel, block_data_t, node_id_t>( data + idx );
00262           idx += sizeof( node_id_t );
00263           msg->sid_target = read<OsModel, block_data_t, node_id_t>( data + idx );
00264      }
00265      
00266      // --------------------------------------------------------------------
00267      // Private variables declaration.                                        |
00268      // --------------------------------------------------------------------
00269      
00271      msg_highway msg_highway_;
00272      
00274      millis_t discovery_time_;
00275      
00277      uint8_t disc_timer_set_;
00278 
00280      uint8_t cand_timer_set_;
00281 
00283      highway_delegate_t hwy_recv_callback_;
00284      
00286      RoutingTable routing_table_;
00287      
00289      HighwayTable highway_table_;
00290      
00292      PortsQueue ports_queue_;
00293      
00295      block_data_t buffer_[Radio::MAX_MESSAGE_LENGTH];
00296 
00298      int8_t max_acks_;
00299 
00307      void send( bool send_ack, node_id_t receiver, size_t len, block_data_t *data );
00308      
00310      CHD_t CHD_;
00311      JD_t JD_;
00312      IT_t IT_;
00313 
00314 #ifdef HWY_METRICS
00315 
00316      uint16_t r_cand, r_req, r_req2, r_pack, r_pack2, r_pnack, r_pnack2, r_send, r_send2, r_ack, r_ack2;
00317      uint16_t s_cand, s_req, s_req2, s_pack, s_pack2, s_pnack, s_pnack2, s_send, s_send2, s_ack, s_ack2;
00318      uint8_t n_hwy;
00319      uint8_t time;
00320 #endif
00321      
00322      // --------------------------------------------------------------------
00323      // Private method declaration.                                        |
00324      // --------------------------------------------------------------------
00325      
00329      Radio& radio() {
00330           return *radio_;
00331      }
00332      
00336      Timer& timer() {
00337           return *timer_;
00338      }
00339 
00343      Clock& clock() {
00344           return *clock_;
00345      }
00346      
00350      Debug& debug() {
00351           return *debug_;
00352      }
00353      
00357      Cluster& cluster() {
00358           return *cluster_;
00359      }
00360      
00364      Neighbor& neighbor() {
00365           return *neighbor_;
00366      }
00367      
00372      void cluster_callback(int state);
00373      
00377      void cluster_discovery( void );
00378 
00386      void neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data);
00387      
00392      void discovery_timeout( void *userdata );
00393 
00398      void candidacies_timeout( void *userdata );
00399 
00406      void receive( node_id_t from, size_t len, block_data_t *data );
00407      
00414      void send_to_leader( node_id_t from, size_t len, block_data_t *data );
00415      
00422      void send_away( node_id_t from, size_t len, block_data_t *data );
00423      
00430      void process_send( node_id_t from, size_t len, block_data_t *data );
00431      
00438      void cluster_head_work( node_id_t from, size_t len, block_data_t *data );
00439 
00440 #ifdef HWY_METRICS
00441 
00444      void graph_print( void * userdata );
00445 #endif
00446      
00447 }; // End of class.
00448 
00449 // --------------------------------------------------------------------
00450 // Start of the method code: PUBLIC METHODS                           |
00451 // --------------------------------------------------------------------
00452 template<typename OsModel_P,
00453          typename RoutingTable_P,
00454          typename Cluster_P,
00455          typename Neighbor_P,
00456          uint16_t MAX_CLUSTERS>
00457 inline int
00458 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00459 init( TxRadio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Rand& rand, Cluster& cluster, Neighbor& neighbor ) {
00460      radio_ = &tx_radio;
00461      timer_ = &timer;
00462      clock_ = &clock;
00463      debug_ = &debug;
00464      rand_ = &rand;
00465      cluster_ = &cluster;
00466      neighbor_ = &neighbor;
00467 
00468      // Initialize the neighborhood discovery module.
00469      neighbor_->init( tx_radio, *clock_, *timer_, *debug_ );
00470      
00471      // Stabilizing cluster initialization.
00472      // set the HeadDecision Module
00473      cluster_->set_cluster_head_decision( CHD_ );
00474      // set the JoinDecision Module
00475      cluster_->set_join_decision( JD_ );
00476      // set the Iterator Module
00477      cluster_->set_iterator( IT_ );
00478      cluster_->init( *radio_, *timer_, *debug_, *rand_, *neighbor_ );
00479 
00480      //IMPROVE: Take the value upper as soon as more hops clustering is tested.
00481      //cluster_->set_maxhops( 1 );
00482      cluster_->set_maxhops( 2 );
00483 
00484 #ifdef HWY_METRICS
00485      // Graph variables initialization
00486      r_cand = 0;
00487      s_cand = 0;
00488      r_req = 0;
00489      s_req = 0;
00490      r_req2 = 0;
00491      s_req2 = 0;
00492      r_pack = 0;
00493      s_pack = 0;
00494      r_pack2 = 0;
00495      s_pack2 = 0;
00496      r_pnack = 0;
00497      s_pnack = 0;
00498      r_pnack2 = 0;
00499      s_pnack2 = 0;
00500      r_send = 0;
00501      s_send = 0;
00502      r_send2 = 0;
00503      s_send2 = 0;
00504      r_ack = 0;
00505      s_ack = 0;
00506      r_ack2 = 0;
00507      s_ack2 = 0;
00508      n_hwy = 0;
00509      time = 0;
00510 #endif
00511      
00512      return SUCCESS;
00513 }
00514 
00515 // --------------------------------------------------------------------
00516 
00517 template<typename OsModel_P,
00518          typename RoutingTable_P,
00519          typename Cluster_P,
00520          typename Neighbor_P,
00521          uint16_t MAX_CLUSTERS>
00522 void
00523 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00524 enable( void )
00525 {
00526 #ifdef HIGHWAY_METHOD_DEBUG
00527      debug().debug( "@@ %d METHOD CALLED: enable()\n", radio().id() );
00528 #endif
00529      // Enabling and registering radio 
00530      radio().enable_radio();
00531      radio().template reg_recv_callback<self_type, &self_type::receive>( this );
00532 
00533      // Enabling neighborhood and registering cluster
00534      cluster().enable();
00535      cluster().template reg_state_changed_callback<self_type, &self_type::cluster_callback > ( this );
00536      neighbor().enable();
00537 
00538 #ifdef HWY_METRICS
00539      time = 0;
00540      graph_print( ( void * )0 );
00541 #endif
00542 
00543 #ifdef HIGHWAY_METHOD_DEBUG
00544      debug().debug( "@@ %d METHOD ENDED: enable()\n", radio().id() );
00545 #endif
00546 }
00547 
00548 // --------------------------------------------------------------------
00549 
00550 template<typename OsModel_P,
00551          typename RoutingTable_P,
00552          typename Cluster_P,
00553          typename Neighbor_P,
00554          uint16_t MAX_CLUSTERS>
00555 void
00556 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00557 send( node_id_t destination, size_t len, block_data_t *data )
00558 {
00559 #ifdef HIGHWAY_METHOD_DEBUG
00560      debug().debug( "@@ %d METHOD CALLED: send()\n", radio().id() );
00561 #endif
00562 
00563      send(true, destination, len, data);
00564 
00565 #ifdef HIGHWAY_METHOD_DEBUG
00566      debug().debug( "@@ %d METHOD ENDED: send()\n", radio().id() );
00567 #endif
00568 }
00569 
00570 // -----------------------------------------------------------------------
00571 
00572 template<typename OsModel_P,
00573          typename RoutingTable_P,
00574          typename Cluster_P,
00575          typename Neighbor_P,
00576          uint16_t MAX_CLUSTERS>
00577 void
00578 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00579 cluster_neighbors( Node_vect * neighbors )
00580 {
00581 #ifdef HIGHWAY_METHOD_DEBUG
00582      debug().debug( "@@ %d METHOD CALLED: cluster_neighbors()\n", radio().id() );
00583 #endif
00584 
00585      neighbors->clear();
00586      if ( not cluster().is_cluster_head() )
00587      {
00588          return; 
00589      }
00590      
00591      highway_iterator it;
00592      for ( it = highway_table_.begin(); it != highway_table_.end(); ++it )
00593      {
00594           neighbors->push_back( it->first );
00595      }
00596 
00597 #ifdef HIGHWAY_METHOD_DEBUG
00598      debug().debug( "@@ %d METHOD ENDED: cluster_neighbors()\n", radio().id() );
00599 #endif
00600 }
00601 
00602 // -----------------------------------------------------------------------
00603 // PRIVATE METHODS                                                       |
00604 // -----------------------------------------------------------------------
00605 
00606 template<typename OsModel_P,
00607          typename RoutingTable_P,
00608          typename Cluster_P,
00609          typename Neighbor_P,
00610          uint16_t MAX_CLUSTERS>
00611 void
00612 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00613 cluster_callback( int state )
00614 {
00615 #ifdef HIGHWAY_METHOD_DEBUG
00616      debug().debug( "@@ %d METHOD_CALLED: cluster_callback()\n", radio().id() );
00617 #endif
00618 
00619 #ifdef HIGHWAY_DEBUG
00620      if( state == CLUSTER_HEAD_CHANGED )
00621      {
00622           debug().debug( "@@ %d CLUSTER_HEAD_CHANGED\n", radio().id() );
00623      }
00624      else if( state == CLUSTER_FORMED )
00625      {
00626           debug().debug( "@@ %d CLUSTER_FORMED\n", radio().id() );
00627      }
00628      else if( state == NODE_JOINED )
00629      {
00630           debug().debug( "@@ %d NODE_JOINED\n", radio().id() );
00631      }
00632 #endif
00633      
00634      // Otherwise flush routing and highway tables and start
00635      if ( state == CLUSTER_HEAD_CHANGED or state == NODE_JOINED )
00636      {
00637           highway_table_.clear();
00638           ports_queue_.clear();
00639           routing_table_.clear();
00640 #ifdef VISOR_DEBUG 
00641           debug().debug( "+%d#%d#%d#1\n", radio().id(), cluster().cluster_id(), cluster().is_cluster_head() );
00642 #endif
00643 
00644           if ( state == CLUSTER_HEAD_CHANGED )
00645           {
00646                neighbor().unreg_event_callback( HWY_N );
00647           }
00648           else //is not cluster head.
00649           {
00650 #ifdef VISOR_DEBUG
00651                debug().debug( "$%d->%d$t\n", cluster().parent(), radio_->id() );
00652 #endif
00653                cluster_discovery();
00654           }
00655      }
00656 #ifdef HIGHWAY_METHOD_DEBUG
00657      debug().debug( "@@ %d METHOD_ENDED: start_wrapper()\n", radio().id() );
00658 #endif
00659 }
00660 
00661 // -----------------------------------------------------------------------
00662 
00663 template<typename OsModel_P,
00664          typename RoutingTable_P,
00665          typename Cluster_P,
00666          typename Neighbor_P,
00667          uint16_t MAX_CLUSTERS>
00668 void
00669 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00670 cluster_discovery( void )
00671 {
00672 #ifdef HIGHWAY_METHOD_DEBUG
00673      debug().debug( "@@ %d METHOD CALLED: cluster_discovery()\n", radio().id() );
00674 #endif
00675 
00676      // Add the piggybacking information to the neighborhood discovery module.
00677      node_id_t id = cluster().cluster_id();
00678      uint8_t length;
00679      
00680      // Adapt cluster_id to the node_id_t size of the plattform.
00681 #ifdef ISENSE_APP
00682      uint8_t sid_buf[3];
00683      sid_buf[0] = id & 0xFF;
00684      sid_buf[1] = id >> 8;
00685      sid_buf[2] = cluster().hops();
00686      length = 3;
00687 #else
00688      uint8_t sid_buf[5];
00689      sid_buf[0] = id & 0xFF;
00690      sid_buf[1] = ( id >> 8 ) & 0xFF;
00691      sid_buf[2] = ( id >> 16 ) & 0xFF;
00692      sid_buf[3] = ( id >> 24 ) & 0xFF;
00693      sid_buf[4] = cluster().hops();
00694      length = 5;
00695 #endif
00696 
00697 #ifdef HIGHWAY_DEBUG
00698      debug().debug( "@@ Node %d:%d cluster_disc hops: %d\n", id, radio().id(), cluster().hops() );
00699 #endif
00700 
00701      // Register and add the payload space to the neighborhood discovery module.
00702      if ( neighbor().register_payload_space( HWY_N ) !=0 )
00703      {
00704 #ifdef HIGHWAY_DEBUG
00705           debug().debug( "Error registering payload space\n" );
00706 #endif
00707      }
00708      else if(neighbor().set_payload( HWY_N, sid_buf, length )!=0) {
00709 #ifdef HIGHWAY_DEBUG
00710           debug().debug( "Error adding payload\n" );
00711 #endif
00712      }
00713      else
00714      {
00715 #ifdef HIGHWAY_DEBUG
00716           debug().debug( "%d Registering neighborhood\n", radio().id() );
00717 #endif          
00718           uint8_t flags = nb_t::LOST_NB_BIDI | nb_t::NEW_PAYLOAD_BIDI;
00719           neighbor().template reg_event_callback<HighwayCluster,&HighwayCluster::neighbor_callback>( HWY_N, flags, this );
00720           if( not disc_timer_set_ )
00721           {
00722                disc_timer_set_ = 1;
00723                timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ , this, (void *) 0 );
00724           }
00725      }
00726 #ifdef HIGHWAY_METHOD_DEBUG
00727      debug().debug( "@@ %d METHOD ENDED: cluster_discovery()\n", radio().id() );
00728 #endif
00729 }
00730 
00731 // -----------------------------------------------------------------------
00732 
00733 template<typename OsModel_P,
00734          typename RoutingTable_P,
00735          typename Cluster_P,
00736          typename Neighbor_P,
00737          uint16_t MAX_CLUSTERS>
00738 void
00739 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00740 neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data)
00741 {
00742 #ifdef HIGHWAY_METHOD_DEBUG
00743      debug().debug("@@ %d METHOD CALLED: neighbor_callback()\n", radio().id());
00744 #endif
00745 
00746      memcpy( buffer_, data, len );
00747      
00748      node_id_t sid;
00749      uint8_t hops;
00750      
00751      // On payload event, process the data according to the plattform
00752      if ( nb_t::NEW_PAYLOAD_BIDI == event ) {
00753 #ifdef ISENSE_APP
00754           sid = ( buffer_[1] << 8 ) | buffer_[0];
00755           hops = buffer_[2];
00756 #else
00757           sid = ( buffer_[3] << 24 ) | ( buffer_[2] << 16 ) | ( buffer_[1] << 8 ) | buffer_[0];
00758           hops = buffer_[4];
00759 #endif
00760 
00761 #ifdef HIGHWAY_DEBUG
00762           debug().debug( "@@Node: %d, cluster_id: %d, hops: %d\n", from, sid, hops );
00763 #endif
00764           // If not cluster leader and the message is from another cluster add it to the highway table of the now to be port candidate.
00765           if ( !cluster().is_cluster_head() and cluster().cluster_id() != sid )
00766           {
00767                //debug().debug( "PQ[%d].first=%d(%d) from=%d(%d)", sid, ports_queue_[sid].first, ports_queue_[sid].second.first, from, hops );
00768                //Check if it is new and that it is better than the current one
00769                if( ports_queue_[sid].first.second != from && ( ( ports_queue_[sid].second.first == 0 ) || ( ports_queue_[sid].second.first > hops ) ) )
00770                {
00771                     ports_queue_[sid] = entry( source_target( radio().id(), from ), hops_ack( hops, 0 ));
00772                }
00773                else
00774                     return;
00775           }
00776           if( not disc_timer_set_ )
00777           {
00778                disc_timer_set_ = 1;
00779                timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ , this, (void *) 0 );
00780           }
00781      }
00782      else if ( nb_t::LOST_NB_BIDI == event )
00783      {
00784           //TODO: Work on fault tolerance here!
00785           // 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.
00786 #ifdef HIGHWAY_DEBUG
00787           debug().debug( "NODE %d: event LOST_NB_BIDI %d \n",radio().id(), from);
00788 #endif
00789      }
00790 #ifdef HIGHWAY_METHOD_DEBUG
00791      debug().debug("@@ %d METHOD ENDED: neighbor_callback()\n", radio().id());
00792 #endif
00793 }
00794 
00795 // -----------------------------------------------------------------------
00796 
00797 template<typename OsModel_P,
00798     typename RoutingTable_P,
00799     typename Cluster_P,
00800     typename Neighbor_P,
00801     uint16_t MAX_CLUSTERS>
00802 void
00803 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00804 discovery_timeout( void *userdata )
00805 {
00806 #ifdef HIGHWAY_METHOD_DEBUG
00807 debug().debug( "@@ %d METHOD CALLED: discovery_timeout()\n", radio().id());
00808 #endif
00809 if( disc_timer_set_ )
00810 {
00811      disc_timer_set_ = 0;
00812 }
00813 
00814 highway_iterator it;
00815 for ( it = ports_queue_.begin(); it != ports_queue_.end(); ++it )
00816 {
00817      //Check if the port candidate is already set as highway
00818      if(highway_table_[it->first].first.first == it->second.first.first and highway_table_[it->first].first.second == it->second.first.second )
00819           return;
00820      // Create a CANDIDACY highway message with: hops, port_source, port_target, cluster_id_own, cluster_id_target. 
00821      set_msg_highway( buffer_, CANDIDACY, it->second.second.first, radio().id(), it->second.first.second, cluster().cluster_id(), it->first );
00822         
00823      // Send it to the parent.
00824      radio().send( cluster().parent(), HWY_MSG_SIZE, buffer_ );
00825 #ifdef HWY_METRICS
00826      s_cand++;
00827 #endif
00828  }
00829 #ifdef HIGHWAY_METHOD_DEBUG
00830 debug().debug( "@@ %d METHOD ENDED: discovery_timeout()\n", radio().id() );
00831 #endif
00832 }
00833 
00834 // -----------------------------------------------------------------------
00835 
00836 template<typename OsModel_P,
00837     typename RoutingTable_P,
00838     typename Cluster_P,
00839     typename Neighbor_P,
00840     uint16_t MAX_CLUSTERS>
00841 void
00842 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00843 candidacies_timeout( void *userdata )
00844 {
00845 #ifdef HIGHWAY_METHOD_DEBUG
00846 debug().debug( "@@ %d METHOD STARTED: candidacies_timeout()\n", radio().id() );
00847 #endif
00848 if( cand_timer_set_ )
00849 {
00850      cand_timer_set_ = 0;
00851 }
00852 
00853 if ( !ports_queue_.empty() ) // If no candidacies were presented we will call the same method after a work period.
00854 { 
00855 #ifdef HIGHWAY_DEBUG
00856      debug().debug( "%d Cand_timeout leader with ports to start\n", radio().id() );
00857 #endif
00858      highway_iterator it;
00859      for ( it = ports_queue_.begin(); it != ports_queue_.end(); ++it )
00860      {
00861           // Check that it is not the same highway
00862           if( it->second.second.first == 0 || ( it->second.first.first == highway_table_[it->first].first.first && it->second.first.second == highway_table_[it->first].first.second ))
00863                continue;
00864           //Check that there's a current highway and that it is still working properly
00865           if( highway_table_[it->first].second.first == 0 || highway_table_[it->first].second.second > max_acks_ )
00866           {
00867 #ifdef HIGHWAY_DEBUG
00868                debug().debug( "%d Sent port request to %d through %d\n", radio().id(), it->first, routing_table_[it->second.first.first] );
00869 #endif
00870                // Create a CANDIDACY highway message with: hops, port_source, port_target, cluster_id_own, cluster_id_target.
00871                set_msg_highway( buffer_, PORT_REQ, it->second.second.first, it->second.first.first, it->second.first.second, cluster().cluster_id(), it->first );
00872                radio().send( routing_table_[it->second.first.first], HWY_MSG_SIZE, buffer_ );
00873 #ifdef HWY_METRICS
00874                s_req++;
00875 #endif
00876           }
00877      }
00878           
00879      //After processing all the ports, we flush the queue.
00880      //IMPROVE: Check if it isn't better to save an extra port for when the ACKs are not arriving.
00881      ports_queue_.clear();
00882 }
00883 #ifdef HIGHWAY_METHOD_DEBUG
00884      debug().debug( "@@ %d METHOD ENDED: candidacies_timeout()\n", radio().id() );
00885 #endif
00886 }
00887 
00888 // -----------------------------------------------------------------------
00889 
00890 template<typename OsModel_P,
00891          typename RoutingTable_P,
00892          typename Cluster_P,
00893          typename Neighbor_P,
00894          uint16_t MAX_CLUSTERS>
00895 void
00896 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00897 receive( node_id_t from, size_t len, block_data_t *data )
00898 {
00899 #ifdef HIGHWAY_METHOD_DEBUG
00900 //     debug().debug("@@ %d METHOD_CALLED: receive()\n", radio().id());
00901 #endif
00902      
00903      // Ignore if heard oneself's message.
00904      if ( from == radio().id() )
00905      {
00906           return;
00907      }
00908      memcpy( &buffer_, data, len);
00909           
00910 #ifdef HIGHWAY_MSG_RECV_DEBUG
00911      if ( buffer_[0] == CANDIDACY ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: CANDIDACY\n", radio().id(), from );
00912      else if ( buffer_[0] == PORT_REQ ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_REQ\n", radio().id(), from );
00913      else if ( buffer_[0] == PORT_REQ2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_REQ2\n", radio().id(), from );
00914      else if ( buffer_[0] == PORT_ACK ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_ACK\n", radio().id(), from );
00915      else if ( buffer_[0] == PORT_ACK2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_ACK2\n", radio().id(), from );
00916      else if ( buffer_[0] == PORT_NACK ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_NACK\n", radio().id(), from );
00917      else if ( buffer_[0] == PORT_NACK2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_NACK2\n", radio().id(), from );
00918      else if ( buffer_[0] == SEND ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: SEND\n", radio().id(), from );
00919      else if ( buffer_[0] == SEND2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: SEND2\n", radio().id(), from );
00920 #endif
00921 
00922 #ifdef CTI_VISOR
00923      if ( buffer_[0] == CANDIDACY ) debug().debug( "HWY_MSG; CAND; %d; %d", radio().id(), from );
00924      else if ( buffer_[0] == PORT_REQ  or buffer_[0] == PORT_REQ2 ) debug().debug( "HWY_MSG; REQ; %d; %d", radio().id(), from );
00925      else if ( buffer_[0] == PORT_ACK  or buffer_[0] == PORT_ACK2 ) debug().debug( "HWY_MSG; PACK; %d; %d", radio().id(), from );
00926      else if ( buffer_[0] == PORT_NACK  or buffer_[0] == PORT_NACK2 ) debug().debug( "HWY_MSG; PNACK; %d; %d", radio().id(), from );
00927      else if ( buffer_[0] == SEND  or buffer_[0] == SEND2 ) debug().debug( "HWY_MSG; SEND; %d; %d", radio().id(), from );
00928      else if ( buffer_[0] == ACK  or buffer_[0] == ACK2 ) debug().debug( "HWY_MSG; ACK; %d; %d", radio().id(), from );
00929 #endif
00930 
00931 #ifdef HWY_METRICS 
00932      if ( buffer_[0] == CANDIDACY ) r_cand++;
00933      else if ( buffer_[0] == PORT_REQ ) r_req++;
00934      else if ( buffer_[0] == PORT_REQ2 ) r_req2++;
00935      else if ( buffer_[0] == PORT_ACK ) r_pack++;
00936      else if ( buffer_[0] == PORT_ACK2 ) r_pack2++;
00937      else if ( buffer_[0] == PORT_NACK ) r_pnack++;
00938      else if ( buffer_[0] == PORT_NACK2 ) r_pnack2++;
00939      else if ( buffer_[0] == SEND ) r_send++;
00940      else if ( buffer_[0] == SEND2 ) r_send2++;
00941      else if ( buffer_[0] == ACK ) r_ack++;
00942      else if ( buffer_[0] == ACK2 ) r_ack2++;
00943 #endif
00944 
00945 
00946      // Messages travelling to the current node cluster leader are processed in send_to_leader
00947      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 )
00948      {
00949           send_to_leader( from, len, buffer_ );
00950      }
00951      else if ( buffer_[0] == PORT_REQ or buffer_[0] == PORT_ACK or buffer_[0] == PORT_NACK ) // Construction messages travelling outwards
00952      {
00953           send_away( from, len, buffer_ );
00954      }
00955      else if ( buffer_[0] == SEND or buffer_[0] == ACK ) // Data messages travelling outwards.
00956      {
00957           process_send( from, len, buffer_ );
00958      }
00959 }
00960 
00961 // -----------------------------------------------------------------------
00962 
00963 template<typename OsModel_P,
00964          typename RoutingTable_P,
00965          typename Cluster_P,
00966          typename Neighbor_P,
00967          uint16_t MAX_CLUSTERS>
00968 void
00969 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00970 send_to_leader( node_id_t from, size_t len, block_data_t *data )
00971 {
00972 #ifdef HIGHWAY_METHOD_DEBUG
00973      debug().debug( "@@ %d METHOD_CALLED: send_to_leader()\n", radio().id()) ;
00974 #endif
00975      uint8_t type = data[0];
00976 
00977 #ifdef HIGHWAY_MSG_RECV_DEBUG
00978      if( type == SEND2 )
00979      {
00980           debug().debug( "---------------SENDRECV2--------------\n" );
00981           for( int i = 0; i<len; ++i )
00982                debug().debug( "Data[%d]: %d\n", i, data[i] );
00983           debug().debug( "---------------/SENDRECV2--------------\n" );    
00984      }
00985 #endif
00986 
00987      get_msg_highway( &msg_highway_, data );
00988      
00989      if( type == CANDIDACY )
00990      {
00991           routing_table_[msg_highway_.source] = from;
00992      }
00993      else if( type == PORT_REQ2 )
00994      {
00995           routing_table_[msg_highway_.target] = from;
00996      }
00997      else if( type == PORT_ACK2 )
00998      {
00999           // Improve: put it on the highway_table for fault tolerance
01000 #ifdef VISOR_DEBUG
01001           debug().debug( "$%d->%d$h\n", from, radio_->id() );
01002 #endif
01003 #ifdef CTI_VISOR
01004           debug().debug( "HWY_EDGE; %d; %d", from, radio_->id() );
01005 #endif
01006      }
01007      
01008      if( cluster().is_cluster_head() )
01009      {
01010           cluster_head_work( from, len, data );
01011      }
01012      else
01013      {
01014           radio().send( cluster().parent(), len, data );
01015      }
01016 #ifdef HIGHWAY_METHOD_DEBUG
01017      debug().debug( "@@ %d METHOD_ENDED: send_to_leader()\n", radio().id()) ;
01018 #endif
01019 }
01020 
01021 // -----------------------------------------------------------------------
01022 
01023 template<typename OsModel_P,
01024          typename RoutingTable_P,
01025          typename Cluster_P,
01026          typename Neighbor_P,
01027          uint16_t MAX_CLUSTERS>
01028 void
01029 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01030 send_away( node_id_t from, size_t len, block_data_t *data )
01031 {
01032 #ifdef HIGHWAY_METHOD_DEBUG
01033      debug().debug("@@ %d METHOD_CALLED: send_away()\n", radio().id());
01034 #endif
01035 
01036 #ifdef VISOR_DEBUG
01037      if( *data == PORT_ACK )
01038           debug().debug("$%d->%d$h\n", from, radio_->id());
01039 #endif
01040 #ifdef CTI_VISOR
01041      debug().debug( "HWY_EDGE; %d; %d", from, radio_->id());
01042 #endif
01043 
01044      //msg_highway_ = * ((msg_highway * ) data);
01045      get_msg_highway( &msg_highway_, data );
01046      
01047      // Check if we are still in the cluster that originated the request.
01048      if ( from == cluster().parent() )
01049      {
01050           // If the current node is not the port, continue the way to the port.
01051           if ( msg_highway_.msg_id == PORT_REQ && msg_highway_.source != radio().id() )
01052           {
01053                radio().send( routing_table_[msg_highway_.source], HWY_MSG_SIZE, data );
01054 #ifdef HIGHWAY_DEBUG
01055                debug().debug( "Still same cluster, not yet port, sending PORT_REQ through %d", msg_highway_.source );
01056 #endif
01057           }
01058           else if ( msg_highway_.msg_id == PORT_ACK && msg_highway_.target != radio().id() )
01059           {
01060                radio().send( routing_table_[msg_highway_.target], HWY_MSG_SIZE, data );
01061 #ifdef HIGHWAY_DEBUG
01062                debug().debug( "Still same cluster, not yet port, sending PORT_REQ through %d", msg_highway_.target );
01063 #endif
01064           }
01065           else // It is the port. Send the message to the other cluster port and set the port to highway status(if needed).
01066           {
01067                if ( msg_highway_.msg_id == PORT_REQ )
01068                {
01069                     radio().send( msg_highway_.target, HWY_MSG_SIZE, data );
01070 #ifdef HIGHWAY_DEBUG
01071                     debug().debug( "Still same cluster, already port, passing request to %d", msg_highway_.target );
01072 #endif
01073 #ifdef HWY_METRICS
01074                     s_req++;
01075 #endif
01076                }
01077                else if ( msg_highway_.msg_id == PORT_ACK ) {
01078 #ifdef HIGHWAY_DEBUG
01079                     debug().debug( "Still same cluster, already port, passing pack to %d", msg_highway_.target );
01080 #endif
01081                     highway_table_[msg_highway_.sid_source] = entry( source_target( msg_highway_.target, msg_highway_.source ), hops_ack( msg_highway_.hops, 0 ) );
01082                     radio().send( msg_highway_.source, HWY_MSG_SIZE, data );
01083 #ifdef HWY_METRICS
01084                     s_pack++;
01085 #endif
01086                }
01087                else //NACK
01088                {
01089 #ifdef HIGHWAY_DEBUG
01090                     debug().debug( "Still same cluster, already port, passing pnack to %d", msg_highway_.target );
01091 #endif
01092                     radio().send( msg_highway_.source, HWY_MSG_SIZE, data );
01093 #ifdef HWY_METRICS
01094                     s_pnack++;
01095 #endif
01096                }                    
01097           }
01098      }
01099      else // Create a "2" message.
01100      {
01101 #ifdef HIGHWAY_DEBUG
01102           debug().debug( "Passed to new cluster cluster" );
01103 #endif
01104           if ( msg_highway_.msg_id == PORT_REQ )
01105           {
01106 #ifdef HIGHWAY_DEBUG
01107                debug().debug( "^^%d transforming to PORT_REQ2 and sending to %d", cluster().is_cluster_head(), cluster().parent() );
01108 #endif
01109                msg_highway_.msg_id = PORT_REQ2;
01110 #ifdef HWY_METRICS
01111                s_req2++;
01112 #endif
01113           }
01114           else if ( msg_highway_.msg_id == PORT_ACK ) {
01115 #ifdef VISOR_DEBUG
01116                debug().debug( "+%d#%d#%d#1\n", radio().id(), cluster().cluster_id(), cluster().is_cluster_head() );
01117                debug().debug( "+%d#%d#%d#1\n", from, msg_highway_.sid_target, cluster().is_cluster_head() );
01118 #endif
01119 #ifdef CTI_VISOR
01120                debug().debug( "HWY_PORTS; %d; %d", radio().id(), from );
01121 #endif
01122                msg_highway_.msg_id = PORT_ACK2;
01123                highway_table_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, from ), hops_ack( msg_highway_.hops, 0 ) );
01124 #ifdef HWY_METRICS
01125                s_pack2++;
01126 #endif
01127                     
01128           }
01129           else //NACK
01130           {
01131                msg_highway_.msg_id = PORT_NACK2;
01132 #ifdef HWY_METRICS
01133                s_pnack2++;
01134 #endif
01135           }
01136           
01137           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 );
01138           radio().send( cluster().parent(), HWY_MSG_SIZE, buffer_ );
01139      }
01140 #ifdef HIGHWAY_METHOD_DEBUG
01141      debug().debug("@@ %d 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 #ifdef HIGHWAY_METHOD_DEBUG
01157      debug().debug("@@ %d METHOD_CALLED: send_process()\n", radio().id());
01158 #endif
01159      node_id_t port, destination;
01160 
01161 #ifdef HIGHWAY_MSG_RECV_DEBUG
01162      debug().debug("---------------SENDRECV--------------\n");
01163      for(int i = 0; i<len; ++i)
01164           debug().debug("Data[%d]: %d\n", i, data[i]);
01165      debug().debug("---------------/SENDRECV--------------\n");
01166 #endif
01167 
01168      // Check if we are still in the cluster that originated the request.
01169      if ( from == cluster().parent() )
01170      {
01171           // If the current node is not the port, continue the way to the port.
01172 #ifdef ISENSE_APP
01173           port = ( data[4] << 8 ) | data[3];
01174           destination = ( data[2] << 8 ) | data[1];
01175 #else
01176           port = ( data[8] << 24 ) | ( data[7] << 16 ) | ( data[6] << 8 ) | data[5];
01177           destination = ( data[4] << 24 ) | ( data[3] << 16 ) | ( data[2] << 8 ) | data[1];
01178 #endif
01179 
01180           if ( port != radio().id() )
01181           {
01182                radio().send( routing_table_[port], len, data );
01183           }
01184           else // Send the message to the other cluster port.
01185           {
01186                radio().send( highway_table_[destination].first.second, len, data );
01187 #ifdef HWY_METRICS
01188                     s_send++;
01189 #endif
01190           }
01191      }
01192      else // Create a "2" message.
01193      {
01194           if(*data == SEND)
01195           {
01196                *data = SEND2;
01197 #ifdef HWY_METRICS
01198                     s_send2++;
01199 #endif
01200           }
01201           else
01202           {
01203                *data = ACK2;
01204 #ifdef HWY_METRICS
01205                s_ack2++;
01206 #endif
01207           }
01208           radio().send( cluster().parent(), len, data );
01209      }
01210 #ifdef HIGHWAY_METHOD_DEBUG
01211      debug().debug("@@ %d METHOD_ENDED: send_process()\n", radio().id());
01212 #endif
01213 }
01214 
01215 // -----------------------------------------------------------------------
01216 
01217 template<typename OsModel_P,
01218          typename RoutingTable_P,
01219          typename Cluster_P,
01220          typename Neighbor_P,
01221          uint16_t MAX_CLUSTERS>
01222 void
01223 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01224 cluster_head_work( node_id_t from, size_t len, block_data_t *data )
01225 {
01226 #ifdef HIGHWAY_METHOD_DEBUG
01227      debug().debug("@@ %d METHOD_CALLED: cluster_head_work()\n", radio().id() );
01228 #endif
01229      node_id_t sender;
01230      
01231      get_msg_highway( &msg_highway_, data );
01232      
01233      if ( msg_highway_.msg_id == CANDIDACY ) // Add the port candidate to the queue.
01234      {
01235 #ifdef HIGHWAY_DEBUG
01236           debug().debug( "Putting an entry to ports_queue on %d\n", radio().id() );
01237 #endif
01238           // Check that the port candidate is better than the stored candidate
01239           if( ( ports_queue_[msg_highway_.sid_target].first.first != msg_highway_.source || ports_queue_[msg_highway_.sid_target].first.second != msg_highway_.target ) && ( ( ports_queue_[msg_highway_.sid_target].second.first == 0 ) || ( ports_queue_[msg_highway_.sid_target].second.first > msg_highway_.hops ) ) )
01240           {
01241                ports_queue_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, msg_highway_.target ), hops_ack( msg_highway_.hops, 0 ));
01242                if( not cand_timer_set_ )
01243                {
01244                     cand_timer_set_ = 1;
01245                     timer().template set_timer<self_type, &self_type::candidacies_timeout>( discovery_time_ , this, (void *) 0 );
01246                }
01247           }
01248      }
01249      else if ( msg_highway_.msg_id == PORT_REQ2 ) // Accept or reject the highway request.
01250      {
01251           // iff there is no highway set or the ack of the current one are too high accept
01252           if( highway_table_[msg_highway_.sid_source].second.first == 0 || highway_table_[msg_highway_.sid_source].second.second > max_acks_ )
01253           {
01254                highway_table_[msg_highway_.sid_source] = entry( source_target( msg_highway_.target, msg_highway_.source ), hops_ack( msg_highway_.hops, 0 ) );
01255                msg_highway_.msg_id = PORT_ACK;
01256 #ifdef HWY_METRICS               
01257                n_hwy++;
01258                s_pack++;
01259 #endif
01260           }
01261           else
01262           {
01263                msg_highway_.msg_id = PORT_NACK;
01264 #ifdef HWY_METRICS               
01265                s_pack++;
01266 #endif
01267           }
01268           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 );
01269           radio().send( from, HWY_MSG_SIZE, buffer_ );
01270      }
01271      else if ( msg_highway_.msg_id == PORT_ACK2 ) // Establish the port.
01272      {
01273           highway_table_[msg_highway_.sid_target] = entry( source_target( msg_highway_.source, msg_highway_.target ), hops_ack( msg_highway_.hops, 0 ) );
01274 #ifdef HWY_METRICS               
01275           n_hwy += 1;
01276 #endif
01277      }
01278      else if ( msg_highway_.msg_id == PORT_NACK2 ) // Remove the port candidate.
01279      {
01280           //IMPROVE: Check if it is worth it to start a new negotiation if there's a new port in the queue
01281           /*if( ports_queue_[msg_highway_.sid_target].first.first != msg_highway_.source || ports_queue_[msg_highway_.sid_target].first.second != msg_highway_.target )
01282           {
01283                if( ports_queue_[msg_highway_.sid_target].second.first != 0 && highway_table_[it->first].second.second > max_acks_ )
01284                {
01285                     set_msg_highway( buffer_, PORT_REQ, ports_queue_[msg_highway_.sid_target].second.first, ports_queue_[msg_highway_.sid_target].first.first, ports_queue_[msg_highway_.sid_target].first.second, cluster().cluster_id(), msg_highway_sid_target );
01286                     radio().send( routing_table_[ports_queue_[msg_highway_.sid_target].first.first], HWY_MSG_SIZE, buffer_ );
01287                }
01288                ports_queue_.erase( it->first );
01289           }*/
01290           // Try to renegotiate
01291           candidacies_timeout( (void *) 0 );
01292      }
01293      else
01294      {
01295           if ( *data == SEND2 ) // Send the msg_ack andi call the registered (if exists) receiving method.
01296           {
01297 #ifdef ISENSE_APP
01298                sender = (data[6] << 8) | data[5];
01299 #else
01300                sender = ( data[12] << 24 ) | ( data[11] << 16 ) | ( data[10] << 8 ) | data[9];
01301 #endif
01302 #ifdef HIGHWAY_MSG_RECV_DEBUG
01303                debug().debug( "---------------HEAD_WORK_RECV--------------\n" );
01304                for( int i = 0; i<len; ++i )
01305                     debug().debug( "Data[%d]: %d\n", i, data[i] );
01306                debug().debug( "---------------HEAD_WORK_RECV--------------\n" );    
01307 #endif
01308                send( false, sender, 0, data );
01309                if( hwy_recv_callback_  ) hwy_recv_callback_(sender, len-SEND_OVERHEAD, &data[SEND_OVERHEAD]);
01310           }
01311           else if ( *data == ACK2 ) //Count the received ACKs from the highway
01312           {
01313                highway_table_[sender].second.second -= 1;
01314           }
01315      }
01316 #ifdef HIGHWAY_METHOD_DEBUG
01317      debug().debug("@@ %d METHOD_ENDED: cluster_head_work()\n", radio().id() );
01318 #endif
01319 }
01320 
01321 // -----------------------------------------------------------------------
01322 
01323 template<typename OsModel_P,
01324          typename RoutingTable_P,
01325          typename Cluster_P,
01326          typename Neighbor_P,
01327          uint16_t MAX_CLUSTERS>
01328 void
01329 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01330 send( bool send_ack, node_id_t destination, size_t len, block_data_t *data )
01331 {
01332 #ifdef HIGHWAY_METHOD_DEBUG
01333      debug().debug( "@@ %d METHOD CALLED: send()\n", radio().id() );
01334 #endif
01335 
01336      node_id_t port = highway_table_[destination].first.first;
01337      if(send_ack)
01338      {
01339          buffer_[0] = SEND;
01340          highway_table_[destination].second.second += 1;
01341 #ifdef HWY_METRICS               
01342           s_send++;
01343 #endif
01344      }
01345      else
01346      {
01347          buffer_[0] = ACK;
01348 #ifdef HWY_METRICS               
01349           s_ack++;
01350 #endif
01351      }
01352 #ifdef ISENSE_APP
01353      buffer_[1] = destination & 0xFF;
01354      buffer_[2] = ( destination >> 8 ) & 0xFF;
01355      buffer_[3] = port & 0xFF;
01356      buffer_[4] = ( port >> 8 ) & 0xFF;
01357      buffer_[5] = radio().id() & 0xFF;
01358      buffer_[6] = ( radio().id() >> 8 ) & 0xFF;
01359 #else
01360      buffer_[1] = destination & 0xFF;
01361      buffer_[2] = ( destination >> 8 ) & 0xFF;
01362      buffer_[3] = ( destination >> 16 ) & 0xFF;
01363      buffer_[4] = ( destination >> 24 ) & 0xFF;
01364      buffer_[5] = port & 0xFF;
01365      buffer_[6] = ( port >> 8 ) & 0xFF;
01366      buffer_[7] = ( port >> 16 ) & 0xFF;
01367      buffer_[8] = ( port >> 24 ) & 0xFF;
01368      buffer_[9] = radio().id() & 0xFF;
01369      buffer_[10] = ( radio().id() >> 8 ) & 0xFF;
01370      buffer_[11] = ( radio().id() >> 16 ) & 0xFF;
01371      buffer_[12] = ( radio().id() >> 24 ) & 0xFF;
01372 #endif
01373      
01374 #ifdef HIGHWAY_MSG_RECV_DEBUG
01375      debug().debug( "---------------ENCAPSULATING----------------\n" );
01376 #endif
01377 
01378      for (int i = SEND_OVERHEAD; i < ( len+SEND_OVERHEAD ); ++i)
01379      {
01380           buffer_[i] = data[i-SEND_OVERHEAD];
01381 #ifdef HIGHWAY_MSG_RECV_DEBUG
01382           debug().debug( "Data item %d: %d\n", i-SEND_OVERHEAD, data[i-SEND_OVERHEAD] );
01383 #endif          
01384      }
01385 
01386 
01387 #ifdef HIGHWAY_MSG_RECV_DEBUG
01388      for (int i = 0; i < len+SEND_OVERHEAD; ++i)
01389      {
01390           debug().debug( "Buffer item %d: %d\n", i, buffer_[i] );
01391      }
01392 #endif
01393 
01394 #ifdef HIGHWAY_MSG_RECV_DEBUG
01395      debug().debug( "---------------/ENCAPSULATING----------------\n" );
01396 #endif
01397 
01398      radio().send( routing_table_[port], len+SEND_OVERHEAD, buffer_ );
01399 #ifdef HIGHWAY_METHOD_DEBUG
01400      debug().debug( "@@ %d METHOD ENDED: send()\n", radio().id() );
01401 #endif
01402 }
01403 
01404 
01405 // -----------------------------------------------------------------------
01406 // Helper methods.                                                       |
01407 // -----------------------------------------------------------------------
01408 
01409 #ifdef HWY_METRICS
01410 template<typename OsModel_P,
01411          typename RoutingTable_P,
01412          typename Cluster_P,
01413          typename Neighbor_P,
01414          uint16_t MAX_CLUSTERS>
01415 void         
01416 HighwayCluster<OsModel_P, RoutingTable_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01417 graph_print( void * userdata )
01418 {
01419 #ifdef HIGHWAY_METHOD_DEBUG
01420      debug().debug( "@@ %d METHOD_CALLED: graph_print()\n", radio().id() );
01421 #endif
01422      timer().template set_timer<self_type, &self_type::graph_print>( (millis_t)1000 , this, (void *) 0 );
01423      time++;
01424      if(cluster().is_cluster_head())
01425           debug().debug( "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", time, n_hwy, r_cand, r_req, r_req2, r_pack, r_pack2, r_pnack, r_pnack2, r_send, r_send2, r_ack, r_ack2, s_cand, s_req, s_req2, s_pack, s_pack2, s_pnack, s_pnack2, s_send, s_send2, s_ack, s_ack2 );
01426 #ifdef HIGHWAY_METHOD_DEBUG
01427      debug().debug( "@@ %d METHOD_ENDED: graph_print()\n", radio().id() );
01428 #endif
01429 }
01430 #endif
01431 
01432 }
01433 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines