00001 /* 00002 * StaticRoutingExtension.cpp 00003 * 00004 * Created on: 16.02.2010 00005 * Author: morgenro 00006 */ 00007 00008 #include "routing/StaticRoutingExtension.h" 00009 #include "routing/QueueBundleEvent.h" 00010 #include "net/TransferAbortedEvent.h" 00011 #include "net/TransferCompletedEvent.h" 00012 #include "routing/RequeueBundleEvent.h" 00013 #include "core/SimpleBundleStorage.h" 00014 #include <typeinfo> 00015 00016 namespace dtn 00017 { 00018 namespace routing 00019 { 00020 StaticRoutingExtension::StaticRoutingExtension(list<StaticRoutingExtension::StaticRoute> routes) 00021 : _routes(routes) 00022 { 00023 try { 00024 // scan for bundles in the storage 00025 dtn::core::SimpleBundleStorage &storage = dynamic_cast<dtn::core::SimpleBundleStorage&>(getRouter()->getStorage()); 00026 00027 std::list<dtn::data::BundleID> list = storage.getList(); 00028 00029 for (std::list<dtn::data::BundleID>::const_iterator iter = list.begin(); iter != list.end(); iter++) 00030 { 00031 try { 00032 dtn::data::MetaBundle meta( storage.get(*iter) ); 00033 00034 // push the bundle into the queue 00035 route( meta ); 00036 } catch (dtn::core::BundleStorage::NoBundleFoundException) { 00037 // error, bundle not found! 00038 } 00039 } 00040 } catch (std::bad_cast ex) { 00041 // Another bundle storage is used! 00042 } 00043 } 00044 00045 StaticRoutingExtension::~StaticRoutingExtension() 00046 { 00047 00048 } 00049 00050 void StaticRoutingExtension::notify(const dtn::core::Event *evt) 00051 { 00052 try { 00053 const QueueBundleEvent &queued = dynamic_cast<const QueueBundleEvent&>(*evt); 00054 00055 // try to route this bundle 00056 route(queued.bundle); 00057 00058 return; 00059 } catch (std::bad_cast ex) { }; 00060 00061 try { 00062 const dtn::net::TransferCompletedEvent &completed = dynamic_cast<const dtn::net::TransferCompletedEvent&>(*evt); 00063 try { 00064 // delete bundle in storage 00065 dtn::core::BundleStorage &storage = getRouter()->getStorage(); 00066 00067 storage.remove(completed.getBundle()); 00068 } catch (const dtn::core::BundleStorage::NoBundleFoundException&) { 00069 00070 } 00071 return; 00072 } catch (std::bad_cast ex) { }; 00073 00074 // try { 00075 // const dtn::net::TransferAbortedEvent &aborted = dynamic_cast<const dtn::net::TransferAbortedEvent&>(*evt); 00076 // // nothing? 00077 // } catch (std::bad_cast ex) { }; 00078 } 00079 00080 void StaticRoutingExtension::route(const dtn::data::MetaBundle &meta) 00081 { 00082 // check all routes 00083 for (std::list<StaticRoute>::const_iterator iter = _routes.begin(); iter != _routes.end(); iter++) 00084 { 00085 StaticRoute route = (*iter); 00086 if ( route.match(meta.destination) ) 00087 { 00088 dtn::data::EID target = dtn::data::EID(route.getDestination()); 00089 00090 // Yes, make transmit it now! 00091 getRouter()->transferTo( target, meta); 00092 return; 00093 } 00094 } 00095 } 00096 00097 StaticRoutingExtension::StaticRoute::StaticRoute(string route, string dest) 00098 : m_route(route), m_dest(dest) 00099 { 00100 // prepare for fast matching 00101 size_t splitter = m_route.find_first_of("*"); 00102 00103 // four types of matching possible 00104 // 0. no asterisk exists, do exact matching 00105 // 1. asterisk at the begin 00106 // 2. asterisk in the middle 00107 // 3. asterisk at the end 00108 if ( splitter == string::npos ) m_matchmode = 0; 00109 else if ( splitter == 0 ) m_matchmode = 1; 00110 else if ( splitter == (m_route.length() -1) ) m_matchmode = 3; 00111 else m_matchmode = 2; 00112 00113 switch (m_matchmode) 00114 { 00115 default: 00116 00117 break; 00118 00119 case 1: 00120 m_route1 = m_route.substr(1); 00121 break; 00122 00123 case 2: 00124 m_route1 = m_route.substr(0, splitter); 00125 m_route2 = m_route.substr(splitter + 1); 00126 break; 00127 00128 case 3: 00129 m_route1 = m_route.substr(0, m_route.length() - 1 ); 00130 break; 00131 } 00132 } 00133 00134 StaticRoutingExtension::StaticRoute::~StaticRoute() 00135 { 00136 } 00137 00138 bool StaticRoutingExtension::StaticRoute::match(const dtn::data::EID &eid) 00139 { 00140 string dest = eid.getNodeEID(); 00141 00142 switch (m_matchmode) 00143 { 00144 default: 00145 // exact matching 00146 if ( dest == m_route ) return true; 00147 break; 00148 00149 case 3: 00150 // asterisk at the end. the begining must be equal. 00151 if ( dest.find(m_route1, 0) == 0 ) return true; 00152 break; 00153 00154 case 2: 00155 if ( 00156 ( dest.find(m_route1) == 0 ) && 00157 ( dest.rfind(m_route2) == (dest.length() - m_route2.length()) ) 00158 ) 00159 return true; 00160 break; 00161 00162 case 1: 00163 // asterisk at begin. the end must be equal. 00164 if ( dest.rfind(m_route1) == (dest.length() - m_route1.length()) ) return true; 00165 break; 00166 } 00167 00168 return false; 00169 } 00170 00171 string StaticRoutingExtension::StaticRoute::getDestination() 00172 { 00173 return m_dest; 00174 } 00175 } 00176 }
1.7.1