Wiselib
wiselib.testing/algorithms/synchronization/lts/lts_synchronization.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_SYNCHRONIZATION_LTS_SYNCHRONIZATION_H__
00020 #define __ALGORITHMS_SYNCHRONIZATION_LTS_SYNCHRONIZATION_H__
00021 
00022 #include "algorithms/synchronization/lts/lts_synchronization_message.h"
00023 #include "algorithms/graph/ddfs/ddfs_graph.h"
00024 #include "util/delegates/delegate.hpp"
00025 
00026 #define DEBUG_LTS_SYNCHRONIZATION
00027 // #define DEBUG_LTS_SYNCHRONIZATION_SHAWN
00028 namespace wiselib
00029 {
00030 
00031    template<typename OsModel_P,
00032             typename Radio_P = typename OsModel_P::Radio,
00033             typename Clock_P = typename OsModel_P::Clock,
00034             typename Debug_P = typename OsModel_P::Debug,
00035             typename NeighborhoodDiscovery_P = typename wiselib::DdfsGraph<OsModel_P, Radio_P, Debug_P, MAX_NODES>,
00036             uint16_t MAX_NODES = 32>
00037    class LtsSynchronization : public synchronizationBase<OsModel_P>
00038    {
00039    public:
00040       typedef OsModel_P OsModel;
00041       typedef Radio_P Radio;
00042       typedef Debug_P Debug;
00043       typedef Clock_P Clock;
00044       typedef typename Clock::time_t time_t;
00045       typedef NeighborhoodDiscovery_P NeighborhoodDiscovery;
00046 
00047       typedef LtsSynchronization<OsModel, Radio, Debug, Clock, MAX_NODES, Neighborhood> self_type;
00048       typedef LtsSynchronizationMessage<OsModel, Radio, time_t> SynchronizationMessage;
00049 
00050       typedef typename Radio::node_id_t node_id_t;
00051       typedef typename Radio::size_t size_t;
00052       typedef typename Radio::block_data_t block_data_t;
00053 
00054       typedef delegate0<void> lts_delegate_t;
00055 
00056       static const uint8_t TIME_SIZE = sizeof( Time );
00057 
00060       LtsSynchronization();
00061       ~LtsSynchronization();
00063 
00066       void enable( void );
00067       void disable( void );
00068       inline void set_root( bool root )
00069       { root_ = root; }
00071 
00074       void receive( node_id_t from, size_t len, block_data_t *data );
00076 
00077       time_t time()
00078       {
00079          return clock().time();
00080       }
00081 
00082       void start_synchronization();
00083       
00084       void destruct()
00085       {}
00086       
00087    private:
00088       Radio& radio()
00089       { return *radio_; }
00090       
00091       Clock& clock()
00092       { return *clock_; }
00093       
00094       Debug& debug()
00095       { return *debug_; }
00096       
00097       NeighborhoodDiscovery& neighborhood_discovery()
00098       { return *neighborhood_discovery_; }
00099       
00100       Radio * radio_;
00101       Clock * clock_;
00102       Debug * debug_;
00103       NeighborhoodDiscovery * neighborhood_discovery_;
00104 
00107       enum LtsSynchronizationMsgIds {
00108          LtsMsgIdSynchronizationPulse = 150, 
00109          LtsMsgIdAcknowledgement = 151, 
00110          LtsMsgIdOffset = 152, 
00111       };
00112 
00113       bool root_;
00114 
00115       SynchronizationMessage synchronizationMessage;
00116 
00117    };
00118    // -----------------------------------------------------------------------
00119    // -----------------------------------------------------------------------
00120    // -----------------------------------------------------------------------
00121    template<typename OsModel_P,
00122             typename Radio_P,
00123             typename Clock_P,
00124             typename Debug_P,
00125             typename NeighborhoodDiscovery_P,
00126             uint16_t MAX_NODES>
00127    LtsSynchronization<OsModel_P, Radio_P, Clock_P, Debug_P, NeighborhoodDiscovery_P, MAX_NODES>::
00128    LtsSynchronization()
00129    {};
00130    // -----------------------------------------------------------------------
00131    template<typename OsModel_P,
00132             typename Radio_P,
00133             typename Clock_P,
00134             typename Debug_P,
00135             typename NeighborhoodDiscovery_P,
00136             uint16_t MAX_NODES>
00137    LtsSynchronization<OsModel_P, Radio_P, Clock_P, Debug_P, NeighborhoodDiscovery_P, MAX_NODES>::
00138    ~LtsSynchronization()
00139    {
00140 #ifdef DEBUG_LTS_SYNCHRONIZATION
00141       debug().debug( "LtsSynchronization Destroyed\n" );
00142 #endif
00143    };
00144    // -----------------------------------------------------------------------
00145    template<typename OsModel_P,
00146             typename Radio_P,
00147             typename Clock_P,
00148             typename Debug_P,
00149             typename NeighborhoodDiscovery_P,
00150             uint16_t MAX_NODES>
00151     void
00152     LtsSynchronization<OsModel_P, Radio_P, Clock_P, Debug_P, NeighborhoodDiscovery_P, MAX_NODES>::
00153     init ( Radio& radio, Clock& clock, Debug& debug, NeighborhoodDiscovery& neighborhood_discovery )
00154       {
00155          radio_ = &radio;
00156          clock_ = &clock;
00157          debug_ = &debug;
00158          neighborhood_discovery_ = &neighborhood_discovery;
00159 #ifdef DEBUG_LTS_SYNCHRONIZATION
00160          debug().debug( "LtsSynchronization Boots for %i\n", radio().id() );
00161 #endif
00162          radio().enable_radio();
00163          radio().template reg_recv_callback<self_type, &self_type::receive>( this );
00164          
00165          neighborhood_discovery_.set_root( root );
00166          neighborhood_discovery().template reg_finish_callback<self_type, &self_type::start_synchronization>( this );
00167          neighborhood_discovery_.reinit();
00168       }
00169    // -----------------------------------------------------------------------
00170    template<typename OsModel_P,
00171             typename Radio_P,
00172             typename Clock_P,
00173             typename Debug_P,
00174             typename NeighborhoodDiscovery_P,
00175             uint16_t MAX_NODES>
00176    void
00177    LtsSynchronization<OsModel_P, Radio_P, Clock_P, Debug_P, NeighborhoodDiscovery_P, MAX_NODES>::
00178    receive( node_id_t from, size_t len, block_data_t *data )
00179    {
00180       uint8_t msg_id = *data;
00181 #ifdef DEBUG_LTS_SYNCHRONIZATION
00182    debug().debug( "%i: Received %d message from %i\n", radio().id(), msg_id, from );
00183 #endif
00184       if ( msg_id == LtsMsgIdSynchronizationPulse )
00185       {
00186          synchronizationMessage.set_t2( clock().time() );
00187          SynchronizationMessage *msg = ( SynchronizationMessage * )data;
00188          synchronizationMessage.set_msg_id( LtsMsgIdAcknowledgement );
00189          synchronizationMessage.set_t1( msg->t1() );
00190          synchronizationMessage.set_t3( clock().time() );
00191          radio().send( from, 1 + 3*TIME_SIZE, (uint8_t*)&synchronizationMessage );
00192       }
00193       else if ( msg_id == LtsMsgIdAcknowledgement )
00194       {
00195          Time t4 = clock().time();
00196          SynchronizationMessage *msg = (SynchronizationMessage *)data;
00197          Time offset = ( msg->t2() + msg->t3() - msg->t1() - t4  )/2;
00198          synchronizationMessage.set_msg_id( LtsMsgIdOffset );
00199          synchronizationMessage.set_t1( offset );
00200          radio().send( from, 1 + TIME_SIZE, (uint8_t*)&synchronizationMessage );
00201       }
00202       else if ( msg_id == LtsMsgIdOffset ) {
00203          SynchronizationMessage *msg = (SynchronizationMessage *)data;
00204          clock().set_time( clock().time() + msg->t1() );
00205 #ifdef DEBUG_LTS_SYNCHRONIZATION_SHAWN
00206    debug().debug( "%i: My new time is %f\n", radio().id(), clock().time() + msg->t1() );
00207 #endif
00208          notify_listeners();
00209          start_synchronization();
00210       }
00211    }
00212    // -----------------------------------------------------------------------
00213    template<typename OsModel_P,
00214             typename Radio_P,
00215             typename Clock_P,
00216             typename Debug_P,
00217             typename NeighborhoodDiscovery_P,
00218             uint16_t MAX_NODES>
00219    void
00220    LtsSynchronization<OsModel_P, Radio_P, Clock_P, Debug_P, NeighborhoodDiscovery_P, MAX_NODES>::
00221    start_synchronization( )
00222    {
00223       // Send the synchronization pulse to all children
00224       synchronizationMessage.set_msg_id( LtsMsgIdSynchronizationPulse );
00225       for ( int i = 0; i < (int)neighbors_.children_.size(); ++i ) {
00226 #ifdef DEBUG_LTS_SYNCHRONIZATION
00227    debug().debug( "%i: Sending synch_pulse to %i\n", radio().id(), neighbors_.children_[i]  );
00228 #endif
00229          synchronizationMessage.set_t1( clock().time() );
00230          radio().send( neighbors_.children_[i], 1 + TIME_SIZE, (uint8_t*)&synchronizationMessage );
00231       }
00232    }
00233 }
00234 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines