IBR-DTNSuite  0.10
BundleStorage.cpp
Go to the documentation of this file.
1 /*
2  * BundleStorage.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 
22 #include "core/BundleCore.h"
23 #include "storage/BundleStorage.h"
24 #include "core/CustodyEvent.h"
27 #include <ibrdtn/data/BundleID.h>
29 #include <ibrcommon/Logger.h>
30 
31 namespace dtn
32 {
33  namespace storage
34  {
36  : _faulty(false), _maxsize(maxsize), _currentsize(0)
37  {
38  }
39 
41  {
42  }
43 
45  {
46  remove(dtn::data::BundleID(b));
47  }
48 
50  {
51  class BundleFilter : public dtn::storage::BundleSelector
52  {
53  public:
54  BundleFilter(const ibrcommon::BloomFilter &filter)
55  : _filter(filter)
56  {};
57 
58  virtual ~BundleFilter() {};
59 
60  virtual dtn::data::Size limit() const throw () { return 1; };
61 
62  virtual bool shouldAdd(const dtn::data::MetaBundle &meta) const throw (dtn::storage::BundleSelectorException)
63  {
64  // select the bundle if it is in the filter
65  return _filter.contains(meta.toString());
66  };
67 
68  const ibrcommon::BloomFilter &_filter;
69  } bundle_filter(filter);
70 
72 
73  // query an unknown bundle from the storage, the list contains 1 item.
74  get(bundle_filter, list);
75 
76  if (list.empty())
77  throw NoBundleFoundException();
78 
79  dtn::data::MetaBundle ret = list.front();
80  this->remove(ret);
81 
82  return ret;
83  }
84 
86  {
87  if (!meta.get(Bundle::CUSTODY_REQUESTED))
88  throw ibrcommon::Exception("custody transfer is not requested for this bundle.");
89 
90  if (meta.custodian == EID())
91  throw ibrcommon::Exception("no previous custodian is set.");
92 
93  // create a new bundle
94  Bundle custody_bundle;
95 
96  // set priority to HIGH
97  custody_bundle.set(dtn::data::PrimaryBlock::PRIORITY_BIT1, false);
98  custody_bundle.set(dtn::data::PrimaryBlock::PRIORITY_BIT2, true);
99 
100  // create a custody signal with accept flag
101  CustodySignalBlock signal;
102 
103  // set the bundle to match
104  signal.setMatch(meta);
105 
106  // set accepted
107  signal.custody_accepted = true;
108 
109  // write the custody data to a payload block
110  dtn::data::PayloadBlock &payload = custody_bundle.push_back<dtn::data::PayloadBlock>();
111  signal.write(payload);
112 
115  custody_bundle.destination = meta.custodian;
116  custody_bundle.source = dtn::core::BundleCore::local;
117 
118  // send the custody accepted bundle
120 
121  // raise the custody accepted event
123 
125  }
126 
128  {
129  if (!meta.get(Bundle::CUSTODY_REQUESTED))
130  throw ibrcommon::Exception("custody transfer is not requested for this bundle.");
131 
132  if (meta.custodian == EID())
133  throw ibrcommon::Exception("no previous custodian is set.");
134 
135  // create a new bundle
136  Bundle b;
137 
138  // create a custody signal with reject flag
139  CustodySignalBlock signal;
140 
141  // set the bundle to match
142  signal.setMatch(meta);
143 
144  // set reason code
145  signal.reason = reason;
146 
147  // write the custody data to a payload block
149  signal.write(payload);
150 
152  b.destination = meta.custodian;
154 
155  // send the custody rejected bundle
157 
158  // raise the custody rejected event
160  }
161 
163  {
164  return _currentsize;
165  }
166 
168  {
169  ibrcommon::MutexLock l(_sizelock);
170 
171  // check if this container is too big for us.
172  if ((_maxsize > 0) && (_currentsize + size > _maxsize))
173  {
175  }
176 
177  // increment the storage size
178  _currentsize += size;
179  }
180 
181  void BundleStorage::freeSpace(const dtn::data::Length &size) throw ()
182  {
183  ibrcommon::MutexLock l(_sizelock);
184  if (size > _currentsize)
185  {
186  _currentsize = 0;
187  IBRCOMMON_LOGGER_TAG("BundleStorage", critical) << "More space to free than allocated." << IBRCOMMON_LOGGER_ENDL;
188  }
189  else
190  {
191  _currentsize -= size;
192  }
193  }
194 
196  {
197  ibrcommon::MutexLock l(_sizelock);
198  _currentsize = 0;
199  }
200 
202  {
203  IBRCOMMON_LOGGER_DEBUG_TAG("BundleStorage", 2) << "add bundle to index: " << b.toString() << IBRCOMMON_LOGGER_ENDL;
204 
205  for (index_list::iterator it = _indexes.begin(); it != _indexes.end(); ++it) {
206  BundleIndex &index = (**it);
207  index.add(b);
208  }
209  }
210 
212  {
213  IBRCOMMON_LOGGER_DEBUG_TAG("BundleStorage", 2) << "remove bundle from index: " << id.toString() << IBRCOMMON_LOGGER_ENDL;
214 
215  for (index_list::iterator it = _indexes.begin(); it != _indexes.end(); ++it) {
216  BundleIndex &index = (**it);
217  index.remove(id);
218  }
219  }
220 
222  {
223  ibrcommon::MutexLock l(_index_lock);
224  _indexes.insert(index);
225  }
226 
228  {
229  ibrcommon::MutexLock l(_index_lock);
230  _indexes.erase(index);
231  }
232  }
233 }