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