Wiselib
wiselib.testing/algorithms/routing/autocast/autocast_algorithm.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 
00020 #ifndef __AUTOCAST_ALGORITHM_H__
00021 #define __AUTOCAST_ALGORITHM_H__
00022 
00023 #include "util/base_classes/routing_base.h"
00024 #include "util/delegates/delegate.hpp"
00025 
00026 #include "util/pstl/vector_static.h"
00027 
00028 #include "data_unit.h"
00029 #include "autocast_message.h"
00030 
00031 // the max size of vector to save the data units and hash values
00032 #define MAX_VECTOR_SIZE 15
00033 
00034 #define DELTA 8
00035 
00036 #define MSG_ID 112
00037 // 
00038 #define BEACON_TIMER_NR 0
00039 #define FLOOD_TIMER_NR 1
00040 #define ANSWER_TIMER_NR 2
00041 #define REQUEST_TIMER_NR 3
00042 #define NUM_TIMER 4
00043 
00044 typedef wiselib::OSMODEL Os;
00045 
00046 namespace wiselib
00047 {
00058    template<typename OsModel_P,
00059             typename Radio_P = typename OsModel_P::Radio,
00060             typename Timer_P = typename OsModel_P::Timer,
00061             typename Debug_P = typename OsModel_P::Debug>
00062    class AutoCast
00063       : public RoutingBase<OsModel_P, Radio_P>
00064    {
00065 
00066    public:
00067       typedef OsModel_P OsModel;
00068       typedef Radio_P Radio;
00069       typedef Timer_P Timer;
00070       typedef Debug_P Debug;
00071 
00072       typedef AutoCast<OsModel, Radio_P, Timer, Debug> self_type;
00073       typedef self_type* self_pointer_t;
00074 
00075       typedef typename Radio::node_id_t node_id_t;
00076       typedef typename Radio::size_t size_t;
00077       typedef typename Radio::block_data_t block_data_t;
00078       typedef typename Radio::message_id_t message_id_t;
00079 
00080       typedef typename Timer::millis_t millis_t;
00081       //------------------------------------------------------------
00082       //---------------------------------------------------------------
00083       typedef wiselib::AutoCast_Message<OsModel, Radio, Debug> Message;
00084 
00085       typedef DataUnit<Os, Radio> dataUnit_t;
00086       
00087       // for the callback functions 
00088       typedef delegate1<uint8_t, dataUnit_t*> radio_delegate_t;
00089 
00090       typedef uint8_t hash_Value_t;
00091 
00092       typedef wiselib::vector_static<Os, dataUnit_t, MAX_VECTOR_SIZE> dataUnit_list_t;
00093 
00094       typedef wiselib::vector_static<Os, dataUnit_t*, MAX_VECTOR_SIZE> dataUnit_list_ptr_t;
00095 
00096       typedef wiselib::vector_static<Os, hash_Value_t, MAX_VECTOR_SIZE> dataHash_list_t;
00097    
00098       typedef typename dataUnit_list_t::iterator iterator_dataUnit;
00099       typedef typename dataHash_list_t::iterator iterator_dataHash;
00100 
00101       typedef wiselib::TriSOSClockModel<Os> c_time_t;
00102       
00103       //----------------------------------------------------------
00104       //----------------------------------------------------------
00105 
00106 
00107       // --------------------------------------------------------------------
00108       enum ErrorCodes
00109       {
00110          SUCCESS = OsModel::SUCCESS,
00111          ERR_UNSPEC = OsModel::ERR_UNSPEC,
00112          ERR_NOTIMPL = OsModel::ERR_NOTIMPL,
00113          ERR_HOSTUNREACH = OsModel::ERR_HOSTUNREACH
00114       };
00115       // --------------------------------------------------------------------
00116       enum SpecialNodeIds {
00117          BROADCAST_ADDRESS = Radio_P::BROADCAST_ADDRESS, 
00118          NULL_NODE_ID      = Radio_P::NULL_NODE_ID      
00119       };
00120      
00121       // --------------------------------------------------------------------
00124       AutoCast();
00125       ~AutoCast();
00127 
00128       int init( Radio& radio, Timer& timer, Debug& debug )
00129       {
00130          radio_ = &radio;
00131          timer_ = &timer;
00132          debug_ = &debug;
00133          return SUCCESS;
00134       }
00135 
00136     //   Callback functions for the getstate function in the application
00137    //------------------------------------------------------
00138    //-----------------------------------------------------
00139       template<class T, uint8_t (T::*TMethod)(dataUnit_t*)>
00140       int reg_getstate_callback( T *obj_pnt )
00141       {
00142 
00143        if ( callback == NULL )
00144        {
00145          callback = radio_delegate_t();
00146        }
00147 
00148          if ( callback == radio_delegate_t())
00149          {
00150              callback = radio_delegate_t::template from_method<T, TMethod>( obj_pnt);
00151           
00152              return 0;
00153          }
00154          return -1;
00155       }
00156       // --------------------------------------------------------------------
00157       int unreg_state_callback()
00158       {
00159          return SUCCESS;
00160       }
00161       // --------------------------------------------------------------------
00162        uint8_t notify_getstate(dataUnit_t *du)
00163       {
00164          if ( callback != radio_delegate_t())
00165        {
00166 
00167             return (callback)(du);
00168        }
00169       }
00170    //-----------------------------------------------------------------------
00171    //-----------------------------------------------------------------------
00172 
00173 
00174       inline int init();
00175       inline int destruct();
00176 
00179       int enable_radio( void );
00180       int disable_radio( void );
00181 
00184 
00186       int send( node_id_t receiver, size_t len, block_data_t *data );
00189       void receive( node_id_t from, size_t len, block_data_t *data );
00192       typename Radio::node_id_t id()
00193       { return radio_->id(); }
00195 
00196 
00197    private:
00198 
00199       Radio& radio()
00200       { return *radio_; }
00201 
00202       Timer& timer()
00203       { return *timer_; }
00204 
00205       Debug& debug()
00206       { return *debug_; }
00207 
00208       typename Radio::self_pointer_t radio_;
00209       typename Timer::self_pointer_t timer_;
00210       typename Debug::self_pointer_t debug_;
00211 
00212      uint8_t numberOfData;
00213 
00214      c_time_t c_time;
00215 
00216      dataUnit_list_t setDataUnits;  
00217      dataUnit_list_t setStaleDataUnits;
00218      dataUnit_list_ptr_t setDUsForSend;
00219 
00220      dataUnit_list_ptr_t setNewDataUnits; 
00221 
00222      dataHash_list_t setReqHashes;
00223 
00224      bool find_InSetDataUnits(hash_Value_t hashValue);
00225      
00226      bool find_InSetStaleDataUnits(hash_Value_t hashValue);
00227 
00228      void onTimerExpired();
00229 
00230      void deltaTimerElapsed( void* userdata);
00231 
00232      void updateDataUnits();
00233      
00234      // to save, that the timer allready set or not (rrue)
00235      bool timerPending[NUM_TIMER];
00236      // to save the expire time for all timer
00237      millis_t timerExpireTime[NUM_TIMER];
00238 
00239      // timer function to expire, cancel and test the validit of the 4 actions (Beacon, Requesr, Answer and flood)
00240      // ---------------------------------------------------
00241      void expireIn(uint8_t timerNr, millis_t timedelta);
00242 
00243      bool isPending(uint8_t timerNr);
00244 
00245      void cancel(uint8_t timerNr);
00246      //----------------------------------------------------
00247 
00248      radio_delegate_t callback;
00249      // auxiliary variable to check, that the element already in msg.setHashes.
00250      bool element_is_in_setDUsForSend;
00251      // auxiliary variable to check, that the element already in msg.setDUsForSend.
00252      bool element_is_in_msgSetH;
00253       // auxiliary variable to check, that the element already in msg.setDataUnits.
00254       // use for the setDataUnits
00255      bool element_is_in_msgSetDU;
00256      // auxiliary variable to check, that the element already in msg.setStaleHashes.
00257      bool element_is_in_msgSetSH;
00258       // auxiliary variable to check, that the element already in msg.setDataUnits.
00259       // use for the setReqHashes
00260      bool element_is_in_msgSetDU_1;
00261    };
00262    // -----------------------------------------------------------------------
00263    // -----------------------------------------------------------------------
00264    // -----------------------------------------------------------------------
00265    template<typename OsModel_P,
00266          
00267             typename Radio_P,
00268             typename Timer_P,
00269             typename Debug_P>
00270    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00271    AutoCast()
00272       : radio_ ( 0 ),
00273          timer_ ( 0 ),
00274          debug_ ( 0 )
00275    {}
00276    // -----------------------------------------------------------------------
00277    template<typename OsModel_P,
00278             
00279             typename Radio_P,
00280             typename Timer_P,
00281             typename Debug_P>
00282    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00283    ~AutoCast()
00284    {
00285 
00286 #ifdef ROUTING_AUTOCAST_DEBUG
00287       debug().debug( "AutoCast: Destroyed\n" );
00288 #endif
00289    }
00290    // -----------------------------------------------------------------------
00291    template<typename OsModel_P,
00292             
00293             typename Radio_P,
00294             typename Timer_P,
00295             typename Debug_P>
00296    int
00297    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00298    init( void )
00299    {
00300       enable_radio();
00301 
00302       return SUCCESS;
00303    }
00304    // -----------------------------------------------------------------------
00305    template<typename OsModel_P,
00306             
00307             typename Radio_P,
00308             typename Timer_P,
00309             typename Debug_P>
00310    int
00311    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00312    destruct( void )
00313 
00314    {
00315       return disable_radio();
00316    }
00317    // -----------------------------------------------------------------------
00318    template<typename OsModel_P,
00319            
00320             typename Radio_P,
00321             typename Timer_P,
00322             typename Debug_P>
00323    int
00324    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00325    enable_radio( void )
00326    {
00327 
00328 #ifdef ROUTING_AUTOCAST_DEBUG
00329       debug().debug( "AutoCast: Boot for %i\n", radio().id() );
00330 #endif
00331       radio().enable_radio();
00332       radio().template reg_recv_callback<self_type, &self_type::receive>( this );
00333 
00334      //reg_getstate_callback<self_type, &self_type::updateDataUnits>( this ); 
00335    
00336      // intialisierung of all auxiliary variables
00337      element_is_in_msgSetH = false;
00338      element_is_in_setDUsForSend = false;
00339      element_is_in_msgSetDU = false;
00340      element_is_in_msgSetSH = false;
00341      element_is_in_msgSetDU = false;
00342      
00343       expireIn(BEACON_TIMER_NR,5000);
00344 
00345      timer().template set_timer<self_type, &self_type::deltaTimerElapsed>(DELTA, this, 0 );
00346 
00347 
00348       return SUCCESS;
00349    }
00350 
00351    // -----------------------------------------------------------------------
00352    template<typename OsModel_P,
00353             
00354             typename Radio_P,
00355             typename Timer_P,
00356             typename Debug_P>
00357    int
00358    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00359    disable_radio( void )
00360    {
00361 
00362 #ifdef ROUTING_AUTOCAST_DEBUG
00363       debug().debug( "AutoCast: Disable\n" );
00364 #endif
00365       return ERR_NOTIMPL;
00366    }
00367 /* --------------------------------------------------------------------
00368    this function contains the timer. This timer will be called periodic for the time DELTA
00369    and test, that the one time of the furth timers allready expired, if yes then call the function
00370    onTimerExpired() and canceld all other timer expect the beacon timer
00371     -----------------------------------------------------------------------*/
00372    template<typename OsModel_P,
00373            
00374             typename Radio_P,
00375             typename Timer_P,
00376             typename Debug_P>
00377    void
00378    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00379    deltaTimerElapsed( void* userdata)
00380    {
00381       millis_t t = c_time.time();
00382       millis_t time = (c_time.seconds(t) * 1000) + c_time.milliseconds(t);
00383 
00384       if( (time > timerExpireTime[BEACON_TIMER_NR] && isPending(BEACON_TIMER_NR)) ||
00385             (time > timerExpireTime[FLOOD_TIMER_NR] && isPending(FLOOD_TIMER_NR))   ||
00386             (time > timerExpireTime[ANSWER_TIMER_NR] && isPending(FLOOD_TIMER_NR))  ||
00387             (time > timerExpireTime[REQUEST_TIMER_NR] && isPending(REQUEST_TIMER_NR)) )
00388       {
00389          onTimerExpired();
00390          
00391       }
00392 
00393       timer().template set_timer<self_type, &self_type::deltaTimerElapsed>(DELTA, this, 0 );
00394    
00395    }
00396 
00397 /* -----------------------------------------------------------------------
00398    this function test, that the max life time of all data units in setDataUnits
00399    expired, if yes then remove it from setDataUnits and put it in setStaleDataUnits 
00400    -----------------------------------------------------------------------*/
00401    template<typename OsModel_P,
00402            
00403             typename Radio_P,
00404             typename Timer_P,
00405             typename Debug_P>
00406    void
00407    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00408    updateDataUnits()
00409    {
00410       // data units are unintersting 
00411       for(int i =0; i< setDataUnits.size(); i++){
00412 
00413          if(notify_getstate(&(setDataUnits[i])) == dataUnit_t::STALE /*&& !find_InSetStaleDataUnits(setDataUnits[i].getHashValue())*/){
00414             
00415             setStaleDataUnits.push_back(setDataUnits[i]);
00416             setDataUnits.erase(setDataUnits.begin()+i);
00417          }else{
00418             if(notify_getstate(&(setDataUnits[i])) == dataUnit_t::INVALID)
00419                
00420                setDataUnits.erase(setDataUnits.begin()+i);
00421          }
00422       }
00423 
00424       // uninteresting data units
00425       for(int j =0; j < setStaleDataUnits.size(); j++){
00426 
00427          if(notify_getstate(&(setStaleDataUnits[j])) == dataUnit_t::VALID /* && !find_InSetDataUnits(setStaleDataUnits[j].getHashValue())*/){
00428             
00429             // again interesting
00430             setDataUnits.push_back(setStaleDataUnits[j]);
00431             setStaleDataUnits.erase(setStaleDataUnits.begin()+j);
00432          }
00433          else{
00434             
00435             if(notify_getstate(&(setStaleDataUnits[j])) == dataUnit_t::INVALID){
00436                
00437                // data unit from set of stale data units will be final deleted
00438                setStaleDataUnits.erase(setStaleDataUnits.begin()+j);
00439             }
00440          }
00441       }
00442 
00443     }
00444 
00445 /* -----------------------------------------------------------------------
00446    this function test, that the given data unit is already in setDataUnits,
00447    if yes then return true otherwise false
00448    -----------------------------------------------------------------------*/
00449    template<typename OsModel_P,
00450            
00451             typename Radio_P,
00452             typename Timer_P,
00453             typename Debug_P>
00454    bool
00455    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00456    find_InSetDataUnits(hash_Value_t hashValue)
00457    {
00458       for(iterator_dataUnit it= setDataUnits.begin(); it != setDataUnits.end(); ++it)
00459       {  
00460          if(it->getHashValue() ==  hashValue)
00461          {
00462             return true;
00463          }
00464        }
00465       return false;  
00466    }
00467 
00468 /* -----------------------------------------------------------------------
00469    this function test, that the given data unit is already in setStaleDataUnits,
00470    if yes then return true otherwise false
00471    -----------------------------------------------------------------------*/
00472    template<typename OsModel_P,
00473            
00474             typename Radio_P,
00475             typename Timer_P,
00476             typename Debug_P>
00477    bool
00478    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00479    find_InSetStaleDataUnits(hash_Value_t hashValue)
00480    {
00481       for(iterator_dataUnit it= setStaleDataUnits.begin(); it != setStaleDataUnits.end(); ++it)
00482       {
00483          if(it->getHashValue() ==  hashValue)
00484          {
00485             return true;
00486          }
00487        }
00488       return false;  
00489    }
00490 /* --------------------------------------------------------------------
00491    this function move the time to the given timedelta for one given timer number
00492    and saver it in the array timerExpireTime
00493     -----------------------------------------------------------------------*/
00494    template<typename OsModel_P,
00495             
00496             typename Radio_P,
00497             typename Timer_P,
00498             typename Debug_P>
00499    void
00500    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00501    expireIn(uint8_t timerNr, millis_t timedelta)
00502    {  
00503       timerPending[timerNr]=true;
00504       millis_t t = c_time.time();
00505       millis_t time = (c_time.seconds(t) * 1000) + c_time.milliseconds(t);
00506       time+=timedelta;
00507       timerExpireTime[timerNr]= time;
00508 
00509    } 
00510 /* ----------------------------------------------------------------------- 
00511    set the timer of false for the given timer number
00512    -----------------------------------------------------------------------*/
00513    template<typename OsModel_P,
00514             
00515             typename Radio_P,
00516             typename Timer_P,
00517             typename Debug_P>
00518    void
00519    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00520    cancel(uint8_t timerNr)
00521    {  
00522    timerPending[timerNr]=false;
00523       
00524    }
00525 
00526 /* ----------------------------------------------------------------------- 
00527    return true if the timer number allready set otherwise false
00528    -----------------------------------------------------------------------*/
00529    template<typename OsModel_P,
00530             
00531             typename Radio_P,
00532             typename Timer_P,
00533             typename Debug_P>
00534    bool
00535    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00536    isPending(uint8_t timerNr)
00537    {  
00538       return timerPending[timerNr];
00539    }
00540 /* ----------------------------------------------------------------------- 
00541    this function will be called after every action (flood, answer, request and beacon timer).
00542    Greate and send the message
00543    -----------------------------------------------------------------------*/
00544    template<typename OsModel_P,
00545             
00546             typename Radio_P,
00547             typename Timer_P,
00548             typename Debug_P>
00549    void
00550    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00551    onTimerExpired()
00552    {  
00553       updateDataUnits();
00554 
00555       // cancel all timers, it dose not need more timer, message will be send
00556       cancel(FLOOD_TIMER_NR);
00557       cancel(ANSWER_TIMER_NR);
00558       cancel(REQUEST_TIMER_NR);
00559       
00560       // generate a message with the number of byte of the hash value
00561       Message message(sizeof(hash_Value_t));
00562 
00563       // add the stale data Unit from setStaleDUsForSend to the message
00564       for(int i = 0; i < setStaleDataUnits.size(); i++){
00565          
00566          hash_Value_t hv_stale = setStaleDataUnits[i].getHashValue();
00567 
00568          message.addStaleDataHash((block_data_t *) &(hv_stale));
00569       }     
00570 
00571       // add the hash value of all data unit from setDataUnit to the message
00572       for(iterator_dataUnit it = setDataUnits.begin(); it != setDataUnits.end(); ++it){
00573 
00574          hash_Value_t hv_DataUnit = it->getHashValue();
00575 
00576          for(int i=0; i < setDUsForSend.size(); i++){
00577 
00578             if(hv_DataUnit == setDUsForSend[i]->getHashValue()){
00579                
00580                element_is_in_setDUsForSend = true; //TODO
00581             }
00582          }
00583          // if the data unit from setDataUnits is not in setDUsForSend
00584          if(!element_is_in_setDUsForSend){
00585 
00586             // then add it to the message
00587             message.addDataHash((block_data_t *) &(hv_DataUnit));
00588          }  
00589       }
00590       
00591       element_is_in_setDUsForSend = false;   
00592 
00593       // add the data from setDUsForSend to the message
00594       for(int i = 0; i < setDUsForSend.size(); i++){
00595 
00596          message.addDataUnit(setDUsForSend[i]->buffer_size() , (block_data_t *) (setDUsForSend[i]));
00597 
00598       }
00599 
00600       // output to test the protocol
00601       // ----------------------------------------------------
00602       for(int i=0; i < setDataUnits.size(); i++){
00603 
00604          debug_->debug( " %d / ",setDataUnits[i].getHashValue());
00605       }
00606 
00607       // output to test the protocol
00608       // ----------------------------------------------------
00609       for(int i=0; i < setStaleDataUnits.size(); i++){
00610 
00611          debug_->debug( "\nStaleDU  %d / ",setStaleDataUnits[i].getHashValue());
00612       }
00613 
00614       // send the message
00615          radio().send( radio().BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*) &message);
00616       debug_->debug( "\n message sent \n");
00617 
00618       
00619       // clear setDUsForSend
00620       setDUsForSend.clear();
00621       // clear setReqHashes
00622       setReqHashes.clear();
00623 
00624       // set the beacon time of 5 seconds again
00625        expireIn(BEACON_TIMER_NR,5000);
00626 
00627    }
00628  
00629 // ----------------------------------------------------------------------- 
00630 // -----------------------------------------------------------------------
00631    template<typename OsModel_P,
00632             
00633             typename Radio_P,
00634             typename Timer_P,
00635             typename Debug_P>
00636    int
00637    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00638    send( node_id_t destination, size_t len, block_data_t *data)
00639    {
00640       
00641 #ifdef ROUTING_AUTOCAST_DEBUG
00642       debug().debug( "AutoCast: Send at %d\n", radio_->id() );
00643 #endif
00644 
00645       dataUnit_t *du = (dataUnit_t*)data; 
00646 
00647       //dataUnit with the same node_id already in list?
00648       if(!find_InSetDataUnits(du->getHashValue())){
00649                
00650          setDataUnits.push_back(*du);
00651          // save the data unit in setDUsForSend
00652          setDUsForSend.push_back(&(setDataUnits.back()));
00653       }
00654 
00655          return SUCCESS;
00656    }
00657 // ----------------------------------------------------------------------- 
00658 // -----------------------------------------------------------------------
00659   template<typename OsModel_P,
00660             
00661             typename Radio_P,
00662             typename Timer_P,
00663             typename Debug_P>
00664    void
00665    AutoCast<OsModel_P, Radio_P,Timer_P, Debug_P>::
00666    receive( node_id_t from, size_t len, block_data_t *data)
00667    {  
00668          Message *message = (Message*)data;
00669 
00670 /*       for(int i=0; i<len; i++){
00671 
00672             debug_->debug("%d: %d(%c) \n", i, (uint8_t) data[i],(char) data[i]);
00673          }
00674 */
00675       if(message->getMessageId() == MSG_ID){
00676 
00677          // intialization of the auxiliary variable for the number of hash value to answer or to request
00678          uint8_t nrOfHashesForAnswer = 0;
00679          uint8_t nrOfHashesForRequst = 0;
00680          
00681 
00682          // delay the planned actions to avoid the overhead of tha radio channel
00684          if(isPending(FLOOD_TIMER_NR)){
00685             expireIn(FLOOD_TIMER_NR,2 * DELTA);
00686          }
00687          if(isPending(ANSWER_TIMER_NR)){
00688             expireIn(ANSWER_TIMER_NR, DELTA);
00689          }
00690          if(isPending(REQUEST_TIMER_NR)){
00691             expireIn(REQUEST_TIMER_NR, 3 * DELTA);
00692          }
00693          
00694          // sort the received data units        
00696          for(int i = 0; i < message->getNrOfDataUnits(); i++){
00697             
00698             dataUnit_t *du = (dataUnit_t*) message->getDataUnit(i);
00699 
00700             // is the data unit from message already in setDataUnits or in setStaleDataUnits ?
00701             if(!find_InSetDataUnits(du->getHashValue()) && !find_InSetStaleDataUnits(du->getHashValue())){
00702 
00703                // callback function to check the validation of the data unit
00704                if(notify_getstate(du) == dataUnit_t::VALID){
00705                   
00706                   setDataUnits.push_back(*du);
00707                   // add the new data unit to th set setNewDataUnit
00708                   setNewDataUnits.push_back(&(setDataUnits.back()));
00709 
00710                   notify_receivers(radio_->id(), du->buffer_size(), (block_data_t *) du );
00711                }
00712                else{
00713                   if(notify_getstate(du) == dataUnit_t::STALE){
00714 
00715                      setStaleDataUnits.push_back(*du);
00716                   }
00717                }
00718             }
00719             }
00720          
00721          // Flood action
00722          //---------------------------------------------------------------------------
00723          //---------------------------------------------------------------------------
00724          if(setNewDataUnits.size() > 0){
00725 
00726             for(int j=0; j< setNewDataUnits.size(); j++){
00727                
00728                // add the new data units to the set "setDUsForSend"
00729                setDUsForSend.push_back((setNewDataUnits.at(j)));
00730             }
00731             // 
00732              expireIn( FLOOD_TIMER_NR, 2 * DELTA); 
00733 
00734              debug_->debug( "flood is finish \n");
00735          }
00736       
00737          setNewDataUnits.clear();
00738 
00739          
00740          // Answer action
00741          //---------------------------------------------------------------------------
00742          //--------------------------------------------------------------------------
00743          for(int k=0; k < setDataUnits.size(); k++){
00744             
00745             // to check, that the data unit is already in msg.setHashes.
00746             for(int i = 0; i< message->getNrOfDataHashes(); i++){
00747                
00748                hash_Value_t *temp = (hash_Value_t *) message->getDataHash(i);
00749 
00750                if(setDataUnits[k].getHashValue() == *temp){
00751 
00752                   element_is_in_msgSetH = true;  // TODO wenn das Element gefunden wurde soll nicht meher suchen (raus springen von for schleife)
00753                }
00754             }
00755             // to check, that the data unit is already in msg.setDataUnits.
00756             for(int j = 0; j< message->getNrOfDataUnits(); j++){
00757                
00758                 dataUnit_t *du = (dataUnit_t *) message->getDataUnit(j);
00759 
00760                if(setDataUnits[k].getHashValue() == du->getHashValue()){
00761 
00762                   element_is_in_msgSetDU = true;  // TODO wenn das Element gefunden wurde soll nicht meher suchen (raus springen von for schleife)
00763                }
00764             }
00765             // to check, that the data unit is already in msg.setStaleHashes.
00766             for(int v = 0; v < message->getNrOfStaleHashes(); v++){
00767                
00768                 dataUnit_t *du = (dataUnit_t *) message->getStaleDataHash(v);
00769 
00770                if(setDataUnits[k].getHashValue() == du->getHashValue()){
00771 
00772                   element_is_in_msgSetSH = true;  // TODO wenn das Element gefunden wurde soll nicht meher suchen (raus springen von for schleife)
00773                }
00774             }
00775 
00776             // if the the data unit from setDataUnits is not already in msg.setHashVales, meg.setDataUnits or in msg.setStaleDataUnits available 
00777             if(!element_is_in_msgSetH && !element_is_in_msgSetDU && !element_is_in_msgSetSH){
00778 
00779                setDUsForSend.push_back(&(setDataUnits.at(k)));
00780                nrOfHashesForAnswer++;
00781             }
00782          }
00783 
00784          if(nrOfHashesForAnswer > 0){
00785 
00786             expireIn( ANSWER_TIMER_NR, DELTA);
00787             debug_->debug( "answer is finish \n");
00788          }
00789 
00790          // set the auxiliary variable of false again to be ready for the next message
00791          element_is_in_msgSetH = false;
00792          element_is_in_msgSetDU = false;
00793          element_is_in_msgSetSH = false;        
00794 
00795          // Request action
00796          //---------------------------------------------------------------------------
00797          //---------------------------------------------------------------------------
00798          for(int i = 0; i< message->getNrOfDataHashes(); i++){
00799 
00800             hash_Value_t *temp = (hash_Value_t *) message->getDataHash(i);
00801 
00802             if(!find_InSetDataUnits(*temp) && !find_InSetStaleDataUnits(*temp)){
00803 
00804                setReqHashes.push_back(*temp);
00805                nrOfHashesForRequst++;
00806             }
00807          }
00808 
00809          if(nrOfHashesForRequst > 0){
00810 
00811             expireIn( REQUEST_TIMER_NR, 3 * DELTA);
00812             debug_->debug( "request is finish \n");
00813          }
00814 
00815          // Request cancel
00816          //---------------------------------------------------------------------------
00817          //---------------------------------------------------------------------------
00818          for(int i=0; i < setReqHashes.size(); i++){
00819 
00820             
00821             for(int j = 0; j< message->getNrOfDataUnits(); j++){
00822                
00823                dataUnit_t *du = (dataUnit_t *) message->getDataUnit(j);
00824 
00825                if(setReqHashes[i] == du->getHashValue()){
00826 
00827                   element_is_in_msgSetDU_1 = true;
00828                }
00829             }
00830             if(element_is_in_msgSetDU_1){
00831 
00832                setReqHashes.erase(setReqHashes.begin()+i);
00833             }
00834          }
00835          // if the set of the request hashes is zero (no hash value more )
00836          if(setReqHashes.size() == 0){
00837             
00838             cancel(REQUEST_TIMER_NR);
00839             //debug_->debug( "cancel request \n");
00840          }
00841 
00842          // set the auxiliary variable of false again to be ready for the next message
00843          element_is_in_msgSetDU_1 = false;
00844       }  
00845    }
00846 
00847 }
00848 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines