예제 #1
0
		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;
				}
			}
		}
예제 #2
0
		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();
			}
		}