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