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 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(); } }