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 const QueueBundleEvent *queued = dynamic_cast<const QueueBundleEvent*>(evt); 00053 const dtn::net::TransferCompletedEvent *completed = dynamic_cast<const dtn::net::TransferCompletedEvent*>(evt); 00054 const dtn::net::TransferAbortedEvent *aborted = dynamic_cast<const dtn::net::TransferAbortedEvent*>(evt); 00055 00056 if (queued != NULL) 00057 { 00058 // try to route this bundle 00059 route(queued->bundle); 00060 } 00061 else if (completed != NULL) 00062 { 00063 try { 00064 // delete bundle in storage 00065 dtn::core::BundleStorage &storage = getRouter()->getStorage(); 00066 00067 storage.remove(completed->getBundle()); 00068 } catch (dtn::core::BundleStorage::NoBundleFoundException ex) { 00069 00070 } 00071 } 00072 else if (aborted != NULL) 00073 { 00074 // nothing? 00075 } 00076 } 00077 00078 void StaticRoutingExtension::route(const dtn::data::MetaBundle &meta) 00079 { 00080 try { 00081 // check all routes 00082 for (std::list<StaticRoute>::const_iterator iter = _routes.begin(); iter != _routes.end(); iter++) 00083 { 00084 StaticRoute route = (*iter); 00085 if ( route.match(meta.destination) ) 00086 { 00087 dtn::data::EID target = dtn::data::EID(route.getDestination()); 00088 00089 // Yes, make transmit it now! 00090 getRouter()->transferTo( target, meta); 00091 return; 00092 } 00093 } 00094 } catch (dtn::core::BundleStorage::NoBundleFoundException ex) { 00095 // bundle may expired, ignore it. 00096 } 00097 } 00098 00099 StaticRoutingExtension::StaticRoute::StaticRoute(string route, string dest) 00100 : m_route(route), m_dest(dest) 00101 { 00102 // prepare for fast matching 00103 size_t splitter = m_route.find_first_of("*"); 00104 00105 // four types of matching possible 00106 // 0. no asterisk exists, do exact matching 00107 // 1. asterisk at the begin 00108 // 2. asterisk in the middle 00109 // 3. asterisk at the end 00110 if ( splitter == string::npos ) m_matchmode = 0; 00111 else if ( splitter == 0 ) m_matchmode = 1; 00112 else if ( splitter == (m_route.length() -1) ) m_matchmode = 3; 00113 else m_matchmode = 2; 00114 00115 switch (m_matchmode) 00116 { 00117 default: 00118 00119 break; 00120 00121 case 1: 00122 m_route1 = m_route.substr(1); 00123 break; 00124 00125 case 2: 00126 m_route1 = m_route.substr(0, splitter); 00127 m_route2 = m_route.substr(splitter + 1); 00128 break; 00129 00130 case 3: 00131 m_route1 = m_route.substr(0, m_route.length() - 1 ); 00132 break; 00133 } 00134 } 00135 00136 StaticRoutingExtension::StaticRoute::~StaticRoute() 00137 { 00138 } 00139 00140 bool StaticRoutingExtension::StaticRoute::match(const dtn::data::EID &eid) 00141 { 00142 string dest = eid.getNodeEID(); 00143 00144 switch (m_matchmode) 00145 { 00146 default: 00147 // exact matching 00148 if ( dest == m_route ) return true; 00149 break; 00150 00151 case 3: 00152 // asterisk at the end. the begining must be equal. 00153 if ( dest.find(m_route1, 0) == 0 ) return true; 00154 break; 00155 00156 case 2: 00157 if ( 00158 ( dest.find(m_route1) == 0 ) && 00159 ( dest.rfind(m_route2) == (dest.length() - m_route2.length()) ) 00160 ) 00161 return true; 00162 break; 00163 00164 case 1: 00165 // asterisk at begin. the end must be equal. 00166 if ( dest.rfind(m_route1) == (dest.length() - m_route1.length()) ) return true; 00167 break; 00168 } 00169 00170 return false; 00171 } 00172 00173 string StaticRoutingExtension::StaticRoute::getDestination() 00174 { 00175 return m_dest; 00176 } 00177 } 00178 }
1.6.3