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