Wiselib
wiselib.testing/external_interface/isense/isense_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 CONNECTOR_ISENSE_EXTENDEDTXRADIOMODEL_H
00020 #define CONNECTOR_ISENSE_EXTENDEDTXRADIOMODEL_H
00021 
00022 #include "external_interface/isense/isense_types.h"
00023 #include "util/delegates/delegate.hpp"
00024 #include "config_testing.h"
00025 #include <isense/os.h>
00026 #include <isense/radio.h>
00027 #include <isense/hardware_radio.h>
00028 #include <isense/dispatcher.h>
00029 #include <isense/time.h>
00030 
00031 namespace wiselib {
00032 
00033     template<typename OsModel_P>
00034     class iSenseExtendedTxRadioModel
00035     : public isense::Receiver
00036 #ifdef DEBUG_ISENSE_EXTENDED_TX_RADIO
00037     , public isense::Sender
00038 #endif
00039     {
00040     public:
00041 
00042         class ExtendedData {
00043         public:
00044 
00045             ExtendedData() {
00046             }
00047 
00048             uint16 link_metric() const {
00049                 return link_metric_;
00050             };
00051 
00052             void set_link_metric(uint16 lm) {
00053                 link_metric_ = lm;
00054             };
00055 
00056         private:
00057             uint16 link_metric_;
00058         };
00059         // --------------------------------------------------------------------
00060         typedef OsModel_P OsModel;
00061 
00062         typedef iSenseExtendedTxRadioModel<OsModel> self_type;
00063         typedef self_type* self_pointer_t;
00064 
00065 #ifdef ISENSE_RADIO_ADDR_TYPE
00066         typedef ISENSE_RADIO_ADDR_TYPE node_id_t;
00067 #else
00068         typedef uint16 node_id_t;
00069 #endif
00070         typedef uint8 block_data_t;
00071         typedef uint8 size_t;
00072         typedef uint8 message_id_t;
00073 
00074         typedef delegate3<void, node_id_t, size_t, block_data_t*> isense_radio_delegate_t;
00075         typedef delegate4<void, node_id_t, size_t, block_data_t*,
00076         const ExtendedData&> extended_radio_delegate_t;
00077         typedef isense_radio_delegate_t radio_delegate_t;
00078         // --------------------------------------------------------------------
00079 
00080         enum ErrorCodes {
00081             SUCCESS = OsModel::SUCCESS,
00082             ERR_UNSPEC = OsModel::ERR_UNSPEC,
00083             ERR_NOTIMPL = OsModel::ERR_NOTIMPL
00084         };
00085         // --------------------------------------------------------------------
00086 
00087         enum {
00088             MAX_INTERNAL_RECEIVERS = 10
00089         };
00090 
00091         enum {
00092             MAX_EXTENDED_RECEIVERS = MAX_INTERNAL_RECEIVERS
00093         };
00094         // --------------------------------------------------------------------
00095 
00096         enum SpecialNodeIds {
00097             BROADCAST_ADDRESS = 0xffff, 
00098             NULL_NODE_ID = 0 
00099         };
00100         // --------------------------------------------------------------------
00101 
00102         enum Restrictions {
00103             MAX_MESSAGE_LENGTH = 116 
00104         };
00105         // --------------------------------------------------------------------
00106         class TxPower;
00107         // --------------------------------------------------------------------
00108 
00109         iSenseExtendedTxRadioModel(isense::Os& os)
00110         : os_(os) {
00111             os_.dispatcher().add_receiver(this);
00112 #ifdef ISENSE_EXTENDED_TX_RADIO_RANDOM_DELAY
00113             os_.srand(os_.id());
00114 #endif
00115         }
00116         // --------------------------------------------------------------------
00117 
00118         int
00119         send(node_id_t id, size_t len, block_data_t *data) {
00120 #ifdef ISENSE_EXTENDED_TX_RADIO_RANDOM_DELAY
00121          uint16 ms = os().rand(ISENSE_EXTENDED_TX_RADIO_RANDOM_DELAY_MAX);
00122          isense::Time t2, t1 = os().time();
00123 //          os().debug( "Radio: delay is %d at %d", ms, t1.ms() );
00124          do
00125          {
00126             t2 = os().time();
00127          } while ( t2.ms() - t1.ms() < ms );
00128 //          os().debug( "Radio: fin at %d", t2.ms() );
00129 #endif
00130 
00131 #ifdef DEBUG_ISENSE_EXTENDED_TX_RADIO
00132          uint8 options = isense::Radio::ISENSE_RADIO_TX_OPTION_NONE;
00133          if ( id != BROADCAST_ADDRESS )
00134             options |= isense::Radio::ISENSE_RADIO_TX_OPTION_ACK;
00135          os().radio().send( id, len, data, options, this );
00136 #else
00137             os().radio().send(id, len, data, 0, 0);
00138 #endif
00139             return SUCCESS;
00140         }
00141         // --------------------------------------------------------------------
00142 #ifdef DEBUG_ISENSE_EXTENDED_TX_RADIO
00143 
00144         virtual void confirm(uint8 state, uint8 tries, isense::Time time) {
00145             // some error values:
00146             //    ISENSE_RADIO_STATE_NO_ACK /**< No acknowledgement received when expected (0xE9) */
00147             //    ISENSE_RADIO_STATE_FRAME_TOO_LONG, /**< Frame too long after security processing to be sent (0xE5) */
00148             //    ISENSE_RADIO_STATE_CHANNEL_ACCESS_FAILURE /**< CSMA/CA channel access failure (0xE1) */
00149             //    ISENSE_RADIO_STATE_RADIO_NOT_ACTIVE /**< Radio switched off (0x00) */
00150             //    ISENSE_RADIO_STATE_BUFFER_OVERFLOW /**< Radio send queue full (0x01) */
00151 
00152             if (state != isense::Radio::ISENSE_RADIO_STATE_SUCCESS)
00153                 os().debug("Radio: SEND FAILED at %d state %d tries %d", os().id(), state, tries);
00154         }
00155 #endif
00156         // --------------------------------------------------------------------
00157 
00158         int enable_radio() {
00159             os().radio().enable();
00160             return SUCCESS;
00161         }
00162         
00163         // --------------------------------------------------------------------
00164         int set_channel(int channel) {
00165             if ((channel >= 11) && (channel <= 26)) {
00166                 os().radio().hardware_radio().set_channel(channel);
00167                 return channel;
00168             } else {
00169                 return -1;
00170             }
00171         }
00172         
00173         // --------------------------------------------------------------------
00174 
00175         int disable_radio() {
00176             os().radio().disable();
00177             return SUCCESS;
00178         }
00179         // --------------------------------------------------------------------
00180 
00181         node_id_t id() {
00182             return os().id();
00183         }
00184         // --------------------------------------------------------------------
00185         //---------- From concept VariablePowerRadio ------------
00186         int set_power(TxPower p);
00187         //-------------------------------------------------------
00188         TxPower power();
00189         //-------------------------------------------------------
00190 
00191         template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*)>
00192         int reg_recv_callback(T *obj_pnt) {
00193             for (int i = 0; i < MAX_INTERNAL_RECEIVERS; i++) {
00194                 if (!isense_radio_callbacks_[i]) {
00195                     isense_radio_callbacks_[i] =
00196                             isense_radio_delegate_t::template from_method<T, TMethod > (obj_pnt);
00197                     return i;
00198                 }
00199             }
00200             return -1;
00201         }
00202         // --------------------------------------------------------------------
00203 
00204         template<class T, void (T::*TMethod)(node_id_t, size_t, block_data_t*, const ExtendedData&) >
00205         int reg_recv_callback(T *obj_pnt) {
00206             for (int i = 0; i < MAX_EXTENDED_RECEIVERS; i++) {
00207                 if (!isense_ext_radio_callbacks_[i]) {
00208                     isense_ext_radio_callbacks_[i] =
00209                             extended_radio_delegate_t::template from_method<T, TMethod > (obj_pnt);
00210                     return i;
00211                 }
00212             }
00213             return -1;
00214         }
00215         // --------------------------------------------------------------------
00216 
00217         int unreg_recv_callback(int idx) {
00218             // TODO: Implement unregister - thereby different ids for receive
00219             //       with and without ExtendedData must be generated
00220             return ERR_NOTIMPL;
00221         }
00222         // --------------------------------------------------------------------
00223 #ifdef ISENSE_RADIO_ADDR_TYPE
00224         virtual void receive(uint8 len, const uint8 *buf,
00225                 ISENSE_RADIO_ADDR_TYPE src_addr, ISENSE_RADIO_ADDR_TYPE dest_addr,
00226                 uint16 signal_strength, uint16 signal_quality, uint8 sequence_no,
00227                 uint8 interface, isense::Time rx_time)
00228 #else
00229 
00230         virtual void receive(uint8 len, const uint8 *buf,
00231                 uint16 src_addr, uint16 dest_addr,
00232                 uint16 lqi, uint8 seq_no, uint8 interface)
00233 #endif
00234         {
00235             for (int i = 0; i < MAX_INTERNAL_RECEIVERS; i++) {
00236                 if (isense_radio_callbacks_[i])
00237                     isense_radio_callbacks_[i](src_addr, len, const_cast<uint8*> (buf));
00238             }
00239 
00240             ExtendedData ex;
00241             ex.set_link_metric(255 - signal_strength);
00242             for (int i = 0; i < MAX_EXTENDED_RECEIVERS; i++) {
00243                 if (isense_ext_radio_callbacks_[i])
00244                     isense_ext_radio_callbacks_[i](src_addr, len, const_cast<uint8*> (buf), ex);
00245             }
00246         }
00247 
00248     private:
00249 
00250         isense::Os& os() {
00251             return os_;
00252         }
00253         // --------------------------------------------------------------------
00254         isense::Os& os_;
00255         isense_radio_delegate_t isense_radio_callbacks_[MAX_INTERNAL_RECEIVERS];
00256         extended_radio_delegate_t isense_ext_radio_callbacks_[MAX_EXTENDED_RECEIVERS];
00257     };
00258     // --------------------------------------------------------------------
00259 
00265     template<typename OsModel_P>
00266     class iSenseExtendedTxRadioModel<OsModel_P>::TxPower {
00267     public:
00268         TxPower();
00269         TxPower(TxPower const &);
00270 
00271         TxPower &operator=(TxPower const &);
00272         bool operator==(TxPower) const;
00273         bool operator!=(TxPower) const;
00274         bool operator<=(TxPower) const;
00275         bool operator>=(TxPower) const;
00276         bool operator<(TxPower) const;
00277         bool operator>(TxPower) const;
00278         TxPower operator++();
00279         TxPower operator++(int);
00280         TxPower operator--();
00281         TxPower operator--(int);
00282 
00283         static TxPower from_ratio(int);
00284         void set_ratio(int);
00285         int to_ratio() const;
00286         static TxPower from_dB(int);
00287         void set_dB(int);
00288         int to_dB() const;
00289 
00290         static TxPower const MIN;
00291         static TxPower const MAX;
00292 
00293     private:
00294         TxPower(int);
00295 
00296         int value;
00297 
00298         friend class iSenseExtendedTxRadioModel<OsModel_P>;
00299     };
00300 
00301     template<typename OsModel_P>
00302             typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower const iSenseExtendedTxRadioModel<OsModel_P>::TxPower::MIN = -30;
00303 
00304     template<typename OsModel_P>
00305             typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower const iSenseExtendedTxRadioModel<OsModel_P>::TxPower::MAX = 0;
00306 
00307     template<typename OsModel_P>
00308     inline iSenseExtendedTxRadioModel<OsModel_P>::TxPower::TxPower(int v) : value(v) {
00309     }
00310 
00311     template<typename OsModel_P>
00312     inline iSenseExtendedTxRadioModel<OsModel_P>::TxPower::TxPower() : value(0) {
00313     }
00314 
00315     template<typename OsModel_P>
00316             inline typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower &iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator=(TxPower const &p) {
00317         value = p.value;
00318         return *this;
00319     }
00320 
00321     template<typename OsModel_P>
00322     inline iSenseExtendedTxRadioModel<OsModel_P>::TxPower::TxPower(TxPower const &power) : value(power.value) {
00323     }
00324 
00325     template<typename OsModel_P>
00326     inline bool iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator==(TxPower p) const {
00327         return value == p.value;
00328     }
00329 
00330     template<typename OsModel_P>
00331     inline bool iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator!=(TxPower p) const {
00332         return value != p.value;
00333     }
00334 
00335     template<typename OsModel_P>
00336     inline bool iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator<=(TxPower p) const {
00337         return value <= p.value;
00338     }
00339 
00340     template<typename OsModel_P>
00341     inline bool iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator>=(TxPower p) const {
00342         return value >= p.value;
00343     }
00344 
00345     template<typename OsModel_P>
00346     inline bool iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator<(TxPower p) const {
00347         return value < p.value;
00348     }
00349 
00350     template<typename OsModel_P>
00351     inline bool iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator>(TxPower p) const {
00352         return value > p.value;
00353     }
00354 
00355     template<typename OsModel_P>
00356     typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator++() {
00357         value += 6;
00358         return *this;
00359     }
00360 
00361     template<typename OsModel_P>
00362     typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator++(int) {
00363         TxPower p = *this;
00364         value += 6;
00365         return p;
00366     }
00367 
00368     template<typename OsModel_P>
00369     typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator--() {
00370         value -= 6;
00371         return *this;
00372     }
00373 
00374     template<typename OsModel_P>
00375     typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower iSenseExtendedTxRadioModel<OsModel_P>::TxPower::operator--(int) {
00376         TxPower p = *this;
00377         value -= 6;
00378         return p;
00379     }
00380 
00381     template<typename OsModel_P>
00382     typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower iSenseExtendedTxRadioModel<OsModel_P>::TxPower::from_ratio(int ratio) {
00383         if (ratio <= 1)
00384             return MIN;
00385         else if (ratio <= 4)
00386             return TxPower(-24);
00387         else if (ratio <= 16)
00388             return TxPower(-18);
00389         else if (ratio <= 63)
00390             return TxPower(-12);
00391         else if (ratio <= 251)
00392             return TxPower(-6);
00393         else
00394             return MAX;
00395     }
00396 
00397     template<typename OsModel_P>
00398     void iSenseExtendedTxRadioModel<OsModel_P>::TxPower::set_ratio(int ratio) {
00399         if (ratio <= 1)
00400             value = -30;
00401         else if (ratio <= 4)
00402             value = -24;
00403         else if (ratio <= 16)
00404             value = -18;
00405         else if (ratio <= 63)
00406             value = -12;
00407         else if (ratio <= 251)
00408             value = -6;
00409         else
00410             value = 0;
00411     }
00412 
00413     template<typename OsModel_P>
00414     int iSenseExtendedTxRadioModel<OsModel_P>::TxPower::to_ratio() const {
00415         switch (value) {
00416             case 0:
00417                 return 1000;
00418             case -6:
00419                 return 251;
00420             case -12:
00421                 return 63;
00422             case -18:
00423                 return 16;
00424             case -24:
00425                 return 4;
00426             default:
00427                 return 1;
00428         }
00429     }
00430 
00431     template<typename OsModel_P>
00432     typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower iSenseExtendedTxRadioModel<OsModel_P>::TxPower::from_dB(int db) {
00433         if (db <= -30)
00434             return MIN;
00435         else if (db <= -24)
00436             return TxPower(-24);
00437         else if (db <= -18)
00438             return TxPower(-18);
00439         else if (db <= -12)
00440             return TxPower(-12);
00441         else if (db <= -6)
00442             return TxPower(-6);
00443         else
00444             return MAX;
00445     }
00446 
00447     template<typename OsModel_P>
00448     void iSenseExtendedTxRadioModel<OsModel_P>::TxPower::set_dB(int db) {
00449         if (db <= -30)
00450             value = -30;
00451         else if (db <= -24)
00452             value = -24;
00453         else if (db <= -18)
00454             value = -18;
00455         else if (db <= -12)
00456             value = -12;
00457         else if (db <= -6)
00458             value = -6;
00459         else
00460             value = 0;
00461         //Another way: value=-(((-db)/6)*6);
00462     }
00463 
00464     template<typename OsModel_P>
00465     inline int iSenseExtendedTxRadioModel<OsModel_P>::TxPower::to_dB() const {
00466         return value;
00467     }
00468     // --------------------------------------------------------------------
00469 
00470     template<typename OsModel_P>
00471     int iSenseExtendedTxRadioModel<OsModel_P>::set_power(TxPower p) {
00472         os().radio().hardware_radio().set_power(p.value);
00473         return SUCCESS;
00474     }
00475 
00476     template<typename OsModel_P>
00477     typename iSenseExtendedTxRadioModel<OsModel_P>::TxPower iSenseExtendedTxRadioModel<OsModel_P>::power() {
00478         return TxPower(os().radio().hardware_radio().power());
00479     }
00480     //-------------------------------------------------------
00481 }
00482 
00483 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines