Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "net/ConnectionManager.h"
00009 #include "net/UDPConvergenceLayer.h"
00010 #include "net/TCPConvergenceLayer.h"
00011 #include "net/BundleReceivedEvent.h"
00012 #include "core/NodeEvent.h"
00013 #include "core/BundleEvent.h"
00014 #include "ibrcommon/net/tcpserver.h"
00015 #include "core/BundleCore.h"
00016 #include "routing/RequeueBundleEvent.h"
00017 #include "net/ConnectionEvent.h"
00018
00019 #include "core/NodeEvent.h"
00020 #include "core/TimeEvent.h"
00021
00022 #include <iostream>
00023 #include <iomanip>
00024 #include <algorithm>
00025 #include <functional>
00026 #include <typeinfo>
00027 #include <ibrcommon/Logger.h>
00028
00029 using namespace dtn::core;
00030
00031 namespace dtn
00032 {
00033 namespace net
00034 {
00035 struct CompareNodeDestination:
00036 public std::binary_function< dtn::core::Node, dtn::data::EID, bool > {
00037 bool operator() ( const dtn::core::Node &node, const dtn::data::EID &destination ) const {
00038 return dtn::data::EID(node.getURI()) == destination;
00039 }
00040 };
00041
00042 ConnectionManager::ConnectionManager()
00043 : _shutdown(false)
00044 {
00045 }
00046
00047 ConnectionManager::~ConnectionManager()
00048 {
00049 }
00050
00051 void ConnectionManager::componentUp()
00052 {
00053 bindEvent(TimeEvent::className);
00054 bindEvent(NodeEvent::className);
00055 bindEvent(ConnectionEvent::className);
00056 }
00057
00058 void ConnectionManager::componentDown()
00059 {
00060 {
00061 ibrcommon::MutexLock l(_cl_lock);
00062
00063 _cl.clear();
00064 }
00065
00066 unbindEvent(NodeEvent::className);
00067 unbindEvent(TimeEvent::className);
00068 unbindEvent(ConnectionEvent::className);
00069 }
00070
00071 void ConnectionManager::raiseEvent(const dtn::core::Event *evt)
00072 {
00073 try {
00074 const NodeEvent &nodeevent = dynamic_cast<const NodeEvent&>(*evt);
00075 const Node &n = nodeevent.getNode();
00076
00077 switch (nodeevent.getAction())
00078 {
00079 case NODE_INFO_UPDATED:
00080 discovered(n);
00081 break;
00082
00083 case NODE_AVAILABLE:
00084 if (n.doConnectImmediately())
00085 {
00086
00087 open(n);
00088 }
00089 break;
00090
00091 default:
00092 break;
00093 }
00094 } catch (const std::bad_cast&) { }
00095
00096 try {
00097 const TimeEvent &timeevent = dynamic_cast<const TimeEvent&>(*evt);
00098
00099 if (timeevent.getAction() == TIME_SECOND_TICK)
00100 {
00101 check_discovered();
00102 }
00103 } catch (const std::bad_cast&) { }
00104
00105 try {
00106 const ConnectionEvent &connection = dynamic_cast<const ConnectionEvent&>(*evt);
00107
00108 switch (connection.state)
00109 {
00110 case ConnectionEvent::CONNECTION_UP:
00111 {
00112 ibrcommon::MutexLock l(_node_lock);
00113
00114
00115 if (!isNeighbor(connection.node))
00116 {
00117
00118 dtn::core::NodeEvent::raise(connection.node, dtn::core::NODE_AVAILABLE);
00119 }
00120
00121 _connected_nodes.insert(connection.node);
00122 break;
00123 }
00124
00125 case ConnectionEvent::CONNECTION_DOWN:
00126 {
00127 ibrcommon::MutexLock l(_node_lock);
00128
00129
00130 if (isNeighbor(connection.node))
00131 {
00132
00133 _connected_nodes.erase(connection.node);
00134
00135
00136 _discovered_nodes.erase(connection.node);
00137
00138
00139 if (!isNeighbor(connection.node))
00140 {
00141
00142 dtn::core::NodeEvent::raise(connection.node, dtn::core::NODE_UNAVAILABLE);
00143 }
00144 }
00145 break;
00146 }
00147
00148 default:
00149 break;
00150 }
00151
00152 } catch (const std::bad_cast&) {
00153
00154 }
00155 }
00156
00157 void ConnectionManager::addConnection(const dtn::core::Node &n)
00158 {
00159 ibrcommon::MutexLock l(_node_lock);
00160 _static_nodes.insert(n);
00161 dtn::core::NodeEvent::raise(n, dtn::core::NODE_AVAILABLE);
00162 }
00163
00164 void ConnectionManager::addConvergenceLayer(ConvergenceLayer *cl)
00165 {
00166 ibrcommon::MutexLock l(_cl_lock);
00167 _cl.insert( cl );
00168 }
00169
00170 void ConnectionManager::discovered(const dtn::core::Node &node)
00171 {
00172
00173 if (EID(node.getURI()) == dtn::core::BundleCore::local) return;
00174
00175 ibrcommon::MutexLock l(_node_lock);
00176
00177
00178 if (!isNeighbor(node))
00179 {
00180
00181 dtn::core::NodeEvent::raise(node, dtn::core::NODE_AVAILABLE);
00182 }
00183
00184 _discovered_nodes.erase(node);
00185 _discovered_nodes.insert(node);
00186 }
00187
00188 void ConnectionManager::check_discovered()
00189 {
00190 ibrcommon::MutexLock l(_node_lock);
00191
00192
00193 std::set<dtn::core::Node>::iterator iter = _discovered_nodes.begin();
00194
00195 while (iter != _discovered_nodes.end())
00196 {
00197 dtn::core::Node n = (*iter);
00198
00199
00200 _discovered_nodes.erase( iter++ );
00201
00202 if ( !n.decrementTimeout(1) )
00203 {
00204
00205 _connected_nodes.erase(n);
00206
00207
00208 dtn::core::NodeEvent::raise(n, dtn::core::NODE_UNAVAILABLE);
00209 }
00210 else
00211 {
00212 _discovered_nodes.insert(n);
00213 }
00214 }
00215 }
00216
00217 void ConnectionManager::open(const dtn::core::Node &node)
00218 {
00219 if ((node.getProtocol() == Node::CONN_UNDEFINED) || (node.getProtocol() == Node::CONN_UNSUPPORTED))
00220 throw ConnectionNotAvailableException();
00221
00222 ibrcommon::MutexLock l(_cl_lock);
00223
00224
00225 for (std::set<ConvergenceLayer*>::iterator iter = _cl.begin(); iter != _cl.end(); iter++)
00226 {
00227 ConvergenceLayer *cl = (*iter);
00228 if (node.getProtocol() == cl->getDiscoveryProtocol())
00229 {
00230 cl->open(node);
00231
00232
00233 return;
00234 }
00235 }
00236
00237 throw ConnectionNotAvailableException();
00238 }
00239
00240 void ConnectionManager::queue(const dtn::core::Node &node, const ConvergenceLayer::Job &job)
00241 {
00242 if ((node.getProtocol() == Node::CONN_UNDEFINED) || (node.getProtocol() == Node::CONN_UNSUPPORTED))
00243 throw ConnectionNotAvailableException();
00244
00245 ibrcommon::MutexLock l(_cl_lock);
00246
00247
00248 for (std::set<ConvergenceLayer*>::iterator iter = _cl.begin(); iter != _cl.end(); iter++)
00249 {
00250 ConvergenceLayer *cl = (*iter);
00251 if (node.getProtocol() == cl->getDiscoveryProtocol())
00252 {
00253 cl->queue(node, job);
00254
00255
00256 return;
00257 }
00258 }
00259
00260 throw ConnectionNotAvailableException();
00261 }
00262
00263 void ConnectionManager::queue(const ConvergenceLayer::Job &job)
00264 {
00265 try {
00266 ibrcommon::MutexLock l(_node_lock);
00267
00268
00269 std::list<dtn::core::Node> match_rank;
00270
00271
00272 match_rank.push_back(dtn::core::Node(job._destination, Node::CONN_TCPIP));
00273
00274
00275 match_rank.push_back(dtn::core::Node(job._destination, Node::CONN_UDPIP));
00276
00277
00278 match_rank.push_back(dtn::core::Node(job._destination, Node::CONN_BLUETOOTH));
00279
00280
00281 match_rank.push_back(dtn::core::Node(job._destination, Node::CONN_ZIGBEE));
00282
00283
00284 match_rank.push_back(dtn::core::Node(job._destination, Node::CONN_HTTP));
00285
00286 if (IBRCOMMON_LOGGER_LEVEL >= 50)
00287 {
00288 IBRCOMMON_LOGGER_DEBUG(50) << "## static node list ##" << IBRCOMMON_LOGGER_ENDL;
00289 for (std::set<dtn::core::Node>::const_iterator iter = _static_nodes.begin(); iter != _static_nodes.end(); iter++)
00290 {
00291 const dtn::core::Node &n = (*iter);
00292 IBRCOMMON_LOGGER_DEBUG(50) << n.toString() << IBRCOMMON_LOGGER_ENDL;
00293 }
00294 }
00295
00296 if (IBRCOMMON_LOGGER_LEVEL >= 50)
00297 {
00298 IBRCOMMON_LOGGER_DEBUG(50) << "## dynamic node list ##" << IBRCOMMON_LOGGER_ENDL;
00299 for (std::set<dtn::core::Node>::const_iterator iter = _discovered_nodes.begin(); iter != _discovered_nodes.end(); iter++)
00300 {
00301 const dtn::core::Node &n = (*iter);
00302 IBRCOMMON_LOGGER_DEBUG(50) << n.toString() << IBRCOMMON_LOGGER_ENDL;
00303 }
00304 }
00305
00306 if (IBRCOMMON_LOGGER_LEVEL >= 50)
00307 {
00308 IBRCOMMON_LOGGER_DEBUG(50) << "## connected node list ##" << IBRCOMMON_LOGGER_ENDL;
00309 for (std::set<dtn::core::Node>::const_iterator iter = _connected_nodes.begin(); iter != _connected_nodes.end(); iter++)
00310 {
00311 const dtn::core::Node &n = (*iter);
00312 IBRCOMMON_LOGGER_DEBUG(50) << n.toString() << IBRCOMMON_LOGGER_ENDL;
00313 }
00314 }
00315
00316
00317 for (std::list<dtn::core::Node>::const_iterator imatch = match_rank.begin(); imatch != match_rank.end(); imatch++)
00318 {
00319 const dtn::core::Node &match = (*imatch);
00320 IBRCOMMON_LOGGER_DEBUG(50) << "match for " << match.toString() << IBRCOMMON_LOGGER_ENDL;
00321
00322 try {
00323
00324 std::set<dtn::core::Node>::const_iterator iter = _static_nodes.find(match);
00325
00326 if (iter != _static_nodes.end())
00327 {
00328 throw (*iter);
00329 }
00330 } catch (const std::exception&) { }
00331
00332 try {
00333
00334 std::set<dtn::core::Node>::const_iterator iter = _discovered_nodes.find(match);
00335
00336 if (iter != _discovered_nodes.end())
00337 {
00338 throw (*iter);
00339 }
00340 } catch (const std::exception&) { }
00341
00342 try {
00343
00344 std::set<dtn::core::Node>::const_iterator iter = _connected_nodes.find(match);
00345
00346 if (iter != _connected_nodes.end())
00347 {
00348 throw (*iter);
00349 }
00350 } catch (const std::exception&) { }
00351 }
00352 } catch (const dtn::core::Node next) {
00353 IBRCOMMON_LOGGER_DEBUG(50) << "next hop: " << next.toString() << IBRCOMMON_LOGGER_ENDL;
00354 queue(next, job);
00355 return;
00356 }
00357
00358 throw NeighborNotAvailableException("No active connection to this neighbor available!");
00359 }
00360
00361 void ConnectionManager::queue(const dtn::data::EID &eid, const dtn::data::BundleID &b)
00362 {
00363 queue( ConvergenceLayer::Job(eid, b) );
00364 }
00365
00366 const std::set<dtn::core::Node> ConnectionManager::getNeighbors()
00367 {
00368 ibrcommon::MutexLock l(_node_lock);
00369
00370 std::set<dtn::core::Node> _nodes;
00371
00372 for (std::set<dtn::core::Node>::const_iterator iter = _static_nodes.begin(); iter != _static_nodes.end(); iter++)
00373 {
00374 _nodes.insert( *iter );
00375 }
00376
00377 for (std::set<dtn::core::Node>::const_iterator iter = _discovered_nodes.begin(); iter != _discovered_nodes.end(); iter++)
00378 {
00379 _nodes.insert( *iter );
00380 }
00381
00382 for (std::set<dtn::core::Node>::const_iterator iter = _connected_nodes.begin(); iter != _connected_nodes.end(); iter++)
00383 {
00384 _nodes.insert( *iter );
00385 }
00386
00387 return _nodes;
00388 }
00389
00390
00391 bool ConnectionManager::isNeighbor(const dtn::core::Node &node)
00392 {
00393
00394 if (_static_nodes.find(node) != _static_nodes.end())
00395 {
00396 return true;
00397 }
00398
00399 if (_discovered_nodes.find(node) != _discovered_nodes.end())
00400 {
00401 return true;
00402 }
00403
00404 if (_connected_nodes.find(node) != _connected_nodes.end())
00405 {
00406 return true;
00407 }
00408
00409 return false;
00410 }
00411
00412 const std::string ConnectionManager::getName() const
00413 {
00414 return "ConnectionManager";
00415 }
00416 }
00417 }