Go to the documentation of this file.00001 #include "core/BundleCore.h"
00002 #include "core/GlobalEvent.h"
00003 #include "routing/RequeueBundleEvent.h"
00004 #include "routing/QueueBundleEvent.h"
00005 #include "core/BundleEvent.h"
00006 #include "core/TimeEvent.h"
00007
00008 #include <ibrcommon/data/BLOB.h>
00009 #include <ibrdtn/data/MetaBundle.h>
00010 #include <ibrdtn/data/Exceptions.h>
00011 #include <ibrdtn/data/EID.h>
00012 #include <ibrdtn/utils/Clock.h>
00013 #include <ibrcommon/Logger.h>
00014
00015 #include "limits.h"
00016 #include <iostream>
00017 #include <typeinfo>
00018 #include <stdint.h>
00019
00020 using namespace dtn::data;
00021 using namespace dtn::utils;
00022 using namespace std;
00023
00024 namespace dtn
00025 {
00026 namespace core
00027 {
00028 dtn::data::EID BundleCore::local;
00029 size_t BundleCore::blocksizelimit = 0;
00030 bool BundleCore::forwarding = true;
00031
00032 BundleCore& BundleCore::getInstance()
00033 {
00034 static BundleCore instance;
00035 return instance;
00036 }
00037
00038 BundleCore::BundleCore()
00039 : _clock(1), _storage(NULL)
00040 {
00044 if (dtn::utils::Clock::getTime() > 0)
00045 {
00046 dtn::utils::Clock::quality = 1;
00047 }
00048 else
00049 {
00050 IBRCOMMON_LOGGER(warning) << "The local clock seems to be wrong. Expiration disabled." << IBRCOMMON_LOGGER_ENDL;
00051 }
00052
00053 bindEvent(dtn::routing::QueueBundleEvent::className);
00054 bindEvent(dtn::core::TimeEvent::className);
00055 }
00056
00057 BundleCore::~BundleCore()
00058 {
00059 unbindEvent(dtn::routing::QueueBundleEvent::className);
00060 unbindEvent(dtn::core::TimeEvent::className);
00061 }
00062
00063 void BundleCore::componentUp()
00064 {
00065 _connectionmanager.initialize();
00066 _clock.initialize();
00067
00068
00069 _clock.startup();
00070 }
00071
00072 void BundleCore::componentDown()
00073 {
00074 _connectionmanager.terminate();
00075 _clock.terminate();
00076 }
00077
00078 void BundleCore::setStorage(dtn::core::BundleStorage *storage)
00079 {
00080 _storage = storage;
00081 }
00082
00083 dtn::core::BundleStorage& BundleCore::getStorage()
00084 {
00085 if (_storage == NULL)
00086 {
00087 throw ibrcommon::Exception("No bundle storage is set! Use BundleCore::setStorage() to set a storage.");
00088 }
00089 return *_storage;
00090 }
00091
00092 WallClock& BundleCore::getClock()
00093 {
00094 return _clock;
00095 }
00096
00097 void BundleCore::transferTo(const dtn::data::EID &destination, const dtn::data::BundleID &bundle)
00098 {
00099 try {
00100 _connectionmanager.queue(destination, bundle);
00101 } catch (dtn::net::NeighborNotAvailableException ex) {
00102
00103 dtn::routing::RequeueBundleEvent::raise(destination, bundle);
00104 } catch (dtn::net::ConnectionNotAvailableException ex) {
00105
00106 dtn::routing::RequeueBundleEvent::raise(destination, bundle);
00107 } catch (ibrcommon::Exception) {
00108 dtn::routing::RequeueBundleEvent::raise(destination, bundle);
00109 }
00110 }
00111
00112 void BundleCore::addConvergenceLayer(dtn::net::ConvergenceLayer *cl)
00113 {
00114 _connectionmanager.addConvergenceLayer(cl);
00115 }
00116
00117 void BundleCore::addConnection(const dtn::core::Node &n)
00118 {
00119 _connectionmanager.addConnection(n);
00120 }
00121
00122 const std::set<dtn::core::Node> BundleCore::getNeighbors()
00123 {
00124 return _connectionmanager.getNeighbors();
00125 }
00126
00127 void BundleCore::raiseEvent(const dtn::core::Event *evt)
00128 {
00129 try {
00130 dynamic_cast<const dtn::core::TimeEvent&>(*evt);
00131
00135 if (dtn::utils::Clock::quality == 0)
00136 {
00137 if (dtn::utils::Clock::getTime() > 0)
00138 {
00139 dtn::utils::Clock::quality = 1;
00140 IBRCOMMON_LOGGER(warning) << "The local clock seems to be okay again. Expiration enabled." << IBRCOMMON_LOGGER_ENDL;
00141 }
00142 }
00143
00144 } catch (std::bad_cast ex) {
00145
00146 }
00147
00148 try {
00149 const dtn::routing::QueueBundleEvent &queued = dynamic_cast<const dtn::routing::QueueBundleEvent&>(*evt);
00150 const dtn::data::MetaBundle &meta = queued.bundle;
00151
00152 if (meta.destination == local)
00153 {
00154
00155
00156 bool delivered = false;
00157
00158
00159 dtn::data::Bundle bundle = getStorage().get(meta);
00160
00161 try {
00162
00163 dtn::data::CustodySignalBlock custody = bundle.getBlock<dtn::data::CustodySignalBlock>();
00164 dtn::data::BundleID id(custody._source, custody._bundle_timestamp.getValue(), custody._bundle_sequence.getValue(), (custody._fragment_length.getValue() > 0), custody._fragment_offset.getValue());
00165 getStorage().releaseCustody(id);
00166
00167 IBRCOMMON_LOGGER_DEBUG(5) << "custody released for " << bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00168
00169 delivered = true;
00170 } catch (dtn::data::Bundle::NoSuchBlockFoundException) {
00171
00172 }
00173
00174 if (delivered)
00175 {
00176
00177 dtn::core::BundleEvent::raise(meta, BUNDLE_DELIVERED);
00178 }
00179 else
00180 {
00181
00182 dtn::core::BundleEvent::raise(meta, BUNDLE_DELETED, StatusReportBlock::DESTINATION_ENDPOINT_ID_UNINTELLIGIBLE);
00183 }
00184
00185
00186 getStorage().remove(meta);
00187 }
00188 } catch (std::bad_cast ex) {
00189
00190 }
00191 }
00192
00193 void BundleCore::validate(const dtn::data::PrimaryBlock &p) const throw (dtn::data::Validator::RejectedException)
00194 {
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 if (!BundleCore::forwarding)
00208 {
00209 if (!p._destination.sameHost(BundleCore::local))
00210 {
00211
00212 IBRCOMMON_LOGGER(warning) << "non-local bundle rejected: " << p.toString() << IBRCOMMON_LOGGER_ENDL;
00213 throw dtn::data::Validator::RejectedException("bundle is not local");
00214 }
00215 }
00216
00217
00218 if (p.isExpired())
00219 {
00220 IBRCOMMON_LOGGER(warning) << "bundle rejected: bundle has expired (" << p.toString() << ")" << IBRCOMMON_LOGGER_ENDL;
00221 throw dtn::data::Validator::RejectedException("bundle is expired");
00222 }
00223 }
00224
00225 void BundleCore::validate(const dtn::data::Block&, const size_t size) const throw (dtn::data::Validator::RejectedException)
00226 {
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 if ((BundleCore::blocksizelimit > 0) && (size > BundleCore::blocksizelimit))
00238 {
00239 IBRCOMMON_LOGGER(warning) << "bundle rejected: block size of " << size << " is too big" << IBRCOMMON_LOGGER_ENDL;
00240 throw dtn::data::Validator::RejectedException("block size is too big");
00241 }
00242 }
00243
00244 void BundleCore::validate(const dtn::data::Bundle&) const throw (dtn::data::Validator::RejectedException)
00245 {
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 }
00256
00257 const std::string BundleCore::getName() const
00258 {
00259 return "BundleCore";
00260 }
00261 }
00262 }