diff options
| -rw-r--r-- | Nim/main.cpp | 77 | ||||
| -rw-r--r-- | Swiften/LinkLocal/AppleDNSSDService.cpp | 56 | ||||
| -rw-r--r-- | Swiften/LinkLocal/AppleDNSSDService.h | 1 | ||||
| -rw-r--r-- | Swiften/LinkLocal/DNSSDService.h | 1 | ||||
| -rw-r--r-- | Swiften/LinkLocal/LinkLocalRoster.cpp | 3 | 
5 files changed, 94 insertions, 44 deletions
| diff --git a/Nim/main.cpp b/Nim/main.cpp index 024ecd1..8166534 100644 --- a/Nim/main.cpp +++ b/Nim/main.cpp @@ -1,5 +1,3 @@ -// TODO: Prohibit multiple logins -  #include <string>  #include <boost/bind.hpp>  #include <boost/shared_ptr.hpp> @@ -54,6 +52,8 @@ class Server {  			serverFromNetworkConnectionServer_->start();  			dnsSDService_ = boost::shared_ptr<AppleDNSSDService>(new AppleDNSSDService()); +			dnsSDService_->onServiceRegistered.connect(boost::bind(&Server::handleServiceRegistered, this, _1)); +  			linkLocalRoster_ = boost::shared_ptr<LinkLocalRoster>(new LinkLocalRoster(dnsSDService_));  			linkLocalRoster_->onRosterChanged.connect(boost::bind(&Server::handleRosterChanged, this, _1));  			linkLocalRoster_->onPresenceChanged.connect(boost::bind(&Server::handlePresenceChanged, this, _1)); @@ -67,7 +67,6 @@ class Server {  			}  			serverFromClientSession_ = boost::shared_ptr<ServerFromClientSession>(new ServerFromClientSession(idGenerator_.generateID(), c, &payloadParserFactories_, &payloadSerializers_, &userRegistry_));  			serverFromClientSession_->onStanzaReceived.connect(boost::bind(&Server::handleStanzaReceived, this, _1, serverFromClientSession_)); -			serverFromClientSession_->onSessionStarted.connect(boost::bind(&Server::handleSessionStarted, this, serverFromClientSession_));  			serverFromClientSession_->onSessionFinished.connect(boost::bind(&Server::handleSessionFinished, this, serverFromClientSession_));  			serverFromClientSession_->start();  		} @@ -76,34 +75,21 @@ class Server {  			std::cout << "Incoming link local connection" << std::endl;  		} -		void handleSessionStarted(boost::shared_ptr<ServerFromClientSession> session) { -			if (!dnsSDServiceRegistered_) { -				dnsSDServiceRegistered_ = true; -				dnsSDService_->onServiceRegistered.connect(boost::bind(&Server::handleServiceRegistered, this, _1)); -				LinkLocalServiceInfo info; -				info.setFirstName("Remko"); -				info.setLastName("Tron\xc3\xa7on"); -				info.setEMail("email@example.com"); -				info.setJID(JID("jid@example.com")); -				info.setMessage("I'm not Here"); -				info.setNick("Remko"); -				info.setStatus(LinkLocalServiceInfo::Away); -				info.setPort(linkLocalConnectionPort_); -				dnsSDService_->registerService(session->getJID().toBare().toString(), linkLocalConnectionPort_, info); -			} -		} -  		void handleServiceRegistered(const DNSSDService::Service& service) {  			std::cout << "Service registered " << service.name << " " << service.type << " " << service.domain << std::endl;  		}  		void handleSessionFinished(boost::shared_ptr<ServerFromClientSession>) {  			serverFromClientSession_.reset(); - -			std::cout << "Service unregistered" << std::endl; -			dnsSDServiceRegistered_ = false; +			unregisterService();  			rosterRequested_ = false; -			dnsSDService_->unregisterService(); +		} + +		void unregisterService() { +			if (dnsSDServiceRegistered_) { +				dnsSDServiceRegistered_ = false; +				dnsSDService_->unregisterService(); +			}  		}  		void handleStanzaReceived(boost::shared_ptr<Stanza> stanza, boost::shared_ptr<ServerFromClientSession> session) { @@ -111,7 +97,22 @@ class Server {  			if (!stanza->getTo().isValid()) {  				stanza->setTo(JID(session->getDomain()));  			} -			if (!stanza->getTo().isValid() || stanza->getTo() == session->getDomain() || stanza->getTo() == session->getJID().toBare()) { + +			if (boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza)) { +				if (presence->getType() == Presence::Available) { +					if (!dnsSDServiceRegistered_) { +						dnsSDServiceRegistered_ = true; +						dnsSDService_->registerService(session->getJID().toBare().toString(), linkLocalConnectionPort_, getLinkLocalServiceInfo(presence)); +					} +					else { +						dnsSDService_->updateService(getLinkLocalServiceInfo(presence)); +					} +				} +				else { +					unregisterService(); +				} +			} +			else if (!stanza->getTo().isValid() || stanza->getTo() == session->getDomain() || stanza->getTo() == session->getJID().toBare()) {  				if (boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza)) {  					if (iq->getPayload<RosterPayload>()) {  						if (iq->getType() == IQ::Get) { @@ -156,6 +157,32 @@ class Server {  			}  		} +		LinkLocalServiceInfo getLinkLocalServiceInfo(boost::shared_ptr<Presence> presence) { +			LinkLocalServiceInfo info; +			info.setFirstName("Remko"); +			info.setLastName("Tron\xc3\xa7on"); +			info.setEMail("email@example.com"); +			info.setJID(JID("jid@example.com")); +			info.setMessage(presence->getStatus()); +			info.setNick("Remko"); +			switch (presence->getShow()) { +				case StatusShow::Online:  +				case StatusShow::None:  +				case StatusShow::FFC:  +					info.setStatus(LinkLocalServiceInfo::Available); +					break; +				case StatusShow::Away:  +				case StatusShow::XA:  +					info.setStatus(LinkLocalServiceInfo::Away); +					break; +				case StatusShow::DND:  +					info.setStatus(LinkLocalServiceInfo::DND); +					break; +			} +			info.setPort(linkLocalConnectionPort_); +			return info; +		} +  	private:  		IDGenerator idGenerator_;  		BoostIOServiceThread boostIOServiceThread_; diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp index 18cdcb0..d4befd1 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.cpp +++ b/Swiften/LinkLocal/AppleDNSSDService.cpp @@ -55,6 +55,13 @@ void AppleDNSSDService::registerService(const String& name, int port, const Link  	interruptSelect();  } +void AppleDNSSDService::updateService(const LinkLocalServiceInfo& info) { +	boost::lock_guard<boost::mutex> lock(sdRefsMutex); +	assert(registerSDRef); +	ByteArray txtRecord = info.toTXTRecord(); +	DNSServiceUpdateRecord(registerSDRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); +} +  void AppleDNSSDService::unregisterService() {  	boost::lock_guard<boost::mutex> lock(sdRefsMutex); @@ -91,6 +98,7 @@ void AppleDNSSDService::stopResolvingService(const Service& service) {  void AppleDNSSDService::resolveHostname(const String& hostname, int interfaceIndex) {  	boost::lock_guard<boost::mutex> lock(sdRefsMutex); +	std::cout << "Resolve " << hostname << std::endl;  	DNSServiceRef hostnameResolveSDRef;  	DNSServiceErrorType result = DNSServiceGetAddrInfo(&hostnameResolveSDRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, hostname.getUTF8Data(), &AppleDNSSDService::handleHostnameResolvedGlobal, this); @@ -110,11 +118,14 @@ void AppleDNSSDService::doStart() {  	onStarted();  	// Listen for new services -	assert(!browseSDRef); -	DNSServiceErrorType result = DNSServiceBrowse(&browseSDRef, 0, 0, "_presence._tcp", 0, &AppleDNSSDService::handleServiceDiscoveredGlobal , this); -	if (result != kDNSServiceErr_NoError) { -		std::cerr << "Error creating browse query" << std::endl; -		haveError = true; +	{ +		boost::lock_guard<boost::mutex> lock(sdRefsMutex); +		assert(!browseSDRef); +		DNSServiceErrorType result = DNSServiceBrowse(&browseSDRef, 0, 0, "_presence._tcp", 0, &AppleDNSSDService::handleServiceDiscoveredGlobal , this); +		if (result != kDNSServiceErr_NoError) { +			std::cerr << "Error creating browse query" << std::endl; +			haveError = true; +		}  	}  	// Run the main loop @@ -148,6 +159,7 @@ void AppleDNSSDService::doStart() {  			// Hostname resolving  			for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) { +				std::cout << "Adding ostname resolve " << std::endl;  				int hostnameResolveSocket = DNSServiceRefSockFD(*i);  				maxSocket = std::max(maxSocket, hostnameResolveSocket);  				FD_SET(hostnameResolveSocket, &fdSet); @@ -181,6 +193,7 @@ void AppleDNSSDService::doStart() {  			for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) {  				if (FD_ISSET(DNSServiceRefSockFD(*i), &fdSet)) {  					DNSServiceProcessResult(*i); +					std::cout << "Removing hostnameResolve" << std::endl;  					hostnameResolveSDRefs.erase(std::remove(hostnameResolveSDRefs.begin(), hostnameResolveSDRefs.end(), *i), hostnameResolveSDRefs.end());  					DNSServiceRefDeallocate(*i);  					break; // Stop the loop, because we removed an element @@ -189,23 +202,28 @@ void AppleDNSSDService::doStart() {  		}  	} -	for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) { -		DNSServiceRefDeallocate(i->second); -	} -	resolveSDRefs.clear(); +	{ +		boost::lock_guard<boost::mutex> lock(sdRefsMutex); -	for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) { -		DNSServiceRefDeallocate(*i); -	} -	hostnameResolveSDRefs.clear(); +		for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) { +			DNSServiceRefDeallocate(i->second); +		} +		resolveSDRefs.clear(); -	if (registerSDRef) { -		DNSServiceRefDeallocate(registerSDRef); -		registerSDRef = NULL; -	} +		for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) { +			std::cout << "Removing hostnameResolve" << std::endl; +			DNSServiceRefDeallocate(*i); +		} +		hostnameResolveSDRefs.clear(); + +		if (registerSDRef) { +			DNSServiceRefDeallocate(registerSDRef); +			registerSDRef = NULL; +		} -	DNSServiceRefDeallocate(browseSDRef); -	browseSDRef = NULL; +		DNSServiceRefDeallocate(browseSDRef); +		browseSDRef = NULL; +	}  	MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), haveError), shared_from_this());  } diff --git a/Swiften/LinkLocal/AppleDNSSDService.h b/Swiften/LinkLocal/AppleDNSSDService.h index cdeafed..fe4a648 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.h +++ b/Swiften/LinkLocal/AppleDNSSDService.h @@ -18,6 +18,7 @@ namespace Swift {  			virtual void stop();  			virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&); +			virtual void updateService(const LinkLocalServiceInfo&);  			virtual void unregisterService();  			virtual void startResolvingService(const Service&); diff --git a/Swiften/LinkLocal/DNSSDService.h b/Swiften/LinkLocal/DNSSDService.h index 3dd8c7b..9689352 100644 --- a/Swiften/LinkLocal/DNSSDService.h +++ b/Swiften/LinkLocal/DNSSDService.h @@ -55,6 +55,7 @@ namespace Swift {  			virtual void stop() = 0;  			virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&) = 0; +			virtual void updateService(const LinkLocalServiceInfo&) = 0;  			virtual void unregisterService() = 0;  			virtual void startResolvingService(const Service&) = 0; diff --git a/Swiften/LinkLocal/LinkLocalRoster.cpp b/Swiften/LinkLocal/LinkLocalRoster.cpp index aedea77..89bfa55 100644 --- a/Swiften/LinkLocal/LinkLocalRoster.cpp +++ b/Swiften/LinkLocal/LinkLocalRoster.cpp @@ -81,6 +81,9 @@ void LinkLocalRoster::handleServiceAdded(const DNSSDService::Service& service) {  }  void LinkLocalRoster::handleServiceRemoved(const DNSSDService::Service& service) { +	if (selfService && *selfService == service) { +		return; +	}  	dnsSDService->stopResolvingService(service);  	services.erase(service);  	boost::shared_ptr<RosterPayload> roster(new RosterPayload()); | 
 Swift
 Swift