Wiselib
wiselib.testing/util/wisebed_node_api/virtual_extended_txradio.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_EXRADIO_MODEL_H
00020 #define __UTIL_WISEBED_NODE_API_VIRTUAL_EXRADIO_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 //uncomment to enable debug
00033 //#define VIRTUAL_RADIO_DEBUG
00034 
00035 
00036 namespace wiselib {
00037 
00043     template<typename OsModel_P,
00044             typename Radio_P,
00045             typename Uart_P,
00046             typename Debug_P = typename OsModel_P::Debug,
00047             int MAX_VIRTUAL_LINKS = 10 >
00048             class VirtualExtendedTxRadioModel {
00049     public:
00050 
00051         typedef OsModel_P OsModel;
00052         typedef typename OsModel::Os Os;
00053         typedef Radio_P Radio;
00054         typedef Uart_P Uart;
00055         typedef Debug_P Debug;
00056         typedef VirtualExtendedTxRadioModel<OsModel, Radio, Uart, Debug, MAX_VIRTUAL_LINKS> self_type;
00057         typedef self_type* self_pointer_t;
00058 
00059         typedef VirtualLinkInMessage<OsModel, Radio> InMessage;
00060         typedef VirtualLinkOutMessage<OsModel, Radio> OutMessage;
00061 
00062         typedef typename Radio::node_id_t node_id_t;
00063         typedef typename Radio::size_t size_t;
00064         typedef typename Radio::block_data_t block_data_t;
00065         typedef typename Radio::message_id_t message_id_t;
00066 
00067         typedef typename Radio::radio_delegate_t radio_delegate_t;
00068         typedef typename Radio::extended_radio_delegate_t extended_radio_delegate_iss_t;
00069 
00070         typedef vector_static<OsModel, radio_delegate_t, 10 > Receivers;
00071         typedef typename Receivers::iterator ReceiversIterator;
00072 
00073         typedef vector_static<OsModel, extended_radio_delegate_iss_t, 10 > Extended_Receivers;
00074         typedef typename Extended_Receivers::iterator Extended_ReceiversIterator;
00075 
00076         typedef vector_static<OsModel, node_id_t, 10 > DestinationVector;
00077         typedef typename DestinationVector::iterator DestinationVectorIterator;
00078 
00079         typedef vector_static<OsModel, node_id_t, 10 > DeadLinksVector;
00080         typedef typename DeadLinksVector::iterator DeadLinksVectorIterator;
00081 
00082         typedef typename Radio::ExtendedData ExtendedData;
00083         typedef typename Radio::TxPower TxPower;
00084 
00085         // --------------------------------------------------------------------
00086         Receivers receivers_;
00087         Extended_Receivers extended_receivers_;
00088         DestinationVector destinations_;
00089         DeadLinksVector deadlinks_;
00090 
00091         bool nodeactive_;
00092         node_id_t virtual_node_id_;
00093         // --------------------------------------------------------------------
00094 
00095         enum SpecialNodeIds {
00096             BROADCAST_ADDRESS = Radio::BROADCAST_ADDRESS, 
00097             NULL_NODE_ID = Radio::NULL_NODE_ID 
00098         };
00099         // --------------------------------------------------------------------
00100 
00101         enum Restrictions {
00102             MAX_MESSAGE_LENGTH = Radio::MAX_MESSAGE_LENGTH 
00103         };
00104 
00105         // --------------------------------------------------------------------
00106 
00107         void init(Radio& radio, Uart& uart, Debug& debug) {
00108             radio_ = &radio;
00109             uart_ = &uart;
00110             debug_ = &debug;
00111         }
00112         // --------------------------------------------------------------------
00113 
00114         void destruct() {
00115         }
00116         // --------------------------------------------------------------------
00117 
00118         void send(node_id_t to, size_t len, block_data_t *buf) {
00119             // send virtual link message over uart
00120             if ((nodeactive_ == true) && (!destinations_.empty())) {
00121                 OutMessage message;
00122                 message.set_command_type(NODE_OUTPUT_VIRTUAL_LINK);
00123                 message.set_destination(to);
00124                 message.set_source(id());
00125                 message.set_rssi(0);
00126                 message.set_lqi(0);
00127                 message.set_payload(len, buf);
00128                 uart().write(message.buffer_size(), (uint8_t*) (&message));
00129 #ifdef VIRTUAL_RADIO_DEBUG
00130                 debug().debug("EXVR::sent::UART::node%x::to%x::len%d::", id(), to, len);
00131 #endif
00132             }
00133 
00134             // send message over physical radio
00135             if ((nodeactive_ == true) && (node_in_deadlink_vector(to) == false)) {
00136                 radio().send(to, len, buf);
00137 #ifdef VIRTUAL_RADIO_DEBUG
00138 
00139                 debug().debug("EXVR::send::PHYSICAL::node%x::to%x::len%d::", id(), to, len);
00140 #endif
00141             }
00142         }
00143 
00144         // --------------------------------------------------------------------
00145 
00146         void receive_message(node_id_t from, size_t len, block_data_t * msg, ExtendedData const &ex) {
00147             for (ReceiversIterator it = receivers_.begin(); it != receivers_.end(); ++it) {
00148                 (*it)(from, len, msg);
00149 #ifdef VIRTUAL_RADIO_DEBUG
00150                 debug().debug("EXVR::deliver::node%x::from%x::len%d::", id(), from, len);
00151 #endif
00152             }
00153 
00154             for (Extended_ReceiversIterator it = extended_receivers_.begin(); it != extended_receivers_.end(); ++it) {
00155                 (*it)(from, len, msg, ex);
00156 #ifdef VIRTUAL_RADIO_DEBUG
00157                 debug().debug("EXVR::deliverExtended::node%x::from%x::len%d::lqi%d::", id(), from, len, ex.link_metric());
00158 #endif
00159             }
00160         }
00161         // --------------------------------------------------------------------
00162 
00163         void set_virtual_link(block_data_t* data) {
00164 
00165             uint8_t request_id = read<OsModel, block_data_t, uint8_t > (data);
00166             node_id_t dest = read<OsModel, block_data_t, uint64_t > (data + 1);
00167 
00168             destinations_.push_back(dest);
00169 
00170             send_response_message(SET_VIRTUAL_LINK, request_id, COMMAND_SUCCESS, 0, NULL);
00171         }
00172         // --------------------------------------------------------------------
00173 
00174         void destroy_virtual_link(block_data_t* data) {
00175             uint8_t request_id = read<OsModel, block_data_t, uint8_t > (data);
00176             node_id_t dest = read<OsModel, block_data_t, uint64_t > (data + 1);
00177 
00178             for (DestinationVectorIterator it = destinations_.begin(); it != destinations_.begin(); ++it) {
00179 
00180                 if (*it == dest)
00181                     destinations_.erase(it);
00182             }
00183 
00184             send_response_message(DESTROY_VIRTUAL_LINK, request_id, COMMAND_SUCCESS, 0, NULL);
00185         }
00186         // --------------------------------------------------------------------
00187 
00188         void enable_physical_link(block_data_t* data) {
00189             uint8_t request_id = read<OsModel, block_data_t, uint8_t > (data);
00190             node_id_t dest = read<OsModel, block_data_t, uint64_t > (data + 1);
00191 
00192             for (DeadLinksVectorIterator it = deadlinks_.begin(); it != deadlinks_.begin(); ++it) {
00193 
00194                 if (*it == dest)
00195                     deadlinks_.erase(it);
00196             }
00197 
00198             send_response_message(ENABLE_PHYSICAL_LINK, request_id, COMMAND_SUCCESS, 0, NULL);
00199         }
00200         // --------------------------------------------------------------------
00201 
00202         void disable_physical_link(block_data_t* data) {
00203 
00204             uint8_t request_id = read<OsModel, block_data_t, uint8_t > (data);
00205             node_id_t dest = read<OsModel, block_data_t, uint64_t > (data + 1);
00206 
00207             deadlinks_.push_back(dest);
00208 
00209             send_response_message(DISABLE_PHYSICAL_LINK, request_id, COMMAND_SUCCESS, 0, NULL);
00210         }
00211         // --------------------------------------------------------------------
00212 
00213         bool node_in_deadlink_vector(node_id_t dest) {
00214             for (DeadLinksVectorIterator it = deadlinks_.begin(); it != deadlinks_.begin(); ++it) {
00215                 if (*it == dest)
00216 
00217                     return true;
00218             }
00219 
00220             return false;
00221         }
00222         // --------------------------------------------------------------------
00223 
00224         void enable_node(block_data_t* data) {
00225 
00226             uint8_t request_id = read<OsModel, block_data_t, uint8_t > (data);
00227 
00228             nodeactive_ = true;
00229 
00230             send_response_message(ENABLE_NODE, request_id, COMMAND_SUCCESS, 0, NULL);
00231         }
00232         // --------------------------------------------------------------------
00233 
00234         void disable_node(block_data_t* data) {
00235 
00236             uint8_t request_id = read<OsModel, block_data_t, uint8_t > (data);
00237 
00238             nodeactive_ = false;
00239 
00240             send_response_message(DISABLE_NODE, request_id, COMMAND_SUCCESS, 0, NULL);
00241         }
00242         // --------------------------------------------------------------------
00243 
00244         void rcv_uart_packet(size_t len, block_data_t* data) {
00245             switch (*data) {
00246                 case VIRTUAL_LINK_MESSAGE:
00247                 {
00248 
00249                     InMessage *msg = (InMessage*) data;
00250                     //debug().debug("RECEIVED VIRTUAL LINK from %d to %d with size %d",
00251                     //(uint32_t) msg->source(), (uint32_t) msg->destination(), msg->payload_length());
00252 
00253                     ExtendedData ex;
00254                     ex.set_link_metric(1);
00255 
00256                     if (msg->destination() == radio().id() ||
00257                             msg->destination() == Radio::BROADCAST_ADDRESS)
00258                         receive_message(msg->source(), msg->payload_length(), msg->payload(), ex);
00259 
00260                     send_response_message(VIRTUAL_LINK_MESSAGE, msg->request_id(), COMMAND_SUCCESS, 0, NULL);
00261 
00262                     break;
00263                 }
00264                 case ENABLE_NODE:
00265                     enable_node(data + sizeof (block_data_t));
00266                     break;
00267                 case DISABLE_NODE:
00268                     disable_node(data + sizeof (block_data_t));
00269                     break;
00270                 case SET_VIRTUAL_LINK:
00271                     set_virtual_link(data + sizeof (block_data_t));
00272                     break;
00273                 case DESTROY_VIRTUAL_LINK:
00274                     destroy_virtual_link(data + sizeof (block_data_t));
00275                     break;
00276                 case ENABLE_PHYSICAL_LINK:
00277                     enable_physical_link(data + sizeof (block_data_t));
00278                     break;
00279                 case DISABLE_PHYSICAL_LINK:
00280                     disable_physical_link(data + sizeof (block_data_t));
00281                     break;
00282                 default:
00283                     uint8_t command_type = read<OsModel, block_data_t, uint8_t > (data);
00284                     uint8_t request_id = read<OsModel, block_data_t, uint8_t > (data + 1);
00285                     send_response_message(command_type, request_id, UNKNOWN_PARAMETER, 0, NULL);
00286 
00287                     break;
00288             }
00289         }
00290         // --------------------------------------------------------------------
00291 
00292         void send_response_message(uint8_t command_type, uint8_t request_id,
00293                 uint8_t result, uint8_t len, block_data_t* payload) {
00294 
00295             uint8_t buf_len = 3 + len;
00296             uint8_t uart_buf[buf_len];
00297 
00298             uart_buf[0] = command_type;
00299             uart_buf[1] = request_id;
00300             uart_buf[2] = result;
00301 
00302             memcpy(uart_buf + 3, payload, len);
00303 
00304             uart().write(buf_len, (uint8_t*) (&uart_buf));
00305         }
00306         // --------------------------------------------------------------------
00307 
00308         void enable_radio() {
00309 
00310             nodeactive_ = true;
00311             virtual_node_id_ = radio().id();
00312 
00313             radio().enable_radio();
00314             radio().template reg_recv_callback<self_type, &self_type::receive_message > (this);
00315             uart().enable_serial_comm();
00316             uart().template reg_read_callback<self_type, &self_type::rcv_uart_packet > (this);
00317         }
00318         // --------------------------------------------------------------------
00319 
00320         int set_channel(int channel) {
00321 
00322             return radio().set_channel(channel);
00323         }
00324         // --------------------------------------------------------------------
00325 
00326         void disable_radio() {
00327 
00328             nodeactive_ = false;
00329 
00330             uart().disable_serial_comm();
00331             radio().disable_radio();
00332         }
00333         // --------------------------------------------------------------------
00334 
00335         node_id_t id() {
00336 
00337             return radio().id();
00338         }
00339         // --------------------------------------------------------------------
00340 
00341         template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)>
00342         int reg_recv_callback(T *obj_pnt) {
00343             receivers_.push_back(radio_delegate_t::template from_method<T, TMethod > (obj_pnt));
00344             // TODO: return real id!
00345 
00346             return 0;
00347         }
00348         // --------------------------------------------------------------------
00349 
00350         template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*, ExtendedData const&) >
00351         int reg_recv_callback(T *obj_pnt) {
00352             extended_receivers_.push_back(extended_radio_delegate_iss_t::template from_method<T, TMethod > (obj_pnt));
00353             // TODO: return real id!
00354 
00355             return 0;
00356         }
00357         // --------------------------------------------------------------------
00358 
00359         void unreg_recv_callback(int idx) {
00360         }
00361 
00362     private:
00363 
00364         Radio& radio() {
00365 
00366             return *radio_;
00367         }
00368 
00369         Uart& uart() {
00370 
00371             return *uart_;
00372         }
00373 
00374         Debug& debug() {
00375             return *debug_;
00376         }
00377 
00378         Radio* radio_;
00379         Uart* uart_;
00380         Debug* debug_;
00381     };
00382 
00383 }
00384 
00385 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines