Wiselib
wiselib.testing/algorithms/synchronization/hrts/hrts_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_TPSN_SYNCHRONIZATION_H__
00020 #define __ALGORITHMS_SYNCHRONIZATION_TPSN_SYNCHRONIZATION_H__
00021 
00022 #include "algorithms/synchronization/hrts/hrts_synchronization_message.h"
00023 #include "algorithms/neighborhood_discovery/echo.h"
00024 #include "util/pstl/vector_static.h"
00025 
00026 #define DEBUG_TPSN_SYNCHRONIZATION
00027 #define DEBUG_TPSN_SYNCHRONIZATION_ISENSE
00028 // #define DEBUG_TPSN_SYNCHRONIZATION_SHAWN
00029 
00030 namespace wiselib
00031 {
00032 
00038    template<typename OsModel_P,
00039             typename Radio_P = typename OsModel_P::Radio,
00040             typename Debug_P = typename OsModel_P::Debug,
00041             typename Clock_P = typename OsModel_P::Clock,
00042             uint16_t MAX_NODES = 32>
00043    class TpsnSynchronization
00044    {
00045    public:
00046       typedef OsModel_P OsModel;
00047       typedef Radio_P Radio;
00048       typedef Debug_P Debug;
00049       typedef Clock_P Clock;
00050 
00051       typedef typename OsModel_P::Timer Timer;
00052       typedef Echo<OsModel, Radio, Timer, Debug> Neighborhood;
00053 
00054       typedef TpsnSynchronization<OsModel, Radio, Debug, Clock, MAX_NODES> self_type;
00055       typedef TpsnSynchronizationMessage<OsModel, Radio, Clock> SynchronizationMessage;
00056 
00057       typedef typename Radio::node_id_t node_id_t;
00058       typedef typename Radio::size_t size_t;
00059       typedef typename Radio::block_data_t block_data_t;
00060       static const uint8_t NODE_ID_SIZE = sizeof( node_id_t );
00061 
00062       typedef typename Timer::millis_t millis_t;
00063 
00064       typedef typename Clock::time_t time_t;
00065       static const uint8_t TIME_SIZE = sizeof( time_t );
00066 
00070 
00073       TpsnSynchronization();
00074       ~TpsnSynchronization();
00076 
00079       void enable( void );
00080       void disable( void );
00081       inline void set_root( void )
00082       { level_ = 0; }
00084 
00087       void timer_elapsed( void *userdata );
00089 
00092       void receive( node_id_t from, size_t len, block_data_t *data );
00094 
00095       inline void set_root_startup_time( millis_t root_startup_time )
00096       { root_startup_time_ = root_startup_time; };
00097 
00098       inline void set_tree_construction_time( millis_t tree_construction_time )
00099       { tree_construction_time_ = tree_construction_time; };
00100 
00101       inline void set_random_interval_time( millis_t random_interval_time )
00102       { random_interval_time_ = random_interval_time; };
00103 
00104       void init( Radio& radio, Timer& timer, Debug& debug, Clock& clock ) {
00105          radio_ = &radio;
00106          timer_ = &timer;
00107          debug_ = &debug;
00108          clock_ = &clock;
00109          neighborhood_.init(radio_, clock_, timer_, debug_);
00110       }
00111       
00112       void destruct() {
00113       }
00114       
00115    private:
00116       Radio& radio()
00117       { return *radio_; }
00118       
00119       Timer& timer()
00120       { return *timer_; }
00121       
00122       Debug& debug()
00123       { return *debug_; }
00124       
00125       Clock& clock()
00126       { return *clock_; }
00127      
00128       Radio * radio_;
00129       Timer * timer_;
00130       Debug * debug_;
00131       Clock * clock_;
00132 
00133       void send_sync_pulse();
00134 
00137       // TODO: standarize msg ids
00138       enum TpsnSynchronizationMsgIds {
00139          TpsnMsgIdBeginSync = 230, 
00140          TpsnMsgIdReply = 231, 
00141          TpsnMsgIdDiffSync = 232, 
00142       };
00143 
00144       SynchronizationMessage message;
00145       Neighborhood neighborhood_;
00146 
00147       int8_t level_;
00148       bool built_tree_;
00149       time_t t1_;
00150       millis_t timeout_;
00151       bool propagated_;
00152    };
00153    // -----------------------------------------------------------------------
00154    // -----------------------------------------------------------------------
00155    // -----------------------------------------------------------------------
00156    template<typename OsModel_P,
00157             typename Radio_P,
00158             typename Debug_P,
00159             typename Clock_P,
00160             uint16_t MAX_NODES>
00161    TpsnSynchronization<OsModel_P, Radio_P, Debug_P, Clock_P, MAX_NODES>::
00162    TpsnSynchronization()
00163       : level_ ( -1 ),
00164       timeout_ ( 1000 ),
00165       propagated_ ( false )
00166    {};
00167    // -----------------------------------------------------------------------
00168    template<typename OsModel_P,
00169             typename Radio_P,
00170             typename Debug_P,
00171             typename Clock_P,
00172             uint16_t MAX_NODES>
00173    TpsnSynchronization<OsModel_P, Radio_P, Debug_P, Clock_P, MAX_NODES>::
00174    ~TpsnSynchronization()
00175    {
00176 #ifdef DEBUG_TPSN_SYNCHRONIZATION
00177       debug().debug( "TpsnSynchronization Destroyed\n" );
00178 #endif
00179    };
00180    // -----------------------------------------------------------------------
00181    template<typename OsModel_P,
00182             typename Radio_P,
00183             typename Debug_P,
00184             typename Clock_P,
00185             uint16_t MAX_NODES>
00186    void
00187    TpsnSynchronization<OsModel_P, Radio_P, Debug_P, Clock_P, MAX_NODES>::
00188    enable( void )
00189    {
00190       neighborhood_.enable();
00191       if ( level_ != -1 and  not propagated_ )
00192       {
00193 #ifdef DEBUG_TPSN_SYNCHRONIZATION
00194    debug().debug( "%i: TpsnSynchronization Boots as Root\n", radio().id() );
00195 #endif
00196          start_propagation();
00197          timer().template set_timer<self_type, &self_type::enable>(
00198                            timeout_, this, 0 );
00199       }
00200    }
00201    // -----------------------------------------------------------------------
00202    template<typename OsModel_P,
00203             typename Radio_P,
00204             typename Debug_P,
00205             typename Clock_P,
00206             uint16_t MAX_NODES>
00207    void
00208    TpsnSynchronization<OsModel_P, Radio_P, Debug_P, Clock_P, MAX_NODES>::
00209    disable( void )
00210    {
00211 #ifdef DEBUG_TPSN_SYNCHRONIZATION
00212       debug().debug( "%i: Called TpsnSynchronization::disable\n", radio().id() );
00213 #endif
00214    }
00215    // -----------------------------------------------------------------------
00216    template<typename OsModel_P,
00217             typename Radio_P,
00218             typename Debug_P,
00219             typename Clock_P,
00220             uint16_t MAX_NODES>
00221    void
00222    TpsnSynchronization<OsModel_P, Radio_P, Debug_P, Clock_P, MAX_NODES>::
00223    receive( node_id_t from, size_t len, block_data_t *data )
00224    {
00225       time_t t = clock().time();
00226       if ( from == radio().id() )
00227          return;
00228       uint8_t msg_id = *data;
00229       message = *((Synchronization *) data);
00230 #ifdef DEBUG_TPSN_SYNCHRONIZATION
00231    debug().debug( "%i: Received message from %i and msg_id is %d\n", radio().id(), from, msg_id );
00232 #endif
00233       if ( msg_id == TpsnMsgIdBeginSync )
00234       {
00235          uint8_t level = *data;
00236          if ( level_ != -1 and level_ > message.level )
00237             return;
00238          t1 = message.t1();
00239          if (message.receiver == radio().id()) {
00240             message.set_msg_id(TpsnMsgIdReply);
00241             message.set_t1(t);
00242             message.set_t2(clock().time());
00243             radio().send( from, sizeof( SynchronizationMessage ), (uint8_t*)&message );
00244          }
00245       }
00246       else if ( msg_id == TpsnMsgIdReply )
00247       {
00248          time_t d2 = ((message.t1() - t1) - (t - message.t2()))/2;
00249          message.set_msg_id(TpsnMsgIdDiffSync);
00250          message.set_t1(message.t1());
00251          message.set_t2(d2);
00252          radio().send( radio().BROADCAST_ADDRESS, sizeof( SynchronizationMessage ), (uint8_t*)&message );
00253       }
00254       else if ( msg_id == TpsnMsgIdDiffSync )
00255       {
00256          clock().set_time(clock_time()+message.t2()+message.t1()-t1);
00257       }
00258    }
00259    // -----------------------------------------------------------------------
00260    template<typename OsModel_P,
00261             typename Radio_P,
00262             typename Debug_P,
00263             typename Clock_P,
00264             uint16_t MAX_NODES>
00265    void
00266    TpsnSynchronization<OsModel_P, Radio_P, Debug_P, Clock_P, MAX_NODES>::
00267    start_propagation( )
00268    {
00269       if (neighborhood_.neighbors_.empty())
00270          propagated_ = true;
00271       else {
00272          message.set_msg_id(TpsnMsgIdBeginSync);
00273          message.set_receiver(neighborhood_.neighbors_[0]);
00274          t1 = clock().time();
00275          message.set_t1( t1 );
00276          radio().send( radio().BROADCAST_ADDRESS, sizeof( SynchronizationMessage ), (uint8_t*)&message );
00277       }
00278    }
00279 }
00280 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines