#include #include #include "Swiften/LinkLocal/LinkLocalRoster.h" #include "Swiften/Network/HostAddress.h" namespace Swift { LinkLocalRoster::LinkLocalRoster(boost::shared_ptr service) : dnsSDService(service) { dnsSDService->onStopped.connect(boost::bind(&LinkLocalRoster::handleStopped, this, _1)); dnsSDService->onServiceRegistered.connect(boost::bind(&LinkLocalRoster::handleServiceRegistered, this, _1)); dnsSDService->onServiceAdded.connect(boost::bind(&LinkLocalRoster::handleServiceAdded, this, _1)); dnsSDService->onServiceRemoved.connect(boost::bind(&LinkLocalRoster::handleServiceRemoved, this, _1)); dnsSDService->onServiceResolved.connect(boost::bind(&LinkLocalRoster::handleServiceResolved, this, _1, _2)); } boost::shared_ptr LinkLocalRoster::getRoster() const { boost::shared_ptr roster(new RosterPayload()); for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { roster->addItem(getRosterItem(i->first, i->second)); } return roster; } std::vector > LinkLocalRoster::getAllPresence() const { std::vector > result; for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { result.push_back(getPresence(i->first, i->second)); } return result; } RosterItemPayload LinkLocalRoster::getRosterItem(const DNSSDServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { return RosterItemPayload(getJIDForService(service), getRosterName(service, resolveResult), RosterItemPayload::Both); } String LinkLocalRoster::getRosterName(const DNSSDServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { if (!resolveResult.info.getNick().isEmpty()) { return resolveResult.info.getNick(); } else if (!resolveResult.info.getFirstName().isEmpty()) { String result = resolveResult.info.getFirstName(); if (!resolveResult.info.getLastName().isEmpty()) { result += " " + resolveResult.info.getLastName(); } return result; } else if (!resolveResult.info.getLastName().isEmpty()) { return resolveResult.info.getLastName(); } return service.getName(); } JID LinkLocalRoster::getJIDForService(const DNSSDServiceID& service) const { return JID(service.getName()); } boost::shared_ptr LinkLocalRoster::getPresence(const DNSSDServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { boost::shared_ptr presence(new Presence()); presence->setFrom(getJIDForService(service)); switch (resolveResult.info.getStatus()) { case LinkLocalServiceInfo::Available: presence->setShow(StatusShow::Online); break; case LinkLocalServiceInfo::Away: presence->setShow(StatusShow::Away); break; case LinkLocalServiceInfo::DND: presence->setShow(StatusShow::DND); break; } presence->setStatus(resolveResult.info.getMessage()); return presence; } void LinkLocalRoster::handleServiceAdded(const DNSSDServiceID& service) { if (selfService && *selfService == service) { return; } dnsSDService->startResolvingService(service); } void LinkLocalRoster::handleServiceRemoved(const DNSSDServiceID& service) { if (selfService && *selfService == service) { return; } dnsSDService->stopResolvingService(service); services.erase(service); boost::shared_ptr roster(new RosterPayload()); roster->addItem(RosterItemPayload(getJIDForService(service), "", RosterItemPayload::Remove)); onRosterChanged(roster); } void LinkLocalRoster::handleServiceResolved(const DNSSDServiceID& service, const DNSSDService::ResolveResult& result) { std::pair r = services.insert(std::make_pair(service, result)); if (r.second) { boost::shared_ptr roster(new RosterPayload()); roster->addItem(getRosterItem(service, result)); onRosterChanged(roster); } else { r.first->second = result; } onPresenceChanged(getPresence(service, result)); } void LinkLocalRoster::handleServiceRegistered(const DNSSDServiceID& service) { selfService = service; } void LinkLocalRoster::handleStopped(bool error) { std::cout << "DNSSDService stopped: " << error << std::endl; } bool LinkLocalRoster::hasItem(const JID& j) const { for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { if (getJIDForService(i->first) == j) { return true; } } return false; } String LinkLocalRoster::getHostname(const JID& j) const { for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { if (getJIDForService(i->first) == j) { return i->second.host; } } return ""; } int LinkLocalRoster::getPort(const JID& j) const { for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { if (getJIDForService(i->first) == j) { return i->second.port; } } return 0; } }