Wiselib
wiselib.testing/algorithms/routing/controlled_topology_tree/controlled_topology_tree_routing.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_ROUTING_CONTROLLEDTOPOLOGYTREEROUTING_H__
00020 #define __ALGORITHMS_ROUTING_CONTROLLEDTOPOLOGYTREEROUTING_H__
00021 
00022 #include "util/pstl/algorithm.h"
00023 #include "util/base_classes/routing_base.h"
00024 #include "algorithms/routing/tree/tree_broadcast_message.h"
00025 #include "algorithms/routing/tree/tree_routing_message.h"
00026 
00027 namespace wiselib
00028 {
00029 
00038    template<typename OsModel_P,
00039             typename Timer_P = typename OsModel_P::Timer,
00040             typename Radio_P = typename OsModel_P::Radio,
00041             typename Debug_P = typename OsModel_P::Debug,
00042             typename OsModel_P::size_t MAX_NEIGHBORS=32>
00043    class ControlledTopologyTreeRouting
00044       : public RoutingBase<OsModel_P, Radio_P>
00045    {
00046    public:
00047       typedef OsModel_P OsModel;
00048       typedef Timer_P Timer;
00049       typedef Radio_P Radio;
00050       typedef Debug_P Debug;
00051 
00052       typedef ControlledTopologyTreeRouting<OsModel, Timer, Radio, Debug, MAX_NEIGHBORS> self_type;
00053 
00054       typedef typename Radio::node_id_t node_id_t;
00055       typedef typename Radio::size_t size_t;
00056       typedef typename Radio::block_data_t block_data_t;
00057       typedef uint8_t message_id_t;
00058 
00059       typedef typename Timer::millis_t millis_t;
00060 
00061       typedef TreeBroadcastMessage<OsModel, Radio> BroadcastMessage;
00062       typedef TreeRoutingMessage<OsModel, Radio> RoutingMessage;
00063 
00064       typedef vector_static<OsModel,node_id_t,MAX_NEIGHBORS> Neighbors;
00065 
00066       // --------------------------------------------------------------------
00067       enum ErrorCodes
00068       {
00069          SUCCESS = OsModel::SUCCESS,
00070          ERR_UNSPEC = OsModel::ERR_UNSPEC,
00071          ERR_NOTIMPL = OsModel::ERR_NOTIMPL,
00072          ERR_HOSTUNREACH = OsModel::ERR_HOSTUNREACH
00073       };
00074       // --------------------------------------------------------------------
00075       enum SpecialNodeIds {
00076          BROADCAST_ADDRESS = Radio_P::BROADCAST_ADDRESS, 
00077          NULL_NODE_ID      = Radio_P::NULL_NODE_ID      
00078       };
00079       // --------------------------------------------------------------------
00080       enum Restrictions {
00081          MAX_MESSAGE_LENGTH = Radio_P::MAX_MESSAGE_LENGTH - RoutingMessage::PAYLOAD_POS  
00082       };
00083       // --------------------------------------------------------------------
00084 
00087       ControlledTopologyTreeRouting();
00088       ~ControlledTopologyTreeRouting();
00090 
00093 
00113       void enable( void );
00118       void disable( void );
00123       inline void set_sink( bool sink );
00125 
00128 
00131       void send( node_id_t receiver, size_t len, block_data_t *data );
00133 
00136 
00144       void timer_elapsed( void *userdata );
00146 
00149 
00154       void receive( node_id_t from, size_t len, block_data_t *data );
00156 
00157       void set_topology(Neighbors *t=0){
00158         topology_=t;
00159       }
00160 
00161       Neighbors *topology(){
00162         return topology_;
00163       }
00164 
00165       node_id_t parent() const {
00166         return parent_;
00167       }
00168 
00169 #ifdef DEBUG
00170       void init( Radio& radio, Timer& timer, Debug& debug ) {
00171          radio_ = &radio;
00172          timer_ = &timer;
00173          debug_ = &debug;
00174       }
00175 #else
00176       void init( Radio& radio, Timer& timer) {
00177          radio_ = &radio;
00178          timer_ = &timer;
00179       }
00180 #endif
00181       
00182       void destruct() {
00183       }
00184       
00185    private:
00186       Radio& radio()
00187       { return *radio_; }
00188       
00189       Timer& timer()
00190       { return *timer_; }
00191       
00192 #ifdef DEBUG
00193       Debug& debug()
00194       { return *debug_; }
00195 #endif
00196      
00197       Radio * radio_;
00198       Timer * timer_;
00199 #ifdef DEBUG
00200       Debug * debug_;
00201 #endif
00202 
00205       enum TreeRoutingMsgIds {
00206          TrMsgIdBroadcast = 209, 
00207          TrMsgIdRouting   = 210  
00208       };
00209 
00210       enum TreeRoutingState {
00211          TrGateway,
00212          TrConnected,
00213          TrUnconnected
00214       };
00215 
00216       TreeRoutingState state_;
00218       millis_t work_period_;
00219       node_id_t parent_;
00220       uint8_t hops_;
00221       Neighbors *topology_;
00222       bool enabled;
00223    };
00224    // -----------------------------------------------------------------------
00225    // -----------------------------------------------------------------------
00226    // -----------------------------------------------------------------------
00227    template<typename OsModel_P,
00228             typename Timer_P,
00229             typename Radio_P,
00230             typename Debug_P,
00231             typename OsModel_P::size_t MAX_NEIGHBORS>
00232    ControlledTopologyTreeRouting<OsModel_P, Timer_P, Radio_P, Debug_P, MAX_NEIGHBORS>::
00233    ControlledTopologyTreeRouting()
00234       : state_         ( TrUnconnected ),
00235          work_period_  ( 5000 ),
00236          parent_       ( Radio::NULL_NODE_ID ),
00237          topology_      ( 0 ),
00238          enabled(false)
00239    {
00240       // Attention! Depending on where an instance is created, there may be not
00241       // all information available. E.g., if a ControlledTopologyTreeRouting object is a global
00242       // one, accessing OsModel::get_firmware_instance() may fail because the
00243       // firmware instance may not exist yet.
00244       //
00245       // Hence, only /private assignments/ are allowed to be done here!
00246    }
00247    // -----------------------------------------------------------------------
00248    template<typename OsModel_P,
00249             typename Timer_P,
00250             typename Radio_P,
00251             typename Debug_P,
00252             typename OsModel_P::size_t MAX_NEIGHBORS>
00253    ControlledTopologyTreeRouting<OsModel_P, Timer_P, Radio_P, Debug_P, MAX_NEIGHBORS>::
00254    ~ControlledTopologyTreeRouting()
00255    {
00256 #ifdef DEBUG
00257       debug().debug( "ControlledTopologyTreeRouting: Destroyed\n" );
00258 #endif
00259    }
00260    // -----------------------------------------------------------------------
00261    template<typename OsModel_P,
00262             typename Timer_P,
00263             typename Radio_P,
00264             typename Debug_P,
00265             typename OsModel_P::size_t MAX_NEIGHBORS>
00266    void
00267    ControlledTopologyTreeRouting<OsModel_P, Timer_P, Radio_P, Debug_P, MAX_NEIGHBORS>::
00268    enable( void )
00269    {
00270       enabled=true;
00271 //       work_period_  = 15000;
00272 
00273       //radio().enable_radio();
00274       radio().template reg_recv_callback<self_type, &self_type::receive>( this );
00275 #ifdef DEBUG
00276       debug().debug( "ControlledTopologyTreeRouting: Boot for %i\n", radio().id() );
00277 #endif
00278       if ( state_ == TrGateway )
00279       {
00280          parent_ = radio().id();
00281          hops_ = 0;
00282 #ifdef DEBUG
00283          debug().debug( "ControlledTopologyTreeRouting: Start as sink/gateway\n" );
00284 #endif
00285       }
00286       else
00287       {
00288          parent_ = Radio::NULL_NODE_ID;
00289          hops_   = 0xff;
00290 #ifdef DEBUG
00291          debug().debug( "ControlledTopologyTreeRouting: Start as ordinary node\n" );
00292 #endif
00293       }
00294 
00295       timer().template set_timer<self_type, &self_type::timer_elapsed>(
00296                                  work_period_, this, 0 );
00297    }
00298    // -----------------------------------------------------------------------
00299    template<typename OsModel_P,
00300             typename Timer_P,
00301             typename Radio_P,
00302             typename Debug_P,
00303             typename OsModel_P::size_t MAX_NEIGHBORS>
00304    void
00305    ControlledTopologyTreeRouting<OsModel_P, Timer_P, Radio_P, Debug_P, MAX_NEIGHBORS>::
00306    disable( void )
00307    {
00308       enabled=false;
00309 #ifdef DEBUG
00310       debug().debug( "ControlledTopologyTreeRouting: Should stop routing now...\n" );
00311 #endif
00312    }
00313    // -----------------------------------------------------------------------
00314    template<typename OsModel_P,
00315             typename Timer_P,
00316             typename Radio_P,
00317             typename Debug_P,
00318             typename OsModel_P::size_t MAX_NEIGHBORS>
00319    void
00320    ControlledTopologyTreeRouting<OsModel_P, Timer_P, Radio_P, Debug_P, MAX_NEIGHBORS>::
00321    set_sink( bool sink )
00322    {
00323       if ( sink )
00324          state_ = TrGateway;
00325       else
00326          state_ = TrUnconnected;
00327    }
00328    // -----------------------------------------------------------------------
00329    template<typename OsModel_P,
00330             typename Timer_P,
00331             typename Radio_P,
00332             typename Debug_P,
00333             typename OsModel_P::size_t MAX_NEIGHBORS>
00334    void
00335    ControlledTopologyTreeRouting<OsModel_P, Timer_P, Radio_P, Debug_P, MAX_NEIGHBORS>::
00336    send( node_id_t receiver, size_t len, block_data_t *data )
00337    {
00338       if(!enabled)
00339          return;
00340       if ( parent_ != Radio::NULL_NODE_ID )
00341       {
00342 #ifdef DEBUG
00343          debug().debug( "ControlledTopologyTreeRouting: Send to Gate over %i...\n", parent_ );
00344 #endif
00345          RoutingMessage message( TrMsgIdRouting, radio().id( ) );
00346          message.set_payload( len, data );
00347          radio().send( parent_, message.buffer_size(), (uint8_t*)&message );
00348       }
00349 #ifdef DEBUG
00350       else
00351          debug().debug( "ControlledTopologyTreeRouting: Not Connected. Cannot send.\n" );
00352 #endif
00353    }
00354    // -----------------------------------------------------------------------
00355    template<typename OsModel_P,
00356             typename Timer_P,
00357             typename Radio_P,
00358             typename Debug_P,
00359             typename OsModel_P::size_t MAX_NEIGHBORS>
00360    void
00361    ControlledTopologyTreeRouting<OsModel_P, Timer_P, Radio_P, Debug_P, MAX_NEIGHBORS>::
00362    timer_elapsed( void* userdata )
00363    {
00364       if(!enabled)
00365          return;
00366 #ifdef DEBUG
00367       debug().debug( "ControlledTopologyTreeRouting: Execute Task 'ControlledTopologyTreeRouting' at %i\n", radio().id() );
00368 #endif
00369 
00370       switch ( state_ )
00371       {
00372          case TrGateway:
00373          case TrConnected:
00374          {
00375             BroadcastMessage message( TrMsgIdBroadcast, hops_, parent_ );
00376             radio().send( Radio::BROADCAST_ADDRESS, message.buffer_size(), (uint8_t*)&message );
00377             break;
00378          }
00379          case TrUnconnected:
00380 #ifdef DEBUG
00381             debug().debug( "ControlledTopologyTreeRouting: Not connected. Waiting for FloodingMessage\n" );
00382 #endif
00383             break;
00384 #ifdef DEBUG
00385          default:
00386             debug().debug( "ControlledTopologyTreeRouting: Warning! Should not be reached!\n" );
00387 #endif
00388       }
00389 
00390       timer().template set_timer<self_type, &self_type::timer_elapsed>(
00391                                  work_period_, this, 0 );
00392    }
00393    // -----------------------------------------------------------------------
00394    template<typename OsModel_P,
00395             typename Timer_P,
00396             typename Radio_P,
00397             typename Debug_P,
00398             typename OsModel_P::size_t MAX_NEIGHBORS>
00399    void
00400    ControlledTopologyTreeRouting<OsModel_P, Timer_P, Radio_P, Debug_P, MAX_NEIGHBORS>::
00401    receive( node_id_t from, size_t len, block_data_t *data )
00402    {
00403       if(!enabled)
00404          return;
00405 #ifdef DEBUG
00406      //debug().debug( "ControlledTopologyTreeRouting: Received t %i l %i f %i\n", (block_data_t)*data, len, from );
00407 #endif
00408 
00409       if ( from == radio().id() )
00410          return;
00411 
00412       message_id_t msg_id = *data;
00413 
00414       if ( msg_id == TrMsgIdBroadcast )
00415       {
00416        if(topology_&&find(topology_->begin(),topology_->end(),from)==topology_->end())
00417           return;
00418          BroadcastMessage *message = reinterpret_cast<BroadcastMessage*>(data);
00419          if ( message->hops() + 1 < hops_ )
00420          {
00421             hops_ = message->hops() + 1;
00422             parent_ = from;
00423             state_ = TrConnected;
00424 #ifdef DEBUG
00425             debug().debug( "ControlledTopologyTreeRouting:   -> Updated hop count to %i (at %i with p %i)\n",
00426                hops_, radio().id(), parent_ );
00427 #endif
00428          }
00429       }
00430       else if ( msg_id == TrMsgIdRouting )
00431       {
00432         if ( state_ == TrGateway )
00433         {
00434            RoutingMessage *message = reinterpret_cast<RoutingMessage*>(data);
00435            notify_receivers( message->source(), message->payload_size(), message->payload() );
00436 #ifdef DEBUG
00437            debug().debug( "ControlledTopologyTreeRouting: Routing message at Gate from %i\n", message->source() );
00438 #endif
00439         }
00440         else if ( parent_ != Radio::NULL_NODE_ID )
00441         {
00442            radio().send( parent_, len, data );
00443 #ifdef DEBUG
00444            debug().debug( "ControlledTopologyTreeRouting: Forward routing message at %i to %i\n", radio().id(), parent_ );
00445 #endif
00446         }
00447       }
00448    }
00449 
00450 }
00451 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines