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