Wiselib
wiselib.testing/algorithms/topology/basic_topology.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_BASIC_TOPOLOGY_H__
00022 #define __ALGORITHMS_TOPOLOGY_BASIC_TOPOLOGY_H__
00023 
00024 #include "util/pstl/algorithm.h"
00025 #include "util/pstl/pair.h"
00026 #include "external_interface/external_interface.h"
00027 #include "algorithms/topology/topology_control_base.h"
00028 #include "algorithms/topology/basic_topology_broadcast_message.h"
00029 #include "algorithms/topology/basic_topology_types.h"
00030 
00031 namespace wiselib {
00032 
00033 #define PING_PERIOD_DEF 1000
00034 
00040 template<class OsModel_P, class Neigh_P,
00041       class Radio_P = typename OsModel_P::Radio,
00042       class Timer_P = typename OsModel_P::Timer>
00043 class BasicTopology: public TopologyBase<OsModel_P> {
00044 public:
00045    typedef OsModel_P OsModel;
00046    typedef Neigh_P Neighbors;
00047    typedef Radio_P Radio;
00048    typedef Timer_P Timer;
00049 #ifdef DEBUG
00050    typedef typename OsModel_P::Debug Debug;
00051 #endif
00052 
00053    typedef BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P> self_type;
00054 
00055    typedef typename OsModel::Os Os;
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 
00061    typedef typename Timer::millis_t millis_t;
00062 
00065    BasicTopology();
00067 
00070    void enable();
00071    void disable();
00073 
00074    Neighbors &topology();
00075 
00076 #ifdef DEBUG
00077    void init(Radio &r, Timer &t, Debug &d) {
00078       radio = &r;
00079       timer = &t;
00080       debug=&d;
00081    }
00082 #else
00083    void init(Radio &r, Timer &t) {
00084       radio = &r;
00085       timer = &t;
00086    }
00087 #endif
00088 
00089    void set_ping_period(register millis_t const period = s_period_def) {
00090       if (!d_enabled)
00091          d_period = period;
00092    }
00093 
00094    millis_t ping_period() const {
00095       return d_period;
00096    }
00097 
00098    static void set_default_ping_period(millis_t const period = PING_PERIOD_DEF) {
00099       s_period_def = period;
00100    }
00101 
00102    static millis_t default_ping_period() {
00103       return s_period_def;
00104    }
00105 
00106 private:
00109    void timer_callback(void * const userdata);
00111 
00114    void receive(node_id_t from, size_t len, block_data_t *data);
00116 
00117 
00118    bool d_enabled;
00119    millis_t d_period;
00120 
00121    Neighbors neigh;
00122    Radio *radio;
00123    Timer *timer;
00124 #ifdef DEBUG
00125    Debug *debug;
00126 #endif
00127 
00128    BasicTopologyBroadcastMessage<OsModel, Radio> broadcast_msg;
00129 
00130    static millis_t s_period_def;
00131 };
00132 // -----------------------------------------------------------------------
00133 // -----------------------------------------------------------------------
00134 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P>
00135 typename Timer_P::millis_t
00136       BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::s_period_def =
00137             PING_PERIOD_DEF;
00138 // -----------------------------------------------------------------------
00139 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P>
00140 BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::BasicTopology() :
00141    d_enabled(false), d_period(s_period_def) {
00142 }
00143 ;
00144 // -----------------------------------------------------------------------
00145 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P>
00146 void BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::enable(void) {
00147 #ifdef DEBUG
00148    debug->debug("Enabling BasicTopology\n");
00149 #endif
00150    d_enabled = true;
00151    radio->template reg_recv_callback<self_type, &self_type::receive> (this);
00152    timer->template set_timer<self_type, &self_type::timer_callback> (
00153          ping_period(), this, 0);
00154    neigh.clear();
00155 #ifdef DEBUG
00156    debug->debug("BasicTopology Boots for %i\n", radio->id());
00157 #endif
00158 }
00159 // -----------------------------------------------------------------------
00160 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P>
00161 void BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::disable(void) {
00162 #ifdef DEBUG
00163    debug->debug("Called BasicTopology::disable\n");
00164 #endif
00165    d_enabled = false;
00166 }
00167 // -----------------------------------------------------------------------
00168 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P>
00169 typename BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::Neighbors &
00170 BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::topology() {
00171    return neigh;
00172 }
00173 // -----------------------------------------------------------------------
00174 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P>
00175 void BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::timer_callback(
00176       void* userdata) {
00177    if (!d_enabled)
00178       return;
00179 #ifdef DEBUG
00180    debug->debug("Timer elapsed\n");
00181 #endif
00182    broadcast_msg.set_msg_id(BasicTopologyBroadcastMsgId);
00183    radio->send(Radio::BROADCAST_ADDRESS, broadcast_msg.buffer_size(),
00184          broadcast_msg.buf());
00185    timer->template set_timer<self_type, &self_type::timer_callback> (
00186          ping_period(), this, 0);
00187 #ifdef DEBUG
00188    debug->debug("Broadcast message sent\n");
00189 #endif
00190 }
00191 // -----------------------------------------------------------------------
00192 template<class OsModel_P, class Neigh_P, class Radio_P, class Timer_P>
00193 void BasicTopology<OsModel_P, Neigh_P, Radio_P, Timer_P>::receive(
00194       node_id_t from, size_t len, block_data_t *data) {
00195    if (len == 0)
00196       return;
00197    switch (*data) {
00198    case BasicTopologyBroadcastMsgId:
00199 #ifdef DEBUG
00200       debug->debug("Broadcast message received\n");
00201 #endif
00202       if (find(neigh.begin(), neigh.end(), from) == neigh.end()) {
00203          neigh.push_back(from);
00204          TopologyBase<OsModel>::notify_listeners();
00205       }
00206       break;
00207    }
00208 }
00209 
00210 }
00211 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines