Wiselib
wiselib.testing/algorithms/end_to_end_communication/end_to_end_communication.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 #ifndef __ALGORITHMS_END_TO_END_COMMUNICATION_END_TO_END_COMMUNICATION_H__H__
00020 #define __ALGORITHMS_END_TO_END_COMMUNICATION_END_TO_END_COMMUNICATION_H__H__
00021 
00022 #include "algorithms/end_to_end_communication/end_to_end_communication_msg.h"
00023 #include "algorithms/neighbor_discovery/echo.h"
00024 #include "algorithms/neighbor_discovery/pgb_payloads_ids.h"
00025 
00026 //#include "algorithms/cluster/highway/highway_stabilizing_new.h"
00027 #include "algorithms/cluster/highway/highway_dumber.h"
00028 #include "algorithms/cluster/clustering_types.h"
00029 #include "util/pstl/vector_static.h"
00030 #include "util/pstl/priority_queue.h"
00031 #include "util/pstl/pair.h"
00032 #include "util/pstl/map_static_vector.h"
00033 #include "internal_interface/routing_table/routing_table_static_array.h"
00034 #include "util/delegates/delegate.hpp"
00035 
00036 #include "algorithms/cluster/fronts/fronts_core.h"
00037 #include "algorithms/cluster/modules/chd/attr_chd.h"
00038 #include "algorithms/cluster/modules/it/fronts_it.h"
00039 #include "algorithms/cluster/modules/jd/bfs_jd.h"
00040 
00041 #include "util/serialization/serialization.h"
00042 #include "util/base_classes/routing_base.h"
00043 
00044 //#define DEBUG
00045 //#define CTI_VISOR
00046 
00047 namespace wiselib {
00048 
00052 template<typename OsModel_P,
00053      typename Radio_P,
00054      typename Neighbor_Discovery_P = wiselib::Echo<OsModel_P, Radio_P, typename OsModel_P::Timer, typename OsModel_P::Debug>,
00055      typename Cluster_P = wiselib::FrontsCore<OsModel_P, Radio_P, wiselib::AtributeClusterHeadDecision<OsModel_P, Radio_P>, wiselib::BfsJoinDecision<OsModel_P, Radio_P>, wiselib::FrontsIterator<OsModel_P, Radio_P> > >
00056     class EndToEndCommunication : public RoutingBase<OsModel_P, Radio_P> {
00057 public:
00058         
00059      typedef OsModel_P OsModel;
00060      
00061      typedef Radio_P Radio;
00062      typedef typename OsModel_P::Debug Debug;
00063      typedef typename OsModel_P::Clock Clock;
00064      typedef typename OsModel::Timer Timer;
00065      typedef typename OsModel::Rand Rand;
00066      typedef typename Radio::node_id_t node_id_t;
00067      typedef typename Radio::size_t size_t;
00068      typedef typename Radio::block_data_t block_data_t;
00069      typedef typename Radio::message_id_t message_id_t;
00070      typedef typename Timer::millis_t millis_t;
00071 
00072      typedef Cluster_P Cluster;
00073      typedef Neighbor_Discovery_P NeighborDiscovery;
00074 
00075    
00076      typedef wiselib::AtributeClusterHeadDecision<OsModel, Radio> CHD_t;
00077      typedef wiselib::BfsJoinDecision<OsModel, Radio> JD_t;
00078      typedef wiselib::FrontsIterator<OsModel, Radio> IT_t;
00079      typedef wiselib::FrontsCore<OsModel, Radio, CHD_t, JD_t, IT_t> clustering_algo_t;
00080      typedef wiselib::StaticArrayRoutingTable<OsModel, Radio, 10> RoutingTable;
00081      typedef wiselib::Echo<OsModel, Radio, Timer, Debug> nb_t;
00082      typedef wiselib::HighwayCluster<OsModel, RoutingTable, clustering_algo_t, nb_t, 4> HighwayCluster;
00083      typedef typename HighwayCluster::Node_vect Node_vect;
00084 
00085      typedef typename Node_vect::iterator Node_vect_it;
00086 
00087      typedef wiselib::CommunicationMessage<OsModel, Radio> CommunicationMsg_t;
00088      typedef EndToEndCommunication<OsModel, Radio, NeighborDiscovery, Cluster> self_type;
00089 
00090      typedef self_type* self_pointer_t;
00091      typedef delegate3<void, node_id_t, size_t, block_data_t*> endToEnd_delegate_t;
00092 
00093      typedef CommunicationMessage<OsModel, Radio> Communicationmsg_t;
00094      
00095      // --------------------------------------------------------------------
00096      enum SpecialNodeIds {
00097           BROADCAST_ADDRESS = Radio::BROADCAST_ADDRESS, 
00098           NULL_NODE_ID      = Radio::NULL_NODE_ID      
00099      };
00100      // --------------------------------------------------------------------
00101      enum Restrictions {
00102           MESSAGE_SIZE = Communicationmsg_t::MAX_PAYLOAD_LENGTH   
00103      };
00104      enum{
00105           END_TO_END_MESSAGE = 245,
00106           NODE_IN_CLUSTER = 246,
00107      };
00108 
00109      enum ErrorCodes{
00110           SUCCESS = OsModel::SUCCESS,
00111           ERR_UNSPEC = OsModel::ERR_UNSPEC
00112      };
00113         // --------------------------------------------------------------------
00116         EndToEndCommunication() {}
00117         ~EndToEndCommunication() {}
00119 
00122         void enable_radio();
00123         void disable_radio();
00125 
00128 
00130      void send( node_id_t receiver, size_t len, block_data_t *data );
00131      void send_highway( node_id_t receiver, size_t len, block_data_t *data );
00132      void receive_highway (node_id_t from, size_t len, block_data_t *data ); 
00133      void on_receive (node_id_t from, size_t len, block_data_t *data ); 
00134 
00135      bool is_in_cluster ( node_id_t nodeID );
00136      void print_statistics();
00137      void arriving_robot(uint8_t event, node_id_t from, uint8_t len, uint8_t* data);
00138 
00139      int init( Radio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Rand& rand, Cluster& cluster, HighwayCluster& highwaycluster, NeighborDiscovery& neighbor );
00140      void disconnected_node_timeout( void* a);
00141     
00142      template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)>
00143                uint8_t endToEnd_reg_recv_callback(T *obj_pnt) {
00144                     endToEnd_recv_callback_ = endToEnd_delegate_t::template from_method<T, TMethod > ( obj_pnt );
00145                     return 0;
00146           }
00147 
00148           void unreg_endToEnd_recv_callback() {
00149           endToEnd_recv_callback_ = endToEnd_delegate_t();
00150           }
00151 
00152         typename Radio::node_id_t id()
00153         {
00154            return tx_radio_->id();
00155         }
00156         
00157         void destruct() {}
00158    
00159   
00160 protected:
00161      typename Radio::self_pointer_t tx_radio_;
00162      typename Debug::self_pointer_t debug_;
00163      typename Clock::self_pointer_t clock_;
00164      typename HighwayCluster::self_type* highway_;
00165      typename Timer::self_pointer_t timer_;
00166      typename Cluster::self_type* cluster_;
00167      typename NeighborDiscovery::self_t* neighbor_;
00168      typename Rand::self_pointer_t rand_; 
00169 
00170      CommunicationMsg_t comm_message;
00171      endToEnd_delegate_t endToEnd_recv_callback_;
00172      CHD_t CHD_;
00173      JD_t JD_;
00174      IT_t IT_;
00175 //   METRICS FOR END_TO_END COMMUNICATION
00176      
00177      millis_t disconnected_node_timeout_;     
00178      int RX_total ; //Messages received from neighbor nodes
00179 //Metrics for cluster heads
00180 
00181      uint16_t RX_childs; //Messages received from nodes in the cluster
00182      uint16_t RX_highways; //Messages received from highways
00183 
00184      uint16_t FW_childs; //Messages coming from nodes in the cluster and delivered to the final destination INSIDE THE SAME CLUSTER
00185      uint16_t FW_highways;//Messages coming from nodes in the cluster and delivered to the final destination IN ANOTHER CLUSTER
00186 
00187 
00188      uint16_t TX_neigh;       //Messages generated and transmitted directly to the final destination (Cluster heads uses the same metric for messages generated by itself)
00189      uint16_t TX_cluster_head;     //Messages generated and transmitted to the cluster head because the node is not a direct neighbor
00190      uint16_t TX_highways;    //Messages generated by the cluster head and transmitted directly on the highways because the destination is not in the cluster
00191      uint16_t TX_in_cluster;
00192 
00193      bool has_roomba_neighbor;
00194      node_id_t roomba_id;
00195      bool has_msg;
00196 
00197 
00198      int radio_recv_callback_id_;
00199      int highway_recv_callback_id_;
00200      bool is_disconnected_node;
00201 
00202      Radio& radio()
00203      {
00204           return *tx_radio_;
00205      }
00206      Timer& timer()
00207      {
00208           return *timer_;
00209      }
00210      Debug& debug()
00211      {
00212           return *debug_;
00213      }
00214 
00215      Cluster& cluster()
00216      {
00217           return *cluster_;
00218      }
00219 
00220      Clock& clock()
00221      {
00222      return *clock_;
00223      }
00224 
00225      NeighborDiscovery& neighbor_discovery(){
00226           return *neighbor_;       
00227      }
00228 
00229      HighwayCluster& highway()
00230      {
00231           return *highway_;
00232      }
00233 
00234 
00235 };
00236 
00237     // -----------------------------------------------------------------------
00238 
00239     template<typename OsModel_P,
00240      typename Radio_P,
00241      typename Neighbor_Discovery_P,
00242      typename Cluster_P>
00243     int
00244     EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P,Cluster_P>::
00245     init (Radio& tx_radio, Timer& timer, Clock& clock, Debug& debug, Rand& rand, Cluster& cluster, HighwayCluster& highwaycluster, NeighborDiscovery& neighbor) {
00246      tx_radio_ = &tx_radio;
00247      timer_ = &timer;
00248      clock_ = &clock;
00249      rand_ = &rand;
00250      neighbor_ = &neighbor;
00251      debug_ = &debug;
00252      cluster_= &cluster;
00253      highway_ = &highwaycluster;
00254      highway_->init( *tx_radio_, *timer_, clock, *debug_, *rand_, *cluster_, *neighbor_ );
00255      highway_->set_discovery_time(1000);
00256      highway_->enable();
00257      highway_recv_callback_id_ = highway().template hwy_reg_recv_callback<self_type, &self_type::receive_highway >(this);
00258      RX_total = 0 ; //Messages received from neighbor nodes
00259      RX_childs = 0 ;
00260      RX_highways = 0 ;
00261      FW_childs = 0;
00262      FW_highways = 0;
00263 
00264      disconnected_node_timeout_ = (millis_t)1000;
00265      roomba_id = 0;
00266      TX_neigh = 0 ;
00267      TX_cluster_head = 0 ;
00268      TX_highways = 0 ;
00269 
00270 
00271      cluster_->set_cluster_head_decision( CHD_ );
00272      cluster_->set_join_decision( JD_ );
00273      cluster_->set_iterator( IT_ );
00274      cluster_->init( *tx_radio_, *timer_, *debug_, *rand_, *neighbor_ );
00275      cluster_->set_maxhops( 1 );
00276 
00277 #ifdef DEBUG
00278      debug_->debug("EndToEnd Algorithm: Successfully initialized module\n");
00279      debug_->debug("Debug_->debug: Node %x: TX_neigh value is %i\n" , radio().id(), TX_neigh);
00280 #endif
00281      return SUCCESS;
00282 }
00283 
00284 
00285 template<typename OsModel_P,
00286      typename Radio_P,
00287      typename Neighbor_Discovery_P,
00288      typename Cluster_P>
00289 void
00290 EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00291 enable_radio()
00292 {
00293 #ifdef DEBUG
00294      debug_->debug("EndToEndCommunication boots on %x\n", tx_radio_->id());
00295 #endif
00296 
00297      radio().enable_radio();
00298      neighbor_discovery().enable();
00299 
00300         
00301      radio_recv_callback_id_ = radio().template reg_recv_callback<self_type, &self_type::on_receive >(this);
00302 #ifdef DEBUG
00303      if( neighbor_discovery().register_payload_space( MOBILITY ) )
00304           debug_->debug( "Could not register payload space in neighbor discovery module!\n" );
00305 #endif
00306 
00307      //Sets the nodes MOBILITY-payload to 0 (i.e. not a robot).
00308      uint8_t data = 0;
00309      neighbor_discovery().set_payload( MOBILITY, &data, sizeof( data ) );
00310 
00311      //Registers callback for the MOBILITY-payload
00312      uint8_t flags = nb_t::NEW_PAYLOAD_BIDI;
00313      neighbor_discovery().template reg_event_callback<self_type, &self_type::arriving_robot>( MOBILITY, flags, this );
00314      has_roomba_neighbor = false;
00315 }
00316 
00317     // -----------------------------------------------------------------------
00318 
00319 template<typename OsModel_P,
00320      typename Radio_P,
00321      typename Neighbor_Discovery_P,
00322      typename Cluster_P>
00323 void
00324 EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00325 disable_radio(void) {
00326 #ifdef DEBUG
00327      debug_->debug("Called EndToEndCommunication::disable\n");
00328 #endif
00329      //Unregister callbacks
00330      neighbor_discovery->unregister_payload_space( MOBILITY );
00331      neighbor_discovery->unreg_recv_callback( MOBILITY );
00332      radio().unregister_recv_callback( radio_recv_callback_id_ );
00333 
00334      neighbor_discovery->disable();
00335      radio().disable_radio();
00336 }
00337       
00338 // -----------------------------------------------------------------------
00339 
00340     template<typename OsModel_P,
00341      typename Radio_P,
00342      typename Neighbor_Discovery_P,
00343      typename Cluster_P>
00344     void
00345     EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00346     send( node_id_t destination, size_t len, block_data_t *data ) {
00347 
00348           CommunicationMsg_t* msg = (CommunicationMsg_t*)data;
00349 #ifdef DEBUG
00350           debug().debug("Node %x is not a cluster leader\n", radio().id());
00351 #endif
00352 
00353           if (neighbor_discovery().is_neighbor_bidi(msg->dest())){
00354                TX_neigh++;
00355 #ifdef DEBUG
00356                debug_->debug ("Node %x is a bidi neighbor of %x; sending message; sent a total of %i messages\n", msg->dest(), radio().id(), TX_neigh );
00357                debug_->debug("Node %x: TX_neigh value is %i\n" , radio().id(), TX_neigh);
00358 #endif
00359                radio().send(msg->dest(), len , data);        
00360                } 
00361 
00362           else if ((!neighbor_discovery().is_neighbor_bidi(msg->dest())) && (!cluster().is_cluster_head())){
00363                TX_cluster_head++;
00364 #ifdef DEBUG
00365                debug_->debug ("Node %x: sending message to cluster leader %x\n", tx_radio_->id(), cluster().parent() );
00366                debug().debug("Node %x: TX_cluster_head = %i\n", radio().id(), TX_cluster_head);
00367 #endif
00368                //comm_message.set_dest(cluster().parent());
00369                radio().send( cluster().parent(), len, data );
00370                }
00371 
00372           else if (cluster().is_cluster_head()){
00373                if (is_in_cluster(destination)) {
00374                     TX_in_cluster++;
00375                     radio().send( destination, len, data);
00376                     }
00377                else
00378 
00379                     send_highway( destination, len, data );
00380 
00381           }    
00382      }
00383 
00384     template<typename OsModel_P,
00385      typename Radio_P,
00386      typename Neighbor_Discovery_P,
00387      typename Cluster_P>
00388     void
00389     EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00390     send_highway( node_id_t destination, size_t len, block_data_t *data ) {
00391 
00392           Node_vect neigh;
00393           highway().cluster_neighbors(&neigh);
00394           Node_vect_it it;
00395           //Broadcast the message toward all the other neighbor leaders
00396 
00397           for( it = neigh.begin(); it != neigh.end(); ++it )
00398           {
00399 #ifdef DEBUG
00400                debug_->debug("Neighbor Leaders of %x <--> %x\n", tx_radio_->id(), *it );
00401                debug_->debug("Node %x Sending through the highway to all its neighboring clusters\n", tx_radio_->id());
00402 #endif
00403                highway().send(*it, sizeof(data), data);
00404           }
00405 
00406           /* Start the timer to wait for an ACK saying if the node is connected to some cluster*/
00407 
00408           timer().template set_timer< self_type, &self_type::disconnected_node_timeout >( disconnected_node_timeout_ , this, (void *) 0 );
00409           is_disconnected_node = true;
00410      }
00411 
00412 
00413     template<typename OsModel_P,
00414      typename Radio_P,
00415      typename Neighbor_Discovery_P,
00416      typename Cluster_P>
00417 
00418     void
00419     EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00420     on_receive( node_id_t from, size_t len, block_data_t *data ) {
00421      message_id_t msg_id = read<OsModel, block_data_t, message_id_t>( data );
00422 
00423 
00424      //Only treat CommunicationMessages
00425      if( msg_id == END_TO_END_MESSAGE )
00426      {
00427           CommunicationMsg_t* msg = (CommunicationMsg_t*)data;
00428 
00429           if( msg->dest() == tx_radio_->id() ) {
00430                // The message reached its destination => Notify registered receivers.
00431                notify_receivers( msg->source(), msg->payload_size(), msg->payload() );
00432 #ifdef DEBUG
00433                debug_->debug("Node %x received an EndToEnd message from %x for itself\n", radio().id(), from);
00434                debug().debug("Node %x: Total RX messages = %i\n", radio().id(), RX_total);
00435 #endif
00436 #ifdef CTI_VISOR
00437           if ( from == cluster().parent())
00438                debug_->debug("E2E_MSG; CLUST; %d; %d", radio().id(), from);
00439           else
00440                debug_->debug("E2E_MSG; NEIGH; %d; %d", radio().id(), from);
00441 #endif
00442                RX_total++;
00443           } 
00444 
00445           else if (cluster().is_cluster_head()){
00446 #ifdef DEBUG
00447                debug().debug("Cluster leader %x received a message from %x destined to %x\n", radio().id(), from, msg->dest());
00448 #endif
00449                RX_childs++;
00450                if (is_in_cluster( msg->dest()) || (neighbor_discovery().is_neighbor_bidi(msg->dest()))) {
00451                     radio().send( msg->dest(), len, data );
00452                     FW_childs++;
00453 #ifdef DEBUG
00454                     debug().debug("Node %x: Cluster leader forwarded a message for the destination %x \n",radio().id(), msg->dest());
00455 #endif
00456                     }
00457 
00458                else      {              
00459                          send_highway( from, len, data );
00460                     }
00461                }
00462           }
00463      }
00464 
00465 template<typename OsModel_P,
00466      typename Radio_P,
00467      typename Neighbor_Discovery_P,
00468      typename Cluster_P>
00469       void
00470       EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::       
00471       receive_highway(node_id_t from, size_t len, block_data_t *data){
00472           message_id_t msg_id = read<OsModel, block_data_t, message_id_t>( data );
00473 
00474           CommunicationMsg_t* msg = (CommunicationMsg_t*)data;
00475 
00476           if (msg_id == END_TO_END_MESSAGE){
00477 #ifdef DEBUG        
00478                debug_->debug("Node %x: Receiving message from the highway\n",radio().id());
00479 #endif
00480                if (is_in_cluster(msg->dest())){
00481                     radio().send(msg->dest(), sizeof(data), data);
00482 #ifdef DEBUG
00483                     debug().debug("Node %x: Delivering message to final destination %x\n", tx_radio_->id(), data[1]);
00484 #endif
00485                     //Send back an answer to the leader from which we received the message
00486                     CommunicationMsg_t ack;
00487                
00488                     /*This buffer is used as follows:
00489                     buf[0] = MSG_TYPE
00490                     buf[1] = a boolean flag: 1 means the desired node was found in the cluster, 0 means it was not found
00491                     */
00492                     ack.set_dest(from);
00493                     ack.set_msg_id(NODE_IN_CLUSTER);
00494                     uint8_t buf_to_send[8];  
00495                     ack.set_payload(sizeof(buf_to_send), buf_to_send);          
00496                               highway().send(from, ack.buffer_size(),(uint8_t *) &ack);   
00497 
00498                }              
00499                else 
00500                     debug().debug("Node %x: node is not in my cluster\n",radio().id());
00501                }
00502           else if (msg_id == NODE_IN_CLUSTER){
00503                debug().debug("Node %x: Receive a NODE_IN_CLUSTER message from highway\n", radio().id());
00504       }
00505      }
00506 
00507 template<typename OsModel_P,
00508      typename Radio_P,
00509      typename Neighbor_Discovery_P,
00510      typename Cluster_P>
00511     bool
00512     EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00513     is_in_cluster ( node_id_t nodeID ){
00514           node_id_t cluster_members[cluster().childs_count()];
00515           bool result = false;
00516           cluster().childs(cluster_members);
00517           for (int i = 0; i < cluster().childs_count(); i++){
00518                if ( cluster_members[i] == nodeID ){
00519                     result = true;
00520 #ifdef DEBUG
00521                     debug().debug("Node %x: node %x is in my cluster!\n", radio().id(), nodeID);
00522 #endif
00523                     return result;
00524                }
00525           }
00526 #ifdef DEBUG
00527           debug().debug("Node %x: node %x is not in my cluster!\n", radio().id(), nodeID);
00528 #endif
00529           return result;
00530      }
00531 
00532 template<typename OsModel_P,
00533      typename Radio_P,
00534      typename Neighbor_Discovery_P,
00535      typename Cluster_P>
00536     void 
00537     EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00538     disconnected_node_timeout ( void* a ){
00539           if (is_disconnected_node){
00540 #ifdef DEBUG
00541                debug_->debug("Node %x: Send to Robot\n", radio().id());
00542 #endif
00543                //int dummyDest = 0;
00544                //send_to_robot( dummyDest ); 
00545                }   
00546 #ifdef DEBUG           
00547           else
00548                debug_->debug("Node %x: destination node was in my cluster. Message delivered\n", radio().id());
00549 #endif
00550      }
00551 
00552 template<typename OsModel_P,
00553      typename Radio_P,
00554      typename Neighbor_Discovery_P,
00555      typename Cluster_P>
00556      void EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00557      arriving_robot( uint8_t event, node_id_t from, uint8_t len, uint8_t* data ) {
00558                if( ( event & nb_t::NEW_PAYLOAD_BIDI ) != 0 )
00559                {
00560                     if( *data )
00561                     {
00562                          has_roomba_neighbor = true;
00563                          roomba_id = from;
00564 
00565                          if( has_msg )
00566                          {
00567                          //   send_message();
00568                          }
00569                     }
00570                }
00571           }
00572 
00573 template<typename OsModel_P,
00574      typename Radio_P,
00575      typename Neighbor_Discovery_P,
00576      typename Cluster_P>
00577     void
00578     EndToEndCommunication<OsModel_P, Radio_P, Neighbor_Discovery_P, Cluster_P>::
00579     print_statistics (){
00580           debug().debug("PRINTING METRICS OF NODE %x\n", radio().id());
00581           debug().debug("RX_total = %i\n; RX_childs = %i\n; RX_highways = %i\n; FW_childs = %i\n; FW_highways = %i\n; TX_neigh = %i\n; TX_cluster_head = %i\n; TX_highways = %i\n",
00582                     RX_total, RX_childs, RX_highways, FW_childs, FW_highways, TX_neigh, TX_cluster_head, TX_highways);
00583      
00584      }
00585 
00586      
00587 
00588 }
00589 #endif
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines