IBR-DTN  1.0.0
RetransmissionExtension.cpp
Go to the documentation of this file.
1 /*
2  * RetransmissionExtension.cpp
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
23 
24 #include "core/BundleCore.h"
25 #include "core/EventDispatcher.h"
27 
28 #include <ibrdtn/utils/Clock.h>
29 #include <ibrdtn/data/Exceptions.h>
30 #include <ibrcommon/thread/MutexLock.h>
31 
32 
33 namespace dtn
34 {
35  namespace routing
36  {
38  {
39  }
40 
42  {
43  }
44 
46  {
51  }
52 
54  {
59  }
60 
62  {
63  // remove the bundleid in our list
64  RetransmissionData data(meta, peer);
65  _set.erase(data);
66  }
67 
69  {
70  ibrcommon::MutexLock l(_mutex);
71  if (!_queue.empty())
72  {
73  const RetransmissionData &data = _queue.front();
74 
75  if ( data.getTimestamp() <= time.getTimestamp() )
76  {
77  try {
79 
80  try {
81  // create a new bundle transfer
82  dtn::net::BundleTransfer transfer(data.destination, meta, data.protocol);
83 
84  try {
85  // re-queue the bundle
87  } catch (const dtn::core::P2PDialupException&) {
88  // abort transmission
90  }
91  } catch (const ibrcommon::Exception&) {
92  // do nothing here
93  }
94  } catch (const ibrcommon::Exception&) {
95  // bundle is not available, abort transmission
97  }
98 
99  // remove the item off the queue
100  _queue.pop();
101  }
102  }
103  }
104 
106  {
107  // remove the bundleid in our list
108  RetransmissionData data(aborted.getBundleID(), aborted.getPeer());
109  _set.erase(data);
110  }
111 
113  {
114  const RetransmissionData data(requeue.getBundle(), requeue.getPeer(), requeue.getProtocol());
115 
116  ibrcommon::MutexLock l(_mutex);
117  std::set<RetransmissionData>::const_iterator iter = _set.find(data);
118 
119  if (iter != _set.end())
120  {
121  // increment the retry counter
122  RetransmissionData data2 = (*iter);
123  data2++;
124 
125  // remove the item
126  _set.erase(data);
127 
128  if (data2.getCount() <= 8)
129  {
130  // requeue the bundle
131  _set.insert(data2);
132  _queue.push(data2);
133  }
134  else
135  {
137  }
138  }
139  else
140  {
141  // queue the bundle
142  _set.insert(data);
143  _queue.push(data);
144  }
145  }
146 
148  {
149  // delete all matching elements in the queue
150  ibrcommon::MutexLock l(_mutex);
151 
152  dtn::data::Size elements = _queue.size();
153  for (dtn::data::Size i = 0; i < elements; ++i)
154  {
155  const RetransmissionData &data = _queue.front();
156 
157  if ((dtn::data::BundleID&)data == expired.getBundle())
158  {
160  }
161  else
162  {
163  _queue.push(data);
164  }
165 
166  _queue.pop();
167  }
168  }
169 
170  bool RetransmissionExtension::RetransmissionData::operator!=(const RetransmissionData &obj)
171  {
172  const dtn::data::BundleID &id1 = dynamic_cast<const dtn::data::BundleID&>(obj);
173  const dtn::data::BundleID &id2 = dynamic_cast<const dtn::data::BundleID&>(*this);
174 
175  if (id1 != id2) return true;
176  if (obj.destination != destination) return true;
177 
178  return false;
179  }
180 
181  bool RetransmissionExtension::RetransmissionData::operator==(const RetransmissionData &obj)
182  {
183  const dtn::data::BundleID &id1 = dynamic_cast<const dtn::data::BundleID&>(obj);
184  const dtn::data::BundleID &id2 = dynamic_cast<const dtn::data::BundleID&>(*this);
185 
186  if (id1 != id2) return false;
187  if (obj.destination != destination) return false;
188 
189  return true;
190  }
191 
192  dtn::data::Size RetransmissionExtension::RetransmissionData::getCount() const
193  {
194  return _count;
195  }
196 
197  const dtn::data::Timestamp& RetransmissionExtension::RetransmissionData::getTimestamp() const
198  {
199  return _timestamp;
200  }
201 
202  RetransmissionExtension::RetransmissionData& RetransmissionExtension::RetransmissionData::operator++(int)
203  {
204  _count++;
205  _timestamp = dtn::utils::Clock::getTime();
206  float backoff = ::pow((float)retry, (int)_count -1);
207  _timestamp += static_cast<dtn::data::Size>(backoff);
208 
209  return (*this);
210  }
211 
212  RetransmissionExtension::RetransmissionData& RetransmissionExtension::RetransmissionData::operator++()
213  {
214  _count++;
215  _timestamp = dtn::utils::Clock::getTime();
216  float backoff = ::pow((float)retry, (int)_count -1);
217  _timestamp += static_cast<dtn::data::Size>(backoff);
218 
219  return (*this);
220  }
221 
222  RetransmissionExtension::RetransmissionData::RetransmissionData(const dtn::data::BundleID &id, const dtn::data::EID &d, dtn::core::Node::Protocol p, const dtn::data::Size r)
223  : dtn::data::BundleID(id), destination(d), protocol(p), _timestamp(0), _count(0), retry(r)
224  {
225  (*this)++;
226  }
227 
228  RetransmissionExtension::RetransmissionData::~RetransmissionData()
229  {
230  }
231  }
232 }
static void add(EventReceiver< E > *receiver)
static void raise(const dtn::data::EID &peer, const dtn::data::BundleID &id, const AbortReason reason=REASON_UNDEFINED)
static void remove(const EventReceiver< E > *receiver)
dtn::net::ConnectionManager & getConnectionManager()
Definition: BundleCore.cpp:260
virtual dtn::data::MetaBundle info(const dtn::data::BundleID &id)=0
void queue(dtn::net::BundleTransfer &job)
virtual void eventTransferCompleted(const dtn::data::EID &peer, const dtn::data::MetaBundle &meta)
static dtn::data::Timestamp getTime()
Definition: Clock.cpp:167
void raiseEvent(const dtn::net::TransferAbortedEvent &evt)
void abort(const TransferAbortedEvent::AbortReason reason)
size_t Size
Definition: Number.h:34
dtn::storage::BundleStorage & getStorage()
Definition: BundleCore.cpp:237
static BundleCore & getInstance()
Definition: BundleCore.cpp:82