Wiselib
|
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 #ifndef __UTIL_WISEBED_NODE_API_REMOTE_UART_MODEL_H 00020 #define __UTIL_WISEBED_NODE_API_REMOTE_UART_MODEL_H 00021 00022 #include "util/base_classes/uart_base.h" 00023 #include "util/wisebed_node_api/response_types.h" 00024 #include "util/wisebed_node_api/command_types.h" 00025 #include "util/wisebed_node_api/remote_uart_message.h" 00026 #include "util/delegates/delegate.hpp" 00027 #include "util/serialization/simple_types.h" 00028 #include "util/pstl/vector_static.h" 00029 #include "util/pstl/pair.h" 00030 #include "config_testing.h" 00031 #include <stdint.h> 00032 00033 namespace wiselib 00034 { 00035 00041 template<typename OsModel_P, 00042 typename Radio_P, 00043 typename Flooding_Radio_P, 00044 typename Uart_P, 00045 typename Debug_P = typename OsModel_P::Debug, 00046 typename Timer_P = typename OsModel_P::Timer, 00047 typename Rand_P = typename OsModel_P::Rand, 00048 typename Clock_P = typename OsModel_P::Clock> 00049 class RemoteUartModel 00050 : public UartBase<OsModel_P, 00051 typename Uart_P::size_t, 00052 typename Uart_P::block_data_t> 00053 { 00054 public: 00055 typedef OsModel_P OsModel; 00056 typedef Radio_P Radio; 00057 typedef Flooding_Radio_P Flooding; 00058 typedef Uart_P Uart; 00059 typedef Timer_P Timer; 00060 typedef Debug_P Debug; 00061 typedef Rand_P Rand; 00062 typedef Clock_P Clock; 00063 00064 typedef RemoteUartModel<OsModel,Radio,Flooding,Uart,Debug,Timer,Rand,Clock> self_type; 00065 typedef typename Radio::node_id_t node_id_t; 00066 typedef typename Uart::size_t size_t; 00067 typedef typename Uart::block_data_t block_data_t; 00068 typedef typename Radio::size_t radio_size_t; 00069 typedef typename Radio::block_data_t radio_block_data_t; 00070 typedef RemoteUartInMessage<OsModel, Radio> Message; 00071 // -------------------------------------------------------------------- 00072 enum ErrorCodes 00073 { 00074 SUCCESS = OsModel::SUCCESS, 00075 ERR_UNSPEC = OsModel::ERR_UNSPEC, 00076 ERR_NETDOWN = OsModel::ERR_NETDOWN, 00077 ERR_HOSTUNREACH = OsModel::ERR_HOSTUNREACH 00078 }; 00079 // -------------------------------------------------------------------- 00080 enum SpecialNodeIds 00081 { 00082 BROADCAST_ADDRESS = Radio_P::BROADCAST_ADDRESS, 00083 NULL_NODE_ID = Radio_P::NULL_NODE_ID 00084 }; 00085 // -------------------------------------------------------------------- 00086 enum Restrictions 00087 { 00088 MAX_MESSAGE_LENGTH = Radio_P::MAX_MESSAGE_LENGTH - Message::PAYLOAD_POS, 00089 FLUSH_TIMEOUT_MS = 5, 00090 KEEP_ALIVE_TIMEOUT = 60000 00091 }; 00092 // -------------------------------------------------------------------- 00093 enum ConnectionState 00094 { 00095 CONNECTED, 00096 PENDING, 00097 DISCONNECTED 00098 }; 00099 // -------------------------------------------------------------------- 00100 RemoteUartModel() 00101 : radio_(0), 00102 flooding_(0), 00103 uart_(0), 00104 debug_(0), 00105 timer_(0), 00106 random_(0), 00107 clock_(0), 00108 has_uart_(false), 00109 connection_state_(DISCONNECTED) 00110 {} 00111 // -------------------------------------------------------------------- 00112 void init( Radio& radio, Flooding& flooding_radio, Uart& uart, 00113 Debug& debug, Timer& timer, Rand& random, Clock& clock ) 00114 { 00115 radio_ = &radio; 00116 uart_ = &uart; 00117 debug_ = &debug; 00118 timer_ = &timer; 00119 flooding_ = &flooding_radio; 00120 random_ = &random; 00121 clock_ = &clock; 00122 uart_->enable_serial_comm(); 00123 timer_->template set_timer<self_type, &self_type::timer_elapsed>((unsigned int)(((double)(*random_)()/(double)random_->RANDOM_MAX)*1000), this, 0); 00124 has_uart_ = false; 00125 newMessage(0); 00126 timer_->template set_timer<self_type, &self_type::flush_timeout>(5, this, 0); 00127 timer_->template set_timer<self_type, &self_type::keep_alive>(KEEP_ALIVE_TIMEOUT, this, 0); 00128 debug_->debug("init remote uart max message length = %d\n",MAX_MESSAGE_LENGTH); 00129 } 00130 // -------------------------------------------------------------------- 00131 void timer_elapsed(void*) 00132 { 00133 if(enabled_ && connection_state_==DISCONNECTED) 00134 { 00135 request_sink(); 00136 timer_->template set_timer<self_type, &self_type::timer_elapsed>((int)(((double)(*random_)()/(double)random_->RANDOM_MAX)*10000), this, 0); 00137 } 00138 } 00139 // -------------------------------------------------------------------- 00140 void set_sink( void ) 00141 { 00142 if( !has_uart_ ) 00143 { 00144 #ifdef UTIL_REMOTE_UART_DEBUG 00145 debug().debug("set node %d to sink\n", radio().id()); 00146 #endif 00147 has_uart_ = true; 00148 sink_id_ = radio().id(); 00149 connection_state_ = CONNECTED; 00150 } 00151 } 00152 // -------------------------------------------------------------------- 00153 void request_sink() 00154 { 00155 if(!has_uart_) 00156 { 00157 #ifdef UTIL_REMOTE_UART_DEBUG 00158 debug().debug("requesting sink at node %x\n", radio().id()); 00159 #endif 00160 Message message; 00161 message.set_command_type(REMOTE_UART_SINK_REQUEST); 00162 message.set_destination(radio().BROADCAST_ADDRESS); 00163 message.set_source(radio().id()); 00164 message.set_payload(0, 0); 00165 flooding().send( 00166 Radio::BROADCAST_ADDRESS, 00167 message.buffer_size(), 00168 (typename Radio::block_data_t*)(&message) 00169 ); 00170 } 00171 } 00172 // -------------------------------------------------------------------- 00173 void destruct() 00174 {} 00175 // ----------------------------------------------------------------------- 00176 int write(size_t len, block_data_t *buf) 00177 { 00178 00179 00180 size_t pos = 0; 00181 while(len > 0) 00182 { 00183 size_t free_buffer_size = MAX_MESSAGE_LENGTH-buffer_.payload_length(); 00184 size_t writable_bytes = 0; 00185 if(free_buffer_size >= len) 00186 writable_bytes = len; 00187 else 00188 writable_bytes = free_buffer_size; 00189 // debug().debug("%d bytes available writable bytes %d free buffer size: %d, buffer size: %d payload size = %d\n",len,writable_bytes,free_buffer_size,buffer_.buffer_size(),buffer_.payload_length()); 00190 // debug().debug("bytes to write:\n"); 00191 // for(int i = 0; i<writable_bytes;i++) 00192 // { 00193 // debug().debug("%d",buf[i]); 00194 // } 00195 bool success = buffer_.append(buf,pos,writable_bytes); 00196 // debug().debug("sucess ? %d payload length:%d sequence nr: %d destination: %d source %d \n",success,buffer_.payload_length(),buffer_.sequence_number(),buffer_.destination(),buffer_.source()); 00197 00198 // for(int i = 0; i<buffer_.payload_length();i++) 00199 // { 00200 // debug().debug("%d",buffer_.payload()[i]); 00201 // } 00202 // debug().debug("\n"); 00203 if(!success) 00204 { 00205 // debug().debug("error append failed\n"); 00206 newMessage((buffer_.sequence_number()+1)%256); 00207 return ERR_UNSPEC; 00208 } 00209 pos += writable_bytes; 00210 len = len - writable_bytes; 00211 last_write_ = clock_->time(); 00212 // debug().debug("post write buffer size: %d vs MAX_MESSAGE_LENGHT: %i len =%d\n",buffer_.buffer_size(),MAX_MESSAGE_LENGTH,len); 00213 if(buffer_.payload_length() == MAX_MESSAGE_LENGTH) 00214 { 00215 // debug().debug("flushing\n"); 00216 flush(); 00217 } 00218 } 00219 return SUCCESS; 00220 } 00221 // ----------------------------------------------------------------------- 00222 void new_packet() 00223 { 00224 block_data_t temp = (block_data_t) DLE; 00225 write(1,&temp); 00226 temp = (block_data_t) STX; 00227 write(1,&temp); 00228 } 00229 // ----------------------------------------------------------------------- 00230 void end_packet() 00231 { 00232 block_data_t temp = (block_data_t) DLE; 00233 write(1,&temp); 00234 temp = (block_data_t) ETX; 00235 write(1,&temp); 00236 flush(); 00237 } 00238 // ----------------------------------------------------------------------- 00239 void rcv_uart_packet( size_t len, block_data_t* data ) 00240 { 00241 // set_sink(); 00242 Message *msg = (Message*) data; 00243 //#ifdef UTIL_REMOTE_UART_DEBUG 00244 debug().debug("received something over uart: command type: %d", msg->command_type() ); 00245 //#endif 00246 if(msg->command_type() == REMOTE_UART_MESSAGE) 00247 { 00248 if(msg->destination() != radio().id()) 00249 { 00250 //#ifdef UTIL_REMOTE_UART_DEBUG 00251 debug().debug("send uart msg(%d) from node %x to node %x\n", data[0], msg->source(), msg->destination()); 00252 //#endif 00253 radio().send(msg->destination(), len, data); 00254 } 00255 else 00256 { 00257 //#ifdef UTIL_REMOTE_UART_DEBUG 00258 debug().debug("Message for me, unwrapping payload of size: %d\n", msg->payload_length()); 00259 //#endif 00260 notify_receivers(msg->payload_length(),msg->payload()); 00261 } 00262 } 00263 else 00264 { 00265 notify_receivers(len,data); 00266 } 00267 } 00268 // ----------------------------------------------------------------------- 00269 void 00270 receive_radio_message( 00271 typename Radio::node_id_t source, 00272 typename Radio::size_t length, 00273 typename Radio::block_data_t *buf) 00274 { 00275 Message *msg = (Message*) buf; 00276 if (msg->source() == radio().id()) 00277 return; 00278 switch (msg->command_type()) { 00279 case REMOTE_UART_SINK_RESPONSE: 00280 sink_id_ = msg->source(); 00281 connection_state_ = CONNECTED; 00282 #ifdef UTIL_REMOTE_UART_DEBUG 00283 debug().debug("got sink information at node %x, sink is node %x\n", 00284 radio().id(), sink_id_); 00285 #endif 00286 break; 00287 case REMOTE_UART_SINK_REQUEST: 00288 if (has_uart_ || connection_state_ == CONNECTED) { 00289 Message message; 00290 message.set_command_type(REMOTE_UART_SINK_RESPONSE); 00291 message.set_destination(msg->source()); 00292 //even if we are not the sink but know the sink address, we mimik to be the sink 00293 #ifdef UTIL_REMOTE_UART_DEBUG 00294 debug().debug("node %x knows sink id, sending sink id %x to requesting node %x", radio().id(), sink_id_, source); 00295 #endif 00296 message.set_source(sink_id_); 00297 message.set_payload(0, 0); 00298 radio().send(msg->source(), message.buffer_size(), (block_data_t*) (&message)); 00299 if (has_uart_ && sink_id_ == radio().id()) 00300 uart().write(length, buf); 00301 } 00302 break; 00303 case REMOTE_UART_MESSAGE: 00304 #ifdef UTIL_REMOTE_UART_DEBUG 00305 debug().debug("received uart message seq_id %d with size %d at node %d from %d\n node has uart? %i\n", msg->sequence_number(),msg->payload_length(), radio().id(), source,has_uart_ ); 00306 #endif 00307 if (has_uart_) { 00308 uart().write(length, buf); 00309 } else { 00310 #ifdef UTIL_REMOTE_UART_DEBUG 00311 debug().debug("Message for me, unwrapping payload of size: %d\n", msg->payload_length()); 00312 #endif 00313 notify_receivers(msg->payload_length(), msg->payload()); 00314 } 00315 break; 00316 case REMOTE_UART_KEEP_ALIVE: 00317 00318 if (has_uart_ && sink_id_ == radio().id()) 00319 { 00320 Message message; 00321 message.set_command_type(REMOTE_UART_KEEP_ALIVE); 00322 message.set_destination(msg->source()); 00323 00324 #ifdef UTIL_REMOTE_UART_DEBUG 00325 debug().debug("sink %x received keep alive, sending response to node %x", radio().id(), msg->source()); 00326 #endif 00327 message.set_source(sink_id_); 00328 message.set_payload(0, 0); 00329 radio().send(msg->source(), message.buffer_size(), (block_data_t*) (&message)); 00330 uart().write(length, buf); 00331 } 00332 else if(sink_id_ == msg->source()) 00333 { 00334 #ifdef UTIL_REMOTE_UART_DEBUG 00335 debug().debug("received keep alive response from sink with id %x", msg->source()); 00336 #endif 00337 connection_state_ = CONNECTED; 00338 } 00339 break; 00340 } 00341 } 00342 // ----------------------------------------------------------------------- 00343 void enable_serial_comm() 00344 { 00345 radio().enable_radio(); 00346 radio().template reg_recv_callback<self_type, &self_type::receive_radio_message>(this); 00347 flooding().enable_radio(); 00348 flooding().template reg_recv_callback<self_type, &self_type::receive_radio_message>(this); 00349 uart().enable_serial_comm(); 00350 uart().template reg_read_callback<self_type, &self_type::rcv_uart_packet>(this); 00351 enabled_ = true; 00352 } 00353 // ----------------------------------------------------------------------- 00354 void disable_serial_comm() 00355 { 00356 uart().disable_serial_comm(); 00357 radio().disable_radio(); 00358 flooding().disabel(); 00359 enabled_ = false; 00360 } 00361 // ----------------------------------------------------------------------- 00362 void debug( const char *msg, ... ) 00363 { 00364 va_list fmtargs; 00365 char buffer[1024]; 00366 va_start( fmtargs, msg ); 00367 vsnprintf( buffer, sizeof(buffer) - 1, msg, fmtargs ); 00368 va_end( fmtargs ); 00369 write(sizeof(buffer),buffer); 00370 } 00371 00372 int flush() 00373 { 00374 if(buffer_.payload_length() == 0) 00375 return SUCCESS; 00376 if(connection_state_==DISCONNECTED) 00377 return ERR_NETDOWN; 00378 if (enabled_ && has_uart_) 00379 { 00380 uart().write(buffer_.buffer_size(), 00381 (typename Uart::block_data_t*)(&buffer_)); 00382 #ifdef UTIL_REMOTE_UART_DEBUG 00383 debug().debug("SENT to local uart!\n"); 00384 #endif 00385 newMessage((buffer_.sequence_number()+1)%256); 00386 return SUCCESS; 00387 } 00388 else if (enabled_ && connection_state_ == CONNECTED) 00389 { 00390 radio().send(sink_id_, buffer_.buffer_size(), 00391 (typename Radio::block_data_t*)(&buffer_)); 00392 #ifdef UTIL_REMOTE_UART_DEBUG 00393 debug().debug("SENT message from node %x to remote uart %x size = %i\n", radio().id(),sink_id_,buffer_.payload_length()); 00394 #endif 00395 newMessage((buffer_.sequence_number()+1)%256); 00396 return SUCCESS; 00397 } 00398 else 00399 { 00400 #ifdef UTIL_REMOTE_UART_DEBUG 00401 //debug().debug("No sink or uart available, dropping output at node %d\n",radio().id()); 00402 #endif 00403 newMessage((buffer_.sequence_number()+1)%256); 00404 return ERR_HOSTUNREACH; 00405 } 00406 last_write_ = clock_->time(); 00407 } 00408 00409 private: 00410 00411 enum { DLE = 0x10, STX = 0x02, ETX = 0x03 }; 00412 00413 Radio& radio() 00414 { return *radio_; } 00415 00416 Flooding& flooding() 00417 { return *flooding_; } 00418 00419 Uart& uart() 00420 { return *uart_; } 00421 00422 Debug& debug() 00423 { return *debug_; } 00424 00425 void newMessage(uint8_t seqNr){ 00426 buffer_.set_command_type(REMOTE_UART_MESSAGE); 00427 buffer_.set_sequence_number(seqNr); 00428 buffer_.set_destination(sink_id_); 00429 buffer_.set_source(radio().id()); 00430 buffer_.set_payload(0, 0); 00431 00432 } 00433 00434 void flush_timeout(void*) 00435 { 00436 //debug().debug("flush_timeout"); 00437 if(clock_->time() - last_write_ >= FLUSH_TIMEOUT_MS){ 00438 flush(); 00439 } 00440 timer_->template set_timer<self_type, &self_type::flush_timeout>(5, this, 0); 00441 } 00442 00443 void keep_alive(void*){ 00444 if(!has_uart_ && connection_state_ == CONNECTED) 00445 { 00446 #ifdef UTIL_REMOTE_UART_DEBUG 00447 debug().debug("sending keep alive at node %x\n", radio().id()); 00448 #endif 00449 Message message; 00450 message.set_command_type(REMOTE_UART_KEEP_ALIVE); 00451 message.set_destination(sink_id_); 00452 message.set_source(radio().id()); 00453 message.set_payload(0, 0); 00454 radio().send( 00455 sink_id_, 00456 message.buffer_size(), 00457 (typename Radio::block_data_t*)(&message) 00458 ); 00459 connection_state_ =PENDING; 00460 } 00461 else if(connection_state_ == PENDING) 00462 { 00463 connection_state_=DISCONNECTED; 00464 request_sink(); 00465 } 00466 timer_->template set_timer<self_type, &self_type::keep_alive>(KEEP_ALIVE_TIMEOUT, this, 0); 00467 } 00468 00469 Radio* radio_; 00470 Flooding* flooding_; 00471 Uart* uart_; 00472 Debug* debug_; 00473 Timer* timer_; 00474 Rand* random_; 00475 Clock* clock_; 00476 Message buffer_; 00477 00478 bool has_uart_; 00479 typename Clock::time_t last_write_; 00480 node_id_t sink_id_; 00481 bool enabled_; 00482 ConnectionState connection_state_; 00483 }; 00484 } 00485 00486 #endif