Wiselib
wiselib.testing/algorithms/topology/xtc/xtc_topology_control.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  ** Author: Juan Farré, jafarre@lsi.upc.edu                                 **
00020  ***************************************************************************/
00021 #ifndef __ALGORITHMS_TOPOLOGY_XTC_TOPOLOGY_CONTROL_H__
00022 #define __ALGORITHMS_TOPOLOGY_XTC_TOPOLOGY_CONTROL_H__
00023 
00024 #include "algorithms/topology/topology_control_base.h"
00025 #include "algorithms/topology/xtc/xtc_broadcast_message.h"
00026 #include "algorithms/topology/xtc/xtc_order_message.h"
00027 #include "algorithms/topology/xtc/xtc_types.h"
00028 #include "util/pstl/algorithm.h"
00029 #include "util/pstl/pair.h"
00030 #include "util/pstl/vector_static.h"
00031 
00032 namespace wiselib {
00033 
00034 #define DELTA_DEF 60000
00035 
00041 template<class OsModel_P, typename OsModel_P::size_t MAX_NODES = 32,
00042 class Radio_P = typename OsModel_P::Radio,
00043 class Timer_P = typename OsModel_P::Timer>
00044 class XTCProtocol:
00045 public TopologyBase<OsModel_P>
00046 {
00047 public:
00048    typedef OsModel_P OsModel;
00049    typedef Radio_P Radio;
00050    typedef Timer_P Timer;
00051 #ifdef DEBUG
00052       typedef typename OsModel_P::Debug Debug;
00053 #endif
00054 
00055       typedef XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P> self_type;
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       typedef typename Radio::ExtendedData ExtendedData;
00061 
00062       typedef typename Timer::millis_t millis_t;
00063       struct Neighbor;
00064       typedef vector_static<OsModel,Neighbor,MAX_NODES> Order;
00065       typedef vector_static<OsModel,node_id_t,MAX_NODES> Neighbors;
00066       typedef Neighbors VOrders[MAX_NODES];
00067 
00070       XTCProtocol();
00072 
00075       void enable();
00076       void disable();
00078 
00079       Neighbors &topology();
00080 
00083       void timer0( void * const userdata );
00084       void timer1( void * const userdata );
00085       void timer2( void * const userdata );
00086       void timer3( void * const userdata );
00088 
00091       void receive( node_id_t from, size_t len, block_data_t *data, ExtendedData const &ext );
00093 
00094       void set_delta(millis_t const delta=s_delta_def) {
00095          if(!d_enabled)
00096          d_delta=delta;
00097       }
00098 
00099       millis_t delta() const {
00100          return d_delta;
00101       }
00102 
00103       static void set_default_delta(millis_t const delta=DELTA_DEF) {
00104          s_delta_def=delta;
00105       }
00106 
00107       static millis_t default_delta() {
00108          return s_delta_def;
00109       }
00110 
00111 #ifdef DEBUG
00112       void init( Radio& radio, Timer& timer, Debug& debug ) {
00113          radio_ = &radio;
00114          timer_ = &timer;
00115          debug_ = &debug;
00116       }
00117 #else
00118       void init( Radio& radio, Timer& timer) {
00119          radio_ = &radio;
00120          timer_ = &timer;
00121       }
00122 #endif
00123 
00124       void destruct() {
00125       }
00126 
00127    private:
00128       Radio& radio()
00129       {  return *radio_;}
00130 
00131       Timer& timer()
00132       {  return *timer_;}
00133 
00134 #ifdef DEBUG
00135       Debug& debug()
00136       {  return *debug_;}
00137 #endif
00138 
00139       Radio * radio_;
00140       Timer * timer_;
00141 #ifdef DEBUG
00142       Debug * debug_;
00143 #endif
00144 
00145       static millis_t s_delta_def;
00146       bool d_enabled;
00147       millis_t d_delta;
00148 
00149       Order order;
00150       Neighbors neighbors;
00151       VOrders vorders;
00152       XTCOrderMessage<OsModel,MAX_NODES,Radio> msg;
00153       XTCBroadcastMessage<OsModel,Radio> broadcast;
00154    };
00155    // -----------------------------------------------------------------------
00156    template<class OsModel_P,
00157    typename OsModel_P::size_t MAX_NODES,
00158    class Radio_P,
00159    class Timer_P>
00160    typename Timer_P::millis_t XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::s_delta_def=DELTA_DEF;
00161    // -----------------------------------------------------------------------
00162    template<class OsModel_P,
00163    typename OsModel_P::size_t MAX_NODES,
00164    class Radio_P,
00165    class Timer_P>
00166    struct XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::Neighbor {
00167       node_id_t id;
00168       uint16_t lqi;
00169 
00170       Neighbor():
00171       id(Radio::NULL_NODE_ID)
00172       ,lqi(0xffff) {}
00173 
00174       Neighbor(node_id_t n,uint16_t q):
00175       id(n)
00176       ,lqi(q) {}
00177 
00178       bool operator< (Neighbor const &n) const {
00179          return lqi<n.lqi;
00180       }
00181    };
00182    // -----------------------------------------------------------------------
00183    template<class OsModel_P,
00184    typename OsModel_P::size_t MAX_NODES,
00185    class Radio_P,
00186    class Timer_P>
00187    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::
00188 	XTCProtocol()
00189    : d_enabled(false),
00190    d_delta(s_delta_def)
00191    {
00192    }
00193    // -----------------------------------------------------------------------
00194    template<class OsModel_P,
00195    typename OsModel_P::size_t MAX_NODES,
00196    class Radio_P,
00197    class Timer_P>
00198    void
00199    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::
00200 	enable( void )
00201    {
00202       order.clear();
00203       neighbors.clear();
00204       for(size_t i=0;i<MAX_NODES;i++)
00205       vorders[i].clear();
00206       d_enabled=true;
00207       radio().template reg_recv_callback<self_type, &self_type::receive>( this );
00208       timer().template set_timer<self_type, &self_type::timer0>(
00209             delta(), this, 0 );
00210 #ifdef DEBUG
00211       debug().debug( "XTCProtocol Boots for %i\n", radio().id() );
00212 #endif
00213    }
00214    // -----------------------------------------------------------------------
00215    template<class OsModel_P,
00216    typename OsModel_P::size_t MAX_NODES,
00217    class Radio_P,
00218    class Timer_P>
00219    void
00220    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::
00221 	disable( void )
00222    {
00223       d_enabled=false;
00224 #ifdef DEBUG
00225       debug().debug( "Called XTCProtocol::disable\n" );
00226 #endif
00227    }
00228    // -----------------------------------------------------------------------
00229    template<class OsModel_P,
00230    typename OsModel_P::size_t MAX_NODES,
00231    class Radio_P,
00232    class Timer_P>
00233    typename XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::Neighbors &
00234    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::topology()
00235    {
00236       return neighbors;
00237    }
00238    // -----------------------------------------------------------------------
00239    template<class OsModel_P,
00240    typename OsModel_P::size_t MAX_NODES,
00241    class Radio_P,
00242    class Timer_P>
00243    void
00244    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::
00245 	timer0( void* userdata )
00246    {
00247 #ifdef DEBUG
00248       debug().debug( "Timer0 elapsed\n");
00249 #endif
00250       if(!d_enabled)
00251       return;
00252       broadcast.set_msg_id(XTCBroadcastMsgId);
00253       radio().send( radio().BROADCAST_ADDRESS, broadcast.buffer_size(), broadcast.buf() );
00254       timer().template set_timer<self_type, &self_type::timer1>(
00255             delta(), this, 0 );
00256 #ifdef DEBUG
00257       debug().debug( "Broadcast message sent\n");
00258 #endif
00259    }
00260 
00261    template<class OsModel_P,
00262    typename OsModel_P::size_t MAX_NODES,
00263    class Radio_P,
00264    class Timer_P>
00265    void
00266    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::
00267 	timer1( void* userdata )
00268    {
00269 #ifdef DEBUG
00270       debug().debug( "Timer1 elapsed\n");
00271 #endif
00272       if(!d_enabled)
00273       return;
00274       insertion_sort(order.begin(),order.end());
00275       timer().template set_timer<self_type, &self_type::timer2>(
00276             delta(), this, 0 );
00277 #ifdef DEBUG
00278       debug().debug( "Neighbor order generated\n");
00279 #endif
00280    }
00281 
00282    template<class OsModel_P,
00283    typename OsModel_P::size_t MAX_NODES,
00284    class Radio_P,
00285    class Timer_P>
00286    void
00287    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::
00288 	timer2( void* userdata )
00289    {
00290 #ifdef DEBUG
00291       debug().debug( "Timer2 elapsed\n");
00292 #endif
00293       if(!d_enabled)
00294       return;
00295       msg.set_msg_id(XTCOrderMsgId);
00296       for(size_t i=0;i<order.size();i++)
00297       msg.set_neighbor(i,order[i].id);
00298       msg.set_neighbor_number(order.size());
00299       radio().send( radio().BROADCAST_ADDRESS, msg.buffer_size(), msg.buf() );
00300       timer().template set_timer<self_type, &self_type::timer3>(
00301             delta(), this, 0 );
00302 #ifdef DEBUG
00303       debug().debug( "Order message sent\n");
00304 #endif
00305    }
00306 
00307    template<class OsModel_P,
00308    typename OsModel_P::size_t MAX_NODES,
00309    class Radio_P,
00310    class Timer_P>
00311    void
00312    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::
00313 	timer3( void* userdata )
00314    {
00315       typedef typename Order::iterator NeighIterator;
00316       typedef typename Neighbors::iterator NodeIterator;
00317 #ifdef DEBUG
00318       debug().debug( "Timer3 elapsed\n");
00319 #endif
00320       if(!d_enabled)
00321       return;
00322       for(size_t i=0;i<order.size();i++) {
00323          NodeIterator const iu=find(vorders[i].begin(), vorders[i].end(),radio().id());
00324          if(iu==vorders[i].end())
00325          continue;
00326          bool insert=true;
00327          for(size_t j=0;j<i;j++) {
00328             NodeIterator const k=find(vorders[i].begin(),iu,order[j].id);
00329             if(k!=iu) {
00330                insert=false;
00331                break;
00332             }
00333          }
00334          if(insert)
00335          neighbors.push_back(order[i].id);
00336       }
00337 #ifdef DEBUG
00338       debug().debug( "Topology generated\n");
00339 #endif
00340       TopologyBase<OsModel>::notify_listeners();
00341    }
00342    // -----------------------------------------------------------------------
00343    template<class OsModel_P,
00344    typename OsModel_P::size_t MAX_NODES,
00345    class Radio_P,
00346    class Timer_P>
00347    void
00348    XTCProtocol<OsModel_P, MAX_NODES, Radio_P, Timer_P>::
00349 	receive( node_id_t from, size_t len, block_data_t *data, ExtendedData const &ext )
00350    {
00351       if(!d_enabled)
00352       return;
00353       switch(*data) {
00354          case XTCBroadcastMsgId:
00355          order.push_back(Neighbor(from,ext.link_metric()));
00356 #ifdef DEBUG
00357       debug().debug( "Broadcast message received\n");
00358 #endif
00359       break;
00360       case XTCOrderMsgId: {
00361          size_t i;
00362          for(i=0;i<order.size()&&order[i].id!=from;i++);
00363          if(i<order.size()) {
00364             XTCOrderMessage<OsModel,MAX_NODES,Radio> *const m=reinterpret_cast<XTCOrderMessage<OsModel,MAX_NODES,Radio> *>(data);
00365             for(size_t j=0;j<m->neighbor_number();j++)
00366             vorders[i].push_back(m->neighbor(j));
00367          }
00368       }
00369 #ifdef DEBUG
00370       debug().debug( "Order message received\n");
00371 #endif
00372       break;
00373    }
00374 }
00375 
00376 }
00377 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines