Wiselib
wiselib.testing/util/wisebed_node_api/remote_uart.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines