Wiselib
wiselib.testing/util/wisebed_node_api/onehop_virtual_radio.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 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines