• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

daemon/src/net/IPNDAgent.cpp

Go to the documentation of this file.
00001 /*
00002  * IPNDAgent.cpp
00003  *
00004  *  Created on: 14.09.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "net/IPNDAgent.h"
00009 #include "core/BundleCore.h"
00010 #include <ibrdtn/data/Exceptions.h>
00011 #include <sstream>
00012 #include <string.h>
00013 #include <ibrcommon/Logger.h>
00014 #include <ibrcommon/net/MulticastSocket.h>
00015 #include <ibrcommon/net/BroadcastSocket.h>
00016 #include "Configuration.h"
00017 #include <typeinfo>
00018 
00019 namespace dtn
00020 {
00021         namespace net
00022         {
00023                 IPNDAgent::IPNDAgent(int port, std::string address)
00024                  : DiscoveryAgent(dtn::daemon::Configuration::getInstance().getDiscovery()), _version(DiscoveryAnnouncement::DISCO_VERSION_01), _socket(NULL), _destination(address), _port(port)
00025                 {
00026                         if (ibrcommon::MulticastSocket::isMulticast(_destination))
00027                         {
00028                                 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: multicast mode " << address << ":" << port << IBRCOMMON_LOGGER_ENDL;
00029                                 _socket = new ibrcommon::MulticastSocket();
00030                         }
00031                         else
00032                         {
00033                                 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: broadcast mode " << address << ":" << port << IBRCOMMON_LOGGER_ENDL;
00034                                 _socket = new ibrcommon::BroadcastSocket();
00035                         }
00036 
00037                         switch (_config.version())
00038                         {
00039                         case 2:
00040                                 _version = DiscoveryAnnouncement::DISCO_VERSION_01;
00041                                 break;
00042 
00043                         case 1:
00044                                 _version = DiscoveryAnnouncement::DISCO_VERSION_00;
00045                                 break;
00046 
00047                         case 0:
00048                                 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: DTN2 compatibility mode" << IBRCOMMON_LOGGER_ENDL;
00049                                 _version = DiscoveryAnnouncement::DTND_IPDISCOVERY;
00050                                 break;
00051                         };
00052                 }
00053 
00054                 IPNDAgent::~IPNDAgent()
00055                 {
00056                         delete _socket;
00057                 }
00058 
00059                 void IPNDAgent::bind(const ibrcommon::NetInterface &net)
00060                 {
00061                         IBRCOMMON_LOGGER(info) << "DiscoveryAgent: bind to interface " << net.toString() << IBRCOMMON_LOGGER_ENDL;
00062                         _interfaces.push_back(net);
00063                 }
00064 
00065                 void IPNDAgent::send(ibrcommon::udpsocket::peer &p, const DiscoveryAnnouncement &announcement)
00066                 {
00067                         stringstream ss;
00068                         ss << announcement;
00069 
00070                         string data = ss.str();
00071                         p.send(data.c_str(), data.length());
00072                 }
00073 
00074                 void IPNDAgent::sendAnnoucement(const u_int16_t &sn, const std::list<DiscoveryService> &services)
00075                 {
00076                         DiscoveryAnnouncement announcement(_version, dtn::core::BundleCore::local);
00077 
00078                         // set sequencenumber
00079                         announcement.setSequencenumber(sn);
00080 
00081                         if (_sockets.empty())
00082                         {
00083                                 if (!_config.shortbeacon())
00084                                 {
00085                                         // add services
00086                                         for (std::list<DiscoveryService>::const_iterator iter = services.begin(); iter != services.end(); iter++)
00087                                         {
00088                                                 const DiscoveryService &service = (*iter);
00089                                                 announcement.addService(service);
00090                                         }
00091                                 }
00092 
00093                                 ibrcommon::udpsocket::peer p = _socket->getPeer(_destination, _port);
00094 
00095                                 // send announcement
00096                                 send(p, announcement);
00097 
00098                                 return;
00099                         }
00100 
00101                         for (std::list<ibrcommon::NetInterface>::const_iterator it_iface = _interfaces.begin(); it_iface != _interfaces.end(); it_iface++)
00102                         {
00103                                 const ibrcommon::NetInterface &iface = (*it_iface);
00104 
00105                                 // clear all services
00106                                 announcement.clearServices();
00107 
00108                                 if (!_config.shortbeacon())
00109                                 {
00110                                         // add services
00111                                         for (std::list<DiscoveryService>::const_iterator iter = services.begin(); iter != services.end(); iter++)
00112                                         {
00113                                                 const DiscoveryService &service = (*iter);
00114                                                 if (service.onInterface(iface))
00115                                                 {
00116                                                         announcement.addService(service);
00117                                                 }
00118                                         }
00119                                 }
00120 
00121                                 ibrcommon::udpsocket *sock = _sockets[iface.toString()];
00122 
00123                                 if (sock == NULL)
00124                                 {
00125                                         sock = _socket;
00126                                 }
00127 
00128                                 ibrcommon::udpsocket::peer p = sock->getPeer(_destination, _port);
00129 
00130                                 // send announcement
00131                                 send(p, announcement);
00132                         }
00133                 }
00134 
00135                 void IPNDAgent::componentUp()
00136                 {
00137                         DiscoveryAgent::componentUp();
00138 
00139                         try {
00140                                 ibrcommon::MulticastSocket &sock = dynamic_cast<ibrcommon::MulticastSocket&>(*_socket);
00141                                 sock.bind(_port);
00142 
00143                                 if (_interfaces.empty())
00144                                 {
00145                                         sock.joinGroup(_destination);
00146                                 }
00147                                 else
00148                                 {
00149                                         for (std::list<ibrcommon::NetInterface>::const_iterator iter = _interfaces.begin(); iter != _interfaces.end(); iter++)
00150                                         {
00151                                                 const ibrcommon::NetInterface &net = (*iter);
00152 
00153                                                 if (_sockets.empty())
00154                                                 {
00155                                                         _sockets[net.toString()] = _socket;
00156                                                         sock.setInterface(net);
00157                                                 }
00158                                                 else
00159                                                 {
00160                                                         ibrcommon::MulticastSocket *newsock = new ibrcommon::MulticastSocket();
00161                                                         newsock->setInterface(net);
00162                                                         _sockets[net.toString()] = newsock;
00163                                                 }
00164 
00165                                                 sock.joinGroup(_destination, (*iter));
00166                                         }
00167                                 }
00168                         } catch (std::bad_cast) {
00169 
00170                         }
00171 
00172                         try {
00173                                 ibrcommon::BroadcastSocket &sock = dynamic_cast<ibrcommon::BroadcastSocket&>(*_socket);
00174                                 sock.bind(_port);
00175                         } catch (std::bad_cast) {
00176 
00177                         }
00178                 }
00179 
00180                 void IPNDAgent::componentDown()
00181                 {
00182                         _socket->shutdown();
00183                         DiscoveryAgent::componentDown();
00184                 }
00185 
00186                 void IPNDAgent::componentRun()
00187                 {
00188                         while (true)
00189                         {
00190                                 DiscoveryAnnouncement announce(_version);
00191 
00192                                 char data[1500];
00193 
00194                                 std::string sender;
00195                                 int len = _socket->receive(data, 1500, sender);
00196                                 
00197                                 if (announce.isShort())
00198                                 {
00199                                         // TODO: generate name with the sender address
00200                                 }
00201 
00202                                 if (announce.getServices().empty())
00203                                 {
00204                                         announce.addService(dtn::net::DiscoveryService("tcpcl", "ip=" + sender + ";port=4556;"));
00205                                 }
00206 
00207                                 if (len < 0) return;
00208 
00209                                 stringstream ss;
00210                                 ss.write(data, len);
00211 
00212                                 try {
00213                                         ss >> announce;
00214                                         received(announce);
00215                                 } catch (dtn::InvalidDataException ex) {
00216                                 } catch (ibrcommon::IOException ex) {
00217                                 }
00218 
00219                                 yield();
00220                         }
00221                 }
00222 
00223                 bool IPNDAgent::__cancellation()
00224                 {
00225                         // since this is an receiving thread we have to cancel the hard way
00226                         return false;
00227                 }
00228 
00229                 const std::string IPNDAgent::getName() const
00230                 {
00231                         return "IPNDAgent";
00232                 }
00233         }
00234 }

Generated on Thu Nov 11 2010 09:49:47 for IBR-DTNSuite by  doxygen 1.7.1