00001
00002
00003
00004
00005
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 const dtn::core::TimeEvent *time = dynamic_cast<const dtn::core::TimeEvent*>(evt);
00032 const dtn::net::TransferCompletedEvent *completed = dynamic_cast<const dtn::net::TransferCompletedEvent*>(evt);
00033 const dtn::routing::RequeueBundleEvent *requeue = dynamic_cast<const dtn::routing::RequeueBundleEvent*>(evt);
00034 const dtn::core::BundleExpiredEvent *expired = dynamic_cast<const dtn::core::BundleExpiredEvent*>(evt);
00035
00036 if (time != NULL)
00037 {
00038 if (!_queue.empty())
00039 {
00040 const RetransmissionData &data = _queue.front();
00041
00042 if ( data.getTimestamp() <= time->getTimestamp() )
00043 {
00044 try {
00045
00046 getRouter()->transferTo(data.destination, data);
00047 } catch (dtn::core::BundleStorage::NoBundleFoundException ex) {
00048
00049 dtn::net::TransferAbortedEvent::raise(data.destination, data);
00050 }
00051
00052
00053 _queue.pop();
00054 }
00055 }
00056 }
00057 else if (completed != NULL)
00058 {
00059
00060 RetransmissionData data(completed->getBundle(), completed->getPeer());
00061 _set.erase(data);
00062 }
00063 else if (requeue != NULL)
00064 {
00065 const RetransmissionData data(requeue->_bundle, requeue->_peer);
00066 std::set<RetransmissionData>::const_iterator iter = _set.find(data);
00067
00068 if (iter != _set.end())
00069 {
00070
00071 RetransmissionData data2 = (*iter);
00072 data2++;
00073
00074
00075 _set.erase(data);
00076
00077 if (data2.getCount() <= 10)
00078 {
00079
00080 _set.insert(data2);
00081 _queue.push(data2);
00082 }
00083 else
00084 {
00085 dtn::net::TransferAbortedEvent::raise(requeue->_peer, requeue->_bundle);
00086 }
00087 }
00088 else
00089 {
00090
00091 _set.insert(data);
00092 _queue.push(data);
00093 }
00094 }
00095 }
00096
00097 bool RetransmissionExtension::RetransmissionData::operator!=(const RetransmissionData &obj)
00098 {
00099 const dtn::data::BundleID &id1 = dynamic_cast<const dtn::data::BundleID&>(obj);
00100 const dtn::data::BundleID &id2 = dynamic_cast<const dtn::data::BundleID&>(*this);
00101
00102 if (id1 != id2) return true;
00103 if (obj.destination != destination) return true;
00104
00105 return false;
00106 }
00107
00108 bool RetransmissionExtension::RetransmissionData::operator==(const RetransmissionData &obj)
00109 {
00110 const dtn::data::BundleID &id1 = dynamic_cast<const dtn::data::BundleID&>(obj);
00111 const dtn::data::BundleID &id2 = dynamic_cast<const dtn::data::BundleID&>(*this);
00112
00113 if (id1 != id2) return false;
00114 if (obj.destination != destination) return false;
00115
00116 return true;
00117 }
00118
00119 size_t RetransmissionExtension::RetransmissionData::getCount() const
00120 {
00121 return _count;
00122 }
00123
00124 size_t RetransmissionExtension::RetransmissionData::getTimestamp() const
00125 {
00126 return _timestamp;
00127 }
00128
00129 RetransmissionExtension::RetransmissionData& RetransmissionExtension::RetransmissionData::operator++(int)
00130 {
00131 _count++;
00132 _timestamp = dtn::utils::Clock::getTime();
00133 _timestamp += retry;
00134
00135 return (*this);
00136 }
00137
00138 RetransmissionExtension::RetransmissionData& RetransmissionExtension::RetransmissionData::operator++()
00139 {
00140 _count++;
00141 _timestamp = dtn::utils::Clock::getTime();
00142 _timestamp += retry;
00143
00144 return (*this);
00145 }
00146
00147 RetransmissionExtension::RetransmissionData::RetransmissionData(const dtn::data::BundleID &id, dtn::data::EID d, size_t r)
00148 : dtn::data::BundleID(id), destination(d), _timestamp(0), _count(0), retry(r)
00149 {
00150 (*this)++;
00151 }
00152
00153 RetransmissionExtension::RetransmissionData::~RetransmissionData()
00154 {
00155 }
00156 }
00157 }