Wiselib
wiselib.testing/algorithms/metrics/individual_link/individual_link_metrics.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_METRICS_INDIVIDUAL_LINK_METRICS_H__
00020 #define __ALGORITHMS_METRICS_INDIVIDUAL_LINK_METRICS_H__
00021 
00022 #include "algorithms/metrics/individual_link/individual_link_metrics_message.h"
00023 
00024 #define DEBUG_INDIVIDUAL_LINK_METRICS
00025 
00026 namespace wiselib
00027 {
00028 
00034    template<typename OsModel_P,
00035             typename Radio_P,
00036             typename Timer_P,
00037             typename Clock_P,
00038             typename Debug_P,
00039             typename DataItemContainer_P>
00040    class IndividualLinkMetrics
00041    {
00042    public:
00043       enum {
00044          MESSAGE_SIZE = 40
00045       };
00046 
00047       typedef OsModel_P OsModel;
00048       typedef Radio_P Radio;
00049       typedef Timer_P Timer;
00050       typedef Clock_P Clock;
00051       typedef Debug_P Debug;
00052       typedef DataItemContainer_P DataItemContainer;
00053 
00054       typedef typename DataItemContainer::iterator DataItemContainerIterator;
00055 
00056       typedef IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P> self_type;
00057       typedef IndividualLinkMetricsMessage<OsModel, Radio, MESSAGE_SIZE> LinkMessage;
00058 
00059       typedef typename Radio::node_id_t node_id_t;
00060       typedef typename Radio::size_t size_t;
00061       typedef typename Radio::block_data_t block_data_t;
00062 
00063       typedef typename Clock::time_t time_t;
00064 
00065       typedef typename Timer::millis_t millis_t;
00066       // --------------------------------------------------------------------
00067       enum ErrorCodes
00068       {
00069          SUCCESS = OsModel::SUCCESS,
00070          ERR_UNSPEC = OsModel::ERR_UNSPEC
00071       };
00072       // --------------------------------------------------------------------
00075       struct MetricsData
00076       {
00077          MetricsData(): total_sent(0), lost(0) {};
00078 
00079          uint16_t total_sent;
00080          uint16_t lost;
00081 
00082          DataItemContainer link_times;
00083       };
00085 
00088       IndividualLinkMetrics();
00089       ~IndividualLinkMetrics();
00091 
00094       int init( Radio_P& r, Timer_P& t, Clock_P& c, Debug_P& d);
00095       inline int init();
00096       inline int destruct( void );
00097       void start( node_id_t receiver, millis_t ti, uint16_t packets_to_send );
00099 
00102       MetricsData& metrics_data( void )
00103       { return metrics_data_; };
00105 
00108       void timer_elapsed( void *userdata );
00110 
00113       void receive( node_id_t from, size_t len, block_data_t *data );
00115 
00116    private:
00117 
00118       Radio& radio()
00119       { return *radio_; }
00120 
00121       Timer& timer()
00122       { return *timer_; }
00123 
00124       Clock& clock()
00125       { return *clock_; }
00126 
00127       Debug& debug()
00128       { return *debug_; }
00129 
00132       enum IndividualLinkMetricsMsgIds {
00133          LinkMetricsRequest = 143,
00134          LinkMetricsReply   = 144
00135       };
00136 
00137       MetricsData metrics_data_;
00138 
00139       node_id_t receiver_;
00140       millis_t transmit_interval_;
00141       uint16_t packets_to_send_;
00142 
00143       typename Radio::self_pointer_t radio_;
00144       typename Timer::self_pointer_t timer_;
00145       typename Clock::self_pointer_t clock_;
00146       typename Debug::self_pointer_t debug_;
00147 
00148       bool ack_;
00149       time_t sent_;
00150    };
00151    // -----------------------------------------------------------------------
00152    // -----------------------------------------------------------------------
00153    // -----------------------------------------------------------------------
00154    template<typename OsModel_P,
00155             typename Radio_P,
00156             typename Timer_P,
00157             typename Clock_P,
00158             typename Debug_P,
00159             typename DataItemContainer_P>
00160    IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P>::
00161    IndividualLinkMetrics()
00162       : receiver_     ( Radio::NULL_NODE_ID ),
00163          transmit_interval_ ( 100 ),
00164          packets_to_send_   ( 0 ),
00165          radio_(0),
00166          timer_(0),
00167          clock_(0),
00168          debug_(0)
00169    {};
00170    // -----------------------------------------------------------------------
00171    template<typename OsModel_P,
00172             typename Radio_P,
00173             typename Timer_P,
00174             typename Clock_P,
00175             typename Debug_P,
00176             typename DataItemContainer_P>
00177    IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P>::
00178    ~IndividualLinkMetrics()
00179    {
00180 #ifdef DEBUG_INDIVIDUAL_LINK_METRICS
00181       debug().debug( "IndividualLinkMetrics Destroyed\n" );
00182 #endif
00183    };
00184    // -----------------------------------------------------------------------
00185    template<typename OsModel_P,
00186             typename Radio_P,
00187             typename Timer_P,
00188             typename Clock_P,
00189             typename Debug_P,
00190             typename DataItemContainer_P>
00191    int
00192    IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P>::
00193    init( Radio_P& r, Timer_P& t, Clock_P& c, Debug_P& d)
00194    {
00195       radio_ = &r;
00196       timer_ = &t;
00197       clock_ = &c;
00198       debug_ = &d;
00199 
00200 #ifdef DEBUG_INDIVIDUAL_LINK_METRICS
00201       debug().debug( "IndividualLinkMetrics Boots for %i\n", radio().id() );
00202 #endif
00203       radio().enable_radio();
00204       radio().template reg_recv_callback<self_type, &self_type::receive>(this);
00205 
00206       return SUCCESS;
00207    }
00208    // -----------------------------------------------------------------------
00209    template<typename OsModel_P,
00210             typename Radio_P,
00211             typename Timer_P,
00212             typename Clock_P,
00213             typename Debug_P,
00214             typename DataItemContainer_P>
00215    int
00216    IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P>::
00217    init( void )
00218    {
00219       return ERR_UNSPEC;
00220    }
00221    // -----------------------------------------------------------------------
00222    template<typename OsModel_P,
00223             typename Radio_P,
00224             typename Timer_P,
00225             typename Clock_P,
00226             typename Debug_P,
00227             typename DataItemContainer_P>
00228    int
00229    IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P>::
00230    destruct( void )
00231    {
00232       radio().disable_radio();
00233       return SUCCESS;
00234    }
00235    // -----------------------------------------------------------------------
00236    template<typename OsModel_P,
00237             typename Radio_P,
00238             typename Timer_P,
00239             typename Clock_P,
00240             typename Debug_P,
00241             typename DataItemContainer_P>
00242    void
00243    IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P>::
00244    start( node_id_t receiver, millis_t ti, uint16_t packets_to_send )
00245    {
00246 #ifdef DEBUG_INDIVIDUAL_LINK_METRICS
00247       debug().debug( "Start IndividualLinkMetrics: %i -> %i \n", radio().id(), receiver );
00248 #endif
00249       receiver_          = receiver;
00250       transmit_interval_ = ti;
00251       packets_to_send_   = packets_to_send;
00252 
00253       metrics_data_.link_times = DataItemContainer();
00254       metrics_data_.total_sent = 1;
00255       metrics_data_.lost = 0;
00256       metrics_data_.link_times.clear();
00257 
00258       ack_ = false;
00259       sent_ = clock().time();
00260       LinkMessage req( LinkMetricsRequest );
00261       radio().send( receiver_, req.buffer_size(), (uint8_t*)&req );
00262 
00263       timer().template set_timer<self_type, &self_type::timer_elapsed>(
00264                transmit_interval_, this, 0 );
00265    }
00266    // -----------------------------------------------------------------------
00267    template<typename OsModel_P,
00268             typename Radio_P,
00269             typename Timer_P,
00270             typename Clock_P,
00271             typename Debug_P,
00272             typename DataItemContainer_P>
00273    void
00274    IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P>::
00275    timer_elapsed( void *userdata )
00276    {
00277       if ( !ack_ )
00278          metrics_data_.lost++;
00279 
00280       if ( metrics_data_.total_sent == packets_to_send_ )
00281       {
00282 #ifdef DEBUG_INDIVIDUAL_LINK_METRICS
00283       debug().debug( "IndividualLinkMetrics done\n" );
00284 #endif
00285          return;
00286       }
00287 
00288       LinkMessage req( LinkMetricsRequest );
00289       ack_ = false;
00290       sent_ = clock().time();
00291 #ifdef DEBUG_INDIVIDUAL_LINK_METRICS
00292       debug().debug( "+\n" );
00293 #endif
00294       radio().send( receiver_, req.buffer_size(), (uint8_t*)&req );
00295       metrics_data_.total_sent++;
00296 
00297       timer().template set_timer<self_type, &self_type::timer_elapsed>(
00298                transmit_interval_, this, 0 );
00299    }
00300    // -----------------------------------------------------------------------
00301    template<typename OsModel_P,
00302             typename Radio_P,
00303             typename Timer_P,
00304             typename Clock_P,
00305             typename Debug_P,
00306             typename DataItemContainer_P>
00307    void
00308    IndividualLinkMetrics<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P, DataItemContainer_P>::
00309    receive( node_id_t from, size_t len, block_data_t *data )
00310    {
00311       uint8_t msg_id = *data;
00312       if ( msg_id == LinkMetricsRequest )
00313       {
00314          LinkMessage reply( LinkMetricsReply );
00315          radio().send( from, reply.buffer_size(), (uint8_t*)&reply );
00316       }
00317       else if ( msg_id == LinkMetricsReply )
00318       {
00319          ack_ = true;
00320          time_t now = clock().time();
00321          time_t duration = now - sent_;
00322          metrics_data_.link_times.push_back( duration );
00323 #ifdef DEBUG_INDIVIDUAL_LINK_METRICS
00324       debug().debug( "#\n" );
00325 #endif
00326 #ifdef DEBUG_INDIVIDUAL_LINK_METRICS
00327 //       debug().debug( "now is %i, sent is %i, dur is %i, size is %i\n", now, sent_, duration, metrics_data_.link_times.size() );
00328 #endif
00329       }
00330    }
00331 
00332 }
00333 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines