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