void DiscoveryAgent::onBeaconReceived(const DiscoveryBeacon &beacon) { // ignore own beacons if (beacon.getEID() == dtn::core::BundleCore::local) return; // convert the announcement into NodeEvents Node n(beacon.getEID()); const std::list<DiscoveryService> &services = beacon.getServices(); for (std::list<DiscoveryService>::const_iterator iter = services.begin(); iter != services.end(); ++iter) { const dtn::data::Number to_value = _config.timeout(); const DiscoveryService &s = (*iter); // get protocol from tag const dtn::core::Node::Protocol p = s.getProtocol(); if (p == dtn::core::Node::CONN_EMAIL) { // Set timeout dtn::data::Number to_value_mailcl = to_value; size_t configTime = dtn::daemon::Configuration::getInstance().getEMail().getNodeAvailableTime(); if(configTime > 0) to_value_mailcl = configTime; n.add(Node::URI(Node::NODE_DISCOVERED, Node::CONN_EMAIL, s.getParameters(), to_value_mailcl, 20)); } else if ((p == dtn::core::Node::CONN_UNSUPPORTED) || (p == dtn::core::Node::CONN_UNDEFINED)) { n.add(Node::Attribute(Node::NODE_DISCOVERED, s.getName(), s.getParameters(), to_value, 20)); } else { n.add(Node::URI(Node::NODE_DISCOVERED, p, s.getParameters(), to_value, 20)); } } // announce NodeInfo to ConnectionManager dtn::core::BundleCore::getInstance().getConnectionManager().updateNeighbor(n); // if continuous announcements are disabled, then reply to this message if (!_config.announce()) { // first check if another announcement was sent during the same seconds const dtn::data::Timestamp ts = dtn::utils::Clock::getMonotonicTimestamp(); if (_last_announce_sent != ts) { IBRCOMMON_LOGGER_DEBUG_TAG("DiscoveryAgent", 55) << "reply with discovery beacon" << IBRCOMMON_LOGGER_ENDL; // reply with an own announcement onAdvertise(); // remember timestamp of last sent discovery _last_announce_sent = ts; } } }
void IPNDAgent::componentRun() throw () { struct timeval tv; // every second we want to transmit a discovery message, timeout of 1 seconds tv.tv_sec = 1; tv.tv_usec = 0; // get the reference to the discovery agent dtn::net::DiscoveryAgent &agent = dtn::core::BundleCore::getInstance().getDiscoveryAgent(); try { while (true) { ibrcommon::socketset fds; try { // select on all bound sockets _socket.select(&fds, NULL, NULL, &tv); // receive from all sockets for (ibrcommon::socketset::const_iterator iter = fds.begin(); iter != fds.end(); ++iter) { ibrcommon::multicastsocket &sock = dynamic_cast<ibrcommon::multicastsocket&>(**iter); char data[1500]; ibrcommon::vaddress sender; DiscoveryBeacon beacon = agent.obtainBeacon(); ssize_t len = sock.recvfrom(data, 1500, 0, sender); if (len < 0) return; stringstream ss; ss.write(data, len); try { ss >> beacon; if (beacon.isShort()) { // generate name with the sender address beacon.setEID( dtn::data::EID("udp://[" + sender.address() + "]:4556") ); // add generated tcpcl service if the services list is empty beacon.addService(dtn::net::DiscoveryService(dtn::core::Node::CONN_TCPIP, "ip=" + sender.address() + ";port=4556;")); } DiscoveryBeacon::service_list &services = beacon.getServices(); // add source address if not set for (dtn::net::DiscoveryBeacon::service_list::iterator iter = services.begin(); iter != services.end(); ++iter) { DiscoveryService &service = (*iter); if ( (service.getParameters().find("port=") != std::string::npos) && (service.getParameters().find("ip=") == std::string::npos) ) { // update service entry service.update("ip=" + sender.address() + ";" + service.getParameters()); } } // announce the received beacon agent.onBeaconReceived(beacon); } catch (const dtn::InvalidDataException&) { } catch (const ibrcommon::IOException&) { } } // trigger an artificial timeout if the remaining timeout value is zero or below if ( tv.tv_sec <= 0 && tv.tv_usec <= 0 ) throw ibrcommon::vsocket_timeout("timeout"); } catch (const ibrcommon::vsocket_timeout&) { // reset timeout to 1 second tv.tv_sec = 1; tv.tv_usec = 0; } yield(); } } catch (const ibrcommon::vsocket_interrupt&) { // vsocket has been interrupted - exit now } catch (const ibrcommon::socket_exception &ex) { // unexpected error - exit now IBRCOMMON_LOGGER_TAG(IPNDAgent::TAG, error) << "unexpected error: " << ex.what() << IBRCOMMON_LOGGER_ENDL; } }
void LOWPANConvergenceLayer::componentRun() throw () { dtn::net::DiscoveryAgent &agent = dtn::core::BundleCore::getInstance().getDiscoveryAgent(); while (_running) { try { ibrcommon::socketset readfds; _vsocket.select(&readfds, NULL, NULL, NULL); for (ibrcommon::socketset::iterator iter = readfds.begin(); iter != readfds.end(); ++iter) { ibrcommon::lowpansocket &sock = dynamic_cast<ibrcommon::lowpansocket&>(**iter); std::vector<char> data(m_maxmsgsize); char header; // place to store the peer address ibrcommon::vaddress peeraddr; // Receive full frame from socket ssize_t len = sock.recvfrom(&data[0], static_cast<size_t>(m_maxmsgsize), 0, peeraddr); IBRCOMMON_LOGGER_DEBUG_TAG("LOWPANConvergenceLayer", 40) << "Received IEEE 802.15.4 frame from " << peeraddr.toString() << IBRCOMMON_LOGGER_ENDL; // We got nothing from the socket, keep reading if (len <= 0) continue; // Retrieve header of frame header = data[0]; // Check for extended header and retrieve if available if ((header & EXTENDED_MASK) && (data[1] & 0x80)) { DiscoveryBeacon beacon = agent.obtainBeacon(); std::stringstream ss; ss.write(&data[2], len-2); ss >> beacon; // ignore own beacons if (beacon.getEID() == dtn::core::BundleCore::local) continue; // do not accept short beacons if (!beacon.isShort()) { agent.onBeaconReceived(beacon); } continue; } ibrcommon::MutexLock lc(_connection_lock); // Connection instance for this address LOWPANConnection* connection = getConnection(peeraddr); // Decide in which queue to write based on the src address connection->getStream().queue(&data[0], len); } } catch (const ibrcommon::socket_exception&) { return; } yield(); } }