Wiselib
|
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