Wiselib
|
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_ */