00001
00002
00003
00004
00005
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 <typeinfo>
00017
00018 namespace dtn
00019 {
00020 namespace net
00021 {
00022 IPNDAgent::IPNDAgent(int port, std::string address)
00023 : _socket(NULL), _destination(address), _port(port)
00024 {
00025 if (ibrcommon::MulticastSocket::isMulticast(_destination))
00026 {
00027 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: multicast mode " << address << ":" << port << IBRCOMMON_LOGGER_ENDL;
00028 _socket = new ibrcommon::MulticastSocket();
00029 }
00030 else
00031 {
00032 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: broadcast mode " << address << ":" << port << IBRCOMMON_LOGGER_ENDL;
00033 _socket = new ibrcommon::BroadcastSocket();
00034 }
00035 }
00036
00037 IPNDAgent::~IPNDAgent()
00038 {
00039 delete _socket;
00040 }
00041
00042 void IPNDAgent::bind(const ibrcommon::NetInterface &net)
00043 {
00044 IBRCOMMON_LOGGER(info) << "DiscoveryAgent: bind to interface " << net.getInterface() << IBRCOMMON_LOGGER_ENDL;
00045 _interfaces.push_back(net);
00046 }
00047
00048 void IPNDAgent::send(ibrcommon::udpsocket::peer &p, const DiscoveryAnnouncement &announcement)
00049 {
00050 stringstream ss;
00051 ss << announcement;
00052
00053 string data = ss.str();
00054 p.send(data.c_str(), data.length());
00055 }
00056
00057 void IPNDAgent::sendAnnoucement(const u_int16_t &sn, const std::list<DiscoveryService> &services)
00058 {
00059 DiscoveryAnnouncement announcement(DiscoveryAnnouncement::DISCO_VERSION_01, dtn::core::BundleCore::local);
00060
00061
00062 announcement.setSequencenumber(sn);
00063
00064 if (_sockets.empty())
00065 {
00066
00067 for (std::list<DiscoveryService>::const_iterator iter = services.begin(); iter != services.end(); iter++)
00068 {
00069 const DiscoveryService &service = (*iter);
00070 announcement.addService(service);
00071 }
00072
00073 ibrcommon::udpsocket::peer p = _socket->getPeer(_destination, _port);
00074
00075
00076 send(p, announcement);
00077
00078 return;
00079 }
00080
00081 for (std::list<ibrcommon::NetInterface>::const_iterator it_iface = _interfaces.begin(); it_iface != _interfaces.end(); it_iface++)
00082 {
00083 const ibrcommon::NetInterface &iface = (*it_iface);
00084
00085
00086 announcement.clearServices();
00087
00088
00089 for (std::list<DiscoveryService>::const_iterator iter = services.begin(); iter != services.end(); iter++)
00090 {
00091 const DiscoveryService &service = (*iter);
00092 if (service.onInterface(iface))
00093 {
00094 announcement.addService(service);
00095 }
00096 }
00097
00098 ibrcommon::udpsocket *sock = _sockets[iface.getInterface()];
00099
00100 if (sock == NULL)
00101 {
00102 sock = _socket;
00103 }
00104
00105 ibrcommon::udpsocket::peer p = sock->getPeer(_destination, _port);
00106
00107
00108 send(p, announcement);
00109 }
00110 }
00111
00112 void IPNDAgent::componentUp()
00113 {
00114 DiscoveryAgent::componentUp();
00115
00116 try {
00117 ibrcommon::MulticastSocket &sock = dynamic_cast<ibrcommon::MulticastSocket&>(*_socket);
00118 sock.bind(_port);
00119
00120 if (_interfaces.empty())
00121 {
00122 sock.joinGroup(_destination);
00123 }
00124 else
00125 {
00126 for (std::list<ibrcommon::NetInterface>::const_iterator iter = _interfaces.begin(); iter != _interfaces.end(); iter++)
00127 {
00128 const ibrcommon::NetInterface &net = (*iter);
00129
00130 if (_sockets.empty())
00131 {
00132 _sockets[net.getInterface()] = _socket;
00133 sock.setInterface(net);
00134 }
00135 else
00136 {
00137 ibrcommon::MulticastSocket *newsock = new ibrcommon::MulticastSocket();
00138 newsock->setInterface(net);
00139 _sockets[net.getInterface()] = newsock;
00140 }
00141
00142 sock.joinGroup(_destination, (*iter));
00143 }
00144 }
00145 } catch (std::bad_cast) {
00146
00147 }
00148
00149 try {
00150 ibrcommon::BroadcastSocket &sock = dynamic_cast<ibrcommon::BroadcastSocket&>(*_socket);
00151 sock.bind(_port);
00152 } catch (std::bad_cast) {
00153
00154 }
00155 }
00156
00157 void IPNDAgent::componentDown()
00158 {
00159 _socket->shutdown();
00160 DiscoveryAgent::componentDown();
00161 }
00162
00163 void IPNDAgent::componentRun()
00164 {
00165 _running = true;
00166
00167 while (_running)
00168 {
00169 DiscoveryAnnouncement announce;
00170
00171 char data[1500];
00172
00173 int len = _socket->receive(data, 1500);
00174
00175 if (len < 0) return;
00176
00177 stringstream ss;
00178 ss.write(data, len);
00179
00180 try {
00181 ss >> announce;
00182 received(announce);
00183 } catch (dtn::InvalidDataException ex) {
00184 } catch (ibrcommon::IOException ex) {
00185 }
00186
00187 yield();
00188 }
00189 }
00190 }
00191 }