• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

daemon/src/core/BundleCore.cpp

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                         // start a clock
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                                 // signal interruption of the transfer
00103                                 dtn::routing::RequeueBundleEvent::raise(destination, bundle);
00104                         } catch (dtn::net::ConnectionNotAvailableException ex) {
00105                                 // signal interruption of the transfer
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                                         // if the delivered variable is still false at the end of this block.
00155                                         // we send a not delivered report.
00156                                         bool delivered = false;
00157 
00158                                         // process this bundle locally
00159                                         dtn::data::Bundle bundle = getStorage().get(meta);
00160 
00161                                         try {
00162                                                 // check for a custody signal
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                                                 // no custody signal available
00172                                         }
00173 
00174                                         if (delivered)
00175                                         {
00176                                                 // gen a report
00177                                                 dtn::core::BundleEvent::raise(meta, BUNDLE_DELIVERED);
00178                                         }
00179                                         else
00180                                         {
00181                                                 // gen a report
00182                                                 dtn::core::BundleEvent::raise(meta, BUNDLE_DELETED, StatusReportBlock::DESTINATION_ENDPOINT_ID_UNINTELLIGIBLE);
00183                                         }
00184 
00185                                         // delete the bundle
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                          * TODO: reject a bundle if...
00198                          * ... it is expired
00199                          * ... already in the storage
00200                          * ... a fragment of an already received bundle in the storage
00201                          *
00202                          * throw dtn::data::DefaultDeserializer::RejectedException();
00203                          *
00204                          */
00205 
00206                         // if we do not forward bundles
00207                         if (!BundleCore::forwarding)
00208                         {
00209                                 if (!p._destination.sameHost(BundleCore::local))
00210                                 {
00211                                         // ... we reject all non-local bundles.
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                         // check if the bundle is expired
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                          * TODO: reject a block if
00230                          * ... it exceeds the payload limit
00231                          *
00232                          * throw dtn::data::DefaultDeserializer::RejectedException();
00233                          *
00234                          */
00235 
00236                         // check for the size of the block
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                          * TODO: reject a bundle if
00249                          * ... the security checks (DTNSEC) failed
00250                          * ... a checksum mismatch is detected (CRC)
00251                          *
00252                          * throw dtn::data::DefaultDeserializer::RejectedException();
00253                          *
00254                          */
00255                 }
00256 
00257                 const std::string BundleCore::getName() const
00258                 {
00259                         return "BundleCore";
00260                 }
00261         }
00262 }

Generated on Thu Nov 11 2010 09:49:46 for IBR-DTNSuite by  doxygen 1.7.1