Wiselib
wiselib.testing/algorithms/cluster/highway/highway_refactor.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  ** This file is part of the generic algorithm library Wiselib.           **
00003  ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project.      **
00004  **                                                                       **
00005  ** The Wiselib is free software: you can redistribute it and/or modify   **
00006  ** it under the terms of the GNU Lesser General Public License as        **
00007  ** published by the Free Software Foundation, either version 3 of the    **
00008  ** License, or (at your option) any later version.                       **
00009  **                                                                       **
00010  ** The Wiselib is distributed in the hope that it will be useful,        **
00011  ** but WITHOUT ANY WARRANTY; without even the implied warranty of        **
00012  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         **
00013  ** GNU Lesser General Public License for more details.                   **
00014  **                                                                       **
00015  ** You should have received a copy of the GNU Lesser General Public      **
00016  ** License along with the Wiselib.                                       **
00017  ** If not, see <http://www.gnu.org/licenses/>.                           **
00018  ***************************************************************************/
00019  
00020 #ifndef __ALGORITHMS_CLUSTER_HIGHWAY_CLUSTER_H__
00021 #define __ALGORITHMS_CLUSTER_HIGHWAY_CLUSTER_H__
00022 
00023 
00024 #include "algorithms/neighbor_discovery/echo.h"
00025 #include "algorithms/cluster/bfscluster/bfsclustering.h"
00026 #include "algorithms/cluster/clustering_types.h"
00027 #include "util/pstl/vector_static.h"
00028 #include "util/pstl/priority_queue.h"
00029 #include "util/pstl/pair.h"
00030 #include "util/pstl/map_static_vector.h"
00031 #include "internal_interface/routing_table/routing_table_static_array.h"
00032 #include "util/delegates/delegate.hpp"
00033 
00034 
00035 // Levels of debug info:
00036 //   HIGHWAY_METHOD_DEBUG: Adds a Method called notice at the beginning of each
00037 //   method.
00038 //   HIGHWAY_MSG_RECV_DEBUG: Adds all sorts of debug messages for the tracking 
00039 //   of sending messages at Highway level.
00040 //   VISOR_DEBUG: Adds debug messages that can be processed by the Python visor
00041 //   application to generate a picture of the final status of the WSN.
00042 //   HIGHWAY_DEBUG: Most general debug messages.
00043 
00044 #define HIGHWAY_DEBUG
00045 //#define HIGHWAY_METHOD_DEBUG
00046 #define HIGHWAY_MSG_RECV_DEBUG
00047 #define VISOR_DEBUG
00048 
00049 namespace wiselib{
00050 template<typename OsModel_P,
00051          typename RoutingTable_P,
00052          typename Radio_P = typename OsModel_P::Radio,
00053          typename Timer_P = typename OsModel_P::Timer,
00054          typename Clock_P = typename OsModel_P::Clock,
00055          typename Debug_P = typename OsModel_P::Debug,
00056          typename Cluster_P = typename wiselib::BfsClustering<OsModel_P, Radio_P, Timer_P, Debug_P>,
00057          typename Neighbor_P = typename wiselib::Echo<OsModel_P, Radio_P, Timer_P, Debug_P>,
00058          uint16_t MAX_CLUSTERS = 8>
00059 class HighwayCluster
00060 {
00061 public:
00062      // Type definitions.
00063      // Type definition of the used Templates.
00064      typedef OsModel_P OsModel;
00065      typedef RoutingTable_P RoutingTable;
00066      typedef Radio_P Radio;
00067      typedef Timer_P Timer;
00068      typedef Clock_P Clock;
00069      typedef Debug_P Debug;
00070      typedef Cluster_P Cluster;
00071      typedef Neighbor_P Neighbor;
00072 
00073      typedef HighwayCluster<OsModel, RoutingTable, Radio, Timer,Clock, Debug, Cluster, Neighbor, MAX_CLUSTERS> self_type;
00074      typedef wiselib::Echo<OsModel, Radio, Timer, Debug> nb_t;
00075      typedef self_type* self_pointer_t;
00076 
00077      // Basic types definition.
00078      typedef typename Radio::node_id_t node_id_t;
00079      typedef typename Radio::size_t size_t;
00080      typedef typename Radio::block_data_t block_data_t;
00081      typedef typename Timer::millis_t millis_t;
00082      
00083      // Type definition for the receive callback.
00084      typedef delegate3<void, node_id_t, size_t, block_data_t*> highway_delegate_t;
00085      
00086      enum Sizes {
00087           MAX_CLUSTER_PORTS = 4
00088      };
00089 
00090      // Type definition for the special data structures of the highway.
00091      typedef wiselib::pair<int16_t, node_id_t> Hops_Node_id;
00092      typedef wiselib::priority_queue<OsModel, Hops_Node_id, MAX_CLUSTER_PORTS> PQ;
00093      typedef wiselib::pair<PQ, int16_t> PQ_Ack;
00094      typedef wiselib::MapStaticVector<OsModel, node_id_t, PQ_Ack, MAX_CLUSTERS> HighwayTable;
00095      typedef wiselib::MapStaticVector<OsModel, node_id_t, PQ_Ack, MAX_CLUSTERS> PortsQueue;
00096      typedef wiselib::vector_static<OsModel, node_id_t, MAX_CLUSTERS> Node_vect;
00097      typedef wiselib::vector_static<OsModel, Hops_Node_id, MAX_CLUSTER_PORTS> Ports_vect;
00098      
00099      // Type definition for the special types iterators.
00100      typedef typename HighwayTable::iterator highway_iterator;
00101      typedef typename PQ::pointer pq_iterator;
00102 
00103      // Return types definition.
00104      enum ErrorCodes {
00105           SUCCESS = OsModel::SUCCESS,
00106           ERR_UNSPEC = OsModel::ERR_UNSPEC
00107      };
00108      
00109      // TODO: Move into a highway message class.
00110      enum msg_id {
00111           CANDIDACY = 100,
00112           PORT_REQ = 101,
00113           PORT_REQ2 = 102,
00114           PORT_ACK = 103,
00115           PORT_ACK2 = 104,
00116           PORT_NACK = 105,
00117           PORT_NACK2 = 106,
00118           SEND = 107,
00119           SEND2 = 108
00120      };
00121      
00122      // --------------------------------------------------------------------
00123      // Public method declaration.                                         |
00124      // --------------------------------------------------------------------
00125      
00128      HighwayCluster():
00129      radio_ ( 0 ),
00130      timer_ ( 0 ),
00131      debug_ ( 0 ),
00132      cluster_ ( 0 ),
00133      discovery_time_ ( 20000 ),
00134      work_period_ ( 50000 ),
00135      clustering_construction_time_ ( 5000 ),
00136      head_offset_ ( 0 )
00137      {
00138 #ifdef HIGHWAY_METHOD_DEBUG
00139           debug().debug("@@ %d: METHOD CALLED: HighwayCluster()\n", radio().id());
00140 #endif
00141      };
00142      
00145      ~HighwayCluster();
00146      
00147      
00151      int init( Radio& radio, Timer& timer, Clock& clock, Debug& debug, Cluster& cluster, Neighbor& neighbor );
00152      
00156      void enable( void );
00157 
00164      void send( node_id_t receiver, size_t len, block_data_t *data );
00165      
00173      void send( node_id_t receiver, node_id_t port, size_t len, block_data_t *data );
00174      
00179      Node_vect cluster_neighbors();
00180      
00185      Ports_vect ports(node_id_t sid);
00186      
00190      template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)>
00191      uint8_t hwy_reg_recv_callback(T *obj_pnt) {
00192           hwy_recv_callback_ = highway_delegate_t::template from_method<T, TMethod > ( obj_pnt );
00193           return 0;
00194      }
00195      
00198      void unreg_hwy_recv_callback() {
00199           hwy_recv_callback_ = highway_delegate_t();
00200      }
00201      
00202      // --------------------------------------------------------------------
00203      // Setters                                                            |
00204      // --------------------------------------------------------------------
00205      
00209      inline void set_discovery_time( millis_t t ) {
00210           discovery_time_ = t;
00211      };
00212      
00216      inline void set_work_period( millis_t t ) {
00217           work_period_ = t;
00218      };
00219      
00223      inline void set_cluster_construction_time( millis_t t ) {
00224           clustering_construction_time_ = t;
00225      };
00226      
00230      inline void set_head_offset( millis_t t ) {
00231           head_offset_ = t;
00232      };
00233      
00234 private:
00235      // Typenaming the underlying modules.
00236      typename Radio::self_pointer_t radio_;
00237      typename Timer::self_pointer_t timer_;
00238      typename Clock::self_pointer_t clock_;
00239      typename Debug::self_pointer_t debug_;
00240      typename Cluster::self_pointer_t cluster_;
00241      typename Neighbor::self_t* neighbor_;
00242      
00243      // TODO: Move into the highway_msg class.
00244      struct msg_highway {
00245           uint8_t msg_id, hops;
00246           node_id_t candidate_id, sid_source, sid_target;
00247      };
00248      
00249      inline void set_msg_highway(uint8_t msg_id, uint8_t hops, node_id_t candidate_id, node_id_t sid_source, node_id_t sid_target) {
00250           msg_highway_.msg_id = msg_id;
00251           msg_highway_.hops = hops;
00252           msg_highway_.candidate_id = candidate_id;
00253           msg_highway_.sid_source = sid_source;
00254           msg_highway_.sid_target = sid_target;
00255      }
00256      // End of highway_msg TODO.
00257      
00258      
00259      // --------------------------------------------------------------------
00260      // Private variables declaration.                                        |
00261      // --------------------------------------------------------------------
00262      
00263      //TODO: Change into highway_msg class
00264      msg_highway msg_highway_;
00265      
00267      millis_t discovery_time_;
00268      
00269      // TODO: Fault tolerance and rebuilding should make this deprecated.
00271      millis_t work_period_;
00272      
00274      millis_t clustering_construction_time_;
00275      
00277      millis_t head_offset_;
00278 
00280      int clustering_callback_;
00281 
00283      highway_delegate_t hwy_recv_callback_;
00284      
00286      node_id_t connected_to;
00287      
00289      RoutingTable routing_table_;
00290      
00292      HighwayTable highway_table_;
00293      
00295      PortsQueue ports_queue_;
00296      
00297      //TODO: Check if this three can be moved inside their respective methods.
00299      vector_static<OsModel, Hops_Node_id, MAX_CLUSTER_PORTS -1 > aux;
00300      
00302      Node_vect neighbors_;
00303      
00305      Ports_vect ports_;
00306      
00308      block_data_t buffer_[Radio::MAX_MESSAGE_LENGTH];
00309      
00310      // --------------------------------------------------------------------
00311      // Private method declaration.                                        |
00312      // --------------------------------------------------------------------
00313      
00317      Radio& radio() {
00318           return *radio_;
00319      }
00320      
00324      Timer& timer() {
00325           return *timer_;
00326      }
00327      
00331      Clock& clock() {
00332           return *clock_;
00333      }
00334      
00338      Debug& debug() {
00339           return *debug_;
00340      }
00341      
00345      Cluster& cluster() {
00346           return *cluster_;
00347      }
00348      
00352      Neighbor& neighbor() {
00353           return *neighbor_;
00354      }
00355      
00360      void start_wrapper(int state);
00361      
00365      void start( void *userdata );
00366 
00370      void cluster_discovery( void );
00371 
00379      void neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data);
00380      
00386      void discovery_timeout( void *userdata );
00387      
00393      void start_port_negotiation( highway_iterator it, uint8_t n );
00394      
00400      void port_negotiation( node_id_t sid, node_id_t candidate );
00401      
00408      void receive( node_id_t from, size_t len, block_data_t *data );
00409      
00416      void send_to_leader( node_id_t from, size_t len, block_data_t *data );
00417      
00424      void send_away( node_id_t from, size_t len, block_data_t *data );
00425      
00432      void process_send( node_id_t from, size_t len, block_data_t *data );
00433      
00440      void cluster_head_work( node_id_t from, size_t len, block_data_t *data );
00441      
00447      void displacing_push(PQ& pq, Hops_Node_id pin);
00448      
00454      Hops_Node_id pop_port(PQ& pq, node_id_t port);
00455      
00456      
00457 }; // End of class.
00458 
00459 // --------------------------------------------------------------------
00460 // Start of the method code.                                          |
00461 // --------------------------------------------------------------------
00462 template<typename OsModel_P,
00463          typename RoutingTable_P,
00464          typename Radio_P,
00465          typename Timer_P,
00466          typename Clock_P,
00467          typename Debug_P,
00468          typename Cluster_P,
00469          typename Neighbor_P,
00470          uint16_t MAX_CLUSTERS>
00471 inline int
00472 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00473 init( Radio& radio, Timer& timer, Clock& clock, Debug& debug, Cluster& cluster, Neighbor& neighbor ) {
00474      radio_ = &radio;
00475      timer_ = &timer;
00476      clock_ = &clock;
00477      debug_ = &debug;
00478      cluster_ = &cluster;
00479      neighbor_ = &neighbor;
00480 
00481      // Initialize the neighborhood discovery module.
00482      ( *neighbor_ ).init( *radio_, *clock_, *timer_, *debug_ );
00483      return SUCCESS;
00484 }
00485 
00486 // --------------------------------------------------------------------
00487 
00488 template<typename OsModel_P,
00489          typename RoutingTable_P,
00490          typename Radio_P,
00491          typename Timer_P,
00492          typename Clock_P,
00493          typename Debug_P,
00494          typename Cluster_P,
00495          typename Neighbor_P,
00496          uint16_t MAX_CLUSTERS>
00497 void
00498 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00499 enable( void )
00500 {
00501 #ifdef HIGHWAY_METHOD_DEBUG
00502      debug().debug( "@@ %d METHOD CALLED: enable()\n", radio().id() );
00503 #endif
00504      radio().enable_radio();
00505      radio().template reg_recv_callback<self_type, &self_type::receive>( this );
00506      cluster().init( radio(), timer(), debug() );
00507      clustering_callback_ = cluster().template reg_changed_callback<self_type, &self_type::start_wrapper>( this );
00508      cluster().enable();
00509      neighbor().enable();
00510 }
00511 
00512 // --------------------------------------------------------------------
00513 
00514 template<typename OsModel_P,
00515          typename RoutingTable_P,
00516          typename Radio_P,
00517          typename Timer_P,
00518          typename Clock_P,
00519          typename Debug_P,
00520          typename Cluster_P,
00521          typename Neighbor_P,
00522          uint16_t MAX_CLUSTERS>
00523 void
00524 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00525 send( node_id_t destination, size_t len, block_data_t *data )
00526 {
00527 #ifdef HIGHWAY_METHOD_DEBUG
00528      debug().debug( "@@ %d METHOD CALLED: send1()\n", radio().id() );
00529 #endif
00530 #ifdef HIGHWAY_MSG_RECV_DEBUG
00531      debug().debug( "!! data: %d  %d\n", data[0], data[1] );
00532 #endif
00533      send( destination, highway_table_[destination].first.top().second, len, data );
00534 }
00535 
00536 // -----------------------------------------------------------------------
00537 
00538 template<typename OsModel_P,
00539          typename RoutingTable_P,
00540          typename Radio_P,
00541          typename Timer_P,
00542          typename Clock_P,
00543          typename Debug_P,
00544          typename Cluster_P,
00545          typename Neighbor_P,
00546          uint16_t MAX_CLUSTERS>
00547 void
00548 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00549 send( node_id_t destination, node_id_t port, size_t len, block_data_t *data )
00550 {
00551 #ifdef HIGHWAY_METHOD_DEBUG
00552      debug().debug( "@@ %d METHOD CALLED: send_spec()\n", radio().id() );
00553 #endif
00554      if (len >= Radio::MAX_MESSAGE_LENGTH-3)
00555      {
00556           debug().debug( "@@ %d: ERROR: message too long\n", radio().id() );    
00557      }
00558      
00559      buffer_[0] = SEND;
00560      buffer_[1] = destination;
00561      buffer_[2] = port;
00562      buffer_[3] = radio().id();
00563      
00564 #ifdef HIGHWAY_MSG_RECV_DEBUG
00565      debug().debug( "---------------ENCAPSULATING----------------\n" );
00566 #endif
00567 
00568      for (int i = 4; i < ( len+4 ); ++i)
00569      {
00570           buffer_[i] = data[i-4];
00571 #ifdef HIGHWAY_MSG_RECV_DEBUG
00572           debug().debug( "Data item %d: %d\n", i-4, data[i-4] );
00573 #endif          
00574      }
00575 
00576 
00577 #ifdef HIGHWAY_MSG_RECV_DEBUG
00578      for (int i = 0; i < len+4; ++i)
00579      {
00580           debug().debug( "Buffer item %d: %d\n", i, buffer_[i] );
00581      }
00582 #endif
00583 
00584 #ifdef HIGHWAY_MSG_RECV_DEBUG
00585      debug().debug( "---------------/ENCAPSULATING----------------\n" );
00586 #endif
00587      radio().send( routing_table_[port], len+4, buffer_ );
00588 }
00589 
00590 // -----------------------------------------------------------------------
00591 
00592 template<typename OsModel_P,
00593          typename RoutingTable_P,
00594          typename Radio_P,
00595          typename Timer_P,
00596          typename Clock_P,
00597          typename Debug_P,
00598          typename Cluster_P,
00599          typename Neighbor_P,
00600          uint16_t MAX_CLUSTERS>
00601 typename HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::Node_vect
00602 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00603 cluster_neighbors( void )
00604 {
00605 #ifdef HIGHWAY_METHOD_DEBUG
00606      debug().debug( "@@ %d METHOD CALLED: cluster_neighbors()\n", radio().id() );
00607 #endif
00608 
00609      neighbors_.clear();
00610      if ( not cluster().cluster_head() )
00611      {
00612          return neighbors_; 
00613      }
00614      
00615      highway_iterator it;
00616      for ( it = highway_table_.begin(); it != highway_table_.end(); ++it )
00617      {
00618           neighbors_.push_back( it->first );
00619      }
00620      
00621      return neighbors_;
00622 }
00623 
00624 // -----------------------------------------------------------------------
00625 
00626 template<typename OsModel_P,
00627          typename RoutingTable_P,
00628          typename Radio_P,
00629          typename Timer_P,
00630          typename Clock_P,
00631          typename Debug_P,
00632          typename Cluster_P,
00633          typename Neighbor_P,
00634          uint16_t MAX_CLUSTERS>
00635 typename HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::Ports_vect
00636 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00637 ports( node_id_t sid )
00638 {
00639 #ifdef HIGHWAY_METHOD_DEBUG
00640      debug().debug( "@@ %d METHOD CALLED: ports()\n", radio().id() );
00641 #endif
00642      ports_.clear();
00643      pq_iterator p = highway_table_[sid].first.data();
00644      for ( int i = 0; i < highway_table_[sid].first.size(); ++i )
00645      {
00646           ports_.push_back( *p );
00647           p++;
00648      }
00649 
00650      return ports_;
00651 }
00652 
00653 // -----------------------------------------------------------------------
00654 
00655 template<typename OsModel_P,
00656          typename RoutingTable_P,
00657          typename Radio_P,
00658          typename Timer_P,
00659          typename Clock_P,
00660          typename Debug_P,
00661          typename Cluster_P,
00662          typename Neighbor_P,
00663          uint16_t MAX_CLUSTERS>
00664 void
00665 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00666 start_wrapper( int state )
00667 {
00668 #ifdef HIGHWAY_METHOD_DEBUG
00669      debug().debug("@@ %d METHOD_CALLED: start_wrapper()\n", radio().id());
00670 #endif
00671      
00672      //TODO: Adapt when cluster stabilization.
00673      if ( state == CLUSTER_FORMED or state == NODE_JOINED )
00674      {
00675           // When joined to a cluster, unregister listening to cluster events.
00676           cluster().unreg_changed_callback( clustering_callback_ );
00677           //TODO: Check that this time is needed.
00678           timer().template set_timer<self_type, &self_type::start>( clustering_construction_time_, this, (void *) 0 );
00679      }
00680      else if ( state == CLUSTER_HEAD_CHANGED or state == NODE_LEFT )
00681      {
00682           //TODO: FAULT TOLERANCE. Manage this situation
00683      }
00684 }
00685 
00686 // -----------------------------------------------------------------------
00687 
00688 template<typename OsModel_P,
00689          typename RoutingTable_P,
00690          typename Radio_P,
00691          typename Timer_P,
00692          typename Clock_P,
00693          typename Debug_P,
00694          typename Cluster_P,
00695          typename Neighbor_P,
00696          uint16_t MAX_CLUSTERS>
00697 void
00698 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00699 start( void *userdata )
00700 {
00701 #ifdef HIGHWAY_METHOD_DEBUG
00702      debug().debug( "@@ %d METHOD CALLED: start(), %d\n", radio().id(), cluster().cluster_head() );
00703 #endif
00704      
00705      if ( not cluster().cluster_head() )
00706      {
00707           cluster_discovery();
00708      }
00709      
00710      timer().template set_timer<self_type, &self_type::discovery_timeout>( discovery_time_ + ( cluster().cluster_head() ? head_offset_ : 0 ), this, (void *) 0 );
00711      
00712 #ifdef VISOR_DEBUG
00713      debug().debug("$%d->%d$t\n", cluster().parent(), radio().id());
00714 #endif
00715 }
00716 
00717 // -----------------------------------------------------------------------
00718 
00719 template<typename OsModel_P,
00720          typename RoutingTable_P,
00721          typename Radio_P,
00722          typename Timer_P,
00723          typename Clock_P,
00724          typename Debug_P,
00725          typename Cluster_P,
00726          typename Neighbor_P,
00727          uint16_t MAX_CLUSTERS>
00728 void
00729 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00730 cluster_discovery( void )
00731 {
00732 #ifdef HIGHWAY_METHOD_DEBUG
00733      debug().debug( "@@ %d METHOD CALLED: cluster_discovery()\n", radio().id() );
00734 #endif
00735 
00736      // Add the piggybacking information to the neighborhood discovery module.
00737      node_id_t id = cluster().cluster_id();
00738      uint8_t length;
00739      
00740      // Adapt cluster_id to the node_id_t size of the plattform.
00741 #ifdef ISENSE_APP
00742      uint8_t sid_buf[3];
00743      sid_buf[0] = id & 0xFF;
00744      sid_buf[1] = id >> 8;
00745      sid_buf[2] = cluster().hops();
00746      length = 3;
00747 #else
00748      uint8_t sid_buf[5];
00749      sid_buf[0] = id & 0xFF;
00750      sid_buf[1] = ( id >> 8 ) & 0xFF;
00751      sid_buf[2] = ( id >> 16 ) & 0xFF;
00752      sid_buf[3] = ( id >> 24 ) & 0xFF;
00753      sid_buf[4] = cluster().hops();
00754      length = 5;
00755 #endif
00756 
00757 #ifdef HIGHWAY_DEBUG
00758      debug().debug( "@@ Node %d cluster_disc hops: %d\n", radio().id(), cluster().hops() );
00759 #endif
00760 
00761      // Register and add the payload space to the neighborhood discovery module.
00762      if ( neighbor().register_payload_space( HWY_N ) !=0 )
00763      {
00764           debug().debug( "Error registering payload space\n" );
00765      }
00766      else if(neighbor().set_payload( HWY_N, sid_buf, length )!=0) {
00767           debug().debug( "Error adding payload\n" );
00768      }
00769      else
00770      {
00771           uint8_t flags = nb_t::NEW_NB | nb_t::DROPED_NB | nb_t::NEW_PAYLOAD;
00772           neighbor().template reg_event_callback<HighwayCluster,&HighwayCluster::neighbor_callback>( HWY_N, flags, this );
00773      }
00774 }
00775 
00776 // -----------------------------------------------------------------------
00777 
00778 template<typename OsModel_P,
00779          typename RoutingTable_P,
00780          typename Radio_P,
00781          typename Timer_P,
00782          typename Clock_P,
00783          typename Debug_P,
00784          typename Cluster_P,
00785          typename Neighbor_P,
00786          uint16_t MAX_CLUSTERS>
00787 void
00788 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00789 neighbor_callback( uint8_t event, node_id_t from, uint8_t len, uint8_t* data)
00790 {
00791 //TODO: Adapt to payload on new_bidi only if Christos changes it.
00792 #ifdef HIGHWAY_METHOD_DEBUG
00793      debug().debug("@@ %d METHOD CALLED: neighbor_callback()\n", radio().id());
00794 #endif
00795      
00796      node_id_t sid;
00797      uint8_t hops;
00798      
00799      // On payload event, process the data according to the plattform
00800      if ( nb_t::NEW_PAYLOAD == event ) {
00801 #ifdef ISENSE_APP
00802           sid = ( data[1] << 8 ) | data[0];
00803           hops = data[2];
00804 #else
00805           sid = ( data[3] << 24 ) | ( data[2] << 16 ) | ( data[1] << 8 ) | data[0];
00806           hops = data[4];
00807 #endif
00808 
00809 #ifdef NEIGHBOR_DEBUG
00810           debug_->debug( "@@Node: %d, cluster_id: %d, hops: %d\n", from, sid, hops );
00811 #endif
00812           // If not cluster leader and the message is from another cluster add it to the highway table of the now to be port candidate.
00813           if ( !cluster().cluster_head() and cluster().cluster_id() != sid and cluster().cluster_id() != -1 )
00814           {
00815                displacing_push(highway_table_[sid].first, Hops_Node_id(hops + cluster().hops(), from));
00816           }
00817 
00818      }
00819      
00820 #ifdef NEIGHBOR_DEBUG
00821      else if ( nb_t::NEW_NB == event ) {
00822           debug_->debug( "NODE %d: event NEW_NB!! new neighbor added %d \n",radio_->id(), from );
00823      }
00824      else if ( nb_t::NEW_NB_BIDI == event ) {
00825           debug_->debug( "NODE %d: event NEW_NB_BIDI!! new neighbor added %d \n",radio_->id(), from );
00826      }
00827 #endif     
00828      else if ( nb_t::DROPED_NB == event ) {
00829           //TODO: Work on fault tolerance here!
00830           // 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.
00831           debug_->debug( "NODE %d: event DROPED_NB!! neighbor added %d \n",radio_->id(), from);
00832      }
00833 }
00834 
00835 // -----------------------------------------------------------------------
00836 
00837 template<typename OsModel_P,
00838          typename RoutingTable_P,
00839          typename Radio_P,
00840          typename Timer_P,
00841          typename Clock_P,
00842          typename Debug_P,
00843          typename Cluster_P,
00844          typename Neighbor_P,
00845          uint16_t MAX_CLUSTERS>
00846 void
00847 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00848 discovery_timeout( void *userdata )
00849 {
00850 #ifdef HIGHWAY_METHOD_DEBUG
00851      debug().debug( "@@ %d METHOD CALLED: discovery_timeout()\n", radio().id() );
00852 #endif
00853 
00854      if ( cluster().cluster_head() )
00855      {
00856           if ( ports_queue_.empty() ) // If no candidacies were presented we will call the same method after a work period.
00857           { 
00858                //IMPROVE: Judge the convenience of shortening this wait into fractions of the work period.
00859                timer().template set_timer<self_type, &self_type::discovery_timeout>( work_period_, this, 0 );
00860                //IMPROVE: Review if this return is needed.
00861                return;
00862           }
00863           else
00864           {
00865                highway_iterator it;
00866                for ( it = ports_queue_.begin(); it != ports_queue_.end(); ++it )
00867                {
00868                     start_port_negotiation( it, 4 ); // The four sets the amount of connectivity.
00869                }
00870           }
00871      }
00872      else
00873      {
00874           highway_iterator it;
00875           for ( it = highway_table_.begin(); it != highway_table_.end(); ++it ) {
00876                //TODO: Adapt to the new highway_msg.
00877                // Create a CANDIDACY highway message with: hops, id->candidate, cluster_id_own, cluster_id_target. 
00878                set_msg_highway( CANDIDACY, it->second.first.top().first, radio().id(), cluster().cluster_id(), it->first );
00879                // Send it to the parent.
00880                radio().send( cluster().parent(), sizeof( msg_highway ), (uint8_t*)&msg_highway_ );
00881           }
00882           
00883           timer().template set_timer<self_type, &self_type::start>( work_period_, this, 0 );
00884      }
00885 }
00886 
00887 // -----------------------------------------------------------------------
00888 
00889 template<typename OsModel_P,
00890          typename RoutingTable_P,
00891          typename Radio_P,
00892          typename Timer_P,
00893          typename Clock_P,
00894          typename Debug_P,
00895          typename Cluster_P,
00896          typename Neighbor_P,
00897          uint16_t MAX_CLUSTERS>
00898 void
00899 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00900 start_port_negotiation( highway_iterator it, uint8_t n )
00901 {
00902 #ifdef HIGHWAY_METHOD_DEBUG
00903      debug().debug("@@ %d METHOD CALLED: start_port_negotiation()\n", radio().id());
00904 #endif
00905 
00906      aux.clear();
00907      
00908      // If there are less candidates than desired connectivity put the available as ceiling.
00909      if ( n > it->second.first.size() )
00910      {
00911           n = it->second.first.size();
00912      }
00913      
00914      // Put max(n, size) elements into the aux vector.
00915      for ( int i = 0; i < n; ++i )
00916      {
00917           aux.push_back( it->second.first.pop() );
00918      }
00919      
00920      // Negotiate all the port candidates in aux.
00921      for ( int i = 0; i < n; ++i )
00922      {
00923           port_negotiation( it->first, aux[i].second );
00924      }
00925      
00926      // Put back the the port candidates.
00927      for ( int i = 0; i < n; ++i )
00928      {
00929           it->second.first.push( aux[i] );
00930      }
00931      
00932      aux.clear();
00933 }
00934 
00935 // -----------------------------------------------------------------------
00936 
00937 template<typename OsModel_P,
00938          typename RoutingTable_P,
00939          typename Radio_P,
00940          typename Timer_P,
00941          typename Clock_P,
00942          typename Debug_P,
00943          typename Cluster_P,
00944          typename Neighbor_P,
00945          uint16_t MAX_CLUSTERS>
00946 void
00947 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00948 port_negotiation( node_id_t sid, node_id_t candidate )
00949 {
00950 #ifdef HIGHWAY_METHOD_DEBUG
00951      debug().debug( "@@ %d METHOD_CALLED: port_negotiation()\n", radio().id() );
00952 #endif
00953      
00954      //TODO: Adapt to highway_msg class.
00955      // Create the highway_msg to request the other cluster a new connection.
00956      set_msg_highway( PORT_REQ, msg_highway_.hops, candidate, cluster().cluster_id(), sid );
00957      
00958      // Send the highway_msg to the first node in the path to candidate.
00959      radio().send( routing_table_[candidate], sizeof( msg_highway ), (uint8_t*)&msg_highway_ );
00960 }
00961 
00962 // -----------------------------------------------------------------------
00963 
00964 template<typename OsModel_P,
00965          typename RoutingTable_P,
00966          typename Radio_P,
00967          typename Timer_P,
00968          typename Clock_P,
00969          typename Debug_P,
00970          typename Cluster_P,
00971          typename Neighbor_P,
00972          uint16_t MAX_CLUSTERS>
00973 void
00974 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
00975 receive( node_id_t from, size_t len, block_data_t *data )
00976 {
00977 #ifdef HIGHWAY_METHOD_DEBUGG
00978      debug().debug("@@ %d METHOD_CALLED: receive()\n", radio().id());
00979 #endif
00980      // Ignore if heard oneself's message.
00981      if ( from == radio().id() )
00982      {
00983           return;
00984      }
00985           
00986 #ifdef HIGHWAY_MSG_RECV_DEBUG
00987      if ( *data == CANDIDACY ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: CANDIDACY\n", radio().id(), from );
00988      else if ( *data == PORT_REQ ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_REQ\n", radio().id(), from );
00989      else if ( *data == PORT_REQ2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_REQ2\n", radio().id(), from );
00990      else if ( *data == PORT_ACK ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_ACK\n", radio().id(), from );
00991      else if ( *data == PORT_ACK2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_ACK2\n", radio().id(), from );
00992      else if ( *data == PORT_NACK ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_NACK\n", radio().id(), from );
00993      else if ( *data == PORT_NACK2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: PORT_NACK2\n", radio().id(), from );
00994      else if ( *data == SEND ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: SEND\n", radio().id(), from );
00995      else if ( *data == SEND2 ) debug().debug( "@@ %d<- %d: MSG_RECEIVED: SEND2\n", radio().id(), from );
00996 #endif
00997 
00998      // Messages travelling to the current node cluster leader are processed in send_to_leader
00999      if ( *data == CANDIDACY or *data == PORT_REQ2 or *data == PORT_ACK2 or *data == PORT_NACK2 or *data == SEND2 )
01000      {
01001           send_to_leader( from, len, data );
01002      }
01003      else if ( *data == PORT_REQ or *data == PORT_ACK or *data == PORT_NACK ) // Construction messages travelling outwards
01004      {
01005           send_away( from, len, data );
01006      }
01007      else if ( *data == SEND) // Data messages travelling outwards.
01008      {
01009           process_send( from, len, data );
01010      }
01011 }
01012 
01013 // -----------------------------------------------------------------------
01014 
01015 template<typename OsModel_P,
01016          typename RoutingTable_P,
01017          typename Radio_P,
01018          typename Timer_P,
01019          typename Clock_P,
01020          typename Debug_P,
01021          typename Cluster_P,
01022          typename Neighbor_P,
01023          uint16_t MAX_CLUSTERS>
01024 void
01025 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01026 send_to_leader( node_id_t from, size_t len, block_data_t *data )
01027 {
01028 #ifdef HIGHWAY_METHOD_DEBUG
01029      debug().debug( "@@ %d METHOD_CALLED: send_to_leader()\n", radio().id()) ;
01030 #endif
01031 
01032 #ifdef HIGHWAY_MSG_RECV_DEBUG
01033      if( *data == SEND2 )
01034      {
01035           debug().debug( "---------------SENDRECV2--------------\n" );
01036           for( int i = 0; i<len; ++i )
01037                debug().debug( "Data[%d]: %d\n", i, data[i] );
01038           debug().debug( "---------------/SENDRECV2--------------\n" );    
01039      }
01040 #endif
01041 
01042      msg_highway_ = * ((msg_highway * ) data);
01043      
01044      if ( *data == CANDIDACY or *data == PORT_REQ2 )
01045      {
01046           routing_table_[msg_highway_.candidate_id] = from;
01047      }
01048      else if ( *data == PORT_ACK2 )
01049      {
01050 #ifdef VISOR_DEBUG
01051           debug().debug( "$%d->%d$h\n", from, radio_->id() );
01052 #endif
01053      }
01054      
01055      if ( cluster().cluster_head() )
01056      {
01057           cluster_head_work( from, len, data );
01058      }
01059      else
01060      {
01061           radio().send( cluster().parent(), len, data );
01062      }
01063 }
01064 
01065 // -----------------------------------------------------------------------
01066 
01067 template<typename OsModel_P,
01068          typename RoutingTable_P,
01069          typename Radio_P,
01070          typename Timer_P,
01071          typename Clock_P,
01072          typename Debug_P,
01073          typename Cluster_P,
01074          typename Neighbor_P,
01075          uint16_t MAX_CLUSTERS>
01076 void
01077 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01078 send_away( node_id_t from, size_t len, block_data_t *data )
01079 {
01080 #ifdef HIGHWAY_METHOD_DEBUGG
01081      debug().debug("@@ %d METHOD_CALLED: send_away()\n", radio().id());
01082 #endif
01083 
01084 #ifdef VISOR_DEBUG
01085      if( *data == PORT_ACK )
01086           debug().debug("$%d->%d$h\n", from, radio_->id());
01087 #endif
01088 
01089      msg_highway_ = * ((msg_highway * ) data);
01090      
01091      // Check if we are still in the cluster that originated the request.
01092      if ( from == cluster().parent() )
01093      {
01094           // If the current node is not the port, continue the way to the port.
01095           if ( msg_highway_.candidate_id != radio().id() )
01096           {
01097                radio().send( routing_table_[msg_highway_.candidate_id], sizeof( msg_highway ), data );
01098           }
01099           else // Send the message o the other cluster port and set connected_to.
01100           {
01101                if ( *data == PORT_REQ )
01102                {
01103                     radio().send( highway_table_[msg_highway_.sid_target].first.top().second, sizeof( msg_highway ), data );
01104                }
01105                else if ( *data == PORT_ACK ) {
01106                     connected_to = routing_table_[msg_highway_.sid_source];
01107                     radio().send( connected_to, sizeof( msg_highway ), data );
01108                }
01109                else //NACK
01110                {
01111                     radio().send( routing_table_[msg_highway_.sid_source], sizeof( msg_highway ), data );
01112                     routing_table_.erase( routing_table_.find(msg_highway_.sid_source) );
01113                }                    
01114           }
01115      }
01116      else // Create a "2" message.
01117      {
01118           if ( *data == PORT_REQ )
01119           {
01120                msg_highway_.msg_id = PORT_REQ2;
01121                routing_table_[msg_highway_.sid_source] = from;
01122                msg_highway_.candidate_id = radio().id();
01123           }
01124           else if ( *data == PORT_ACK ) {
01125 #ifdef VISOR_DEBUG
01126                debug().debug( "+%d#%d#0#1\n", radio().id(), cluster().cluster_id() );
01127                debug().debug( "+%d#%d#0#1\n", from, msg_highway_.sid_target );
01128 #endif
01129                msg_highway_.msg_id = PORT_ACK2;
01130                connected_to = from;
01131                     
01132           }
01133           else //NACK
01134           {
01135                msg_highway_.msg_id = PORT_NACK2;
01136                msg_highway_.candidate_id = radio().id();
01137           }
01138           
01139           msg_highway_.candidate_id = radio().id();
01140           radio().send( cluster().parent(), sizeof( msg_highway ), (uint8_t *)&msg_highway_ );
01141      }
01142 }
01143 
01144 // -----------------------------------------------------------------------
01145 
01146 template<typename OsModel_P,
01147          typename RoutingTable_P,
01148          typename Radio_P,
01149          typename Timer_P,
01150          typename Clock_P,
01151          typename Debug_P,
01152          typename Cluster_P,
01153          typename Neighbor_P,
01154          uint16_t MAX_CLUSTERS>
01155 void
01156 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01157 process_send( node_id_t from, size_t len, block_data_t *data )
01158 {
01159 #ifdef HIGHWAY_METHOD_DEBUGG
01160      debug().debug("@@ %d METHOD_CALLED: send_process()\n", radio().id());
01161 #endif
01162 
01163 #ifdef HIGHWAY_MSG_RECV_DEBUG
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() )
01172      {
01173           // If the current node is not the port, continue the way to the port.
01174           if ( data[2] != radio().id() )
01175           {
01176                radio().send( routing_table_[data[2]], len, data );
01177           }
01178           else // Send the message o the other cluster port and set connected_to.
01179           {
01180                radio().send( connected_to, len, data );
01181           }
01182      }
01183      else // Create a SEND2 message.
01184      {
01185           *data = SEND2;
01186           radio().send( cluster().parent(), len, data );
01187      }
01188 }
01189 
01190 // -----------------------------------------------------------------------
01191 
01192 template<typename OsModel_P,
01193          typename RoutingTable_P,
01194          typename Radio_P,
01195          typename Timer_P,
01196          typename Clock_P,
01197          typename Debug_P,
01198          typename Cluster_P,
01199          typename Neighbor_P,
01200          uint16_t MAX_CLUSTERS>
01201 void
01202 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01203 cluster_head_work( node_id_t from, size_t len, block_data_t *data )
01204 {
01205 #ifdef HIGHWAY_METHOD_DEBUG
01206      debug().debug("@@ %d METHOD_CALLED: cluster_head_work()\n", radio().id());
01207 #endif
01208      msg_highway_ = *((msg_highway * ) data);
01209      
01210      if ( *data == CANDIDACY ) // Add the port candidate to the queue.
01211      {
01212           displacing_push( ports_queue_[msg_highway_.sid_target].first, Hops_Node_id( msg_highway_.hops, msg_highway_.candidate_id ) );
01213      }
01214      else if ( *data == PORT_REQ2 ) // Accept or reject the highway request.
01215      {
01216           if (highway_table_[msg_highway_.sid_source].first.size() < 4)
01217           {
01218                displacing_push( highway_table_[msg_highway_.sid_source].first, Hops_Node_id( msg_highway_.hops, msg_highway_.candidate_id ) );
01219                highway_table_[msg_highway_.sid_source].second = 0;
01220                msg_highway_.msg_id = PORT_ACK;
01221           }
01222           else //IMPROVE: extra NACK conditions.
01223           {
01224                msg_highway_.msg_id = PORT_NACK;
01225           }
01226           radio().send( from, sizeof( msg_highway ), (uint8_t *)&msg_highway_ );
01227      }
01228      else if ( msg_highway_.msg_id == PORT_ACK2 ) // Establish the port.
01229      {
01230           displacing_push( highway_table_[msg_highway_.sid_target].first, pop_port( ports_queue_[msg_highway_.sid_target].first, msg_highway_.candidate_id ) );
01231           highway_table_[msg_highway_.sid_target].second = 0;
01232      }
01233      else if ( msg_highway_.msg_id == PORT_NACK2 ) // Remove the port candidate.
01234      {
01235           pop_port( ports_queue_[msg_highway_.sid_target].first, msg_highway_.candidate_id );
01236      }
01237      else if ( *data == SEND2 ) // Call the registered (if exists) receiving method.
01238      {
01239 #ifdef HIGHWAY_MSG_RECV_DEBUG
01240           debug().debug( "---------------HEAD_WORK_RECV--------------\n" );
01241           for( int i = 0; i<len; ++i )
01242                debug().debug( "Data[%d]: %d\n", i, data[i] );
01243           debug().debug( "---------------HEAD_WORK_RECV--------------\n" );    
01244 #endif
01245      
01246           if( hwy_recv_callback_  ) hwy_recv_callback_((node_id_t)data[3], len-4, &data[4]);
01247      }
01248 }
01249 
01250 // -----------------------------------------------------------------------
01251 // Queue and other helper methods.                                       |
01252 // -----------------------------------------------------------------------
01253 
01254 template<typename OsModel_P,
01255          typename RoutingTable_P,
01256          typename Radio_P,
01257          typename Timer_P,
01258          typename Clock_P,
01259          typename Debug_P,
01260          typename Cluster_P,
01261          typename Neighbor_P,
01262          uint16_t MAX_CLUSTERS>
01263 void
01264 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01265 displacing_push( PQ& pq, Hops_Node_id pin )
01266 {
01267 #ifdef HIGHWAY_METHOD_DEBUG
01268      debug().debug("@@ %d METHOD_CALLED: displacing_push()\n", radio().id());
01269 #endif
01270      if ( pq.size() < MAX_CLUSTER_PORTS )
01271      {
01272           pq.push( pin );
01273           return;
01274      }
01275      
01276      aux.clear();
01277      
01278      for ( int i = 0; i < MAX_CLUSTER_PORTS-1; ++i )
01279      {
01280           aux.push_back( pq.pop() );
01281      }
01282      
01283      if ( pin < pq.top() )
01284      {
01285           pq.pop();
01286           pq.push( pin );
01287      }
01288      
01289      for ( int i = 0; i < MAX_CLUSTER_PORTS-1; ++i )
01290      {
01291           pq.push( aux[aux.size()-1] );
01292           aux.pop_back();
01293      }
01294 }
01295 
01296 // -----------------------------------------------------------------------
01297 
01298 template<typename OsModel_P,
01299          typename RoutingTable_P,
01300          typename Radio_P,
01301          typename Timer_P,
01302          typename Clock_P,
01303          typename Debug_P,
01304          typename Cluster_P,
01305          typename Neighbor_P,
01306          uint16_t MAX_CLUSTERS>
01307 typename HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::Hops_Node_id
01308 HighwayCluster<OsModel_P, RoutingTable_P, Radio_P, Timer_P, Clock_P, Debug_P, Cluster_P, Neighbor_P, MAX_CLUSTERS>::
01309 pop_port( PQ& pq, node_id_t port )
01310 {
01311 #ifdef HIGHWAY_METHOD_DEBUG
01312      debug().debug( "@@ %d METHOD_CALLED: pop_port()\n", radio().id() );
01313 #endif
01314      aux.clear();
01315      Hops_Node_id ret;
01316      for ( int i = 0; i < MAX_CLUSTER_PORTS; ++i )
01317      {
01318           if ( pq.top().second != port )
01319           {
01320                aux.push_back( pq.pop() );
01321           }
01322           else
01323           {
01324                ret = pq.top();
01325           }
01326      }
01327      
01328      for ( uint16_t i = 0; i < aux.size(); ++i )
01329      {
01330           pq.push(aux[i]);
01331      }
01332      
01333      return ret;
01334 }
01335 }
01336 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines