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