Wiselib
wiselib.testing/util/wisebed_node_api/virtual_radio_old.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_VIRTUAL_RADIO_MODEL_H
00020 #define __UTIL_WISEBED_NODE_API_VIRTUAL_RADIO_MODEL_H
00021 
00022 #include "util/wisebed_node_api/response_types.h"
00023 #include "util/wisebed_node_api/command_types.h"
00024 #include "util/wisebed_node_api/virtual_link_in_message.h"
00025 #include "util/wisebed_node_api/virtual_link_out_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 <stdint.h>
00031 
00032 namespace wiselib
00033 {
00034 
00040    template<typename OsModel_P,
00041             typename Radio_P,
00042             typename Uart_P,
00043             typename Debug_P = typename OsModel_P::Debug,
00044             int MAX_VIRTUAL_LINKS = 10>
00045    class VirtualRadioModel_old
00046    {
00047    public:
00048       typedef OsModel_P OsModel;
00049       typedef typename OsModel::Os Os;
00050       typedef Radio_P Radio;
00051       typedef Uart_P Uart;
00052       typedef Debug_P Debug;
00053       typedef VirtualRadioModel_old<OsModel, Radio, Uart, Debug, MAX_VIRTUAL_LINKS> self_type;
00054       typedef VirtualLinkInMessage<OsModel, Radio> InMessage;
00055       typedef VirtualLinkOutMessage<OsModel, Radio> OutMessage;
00056 
00057       typedef typename Radio::node_id_t node_id_t;
00058       typedef typename Radio::size_t size_t;
00059       typedef typename Radio::block_data_t block_data_t;
00060      typedef typename Radio::radio_delegate_t radio_delegate_t;
00061 
00062       typedef vector_static<OsModel, radio_delegate_t, 10> Receivers;
00063       typedef typename Receivers::iterator ReceiversIterator;
00064 
00065       typedef vector_static<OsModel, node_id_t, 10> DestinationVector;
00066       typedef typename DestinationVector::iterator DestinationVectorIterator;
00067 
00068       typedef vector_static<OsModel, node_id_t, 10> DeadLinksVector;
00069       typedef typename DeadLinksVector::iterator DeadLinksVectorIterator;
00070       // --------------------------------------------------------------------
00071       Receivers receivers_;
00072       DestinationVector destinations_;
00073       DeadLinksVector deadlinks_;
00074 
00075       bool nodeactive_;
00076       node_id_t virtual_node_id_;
00077       // --------------------------------------------------------------------
00078       enum SpecialNodeIds
00079       {
00080          BROADCAST_ADDRESS = Radio::BROADCAST_ADDRESS, 
00081          NULL_NODE_ID      = Radio::NULL_NODE_ID       
00082       };
00083       // --------------------------------------------------------------------
00084       enum Restrictions
00085       {
00086          MAX_MESSAGE_LENGTH = Radio::MAX_MESSAGE_LENGTH 
00087       };
00088       // --------------------------------------------------------------------
00089       void init( Radio& radio, Uart& uart, Debug& debug ) {
00090          radio_ = &radio;
00091          uart_ = &uart;
00092          debug_ = &debug;
00093       }
00094       // --------------------------------------------------------------------
00095       void destruct()
00096       {}
00097       // --------------------------------------------------------------------
00098       void send(node_id_t to, size_t len, block_data_t *buf )
00099       {
00100          if ((nodeactive_ == true) && (!destinations_.empty() ))
00101          {
00102             OutMessage message;
00103             message.set_command_type( NODE_OUTPUT_VIRTUAL_LINK );
00104             message.set_destination( to );
00105             message.set_source( id() );
00106             message.set_rssi( 0 );
00107             message.set_lqi( 0 );
00108             message.set_payload( len, buf );
00109             uart().write( message.buffer_size(), (uint8_t*)(&message) );
00110 //             debug().debug( "SENT to uart!" );
00111          }
00112 //          else
00113 //             debug().debug( "NOT sent to uart, dests empty!" );
00114          if ((nodeactive_ == true) && (node_in_deadlink_vector(to) == false))
00115           radio().send( to, len, buf );
00116 //         else
00117 //           debug().debug( "NOT sent to radio, node in deadlink vector!" );
00118       };
00119       // --------------------------------------------------------------------
00120       void
00121       receive_message( node_id_t id, size_t len, block_data_t *buf)
00122       {
00123          for ( ReceiversIterator
00124                   it = receivers_.begin();
00125                   it != receivers_.end();
00126                   ++it )
00127             (*it)( id, len, buf);
00128       }
00129       // --------------------------------------------------------------------
00130       void set_virtual_link( block_data_t* data)
00131       {
00132          uint8_t request_id = read<OsModel, block_data_t, uint8_t>( data );
00133          node_id_t dest = read<OsModel, block_data_t, uint64_t>( data +1);
00134          destinations_.push_back( dest );
00135 
00136          send_response_message(SET_VIRTUAL_LINK, request_id, COMMAND_SUCCESS, 0, NULL);
00137       }
00138       // --------------------------------------------------------------------
00139       void destroy_virtual_link( block_data_t* data)
00140       {
00141           uint8_t request_id = read<OsModel, block_data_t, uint8_t>( data );
00142           node_id_t dest = read<OsModel, block_data_t, uint64_t>( data +1);
00143 
00144           for ( DestinationVectorIterator it = destinations_.begin(); it != destinations_.begin(); ++it )
00145           {
00146              if ( *it == dest )
00147                 destinations_.erase( it );
00148           }
00149 
00150          send_response_message(DESTROY_VIRTUAL_LINK, request_id, COMMAND_SUCCESS, 0, NULL);
00151       }
00152       // --------------------------------------------------------------------
00153       void enable_physical_link( block_data_t* data)
00154       {
00155          uint8_t request_id = read<OsModel, block_data_t, uint8_t>( data );
00156          node_id_t dest = read<OsModel, block_data_t, uint64_t>( data +1);
00157 
00158           for ( DeadLinksVectorIterator it = deadlinks_.begin(); it != deadlinks_.begin(); ++it )
00159           {
00160              if ( *it == dest )
00161                 deadlinks_.erase( it );
00162           }
00163 
00164          send_response_message(ENABLE_PHYSICAL_LINK, request_id, COMMAND_SUCCESS, 0, NULL);
00165       }
00166       // --------------------------------------------------------------------
00167       void disable_physical_link( block_data_t* data)
00168       {
00169          uint8_t request_id = read<OsModel, block_data_t, uint8_t>( data );
00170          node_id_t dest = read<OsModel, block_data_t, uint64_t>( data +1);
00171 
00172          deadlinks_.push_back( dest );
00173 
00174          send_response_message(DISABLE_PHYSICAL_LINK, request_id, COMMAND_SUCCESS, 0, NULL);
00175       }
00176       // --------------------------------------------------------------------
00177       bool node_in_deadlink_vector( node_id_t dest)
00178       {
00179 
00180           for ( DeadLinksVectorIterator it = deadlinks_.begin(); it != deadlinks_.begin(); ++it )
00181           {
00182              if ( *it == dest )
00183                 return true;
00184           }
00185 
00186          return false;
00187       }
00188       // --------------------------------------------------------------------
00189       void enable_node( block_data_t* data)
00190       {
00191         uint8_t request_id = read<OsModel, block_data_t, uint8_t>( data );
00192 
00193         nodeactive_ = true;
00194 
00195         send_response_message(ENABLE_NODE, request_id, COMMAND_SUCCESS, 0, NULL);
00196       }
00197      // --------------------------------------------------------------------
00198      void disable_node( block_data_t* data)
00199      {
00200         uint8_t request_id = read<OsModel, block_data_t, uint8_t>( data );
00201 
00202         nodeactive_ = false;
00203 
00204         send_response_message(DISABLE_NODE, request_id, COMMAND_SUCCESS, 0, NULL);
00205      }
00206       // --------------------------------------------------------------------
00207       void rcv_uart_packet( size_t len, block_data_t* data )
00208       {
00209          switch (*data)
00210          {
00211             case VIRTUAL_LINK_MESSAGE:
00212             {
00213                InMessage *msg = (InMessage*)data;
00214 //                debug().debug( "RECEIVED VIRTUAL LINK from %d to %d with size %d",
00215 //                   (uint32_t)msg->source(), (uint32_t)msg->destination(), msg->payload_length() );
00216 
00217 
00218                if ( msg->destination() == radio().id() || msg->destination() == Radio::BROADCAST_ADDRESS )
00219                   receive_message( msg->source(), msg->payload_length(), msg->payload());
00220 
00221                send_response_message(VIRTUAL_LINK_MESSAGE, msg->request_id(), COMMAND_SUCCESS, 0, NULL);
00222 
00223                break;
00224             }
00225             case ENABLE_NODE:
00226                enable_node( data + sizeof(block_data_t));
00227                break;
00228             case DISABLE_NODE:
00229                disable_node( data + sizeof(block_data_t));
00230                break;
00231             case SET_VIRTUAL_LINK:
00232                set_virtual_link( data + sizeof(block_data_t));
00233                break;
00234             case DESTROY_VIRTUAL_LINK:
00235                destroy_virtual_link( data + sizeof(block_data_t));
00236                break;
00237             case ENABLE_PHYSICAL_LINK:
00238                enable_physical_link( data + sizeof(block_data_t));
00239                break;
00240             case DISABLE_PHYSICAL_LINK:
00241                disable_physical_link( data + sizeof(block_data_t));
00242                break;
00243             default:
00244                uint8_t command_type = read<OsModel, block_data_t, uint8_t>( data );
00245                uint8_t request_id = read<OsModel, block_data_t, uint8_t>( data +1);
00246                send_response_message(command_type, request_id, UNKNOWN_PARAMETER, 0, NULL);
00247                break;
00248          }
00249       }
00250       // --------------------------------------------------------------------
00251       void send_response_message(uint8_t command_type, uint8_t request_id,
00252                          uint8_t result, uint8_t len, block_data_t* payload)
00253       {
00254          uint8_t buf_len = 3+len;
00255          uint8_t uart_buf[buf_len];
00256 
00257          uart_buf[0] = command_type;
00258          uart_buf[1] = request_id;
00259          uart_buf[2] = result;
00260 
00261          memcpy( uart_buf + 3, payload, len);
00262 
00263          uart().write( buf_len, (uint8_t*)(&uart_buf) );
00264       }
00265       // --------------------------------------------------------------------
00266       void enable_radio()
00267       {
00268          nodeactive_ = true;
00269          virtual_node_id_ = radio().id();
00270 
00271          radio().enable_radio();
00272          radio().template reg_recv_callback <self_type, &self_type::receive_message>(this);
00273          uart().enable_serial_comm();
00274          uart().template reg_read_callback<self_type, &self_type::rcv_uart_packet>(this);
00275       }
00276       // --------------------------------------------------------------------
00277       void disable_radio()
00278       {
00279        nodeactive_ = false;
00280          uart().disable_serial_comm();
00281          radio().disable_radio();
00282       }
00283       // --------------------------------------------------------------------
00284       node_id_t id()
00285       {
00286          return radio().id();
00287       }
00288       // --------------------------------------------------------------------
00289       template<class T, void (T::*TMethod)( node_id_t, size_t, block_data_t*)>
00290       int reg_recv_callback( T *obj_pnt )
00291       {
00292          receivers_.push_back( radio_delegate_t::template from_method<T, TMethod>( obj_pnt ) );
00293          // TODO: return real id!
00294          return 0;
00295       }
00296       // --------------------------------------------------------------------
00297       void unreg_recv_callback( int idx )
00298       {}
00299 
00300    private:
00301       Radio& radio()
00302       { return *radio_; }
00303 
00304       Uart& uart()
00305       { return *uart_; }
00306 
00307       Debug& debug()
00308       { return *debug_; }
00309 
00310       Radio* radio_;
00311       Uart* uart_;
00312       Debug* debug_;
00313    };
00314 }
00315 
00316 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines