Wiselib
wiselib.testing/algorithms/routing/static/static_routing_algorithm.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 __STATIC_ROUTING_ALGORITHM_H__
00020 #define __STATIC_ROUTING_ALGORITHM_H__
00021 
00022 #include "util/base_classes/routing_base.h"
00023 #include "static_routing_message.h"
00024 
00025 
00026 namespace wiselib
00027 {
00028 
00036    template<typename OsModel_P,
00037             typename RoutingTable_P,
00038             typename Radio_P = typename OsModel_P::Radio,
00039             typename Debug_P = typename OsModel_P::Debug>
00040    class StaticRoutingAlgorithm
00041       : public RoutingBase<OsModel_P, Radio_P>
00042    {
00043    public:
00044       typedef OsModel_P OsModel;
00045       typedef Radio_P Radio;
00046       typedef Debug_P Debug;
00047 
00048       typedef RoutingTable_P MapType;
00049       typedef typename MapType::iterator MapTypeIterator;
00050 
00051       typedef StaticRoutingAlgorithm<OsModel, MapType, Radio, Debug> self_type;
00052       typedef self_type* self_pointer_t;
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 typename Radio::message_id_t message_id_t;
00058 
00059       typedef StaticRoutingMessage<OsModel, Radio> Message;
00060       // --------------------------------------------------------------------
00061       enum ErrorCodes
00062       {
00063          SUCCESS = OsModel::SUCCESS,
00064          ERR_UNSPEC = OsModel::ERR_UNSPEC
00065       };
00066       // --------------------------------------------------------------------
00067       enum SpecialNodeIds
00068       {
00069          BROADCAST_ADDRESS = Radio_P::BROADCAST_ADDRESS, 
00070          NULL_NODE_ID      = Radio_P::NULL_NODE_ID      
00071       };
00072       // --------------------------------------------------------------------
00073       enum Restrictions
00074       {
00075          MAX_MESSAGE_LENGTH = Radio_P::MAX_MESSAGE_LENGTH - Message::PAYLOAD_POS  
00076       };
00077       // --------------------------------------------------------------------
00080       StaticRoutingAlgorithm();
00081       ~StaticRoutingAlgorithm();
00083 
00084       int init( Radio& radio, Debug& debug )
00085       {
00086          radio_ = &radio;
00087          debug_ = &debug;
00088          return SUCCESS;
00089       }
00090 
00091       int init();
00092       int destruct();
00093 
00096       int enable_radio( void );
00097       int disable_radio( void );
00099 
00102 
00104       int send( node_id_t receiver, size_t len, block_data_t *data );
00107       void receive( node_id_t from, size_t len, block_data_t *data );
00110       void add_hop(node_id_t from, node_id_t to);
00113       void remove_hop(node_id_t from);
00116       void set_route(node_id_t start, node_id_t end);
00119       typename Radio::node_id_t id()
00120       { return radio_->id(); }
00122 
00123    private:
00124       Radio& radio()
00125       { return *radio_; }
00126 
00127       Debug& debug()
00128       { return *debug_; }
00129 
00130       typename Radio::self_pointer_t radio_;
00131       typename Debug::self_pointer_t debug_;
00132 
00133       node_id_t route_start_;
00134       node_id_t route_end_;
00135 
00136       enum MessageIds
00137       {
00138          STATIC_ROUTING_ID = 222
00139       };
00140 
00141       int callback_id_;
00142 
00143       MapType hop_map_;
00144    };
00145    // -----------------------------------------------------------------------
00146    // -----------------------------------------------------------------------
00147    // -----------------------------------------------------------------------
00148    template<typename OsModel_P,
00149             typename RoutingTable_P,
00150             typename Radio_P,
00151             typename Debug_P>
00152    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00153    StaticRoutingAlgorithm()
00154       : callback_id_ ( 0 )
00155    {}
00156    // -----------------------------------------------------------------------
00157    template<typename OsModel_P,
00158             typename RoutingTable_P,
00159             typename Radio_P,
00160             typename Debug_P>
00161    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00162    ~StaticRoutingAlgorithm()
00163    {
00164 #ifdef ROUTING_STATIC_DEBUG
00165       debug().debug( "StaticRoutingAlgorithm:dtor\n" );
00166 #endif
00167    }
00168    // -----------------------------------------------------------------------
00169    template<typename OsModel_P,
00170             typename RoutingTable_P,
00171             typename Radio_P,
00172             typename Debug_P>
00173    int
00174    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00175    init( void )
00176    {
00177       hop_map_.clear();
00178       enable_radio();
00179       return SUCCESS;
00180    }
00181    // -----------------------------------------------------------------------
00182    template<typename OsModel_P,
00183             typename RoutingTable_P,
00184             typename Radio_P,
00185             typename Debug_P>
00186    int
00187    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00188    destruct( void )
00189    {
00190       return disable_radio();
00191    }
00192    // -----------------------------------------------------------------------
00193    template<typename OsModel_P,
00194             typename RoutingTable_P,
00195             typename Radio_P,
00196             typename Debug_P>
00197    int
00198    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00199    enable_radio( void )
00200    {
00201 #ifdef ROUTING_STATIC_DEBUG
00202       debug().debug( "StaticRoutingAlgorithm: Boot for %i\n", radio().id() );
00203 #endif
00204 
00205       radio().enable_radio();
00206       callback_id_ = radio().template reg_recv_callback<self_type, &self_type::receive>( this );
00207       return SUCCESS;
00208    }
00209    // -----------------------------------------------------------------------
00210    template<typename OsModel_P,
00211             typename RoutingTable_P,
00212             typename Radio_P,
00213             typename Debug_P>
00214    int
00215    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00216    disable_radio( void )
00217    {
00218 #ifdef ROUTING_STATIC_DEBUG
00219       debug().debug( "StaticRoutingAlgorithm: Disable\n" );
00220 #endif
00221 
00222       radio().unreg_recv_callback( callback_id_ );
00223       radio().disable();
00224       return SUCCESS;
00225    }
00226    // -----------------------------------------------------------------------
00227    template<typename OsModel_P,
00228             typename RoutingTable_P,
00229             typename Radio_P,
00230             typename Debug_P>
00231    int
00232    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00233    send( node_id_t destination, size_t len, block_data_t *data )
00234    {
00235       Message message;
00236       message.set_msg_id( STATIC_ROUTING_ID );
00237       message.set_source_id( radio().id() );
00238       message.set_destination( destination );
00239       message.set_payload( len, data );
00240 
00241       if(destination == route_end_ && route_start_ != radio_->id() )
00242       {
00243 #ifdef ROUTING_STATIC_DEBUG
00244       debug().debug( "StaticRoutingAlgorithm: node %d Send to %d over %d\n", radio().id(), destination, route_start_ );
00245 #endif
00246           radio().send( route_start_, message.buffer_size(), (block_data_t*)&message );
00247       }
00248       else if(destination == route_end_ && route_start_ == radio_->id() )
00249       {
00250          if ( hop_map_.find( radio().id()) == hop_map_.end() )
00251          {
00252             debug().debug( "FATAL send: no entry for %d\n", radio().id() );
00253             return ERR_UNSPEC;
00254          }
00255          radio().send( hop_map_[radio().id()], message.buffer_size(), (block_data_t*)&message );
00256       }
00257       else
00258       {
00259 #ifdef ROUTING_STATIC_DEBUG
00260       debug().debug( "StaticRoutingAlgorithm: node %d Send to %d\n", radio().id(), destination );
00261 #endif
00262           radio().send( destination, message.buffer_size(), (block_data_t*)&message );
00263       }
00264 
00265       return SUCCESS;
00266    }
00267    // -----------------------------------------------------------------------
00268    template<typename OsModel_P,
00269             typename RoutingTable_P,
00270             typename Radio_P,
00271             typename Debug_P>
00272    void
00273    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00274    add_hop( node_id_t from, node_id_t to  )
00275    {
00276        hop_map_[from] = to;
00277    }
00278    // -----------------------------------------------------------------------
00279    template<typename OsModel_P,
00280             typename RoutingTable_P,
00281             typename Radio_P,
00282             typename Debug_P>
00283    void
00284    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00285    remove_hop( node_id_t from )
00286    {
00287        hop_map_.erase(from);
00288    }
00289    // -----------------------------------------------------------------------
00290    template<typename OsModel_P,
00291             typename RoutingTable_P,
00292             typename Radio_P,
00293             typename Debug_P>
00294    void
00295    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00296    set_route( node_id_t start, node_id_t end )
00297    {
00298        route_start_ = start;
00299        route_end_ = end;
00300    }
00301    // -----------------------------------------------------------------------
00302    template<typename OsModel_P,
00303             typename RoutingTable_P,
00304             typename Radio_P,
00305             typename Debug_P>
00306    void
00307    StaticRoutingAlgorithm<OsModel_P, RoutingTable_P, Radio_P, Debug_P>::
00308    receive( node_id_t from, size_t len, block_data_t *data )
00309    {
00310       if ( from == radio().id() )
00311          return;
00312 
00313       message_id_t msg_id = read<OsModel, block_data_t, message_id_t>( data );
00314       if ( msg_id == STATIC_ROUTING_ID )
00315       {
00316          #ifdef ROUTING_STATIC_DEBUG
00317             debug().debug( "StaticRoutingAlgorithm: got Message from %d on %d size: %d\n", from,radio().id(),len);
00318          #endif
00319 
00320          Message *message = (Message *)data;
00321          if ( message->destination() != radio().id() )
00322          {
00323             #ifdef ROUTING_STATIC_DEBUG
00324                 debug().debug( "StaticRoutingAlgorithm: forward from node %d to node %d\n",
00325                         radio().id(),hop_map_[radio().id()] );
00326             #endif
00327             if ( hop_map_.find( radio().id()) == hop_map_.end() )
00328             {
00329                debug().debug( "FATAL fwd: no entry for %d\n", radio().id() );
00330                return;
00331             }
00332             radio().send( hop_map_[radio().id()], len, data );
00333             return;
00334          }
00335          else
00336          {
00337              #ifdef ROUTING_STATIC_DEBUG
00338                 debug().debug( "StaticRoutingAlgorithm: receive\n" );
00339              #endif
00340              notify_receivers( message->source_id(), message->payload_size(), message->payload() );
00341              return;
00342          }
00343 
00344       }
00345    }
00346 
00347 }
00348 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines