|
IBR-DTNSuite 0.6
|
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 #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 // retransmit the bundle 00042 dtn::core::BundleCore::getInstance().transferTo(data.destination, data); 00043 00044 // remove the item off the queue 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 // remove the bundleid in our list 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 // remove the bundleid in our list 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 // increment the retry counter 00080 RetransmissionData data2 = (*iter); 00081 data2++; 00082 00083 // remove the item 00084 _set.erase(data); 00085 00086 if (data2.getCount() <= 8) 00087 { 00088 // requeue the bundle 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 // queue the bundle 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 // delete all matching elements in the queue 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 }