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 CONNECTOR_ISENSE_VIRTUALRADIOMODEL_H 00020 #define CONNECTOR_ISENSE_VIRTUALRADIOMODEL_H 00021 00022 #include "external_interface/isense/isense_types.h" 00023 #include "util/delegates/delegate.hpp" 00024 #include <isense/os.h> 00025 #include <isense/radio.h> 00026 #include <isense/dispatcher.h> 00027 #include <util/pstl/vector_static.h> 00028 #include <util/pstl/pair.h> 00029 00030 //to gateway: 00031 #define FRW_UNICAST_MSG 200 00032 #define FRW_BCAST_MSG 201 00033 00034 #define VRADIO_MSG_HEADER 4 // 2(for the vlink type msg) + 2 (and for the source vneigbor) 00035 00036 namespace wiselib { 00037 // ----------------------------------------------------------------------- 00038 // ----------------------------------------------------------------------- 00039 // ----------------------------------------------------------------------- 00040 static uint16_t GATEWAY_ADDRESS; 00041 static uint16_t nTxPacket; 00042 static uint16_t nRxPacketT1; 00043 static uint16_t nRxPacketT2; 00044 static uint16_t nRxPacketT3; 00045 static uint16_t nDropPackets; 00046 00047 static uint8_t payload[116]; 00048 static uint16_t vneighbors[8]; 00049 static uint8_t vneighbors_idx; 00050 00051 00057 template<typename OsModel_P, 00058 typename Radio_P = typename OsModel_P::Radio> 00059 class VirtualRadioModel { 00060 public: 00061 typedef OsModel_P OsModel; 00062 typedef typename OsModel::Os Os; 00063 typedef Radio_P Radio; 00064 typedef VirtualRadioModel <OsModel, Radio> self_type; 00065 00066 typedef typename Radio::node_id_t node_id_t; 00067 typedef typename Radio::size_t size_t; 00068 typedef typename Radio::block_data_t block_data_t; 00069 typedef radio_delegate_t vradio_delegate_t; 00070 00071 typedef vector_static<OsModel, vradio_delegate_t, 10> receivers_t; 00072 typedef typename receivers_t::iterator rcv_iterator; 00073 00074 typedef vector_static<OsModel, node_id_t, 10> virtual_links; 00075 typedef typename virtual_links::iterator iterator; 00076 00077 typedef vector_static<OsModel, node_id_t, 10> deactivated_links; 00078 typedef typename deactivated_links::iterator dl_iterator; 00079 00080 00081 static virtual_links vlinks; 00082 static deactivated_links dlinks; 00083 static receivers_t receivers; 00084 00085 enum ControlMessageTypes { 00086 SET_GW = 100, //set as the master gateway the sender 00087 SET_VLINK = 101, //set a new vlink 00088 USET_VLINK = 102, //remove a vlink 00089 SET_DLINK = 103, //deactivate a link 00090 USET_DLINK = 104 //activate a link 00091 }; 00092 // -------------------------------------------------------------------- 00093 enum SpecialNodeIds { 00094 BROADCAST_ADDRESS = Radio::BROADCAST_ADDRESS, 00095 NULL_NODE_ID = Radio::NULL_NODE_ID 00096 }; 00097 // -------------------------------------------------------------------- 00098 00099 enum Restrictions { 00100 // TODO: MAX_MESSAGE_LENGTH = Radio::MAX_MESSAGE_LENGTH - x; 00101 MAX_MESSAGE_LENGTH = 115 00102 //128 - 1(MSG_TYPE)-1(LEN)-2(S_ADDR)-2(D_ADDR) 00103 //-1(VLINK_MSG_TYPE) 00104 }; 00105 // -------------------------------------------------------------------- 00106 00107 static inline uint16_t 00108 getGW(void) 00109 { 00110 return GATEWAY_ADDRESS; 00111 } 00112 00113 static inline char * 00114 dumpStats(void) 00115 { 00116 char dump[140]; 00117 sprintf(dump,"nTxPacket=%d nRxPacketT1=%d nRxPacketT2=%d nRxPacketT3=%d dp=%d", 00118 nTxPacket, 00119 nRxPacketT1, 00120 nRxPacketT2, 00121 nRxPacketT3, 00122 nDropPackets); 00123 return dump; 00124 } 00125 00126 00127 static inline int 00128 findvneighbor(uint16_t addr) 00129 { 00130 for(int i=0;i<vneighbors_idx;i++) 00131 if(vneighbors[i]==addr) 00132 return i; 00133 00134 return -1; 00135 } 00136 00137 static inline void 00138 addvneighbor(uint16_t addr) 00139 { 00140 vneighbors[vneighbors_idx++]=addr; 00141 } 00142 00143 static inline void 00144 removevneighbor(uint16_t addr) 00145 { 00146 for(int i=0;i<vneighbors_idx;i++) 00147 if(vneighbors[i]==addr) 00148 { 00149 if(i!=(vneighbors_idx-1)) 00150 for(int z=i;z<(vneighbors_idx-1);z++) 00151 vneighbors[z] = vneighbors[z+1]; 00152 vneighbors_idx--; 00153 } 00154 } 00155 00156 static inline void 00157 send(Os *os, node_id_t id, size_t len, block_data_t *data) { 00158 00159 nTxPacket++; 00160 // sendToGw(os,100,id,len,data ); 00161 if(GATEWAY_ADDRESS!=0 && vneighbors_idx!=0) 00162 { 00163 if(id == BROADCAST_ADDRESS) 00164 sendToGw(os,FRW_BCAST_MSG,id,len,data); 00165 else 00166 { 00167 for(int i=0;i<vneighbors_idx;i++) 00168 { 00169 if(vneighbors[i]==id) 00170 { 00171 sendToGw(os,FRW_UNICAST_MSG,id,len,data); 00172 return; 00173 } 00174 } 00175 } 00176 } 00177 00178 Radio::send(os, id, len, data); 00179 // os->radio().send( id, len, data, 0, 0 ); 00180 }; 00181 // -------------------------------------------------------------------- 00182 00183 static inline void 00184 sendToGw(Os *os,uint8_t vlink_msg_type, node_id_t id, size_t len, block_data_t *data) { 00185 nRxPacketT2++; 00186 00187 payload[0] = 100; 00188 payload[1] = vlink_msg_type; 00189 memcpy(payload+2,&id,sizeof(node_id_t)); 00190 memcpy(payload+4,data,len); //FIX: check for msg len <113 00191 00192 Radio::send(os, GATEWAY_ADDRESS, len+VRADIO_MSG_HEADER, payload); 00193 } 00194 00195 // -------------------------------------------------------------------- 00196 static inline void enable(Os *os) { 00197 00198 // vlinks.push_back( 0 ); 00199 nTxPacket = 0; 00200 nRxPacketT1 = 0; 00201 nRxPacketT2 = 0; 00202 nRxPacketT3 = 0; 00203 nDropPackets = 0; 00204 00205 00206 Radio:: template reg_recv_callback <&self_type::vlink_rcv > (os); 00207 Radio::enable(os); 00208 GATEWAY_ADDRESS=0; 00209 vneighbors_idx=0; 00210 // Radio::template reg_recv_callback<self_type, &self_type::receive>( os(), this ); 00211 } 00212 00213 static inline void vlink_rcv(node_id_t id, size_t len, block_data_t* data) { 00214 00215 nRxPacketT1++; 00216 00217 if (data[0] == 100) { 00218 uint16_t v_dest = (uint16_t)(data[2]) << 8; 00219 v_dest = v_dest + (data[3]); 00220 // GATEWAY_ADDRESS = 0x9958; 00221 00222 switch(data[1]) { 00223 case SET_GW: 00224 00225 GATEWAY_ADDRESS = id; //TODO: if the node is listening >1 gateways 00226 //choose the one that has better LQI/RSSI 00227 break; 00228 case SET_VLINK: 00229 addvneighbor(v_dest); 00230 break; 00231 00232 case USET_VLINK: 00233 removevneighbor(v_dest); 00234 break; 00235 00236 case SET_DLINK: 00237 00238 dlinks.push_back(v_dest); 00239 break; 00240 00241 case FRW_UNICAST_MSG: 00242 for(rcv_iterator it= receivers.begin();it!=receivers.end();it++) 00243 (*it)(v_dest,len-VRADIO_MSG_HEADER,data+VRADIO_MSG_HEADER);//add destination ?? 00244 break; 00245 00246 case FRW_BCAST_MSG: 00247 for(rcv_iterator it= receivers.begin();it!=receivers.end();it++) 00248 (*it)(v_dest,len-VRADIO_MSG_HEADER,data+VRADIO_MSG_HEADER);//add destination ?? 00249 break; 00250 00251 case USET_DLINK: 00252 nRxPacketT3++; 00253 00254 for(dl_iterator it= dlinks.begin();it!=dlinks.end();it++) 00255 if((*it) == v_dest) 00256 (*it) = 0; 00257 // dlinks.insert(it,0); 00258 //TODO: add proper remove 00259 break; 00260 00261 default: 00262 ; 00263 } 00264 00265 } 00266 else 00267 { 00268 00269 for(dl_iterator it= dlinks.begin();it!=dlinks.end();it++) 00270 if((*it) == id) 00271 { 00272 nDropPackets++; 00273 return; 00274 } 00275 for(rcv_iterator it= receivers.begin();it!=receivers.end();it++) 00276 (*it)(id,len,data); 00277 } 00278 } 00279 00280 // -------------------------------------------------------------------- 00281 00282 static inline void disable(Os *os) { 00283 Radio::disable(os()); 00284 } 00285 00286 // -------------------------------------------------------------------- 00287 00288 static inline node_id_t id(Os *os) { 00289 00290 return Radio::id(os); 00291 } 00292 00293 // -------------------------------------------------------------------- 00294 00295 template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)> 00296 static inline int reg_recv_callback(Os *os, T *obj_pnt) 00297 { 00298 receivers.push_back( vradio_delegate_t::from_method<T, TMethod>( obj_pnt ) ); 00299 // TODO: return real idx! 00300 return 0; 00301 }; 00302 // -------------------------------------------------------------------- 00303 00304 static inline void unreg_recv_callback(Os *os, int idx) { 00305 //Radio::unreg_recv_callback(os, idx); 00306 // os->dispatcher().remove_receiver( &isense_radio_callbacks[idx] ); 00307 }; 00308 00309 00310 }; 00311 } 00312 00313 #endif