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

daemon/src/routing/BaseRouter.cpp

Go to the documentation of this file.
00001 /*
00002  * BaseRouter.cpp
00003  *
00004  *  Created on: 15.02.2010
00005  *      Author: morgenro
00006  */
00007 
00008 #include "routing/BaseRouter.h"
00009 #include "core/BundleCore.h"
00010 
00011 #include "net/TransferAbortedEvent.h"
00012 #include "net/TransferCompletedEvent.h"
00013 #include "net/BundleReceivedEvent.h"
00014 #include "routing/QueueBundleEvent.h"
00015 #include "routing/RequeueBundleEvent.h"
00016 #include "core/BundleStorage.h"
00017 #include "core/BundleGeneratedEvent.h"
00018 #include "core/BundleExpiredEvent.h"
00019 #include "core/BundleEvent.h"
00020 #include "core/NodeEvent.h"
00021 #include "core/TimeEvent.h"
00022 
00023 #include <ibrcommon/Logger.h>
00024 #include <ibrcommon/thread/MutexLock.h>
00025 
00026 namespace dtn
00027 {
00028         namespace routing
00029         {
00030                 BaseRouter *BaseRouter::Extension::_router = NULL;
00031 
00035                 BaseRouter::ThreadedExtension::ThreadedExtension()
00036                 { }
00037 
00038                 BaseRouter::ThreadedExtension::~ThreadedExtension()
00039                 {
00040                         join();
00041                 }
00042 
00046                 BaseRouter::Extension::Extension()
00047                 { }
00048 
00049                 BaseRouter::Extension::~Extension()
00050                 { }
00051 
00052                 BaseRouter* BaseRouter::Extension::getRouter()
00053                 {
00054                         return _router;
00055                 }
00056 
00060                 BaseRouter::Endpoint::Endpoint()
00061                 { }
00062 
00063                 BaseRouter::Endpoint::~Endpoint()
00064                 { }
00065 
00069                 BaseRouter::VirtualEndpoint::VirtualEndpoint(dtn::data::EID name)
00070                  : _client(NULL), _name(name)
00071                 { }
00072 
00073                 BaseRouter::VirtualEndpoint::~VirtualEndpoint()
00074                 { }
00075 
00079                 BaseRouter::BaseRouter(dtn::core::BundleStorage &storage)
00080                  : _storage(storage)
00081                 {
00082                         // register myself for all extensions
00083                         Extension::_router = this;
00084                 }
00085 
00086                 BaseRouter::~BaseRouter()
00087                 {
00088                 }
00089 
00094                 void BaseRouter::addExtension(BaseRouter::Extension *extension)
00095                 {
00096                         _extensions.push_back(extension);
00097                 }
00098 
00099                 void BaseRouter::componentUp()
00100                 {
00101                         bindEvent(dtn::net::TransferAbortedEvent::className);
00102                         bindEvent(dtn::net::TransferCompletedEvent::className);
00103                         bindEvent(dtn::net::BundleReceivedEvent::className);
00104                         bindEvent(dtn::routing::QueueBundleEvent::className);
00105                         bindEvent(dtn::routing::RequeueBundleEvent::className);
00106                         bindEvent(dtn::core::NodeEvent::className);
00107                         bindEvent(dtn::core::BundleExpiredEvent::className);
00108                         bindEvent(dtn::core::TimeEvent::className);
00109                         bindEvent(dtn::core::BundleGeneratedEvent::className);
00110 
00111                         for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++)
00112                         {
00113                                 ThreadedExtension *thread = dynamic_cast<ThreadedExtension*>(*iter);
00114 
00115                                 if (thread != NULL)
00116                                 {
00117                                         try {
00118                                                 // run the thread
00119                                                 thread->start();
00120                                         } catch (const ibrcommon::ThreadException &ex) {
00121                                                 IBRCOMMON_LOGGER(error) << "failed to start component in BaseRouter\n" << ex.what() << IBRCOMMON_LOGGER_ENDL;
00122                                         }
00123                                 }
00124                         }
00125                 }
00126 
00127                 void BaseRouter::componentDown()
00128                 {
00129                         unbindEvent(dtn::net::TransferAbortedEvent::className);
00130                         unbindEvent(dtn::net::TransferCompletedEvent::className);
00131                         unbindEvent(dtn::net::BundleReceivedEvent::className);
00132                         unbindEvent(dtn::routing::QueueBundleEvent::className);
00133                         unbindEvent(dtn::routing::RequeueBundleEvent::className);
00134                         unbindEvent(dtn::core::NodeEvent::className);
00135                         unbindEvent(dtn::core::BundleExpiredEvent::className);
00136                         unbindEvent(dtn::core::TimeEvent::className);
00137                         unbindEvent(dtn::core::BundleGeneratedEvent::className);
00138 
00139                         // delete all extensions
00140                         for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++)
00141                         {
00142                                 ThreadedExtension *thread = dynamic_cast<ThreadedExtension*>(*iter);
00143 
00144                                 if (thread != NULL)
00145                                 {
00146                                         try {
00147                                                 // run the thread
00148                                                 thread->stop();
00149                                         } catch (const ibrcommon::ThreadException &ex) {
00150                                                 IBRCOMMON_LOGGER(error) << "failed to stop component in BaseRouter\n" << ex.what() << IBRCOMMON_LOGGER_ENDL;
00151                                         }
00152                                 }
00153 
00154                                 delete (*iter);
00155                         }
00156                 }
00157 
00164                 void BaseRouter::transferTo(const dtn::data::EID &destination, const dtn::data::BundleID &id)
00165                 {
00166                         dtn::core::BundleCore::getInstance().transferTo(destination, id);
00167                 }
00168 
00172                 void BaseRouter::raiseEvent(const dtn::core::Event *evt)
00173                 {
00174                         try {
00175                                 const dtn::net::BundleReceivedEvent &received = dynamic_cast<const dtn::net::BundleReceivedEvent&>(*evt);
00176 
00177                                 // Store incoming bundles into the storage
00178                                 try {
00179                                         if (received.fromlocal)
00180                                         {
00181                                                 // store the bundle into a storage module
00182                                                 _storage.store(received.bundle);
00183 
00184                                                 // set the bundle as known
00185                                                 setKnown(received.bundle);
00186 
00187                                                 // raise the queued event to notify all receivers about the new bundle
00188                                                 QueueBundleEvent::raise(received.bundle, received.peer);
00189                                         }
00190                                         // if the bundle is not known
00191                                         else if (!isKnown(received.bundle))
00192                                         {
00193                                                 // store the bundle into a storage module
00194                                                 _storage.store(received.bundle);
00195 
00196                                                 // set the bundle as known
00197                                                 setKnown(received.bundle);
00198 
00199                                                 // raise the queued event to notify all receivers about the new bundle
00200                                                 QueueBundleEvent::raise(received.bundle, received.peer);
00201                                         }
00202 
00203                                         // finally create a bundle received event
00204                                         dtn::core::BundleEvent::raise(received.bundle, dtn::core::BUNDLE_RECEIVED);
00205 
00206                                 } catch (ibrcommon::IOException ex) {
00207                                         IBRCOMMON_LOGGER(notice) << "Unable to store bundle " << received.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00208                                 } catch (dtn::core::BundleStorage::StorageSizeExeededException ex) {
00209                                         IBRCOMMON_LOGGER(notice) << "No space left for bundle " << received.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00210                                 }
00211 
00212                                 return;
00213                         } catch (std::bad_cast) {
00214                         }
00215 
00216                         try {
00217                                 const dtn::core::BundleGeneratedEvent &generated = dynamic_cast<const dtn::core::BundleGeneratedEvent&>(*evt);
00218                                 
00219                                 // set the bundle as known
00220                                 setKnown(generated.bundle);
00221 
00222                                 // Store incoming bundles into the storage
00223                                 try {
00224                                         // store the bundle into a storage module
00225                                         _storage.store(generated.bundle);
00226 
00227                                         // raise the queued event to notify all receivers about the new bundle
00228                                         QueueBundleEvent::raise(generated.bundle, dtn::core::BundleCore::local);
00229 
00230                                 } catch (ibrcommon::IOException ex) {
00231                                         IBRCOMMON_LOGGER(notice) << "Unable to store bundle " << generated.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00232                                 } catch (dtn::core::BundleStorage::StorageSizeExeededException ex) {
00233                                         IBRCOMMON_LOGGER(notice) << "No space left for bundle " << generated.bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00234                                 }
00235 
00236                                 return;
00237                         } catch (std::bad_cast) {
00238                         }
00239 
00240                         try {
00241                                 const QueueBundleEvent &queued = dynamic_cast<const QueueBundleEvent&>(*evt);
00242 
00243                                 const dtn::data::EID &dest = queued.bundle.destination;
00244 
00245                                 if ( (dest.getNodeEID() == BundleCore::local.getNodeEID()) && dest.hasApplication() )
00246                                 {
00247                                         // if the bundle is for a local application, do not forward it to routing modules
00248                                         return;
00249                                 }
00250 
00251                                 // jump to jumppoint distribute to distribute the event to all submodules
00252                                 goto distribute;
00253 
00254                         } catch (std::bad_cast) {
00255                         }
00256 
00257                         try {
00258                                 const dtn::core::TimeEvent &time = dynamic_cast<const dtn::core::TimeEvent&>(*evt);
00259                                 ibrcommon::MutexLock l(_known_bundles_lock);
00260                                 _known_bundles.expire(time.getTimestamp());
00261                         } catch (std::bad_cast) {
00262                         }
00263 
00264                         // jumppoint to distribute the events
00265                         distribute:
00266 
00267                         // notify all underlying extensions
00268                         for (std::list<BaseRouter::Extension*>::iterator iter = _extensions.begin(); iter != _extensions.end(); iter++)
00269                         {
00270                                 (*iter)->notify(evt);
00271                         }
00272                 }
00273 
00279                 dtn::data::Bundle BaseRouter::getBundle(const dtn::data::BundleID &id)
00280                 {
00281                         return _storage.get(id);
00282                 }
00283 
00284                 dtn::core::BundleStorage& BaseRouter::getStorage()
00285                 {
00286                         return _storage;
00287                 }
00288 
00289                 void BaseRouter::setKnown(const dtn::data::MetaBundle &meta)
00290                 {
00291                         ibrcommon::MutexLock l(_known_bundles_lock);
00292                         return _known_bundles.add(meta);
00293                 }
00294 
00295                 // set the bundle as known
00296                 bool BaseRouter::isKnown(const dtn::data::BundleID &id)
00297                 {
00298                         ibrcommon::MutexLock l(_known_bundles_lock);
00299                         return _known_bundles.contains(id);
00300                 }
00301 
00302                 const SummaryVector BaseRouter::getSummaryVector()
00303                 {
00304                         ibrcommon::MutexLock l(_known_bundles_lock);
00305                         return _known_bundles.getSummaryVector();
00306                 }
00307 
00308                 const std::string BaseRouter::getName() const
00309                 {
00310                         return "BaseRouter";
00311                 }
00312         }
00313 }

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