IBR-DTNSuite  0.8
daemon/src/core/Node.cpp
Go to the documentation of this file.
00001 #include "core/Node.h"
00002 #include "net/ConvergenceLayer.h"
00003 #include <ibrdtn/utils/Clock.h>
00004 #include <ibrdtn/utils/Utils.h>
00005 #include <ibrcommon/Logger.h>
00006 
00007 #include <iostream>
00008 #include <sstream>
00009 
00010 using namespace std;
00011 
00012 namespace dtn
00013 {
00014         namespace core
00015         {
00016                 Node::URI::URI(const Node::Type t, const Node::Protocol p, const std::string &uri, const size_t to, const int prio)
00017                  : type(t), protocol(p), value(uri), expire((to == 0) ? 0 : dtn::utils::Clock::getTime() + to), priority(prio)
00018                 {
00019                 }
00020 
00021                 Node::URI::~URI()
00022                 {
00023                 }
00024 
00025                 void Node::URI::decode(std::string &address, unsigned int &port) const
00026                 {
00027                         // parse parameters
00028                         std::vector<string> parameters = dtn::utils::Utils::tokenize(";", value);
00029                         std::vector<string>::const_iterator param_iter = parameters.begin();
00030 
00031                         while (param_iter != parameters.end())
00032                         {
00033                                 std::vector<string> p = dtn::utils::Utils::tokenize("=", (*param_iter));
00034 
00035                                 if (p[0].compare("ip") == 0)
00036                                 {
00037                                         address = p[1];
00038                                 }
00039 
00040                                 if (p[0].compare("port") == 0)
00041                                 {
00042                                         std::stringstream port_stream;
00043                                         port_stream << p[1];
00044                                         port_stream >> port;
00045                                 }
00046 
00047                                 param_iter++;
00048                         }
00049                 }
00050 
00051                 bool Node::URI::operator<(const URI &other) const
00052                 {
00053                         if (protocol < other.protocol) return true;
00054                         if (protocol != other.protocol) return false;
00055 
00056                         if (type < other.type) return true;
00057                         if (type != other.type) return false;
00058 
00059                         return (value < other.value);
00060                 }
00061 
00062                 bool Node::URI::operator==(const URI &other) const
00063                 {
00064                         return ((type == other.type) && (protocol == other.protocol) && (value == other.value));
00065                 }
00066 
00067                 bool Node::URI::operator==(const Node::Protocol &p) const
00068                 {
00069                         return (protocol == p);
00070                 }
00071 
00072                 bool Node::URI::operator==(const Node::Type &t) const
00073                 {
00074                         return (type == t);
00075                 }
00076 
00077                 std::ostream& operator<<(std::ostream &stream, const Node::URI &u)
00078                 {
00079                         stream << u.priority << "#" << Node::toString(u.type) << "#" << Node::toString(u.protocol) << "#" << u.value;
00080                         return stream;
00081                 }
00082 
00083                 Node::Attribute::Attribute(const Type t, const std::string &n, const std::string &v, const size_t to, const int p)
00084                  : type(t), name(n), value(v), expire((to == 0) ? 0 : dtn::utils::Clock::getTime() + to), priority(p)
00085                 {
00086                 }
00087 
00088                 Node::Attribute::~Attribute()
00089                 {
00090                 }
00091 
00092                 bool Node::Attribute::operator<(const Attribute &other) const
00093                 {
00094                         if (name < other.name) return true;
00095                         if (name != other.name) return false;
00096 
00097                         return (type < other.type);
00098                 }
00099 
00100                 bool Node::Attribute::operator==(const Attribute &other) const
00101                 {
00102                         return ((type == other.type) && (name == other.name));
00103                 }
00104 
00105                 bool Node::Attribute::operator==(const std::string &n) const
00106                 {
00107                         return (name == n);
00108                 }
00109 
00110                 std::ostream& operator<<(std::ostream &stream, const Node::Attribute &a)
00111                 {
00112                         stream << a.priority << "#" << Node::toString(a.type) << "#" << a.name << "#" << a.value;
00113                         return stream;
00114                 }
00115 
00116                 Node::Node()
00117                 : _connect_immediately(false), _id()
00118                 {
00119                 }
00120 
00121                 Node::Node(const dtn::data::EID &id)
00122                 : _connect_immediately(false), _id(id)
00123                 {
00124                 }
00125 
00126                 Node::~Node()
00127                 {
00128                 }
00129 
00130                 std::string Node::toString(Node::Type type)
00131                 {
00132                         switch (type)
00133                         {
00134                         case Node::NODE_UNAVAILABLE:
00135                                 return "unavailable";
00136 
00137                         case Node::NODE_DISCOVERED:
00138                                 return "discovered";
00139 
00140                         case Node::NODE_STATIC:
00141                                 return "static";
00142 
00143                         case Node::NODE_CONNECTED:
00144                                 return "connected";
00145 
00146                         case Node::NODE_DHT_DISCOVERED:
00147                                 return "dht discovered";
00148                         }
00149 
00150                         return "unknown";
00151                 }
00152 
00153                 std::string Node::toString(Node::Protocol proto)
00154                 {
00155                         switch (proto)
00156                         {
00157                         case Node::CONN_UNSUPPORTED:
00158                                 return "unsupported";
00159 
00160                         case Node::CONN_UNDEFINED:
00161                                 return "undefined";
00162 
00163                         case Node::CONN_UDPIP:
00164                                 return "UDP";
00165 
00166                         case Node::CONN_TCPIP:
00167                                 return "TCP";
00168 
00169                         case Node::CONN_LOWPAN:
00170                                 return "LoWPAN";
00171 
00172                         case Node::CONN_BLUETOOTH:
00173                                 return "Bluetooth";
00174 
00175                         case Node::CONN_HTTP:
00176                                 return "HTTP";
00177 
00178                         case Node::CONN_FILE:
00179                                 return "FILE";
00180 
00181                         case Node::CONN_DGRAM_UDP:
00182                                 return "DGRAM:UDP";
00183 
00184                         case Node::CONN_DGRAM_ETHERNET:
00185                                 return "DGRAM:ETHERNET";
00186 
00187                         case Node::CONN_DGRAM_LOWPAN:
00188                                 return "DGRAM:LOWPAN";
00189                         }
00190 
00191                         return "unknown";
00192                 }
00193 
00194                 bool Node::has(Node::Protocol proto) const
00195                 {
00196                         for (std::set<URI>::const_iterator iter = _uri_list.begin(); iter != _uri_list.end(); iter++)
00197                         {
00198                                 if ((*iter) == proto) return true;
00199                         }
00200                         return false;
00201                 }
00202 
00203                 bool Node::has(const std::string &name) const
00204                 {
00205                         for (std::set<Attribute>::const_iterator iter = _attr_list.begin(); iter != _attr_list.end(); iter++)
00206                         {
00207                                 if ((*iter) == name) return true;
00208                         }
00209                         return false;
00210                 }
00211 
00212                 void Node::add(const URI &u)
00213                 {
00214                         _uri_list.erase(u);
00215                         _uri_list.insert(u);
00216                 }
00217 
00218                 void Node::add(const Attribute &attr)
00219                 {
00220                         _attr_list.erase(attr);
00221                         _attr_list.insert(attr);
00222                 }
00223 
00224                 void Node::remove(const URI &u)
00225                 {
00226                         _uri_list.erase(u);
00227                 }
00228 
00229                 void Node::remove(const Attribute &attr)
00230                 {
00231                         _attr_list.erase(attr);
00232                 }
00233 
00234                 void Node::clear()
00235                 {
00236                         _uri_list.clear();
00237                         _attr_list.clear();
00238                 }
00239 
00240                 // comparison of two URIs according to the priority
00241                 bool compare_uri_priority (const Node::URI &first, const Node::URI &second)
00242                 {
00243                         return first.priority > second.priority;
00244                 }
00245 
00246                 // comparison of two Attributes according to the priority
00247                 bool compare_attr_priority (const Node::Attribute &first, const Node::Attribute &second)
00248                 {
00249                         return first.priority > second.priority;
00250                 }
00251 
00252                 std::list<Node::URI> Node::get(Node::Protocol proto) const
00253                 {
00254                         std::list<URI> ret;
00255                         for (std::set<URI>::const_iterator iter = _uri_list.begin(); iter != _uri_list.end(); iter++)
00256                         {
00257                                 if ((*iter) == proto)
00258                                 {
00259                                         ret.push_back(*iter);
00260                                 }
00261                         }
00262 
00263                         ret.sort(compare_uri_priority);
00264                         return ret;
00265                 }
00266 
00267                 std::list<Node::URI> Node::get(Node::Type type, Node::Protocol proto) const
00268                 {
00269                         std::list<URI> ret;
00270                         for (std::set<URI>::const_iterator iter = _uri_list.begin(); iter != _uri_list.end(); iter++)
00271                         {
00272                                 if (((*iter) == proto) && ((*iter) == type)) ret.push_back(*iter);
00273                         }
00274                         ret.sort(compare_uri_priority);
00275                         return ret;
00276                 }
00277 
00278                 std::set<Node::Type> Node::getTypes() const
00279                 {
00280                         std::set<Type> ret;
00281                         for (std::set<URI>::const_iterator iter = _uri_list.begin(); iter != _uri_list.end(); iter++)
00282                         {
00283                                 ret.insert((*iter).type);
00284                         }
00285                         return ret;
00286                 }
00287 
00288                 std::list<Node::Attribute> Node::get(const std::string &name) const
00289                 {
00290                         std::list<Attribute> ret;
00291                         for (std::set<Attribute>::const_iterator iter = _attr_list.begin(); iter != _attr_list.end(); iter++)
00292                         {
00293                                 if ((*iter) == name) ret.push_back(*iter);
00294                         }
00295                         ret.sort(compare_attr_priority);
00296                         return ret;
00297                 }
00298 
00299                 const dtn::data::EID& Node::getEID() const
00300                 {
00301                         return _id;
00302                 }
00303 
00308                 bool Node::expire()
00309                 {
00310                         // get the current timestamp
00311                         size_t ct = dtn::utils::Clock::getTime();
00312 
00313                         // walk though all Attribute elements and remove the expired ones
00314                         {
00315                                 std::set<Attribute>::iterator iter = _attr_list.begin();
00316                                 while ( iter != _attr_list.end() )
00317                                 {
00318                                         const Attribute &attr = (*iter);
00319                                         if ((attr.expire > 0) && (attr.expire < ct))
00320                                         {
00321                                                 // remove this attribute
00322                                                 _attr_list.erase(iter++);
00323                                         }
00324                                         else
00325                                         {
00326                                                 iter++;
00327                                         }
00328                                 }
00329                         }
00330 
00331                         // walk though all URI elements and remove the expired ones
00332                         {
00333                                 std::set<URI>::iterator iter = _uri_list.begin();
00334                                 while ( iter != _uri_list.end() )
00335                                 {
00336                                         const URI &u = (*iter);
00337                                         if ((u.expire > 0) && (u.expire < ct))
00338                                         {
00339                                                 // remove this attribute
00340                                                 _uri_list.erase(iter++);
00341                                         }
00342                                         else
00343                                         {
00344                                                 iter++;
00345                                         }
00346                                 }
00347                         }
00348 
00349                         return (_attr_list.empty() && _uri_list.empty());
00350                 }
00351 
00352                 const Node& Node::operator+=(const Node &other)
00353                 {
00354                         for (std::set<Attribute>::const_iterator iter = other._attr_list.begin(); iter != other._attr_list.end(); iter++)
00355                         {
00356                                 const Attribute &attr = (*iter);
00357                                 add(attr);
00358                         }
00359 
00360                         for (std::set<URI>::const_iterator iter = other._uri_list.begin(); iter != other._uri_list.end(); iter++)
00361                         {
00362                                 const URI &u = (*iter);
00363                                 add(u);
00364                         }
00365 
00366                         return (*this);
00367                 }
00368 
00369                 const Node& Node::operator-=(const Node &other)
00370                 {
00371                         for (std::set<Attribute>::const_iterator iter = other._attr_list.begin(); iter != other._attr_list.end(); iter++)
00372                         {
00373                                 const Attribute &attr = (*iter);
00374                                 remove(attr);
00375                         }
00376 
00377                         for (std::set<URI>::const_iterator iter = other._uri_list.begin(); iter != other._uri_list.end(); iter++)
00378                         {
00379                                 const URI &u = (*iter);
00380                                 remove(u);
00381                         }
00382 
00383                         return (*this);
00384                 }
00385 
00386                 bool Node::operator==(const dtn::data::EID &other) const
00387                 {
00388                         return (other == _id);
00389                 }
00390 
00391                 bool Node::operator==(const Node &other) const
00392                 {
00393                         return (other._id == _id);
00394                 }
00395 
00396                 bool Node::operator<(const Node &other) const
00397                 {
00398                         if (_id < other._id ) return true;
00399 
00400                         return false;
00401                 }
00402 
00403                 std::string Node::toString() const
00404                 {
00405                         std::stringstream ss; ss << getEID().getString();
00406                         return ss.str();
00407                 }
00408 
00409                 bool Node::doConnectImmediately() const
00410                 {
00411                         return _connect_immediately;
00412                 }
00413 
00414                 void Node::setConnectImmediately(bool val)
00415                 {
00416                         _connect_immediately = val;
00417                 }
00418 
00419                 bool Node::isAvailable() const
00420                 {
00421                         return !_uri_list.empty();
00422                 }
00423 
00424                 std::ostream& operator<<(std::ostream &stream, const Node &node)
00425                 {
00426                         stream << "Node: " << node._id.getString() << " [ ";
00427                         for (std::set<Node::Attribute>::const_iterator iter = node._attr_list.begin(); iter != node._attr_list.end(); iter++)
00428                         {
00429                                 const Node::Attribute &attr = (*iter);
00430                                 stream << attr << "#expire=" << attr.expire << "; ";
00431                         }
00432 
00433                         for (std::set<Node::URI>::const_iterator iter = node._uri_list.begin(); iter != node._uri_list.end(); iter++)
00434                         {
00435                                 const Node::URI &u = (*iter);
00436                                 stream << u << "#expire=" << u.expire << "; ";
00437                         }
00438                         stream << " ]";
00439 
00440                         return stream;
00441                 }
00442         }
00443 }