• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

daemon/src/routing/RetransmissionExtension.cpp

Go to the documentation of this file.
00001 /*
00002  * RetransmissionExtension.cpp
00003  *
00004  *  Created on: 09.03.2010
00005  *      Author: morgenro
00006  */
00007 
00008 #include "routing/RetransmissionExtension.h"
00009 #include "core/TimeEvent.h"
00010 #include "routing/RequeueBundleEvent.h"
00011 #include "net/TransferAbortedEvent.h"
00012 #include "net/TransferCompletedEvent.h"
00013 #include "core/BundleExpiredEvent.h"
00014 #include "ibrdtn/utils/Clock.h"
00015 #include "ibrdtn/data/Exceptions.h"
00016 
00017 namespace dtn
00018 {
00019         namespace routing
00020         {
00021                 RetransmissionExtension::RetransmissionExtension()
00022                 {
00023                 }
00024 
00025                 RetransmissionExtension::~RetransmissionExtension()
00026                 {
00027                 }
00028 
00029                 void RetransmissionExtension::notify(const dtn::core::Event *evt)
00030                 {
00031                         try {
00032                                 const dtn::core::TimeEvent &time = dynamic_cast<const dtn::core::TimeEvent&>(*evt);
00033 
00034                                 if (!_queue.empty())
00035                                 {
00036                                         const RetransmissionData &data = _queue.front();
00037 
00038                                         if ( data.getTimestamp() <= time.getTimestamp() )
00039                                         {
00040                                                 // retransmit the bundle
00041                                                 getRouter()->transferTo(data.destination, data);
00042 
00043                                                 // remove the item off the queue
00044                                                 _queue.pop();
00045                                         }
00046                                 }
00047                                 return;
00048                         } catch (std::bad_cast ex) { };
00049 
00050                         try {
00051                                 const dtn::net::TransferCompletedEvent &completed = dynamic_cast<const dtn::net::TransferCompletedEvent&>(*evt);
00052 
00053                                 // remove the bundleid in our list
00054                                 RetransmissionData data(completed.getBundle(), completed.getPeer());
00055                                 _set.erase(data);
00056 
00057                                 return;
00058                         } catch (std::bad_cast ex) { };
00059 
00060                         try {
00061                                 const dtn::net::TransferAbortedEvent &aborted = dynamic_cast<const dtn::net::TransferAbortedEvent&>(*evt);
00062 
00063                                 // remove the bundleid in our list
00064                                 RetransmissionData data(aborted.getBundleID(), aborted.getPeer());
00065                                 _set.erase(data);
00066 
00067                                 return;
00068                         } catch (std::bad_cast ex) { };
00069 
00070                         try {
00071                                 const dtn::routing::RequeueBundleEvent &requeue = dynamic_cast<const dtn::routing::RequeueBundleEvent&>(*evt);
00072 
00073                                 const RetransmissionData data(requeue._bundle, requeue._peer);
00074                                 std::set<RetransmissionData>::const_iterator iter = _set.find(data);
00075 
00076                                 if (iter != _set.end())
00077                                 {
00078                                         // increment the retry counter
00079                                         RetransmissionData data2 = (*iter);
00080                                         data2++;
00081 
00082                                         // remove the item
00083                                         _set.erase(data);
00084 
00085                                         if (data2.getCount() <= 10)
00086                                         {
00087                                                 // requeue the bundle
00088                                                 _set.insert(data2);
00089                                                 _queue.push(data2);
00090                                         }
00091                                         else
00092                                         {
00093                                                 dtn::net::TransferAbortedEvent::raise(requeue._peer, requeue._bundle, dtn::net::TransferAbortedEvent::REASON_RETRY_LIMIT_REACHED);
00094                                         }
00095                                 }
00096                                 else
00097                                 {
00098                                         // queue the bundle
00099                                         _set.insert(data);
00100                                         _queue.push(data);
00101                                 }
00102 
00103                                 return;
00104                         } catch (std::bad_cast ex) { };
00105 
00106                         try {
00107                                 const dtn::core::BundleExpiredEvent &expired = dynamic_cast<const dtn::core::BundleExpiredEvent&>(*evt);
00108 
00109                                 // delete all matching elements in the queue
00110                                 size_t elements = _queue.size();
00111                                 for (size_t i = 0; i < elements; i++)
00112                                 {
00113                                         const RetransmissionData &data = _queue.front();
00114 
00115                                         if ((dtn::data::BundleID&)data == expired._bundle)
00116                                         {
00117                                                 dtn::net::TransferAbortedEvent::raise(data.destination, data, dtn::net::TransferAbortedEvent::REASON_BUNDLE_DELETED);
00118                                         }
00119                                         else
00120                                         {
00121                                                 _queue.push(data);
00122                                         }
00123 
00124                                         _queue.pop();
00125                                 }
00126 
00127                                 return;
00128                         } catch (std::bad_cast ex) { };
00129                 }
00130 
00131                 bool RetransmissionExtension::RetransmissionData::operator!=(const RetransmissionData &obj)
00132                 {
00133                         const dtn::data::BundleID &id1 = dynamic_cast<const dtn::data::BundleID&>(obj);
00134                         const dtn::data::BundleID &id2 = dynamic_cast<const dtn::data::BundleID&>(*this);
00135 
00136                         if (id1 != id2) return true;
00137                         if (obj.destination != destination) return true;
00138 
00139                         return false;
00140                 }
00141 
00142                 bool RetransmissionExtension::RetransmissionData::operator==(const RetransmissionData &obj)
00143                 {
00144                         const dtn::data::BundleID &id1 = dynamic_cast<const dtn::data::BundleID&>(obj);
00145                         const dtn::data::BundleID &id2 = dynamic_cast<const dtn::data::BundleID&>(*this);
00146 
00147                         if (id1 != id2) return false;
00148                         if (obj.destination != destination) return false;
00149 
00150                         return true;
00151                 }
00152 
00153                 size_t RetransmissionExtension::RetransmissionData::getCount() const
00154                 {
00155                         return _count;
00156                 }
00157 
00158                 size_t RetransmissionExtension::RetransmissionData::getTimestamp() const
00159                 {
00160                         return _timestamp;
00161                 }
00162 
00163                 RetransmissionExtension::RetransmissionData& RetransmissionExtension::RetransmissionData::operator++(int)
00164                 {
00165                         _count++;
00166                         _timestamp = dtn::utils::Clock::getTime();
00167                         _timestamp += retry;
00168 
00169                         return (*this);
00170                 }
00171 
00172                 RetransmissionExtension::RetransmissionData& RetransmissionExtension::RetransmissionData::operator++()
00173                 {
00174                         _count++;
00175                         _timestamp = dtn::utils::Clock::getTime();
00176                         _timestamp += retry;
00177 
00178                         return (*this);
00179                 }
00180 
00181                 RetransmissionExtension::RetransmissionData::RetransmissionData(const dtn::data::BundleID &id, dtn::data::EID d, size_t r)
00182                  : dtn::data::BundleID(id), destination(d), _timestamp(0), _count(0), retry(r)
00183                 {
00184                         (*this)++;
00185                 }
00186 
00187                 RetransmissionExtension::RetransmissionData::~RetransmissionData()
00188                 {
00189                 }
00190         }
00191 }

Generated on Thu Nov 11 2010 09:49:47 for IBR-DTNSuite by  doxygen 1.7.1