Wiselib
wiselib.testing/algorithms/group-key/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       callback_id_ = radio_->template reg_recv_callback<self_type,
00056             &self_type::receive> (this);
00057    }
00058 
00059    void disable_radio() {
00060       radio_->unreg_recv_callback(callback_id_);
00061       clear();
00062    }
00063 
00064    void clear() {
00065       ttl = 0;
00066       set.clear();
00067    }
00068 
00069    void set_ttl(uint8_t new_ttl) {
00070       set.clear();
00071       ttl = new_ttl;
00072    }
00073 
00074    int get_ttl(){
00075       return ttl;
00076    }
00077 
00078    void set_cluster(node_id_t cluster){
00079       my_cluster = cluster;
00080    }
00081 
00082    void set_notify_all_on_path(bool notify) {
00083       notify_all_on_path = notify;
00084    }
00085 
00086 #ifdef TTL_FLOODING_DEBUG
00087    void show_ttl_message(Message* msg, int dir){
00088       uint8_t* temp = (uint8_t*) msg;
00089       if(dir)
00090          debug_->debug("[KL] {%d} outgoing ttl message[0]: [%d]\n", radio_->id(), temp[0]);
00091       else
00092          debug_->debug("[KL] {%d} incoming ttl message[0]: [%d]\n", radio_->id(), temp[0]);
00093       return;
00094    }
00095 #endif
00096 
00097    void send(node_id_t msg_id, size_t size, block_data_t* data);
00098    void receive(node_id_t from, size_t size, block_data_t* data);
00099 
00100 private:
00101    typename Radio::self_pointer_t radio_;
00102    typename Debug::self_pointer_t debug_;
00103    int callback_id_;
00104 
00105    bool notify_all_on_path;
00106    uint8_t ttl;
00107    message_set_t set;
00108    node_id_t my_cluster;
00109 };
00110 
00111 template<typename OsModel_P, typename Radio_P, typename Debug_P, int SEEN_MESSAGE_SET_SIZE>
00112 void TTLFlooding<OsModel_P, Radio_P, Debug_P, SEEN_MESSAGE_SET_SIZE>::send(node_id_t msg_id,
00113       size_t size, block_data_t* data) 
00114 {
00115    if (ttl > 0) {
00116       Message message;
00117       message.set_message_type(TTL_MESSAGE);
00118       message.set_message_id(msg_id);
00119       message.set_source(radio_->id());
00120       message.set_destination(radio_->BROADCAST_ADDRESS);
00121       message.set_ttl(ttl);
00122       message.set_cluster(my_cluster);
00123       message.set_payload(size, data);
00124 
00125 #ifdef TTL_FLOODING_DEBUG
00126       show_ttl_message(&message,1);
00127 #endif
00128       radio_->send(radio_->BROADCAST_ADDRESS, message.buffer_size(),
00129             (block_data_t*) &message);
00130    }
00131 }
00132 
00133 template<typename OsModel_P, typename Radio_P, typename Debug_P, int SEEN_MESSAGE_SET_SIZE>
00134 void TTLFlooding<OsModel_P, Radio_P, Debug_P, SEEN_MESSAGE_SET_SIZE>::receive(node_id_t sender,
00135       size_t size, block_data_t* data) 
00136 {
00137    message_id_t msg_id = read<OsModel, block_data_t, message_id_t> (data);
00138 
00139    Message *message = reinterpret_cast<Message*>( data );
00140 #ifdef TTL_FLOODING_DEBUG
00141    show_ttl_message(message,0);
00142 #endif
00143    if (sender == radio_->id())
00144          return;
00145 
00146    if (msg_id == TTL_MESSAGE)
00147    {
00148 
00149 
00150 #ifdef TTL_FLOODING_DEBUG
00151          debug_->debug("[KLT] {%d} received message (id = %d) with ttl (%d)\n",
00152                      radio_->id(),
00153                      message->message_id(),
00154                      message->ttl()
00155                   );
00156 #endif
00157 
00158       if (message->source() == radio_->id())    return;
00159 
00160       if (set.find(message->message_id()) == set.end())
00161       {
00162          uint8_t msg_ttl = message->ttl();
00163          if (notify_all_on_path || msg_ttl == 1)
00164          {
00165             if(message->get_cluster() == my_cluster)
00166                notify_receivers(
00167                    message->source(),
00168                    message->payload_length(),
00169                    message->payload()
00170                    );
00171          }
00172 
00173          if (msg_ttl > 1)
00174          {
00175 #ifdef TTL_FLOODING_DEBUG
00176             debug_->debug("[KLT] {%d} proxing message id %d\n", radio_->id(), message->message_id());
00177 #endif
00178             Message proxyMessage;
00179             proxyMessage.set_message_id(message->message_id());
00180             proxyMessage.set_message_type(message->message_type());
00181             proxyMessage.set_source(message->source());
00182             proxyMessage.set_destination(radio_->BROADCAST_ADDRESS);
00183             proxyMessage.set_cluster(message->get_cluster());
00184             proxyMessage.set_ttl( msg_ttl - 1 );
00185             proxyMessage.set_payload( message->payload_length(), message->payload() );
00186 #ifdef TTL_FLOODING_DEBUG
00187             show_ttl_message(&proxyMessage,1);
00188 #endif
00189             radio_->send(radio_->BROADCAST_ADDRESS, proxyMessage.buffer_size(),
00190                   (block_data_t*) &proxyMessage);
00191          }
00192 
00193          set.insert(message->message_id());
00194       }
00195    }
00196 }
00197 
00198 }
00199 
00200 #endif  /* _TTL_FLOODING_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines