Wiselib
wiselib.testing/algorithms/gke/ttl_flooding.h
Go to the documentation of this file.
00001 #ifndef _TTL_FLOODING_H_
00002 #define _TTL_FLOODING_H_
00003 
00004 #include "util/base_classes/radio_base.h"
00005 #include "util/pstl/set_static.h"
00006 
00007 #include "keylevels_message.h"
00008 //#include "ttl_message.h"
00009 
00010 namespace wiselib {
00011 
00012 template<typename OsModel_P, typename Radio_P,
00013       typename Debug_P = typename OsModel_P::Debug, int SEEN_MESSAGE_SET_SIZE = 100>
00014 class TTLFlooding: public RadioBase<OsModel_P, typename Radio_P::node_id_t,
00015       typename Radio_P::size_t, typename Radio_P::block_data_t> {
00016 public:
00017    typedef OsModel_P OsModel;
00018    typedef Radio_P Radio;
00019    typedef Debug_P Debug;
00020 
00021    typedef TTLFlooding<OsModel, Radio, Debug, SEEN_MESSAGE_SET_SIZE> self_type;
00022 
00023    typedef typename Radio::node_id_t node_id_t;
00024    typedef typename Radio::size_t size_t;
00025    typedef typename Radio::block_data_t block_data_t;
00026    typedef typename Radio::message_id_t message_id_t;
00027    typedef typename wiselib::set_static<OsModel, node_id_t, SEEN_MESSAGE_SET_SIZE>
00028          message_set_t;
00029 
00030    typedef KeylevelsMessage<OsModel, Radio> Message;
00031 
00032    enum ReturnValues {
00033       SUCCESS = OsModel::SUCCESS
00034    };
00035 
00036    enum SpecialNodeIds {
00037       BROADCAST_ADDRESS = Radio::BROADCAST_ADDRESS,
00038       NULL_NODE_ID = Radio::NULL_NODE_ID,
00039    };
00040 
00041    enum Restrictions {
00042       MAX_MESSAGE_LENGTH = Radio::MAX_MESSAGE_LENGTH
00043    };
00044 
00045    int init(Radio& radio, Debug& debug) {
00046       radio_ = &radio;
00047       debug_ = &debug;
00048       notify_all_on_path = false;
00049       ttl = 0;
00050 
00051       return SUCCESS;
00052    }
00053 
00054    void enable_radio() {
00055       //TODO: sprawdzic czy misiek to slusznie wywalil
00056       //radio_->enable_radio();
00057       callback_id_ = radio_->template reg_recv_callback<self_type,
00058             &self_type::receive> (this);
00059    }
00060 
00061    void disable_radio() {
00062       radio_->unreg_recv_callback(callback_id_);
00063       clear();
00064    }
00065 
00066    void clear() {
00067       ttl = 0;
00068       set.clear();
00069    }
00070 
00071    void set_ttl(uint8_t new_ttl) {
00072       set.clear();
00073       ttl = new_ttl;
00074    }
00075 
00076    int get_ttl(){
00077       return ttl;
00078    }
00079 
00080    void set_notify_all_on_path(bool notify) {
00081       notify_all_on_path = notify;
00082    }
00083 
00084    void show_ttl_message(Message* msg, int dir){
00085 #ifndef KL_EXTREME
00086       return;
00087 #endif
00088       uint8_t* temp = (uint8_t*) msg;
00089       if(dir)
00090          debug_->debug("[KL] {%d} outgoing ttl message[0]: [%d]", radio_->id(), temp[0]);
00091       else
00092          debug_->debug("[KL] {%d} incoming ttl message[0]: [%d]", radio_->id(), temp[0]);
00093       return;
00094       debug_->debug("[");
00095       int i=0;
00096       for(i=0;i<msg->buffer_size();i++){
00097          debug_->debug("%d, ",temp[i]);
00098       }
00099       debug_->debug("]");
00100    }
00101 
00102    void send(node_id_t msg_id, size_t size, block_data_t* data);
00103    void receive(node_id_t from, size_t size, block_data_t* data);
00104 
00105 private:
00106    typename Radio::self_pointer_t radio_;
00107    typename Debug::self_pointer_t debug_;
00108    int callback_id_;
00109 
00110    bool notify_all_on_path;
00111    uint8_t ttl;
00112    message_set_t set;
00113 };
00114 
00115 template<typename OsModel_P, typename Radio_P, typename Debug_P, int SEEN_MESSAGE_SET_SIZE>
00116 void TTLFlooding<OsModel_P, Radio_P, Debug_P, SEEN_MESSAGE_SET_SIZE>::send(node_id_t msg_id,
00117       size_t size, block_data_t* data) 
00118 {
00119    if (ttl > 0) {
00120       Message message;
00121       message.set_message_type(TTL_MESSAGE);
00122       message.set_message_id(msg_id);
00123       message.set_source(radio_->id());
00124       message.set_destination(radio_->BROADCAST_ADDRESS);
00125       message.set_ttl(ttl);
00126       message.set_payload(size, data);
00127 
00128 #ifdef TTL_FLOODING_DEBUG
00129       show_ttl_message(&message,1);
00130 #endif
00131       radio_->send(radio_->BROADCAST_ADDRESS, message.buffer_size(),
00132             (block_data_t*) &message);
00133    }
00134 }
00135 
00136 template<typename OsModel_P, typename Radio_P, typename Debug_P, int SEEN_MESSAGE_SET_SIZE>
00137 void TTLFlooding<OsModel_P, Radio_P, Debug_P, SEEN_MESSAGE_SET_SIZE>::receive(node_id_t sender,
00138       size_t size, block_data_t* data) 
00139 {
00140    message_id_t msg_id = read<OsModel, block_data_t, message_id_t> (data);
00141 
00142    Message *message = reinterpret_cast<Message*>( data );
00143    show_ttl_message(message,0);
00144    if (sender == radio_->id())
00145          return;
00146 
00147    if (msg_id == TTL_MESSAGE)
00148    {
00149 
00150 
00151 #ifdef TTL_FLOODING_DEBUG
00152          debug_->debug("[KLT] {%d} received message (id = %d) with ttl (%d)",
00153                      radio_->id(),
00154                      message->message_id(),
00155                      message->ttl()
00156                   );
00157 #endif
00158 
00159       if (message->source() == radio_->id())    return;
00160 
00161       if (set.find(message->message_id()) != set.end())
00162       { }
00163       else
00164       {
00165          uint8_t msg_ttl = message->ttl();
00166          if (notify_all_on_path || msg_ttl == 1)
00167          {
00168             notify_receivers(
00169                    message->source(),
00170                    message->payload_length(),
00171                    message->payload()
00172                    );
00173          }
00174 
00175          if (msg_ttl > 1)
00176          {
00177 #ifdef TTL_FLOODING_DEBUG
00178             debug_->debug("[KLT] {%d} proxing message id %d\n", radio_->id(), message->message_id());
00179 #endif
00180             Message proxyMessage;
00181             proxyMessage.set_message_id(message->message_id());
00182             proxyMessage.set_message_type(message->message_type());
00183             proxyMessage.set_source(message->source());
00184             proxyMessage.set_destination(radio_->BROADCAST_ADDRESS);
00185             proxyMessage.set_ttl( msg_ttl - 1 );
00186             proxyMessage.set_payload( message->payload_length(), message->payload() );
00187             show_ttl_message(&proxyMessage,1);
00188             radio_->send(radio_->BROADCAST_ADDRESS, proxyMessage.buffer_size(),
00189                   (block_data_t*) &proxyMessage);
00190          }
00191 
00192          set.insert(message->message_id());
00193       }
00194    }
00195 }
00196 
00197 }
00198 
00199 #endif  /* _TTL_FLOODING_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines