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 }
1.7.1